diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index ce1b98b..1c18c6a 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -11,7 +11,7 @@ jobs: outputs: image: ${{ steps.image_name.outputs.image }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Generate image name id: image_name @@ -25,8 +25,19 @@ jobs: HARBOR_PASSWORD: ${{ secrets.HARBOR_PASSWORD }} HARBOR_URI: ${{ secrets.HARBOR_URI }} + - name: Import Secrets + id: import-secrets + uses: hashicorp/vault-action@v3 + with: + url: ${{ secrets.VAULT_ADDR }} + method: userpass + username: ${{ secrets.VAULT_USERNAME }} + password: ${{ secrets.VAULT_PASSWORD }} + secrets: | + applications/data/aznopoly DISCORD_CLIENT_ID | VITE_DISCORD_CLIENT_ID; + - name: Build the Docker image - run: docker buildx build . --file Dockerfile --tag $HARBOR_URI/abstractolotl/aznopoly-web:${IMAGE_NAME} --tag $HARBOR_URI/abstractolotl/aznopoly-web:latest + run: docker buildx build . --build-arg vite_discord_client_id=$VITE_DISCORD_CLIENT_ID --file Dockerfile --tag $HARBOR_URI/abstractolotl/aznopoly-web:${IMAGE_NAME} --tag $HARBOR_URI/abstractolotl/aznopoly-web:latest env: HARBOR_URI: ${{ secrets.HARBOR_URI }} IMAGE_NAME: ${{ steps.image_name.outputs.image }} @@ -41,10 +52,10 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout' # Checkout the repository code. - uses: 'actions/checkout@v3' + uses: 'actions/checkout@v4' - name: Deploy - uses: WyriHaximus/github-action-helm3@v3 + uses: WyriHaximus/github-action-helm3@v4 with: exec: helm upgrade --install --atomic --timeout 5m --history-max 5 --namespace=frontend --set image.tag=${IMAGE_NAME} aznopoly-web helm-charts kubeconfig: '${{ secrets.KUBECONFIG }}' diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index 2074748..2dc0749 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -12,7 +12,7 @@ jobs: outputs: image: ${{ steps.image_name.outputs.image }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Generate image name id: image_name @@ -26,8 +26,19 @@ jobs: HARBOR_PASSWORD: ${{ secrets.HARBOR_PASSWORD }} HARBOR_URI: ${{ secrets.HARBOR_URI }} + - name: Import Secrets + id: import-secrets + uses: hashicorp/vault-action@v3 + with: + url: ${{ secrets.VAULT_ADDR }} + method: userpass + username: ${{ secrets.VAULT_USERNAME }} + password: ${{ secrets.VAULT_PASSWORD }} + secrets: | + applications/data/aznopoly DISCORD_CLIENT_ID | VITE_DISCORD_CLIENT_ID; + - name: Build the Docker image - run: docker buildx build . --file Dockerfile --tag $HARBOR_URI/abstractolotl/aznopoly-web:${IMAGE_NAME} + run: docker buildx build . --build-arg vite_discord_client_id=$VITE_DISCORD_CLIENT_ID --file Dockerfile --tag $HARBOR_URI/abstractolotl/aznopoly-web:${IMAGE_NAME} env: HARBOR_URI: ${{ secrets.HARBOR_URI }} IMAGE_NAME: ${{ steps.image_name.outputs.image }} @@ -41,13 +52,12 @@ jobs: needs: build runs-on: ubuntu-latest if: github.event.pull_request.draft == false && github.event.action != 'closed' && github.event.action != 'merged' && github.event.action != 'converted_to_draft' - steps: - name: 'Checkout' # Checkout the repository code. - uses: 'actions/checkout@v3' + uses: 'actions/checkout@v4' - name: Deploy - uses: WyriHaximus/github-action-helm3@v3 + uses: WyriHaximus/github-action-helm3@v4 with: exec: helm upgrade --install --atomic --timeout 5m --history-max 5 --namespace=frontend --set image.tag=${IMAGE_NAME} --set ingress.domain=${GITHUB_HEAD_REF/\//-}.aznopoly.abstractolotl.de aznopoly-web-${GITHUB_HEAD_REF/\//-} helm-charts kubeconfig: '${{ secrets.KUBECONFIG }}' diff --git a/Dockerfile b/Dockerfile index 55c0419..c322872 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,15 +14,21 @@ COPY --from=install /temp/dev/node_modules node_modules COPY . . ENV NODE_ENV=production +ARG vite_discord_client_id +ENV VITE_DISCORD_CLIENT_ID=$vite_discord_client_id RUN yarn build -COPY assets dist/assets -FROM base AS release -COPY --from=install /temp/dev/node_modules node_modules -COPY --from=prerelease /app/dist/* ./dist -COPY --from=prerelease /app/dist/assets ./dist/assets -COPY --from=prerelease /app/package.json . -RUN yarn global add http-server +FROM nginx:alpine AS release +# Configure Nginx +COPY docker/nginx.conf /etc/nginx/nginx.conf +RUN rm -rf /usr/share/nginx/html/* +# Copy the built app to the html directory +COPY --from=install /temp/dev/node_modules /usr/share/nginx/html/node_modules +COPY --from=prerelease /app/dist/index.html /usr/share/nginx/html/ +COPY --from=prerelease /app/dist/style.css /usr/share/nginx/html/ +COPY --from=prerelease /app/dist/favicon.ico /usr/share/nginx/html/ +COPY --from=prerelease /app/dist/assets /usr/share/nginx/html/assets +COPY --from=prerelease /app/package.json /usr/share/nginx/html/ EXPOSE 8080 -CMD [ "http-server", "dist" ] \ No newline at end of file +ENTRYPOINT ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/docker/nginx.conf b/docker/nginx.conf new file mode 100644 index 0000000..49fc2a8 --- /dev/null +++ b/docker/nginx.conf @@ -0,0 +1,14 @@ +worker_processes 4; +events { worker_connections 1024; } + +http { + server { + listen 8080; + root /usr/share/nginx/html; + include /etc/nginx/mime.types; + + location / { + try_files $uri $uri/ /index.html; + } + } +} \ No newline at end of file diff --git a/package.json b/package.json index ed36ad3..6a501e1 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "preview": "vite preview" }, "dependencies": { + "@discord/embedded-app-sdk": "^1.1.2", "@types/color-convert": "^2.0.3", "@types/seedrandom": "^3.0.8", "babylonjs": "^7.3.0", diff --git a/src/client.ts b/src/client.ts index db48b8c..5e2c32a 100644 --- a/src/client.ts +++ b/src/client.ts @@ -23,13 +23,22 @@ export default class AzNopolyClient extends EventTarget { } this.state = ClientState.CONNECTING; - this.socket = new WebSocket("wss://" + BASE_URL + "/room/" + roomId) + this.socket = new WebSocket("wss://" + this.getBaseUrl() + "/room/" + roomId) this.socket.addEventListener("open", this.onOpen.bind(this)) this.socket.addEventListener("close", this.onClose.bind(this)) this.socket.addEventListener("message", this.onMessage.bind(this)) } + private getBaseUrl() { + const params = new URLSearchParams(window.location.search); + if (params.get('frame_id') !== null) { + // Discord rooting is different + return location.host + "/server"; + } + return BASE_URL; + } + private publishClientEvent(event: PacketType, data: ClientPacket) { this.dispatchEvent(new CustomEvent(event, { detail: data })); } diff --git a/src/game.ts b/src/game.ts index e8ff501..f35822c 100644 --- a/src/game.ts +++ b/src/game.ts @@ -24,8 +24,12 @@ export default class AzNopolyGame { this._client.addEventListener(PacketType.ROOM_INIT, ((event: CustomEvent) => { const uuid = event.detail.data.uuid; + let userName = localStorage.getItem("playerName"); + if (sessionStorage.getItem('discordName') !== null) { + userName = sessionStorage.getItem('discordName'); + } this.setProfile(uuid, { - name: localStorage.getItem("playerName") || "Player", + name: userName || "Player", colorIndex: parseInt(localStorage.getItem("playerColor") || "0"), avatar: localStorage.getItem("playerAvatar") as Avatars || Avatars.AXOLOTL, host: uuid === event.detail.data.room.host, diff --git a/src/main.ts b/src/main.ts index 948555a..b858944 100644 --- a/src/main.ts +++ b/src/main.ts @@ -17,6 +17,8 @@ import * as THREE from 'three'; //import * as WebGLDebugUtils from './webgl-debug.js'; import DebugScene from './phaser/scenes/debug-scene.js'; +import {DiscordClient} from "@/util/discord.ts"; +import {RoomEvent} from "@/room.ts"; window.onload = () => { setTimeout(async () => { @@ -45,7 +47,7 @@ window.onload = () => { physics: { default: 'arcade', arcade: { - gravity: { y: 0 }, + gravity: { y: 0, x: 0 }, debug: true } }, @@ -80,10 +82,19 @@ window.onload = () => { const params = new URLSearchParams(window.location.search); const debug = params.get('debug'); + if (debug !== null) { console.log('Debug mode enabled', debug); mock(aznopoly); game.scene.start(debug || 'lobby'); + } else if (params.get('frame_id') !== null) { + let discordClient = new DiscordClient(); + await discordClient.handleAuthentication(); + + aznopoly.init(discordClient.getRoomId()) + aznopoly.room.addEventListener(RoomEvent.READY, () => { + game.scene.start('lobby') + }, { once: true }); } else { game.scene.start('title'); } diff --git a/src/phaser/components/ui/avatar.ts b/src/phaser/components/ui/avatar.ts index 9aadc2e..9e7b298 100644 --- a/src/phaser/components/ui/avatar.ts +++ b/src/phaser/components/ui/avatar.ts @@ -31,6 +31,7 @@ export default class AzNopolyAvatar extends Phaser.GameObjects.Container { constructor(scene: Phaser.Scene, x: number, y: number, size: number, avatar: Avatars, colorIndex: number) { super(scene, x, y); + this.colorIndex = colorIndex; this.scene = scene; diff --git a/src/phaser/components/ui/input-field.ts b/src/phaser/components/ui/input-field.ts index d649904..14dc635 100644 --- a/src/phaser/components/ui/input-field.ts +++ b/src/phaser/components/ui/input-field.ts @@ -59,6 +59,10 @@ export default class AzNopolyInput extends Phaser.GameObjects.Container { this.add(this.graphics); } + public setDisabled(value: boolean) { + this.inputDom.disabled = value; + } + public getValue() { return this.inputDom.value; } @@ -69,6 +73,7 @@ export default class AzNopolyInput extends Phaser.GameObjects.Container { public setChangeListener(callback: (value: string) => void) { this.inputDom.addEventListener("input", () => { + if (this.inputDom.disabled) return; callback(this.inputDom.value); }); } diff --git a/src/phaser/components/ui/lobby/profile-customization-panel.ts b/src/phaser/components/ui/lobby/profile-customization-panel.ts index 1153ef4..a8dc01a 100644 --- a/src/phaser/components/ui/lobby/profile-customization-panel.ts +++ b/src/phaser/components/ui/lobby/profile-customization-panel.ts @@ -110,6 +110,9 @@ export default class ProfileCustomizationPanel extends AzNopolyPanel { labelName.setOrigin(1, 0.5); this.inputName = new AzNopolyInput(scene, bounds.x + bounds.width * 0.5, labelName.y, 200, 40, "text"); + if (sessionStorage.getItem("discordName") !== null) { + this.inputName.setDisabled(true) + } this.inputName.setPosition(this.inputName.x, this.inputName.y - this.inputName.height * 0.5); this.inputName.setValue(this.profile.name); this.inputName.setChangeListener((value) => { diff --git a/src/phaser/components/ui/player-list.ts b/src/phaser/components/ui/player-list.ts index a37c359..f29ddbb 100644 --- a/src/phaser/components/ui/player-list.ts +++ b/src/phaser/components/ui/player-list.ts @@ -64,7 +64,7 @@ export default class PlayerList extends AzNopolyPanel { public updatePlayerList(players: PlayerProfile[]) { const newEntries: Phaser.GameObjects.Container[] = []; - const oldEntries = this.playerEntries;; + const oldEntries = this.playerEntries; oldEntries.forEach(entry => { entry.destroy(); }); @@ -90,5 +90,4 @@ export default class PlayerList extends AzNopolyPanel { this.setHeadline(`CONNECTED PLAYERS (${num} / 4)`); } - } \ No newline at end of file diff --git a/src/phaser/scenes/lobby-scene-controller.ts b/src/phaser/scenes/lobby-scene-controller.ts index 425d74f..ae793c8 100644 --- a/src/phaser/scenes/lobby-scene-controller.ts +++ b/src/phaser/scenes/lobby-scene-controller.ts @@ -1,7 +1,7 @@ import { PLAYER_COLORS } from "@/style"; import AzNopolyGame from "../../game"; -import { RoomEvent } from "../../room"; -import { SceneSwitcher } from "../../util/scene-switcher"; +import { RoomEvent } from "@/room.ts"; +import { SceneSwitcher } from "@/util/scene-switcher.ts"; import { PlayerProfile } from "../components/ui/player-info"; import NetworkSceneController from "./base/base-scene-controller"; import LobbyScene from "./lobby-scene"; diff --git a/src/phaser/scenes/lobby-scene.ts b/src/phaser/scenes/lobby-scene.ts index 8f89257..60947a9 100644 --- a/src/phaser/scenes/lobby-scene.ts +++ b/src/phaser/scenes/lobby-scene.ts @@ -1,4 +1,4 @@ -import { FONT_STYLE_PANEL_HEADLINE, PLAYER_COLORS } from "../../style"; +import { FONT_STYLE_PANEL_HEADLINE, PLAYER_COLORS } from "@/style.ts"; import TilingBackground from "../components/ui/tiling-background"; import { AzNopolyButton } from "../components/ui/button"; @@ -18,6 +18,7 @@ export default class LobbyScene extends BaseScene { preload() { ProfileCustomizationPanel.preload(this); PlayerList.preload(this); + AzNopolyButton.preload(this); this.load.image('host_crown', 'assets/crown.png'); this.load.image('lobby_bg', 'assets/lobby_background.png'); } @@ -29,7 +30,7 @@ export default class LobbyScene extends BaseScene { create() { this.cameras.main.fadeIn(100); this.add.existing(new TilingBackground(this, 'lobby_bg', new Phaser.Math.Vector2(2, 1), 35, 1.75)); - this.add.text(0, 0, `Lobby ( ${this.aznopoly.room.id} )`, FONT_STYLE_PANEL_HEADLINE); + this.add.text(0, 0, `Lobby ( ${this.aznopoly.room.getName()} )`, FONT_STYLE_PANEL_HEADLINE); const totalWidth = PlayerList.WIDTH + ProfileCustomizationPanel.WIDTH + 20; this.playerList = new PlayerList(this, this.aznopoly.isHost, SETTINGS.DISPLAY_WIDTH * 0.5 - totalWidth * 0.5 + PlayerList.WIDTH * 0.5, SETTINGS.DISPLAY_HEIGHT * 0.5); diff --git a/src/room.ts b/src/room.ts index 4451344..24bdb82 100644 --- a/src/room.ts +++ b/src/room.ts @@ -31,6 +31,10 @@ export default class Room extends EventTarget { this.client.addEventListener(PacketType.ROOM_LEAVE, this.onRoomLeave.bind(this) as EventListener); } + public getName() { + return sessionStorage.getItem('discordChannel') || this.id; + } + public lockRoom() { this.locked = true; } diff --git a/src/util/discord.ts b/src/util/discord.ts new file mode 100644 index 0000000..9c89afd --- /dev/null +++ b/src/util/discord.ts @@ -0,0 +1,169 @@ +import {DiscordSDK, DiscordSDKMock, Types} from '@discord/embedded-app-sdk'; + +const queryParams = new URLSearchParams(window.location.search); + +export class DiscordClient { + private discordSdk: DiscordSDK | DiscordSDKMock; + + constructor() { + if(import.meta.env.VITE_DISCORD_CLIENT_ID === undefined) { + throw new Error('Client ID is not defined'); + } + + this.discordSdk = new DiscordSDK(import.meta.env.VITE_DISCORD_CLIENT_ID); + } + + async handleAuthentication() { + await this.discordSdk.ready() + + const { code} = await this.discordSdk.commands.authorize({ + client_id: import.meta.env.VITE_DISCORD_CLIENT_ID, + response_type: 'code', + state: '', + prompt: 'none', + scope: [ + // "applications.builds.upload", + // "applications.builds.read", + // "applications.store.update", + // "applications.entitlements", + // "bot", + 'identify', + // "connections", + // "email", + // "gdm.join", + 'guilds', + // "guilds.join", + "guilds.members.read", + // "messages.read", + // "relationships.read", + // 'rpc.activities.write', + // "rpc.notifications.read", + // "rpc.voice.write", + 'rpc.voice.read', + // "webhook.incoming", + ], + }); + + const response = await fetch('/server/token', { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({code}), + }); + const {access_token} = await response.json(); + + let auth = await this.discordSdk.commands.authenticate({ + access_token, + }); + + if (auth === null) { + throw new Error('Authentication failed'); + } + + const guildMember: IGuildsMembersRead | null = await fetch( + `/discord/api/users/@me/guilds/${this.discordSdk.guildId}/member`, + { + method: 'get', + headers: {Authorization: `Bearer ${access_token}`}, + }, + ) + .then((j) => j.json()) + .catch(() => { + return null; + }); + + sessionStorage.setItem('discordName', this.getUsername({guildMember: guildMember, user: auth.user})) + sessionStorage.setItem('discordAvatar', this.getAvatar({guildMember: guildMember, user: auth.user})) + sessionStorage.setItem('discordChannel', await this.getChannelName()) + } + + public getRoomId() { + return this.discordSdk.instanceId.slice(2, 8) + } + + private getAvatar({guildMember, user}: GetUserDisplayNameArgs) { + let guildAvatarSrc = ''; + if (guildMember?.avatar) { + guildAvatarSrc = `https://cdn.discordapp.com/guilds/${this.discordSdk.guildId}/users/${user.id}/avatars/${guildMember.avatar}.png?size=256`; + } else if (user.avatar) { + guildAvatarSrc = `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png?size=256`; + } else { + const defaultAvatarIndex = Math.abs(Number(user.id) >> 22) % 6; + guildAvatarSrc = `https://cdn.discordapp.com/embed/avatars/${defaultAvatarIndex}.png`; + } + return guildAvatarSrc; + } + + private getUsername({guildMember, user}: GetUserDisplayNameArgs) { + if (guildMember?.nick != null && guildMember.nick !== '') return guildMember.nick; + + if (user.discriminator !== '0') return `${user.username}#${user.discriminator}`; + + if (user.global_name != null && user.global_name !== '') return user.global_name; + + return user.username ?? 'Player'; + } + + async getChannelName() { + let activityChannel = 'unknown'; + + if (this.discordSdk.channelId != null && this.discordSdk.guildId != null) { + const channel = await this.discordSdk.commands.getChannel({channel_id: this.discordSdk.channelId}); + if (channel.name != null) { + activityChannel = channel.name; + } + } + + return activityChannel; + } + + private getOverrideOrRandomSessionValue(queryParam: `${SessionStorageQueryParam}`) { + const overrideValue = queryParams.get(queryParam); + if (overrideValue != null) { + return overrideValue; + } + + const currentStoredValue = sessionStorage.getItem(queryParam); + if (currentStoredValue != null) { + return currentStoredValue; + } + + // Set queryParam to a random 8-character string + const randomString = Math.random().toString(36).slice(2, 10); + sessionStorage.setItem(queryParam, randomString); + return randomString; + } +} + +enum SessionStorageQueryParam { + user_id = 'user_id', + guild_id = 'guild_id', + channel_id = 'channel_id', +} + +interface GetUserDisplayNameArgs { + guildMember: IGuildsMembersRead | null; + user: Partial; +} + +export interface IGuildsMembersRead { + roles: string[]; + nick: string | null; + avatar: string | null; + premium_since: string | null; + joined_at: string; + is_pending: boolean; + pending: boolean; + communication_disabled_until: string | null; + user: { + id: string; + username: string; + avatar: string | null; + discriminator: string; + public_flags: number; + }; + mute: boolean; + deaf: boolean; +} \ No newline at end of file diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index 11f02fe..6b6e543 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -1 +1,8 @@ /// +interface ImportMetaEnv { + readonly VITE_DISCORD_CLIENT_ID: string +} + +interface ImportMeta { + readonly env: ImportMetaEnv +} \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts index 92e097d..60bf6d3 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,13 +1,12 @@ -import { fileURLToPath } from 'node:url'; +import {fileURLToPath} from 'node:url'; export default { - - resolve: { - alias: [ - { - find: '@', - replacement: fileURLToPath(new URL('./src', import.meta.url)) - }, - ], - }, + resolve: { + alias: [ + { + find: '@', + replacement: fileURLToPath(new URL('./src', import.meta.url)) + }, + ], + }, }; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 7e28c07..4361fe4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,7 +23,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz" integrity sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ== -"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9", "@babel/core@^7.8.0", "@babel/core@>=7.0.0-beta.0 <8": +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9": version "7.24.4" resolved "https://registry.npmjs.org/@babel/core/-/core-7.24.4.tgz" integrity sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg== @@ -387,11 +387,136 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@discord/embedded-app-sdk@^1.1.2": + version "1.1.2" + resolved "https://registry.npmjs.org/@discord/embedded-app-sdk/-/embedded-app-sdk-1.1.2.tgz" + integrity sha512-7m3G0QOYq2T44krit4pUBrB35qhmo8Zthb+NNdEFIn5nW9CwMuvcVIjIqjvxK9Y8XYjhzfYkAVm0d9MzHv/3rQ== + dependencies: + "@types/lodash.transform" "^4.6.6" + "@types/uuid" "^8.3.1" + big-integer "1.6.48" + decimal.js-light "2.5.0" + eventemitter3 "^4.0.7" + lodash.transform "^4.6.0" + rollup "^4.8.0" + uuid "^8.3.2" + zod "^3.9.8" + +"@esbuild/aix-ppc64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537" + integrity sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g== + +"@esbuild/android-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz#db1c9202a5bc92ea04c7b6840f1bbe09ebf9e6b9" + integrity sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg== + +"@esbuild/android-arm@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz#3b488c49aee9d491c2c8f98a909b785870d6e995" + integrity sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w== + +"@esbuild/android-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz#3b1628029e5576249d2b2d766696e50768449f98" + integrity sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg== + "@esbuild/darwin-arm64@0.20.2": version "0.20.2" resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz" integrity sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA== +"@esbuild/darwin-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz#90ed098e1f9dd8a9381695b207e1cff45540a0d0" + integrity sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA== + +"@esbuild/freebsd-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz#d71502d1ee89a1130327e890364666c760a2a911" + integrity sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw== + +"@esbuild/freebsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz#aa5ea58d9c1dd9af688b8b6f63ef0d3d60cea53c" + integrity sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw== + +"@esbuild/linux-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz#055b63725df678379b0f6db9d0fa85463755b2e5" + integrity sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A== + +"@esbuild/linux-arm@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz#76b3b98cb1f87936fbc37f073efabad49dcd889c" + integrity sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg== + +"@esbuild/linux-ia32@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz#c0e5e787c285264e5dfc7a79f04b8b4eefdad7fa" + integrity sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig== + +"@esbuild/linux-loong64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz#a6184e62bd7cdc63e0c0448b83801001653219c5" + integrity sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ== + +"@esbuild/linux-mips64el@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz#d08e39ce86f45ef8fc88549d29c62b8acf5649aa" + integrity sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA== + +"@esbuild/linux-ppc64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz#8d252f0b7756ffd6d1cbde5ea67ff8fd20437f20" + integrity sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg== + +"@esbuild/linux-riscv64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz#19f6dcdb14409dae607f66ca1181dd4e9db81300" + integrity sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg== + +"@esbuild/linux-s390x@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz#3c830c90f1a5d7dd1473d5595ea4ebb920988685" + integrity sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ== + +"@esbuild/linux-x64@0.20.2": + version "0.20.2" + resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz" + integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw== + +"@esbuild/netbsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz#e771c8eb0e0f6e1877ffd4220036b98aed5915e6" + integrity sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ== + +"@esbuild/openbsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz#9a795ae4b4e37e674f0f4d716f3e226dd7c39baf" + integrity sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ== + +"@esbuild/sunos-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz#7df23b61a497b8ac189def6e25a95673caedb03f" + integrity sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w== + +"@esbuild/win32-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz#f1ae5abf9ca052ae11c1bc806fb4c0f519bacf90" + integrity sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ== + +"@esbuild/win32-ia32@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz#241fe62c34d8e8461cd708277813e1d0ba55ce23" + integrity sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ== + +"@esbuild/win32-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz#9c907b21e30a52db959ba4f80bb01a0cc403d5cc" + integrity sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ== + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz" @@ -588,7 +713,7 @@ slash "^3.0.0" write-file-atomic "^4.0.2" -"@jest/types@^29.0.0", "@jest/types@^29.6.3": +"@jest/types@^29.6.3": version "29.6.3" resolved "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz" integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== @@ -624,6 +749,14 @@ resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz" @@ -632,19 +765,86 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" +"@rollup/rollup-android-arm-eabi@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.16.4.tgz#5e8930291f1e5ead7fb1171d53ba5c87718de062" + integrity sha512-GkhjAaQ8oUTOKE4g4gsZ0u8K/IHU1+2WQSgS1TwTcYvL+sjbaQjNHFXbOJ6kgqGHIO1DfUhI/Sphi9GkRT9K+Q== + +"@rollup/rollup-android-arm64@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.16.4.tgz#ffb84f1359c04ec8a022a97110e18a5600f5f638" + integrity sha512-Bvm6D+NPbGMQOcxvS1zUl8H7DWlywSXsphAeOnVeiZLQ+0J6Is8T7SrjGTH29KtYkiY9vld8ZnpV3G2EPbom+w== "@rollup/rollup-darwin-arm64@4.16.4": version "4.16.4" - resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.16.4.tgz" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.16.4.tgz#b2fcee8d4806a0b1b9185ac038cc428ddedce9f4" integrity sha512-i5d64MlnYBO9EkCOGe5vPR/EeDwjnKOGGdd7zKFhU5y8haKhQZTN2DgVtpODDMxUr4t2K90wTUJg7ilgND6bXw== +"@rollup/rollup-darwin-x64@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.16.4.tgz#fcb25ccbaa3dd33a6490e9d1c64bab2e0e16b932" + integrity sha512-WZupV1+CdUYehaZqjaFTClJI72fjJEgTXdf4NbW69I9XyvdmztUExBtcI2yIIU6hJtYvtwS6pkTkHJz+k08mAQ== + +"@rollup/rollup-linux-arm-gnueabihf@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.16.4.tgz#40d46bdfe667e5eca31bf40047460e326d2e26bb" + integrity sha512-ADm/xt86JUnmAfA9mBqFcRp//RVRt1ohGOYF6yL+IFCYqOBNwy5lbEK05xTsEoJq+/tJzg8ICUtS82WinJRuIw== + +"@rollup/rollup-linux-arm-musleabihf@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.16.4.tgz#7741df2448c11c56588b50835dbfe91b1a10b375" + integrity sha512-tJfJaXPiFAG+Jn3cutp7mCs1ePltuAgRqdDZrzb1aeE3TktWWJ+g7xK9SNlaSUFw6IU4QgOxAY4rA+wZUT5Wfg== + +"@rollup/rollup-linux-arm64-gnu@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.16.4.tgz#0a23b02d2933e4c4872ad18d879890b6a4a295df" + integrity sha512-7dy1BzQkgYlUTapDTvK997cgi0Orh5Iu7JlZVBy1MBURk7/HSbHkzRnXZa19ozy+wwD8/SlpJnOOckuNZtJR9w== + +"@rollup/rollup-linux-arm64-musl@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.16.4.tgz#e37ef259358aa886cc07d782220a4fb83c1e6970" + integrity sha512-zsFwdUw5XLD1gQe0aoU2HVceI6NEW7q7m05wA46eUAyrkeNYExObfRFQcvA6zw8lfRc5BHtan3tBpo+kqEOxmg== + +"@rollup/rollup-linux-powerpc64le-gnu@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.16.4.tgz#8c69218b6de05ee2ba211664a2d2ac1e54e43f94" + integrity sha512-p8C3NnxXooRdNrdv6dBmRTddEapfESEUflpICDNKXpHvTjRRq1J82CbU5G3XfebIZyI3B0s074JHMWD36qOW6w== + +"@rollup/rollup-linux-riscv64-gnu@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.16.4.tgz#d32727dab8f538d9a4a7c03bcf58c436aecd0139" + integrity sha512-Lh/8ckoar4s4Id2foY7jNgitTOUQczwMWNYi+Mjt0eQ9LKhr6sK477REqQkmy8YHY3Ca3A2JJVdXnfb3Rrwkng== + +"@rollup/rollup-linux-s390x-gnu@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.16.4.tgz#d46097246a187d99fc9451fe8393b7155b47c5ec" + integrity sha512-1xwwn9ZCQYuqGmulGsTZoKrrn0z2fAur2ujE60QgyDpHmBbXbxLaQiEvzJWDrscRq43c8DnuHx3QorhMTZgisQ== + +"@rollup/rollup-linux-x64-gnu@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.16.4.tgz#6356c5a03a4afb1c3057490fc51b4764e109dbc7" + integrity sha512-LuOGGKAJ7dfRtxVnO1i3qWc6N9sh0Em/8aZ3CezixSTM+E9Oq3OvTsvC4sm6wWjzpsIlOCnZjdluINKESflJLA== + +"@rollup/rollup-linux-x64-musl@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.16.4.tgz#03a5831a9c0d05877b94653b5ddd3020d3c6fb06" + integrity sha512-ch86i7KkJKkLybDP2AtySFTRi5fM3KXp0PnHocHuJMdZwu7BuyIKi35BE9guMlmTpwwBTB3ljHj9IQXnTCD0vA== + +"@rollup/rollup-win32-arm64-msvc@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.16.4.tgz#6cc0db57750376b9303bdb6f5482af8974fcae35" + integrity sha512-Ma4PwyLfOWZWayfEsNQzTDBVW8PZ6TUUN1uFTBQbF2Chv/+sjenE86lpiEwj2FiviSmSZ4Ap4MaAfl1ciF4aSA== + +"@rollup/rollup-win32-ia32-msvc@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.16.4.tgz#aea0b7e492bd9ed46971cb80bc34f1eb14e07789" + integrity sha512-9m/ZDrQsdo/c06uOlP3W9G2ENRVzgzbSXmXHT4hwVaDQhYcRpi9bgBT0FTG9OhESxwK0WjQxYOSfv40cU+T69w== + +"@rollup/rollup-win32-x64-msvc@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.16.4.tgz#c09ad9a132ccb5a67c4f211d909323ab1294f95f" + integrity sha512-YunpoOAyGLDseanENHmbFvQSfVL5BxW3k7hhy0eN4rb3gS/ct75dVD0EXOWIqFT/nE8XYW6LP6vz6ctKRi0k9A== + "@sinclair/typebox@^0.27.8": version "0.27.8" resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz" @@ -773,7 +973,19 @@ expect "^29.0.0" pretty-format "^29.0.0" -"@types/node@*", "@types/node@^18.0.0 || >=20.0.0": +"@types/lodash.transform@^4.6.6": + version "4.6.9" + resolved "https://registry.npmjs.org/@types/lodash.transform/-/lodash.transform-4.6.9.tgz" + integrity sha512-1iIn+l7Vrj8hsr2iZLtxRkcV9AtjTafIyxKO9DX2EEcdOgz3Op5dhwKQFhMJgdfIRbYHBUF+SU97Y6P+zyLXNg== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*": + version "4.17.0" + resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz" + integrity sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA== + +"@types/node@*": version "20.12.7" resolved "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz" integrity sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg== @@ -806,6 +1018,11 @@ fflate "~0.8.2" meshoptimizer "~0.18.1" +"@types/uuid@^8.3.1": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" + integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== + "@types/webxr@*": version "0.5.15" resolved "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.15.tgz" @@ -884,7 +1101,7 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -babel-jest@^29.0.0, babel-jest@^29.7.0: +babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz" integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== @@ -954,6 +1171,11 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +big-integer@1.6.48: + version "1.6.48" + resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz" + integrity sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" @@ -969,7 +1191,7 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.22.2, "browserslist@>= 4.21.0": +browserslist@^4.22.2: version "4.23.0" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz" integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== @@ -1083,16 +1305,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - color-name@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" @@ -1137,6 +1359,11 @@ debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: dependencies: ms "2.1.2" +decimal.js-light@2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.0.tgz#ca7faf504c799326df94b0ab920424fdfc125348" + integrity sha512-b3VJCbd2hwUpeRGG3Toob+CRo8W22xplipNhP3tN7TSVB/cyMX71P1vM2Xjc9H74uV6dS2hDDmo/rHq8L87Upg== + dedent@^1.0.0: version "1.5.3" resolved "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz" @@ -1233,6 +1460,11 @@ esprima@^4.0.0: resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== +eventemitter3@^4.0.7: + version "4.0.7" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + eventemitter3@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz" @@ -1269,7 +1501,7 @@ expect@^29.0.0, expect@^29.7.0: jest-message-util "^29.7.0" jest-util "^29.7.0" -fast-json-stable-stringify@^2.1.0, fast-json-stable-stringify@2.x: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -1705,7 +1937,7 @@ jest-resolve-dependencies@^29.7.0: jest-regex-util "^29.6.3" jest-snapshot "^29.7.0" -jest-resolve@*, jest-resolve@^29.7.0: +jest-resolve@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz" integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== @@ -1849,7 +2081,7 @@ jest-worker@^29.7.0: merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^29.0.0, jest@^29.7.0: +jest@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz" integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== @@ -1914,6 +2146,11 @@ lodash.memoize@4.x: resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz" integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== +lodash.transform@^4.6.0: + version "4.6.0" + resolved "https://registry.npmjs.org/lodash.transform/-/lodash.transform-4.6.0.tgz" + integrity sha512-LO37ZnhmBVx0GvOU/caQuipEh4GN82TcWv3yHlebGDgOxbxiwwzW5Pcx2AcvpIv2WmvmSMoC492yQFNhy/l/UQ== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" @@ -1935,7 +2172,7 @@ make-dir@^4.0.0: dependencies: semver "^7.5.3" -make-error@^1.1.1, make-error@1.x: +make-error@1.x, make-error@^1.1.1: version "1.3.6" resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== @@ -2180,9 +2417,9 @@ resolve@^1.20.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -rollup@^4.13.0: +rollup@^4.13.0, rollup@^4.8.0: version "4.16.4" - resolved "https://registry.npmjs.org/rollup/-/rollup-4.16.4.tgz" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.16.4.tgz#fe328eb41293f20c9593a095ec23bdc4b5d93317" integrity sha512-kuaTJSUbz+Wsb2ATGvEknkI12XV40vIiHmLuFlejoo7HtDok/O5eDDD0UpCVY5bBX5U5RYo8wWP83H7ZsqVEnA== dependencies: "@types/estree" "1.0.5" @@ -2215,14 +2452,7 @@ semver@^6.3.0, semver@^6.3.1: resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.5.3: - version "7.6.0" - resolved "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz" - integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== - dependencies: - lru-cache "^6.0.0" - -semver@^7.5.4: +semver@^7.5.3, semver@^7.5.4: version "7.6.0" resolved "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz" integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== @@ -2396,7 +2626,7 @@ ts-jest@^29.1.1: semver "^7.5.3" yargs-parser "^21.0.1" -ts-node@^10.9.2, ts-node@>=9.0.0: +ts-node@^10.9.2: version "10.9.2" resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz" integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== @@ -2425,7 +2655,7 @@ type-fest@^0.21.3: resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -typescript@^5.2.2, typescript@>=2.7, "typescript@>=4.3 <6": +typescript@^5.2.2: version "5.4.5" resolved "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz" integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== @@ -2443,6 +2673,11 @@ update-browserslist-db@^1.0.13: escalade "^3.1.1" picocolors "^1.0.0" +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz" @@ -2546,3 +2781,8 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zod@^3.9.8: + version "3.23.0" + resolved "https://registry.npmjs.org/zod/-/zod-3.23.0.tgz" + integrity sha512-OFLT+LTocvabn6q76BTwVB0hExEBS0IduTr3cqZyMqEDbOnYmcU+y0tUAYbND4uwclpBGi4I4UUBGzylWpjLGA==