diff --git a/packages/react/package.json b/packages/react/package.json index 474abde3..316dc1f5 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -42,6 +42,7 @@ }, "devDependencies": { "@testing-library/dom": "^10.4.0", + "@testing-library/react": "^16.3.0", "@types/node": "^22.15.3", "@types/react": "^19.1.5", "@vitest/browser": "^3.1.3", @@ -62,8 +63,8 @@ "react": ">=16.8.0" }, "dependencies": { - "@asgardeo/i18n": "workspace:^", "@asgardeo/browser": "workspace:^", + "@asgardeo/i18n": "workspace:^", "@emotion/css": "^11.13.5", "@floating-ui/react": "^0.27.12", "@types/react-dom": "^19.1.5", diff --git a/packages/react/src/__test__/__screenshots__/useBrowserUrl.test.ts/useBrowserUrl-hook-handles-relative-afterSignInUrl-1.png b/packages/react/src/__test__/__screenshots__/useBrowserUrl.test.ts/useBrowserUrl-hook-handles-relative-afterSignInUrl-1.png new file mode 100644 index 00000000..d561bf03 Binary files /dev/null and b/packages/react/src/__test__/__screenshots__/useBrowserUrl.test.ts/useBrowserUrl-hook-handles-relative-afterSignInUrl-1.png differ diff --git a/packages/react/src/__test__/__screenshots__/useForm.test.ts/useForm-hook---full-coverage-setValue-and-validate-on-change-1.png b/packages/react/src/__test__/__screenshots__/useForm.test.ts/useForm-hook---full-coverage-setValue-and-validate-on-change-1.png new file mode 100644 index 00000000..d561bf03 Binary files /dev/null and b/packages/react/src/__test__/__screenshots__/useForm.test.ts/useForm-hook---full-coverage-setValue-and-validate-on-change-1.png differ diff --git a/packages/react/src/__test__/useBranding.test.ts b/packages/react/src/__test__/useBranding.test.ts new file mode 100644 index 00000000..1f0a9dc0 --- /dev/null +++ b/packages/react/src/__test__/useBranding.test.ts @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {renderHook} from '@testing-library/react'; +import useBranding from '../hooks/useBranding'; +import {vi, describe, it, expect, afterEach} from 'vitest'; + +// Mock the context and make default export a vi.fn() +vi.mock('../contexts/Branding/useBrandingContext', () => { + return {default: vi.fn()}; +}); + +// Import the mocked function +import useBrandingContext from '../contexts/Branding/useBrandingContext'; + +describe('useBranding hook', () => { + const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); + + afterEach(() => { + vi.resetAllMocks(); + }); + + it('returns values from context when available', () => { + const mockReturn = { + brandingPreference: {name: 'TestBrand'}, + theme: {colors: {primary: {main: '#000'}}}, + activeTheme: 'light', + isLoading: false, + error: null, + fetchBranding: vi.fn(), + refetch: vi.fn(), + }; + + (useBrandingContext as unknown as ReturnType).mockReturnValue(mockReturn); + + const {result} = renderHook(() => useBranding()); + + expect(result.current.brandingPreference).toEqual(mockReturn.brandingPreference); + expect(result.current.theme).toEqual(mockReturn.theme); + expect(result.current.activeTheme).toBe('light'); + expect(result.current.isLoading).toBe(false); + expect(result.current.error).toBeNull(); + expect(typeof result.current.fetchBranding).toBe('function'); + expect(typeof result.current.refetch).toBe('function'); + }); + + it('returns default values when context is missing', async () => { + (useBrandingContext as unknown as ReturnType).mockImplementation(() => { + throw new Error('Provider missing'); + }); + + const {result} = renderHook(() => useBranding()); + + expect(result.current.brandingPreference).toBeNull(); + expect(result.current.theme).toBeNull(); + expect(result.current.activeTheme).toBeNull(); + expect(result.current.isLoading).toBe(false); + expect(result.current.error).toBeInstanceOf(Error); + + await expect(result.current.fetchBranding()).resolves.toBeUndefined(); + await expect(result.current.refetch()).resolves.toBeUndefined(); + + expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining('useBranding: BrandingProvider not available')); + }); + + it('accepts a config object without breaking', () => { + (useBrandingContext as unknown as ReturnType).mockImplementation(() => { + throw new Error('Provider missing'); + }); + + const {result} = renderHook(() => useBranding({locale: 'en', autoFetch: true})); + + expect(result.current.brandingPreference).toBeNull(); + expect(result.current.theme).toBeNull(); + expect(result.current.activeTheme).toBeNull(); + }); +}); diff --git a/packages/react/src/__test__/useBrowserUrl.test.ts b/packages/react/src/__test__/useBrowserUrl.test.ts new file mode 100644 index 00000000..7390345f --- /dev/null +++ b/packages/react/src/__test__/useBrowserUrl.test.ts @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import useBrowserUrl from '../hooks/useBrowserUrl'; +import {hasAuthParamsInUrl} from '@asgardeo/browser'; +import {vi, describe, it, expect, beforeEach} from 'vitest'; + +// Mock the module +vi.mock('@asgardeo/browser', () => ({ + hasAuthParamsInUrl: vi.fn(), +})); + +describe('useBrowserUrl hook', () => { + const {hasAuthParams} = useBrowserUrl(); + + beforeEach(() => { + vi.clearAllMocks(); + }); + + it('returns true if hasAuthParamsInUrl returns true and URL matches afterSignInUrl', () => { + (hasAuthParamsInUrl as unknown as ReturnType).mockReturnValue(true); + const url = new URL('https://example.com/callback'); + const afterSignInUrl = 'https://example.com/callback'; + expect(hasAuthParams(url, afterSignInUrl)).toBe(true); + }); + + it('returns false if hasAuthParamsInUrl returns false and no error param exists', () => { + (hasAuthParamsInUrl as unknown as ReturnType).mockReturnValue(false); + const url = new URL('https://example.com/callback'); + const afterSignInUrl = 'https://example.com/other'; + expect(hasAuthParams(url, afterSignInUrl)).toBe(false); + }); + + it('returns true if URL contains error param', () => { + (hasAuthParamsInUrl as unknown as ReturnType).mockReturnValue(false); + const url = new URL('https://example.com/callback?error=access_denied'); + const afterSignInUrl = 'https://example.com/other'; + expect(hasAuthParams(url, afterSignInUrl)).toBe(true); + }); + + it('returns false if URL does not match afterSignInUrl and no error param and hasAuthParamsInUrl false', () => { + (hasAuthParamsInUrl as unknown as ReturnType).mockReturnValue(false); + const url = new URL('https://example.com/callback'); + const afterSignInUrl = 'https://example.com/other'; + expect(hasAuthParams(url, afterSignInUrl)).toBe(false); + }); + + // Edge case: trailing slash mismatch + it('normalizes URLs with trailing slashes', () => { + (hasAuthParamsInUrl as unknown as ReturnType).mockReturnValue(true); + const url = new URL('https://example.com/callback/'); + const afterSignInUrl = 'https://example.com/callback'; + expect(hasAuthParams(url, afterSignInUrl)).toBe(false); // still false due to exact match + }); + + // Edge case: relative afterSignInUrl + it('handles relative afterSignInUrl', () => { + (hasAuthParamsInUrl as unknown as ReturnType).mockReturnValue(true); + const url = new URL('https://example.com/callback'); + const afterSignInUrl = '/callback'; + expect(hasAuthParams(url, afterSignInUrl)).toBe(false); // relative URL fails exact match + }); +}); diff --git a/packages/react/src/__test__/useForm.test.ts b/packages/react/src/__test__/useForm.test.ts new file mode 100644 index 00000000..e043cfe5 --- /dev/null +++ b/packages/react/src/__test__/useForm.test.ts @@ -0,0 +1,185 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {renderHook, act} from '@testing-library/react'; +import {useForm, UseFormConfig} from '../hooks/useForm'; +import {vi, describe, it, expect} from 'vitest'; + +interface LoginForm extends Record { + username: string; + password: string; + email?: string; +} + +describe('useForm hook - full coverage', () => { + const initialValues: LoginForm = {username: '', password: '', email: ''}; + const fields = [ + {name: 'username', required: true}, + {name: 'password', required: true}, + {name: 'email', required: false, validator: (value: string) => (value.includes('@') ? null : 'Invalid email')}, + ]; + + const globalValidator = (values: LoginForm) => { + const errors: Record = {}; + if (values.password && values.password.length < 6) { + errors['password'] = 'Password too short'; + } + return errors; + }; + + const config: UseFormConfig = {initialValues, fields, validator: globalValidator}; + + it('initial state', () => { + const {result} = renderHook(() => useForm(config)); + expect(result.current.values).toEqual(initialValues); + expect(result.current.errors).toEqual({}); + expect(result.current.touched).toEqual({}); + expect(result.current.isValid).toBe(true); + expect(result.current.isSubmitted).toBe(false); + }); + + it('setValue and validate on change', () => { + const {result} = renderHook(() => useForm({...config, validateOnChange: true})); + + act(() => result.current.setValue('username', 'Alice')); + expect(result.current.values.username).toBe('Alice'); + + act(() => result.current.setValue('email', 'wrong-email')); + expect(result.current.errors['email']).toBe('Invalid email'); + + act(() => result.current.setValue('email', 'alice@example.com')); + expect(result.current.errors['email']).toBeUndefined(); + }); + + it('bulk setValues', () => { + const {result} = renderHook(() => useForm(config)); + + act(() => result.current.setValues({username: 'Bob', password: '123456'})); + expect(result.current.values.username).toBe('Bob'); + expect(result.current.values.password).toBe('123456'); + }); + + it('setTouched and validate on blur', () => { + const {result} = renderHook(() => useForm(config)); + + act(() => result.current.setTouched('username')); + expect(result.current.touched['username']).toBe(true); + expect(result.current.errors['username']).toBe('This field is required'); + }); + + it('bulk setTouchedFields', () => { + const {result} = renderHook(() => useForm(config)); + act(() => result.current.setTouchedFields({username: true, password: true})); + expect(result.current.touched['username']).toBe(true); + expect(result.current.touched['password']).toBe(true); + }); + + it('touchAllFields triggers validation', () => { + const {result} = renderHook(() => useForm(config)); + act(() => result.current.touchAllFields()); + expect(result.current.touched['username']).toBe(true); + expect(result.current.touched['password']).toBe(true); + expect(result.current.errors['username']).toBe('This field is required'); + }); + + it('setErrors and clearErrors', () => { + const {result} = renderHook(() => useForm(config)); + act(() => result.current.setErrors({username: 'Custom error', password: 'Another error'})); + expect(result.current.errors['username']).toBe('Custom error'); + expect(result.current.errors['password']).toBe('Another error'); + + act(() => result.current.clearErrors()); + expect(result.current.errors).toEqual({}); + }); + + it('validateField returns correct errors', () => { + const {result} = renderHook(() => useForm(config)); + act(() => result.current.setValue('email', 'invalid')); + expect(result.current.validateField('email')).toBe('Invalid email'); + expect(result.current.validateField('username')).toBe('This field is required'); + }); + + it('validateForm returns correct ValidationResult', () => { + const {result} = renderHook(() => useForm(config)); + act(() => result.current.setValue('password', '123')); + const validation = result.current.validateForm(); + expect(validation.isValid).toBe(false); + expect(validation.errors['password']).toBe('Password too short'); + }); + + it('handleSubmit prevents submission if invalid', async () => { + const {result} = renderHook(() => useForm(config)); + const onSubmit = vi.fn(); + + await act(async () => { + await result.current.handleSubmit(onSubmit)({preventDefault: vi.fn()} as any); + }); + + expect(onSubmit).not.toHaveBeenCalled(); + expect(result.current.isSubmitted).toBe(true); + }); + + it('handleSubmit calls onSubmit if valid', async () => { + const {result} = renderHook(() => useForm(config)); + const onSubmit = vi.fn(); + + act(() => { + result.current.setValues({username: 'Alice', password: '123456', email: 'alice@example.com'}); + }); + + await act(async () => { + await result.current.handleSubmit(onSubmit)(); + }); + + expect(onSubmit).toHaveBeenCalledWith({username: 'Alice', password: '123456', email: 'alice@example.com'}); + }); + + it('reset restores initial state', () => { + const {result} = renderHook(() => useForm(config)); + act(() => { + result.current.setValue('username', 'Changed'); + result.current.setTouched('username'); + result.current.setError('username', 'Error'); + result.current.reset(); + }); + + expect(result.current.values).toEqual(initialValues); + expect(result.current.touched).toEqual({}); + expect(result.current.errors).toEqual({}); + expect(result.current.isSubmitted).toBe(false); + }); + + it('getFieldProps works correctly', () => { + const {result} = renderHook(() => useForm(config)); + const props = result.current.getFieldProps('username'); + + expect(props.name).toBe('username'); + expect(props.required).toBe(true); + expect(props.value).toBe(''); + expect(props.touched).toBe(false); + expect(props.error).toBeUndefined(); + expect(typeof props.onBlur).toBe('function'); + expect(typeof props.onChange).toBe('function'); + + act(() => props.onChange('NewValue')); + expect(result.current.values.username).toBe('NewValue'); + + act(() => props.onBlur()); + expect(result.current.touched['username']).toBe(true); + }); +}); diff --git a/packages/react/src/__test__/useTranslation.test.ts b/packages/react/src/__test__/useTranslation.test.ts new file mode 100644 index 00000000..34369ce7 --- /dev/null +++ b/packages/react/src/__test__/useTranslation.test.ts @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {renderHook} from '@testing-library/react'; +import React from 'react'; +import useTranslation from '../hooks/useTranslation'; +import I18nContext, {I18nContextValue} from '../contexts/I18n/I18nContext'; +import {I18nBundle, I18nTextDirection} from '@asgardeo/i18n'; +import {vi, describe, it, expect} from 'vitest'; + +// --- MOCK @asgardeo/browser --- +vi.mock('@asgardeo/browser', () => ({ + deepMerge: vi.fn((a, b) => ({...a, ...b})), + I18nPreferences: vi.fn(), +})); + +// --- Mock Data --- +const globalBundles: Record = { + en: { + translations: {welcome: 'Welcome', goodbye: 'Goodbye', helloName: 'Hello, {name}!'} as any, + metadata: { + localeCode: 'en-US', + countryCode: 'US', + languageCode: 'en', + displayName: 'English', + direction: 'ltr' as I18nTextDirection, + }, + }, + es: { + translations: {welcome: 'Bienvenido', goodbye: 'Adiós'} as any, + metadata: { + localeCode: 'es-ES', + countryCode: 'ES', + languageCode: 'es', + displayName: 'Spanish', + direction: 'ltr' as I18nTextDirection, + }, + }, +}; + +const mockSetLanguage = vi.fn(); + +// --- Context helper --- +const createTFunction = (lang: 'en' | 'es') => (key: string, params?: Record) => { + const translation = + (globalBundles[lang].translations as any)[key] || (globalBundles['en'].translations as any)[key] || key; + if (!params) return translation; + return Object.keys(params).reduce((str, p) => str.replace(`{${p}}`, params[p]), translation); +}; + +const contextValue: I18nContextValue = { + t: createTFunction('en'), + currentLanguage: 'en', + setLanguage: mockSetLanguage, + bundles: globalBundles, + fallbackLanguage: 'en', +}; + +const wrapper: React.FC<{children: React.ReactNode}> = ({children}) => + React.createElement(I18nContext.Provider, {value: contextValue}, children); + +const esContext: I18nContextValue = { + ...contextValue, + currentLanguage: 'es', + t: createTFunction('es'), +}; + +const esWrapper: React.FC<{children: React.ReactNode}> = ({children}) => + React.createElement(I18nContext.Provider, {value: esContext}, children); + +// --- Tests --- +describe('useTranslation hook', () => { + it('returns translations for current language', () => { + const {result} = renderHook(() => useTranslation(), {wrapper}); + const t = result.current.t; + + expect(t('welcome')).toBe('Welcome'); + expect(t('goodbye')).toBe('Goodbye'); + expect(t('nonexistent')).toBe('nonexistent'); + }); + + it('supports translation parameters', () => { + const {result} = renderHook(() => useTranslation(), {wrapper}); + const t = result.current.t; + + expect(t('helloName', {name: 'Alice'})).toBe('Hello, Alice!'); + }); + + it('falls back to fallback language if key missing in current language', () => { + const {result} = renderHook(() => useTranslation(), {wrapper: esWrapper}); + const t = result.current.t; + + expect(t('helloName', {name: 'Bob'})).toBe('Hello, Bob!'); + }); + + it('allows changing language via setLanguage', () => { + const {result} = renderHook(() => useTranslation(), {wrapper}); + + result.current.setLanguage('es'); + expect(mockSetLanguage).toHaveBeenCalledWith('es'); + }); + + it('merges component-level bundles correctly', () => { + const componentBundles = { + bundles: { + en: { + translations: {welcome: 'Welcome Component'} as any, + metadata: { + localeCode: 'en-US', + countryCode: 'US', + languageCode: 'en', + displayName: 'English', + direction: 'ltr' as I18nTextDirection, + }, + }, + }, + }; + + const {result} = renderHook(() => useTranslation(componentBundles), {wrapper}); + const t = result.current.t; + + expect(t('welcome')).toBe('Welcome Component'); + expect(t('goodbye')).toBe('Goodbye'); + }); + + it('returns availableLanguages correctly', () => { + const {result} = renderHook(() => useTranslation(), {wrapper}); + expect(result.current.availableLanguages).toEqual(['en', 'es']); + }); + + it('throws error if used outside of I18nProvider', () => { + expect(() => renderHook(() => useTranslation())).toThrow(/useTranslation must be used within an I18nProvider/); + }); +}); diff --git a/packages/react/tsconfig.spec.json b/packages/react/tsconfig.spec.json index 46a76e28..74d909dd 100644 --- a/packages/react/tsconfig.spec.json +++ b/packages/react/tsconfig.spec.json @@ -2,12 +2,12 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "dist", - "module": "commonjs", - "types": ["jest", "node"] + "module": "esnext", + "types": ["vitest", "node"] }, "include": [ "test-configs", - "jest.config.js", + "vitest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.test.js", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a741c5af..da1e223d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -384,6 +384,9 @@ importers: '@testing-library/dom': specifier: ^10.4.0 version: 10.4.0 + '@testing-library/react': + specifier: ^16.3.0 + version: 16.3.0(@testing-library/dom@10.4.0)(@types/react-dom@19.1.5(@types/react@19.1.5))(@types/react@19.1.5)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@types/node': specifier: ^22.15.3 version: 22.15.30 @@ -951,6 +954,18 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.25.11': + resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.25.9': resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} engines: {node: '>=18'} @@ -963,6 +978,18 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.25.11': + resolution: {integrity: sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.25.9': resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} engines: {node: '>=18'} @@ -975,6 +1002,18 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.25.11': + resolution: {integrity: sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.25.9': resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} engines: {node: '>=18'} @@ -987,6 +1026,18 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.25.11': + resolution: {integrity: sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.25.9': resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} engines: {node: '>=18'} @@ -999,6 +1050,18 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.25.11': + resolution: {integrity: sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.25.9': resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} engines: {node: '>=18'} @@ -1011,6 +1074,18 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.25.11': + resolution: {integrity: sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.25.9': resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} engines: {node: '>=18'} @@ -1023,6 +1098,18 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.25.11': + resolution: {integrity: sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.25.9': resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} engines: {node: '>=18'} @@ -1035,6 +1122,18 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.25.11': + resolution: {integrity: sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.9': resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} engines: {node: '>=18'} @@ -1047,6 +1146,18 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.25.11': + resolution: {integrity: sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.25.9': resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} engines: {node: '>=18'} @@ -1059,6 +1170,18 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.25.11': + resolution: {integrity: sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.25.9': resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} engines: {node: '>=18'} @@ -1071,6 +1194,18 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.25.11': + resolution: {integrity: sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.25.9': resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} engines: {node: '>=18'} @@ -1083,6 +1218,18 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.25.11': + resolution: {integrity: sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.25.9': resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} engines: {node: '>=18'} @@ -1095,6 +1242,18 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.25.11': + resolution: {integrity: sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.25.9': resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} engines: {node: '>=18'} @@ -1107,6 +1266,18 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.25.11': + resolution: {integrity: sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.25.9': resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} engines: {node: '>=18'} @@ -1119,6 +1290,18 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.25.11': + resolution: {integrity: sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.25.9': resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} engines: {node: '>=18'} @@ -1131,6 +1314,18 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.25.11': + resolution: {integrity: sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.25.9': resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} engines: {node: '>=18'} @@ -1143,6 +1338,18 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.25.11': + resolution: {integrity: sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.25.9': resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} engines: {node: '>=18'} @@ -1155,6 +1362,18 @@ packages: cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.25.11': + resolution: {integrity: sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-arm64@0.25.9': resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} engines: {node: '>=18'} @@ -1167,6 +1386,18 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.25.11': + resolution: {integrity: sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.9': resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} engines: {node: '>=18'} @@ -1179,6 +1410,18 @@ packages: cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.25.11': + resolution: {integrity: sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-arm64@0.25.9': resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} engines: {node: '>=18'} @@ -1191,6 +1434,18 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.25.11': + resolution: {integrity: sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.9': resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} engines: {node: '>=18'} @@ -1203,6 +1458,18 @@ packages: cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.25.11': + resolution: {integrity: sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/openharmony-arm64@0.25.9': resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} engines: {node: '>=18'} @@ -1215,6 +1482,18 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.25.11': + resolution: {integrity: sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.25.9': resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} engines: {node: '>=18'} @@ -1227,6 +1506,18 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.25.11': + resolution: {integrity: sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.25.9': resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} engines: {node: '>=18'} @@ -1239,6 +1530,18 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.25.11': + resolution: {integrity: sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.25.9': resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} engines: {node: '>=18'} @@ -1251,6 +1554,18 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.25.11': + resolution: {integrity: sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.25.9': resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} engines: {node: '>=18'} @@ -2184,6 +2499,21 @@ packages: resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} engines: {node: '>=18'} + '@testing-library/react@16.3.0': + resolution: {integrity: sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==} + engines: {node: '>=18'} + peerDependencies: + '@testing-library/dom': ^10.0.0 + '@types/react': ^18.0.0 || ^19.0.0 + '@types/react-dom': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@testing-library/user-event@14.6.1': resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} engines: {node: '>=12', npm: '>=6'} @@ -3456,6 +3786,16 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.25.11: + resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true + esbuild@0.25.9: resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} engines: {node: '>=18'} @@ -7094,156 +7434,312 @@ snapshots: '@esbuild/aix-ppc64@0.25.10': optional: true + '@esbuild/aix-ppc64@0.25.11': + optional: true + + '@esbuild/aix-ppc64@0.25.12': + optional: true + '@esbuild/aix-ppc64@0.25.9': optional: true '@esbuild/android-arm64@0.25.10': optional: true + '@esbuild/android-arm64@0.25.11': + optional: true + + '@esbuild/android-arm64@0.25.12': + optional: true + '@esbuild/android-arm64@0.25.9': optional: true '@esbuild/android-arm@0.25.10': optional: true + '@esbuild/android-arm@0.25.11': + optional: true + + '@esbuild/android-arm@0.25.12': + optional: true + '@esbuild/android-arm@0.25.9': optional: true '@esbuild/android-x64@0.25.10': optional: true + '@esbuild/android-x64@0.25.11': + optional: true + + '@esbuild/android-x64@0.25.12': + optional: true + '@esbuild/android-x64@0.25.9': optional: true '@esbuild/darwin-arm64@0.25.10': optional: true + '@esbuild/darwin-arm64@0.25.11': + optional: true + + '@esbuild/darwin-arm64@0.25.12': + optional: true + '@esbuild/darwin-arm64@0.25.9': optional: true '@esbuild/darwin-x64@0.25.10': optional: true + '@esbuild/darwin-x64@0.25.11': + optional: true + + '@esbuild/darwin-x64@0.25.12': + optional: true + '@esbuild/darwin-x64@0.25.9': optional: true '@esbuild/freebsd-arm64@0.25.10': optional: true + '@esbuild/freebsd-arm64@0.25.11': + optional: true + + '@esbuild/freebsd-arm64@0.25.12': + optional: true + '@esbuild/freebsd-arm64@0.25.9': optional: true '@esbuild/freebsd-x64@0.25.10': optional: true + '@esbuild/freebsd-x64@0.25.11': + optional: true + + '@esbuild/freebsd-x64@0.25.12': + optional: true + '@esbuild/freebsd-x64@0.25.9': optional: true '@esbuild/linux-arm64@0.25.10': optional: true + '@esbuild/linux-arm64@0.25.11': + optional: true + + '@esbuild/linux-arm64@0.25.12': + optional: true + '@esbuild/linux-arm64@0.25.9': optional: true '@esbuild/linux-arm@0.25.10': optional: true + '@esbuild/linux-arm@0.25.11': + optional: true + + '@esbuild/linux-arm@0.25.12': + optional: true + '@esbuild/linux-arm@0.25.9': optional: true '@esbuild/linux-ia32@0.25.10': optional: true + '@esbuild/linux-ia32@0.25.11': + optional: true + + '@esbuild/linux-ia32@0.25.12': + optional: true + '@esbuild/linux-ia32@0.25.9': optional: true '@esbuild/linux-loong64@0.25.10': optional: true + '@esbuild/linux-loong64@0.25.11': + optional: true + + '@esbuild/linux-loong64@0.25.12': + optional: true + '@esbuild/linux-loong64@0.25.9': optional: true '@esbuild/linux-mips64el@0.25.10': optional: true + '@esbuild/linux-mips64el@0.25.11': + optional: true + + '@esbuild/linux-mips64el@0.25.12': + optional: true + '@esbuild/linux-mips64el@0.25.9': optional: true '@esbuild/linux-ppc64@0.25.10': optional: true + '@esbuild/linux-ppc64@0.25.11': + optional: true + + '@esbuild/linux-ppc64@0.25.12': + optional: true + '@esbuild/linux-ppc64@0.25.9': optional: true '@esbuild/linux-riscv64@0.25.10': optional: true + '@esbuild/linux-riscv64@0.25.11': + optional: true + + '@esbuild/linux-riscv64@0.25.12': + optional: true + '@esbuild/linux-riscv64@0.25.9': optional: true '@esbuild/linux-s390x@0.25.10': optional: true + '@esbuild/linux-s390x@0.25.11': + optional: true + + '@esbuild/linux-s390x@0.25.12': + optional: true + '@esbuild/linux-s390x@0.25.9': optional: true '@esbuild/linux-x64@0.25.10': optional: true + '@esbuild/linux-x64@0.25.11': + optional: true + + '@esbuild/linux-x64@0.25.12': + optional: true + '@esbuild/linux-x64@0.25.9': optional: true '@esbuild/netbsd-arm64@0.25.10': optional: true + '@esbuild/netbsd-arm64@0.25.11': + optional: true + + '@esbuild/netbsd-arm64@0.25.12': + optional: true + '@esbuild/netbsd-arm64@0.25.9': optional: true '@esbuild/netbsd-x64@0.25.10': optional: true + '@esbuild/netbsd-x64@0.25.11': + optional: true + + '@esbuild/netbsd-x64@0.25.12': + optional: true + '@esbuild/netbsd-x64@0.25.9': optional: true '@esbuild/openbsd-arm64@0.25.10': optional: true + '@esbuild/openbsd-arm64@0.25.11': + optional: true + + '@esbuild/openbsd-arm64@0.25.12': + optional: true + '@esbuild/openbsd-arm64@0.25.9': optional: true '@esbuild/openbsd-x64@0.25.10': optional: true + '@esbuild/openbsd-x64@0.25.11': + optional: true + + '@esbuild/openbsd-x64@0.25.12': + optional: true + '@esbuild/openbsd-x64@0.25.9': optional: true '@esbuild/openharmony-arm64@0.25.10': optional: true + '@esbuild/openharmony-arm64@0.25.11': + optional: true + + '@esbuild/openharmony-arm64@0.25.12': + optional: true + '@esbuild/openharmony-arm64@0.25.9': optional: true '@esbuild/sunos-x64@0.25.10': optional: true + '@esbuild/sunos-x64@0.25.11': + optional: true + + '@esbuild/sunos-x64@0.25.12': + optional: true + '@esbuild/sunos-x64@0.25.9': optional: true '@esbuild/win32-arm64@0.25.10': optional: true + '@esbuild/win32-arm64@0.25.11': + optional: true + + '@esbuild/win32-arm64@0.25.12': + optional: true + '@esbuild/win32-arm64@0.25.9': optional: true '@esbuild/win32-ia32@0.25.10': optional: true + '@esbuild/win32-ia32@0.25.11': + optional: true + + '@esbuild/win32-ia32@0.25.12': + optional: true + '@esbuild/win32-ia32@0.25.9': optional: true '@esbuild/win32-x64@0.25.10': optional: true + '@esbuild/win32-x64@0.25.11': + optional: true + + '@esbuild/win32-x64@0.25.12': + optional: true + '@esbuild/win32-x64@0.25.9': optional: true @@ -7988,6 +8484,16 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 + '@testing-library/react@16.3.0(@testing-library/dom@10.4.0)(@types/react-dom@19.1.5(@types/react@19.1.5))(@types/react@19.1.5)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@babel/runtime': 7.27.1 + '@testing-library/dom': 10.4.0 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.5 + '@types/react-dom': 19.1.5(@types/react@19.1.5) + '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.0)': dependencies: '@testing-library/dom': 10.4.0 @@ -9694,7 +10200,7 @@ snapshots: esbuild-plugin-inline-worker@0.1.1: dependencies: - esbuild: 0.25.10 + esbuild: 0.25.12 find-cache-dir: 3.3.2 esbuild-plugin-polyfill-node@0.3.0(esbuild@0.25.9): @@ -9743,6 +10249,64 @@ snapshots: '@esbuild/win32-ia32': 0.25.10 '@esbuild/win32-x64': 0.25.10 + esbuild@0.25.11: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.11 + '@esbuild/android-arm': 0.25.11 + '@esbuild/android-arm64': 0.25.11 + '@esbuild/android-x64': 0.25.11 + '@esbuild/darwin-arm64': 0.25.11 + '@esbuild/darwin-x64': 0.25.11 + '@esbuild/freebsd-arm64': 0.25.11 + '@esbuild/freebsd-x64': 0.25.11 + '@esbuild/linux-arm': 0.25.11 + '@esbuild/linux-arm64': 0.25.11 + '@esbuild/linux-ia32': 0.25.11 + '@esbuild/linux-loong64': 0.25.11 + '@esbuild/linux-mips64el': 0.25.11 + '@esbuild/linux-ppc64': 0.25.11 + '@esbuild/linux-riscv64': 0.25.11 + '@esbuild/linux-s390x': 0.25.11 + '@esbuild/linux-x64': 0.25.11 + '@esbuild/netbsd-arm64': 0.25.11 + '@esbuild/netbsd-x64': 0.25.11 + '@esbuild/openbsd-arm64': 0.25.11 + '@esbuild/openbsd-x64': 0.25.11 + '@esbuild/openharmony-arm64': 0.25.11 + '@esbuild/sunos-x64': 0.25.11 + '@esbuild/win32-arm64': 0.25.11 + '@esbuild/win32-ia32': 0.25.11 + '@esbuild/win32-x64': 0.25.11 + + esbuild@0.25.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.12 + '@esbuild/android-arm': 0.25.12 + '@esbuild/android-arm64': 0.25.12 + '@esbuild/android-x64': 0.25.12 + '@esbuild/darwin-arm64': 0.25.12 + '@esbuild/darwin-x64': 0.25.12 + '@esbuild/freebsd-arm64': 0.25.12 + '@esbuild/freebsd-x64': 0.25.12 + '@esbuild/linux-arm': 0.25.12 + '@esbuild/linux-arm64': 0.25.12 + '@esbuild/linux-ia32': 0.25.12 + '@esbuild/linux-loong64': 0.25.12 + '@esbuild/linux-mips64el': 0.25.12 + '@esbuild/linux-ppc64': 0.25.12 + '@esbuild/linux-riscv64': 0.25.12 + '@esbuild/linux-s390x': 0.25.12 + '@esbuild/linux-x64': 0.25.12 + '@esbuild/netbsd-arm64': 0.25.12 + '@esbuild/netbsd-x64': 0.25.12 + '@esbuild/openbsd-arm64': 0.25.12 + '@esbuild/openbsd-x64': 0.25.12 + '@esbuild/openharmony-arm64': 0.25.12 + '@esbuild/sunos-x64': 0.25.12 + '@esbuild/win32-arm64': 0.25.12 + '@esbuild/win32-ia32': 0.25.12 + '@esbuild/win32-x64': 0.25.12 + esbuild@0.25.9: optionalDependencies: '@esbuild/aix-ppc64': 0.25.9 @@ -13171,7 +13735,7 @@ snapshots: vite@7.1.4(@types/node@20.17.50)(jiti@2.6.0)(lightningcss@1.30.1)(sass-embedded@1.92.1)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0): dependencies: - esbuild: 0.25.10 + esbuild: 0.25.11 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6