diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..0a65c24
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+public/background-images/*.jpg filter=lfs diff=lfs merge=lfs -text
diff --git a/.github/assets/template-dark.webp b/.github/assets/template-dark.webp
new file mode 100644
index 0000000..3de98a9
Binary files /dev/null and b/.github/assets/template-dark.webp differ
diff --git a/.github/assets/template-light.webp b/.github/assets/template-light.webp
new file mode 100644
index 0000000..e8bee3f
Binary files /dev/null and b/.github/assets/template-light.webp differ
diff --git a/.github/workflows/sync-to-production.yaml b/.github/workflows/sync-to-production.yaml
index 03acb19..3922a1b 100644
--- a/.github/workflows/sync-to-production.yaml
+++ b/.github/workflows/sync-to-production.yaml
@@ -1,33 +1,16 @@
+# .github/workflows/sync-to-production.yaml
name: Sync main to sandbox-production
on:
- push:
- branches:
- - main
-
-permissions:
- contents: write
- pull-requests: write
+ workflow_dispatch:
jobs:
sync:
runs-on: ubuntu-latest
-
+ permissions:
+ contents: write
steps:
- - name: Checkout code
- uses: actions/checkout@v4
+ - uses: livekit-examples/sandbox-deploy-action@v1
with:
- fetch-depth: 0 # Fetch all history so we can force push
-
- - name: Set up Git
- run: |
- git config --global user.name 'github-actions[bot]'
- git config --global user.email 'github-actions[bot]@livekit.io'
-
- - name: Sync to sandbox-production
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: |
- git checkout sandbox-production || git checkout -b sandbox-production
- git merge --strategy-option theirs main
- git push origin sandbox-production
+ production_branch: 'sandbox-production'
+ token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
new file mode 100644
index 0000000..aab838e
--- /dev/null
+++ b/.github/workflows/test.yaml
@@ -0,0 +1,32 @@
+name: Test
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+
+permissions:
+ contents: read
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+ - uses: pnpm/action-setup@v4
+ - name: Use Node.js 22
+ uses: actions/setup-node@v4
+ with:
+ node-version: 24
+ cache: 'pnpm'
+
+ - name: Install dependencies
+ run: pnpm install
+
+ - name: ESLint
+ run: pnpm lint
+
+ - name: Prettier
+ run: pnpm format:check
+
+ - name: Run Tests
+ run: pnpm test
diff --git a/app/api/connection-details/route.ts b/app/api/connection-details/route.ts
index ff3f963..6c150d8 100644
--- a/app/api/connection-details/route.ts
+++ b/app/api/connection-details/route.ts
@@ -1,4 +1,5 @@
import { randomString } from '@/lib/client-utils';
+import { getLiveKitURL } from '@/lib/getLiveKitURL';
import { ConnectionDetails } from '@/lib/types';
import { AccessToken, AccessTokenOptions, VideoGrant } from 'livekit-server-sdk';
import { NextRequest, NextResponse } from 'next/server';
@@ -6,6 +7,7 @@ import { NextRequest, NextResponse } from 'next/server';
const API_KEY = process.env.LIVEKIT_API_KEY;
const API_SECRET = process.env.LIVEKIT_API_SECRET;
const LIVEKIT_URL = process.env.LIVEKIT_URL;
+
const COOKIE_KEY = 'random-participant-postfix';
export async function GET(request: NextRequest) {
@@ -15,7 +17,10 @@ export async function GET(request: NextRequest) {
const participantName = request.nextUrl.searchParams.get('participantName');
const metadata = request.nextUrl.searchParams.get('metadata') ?? '';
const region = request.nextUrl.searchParams.get('region');
- const livekitServerUrl = region ? getLiveKitURL(region) : LIVEKIT_URL;
+ if (!LIVEKIT_URL) {
+ throw new Error('LIVEKIT_URL is not defined');
+ }
+ const livekitServerUrl = region ? getLiveKitURL(LIVEKIT_URL, region) : LIVEKIT_URL;
let randomParticipantPostfix = request.cookies.get(COOKIE_KEY)?.value;
if (livekitServerUrl === undefined) {
throw new Error('Invalid region');
@@ -75,21 +80,6 @@ function createParticipantToken(userInfo: AccessTokenOptions, roomName: string)
return at.toJwt();
}
-/**
- * Get the LiveKit server URL for the given region.
- */
-function getLiveKitURL(region: string | null): string {
- let targetKey = 'LIVEKIT_URL';
- if (region) {
- targetKey = `LIVEKIT_URL_${region}`.toUpperCase();
- }
- const url = process.env[targetKey];
- if (!url) {
- throw new Error(`${targetKey} is not defined`);
- }
- return url;
-}
-
function getCookieExpirationTime(): string {
var now = new Date();
var time = now.getTime();
diff --git a/app/custom/VideoConferenceClientImpl.tsx b/app/custom/VideoConferenceClientImpl.tsx
index 02b779c..cd7f77a 100644
--- a/app/custom/VideoConferenceClientImpl.tsx
+++ b/app/custom/VideoConferenceClientImpl.tsx
@@ -1,6 +1,6 @@
'use client';
-import { formatChatMessageLinks, LiveKitRoom, VideoConference } from '@livekit/components-react';
+import { formatChatMessageLinks, RoomContext, VideoConference } from '@livekit/components-react';
import {
ExternalE2EEKeyProvider,
LogLevel,
@@ -11,23 +11,24 @@ import {
type VideoCodec,
} from 'livekit-client';
import { DebugMode } from '@/lib/Debug';
-import { useMemo } from 'react';
-import { decodePassphrase } from '@/lib/client-utils';
+import { useEffect, useMemo, useState } from 'react';
+import { KeyboardShortcuts } from '@/lib/KeyboardShortcuts';
import { SettingsMenu } from '@/lib/SettingsMenu';
+import { useSetupE2EE } from '@/lib/useSetupE2EE';
+import { useLowCPUOptimizer } from '@/lib/usePerfomanceOptimiser';
export function VideoConferenceClientImpl(props: {
liveKitUrl: string;
token: string;
codec: VideoCodec | undefined;
+ singlePeerConnection: boolean | undefined;
}) {
- const worker =
- typeof window !== 'undefined' &&
- new Worker(new URL('livekit-client/e2ee-worker', import.meta.url));
const keyProvider = new ExternalE2EEKeyProvider();
-
- const e2eePassphrase =
- typeof window !== 'undefined' ? decodePassphrase(window.location.hash.substring(1)) : undefined;
+ const { worker, e2eePassphrase } = useSetupE2EE();
const e2eeEnabled = !!(e2eePassphrase && worker);
+
+ const [e2eeSetupComplete, setE2eeSetupComplete] = useState(false);
+
const roomOptions = useMemo((): RoomOptions => {
return {
publishDefaults: {
@@ -43,36 +44,55 @@ export function VideoConferenceClientImpl(props: {
worker,
}
: undefined,
+ singlePeerConnection: props.singlePeerConnection,
};
- }, []);
+ }, [e2eeEnabled, props.codec, keyProvider, worker]);
+
+ const room = useMemo(() => new Room(roomOptions), [roomOptions]);
- const room = useMemo(() => new Room(roomOptions), []);
- if (e2eeEnabled) {
- keyProvider.setKey(e2eePassphrase);
- room.setE2EEEnabled(true);
- }
const connectOptions = useMemo((): RoomConnectOptions => {
return {
autoSubscribe: true,
};
}, []);
+ useEffect(() => {
+ if (e2eeEnabled) {
+ keyProvider.setKey(e2eePassphrase).then(() => {
+ room.setE2EEEnabled(true).then(() => {
+ setE2eeSetupComplete(true);
+ });
+ });
+ } else {
+ setE2eeSetupComplete(true);
+ }
+ }, [e2eeEnabled, e2eePassphrase, keyProvider, room, setE2eeSetupComplete]);
+
+ useEffect(() => {
+ if (e2eeSetupComplete) {
+ room.connect(props.liveKitUrl, props.token, connectOptions).catch((error) => {
+ console.error(error);
+ });
+ room.localParticipant.enableCameraAndMicrophone().catch((error) => {
+ console.error(error);
+ });
+ }
+ }, [room, props.liveKitUrl, props.token, connectOptions, e2eeSetupComplete]);
+
+ useLowCPUOptimizer(room);
+
return (
-
-
-
-
+
+
+
+
+
+
+
);
}
diff --git a/app/custom/page.tsx b/app/custom/page.tsx
index 9c100a5..e251904 100644
--- a/app/custom/page.tsx
+++ b/app/custom/page.tsx
@@ -7,9 +7,10 @@ export default async function CustomRoomConnection(props: {
liveKitUrl?: string;
token?: string;
codec?: string;
+ singlePC?: string;
}>;
}) {
- const { liveKitUrl, token, codec } = await props.searchParams;
+ const { liveKitUrl, token, codec, singlePC } = await props.searchParams;
if (typeof liveKitUrl !== 'string') {
return Missing LiveKit URL
;
}
@@ -22,7 +23,12 @@ export default async function CustomRoomConnection(props: {
return (
-
+
);
}
diff --git a/app/rooms/[roomName]/PageClientImpl.tsx b/app/rooms/[roomName]/PageClientImpl.tsx
index 6ecad1d..d31d6bf 100644
--- a/app/rooms/[roomName]/PageClientImpl.tsx
+++ b/app/rooms/[roomName]/PageClientImpl.tsx
@@ -1,15 +1,17 @@
'use client';
+import React from 'react';
import { decodePassphrase } from '@/lib/client-utils';
import { DebugMode } from '@/lib/Debug';
+import { KeyboardShortcuts } from '@/lib/KeyboardShortcuts';
import { RecordingIndicator } from '@/lib/RecordingIndicator';
import { SettingsMenu } from '@/lib/SettingsMenu';
import { ConnectionDetails } from '@/lib/types';
import {
formatChatMessageLinks,
- LiveKitRoom,
LocalUserChoices,
PreJoin,
+ RoomContext,
VideoConference,
} from '@livekit/components-react';
import {
@@ -20,9 +22,13 @@ import {
Room,
DeviceUnsupportedError,
RoomConnectOptions,
+ RoomEvent,
+ TrackPublishDefaults,
+ VideoCaptureOptions,
} from 'livekit-client';
import { useRouter } from 'next/navigation';
-import React from 'react';
+import { useSetupE2EE } from '@/lib/useSetupE2EE';
+import { useLowCPUOptimizer } from '@/lib/usePerfomanceOptimiser';
const CONN_DETAILS_ENDPOINT =
process.env.NEXT_PUBLIC_CONN_DETAILS_ENDPOINT ?? '/api/connection-details';
@@ -91,15 +97,10 @@ function VideoConferenceComponent(props: {
codec: VideoCodec;
};
}) {
- const e2eePassphrase =
- typeof window !== 'undefined' && decodePassphrase(location.hash.substring(1));
-
- const worker =
- typeof window !== 'undefined' &&
- e2eePassphrase &&
- new Worker(new URL('livekit-client/e2ee-worker', import.meta.url));
- const e2eeEnabled = !!(e2eePassphrase && worker);
const keyProvider = new ExternalE2EEKeyProvider();
+ const { worker, e2eePassphrase } = useSetupE2EE();
+ const e2eeEnabled = !!(e2eePassphrase && worker);
+
const [e2eeSetupComplete, setE2eeSetupComplete] = React.useState(false);
const roomOptions = React.useMemo((): RoomOptions => {
@@ -107,30 +108,28 @@ function VideoConferenceComponent(props: {
if (e2eeEnabled && (videoCodec === 'av1' || videoCodec === 'vp9')) {
videoCodec = undefined;
}
+ const videoCaptureDefaults: VideoCaptureOptions = {
+ deviceId: props.userChoices.videoDeviceId ?? undefined,
+ resolution: props.options.hq ? VideoPresets.h2160 : VideoPresets.h720,
+ };
+ const publishDefaults: TrackPublishDefaults = {
+ dtx: false,
+ videoSimulcastLayers: props.options.hq
+ ? [VideoPresets.h1080, VideoPresets.h720]
+ : [VideoPresets.h540, VideoPresets.h216],
+ red: !e2eeEnabled,
+ videoCodec,
+ };
return {
- videoCaptureDefaults: {
- deviceId: props.userChoices.videoDeviceId ?? undefined,
- resolution: props.options.hq ? VideoPresets.h2160 : VideoPresets.h720,
- },
- publishDefaults: {
- dtx: false,
- videoSimulcastLayers: props.options.hq
- ? [VideoPresets.h1080, VideoPresets.h720]
- : [VideoPresets.h540, VideoPresets.h216],
- red: !e2eeEnabled,
- videoCodec,
- },
+ videoCaptureDefaults: videoCaptureDefaults,
+ publishDefaults: publishDefaults,
audioCaptureDefaults: {
deviceId: props.userChoices.audioDeviceId ?? undefined,
},
- adaptiveStream: { pixelDensity: 'screen' },
+ adaptiveStream: true,
dynacast: true,
- e2ee: e2eeEnabled
- ? {
- keyProvider,
- worker,
- }
- : undefined,
+ e2ee: keyProvider && worker && e2eeEnabled ? { keyProvider, worker } : undefined,
+ singlePeerConnection: true,
};
}, [props.userChoices, props.options.hq, props.options.codec]);
@@ -164,6 +163,41 @@ function VideoConferenceComponent(props: {
};
}, []);
+ React.useEffect(() => {
+ room.on(RoomEvent.Disconnected, handleOnLeave);
+ room.on(RoomEvent.EncryptionError, handleEncryptionError);
+ room.on(RoomEvent.MediaDevicesError, handleError);
+
+ if (e2eeSetupComplete) {
+ room
+ .connect(
+ props.connectionDetails.serverUrl,
+ props.connectionDetails.participantToken,
+ connectOptions,
+ )
+ .catch((error) => {
+ handleError(error);
+ });
+ if (props.userChoices.videoEnabled) {
+ room.localParticipant.setCameraEnabled(true).catch((error) => {
+ handleError(error);
+ });
+ }
+ if (props.userChoices.audioEnabled) {
+ room.localParticipant.setMicrophoneEnabled(true).catch((error) => {
+ handleError(error);
+ });
+ }
+ }
+ return () => {
+ room.off(RoomEvent.Disconnected, handleOnLeave);
+ room.off(RoomEvent.EncryptionError, handleEncryptionError);
+ room.off(RoomEvent.MediaDevicesError, handleError);
+ };
+ }, [e2eeSetupComplete, room, props.connectionDetails, props.userChoices]);
+
+ const lowPowerMode = useLowCPUOptimizer(room);
+
const router = useRouter();
const handleOnLeave = React.useCallback(() => router.push('/'), [router]);
const handleError = React.useCallback((error: Error) => {
@@ -177,27 +211,23 @@ function VideoConferenceComponent(props: {
);
}, []);
+ React.useEffect(() => {
+ if (lowPowerMode) {
+ console.warn('Low power mode enabled');
+ }
+ }, [lowPowerMode]);
+
return (
- <>
-
+
+
+
-
- >
+
+
);
}
diff --git a/lib/CameraSettings.tsx b/lib/CameraSettings.tsx
new file mode 100644
index 0000000..37690d0
--- /dev/null
+++ b/lib/CameraSettings.tsx
@@ -0,0 +1,175 @@
+import React from 'react';
+import {
+ MediaDeviceMenu,
+ TrackReference,
+ TrackToggle,
+ useLocalParticipant,
+ VideoTrack,
+} from '@livekit/components-react';
+import { BackgroundBlur, VirtualBackground } from '@livekit/track-processors';
+import { isLocalTrack, LocalTrackPublication, Track } from 'livekit-client';
+import Desk from '../public/background-images/samantha-gades-BlIhVfXbi9s-unsplash.jpg';
+import Nature from '../public/background-images/ali-kazal-tbw_KQE3Cbg-unsplash.jpg';
+
+// Background image paths
+const BACKGROUND_IMAGES = [
+ { name: 'Desk', path: Desk },
+ { name: 'Nature', path: Nature },
+];
+
+// Background options
+type BackgroundType = 'none' | 'blur' | 'image';
+
+export function CameraSettings() {
+ const { cameraTrack, localParticipant } = useLocalParticipant();
+ const [backgroundType, setBackgroundType] = React.useState(
+ (cameraTrack as LocalTrackPublication)?.track?.getProcessor()?.name === 'background-blur'
+ ? 'blur'
+ : (cameraTrack as LocalTrackPublication)?.track?.getProcessor()?.name === 'virtual-background'
+ ? 'image'
+ : 'none',
+ );
+
+ const [virtualBackgroundImagePath, setVirtualBackgroundImagePath] = React.useState(
+ null,
+ );
+
+ const camTrackRef: TrackReference | undefined = React.useMemo(() => {
+ return cameraTrack
+ ? { participant: localParticipant, publication: cameraTrack, source: Track.Source.Camera }
+ : undefined;
+ }, [localParticipant, cameraTrack]);
+
+ const selectBackground = (type: BackgroundType, imagePath?: string) => {
+ setBackgroundType(type);
+ if (type === 'image' && imagePath) {
+ setVirtualBackgroundImagePath(imagePath);
+ } else if (type !== 'image') {
+ setVirtualBackgroundImagePath(null);
+ }
+ };
+
+ React.useEffect(() => {
+ if (isLocalTrack(cameraTrack?.track)) {
+ if (backgroundType === 'blur') {
+ cameraTrack.track?.setProcessor(BackgroundBlur());
+ } else if (backgroundType === 'image' && virtualBackgroundImagePath) {
+ cameraTrack.track?.setProcessor(VirtualBackground(virtualBackgroundImagePath));
+ } else {
+ cameraTrack.track?.stopProcessor();
+ }
+ }
+ }, [cameraTrack, backgroundType, virtualBackgroundImagePath]);
+
+ return (
+
+ {camTrackRef && (
+
+ )}
+
+
+
+
+
Background Effects
+
+
+
+
+
+ {BACKGROUND_IMAGES.map((image) => (
+
+ ))}
+
+
+
+ );
+}
diff --git a/lib/KeyboardShortcuts.tsx b/lib/KeyboardShortcuts.tsx
new file mode 100644
index 0000000..5a0c659
--- /dev/null
+++ b/lib/KeyboardShortcuts.tsx
@@ -0,0 +1,31 @@
+'use client';
+
+import React from 'react';
+import { Track } from 'livekit-client';
+import { useTrackToggle } from '@livekit/components-react';
+
+export function KeyboardShortcuts() {
+ const { toggle: toggleMic } = useTrackToggle({ source: Track.Source.Microphone });
+ const { toggle: toggleCamera } = useTrackToggle({ source: Track.Source.Camera });
+
+ React.useEffect(() => {
+ function handleShortcut(event: KeyboardEvent) {
+ // Toggle microphone: Cmd/Ctrl-Shift-A
+ if (toggleMic && event.key === 'A' && (event.ctrlKey || event.metaKey)) {
+ event.preventDefault();
+ toggleMic();
+ }
+
+ // Toggle camera: Cmd/Ctrl-Shift-V
+ if (event.key === 'V' && (event.ctrlKey || event.metaKey)) {
+ event.preventDefault();
+ toggleCamera();
+ }
+ }
+
+ window.addEventListener('keydown', handleShortcut);
+ return () => window.removeEventListener('keydown', handleShortcut);
+ }, [toggleMic, toggleCamera]);
+
+ return null;
+}
diff --git a/lib/MicrophoneSettings.tsx b/lib/MicrophoneSettings.tsx
new file mode 100644
index 0000000..de2e8b3
--- /dev/null
+++ b/lib/MicrophoneSettings.tsx
@@ -0,0 +1,55 @@
+import React from 'react';
+import { useKrispNoiseFilter } from '@livekit/components-react/krisp';
+import { TrackToggle } from '@livekit/components-react';
+import { MediaDeviceMenu } from '@livekit/components-react';
+import { Track } from 'livekit-client';
+import { isLowPowerDevice } from './client-utils';
+
+export function MicrophoneSettings() {
+ const { isNoiseFilterEnabled, setNoiseFilterEnabled, isNoiseFilterPending } = useKrispNoiseFilter(
+ {
+ filterOptions: {
+ bufferOverflowMs: 100,
+ bufferDropMs: 200,
+ quality: isLowPowerDevice() ? 'low' : 'medium',
+ onBufferDrop: () => {
+ console.warn(
+ 'krisp buffer dropped, noise filter versions >= 0.3.2 will automatically disable the filter',
+ );
+ },
+ },
+ },
+ );
+
+ React.useEffect(() => {
+ // enable Krisp by default on non-low power devices
+ setNoiseFilterEnabled(!isLowPowerDevice());
+ }, []);
+ return (
+
+
+
+
+
+ );
+}
diff --git a/lib/SettingsMenu.tsx b/lib/SettingsMenu.tsx
index c817e9c..9cf7c35 100644
--- a/lib/SettingsMenu.tsx
+++ b/lib/SettingsMenu.tsx
@@ -8,9 +8,9 @@ import {
useRoomContext,
useIsRecording,
} from '@livekit/components-react';
-import { useKrispNoiseFilter } from '@livekit/components-react/krisp';
import styles from '../styles/SettingsMenu.module.css';
-
+import { CameraSettings } from './CameraSettings';
+import { MicrophoneSettings } from './MicrophoneSettings';
/**
* @alpha
*/
@@ -27,7 +27,6 @@ export function SettingsMenu(props: SettingsMenuProps) {
const settings = React.useMemo(() => {
return {
media: { camera: true, microphone: true, label: 'Media Devices', speaker: true },
- effects: { label: 'Effects' },
recording: recordingEndpoint ? { label: 'Recording' } : undefined,
};
}, []);
@@ -38,14 +37,6 @@ export function SettingsMenu(props: SettingsMenuProps) {
);
const [activeTab, setActiveTab] = React.useState(tabs[0]);
- const { isNoiseFilterEnabled, setNoiseFilterEnabled, isNoiseFilterPending } =
- useKrispNoiseFilter();
-
- React.useEffect(() => {
- // enable Krisp by default
- setNoiseFilterEnabled(true);
- }, []);
-
const isRecording = useIsRecording();
const [initialRecStatus, setInitialRecStatus] = React.useState(isRecording);
const [processingRecRequest, setProcessingRecRequest] = React.useState(false);
@@ -83,7 +74,7 @@ export function SettingsMenu(props: SettingsMenuProps) {
};
return (
-
+
{tabs.map(
(tab) =>
@@ -108,22 +99,16 @@ export function SettingsMenu(props: SettingsMenuProps) {
{settings.media && settings.media.camera && (
<>
Camera
-
- Camera
-
-
-
+
>
)}
{settings.media && settings.media.microphone && (
<>
Microphone
-
- Microphone
-
-
-
+
>
)}
@@ -140,21 +125,6 @@ export function SettingsMenu(props: SettingsMenuProps) {
)}
>
)}
- {activeTab === 'effects' && (
- <>
- Audio
-
- >
- )}
{activeTab === 'recording' && (
<>
Record Meeting
@@ -171,12 +141,14 @@ export function SettingsMenu(props: SettingsMenuProps) {
>
)}
-
+
+
+
);
}
diff --git a/lib/client-utils.ts b/lib/client-utils.ts
index b37257f..11ca60b 100644
--- a/lib/client-utils.ts
+++ b/lib/client-utils.ts
@@ -19,3 +19,11 @@ export function randomString(length: number): string {
}
return result;
}
+
+export function isLowPowerDevice() {
+ return navigator.hardwareConcurrency < 6;
+}
+
+export function isMeetStaging() {
+ return new URL(location.origin).host === 'meet.staging.livekit.io';
+}
diff --git a/lib/getLiveKitURL.test.ts b/lib/getLiveKitURL.test.ts
new file mode 100644
index 0000000..68dc9ea
--- /dev/null
+++ b/lib/getLiveKitURL.test.ts
@@ -0,0 +1,35 @@
+import { describe, it, expect } from 'vitest';
+import { getLiveKitURL } from './getLiveKitURL';
+
+describe('getLiveKitURL', () => {
+ it('returns the original URL if no region is provided', () => {
+ const url = 'https://myproject.livekit.cloud';
+ expect(getLiveKitURL(url, null)).toBe(url + '/');
+ });
+
+ it('inserts the region into livekit.cloud URLs', () => {
+ const url = 'https://myproject.livekit.cloud';
+ const region = 'eu';
+ expect(getLiveKitURL(url, region)).toBe('https://myproject.eu.production.livekit.cloud/');
+ });
+
+ it('inserts the region into livekit.cloud URLs and preserves the staging environment', () => {
+ const url = 'https://myproject.staging.livekit.cloud';
+ const region = 'eu';
+ expect(getLiveKitURL(url, region)).toBe('https://myproject.eu.staging.livekit.cloud/');
+ });
+
+ it('returns the original URL for non-livekit.cloud hosts, even with region', () => {
+ const url = 'https://example.com';
+ const region = 'us';
+ expect(getLiveKitURL(url, region)).toBe(url + '/');
+ });
+
+ it('handles URLs with paths and query params', () => {
+ const url = 'https://myproject.livekit.cloud/room?foo=bar';
+ const region = 'ap';
+ expect(getLiveKitURL(url, region)).toBe(
+ 'https://myproject.ap.production.livekit.cloud/room?foo=bar',
+ );
+ });
+});
diff --git a/lib/getLiveKitURL.ts b/lib/getLiveKitURL.ts
new file mode 100644
index 0000000..9634eba
--- /dev/null
+++ b/lib/getLiveKitURL.ts
@@ -0,0 +1,12 @@
+export function getLiveKitURL(projectUrl: string, region: string | null): string {
+ const url = new URL(projectUrl);
+ if (region && url.hostname.includes('livekit.cloud')) {
+ let [projectId, ...hostParts] = url.hostname.split('.');
+ if (hostParts[0] !== 'staging') {
+ hostParts = ['production', ...hostParts];
+ }
+ const regionURL = [projectId, region, ...hostParts].join('.');
+ url.hostname = regionURL;
+ }
+ return url.toString();
+}
diff --git a/lib/usePerfomanceOptimiser.ts b/lib/usePerfomanceOptimiser.ts
new file mode 100644
index 0000000..45ef35e
--- /dev/null
+++ b/lib/usePerfomanceOptimiser.ts
@@ -0,0 +1,71 @@
+import {
+ Room,
+ ParticipantEvent,
+ RoomEvent,
+ RemoteTrack,
+ RemoteTrackPublication,
+ VideoQuality,
+ LocalVideoTrack,
+ isVideoTrack,
+} from 'livekit-client';
+import * as React from 'react';
+
+export type LowCPUOptimizerOptions = {
+ reducePublisherVideoQuality: boolean;
+ reduceSubscriberVideoQuality: boolean;
+ disableVideoProcessing: boolean;
+};
+
+const defaultOptions: LowCPUOptimizerOptions = {
+ reducePublisherVideoQuality: true,
+ reduceSubscriberVideoQuality: true,
+ disableVideoProcessing: false,
+} as const;
+
+/**
+ * This hook ensures that on devices with low CPU, the performance is optimised when needed.
+ * This is done by primarily reducing the video quality to low when the CPU is constrained.
+ */
+export function useLowCPUOptimizer(room: Room, options: Partial
= {}) {
+ const [lowPowerMode, setLowPowerMode] = React.useState(false);
+ const opts = React.useMemo(() => ({ ...defaultOptions, ...options }), [options]);
+ React.useEffect(() => {
+ const handleCpuConstrained = async (track: LocalVideoTrack) => {
+ setLowPowerMode(true);
+ console.warn('Local track CPU constrained', track);
+ if (opts.reducePublisherVideoQuality) {
+ track.prioritizePerformance();
+ }
+ if (opts.disableVideoProcessing && isVideoTrack(track)) {
+ track.stopProcessor();
+ }
+ if (opts.reduceSubscriberVideoQuality) {
+ room.remoteParticipants.forEach((participant) => {
+ participant.videoTrackPublications.forEach((publication) => {
+ publication.setVideoQuality(VideoQuality.LOW);
+ });
+ });
+ }
+ };
+
+ room.localParticipant.on(ParticipantEvent.LocalTrackCpuConstrained, handleCpuConstrained);
+ return () => {
+ room.localParticipant.off(ParticipantEvent.LocalTrackCpuConstrained, handleCpuConstrained);
+ };
+ }, [room, opts.reducePublisherVideoQuality, opts.reduceSubscriberVideoQuality]);
+
+ React.useEffect(() => {
+ const lowerQuality = (_: RemoteTrack, publication: RemoteTrackPublication) => {
+ publication.setVideoQuality(VideoQuality.LOW);
+ };
+ if (lowPowerMode && opts.reduceSubscriberVideoQuality) {
+ room.on(RoomEvent.TrackSubscribed, lowerQuality);
+ }
+
+ return () => {
+ room.off(RoomEvent.TrackSubscribed, lowerQuality);
+ };
+ }, [lowPowerMode, room, opts.reduceSubscriberVideoQuality]);
+
+ return lowPowerMode;
+}
diff --git a/lib/useSetupE2EE.ts b/lib/useSetupE2EE.ts
new file mode 100644
index 0000000..280582e
--- /dev/null
+++ b/lib/useSetupE2EE.ts
@@ -0,0 +1,15 @@
+import React from 'react';
+import { ExternalE2EEKeyProvider } from 'livekit-client';
+import { decodePassphrase } from './client-utils';
+
+export function useSetupE2EE() {
+ const e2eePassphrase =
+ typeof window !== 'undefined' ? decodePassphrase(location.hash.substring(1)) : undefined;
+
+ const worker: Worker | undefined =
+ typeof window !== 'undefined' && e2eePassphrase
+ ? new Worker(new URL('livekit-client/e2ee-worker', import.meta.url))
+ : undefined;
+
+ return { worker, e2eePassphrase };
+}
diff --git a/next.config.js b/next.config.js
index 76f094f..6210192 100644
--- a/next.config.js
+++ b/next.config.js
@@ -2,6 +2,9 @@
const nextConfig = {
reactStrictMode: false,
productionBrowserSourceMaps: true,
+ images: {
+ formats: ['image/webp'],
+ },
webpack: (config, { buildId, dev, isServer, defaultLoaders, nextRuntime, webpack }) => {
// Important: return the modified config
config.module.rules.push({
@@ -9,8 +12,26 @@ const nextConfig = {
enforce: 'pre',
use: ['source-map-loader'],
});
+
return config;
},
+ headers: async () => {
+ return [
+ {
+ source: '/(.*)',
+ headers: [
+ {
+ key: 'Cross-Origin-Opener-Policy',
+ value: 'same-origin',
+ },
+ {
+ key: 'Cross-Origin-Embedder-Policy',
+ value: 'credentialless',
+ },
+ ],
+ },
+ ];
+ },
};
module.exports = nextConfig;
diff --git a/package.json b/package.json
index 13b0bdc..b8865ad 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,11 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
- "lint": "next lint"
+ "lint": "next lint",
+ "lint:fix": "next lint --fix",
+ "test": "vitest run",
+ "format:check": "prettier --check \"**/*.{ts,tsx,md,json}\"",
+ "format:write": "prettier --write \"**/*.{ts,tsx,md,json}\""
},
"dependencies": {
"@datadog/browser-logs": "^5.23.3",
@@ -23,16 +27,18 @@
"tinykeys": "^3.0.0"
},
"devDependencies": {
- "@types/node": "22.14.0",
- "@types/react": "18.3.20",
- "@types/react-dom": "18.3.6",
- "eslint": "9.24.0",
- "eslint-config-next": "15.2.4",
+ "@types/node": "24.10.13",
+ "@types/react": "18.3.27",
+ "@types/react-dom": "18.3.7",
+ "eslint": "9.39.1",
+ "eslint-config-next": "15.5.6",
+ "prettier": "3.7.3",
"source-map-loader": "^5.0.0",
- "typescript": "5.8.3"
+ "typescript": "5.9.3",
+ "vitest": "^3.2.4"
},
"engines": {
"node": ">=18"
},
- "packageManager": "pnpm@9.15.9"
+ "packageManager": "pnpm@10.18.2"
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6f66003..99bb7a2 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -46,32 +46,35 @@ importers:
version: 3.0.0
devDependencies:
'@types/node':
- specifier: 22.14.0
- version: 22.14.0
+ specifier: 24.10.13
+ version: 24.10.13
'@types/react':
- specifier: 18.3.20
- version: 18.3.20
+ specifier: 18.3.27
+ version: 18.3.27
'@types/react-dom':
- specifier: 18.3.6
- version: 18.3.6(@types/react@18.3.20)
+ specifier: 18.3.7
+ version: 18.3.7(@types/react@18.3.27)
eslint:
- specifier: 9.24.0
- version: 9.24.0
+ specifier: 9.39.1
+ version: 9.39.1
eslint-config-next:
- specifier: 15.2.4
- version: 15.2.4(eslint@9.24.0)(typescript@5.8.3)
+ specifier: 15.5.6
+ version: 15.5.6(eslint@9.39.1)(typescript@5.9.3)
+ prettier:
+ specifier: 3.7.3
+ version: 3.7.3
source-map-loader:
specifier: ^5.0.0
version: 5.0.0(webpack@5.95.0)
typescript:
- specifier: 5.8.3
- version: 5.8.3
+ specifier: 5.9.3
+ version: 5.9.3
+ vitest:
+ specifier: ^3.2.4
+ version: 3.2.4(@types/node@24.10.13)(terser@5.39.0)
packages:
- '@bufbuild/protobuf@1.10.0':
- resolution: {integrity: sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==}
-
'@bufbuild/protobuf@1.10.1':
resolution: {integrity: sha512-wJ8ReQbHxsAfXhrf9ixl0aYbZorRuOWpBNzm8pL8ftmSxQx/wnJD5Eg861NwJU/czy2VXFIebCeZnZrI9rktIQ==}
@@ -89,8 +92,164 @@ packages:
'@emnapi/runtime@1.4.0':
resolution: {integrity: sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==}
- '@eslint-community/eslint-utils@4.4.0':
- resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
+ '@esbuild/aix-ppc64@0.27.3':
+ resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.27.3':
+ resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.27.3':
+ resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.27.3':
+ resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.27.3':
+ resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.27.3':
+ resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.27.3':
+ resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.27.3':
+ resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.27.3':
+ resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.27.3':
+ resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.27.3':
+ resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.27.3':
+ resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.27.3':
+ resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.27.3':
+ resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.27.3':
+ resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.27.3':
+ resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.27.3':
+ resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.27.3':
+ resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.27.3':
+ resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.27.3':
+ resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.27.3':
+ resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openharmony-arm64@0.27.3':
+ resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/sunos-x64@0.27.3':
+ resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.27.3':
+ resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.27.3':
+ resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.27.3':
+ resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@eslint-community/eslint-utils@4.9.1':
+ resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
@@ -99,36 +258,32 @@ packages:
resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
- '@eslint/config-array@0.20.0':
- resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==}
+ '@eslint/config-array@0.21.1':
+ resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/config-helpers@0.2.1':
- resolution: {integrity: sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==}
+ '@eslint/config-helpers@0.4.2':
+ resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/core@0.12.0':
- resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==}
- engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
-
- '@eslint/core@0.13.0':
- resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==}
+ '@eslint/core@0.17.0':
+ resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/eslintrc@3.3.1':
resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/js@9.24.0':
- resolution: {integrity: sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==}
+ '@eslint/js@9.39.1':
+ resolution: {integrity: sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/object-schema@2.1.6':
- resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==}
+ '@eslint/object-schema@2.1.7':
+ resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/plugin-kit@0.2.8':
- resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==}
+ '@eslint/plugin-kit@0.4.1':
+ resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@floating-ui/core@1.7.4':
@@ -280,8 +435,8 @@ packages:
'@jridgewell/source-map@0.3.6':
resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==}
- '@jridgewell/sourcemap-codec@1.5.0':
- resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
'@jridgewell/trace-mapping@0.3.25':
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
@@ -333,8 +488,8 @@ packages:
'@next/env@15.2.8':
resolution: {integrity: sha512-TaEsAki14R7BlgywA05t2PFYfwZiNlGUHyIQHVyloXX3y+Dm0HUITe5YwTkjtuOQuDhuuLotNEad4VtnmE11Uw==}
- '@next/eslint-plugin-next@15.2.4':
- resolution: {integrity: sha512-O8ScvKtnxkp8kL9TpJTTKnMqlkZnS+QxwoQnJwPGBxjBbzd6OVVPEJ5/pMNrktSyXQD/chEfzfFzYLM6JANOOQ==}
+ '@next/eslint-plugin-next@15.5.6':
+ resolution: {integrity: sha512-YxDvsT2fwy1j5gMqk3ppXlsgDopHnkM4BoxSVASbvvgh5zgsK8lvWerDzPip8k3WVzsTZ1O7A7si1KNfN4OZfQ==}
'@next/swc-darwin-arm64@15.2.5':
resolution: {integrity: sha512-4OimvVlFTbgzPdA0kh8A1ih6FN9pQkL4nPXGqemEYgk+e7eQhsst/p35siNNqA49eQA6bvKZ1ASsDtu9gtXuog==}
@@ -400,6 +555,131 @@ packages:
resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==}
engines: {node: '>=12.4.0'}
+ '@rollup/rollup-android-arm-eabi@4.57.1':
+ resolution: {integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.57.1':
+ resolution: {integrity: sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.57.1':
+ resolution: {integrity: sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.57.1':
+ resolution: {integrity: sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-freebsd-arm64@4.57.1':
+ resolution: {integrity: sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.57.1':
+ resolution: {integrity: sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.57.1':
+ resolution: {integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.57.1':
+ resolution: {integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-gnu@4.57.1':
+ resolution: {integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-musl@4.57.1':
+ resolution: {integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-loong64-gnu@4.57.1':
+ resolution: {integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==}
+ cpu: [loong64]
+ os: [linux]
+
+ '@rollup/rollup-linux-loong64-musl@4.57.1':
+ resolution: {integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==}
+ cpu: [loong64]
+ os: [linux]
+
+ '@rollup/rollup-linux-ppc64-gnu@4.57.1':
+ resolution: {integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-ppc64-musl@4.57.1':
+ resolution: {integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.57.1':
+ resolution: {integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-musl@4.57.1':
+ resolution: {integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-s390x-gnu@4.57.1':
+ resolution: {integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-gnu@4.57.1':
+ resolution: {integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-musl@4.57.1':
+ resolution: {integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-openbsd-x64@4.57.1':
+ resolution: {integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@rollup/rollup-openharmony-arm64@4.57.1':
+ resolution: {integrity: sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rollup/rollup-win32-arm64-msvc@4.57.1':
+ resolution: {integrity: sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.57.1':
+ resolution: {integrity: sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-gnu@4.57.1':
+ resolution: {integrity: sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==}
+ cpu: [x64]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.57.1':
+ resolution: {integrity: sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==}
+ cpu: [x64]
+ os: [win32]
+
'@rtsao/scc@1.1.0':
resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
@@ -412,6 +692,12 @@ packages:
'@swc/helpers@0.5.15':
resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
+ '@types/chai@5.2.3':
+ resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
+
+ '@types/deep-eql@4.0.2':
+ resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
+
'@types/dom-mediacapture-record@1.0.22':
resolution: {integrity: sha512-mUMZLK3NvwRLcAAT9qmcK+9p7tpU2FHdDsntR3YI4+GY88XrgG4XiE7u1Q2LAN2/FZOz/tdMDC3GQCR4T8nFuw==}
@@ -421,11 +707,8 @@ packages:
'@types/dom-webcodecs@0.1.18':
resolution: {integrity: sha512-vAvE8C9DGWR+tkb19xyjk1TSUlJ7RUzzp4a9Anu7mwBT+fpyePWK1UxmH14tMO5zHmrnrRIMg5NutnnDztLxgg==}
- '@types/estree@1.0.6':
- resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
-
- '@types/estree@1.0.7':
- resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==}
+ '@types/estree@1.0.8':
+ resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
@@ -433,19 +716,19 @@ packages:
'@types/json5@0.0.29':
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
- '@types/node@22.14.0':
- resolution: {integrity: sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==}
+ '@types/node@24.10.13':
+ resolution: {integrity: sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg==}
'@types/prop-types@15.7.13':
resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==}
- '@types/react-dom@18.3.6':
- resolution: {integrity: sha512-nf22//wEbKXusP6E9pfOCDwFdHAX4u172eaJI4YkDRQEZiorm6KfYnSC2SWLDMVWUOWPERmJnN0ujeAfTBLvrw==}
+ '@types/react-dom@18.3.7':
+ resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==}
peerDependencies:
'@types/react': ^18.0.0
- '@types/react@18.3.20':
- resolution: {integrity: sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg==}
+ '@types/react@18.3.27':
+ resolution: {integrity: sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==}
'@typescript-eslint/eslint-plugin@8.8.0':
resolution: {integrity: sha512-wORFWjU30B2WJ/aXBfOm1LX9v9nyt9D3jsSOxC3cCaTQGCW5k4jNpmjFv3U7p/7s4yvdjHzwtv2Sd2dOyhjS0A==}
@@ -504,6 +787,35 @@ packages:
resolution: {integrity: sha512-8mq51Lx6Hpmd7HnA2fcHQo3YgfX1qbccxQOgZcb4tvasu//zXRaA1j5ZRFeCw/VRAdFi4mRM9DnZw0Nu0Q2d1g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ '@vitest/expect@3.2.4':
+ resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==}
+
+ '@vitest/mocker@3.2.4':
+ resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==}
+ peerDependencies:
+ msw: ^2.4.9
+ vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0
+ peerDependenciesMeta:
+ msw:
+ optional: true
+ vite:
+ optional: true
+
+ '@vitest/pretty-format@3.2.4':
+ resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==}
+
+ '@vitest/runner@3.2.4':
+ resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==}
+
+ '@vitest/snapshot@3.2.4':
+ resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==}
+
+ '@vitest/spy@3.2.4':
+ resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==}
+
+ '@vitest/utils@3.2.4':
+ resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==}
+
'@webassemblyjs/ast@1.14.1':
resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==}
@@ -565,13 +877,8 @@ packages:
peerDependencies:
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
- acorn@8.14.0:
- resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
- engines: {node: '>=0.4.0'}
- hasBin: true
-
- acorn@8.14.1:
- resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==}
+ acorn@8.16.0:
+ resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==}
engines: {node: '>=0.4.0'}
hasBin: true
@@ -641,6 +948,10 @@ packages:
resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==}
engines: {node: '>= 0.4'}
+ assertion-error@2.0.1:
+ resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
+ engines: {node: '>=12'}
+
ast-types-flow@0.0.8:
resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==}
@@ -681,6 +992,10 @@ packages:
resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
engines: {node: '>=10.16.0'}
+ cac@6.7.14:
+ resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
+ engines: {node: '>=8'}
+
call-bind@1.0.7:
resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
engines: {node: '>= 0.4'}
@@ -700,10 +1015,18 @@ packages:
caniuse-lite@1.0.30001707:
resolution: {integrity: sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==}
+ chai@5.3.3:
+ resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==}
+ engines: {node: '>=18'}
+
chalk@4.1.2:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'}
+ check-error@2.1.3:
+ resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==}
+ engines: {node: '>= 16'}
+
chrome-trace-event@1.0.4:
resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==}
engines: {node: '>=6.0'}
@@ -739,8 +1062,8 @@ packages:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
- csstype@3.1.3:
- resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+ csstype@3.2.3:
+ resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
damerau-levenshtein@1.0.8:
resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
@@ -765,8 +1088,8 @@ packages:
supports-color:
optional: true
- debug@4.3.7:
- resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
@@ -774,6 +1097,10 @@ packages:
supports-color:
optional: true
+ deep-eql@5.0.2:
+ resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
+ engines: {node: '>=6'}
+
deep-equal@2.2.3:
resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==}
engines: {node: '>= 0.4'}
@@ -826,8 +1153,8 @@ packages:
resolution: {integrity: sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==}
engines: {node: '>= 0.4'}
- es-module-lexer@1.6.0:
- resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==}
+ es-module-lexer@1.7.0:
+ resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
es-object-atoms@1.0.0:
resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==}
@@ -844,6 +1171,11 @@ packages:
resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
engines: {node: '>= 0.4'}
+ esbuild@0.27.3:
+ resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==}
+ engines: {node: '>=18'}
+ hasBin: true
+
escalade@3.2.0:
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
engines: {node: '>=6'}
@@ -852,8 +1184,8 @@ packages:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
- eslint-config-next@15.2.4:
- resolution: {integrity: sha512-v4gYjd4eYIme8qzaJItpR5MMBXJ0/YV07u7eb50kEnlEmX7yhOjdUdzz70v4fiINYRjLf8X8TbogF0k7wlz6sA==}
+ eslint-config-next@15.5.6:
+ resolution: {integrity: sha512-cGr3VQlPsZBEv8rtYp4BpG1KNXDqGvPo9VC1iaCgIA11OfziC/vczng+TnAS3WpRIR3Q5ye/6yl+CRUuZ1fPGg==}
peerDependencies:
eslint: ^7.23.0 || ^8.0.0 || ^9.0.0
typescript: '>=3.3.1'
@@ -930,20 +1262,20 @@ packages:
resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
engines: {node: '>=8.0.0'}
- eslint-scope@8.3.0:
- resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==}
+ eslint-scope@8.4.0:
+ resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
eslint-visitor-keys@3.4.3:
resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- eslint-visitor-keys@4.2.0:
- resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==}
+ eslint-visitor-keys@4.2.1:
+ resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- eslint@9.24.0:
- resolution: {integrity: sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==}
+ eslint@9.39.1:
+ resolution: {integrity: sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
hasBin: true
peerDependencies:
@@ -952,8 +1284,8 @@ packages:
jiti:
optional: true
- espree@10.3.0:
- resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==}
+ espree@10.4.0:
+ resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
esquery@1.6.0:
@@ -972,6 +1304,9 @@ packages:
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
engines: {node: '>=4.0'}
+ estree-walker@3.0.3:
+ resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+
esutils@2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
@@ -980,6 +1315,10 @@ packages:
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
engines: {node: '>=0.8.x'}
+ expect-type@1.3.0:
+ resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==}
+ engines: {node: '>=12.0.0'}
+
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
@@ -1003,6 +1342,15 @@ packages:
fastq@1.17.1:
resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
+ fdir@6.5.0:
+ resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
file-entry-cache@8.0.0:
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
engines: {node: '>=16.0.0'}
@@ -1025,6 +1373,11 @@ packages:
for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
@@ -1254,6 +1607,9 @@ packages:
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+ js-tokens@9.0.1:
+ resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
+
js-yaml@4.1.0:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
hasBin: true
@@ -1330,6 +1686,12 @@ packages:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
+ loupe@3.2.1:
+ resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==}
+
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
map-obj@5.0.0:
resolution: {integrity: sha512-2L3MIgJynYrZ3TYMriLDLWocz15okFakV6J12HXvMXDHui2x/zgChzg1u9mFFGbbGWE+GsLpQByt4POb9Or+uA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -1366,8 +1728,8 @@ packages:
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
- nanoid@3.3.7:
- resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
+ nanoid@3.3.11:
+ resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
@@ -1464,6 +1826,13 @@ packages:
path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+ pathe@2.0.3:
+ resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
+ pathval@2.0.1:
+ resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==}
+ engines: {node: '>= 14.16'}
+
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
@@ -1471,6 +1840,10 @@ packages:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
+ picomatch@4.0.3:
+ resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
+ engines: {node: '>=12'}
+
possible-typed-array-names@1.0.0:
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
engines: {node: '>= 0.4'}
@@ -1479,10 +1852,19 @@ packages:
resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
engines: {node: ^10 || ^12 || >=14}
+ postcss@8.5.6:
+ resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
+ engines: {node: ^10 || ^12 || >=14}
+
prelude-ls@1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
+ prettier@3.7.3:
+ resolution: {integrity: sha512-QgODejq9K3OzoBbuyobZlUhznP5SKwPqp+6Q6xw6o8gnhr4O85L2U915iM2IDcfF2NPXVaM9zlo9tdwipnYwzg==}
+ engines: {node: '>=14'}
+ hasBin: true
+
prop-types@15.8.1:
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
@@ -1550,12 +1932,14 @@ packages:
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+ rollup@4.57.1:
+ resolution: {integrity: sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
- rxjs@7.8.1:
- resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==}
-
rxjs@7.8.2:
resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==}
@@ -1627,6 +2011,9 @@ packages:
resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
engines: {node: '>= 0.4'}
+ siginfo@2.0.0:
+ resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+
simple-swizzle@0.2.2:
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
@@ -1647,6 +2034,12 @@ packages:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
+ stackback@0.0.2:
+ resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+
+ std-env@3.10.0:
+ resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==}
+
stop-iteration-iterator@1.0.0:
resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==}
engines: {node: '>= 0.4'}
@@ -1684,6 +2077,9 @@ packages:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
+ strip-literal@3.1.0:
+ resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==}
+
styled-jsx@5.1.6:
resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
engines: {node: '>= 12.0.0'}
@@ -1734,9 +2130,31 @@ packages:
engines: {node: '>=10'}
hasBin: true
+ tinybench@2.9.0:
+ resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
+
+ tinyexec@0.3.2:
+ resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
+
+ tinyglobby@0.2.15:
+ resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
+ engines: {node: '>=12.0.0'}
+
tinykeys@3.0.0:
resolution: {integrity: sha512-nazawuGv5zx6MuDfDY0rmfXjuOGhD5XU2z0GLURQ1nzl0RUe9OuCJq+0u8xxJZINHe+mr7nw8PWYYZ9WhMFujw==}
+ tinypool@1.1.1:
+ resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+
+ tinyrainbow@2.0.0:
+ resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==}
+ engines: {node: '>=14.0.0'}
+
+ tinyspy@4.0.4:
+ resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==}
+ engines: {node: '>=14.0.0'}
+
to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
@@ -1783,16 +2201,16 @@ packages:
typed-emitter@2.1.0:
resolution: {integrity: sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==}
- typescript@5.8.3:
- resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
+ typescript@5.9.3:
+ resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
engines: {node: '>=14.17'}
hasBin: true
unbox-primitive@1.0.2:
resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
- undici-types@6.21.0:
- resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
+ undici-types@7.16.0:
+ resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
update-browserslist-db@1.1.3:
resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==}
@@ -1809,6 +2227,79 @@ packages:
peerDependencies:
react: ^16.8.0 || ^17 || ^18 || ^19 || ^19.0.0-rc
+ vite-node@3.2.4:
+ resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+ hasBin: true
+
+ vite@7.3.1:
+ resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^20.19.0 || >=22.12.0
+ jiti: '>=1.21.0'
+ less: ^4.0.0
+ lightningcss: ^1.21.0
+ sass: ^1.70.0
+ sass-embedded: ^1.70.0
+ stylus: '>=0.54.8'
+ sugarss: ^5.0.0
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ vitest@3.2.4:
+ resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+ hasBin: true
+ peerDependencies:
+ '@edge-runtime/vm': '*'
+ '@types/debug': ^4.1.12
+ '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+ '@vitest/browser': 3.2.4
+ '@vitest/ui': 3.2.4
+ happy-dom: '*'
+ jsdom: '*'
+ peerDependenciesMeta:
+ '@edge-runtime/vm':
+ optional: true
+ '@types/debug':
+ optional: true
+ '@types/node':
+ optional: true
+ '@vitest/browser':
+ optional: true
+ '@vitest/ui':
+ optional: true
+ happy-dom:
+ optional: true
+ jsdom:
+ optional: true
+
watchpack@2.4.2:
resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==}
engines: {node: '>=10.13.0'}
@@ -1851,6 +2342,11 @@ packages:
engines: {node: '>= 8'}
hasBin: true
+ why-is-node-running@2.3.0:
+ resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
+ engines: {node: '>=8'}
+ hasBin: true
+
word-wrap@1.2.5:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
@@ -1861,8 +2357,6 @@ packages:
snapshots:
- '@bufbuild/protobuf@1.10.0': {}
-
'@bufbuild/protobuf@1.10.1': {}
'@datadog/browser-core@5.35.1': {}
@@ -1876,36 +2370,112 @@ snapshots:
tslib: 2.8.1
optional: true
- '@eslint-community/eslint-utils@4.4.0(eslint@9.24.0)':
+ '@esbuild/aix-ppc64@0.27.3':
+ optional: true
+
+ '@esbuild/android-arm64@0.27.3':
+ optional: true
+
+ '@esbuild/android-arm@0.27.3':
+ optional: true
+
+ '@esbuild/android-x64@0.27.3':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.27.3':
+ optional: true
+
+ '@esbuild/darwin-x64@0.27.3':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.27.3':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.27.3':
+ optional: true
+
+ '@esbuild/linux-arm64@0.27.3':
+ optional: true
+
+ '@esbuild/linux-arm@0.27.3':
+ optional: true
+
+ '@esbuild/linux-ia32@0.27.3':
+ optional: true
+
+ '@esbuild/linux-loong64@0.27.3':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.27.3':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.27.3':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.27.3':
+ optional: true
+
+ '@esbuild/linux-s390x@0.27.3':
+ optional: true
+
+ '@esbuild/linux-x64@0.27.3':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.27.3':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.27.3':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.27.3':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.27.3':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.27.3':
+ optional: true
+
+ '@esbuild/sunos-x64@0.27.3':
+ optional: true
+
+ '@esbuild/win32-arm64@0.27.3':
+ optional: true
+
+ '@esbuild/win32-ia32@0.27.3':
+ optional: true
+
+ '@esbuild/win32-x64@0.27.3':
+ optional: true
+
+ '@eslint-community/eslint-utils@4.9.1(eslint@9.39.1)':
dependencies:
- eslint: 9.24.0
+ eslint: 9.39.1
eslint-visitor-keys: 3.4.3
'@eslint-community/regexpp@4.12.1': {}
- '@eslint/config-array@0.20.0':
+ '@eslint/config-array@0.21.1':
dependencies:
- '@eslint/object-schema': 2.1.6
- debug: 4.3.7
+ '@eslint/object-schema': 2.1.7
+ debug: 4.4.3
minimatch: 3.1.2
transitivePeerDependencies:
- supports-color
- '@eslint/config-helpers@0.2.1': {}
-
- '@eslint/core@0.12.0':
+ '@eslint/config-helpers@0.4.2':
dependencies:
- '@types/json-schema': 7.0.15
+ '@eslint/core': 0.17.0
- '@eslint/core@0.13.0':
+ '@eslint/core@0.17.0':
dependencies:
'@types/json-schema': 7.0.15
'@eslint/eslintrc@3.3.1':
dependencies:
ajv: 6.12.6
- debug: 4.3.7
- espree: 10.3.0
+ debug: 4.4.3
+ espree: 10.4.0
globals: 14.0.0
ignore: 5.3.2
import-fresh: 3.3.0
@@ -1915,13 +2485,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@eslint/js@9.24.0': {}
+ '@eslint/js@9.39.1': {}
- '@eslint/object-schema@2.1.6': {}
+ '@eslint/object-schema@2.1.7': {}
- '@eslint/plugin-kit@0.2.8':
+ '@eslint/plugin-kit@0.4.1':
dependencies:
- '@eslint/core': 0.13.0
+ '@eslint/core': 0.17.0
levn: 0.4.1
'@floating-ui/core@1.7.4':
@@ -2026,7 +2596,7 @@ snapshots:
'@jridgewell/gen-mapping@0.3.8':
dependencies:
'@jridgewell/set-array': 1.2.1
- '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/sourcemap-codec': 1.5.5
'@jridgewell/trace-mapping': 0.3.25
'@jridgewell/resolve-uri@3.1.2': {}
@@ -2038,12 +2608,12 @@ snapshots:
'@jridgewell/gen-mapping': 0.3.8
'@jridgewell/trace-mapping': 0.3.25
- '@jridgewell/sourcemap-codec@1.5.0': {}
+ '@jridgewell/sourcemap-codec@1.5.5': {}
'@jridgewell/trace-mapping@0.3.25':
dependencies:
'@jridgewell/resolve-uri': 3.1.2
- '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/sourcemap-codec': 1.5.5
'@livekit/components-core@0.12.12(livekit-client@2.17.2(@types/dom-mediacapture-record@1.0.22))(tslib@2.8.1)':
dependencies:
@@ -2078,7 +2648,7 @@ snapshots:
'@livekit/protocol@1.44.0':
dependencies:
- '@bufbuild/protobuf': 1.10.0
+ '@bufbuild/protobuf': 1.10.1
'@livekit/track-processors@0.7.0(@types/dom-mediacapture-transform@0.1.11)(livekit-client@2.17.2(@types/dom-mediacapture-record@1.0.22))':
dependencies:
@@ -2090,7 +2660,7 @@ snapshots:
'@next/env@15.2.8': {}
- '@next/eslint-plugin-next@15.2.4':
+ '@next/eslint-plugin-next@15.5.6':
dependencies:
fast-glob: 3.3.1
@@ -2132,6 +2702,81 @@ snapshots:
'@nolyfill/is-core-module@1.0.39': {}
+ '@rollup/rollup-android-arm-eabi@4.57.1':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.57.1':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.57.1':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.57.1':
+ optional: true
+
+ '@rollup/rollup-freebsd-arm64@4.57.1':
+ optional: true
+
+ '@rollup/rollup-freebsd-x64@4.57.1':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.57.1':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.57.1':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.57.1':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.57.1':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-gnu@4.57.1':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-musl@4.57.1':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-gnu@4.57.1':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-musl@4.57.1':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.57.1':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-musl@4.57.1':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.57.1':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.57.1':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.57.1':
+ optional: true
+
+ '@rollup/rollup-openbsd-x64@4.57.1':
+ optional: true
+
+ '@rollup/rollup-openharmony-arm64@4.57.1':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.57.1':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.57.1':
+ optional: true
+
+ '@rollup/rollup-win32-x64-gnu@4.57.1':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.57.1':
+ optional: true
+
'@rtsao/scc@1.1.0': {}
'@rushstack/eslint-patch@1.10.4': {}
@@ -2142,6 +2787,13 @@ snapshots:
dependencies:
tslib: 2.8.1
+ '@types/chai@5.2.3':
+ dependencies:
+ '@types/deep-eql': 4.0.2
+ assertion-error: 2.0.1
+
+ '@types/deep-eql@4.0.2': {}
+
'@types/dom-mediacapture-record@1.0.22': {}
'@types/dom-mediacapture-transform@0.1.11':
@@ -2150,57 +2802,55 @@ snapshots:
'@types/dom-webcodecs@0.1.18': {}
- '@types/estree@1.0.6': {}
-
- '@types/estree@1.0.7': {}
+ '@types/estree@1.0.8': {}
'@types/json-schema@7.0.15': {}
'@types/json5@0.0.29': {}
- '@types/node@22.14.0':
+ '@types/node@24.10.13':
dependencies:
- undici-types: 6.21.0
+ undici-types: 7.16.0
'@types/prop-types@15.7.13': {}
- '@types/react-dom@18.3.6(@types/react@18.3.20)':
+ '@types/react-dom@18.3.7(@types/react@18.3.27)':
dependencies:
- '@types/react': 18.3.20
+ '@types/react': 18.3.27
- '@types/react@18.3.20':
+ '@types/react@18.3.27':
dependencies:
'@types/prop-types': 15.7.13
- csstype: 3.1.3
+ csstype: 3.2.3
- '@typescript-eslint/eslint-plugin@8.8.0(@typescript-eslint/parser@8.8.0(eslint@9.24.0)(typescript@5.8.3))(eslint@9.24.0)(typescript@5.8.3)':
+ '@typescript-eslint/eslint-plugin@8.8.0(@typescript-eslint/parser@8.8.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)':
dependencies:
'@eslint-community/regexpp': 4.12.1
- '@typescript-eslint/parser': 8.8.0(eslint@9.24.0)(typescript@5.8.3)
+ '@typescript-eslint/parser': 8.8.0(eslint@9.39.1)(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.8.0
- '@typescript-eslint/type-utils': 8.8.0(eslint@9.24.0)(typescript@5.8.3)
- '@typescript-eslint/utils': 8.8.0(eslint@9.24.0)(typescript@5.8.3)
+ '@typescript-eslint/type-utils': 8.8.0(eslint@9.39.1)(typescript@5.9.3)
+ '@typescript-eslint/utils': 8.8.0(eslint@9.39.1)(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.8.0
- eslint: 9.24.0
+ eslint: 9.39.1
graphemer: 1.4.0
ignore: 5.3.2
natural-compare: 1.4.0
- ts-api-utils: 1.3.0(typescript@5.8.3)
+ ts-api-utils: 1.3.0(typescript@5.9.3)
optionalDependencies:
- typescript: 5.8.3
+ typescript: 5.9.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/parser@8.8.0(eslint@9.24.0)(typescript@5.8.3)':
+ '@typescript-eslint/parser@8.8.0(eslint@9.39.1)(typescript@5.9.3)':
dependencies:
'@typescript-eslint/scope-manager': 8.8.0
'@typescript-eslint/types': 8.8.0
- '@typescript-eslint/typescript-estree': 8.8.0(typescript@5.8.3)
+ '@typescript-eslint/typescript-estree': 8.8.0(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.8.0
- debug: 4.3.7
- eslint: 9.24.0
+ debug: 4.4.3
+ eslint: 9.39.1
optionalDependencies:
- typescript: 5.8.3
+ typescript: 5.9.3
transitivePeerDependencies:
- supports-color
@@ -2209,42 +2859,42 @@ snapshots:
'@typescript-eslint/types': 8.8.0
'@typescript-eslint/visitor-keys': 8.8.0
- '@typescript-eslint/type-utils@8.8.0(eslint@9.24.0)(typescript@5.8.3)':
+ '@typescript-eslint/type-utils@8.8.0(eslint@9.39.1)(typescript@5.9.3)':
dependencies:
- '@typescript-eslint/typescript-estree': 8.8.0(typescript@5.8.3)
- '@typescript-eslint/utils': 8.8.0(eslint@9.24.0)(typescript@5.8.3)
- debug: 4.3.7
- ts-api-utils: 1.3.0(typescript@5.8.3)
+ '@typescript-eslint/typescript-estree': 8.8.0(typescript@5.9.3)
+ '@typescript-eslint/utils': 8.8.0(eslint@9.39.1)(typescript@5.9.3)
+ debug: 4.4.3
+ ts-api-utils: 1.3.0(typescript@5.9.3)
optionalDependencies:
- typescript: 5.8.3
+ typescript: 5.9.3
transitivePeerDependencies:
- eslint
- supports-color
'@typescript-eslint/types@8.8.0': {}
- '@typescript-eslint/typescript-estree@8.8.0(typescript@5.8.3)':
+ '@typescript-eslint/typescript-estree@8.8.0(typescript@5.9.3)':
dependencies:
'@typescript-eslint/types': 8.8.0
'@typescript-eslint/visitor-keys': 8.8.0
- debug: 4.3.7
+ debug: 4.4.3
fast-glob: 3.3.2
is-glob: 4.0.3
minimatch: 9.0.5
semver: 7.6.3
- ts-api-utils: 1.3.0(typescript@5.8.3)
+ ts-api-utils: 1.3.0(typescript@5.9.3)
optionalDependencies:
- typescript: 5.8.3
+ typescript: 5.9.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/utils@8.8.0(eslint@9.24.0)(typescript@5.8.3)':
+ '@typescript-eslint/utils@8.8.0(eslint@9.39.1)(typescript@5.9.3)':
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@9.24.0)
+ '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.1)
'@typescript-eslint/scope-manager': 8.8.0
'@typescript-eslint/types': 8.8.0
- '@typescript-eslint/typescript-estree': 8.8.0(typescript@5.8.3)
- eslint: 9.24.0
+ '@typescript-eslint/typescript-estree': 8.8.0(typescript@5.9.3)
+ eslint: 9.39.1
transitivePeerDependencies:
- supports-color
- typescript
@@ -2254,6 +2904,48 @@ snapshots:
'@typescript-eslint/types': 8.8.0
eslint-visitor-keys: 3.4.3
+ '@vitest/expect@3.2.4':
+ dependencies:
+ '@types/chai': 5.2.3
+ '@vitest/spy': 3.2.4
+ '@vitest/utils': 3.2.4
+ chai: 5.3.3
+ tinyrainbow: 2.0.0
+
+ '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@24.10.13)(terser@5.39.0))':
+ dependencies:
+ '@vitest/spy': 3.2.4
+ estree-walker: 3.0.3
+ magic-string: 0.30.21
+ optionalDependencies:
+ vite: 7.3.1(@types/node@24.10.13)(terser@5.39.0)
+
+ '@vitest/pretty-format@3.2.4':
+ dependencies:
+ tinyrainbow: 2.0.0
+
+ '@vitest/runner@3.2.4':
+ dependencies:
+ '@vitest/utils': 3.2.4
+ pathe: 2.0.3
+ strip-literal: 3.1.0
+
+ '@vitest/snapshot@3.2.4':
+ dependencies:
+ '@vitest/pretty-format': 3.2.4
+ magic-string: 0.30.21
+ pathe: 2.0.3
+
+ '@vitest/spy@3.2.4':
+ dependencies:
+ tinyspy: 4.0.4
+
+ '@vitest/utils@3.2.4':
+ dependencies:
+ '@vitest/pretty-format': 3.2.4
+ loupe: 3.2.1
+ tinyrainbow: 2.0.0
+
'@webassemblyjs/ast@1.14.1':
dependencies:
'@webassemblyjs/helper-numbers': 1.13.2
@@ -2334,17 +3026,15 @@ snapshots:
'@xtuc/long@4.2.2': {}
- acorn-import-attributes@1.9.5(acorn@8.14.1):
+ acorn-import-attributes@1.9.5(acorn@8.16.0):
dependencies:
- acorn: 8.14.1
+ acorn: 8.16.0
- acorn-jsx@5.3.2(acorn@8.14.0):
+ acorn-jsx@5.3.2(acorn@8.16.0):
dependencies:
- acorn: 8.14.0
+ acorn: 8.16.0
- acorn@8.14.0: {}
-
- acorn@8.14.1: {}
+ acorn@8.16.0: {}
ajv-formats@2.1.1(ajv@8.17.1):
optionalDependencies:
@@ -2448,6 +3138,8 @@ snapshots:
is-array-buffer: 3.0.4
is-shared-array-buffer: 1.0.3
+ assertion-error@2.0.1: {}
+
ast-types-flow@0.0.8: {}
available-typed-arrays@1.0.7:
@@ -2486,6 +3178,8 @@ snapshots:
dependencies:
streamsearch: 1.1.0
+ cac@6.7.14: {}
+
call-bind@1.0.7:
dependencies:
es-define-property: 1.0.0
@@ -2507,11 +3201,21 @@ snapshots:
caniuse-lite@1.0.30001707: {}
+ chai@5.3.3:
+ dependencies:
+ assertion-error: 2.0.1
+ check-error: 2.1.3
+ deep-eql: 5.0.2
+ loupe: 3.2.1
+ pathval: 2.0.1
+
chalk@4.1.2:
dependencies:
ansi-styles: 4.3.0
supports-color: 7.2.0
+ check-error@2.1.3: {}
+
chrome-trace-event@1.0.4: {}
client-only@0.0.1: {}
@@ -2546,7 +3250,7 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
- csstype@3.1.3: {}
+ csstype@3.2.3: {}
damerau-levenshtein@1.0.8: {}
@@ -2572,10 +3276,12 @@ snapshots:
dependencies:
ms: 2.1.3
- debug@4.3.7:
+ debug@4.4.3:
dependencies:
ms: 2.1.3
+ deep-eql@5.0.2: {}
+
deep-equal@2.2.3:
dependencies:
array-buffer-byte-length: 1.0.1
@@ -2711,7 +3417,7 @@ snapshots:
iterator.prototype: 1.1.2
safe-array-concat: 1.1.2
- es-module-lexer@1.6.0: {}
+ es-module-lexer@1.7.0: {}
es-object-atoms@1.0.0:
dependencies:
@@ -2733,25 +3439,54 @@ snapshots:
is-date-object: 1.0.5
is-symbol: 1.0.4
+ esbuild@0.27.3:
+ optionalDependencies:
+ '@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.2.0: {}
escape-string-regexp@4.0.0: {}
- eslint-config-next@15.2.4(eslint@9.24.0)(typescript@5.8.3):
+ eslint-config-next@15.5.6(eslint@9.39.1)(typescript@5.9.3):
dependencies:
- '@next/eslint-plugin-next': 15.2.4
+ '@next/eslint-plugin-next': 15.5.6
'@rushstack/eslint-patch': 1.10.4
- '@typescript-eslint/eslint-plugin': 8.8.0(@typescript-eslint/parser@8.8.0(eslint@9.24.0)(typescript@5.8.3))(eslint@9.24.0)(typescript@5.8.3)
- '@typescript-eslint/parser': 8.8.0(eslint@9.24.0)(typescript@5.8.3)
- eslint: 9.24.0
+ '@typescript-eslint/eslint-plugin': 8.8.0(@typescript-eslint/parser@8.8.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)
+ '@typescript-eslint/parser': 8.8.0(eslint@9.39.1)(typescript@5.9.3)
+ eslint: 9.39.1
eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.8.0(eslint@9.24.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.24.0)
- eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.8.0(eslint@9.24.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.6.3)(eslint@9.24.0)
- eslint-plugin-jsx-a11y: 6.10.0(eslint@9.24.0)
- eslint-plugin-react: 7.37.1(eslint@9.24.0)
- eslint-plugin-react-hooks: 5.2.0(eslint@9.24.0)
+ eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.8.0(eslint@9.39.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.39.1)
+ eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.8.0(eslint@9.39.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.6.3)(eslint@9.39.1)
+ eslint-plugin-jsx-a11y: 6.10.0(eslint@9.39.1)
+ eslint-plugin-react: 7.37.1(eslint@9.39.1)
+ eslint-plugin-react-hooks: 5.2.0(eslint@9.39.1)
optionalDependencies:
- typescript: 5.8.3
+ typescript: 5.9.3
transitivePeerDependencies:
- eslint-import-resolver-webpack
- eslint-plugin-import-x
@@ -2765,37 +3500,37 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.0(eslint@9.24.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.24.0):
+ eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.0(eslint@9.39.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.39.1):
dependencies:
'@nolyfill/is-core-module': 1.0.39
- debug: 4.3.7
+ debug: 4.4.3
enhanced-resolve: 5.18.1
- eslint: 9.24.0
- eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.8.0(eslint@9.24.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.24.0)
+ eslint: 9.39.1
+ eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.8.0(eslint@9.39.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.39.1)
fast-glob: 3.3.2
get-tsconfig: 4.8.1
is-bun-module: 1.2.1
is-glob: 4.0.3
optionalDependencies:
- eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.8.0(eslint@9.24.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.6.3)(eslint@9.24.0)
+ eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.8.0(eslint@9.39.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.6.3)(eslint@9.39.1)
transitivePeerDependencies:
- '@typescript-eslint/parser'
- eslint-import-resolver-node
- eslint-import-resolver-webpack
- supports-color
- eslint-module-utils@2.12.0(@typescript-eslint/parser@8.8.0(eslint@9.24.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.24.0):
+ eslint-module-utils@2.12.0(@typescript-eslint/parser@8.8.0(eslint@9.39.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.39.1):
dependencies:
debug: 3.2.7
optionalDependencies:
- '@typescript-eslint/parser': 8.8.0(eslint@9.24.0)(typescript@5.8.3)
- eslint: 9.24.0
+ '@typescript-eslint/parser': 8.8.0(eslint@9.39.1)(typescript@5.9.3)
+ eslint: 9.39.1
eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.8.0(eslint@9.24.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.24.0)
+ eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.8.0(eslint@9.39.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.39.1)
transitivePeerDependencies:
- supports-color
- eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.0(eslint@9.24.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.6.3)(eslint@9.24.0):
+ eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.0(eslint@9.39.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.6.3)(eslint@9.39.1):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.8
@@ -2804,9 +3539,9 @@ snapshots:
array.prototype.flatmap: 1.3.2
debug: 3.2.7
doctrine: 2.1.0
- eslint: 9.24.0
+ eslint: 9.39.1
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.8.0(eslint@9.24.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.24.0)
+ eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.8.0(eslint@9.39.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.39.1)
hasown: 2.0.2
is-core-module: 2.15.1
is-glob: 4.0.3
@@ -2818,13 +3553,13 @@ snapshots:
string.prototype.trimend: 1.0.8
tsconfig-paths: 3.15.0
optionalDependencies:
- '@typescript-eslint/parser': 8.8.0(eslint@9.24.0)(typescript@5.8.3)
+ '@typescript-eslint/parser': 8.8.0(eslint@9.39.1)(typescript@5.9.3)
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
- supports-color
- eslint-plugin-jsx-a11y@6.10.0(eslint@9.24.0):
+ eslint-plugin-jsx-a11y@6.10.0(eslint@9.39.1):
dependencies:
aria-query: 5.1.3
array-includes: 3.1.8
@@ -2835,7 +3570,7 @@ snapshots:
damerau-levenshtein: 1.0.8
emoji-regex: 9.2.2
es-iterator-helpers: 1.0.19
- eslint: 9.24.0
+ eslint: 9.39.1
hasown: 2.0.2
jsx-ast-utils: 3.3.5
language-tags: 1.0.9
@@ -2844,11 +3579,11 @@ snapshots:
safe-regex-test: 1.0.3
string.prototype.includes: 2.0.0
- eslint-plugin-react-hooks@5.2.0(eslint@9.24.0):
+ eslint-plugin-react-hooks@5.2.0(eslint@9.39.1):
dependencies:
- eslint: 9.24.0
+ eslint: 9.39.1
- eslint-plugin-react@7.37.1(eslint@9.24.0):
+ eslint-plugin-react@7.37.1(eslint@9.39.1):
dependencies:
array-includes: 3.1.8
array.prototype.findlast: 1.2.5
@@ -2856,7 +3591,7 @@ snapshots:
array.prototype.tosorted: 1.1.4
doctrine: 2.1.0
es-iterator-helpers: 1.0.19
- eslint: 9.24.0
+ eslint: 9.39.1
estraverse: 5.3.0
hasown: 2.0.2
jsx-ast-utils: 3.3.5
@@ -2875,38 +3610,37 @@ snapshots:
esrecurse: 4.3.0
estraverse: 4.3.0
- eslint-scope@8.3.0:
+ eslint-scope@8.4.0:
dependencies:
esrecurse: 4.3.0
estraverse: 5.3.0
eslint-visitor-keys@3.4.3: {}
- eslint-visitor-keys@4.2.0: {}
+ eslint-visitor-keys@4.2.1: {}
- eslint@9.24.0:
+ eslint@9.39.1:
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@9.24.0)
+ '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.1)
'@eslint-community/regexpp': 4.12.1
- '@eslint/config-array': 0.20.0
- '@eslint/config-helpers': 0.2.1
- '@eslint/core': 0.12.0
+ '@eslint/config-array': 0.21.1
+ '@eslint/config-helpers': 0.4.2
+ '@eslint/core': 0.17.0
'@eslint/eslintrc': 3.3.1
- '@eslint/js': 9.24.0
- '@eslint/plugin-kit': 0.2.8
+ '@eslint/js': 9.39.1
+ '@eslint/plugin-kit': 0.4.1
'@humanfs/node': 0.16.6
'@humanwhocodes/module-importer': 1.0.1
'@humanwhocodes/retry': 0.4.2
- '@types/estree': 1.0.6
- '@types/json-schema': 7.0.15
+ '@types/estree': 1.0.8
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.6
- debug: 4.3.7
+ debug: 4.4.3
escape-string-regexp: 4.0.0
- eslint-scope: 8.3.0
- eslint-visitor-keys: 4.2.0
- espree: 10.3.0
+ eslint-scope: 8.4.0
+ eslint-visitor-keys: 4.2.1
+ espree: 10.4.0
esquery: 1.6.0
esutils: 2.0.3
fast-deep-equal: 3.1.3
@@ -2924,11 +3658,11 @@ snapshots:
transitivePeerDependencies:
- supports-color
- espree@10.3.0:
+ espree@10.4.0:
dependencies:
- acorn: 8.14.0
- acorn-jsx: 5.3.2(acorn@8.14.0)
- eslint-visitor-keys: 4.2.0
+ acorn: 8.16.0
+ acorn-jsx: 5.3.2(acorn@8.16.0)
+ eslint-visitor-keys: 4.2.1
esquery@1.6.0:
dependencies:
@@ -2942,10 +3676,16 @@ snapshots:
estraverse@5.3.0: {}
+ estree-walker@3.0.3:
+ dependencies:
+ '@types/estree': 1.0.8
+
esutils@2.0.3: {}
events@3.3.0: {}
+ expect-type@1.3.0: {}
+
fast-deep-equal@3.1.3: {}
fast-glob@3.3.1:
@@ -2974,6 +3714,10 @@ snapshots:
dependencies:
reusify: 1.0.4
+ fdir@6.5.0(picomatch@4.0.3):
+ optionalDependencies:
+ picomatch: 4.0.3
+
file-entry-cache@8.0.0:
dependencies:
flat-cache: 4.0.1
@@ -2998,6 +3742,9 @@ snapshots:
dependencies:
is-callable: 1.2.7
+ fsevents@2.3.3:
+ optional: true
+
function-bind@1.1.2: {}
function.prototype.name@1.1.6:
@@ -3044,9 +3791,9 @@ snapshots:
define-properties: 1.2.1
gopd: 1.0.1
- goober@2.1.16(csstype@3.1.3):
+ goober@2.1.16(csstype@3.2.3):
dependencies:
- csstype: 3.1.3
+ csstype: 3.2.3
gopd@1.0.1:
dependencies:
@@ -3211,7 +3958,7 @@ snapshots:
jest-worker@27.5.1:
dependencies:
- '@types/node': 22.14.0
+ '@types/node': 24.10.13
merge-stream: 2.0.0
supports-color: 8.1.1
@@ -3221,6 +3968,8 @@ snapshots:
js-tokens@4.0.0: {}
+ js-tokens@9.0.1: {}
+
js-yaml@4.1.0:
dependencies:
argparse: 2.0.1
@@ -3300,6 +4049,12 @@ snapshots:
dependencies:
js-tokens: 4.0.0
+ loupe@3.2.1: {}
+
+ magic-string@0.30.21:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+
map-obj@5.0.0: {}
merge-stream@2.0.0: {}
@@ -3329,7 +4084,7 @@ snapshots:
ms@2.1.3: {}
- nanoid@3.3.7: {}
+ nanoid@3.3.11: {}
natural-compare@1.4.0: {}
@@ -3432,20 +4187,34 @@ snapshots:
path-parse@1.0.7: {}
+ pathe@2.0.3: {}
+
+ pathval@2.0.1: {}
+
picocolors@1.1.1: {}
picomatch@2.3.1: {}
+ picomatch@4.0.3: {}
+
possible-typed-array-names@1.0.0: {}
postcss@8.4.31:
dependencies:
- nanoid: 3.3.7
+ nanoid: 3.3.11
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ postcss@8.5.6:
+ dependencies:
+ nanoid: 3.3.11
picocolors: 1.1.1
source-map-js: 1.2.1
prelude-ls@1.2.1: {}
+ prettier@3.7.3: {}
+
prop-types@15.8.1:
dependencies:
loose-envify: 1.4.0
@@ -3470,8 +4239,8 @@ snapshots:
react-hot-toast@2.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
- csstype: 3.1.3
- goober: 2.1.16(csstype@3.1.3)
+ csstype: 3.2.3
+ goober: 2.1.16(csstype@3.2.3)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
@@ -3518,15 +4287,41 @@ snapshots:
reusify@1.0.4: {}
+ rollup@4.57.1:
+ dependencies:
+ '@types/estree': 1.0.8
+ optionalDependencies:
+ '@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.3
+
run-parallel@1.2.0:
dependencies:
queue-microtask: 1.2.3
- rxjs@7.8.1:
- dependencies:
- tslib: 2.8.1
- optional: true
-
rxjs@7.8.2:
dependencies:
tslib: 2.8.1
@@ -3633,6 +4428,8 @@ snapshots:
get-intrinsic: 1.2.4
object-inspect: 1.13.2
+ siginfo@2.0.0: {}
+
simple-swizzle@0.2.2:
dependencies:
is-arrayish: 0.3.2
@@ -3653,6 +4450,10 @@ snapshots:
source-map@0.6.1: {}
+ stackback@0.0.2: {}
+
+ std-env@3.10.0: {}
+
stop-iteration-iterator@1.0.0:
dependencies:
internal-slot: 1.0.7
@@ -3707,6 +4508,10 @@ snapshots:
strip-json-comments@3.1.1: {}
+ strip-literal@3.1.0:
+ dependencies:
+ js-tokens: 9.0.1
+
styled-jsx@5.1.6(react@18.3.1):
dependencies:
client-only: 0.0.1
@@ -3736,19 +4541,34 @@ snapshots:
terser@5.39.0:
dependencies:
'@jridgewell/source-map': 0.3.6
- acorn: 8.14.1
+ acorn: 8.16.0
commander: 2.20.3
source-map-support: 0.5.21
+ tinybench@2.9.0: {}
+
+ tinyexec@0.3.2: {}
+
+ tinyglobby@0.2.15:
+ dependencies:
+ fdir: 6.5.0(picomatch@4.0.3)
+ picomatch: 4.0.3
+
tinykeys@3.0.0: {}
+ tinypool@1.1.1: {}
+
+ tinyrainbow@2.0.0: {}
+
+ tinyspy@4.0.4: {}
+
to-regex-range@5.0.1:
dependencies:
is-number: 7.0.0
- ts-api-utils@1.3.0(typescript@5.8.3):
+ ts-api-utils@1.3.0(typescript@5.9.3):
dependencies:
- typescript: 5.8.3
+ typescript: 5.9.3
ts-debounce@4.0.0: {}
@@ -3801,9 +4621,9 @@ snapshots:
typed-emitter@2.1.0:
optionalDependencies:
- rxjs: 7.8.1
+ rxjs: 7.8.2
- typescript@5.8.3: {}
+ typescript@5.9.3: {}
unbox-primitive@1.0.2:
dependencies:
@@ -3812,7 +4632,7 @@ snapshots:
has-symbols: 1.0.3
which-boxed-primitive: 1.0.2
- undici-types@6.21.0: {}
+ undici-types@7.16.0: {}
update-browserslist-db@1.1.3(browserslist@4.24.4):
dependencies:
@@ -3829,6 +4649,81 @@ snapshots:
lodash.debounce: 4.0.8
react: 18.3.1
+ vite-node@3.2.4(@types/node@24.10.13)(terser@5.39.0):
+ dependencies:
+ cac: 6.7.14
+ debug: 4.4.3
+ es-module-lexer: 1.7.0
+ pathe: 2.0.3
+ vite: 7.3.1(@types/node@24.10.13)(terser@5.39.0)
+ transitivePeerDependencies:
+ - '@types/node'
+ - jiti
+ - less
+ - lightningcss
+ - sass
+ - sass-embedded
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+ - tsx
+ - yaml
+
+ vite@7.3.1(@types/node@24.10.13)(terser@5.39.0):
+ dependencies:
+ esbuild: 0.27.3
+ fdir: 6.5.0(picomatch@4.0.3)
+ picomatch: 4.0.3
+ postcss: 8.5.6
+ rollup: 4.57.1
+ tinyglobby: 0.2.15
+ optionalDependencies:
+ '@types/node': 24.10.13
+ fsevents: 2.3.3
+ terser: 5.39.0
+
+ vitest@3.2.4(@types/node@24.10.13)(terser@5.39.0):
+ dependencies:
+ '@types/chai': 5.2.3
+ '@vitest/expect': 3.2.4
+ '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@24.10.13)(terser@5.39.0))
+ '@vitest/pretty-format': 3.2.4
+ '@vitest/runner': 3.2.4
+ '@vitest/snapshot': 3.2.4
+ '@vitest/spy': 3.2.4
+ '@vitest/utils': 3.2.4
+ chai: 5.3.3
+ debug: 4.4.3
+ expect-type: 1.3.0
+ magic-string: 0.30.21
+ pathe: 2.0.3
+ picomatch: 4.0.3
+ std-env: 3.10.0
+ tinybench: 2.9.0
+ tinyexec: 0.3.2
+ tinyglobby: 0.2.15
+ tinypool: 1.1.1
+ tinyrainbow: 2.0.0
+ vite: 7.3.1(@types/node@24.10.13)(terser@5.39.0)
+ vite-node: 3.2.4(@types/node@24.10.13)(terser@5.39.0)
+ why-is-node-running: 2.3.0
+ optionalDependencies:
+ '@types/node': 24.10.13
+ transitivePeerDependencies:
+ - jiti
+ - less
+ - lightningcss
+ - msw
+ - sass
+ - sass-embedded
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+ - tsx
+ - yaml
+
watchpack@2.4.2:
dependencies:
glob-to-regexp: 0.4.1
@@ -3838,16 +4733,16 @@ snapshots:
webpack@5.95.0:
dependencies:
- '@types/estree': 1.0.7
+ '@types/estree': 1.0.8
'@webassemblyjs/ast': 1.14.1
'@webassemblyjs/wasm-edit': 1.14.1
'@webassemblyjs/wasm-parser': 1.14.1
- acorn: 8.14.1
- acorn-import-attributes: 1.9.5(acorn@8.14.1)
+ acorn: 8.16.0
+ acorn-import-attributes: 1.9.5(acorn@8.16.0)
browserslist: 4.24.4
chrome-trace-event: 1.0.4
enhanced-resolve: 5.18.1
- es-module-lexer: 1.6.0
+ es-module-lexer: 1.7.0
eslint-scope: 5.1.1
events: 3.3.0
glob-to-regexp: 0.4.1
@@ -3912,6 +4807,11 @@ snapshots:
dependencies:
isexe: 2.0.0
+ why-is-node-running@2.3.0:
+ dependencies:
+ siginfo: 2.0.0
+ stackback: 0.0.2
+
word-wrap@1.2.5: {}
yocto-queue@0.1.0: {}
diff --git a/public/background-images/ali-kazal-tbw_KQE3Cbg-unsplash.jpg b/public/background-images/ali-kazal-tbw_KQE3Cbg-unsplash.jpg
new file mode 100644
index 0000000..1d133f3
--- /dev/null
+++ b/public/background-images/ali-kazal-tbw_KQE3Cbg-unsplash.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4a3c9eb8da1ef3ddf2439428b49c11abd9a765e056600bd4f1d89a5dfc82778a
+size 52339
diff --git a/public/background-images/samantha-gades-BlIhVfXbi9s-unsplash.jpg b/public/background-images/samantha-gades-BlIhVfXbi9s-unsplash.jpg
new file mode 100644
index 0000000..94add64
--- /dev/null
+++ b/public/background-images/samantha-gades-BlIhVfXbi9s-unsplash.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8bc017736e04acb0188f69cec0aafb88bd6891bfc4a6ff1530665e8dc210dbdf
+size 1273171
diff --git a/styles/SettingsMenu.module.css b/styles/SettingsMenu.module.css
index 2ea4f26..5af6edb 100644
--- a/styles/SettingsMenu.module.css
+++ b/styles/SettingsMenu.module.css
@@ -1,9 +1,3 @@
-.settingsCloseButton {
- position: absolute;
- right: var(--lk-grid-gap);
- bottom: var(--lk-grid-gap);
-}
-
.tabs {
position: relative;
display: flex;