diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index a353720..0000000 --- a/.eslintignore +++ /dev/null @@ -1,10 +0,0 @@ -# typescript defs -*.d.ts - -# configs -/config -jest.config.js -rollup.config.js - -# build -morfi-test-utils/npm/dist \ No newline at end of file diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 9a4cdd3..0000000 --- a/.eslintrc +++ /dev/null @@ -1,47 +0,0 @@ -{ - "extends": [ - "eslint:recommended", - "plugin:react/recommended", - "plugin:react-hooks/recommended", - "plugin:@typescript-eslint/recommended", - "prettier" - ], - "plugins": ["prettier", "@typescript-eslint"], - "env": { - "jest": true, - "browser": true, - "es6": true, - "node": true - }, - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 2020, - "sourceType": "module", - "ecmaFeatures": { - "jsx": true - } - }, - "rules": { - "prettier/prettier": "warn", - "arrow-body-style": ["warn", "as-needed"], - "no-duplicate-imports": "warn", - "react-hooks/exhaustive-deps": ["warn"], - "no-console": "warn", - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-unused-vars": [ - "warn", - { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_", "caughtErrorsIgnorePattern": "^_" } - ] - }, - "settings": { - "react": { - "version": "detect" - } - }, - "overrides": [{ - "files": ["test/**", "test-utils/**", "docs/**"], - "rules": { - "@typescript-eslint/no-non-null-assertion": "off" - } - }] -} diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 80f30c2..a49601f 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -16,7 +16,7 @@ jobs: - name: Test run: pnpm test - name: Coveralls - uses: coverallsapp/github-action@master + uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Build docs diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index a31a57d..0000000 --- a/.prettierrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "useTabs": false, - "printWidth": 120, - "tabWidth": 4, - "singleQuote": true, - "trailingComma": "es5", - "bracketSameLine": true, - "parser": "typescript" -} diff --git a/docs/src/App.tsx b/docs/src/App.tsx index 173b42a..8e1aa5e 100644 --- a/docs/src/App.tsx +++ b/docs/src/App.tsx @@ -1,73 +1,76 @@ -import React, { useCallback, useState } from 'react'; -import { Link, Route, Routes, useLocation } from 'react-router-dom'; -import { Main } from './Main'; -import { FirstSample } from './samples/first/FirstSample'; -import { ValidationSample } from './samples/validation-types/ValidationSample'; -import { AsyncValidationSample } from './samples/async/AsyncValidationSample'; -import { Arrow } from './icons/Arrow'; -import { useChangeEffect } from './hooks/useChangeEffect'; -import { PasswordRepeatForm } from './samples/password-repeat/PasswordRepeatForm'; +import React, { useCallback, useState } from "react"; +import { Link, Route, Routes, useLocation } from "react-router-dom"; +import { useChangeEffect } from "./hooks/useChangeEffect"; +import { Arrow } from "./icons/Arrow"; +import { Main } from "./Main"; +import { AsyncValidationSample } from "./samples/async/AsyncValidationSample"; +import { FirstSample } from "./samples/first/FirstSample"; +import { PasswordRepeatForm } from "./samples/password-repeat/PasswordRepeatForm"; +import { ValidationSample } from "./samples/validation-types/ValidationSample"; type Sample = { pathname: string; label: string }; const Samples: Sample[] = [ - { pathname: '/', label: 'First sample' }, - { pathname: '/validation/types', label: 'Validation types' }, - { pathname: '/validation/async', label: 'Async validation' }, - { pathname: '/validation/passwordRepeat', label: 'Password repetition' }, + { pathname: "/", label: "First sample" }, + { pathname: "/validation/types", label: "Validation types" }, + { pathname: "/validation/async", label: "Async validation" }, + { pathname: "/validation/passwordRepeat", label: "Password repetition" }, ]; export type SidebarProps = { open?: boolean; toggle: () => void }; export const Sidebar: React.FC = ({ open, toggle }) => { - const location = useLocation(); + const location = useLocation(); - useChangeEffect(() => { - toggle(); - }, [location.pathname, toggle]); + useChangeEffect(() => { + toggle(); + }, [location.pathname, toggle]); - let sideBarFadeClass = undefined; - if (open !== undefined) { - sideBarFadeClass = open ? 'fade-in' : 'fade-out'; - } - return ( - - ); + let sideBarFadeClass = undefined; + if (open !== undefined) { + sideBarFadeClass = open ? "fade-in" : "fade-out"; + } + return ( + + ); }; export const App: React.FC = () => { - const [sideBarOpen, setSidebarOpen] = useState(); - const toggleSideBar = useCallback(() => setSidebarOpen((s) => !s), []); + const [sideBarOpen, setSidebarOpen] = useState(); + const toggleSideBar = useCallback(() => setSidebarOpen((s) => !s), []); - return ( -
- -
- - } /> - } /> - } /> - } /> - -
-
- ); + return ( +
+ +
+ + } /> + } /> + } + /> + } /> + +
+
+ ); }; diff --git a/docs/src/Main.tsx b/docs/src/Main.tsx index 2edc8e2..2422fef 100644 --- a/docs/src/Main.tsx +++ b/docs/src/Main.tsx @@ -1,19 +1,29 @@ -import React from 'react'; +import React from "react"; -type FormContainerProps = { children: React.ReactNode; toggleSideBar: () => void }; +type FormContainerProps = { + children: React.ReactNode; + toggleSideBar: () => void; +}; -export const Main: React.FC = ({ children, toggleSideBar }) => ( -
-
- menu - logo -

Welcome to morfi

-
-
{children}
-
+export const Main: React.FC = ({ + children, + toggleSideBar, +}) => ( +
+
+ menu + logo +

Welcome to morfi

+
+
{children}
+
); diff --git a/docs/src/fields/Basic.tsx b/docs/src/fields/Basic.tsx index 12724ba..c3ad675 100644 --- a/docs/src/fields/Basic.tsx +++ b/docs/src/fields/Basic.tsx @@ -1,51 +1,60 @@ -import React from 'react'; -import type { ErrorMessage } from 'morfi'; -import messages from '../../messages.json'; -import { Spinner } from '../icons/Spinner'; +import React from "react"; +import type { ErrorMessage } from "morfi"; +import messages from "../../messages.json"; +import { Spinner } from "../icons/Spinner"; export const __ = (msgOrID: ErrorMessage): string => { - const id = typeof msgOrID === 'string' ? msgOrID : msgOrID.id; - const values = typeof msgOrID === 'string' ? undefined : msgOrID.values; - let result = (messages as Record)[id]; - if (result && values) { - result = Object.keys(values).reduce( - (red: string, key: string) => red.replace(`{${key}}`, String(values[key])), - result - ); - } - return result!; + const id = typeof msgOrID === "string" ? msgOrID : msgOrID.id; + const values = typeof msgOrID === "string" ? undefined : msgOrID.values; + let result = (messages as Record)[id]; + if (result && values) { + result = Object.keys(values).reduce( + (red: string, key: string) => + red.replace(`{${key}}`, String(values[key])), + result, + ); + } + return result!; }; -export const Label = ({ label, required = false }: { label: string; required?: boolean }) => ( - -); +export const Label = ({ + label, + required = false, +}: { + label: string; + required?: boolean; +}) => ; export const DisplayError = ({ error }: { error: ErrorMessage }) => ( - {__(error)} + {__(error)} ); export const onActionWrap = - (cb?: (arg: any) => void, preventDefault = true): React.EventHandler => - (event) => { - if (preventDefault) { - event.preventDefault(); - } - if (cb) { - cb(event.target.value); - } - }; + (cb?: (arg: any) => void, preventDefault = true): React.EventHandler => + (event) => { + if (preventDefault) { + event.preventDefault(); + } + if (cb) { + cb(event.target.value); + } + }; type ButtonProps = { - children: React.ReactNode; - loading?: boolean; - disabled?: boolean; - type?: 'submit' | 'button'; - onClick?: () => void; + children: React.ReactNode; + loading?: boolean; + disabled?: boolean; + type?: "submit" | "button"; + onClick?: () => void; }; -export const Button: React.FC = ({ children, loading, ...rest }) => ( - +export const Button: React.FC = ({ + children, + loading, + ...rest +}) => ( + ); diff --git a/docs/src/fields/FormInput.tsx b/docs/src/fields/FormInput.tsx index 901787f..76131cc 100644 --- a/docs/src/fields/FormInput.tsx +++ b/docs/src/fields/FormInput.tsx @@ -1,66 +1,66 @@ -import React, { useCallback, useState } from 'react'; -import { DisplayError, Label, onActionWrap } from './Basic'; -import { Eye } from '../icons/Eye'; -import { Spinner } from '../icons/Spinner'; -import { FieldControls, FormField, Morfi } from 'morfi'; +import React, { useCallback, useState } from "react"; +import { FieldControls, FormField, Morfi } from "morfi"; +import { Eye } from "../icons/Eye"; +import { Spinner } from "../icons/Spinner"; +import { DisplayError, Label, onActionWrap } from "./Basic"; -type AllowedTypes = 'text' | 'password'; +type AllowedTypes = "text" | "password"; type CommonInputProps = { - label?: string; - className?: string; - autoFocus?: boolean; - disabled?: boolean; - type?: AllowedTypes; - placeholder?: string; - loading?: boolean; + label?: string; + className?: string; + autoFocus?: boolean; + disabled?: boolean; + type?: AllowedTypes; + placeholder?: string; + loading?: boolean; }; type InputProps = FieldControls & CommonInputProps; export const Input: React.FC = ({ - value = '', - label, - error, - required, - className = 'form-group', - onChange, - onBlur, - autoFocus, - disabled, - type = 'text', - placeholder, - loading, + value = "", + label, + error, + required, + className = "form-group", + onChange, + onBlur, + autoFocus, + disabled, + type = "text", + placeholder, + loading, }) => { - const [showPw, setShowPw] = useState(false); - const toggleShowPw = useCallback(() => setShowPw((s) => !s), []); - const usedType = type !== 'password' ? type : showPw ? 'text' : 'password'; + const [showPw, setShowPw] = useState(false); + const toggleShowPw = useCallback(() => setShowPw((s) => !s), []); + const usedType = type !== "password" ? type : showPw ? "text" : "password"; - return ( -
- {label &&
- ); + return ( +
+ {label &&
+ ); }; type FormInputProps = { field: FormField } & CommonInputProps; export const FormInput: React.FC = ({ field, ...rest }) => { - const fieldProps = Morfi.useField(field); - return ; + const fieldProps = Morfi.useField(field); + return ; }; diff --git a/docs/src/fields/FormNumberInput.tsx b/docs/src/fields/FormNumberInput.tsx index 5e4b45c..b6fcbef 100644 --- a/docs/src/fields/FormNumberInput.tsx +++ b/docs/src/fields/FormNumberInput.tsx @@ -1,49 +1,52 @@ -import React from 'react'; -import { DisplayError, Label, onActionWrap } from './Basic'; -import { Morfi, FieldControls, FormField } from 'morfi'; +import React from "react"; +import { FieldControls, FormField, Morfi } from "morfi"; +import { DisplayError, Label, onActionWrap } from "./Basic"; type CommonNumberInputProps = { - label?: string; - className?: string; - autoFocus?: boolean; - disabled?: boolean; + label?: string; + className?: string; + autoFocus?: boolean; + disabled?: boolean; }; -type NumberInputProps = FieldControls & CommonNumberInputProps; +type NumberInputProps = FieldControls & + CommonNumberInputProps; export const NumberInput = ({ - value, - label, - error, - required, - className = 'form-group', - onChange, - onBlur, - autoFocus, - disabled, + value, + label, + error, + required, + className = "form-group", + onChange, + onBlur, + autoFocus, + disabled, }: NumberInputProps) => { - const onChangeWrapped = (v: string) => { - onChange(v === '' ? undefined : Number(v)); - }; - return ( -
- {label &&
- ); + const onChangeWrapped = (v: string) => { + onChange(v === "" ? undefined : Number(v)); + }; + return ( +
+ {label &&
+ ); }; -type FormNumberInputProps = { field: FormField } & CommonNumberInputProps; +type FormNumberInputProps = { + field: FormField; +} & CommonNumberInputProps; export const FormNumberInput = ({ field, ...rest }: FormNumberInputProps) => { - const fieldProps = Morfi.useField(field); - return ; + const fieldProps = Morfi.useField(field); + return ; }; diff --git a/docs/src/fields/FormSelect.tsx b/docs/src/fields/FormSelect.tsx index ed74252..7143f83 100644 --- a/docs/src/fields/FormSelect.tsx +++ b/docs/src/fields/FormSelect.tsx @@ -1,25 +1,25 @@ -import React from 'react'; -import { Morfi, ErrorMessage, FormField } from 'morfi'; -import { EventUtil } from './event-util'; -import { DisplayError, Label } from './Basic'; +import React from "react"; +import { ErrorMessage, FormField, Morfi } from "morfi"; +import { DisplayError, Label } from "./Basic"; +import { EventUtil } from "./event-util"; export type SelectOption = { label: string; value: T }; type CommonSelectProps = { - serialize?: (value: T) => string; - label?: string; - required?: boolean; - className?: string; - options: ReadonlyArray>; - disabled?: boolean; + serialize?: (value: T) => string; + label?: string; + required?: boolean; + className?: string; + options: ReadonlyArray>; + disabled?: boolean; }; type SelectProps = { - value: T; - error?: ErrorMessage; - required?: boolean; - onChange?: (value: T) => void; - onBlur?: (value: T) => void; + value: T; + error?: ErrorMessage; + required?: boolean; + onChange?: (value: T) => void; + onBlur?: (value: T) => void; } & CommonSelectProps; /** @@ -27,54 +27,69 @@ type SelectProps = { * So you should not use any placeholders inside the messages you use as * label for the select options. */ -const Option = ({ label, value }: { label: string; value: string }) => ; +const Option = ({ label, value }: { label: string; value: string }) => ( + +); const _identity = (v: unknown): unknown => v; -const getOptionValues = (options: ReadonlyArray>, serialize?: (value: T) => string): string[] => - options - .map((o) => o.value) - .map(serialize || _identity) - .map((v, i) => (v === undefined ? '' : typeof v === 'string' ? v : String(i))); +const getOptionValues = ( + options: ReadonlyArray>, + serialize?: (value: T) => string, +): string[] => + options + .map((o) => o.value) + .map(serialize || _identity) + .map((v, i) => + v === undefined ? "" : typeof v === "string" ? v : String(i), + ); export const Select = ({ - value, - serialize, - label, - error, - required = false, - className = 'form-group', - onChange, - onBlur, - options, - disabled, + value, + serialize, + label, + error, + required = false, + className = "form-group", + onChange, + onBlur, + options, + disabled, }: SelectProps) => { - const optionValues = getOptionValues(options, serialize); - const handlerRemapped = (handler?: (value: T) => void) => (optionValue: string) => - handler && handler(options[optionValues.indexOf(optionValue)].value); - const currentIndex = options.indexOf(options.find((option) => option.value === value)!); + const optionValues = getOptionValues(options, serialize); + const handlerRemapped = + (handler?: (value: T) => void) => (optionValue: string) => + handler && handler(options[optionValues.indexOf(optionValue)].value); + const currentIndex = options.indexOf( + options.find((option) => option.value === value)!, + ); - return ( -
- {label &&
- ); + return ( +
+ {label &&
+ ); }; type FormSelectProps = { field: FormField } & CommonSelectProps; export const FormSelect = ({ field, ...rest }: FormSelectProps) => { - const fieldProps = Morfi.useField(field); - return ; }; diff --git a/docs/src/fields/event-util.ts b/docs/src/fields/event-util.ts index 39742fb..ce71623 100644 --- a/docs/src/fields/event-util.ts +++ b/docs/src/fields/event-util.ts @@ -1,16 +1,22 @@ -import React from 'react'; +import React from "react"; -type CustomInputHandling = { preventDefault?: boolean; falsyToUndefined?: boolean }; +type CustomInputHandling = { + preventDefault?: boolean; + falsyToUndefined?: boolean; +}; const inputHandler = - ( - cb: (arg: any) => any, - { preventDefault = true, falsyToUndefined = false }: CustomInputHandling = {} - ): React.EventHandler => - (event) => { - if (preventDefault) event.preventDefault(); - const original = event.target.value; - cb(falsyToUndefined ? original || undefined : original); - }; + ( + cb: (arg: any) => any, + { + preventDefault = true, + falsyToUndefined = false, + }: CustomInputHandling = {}, + ): React.EventHandler => + (event) => { + if (preventDefault) event.preventDefault(); + const original = event.target.value; + cb(falsyToUndefined ? original || undefined : original); + }; export const EventUtil = { inputHandler }; diff --git a/docs/src/hooks/useChangeEffect.ts b/docs/src/hooks/useChangeEffect.ts index fbd95f4..0ebfdef 100644 --- a/docs/src/hooks/useChangeEffect.ts +++ b/docs/src/hooks/useChangeEffect.ts @@ -1,25 +1,28 @@ -import { DependencyList, useEffect, useRef } from 'react'; +import { DependencyList, useEffect, useRef } from "react"; // React strict mode calls all effects twice, so we need this helper // see: https://github.com/streamich/react-use/blob/master/src/useFirstMountState.ts export const useFirstMountState = (): boolean => { - const isFirst = useRef(true); + const isFirst = useRef(true); - if (isFirst.current) { - isFirst.current = false; - return true; - } + if (isFirst.current) { + isFirst.current = false; + return true; + } - return isFirst.current; + return isFirst.current; }; type OptionalCleanUpCb = void | (() => void); -export const useChangeEffect: typeof useEffect = (effect: () => OptionalCleanUpCb, deps?: DependencyList) => { - const isFirst = useFirstMountState(); +export const useChangeEffect: typeof useEffect = ( + effect: () => OptionalCleanUpCb, + deps?: DependencyList, +) => { + const isFirst = useFirstMountState(); - useEffect(() => { - if (!isFirst) { - return effect(); - } - }, deps); // eslint-disable-line react-hooks/exhaustive-deps + useEffect(() => { + if (!isFirst) { + return effect(); + } + }, deps); }; diff --git a/docs/src/hooks/useMounted.ts b/docs/src/hooks/useMounted.ts index 6c172e1..2203cea 100644 --- a/docs/src/hooks/useMounted.ts +++ b/docs/src/hooks/useMounted.ts @@ -1,14 +1,14 @@ -import { useEffect, useRef } from 'react'; +import { useEffect, useRef } from "react"; type UseMountedReturnType = Readonly<{ current: boolean }>; export const useMounted = (): UseMountedReturnType => { - const mounted = useRef(true); - useEffect(() => { - mounted.current = true; - return () => { - mounted.current = false; - }; - }, []); - return mounted; + const mounted = useRef(true); + useEffect(() => { + mounted.current = true; + return () => { + mounted.current = false; + }; + }, []); + return mounted; }; diff --git a/docs/src/hooks/useSafeState.ts b/docs/src/hooks/useSafeState.ts index 2959dde..9dff95c 100644 --- a/docs/src/hooks/useSafeState.ts +++ b/docs/src/hooks/useSafeState.ts @@ -1,5 +1,5 @@ -import { useState, useCallback, Dispatch, SetStateAction } from 'react'; -import { useMounted } from './useMounted'; +import { Dispatch, SetStateAction, useCallback, useState } from "react"; +import { useMounted } from "./useMounted"; /* * This hook ensures that state updates that would be done @@ -10,15 +10,15 @@ import { useMounted } from './useMounted'; type UseSafeStateReturnType = [T, Dispatch>]; export const useSafeState = (initial: T): UseSafeStateReturnType => { - const [state, setState] = useState(initial); - const mounted = useMounted(); + const [state, setState] = useState(initial); + const mounted = useMounted(); - const safeSetState = useCallback( - (v: SetStateAction) => { - mounted.current && setState(v); - }, - [mounted] - ); + const safeSetState = useCallback( + (v: SetStateAction) => { + mounted.current && setState(v); + }, + [mounted], + ); - return [state, safeSetState]; + return [state, safeSetState]; }; diff --git a/docs/src/icons/Arrow.tsx b/docs/src/icons/Arrow.tsx index 2f0fce9..905ac5a 100644 --- a/docs/src/icons/Arrow.tsx +++ b/docs/src/icons/Arrow.tsx @@ -1,23 +1,31 @@ -import React from 'react'; +import React from "react"; -type Direction = 'UP' | 'DOWN' | 'LEFT' | 'RIGHT'; +type Direction = "UP" | "DOWN" | "LEFT" | "RIGHT"; const rotationByDirection = { - UP: 0, - RIGHT: 90, - DOWN: 180, - LEFT: 270, + UP: 0, + RIGHT: 90, + DOWN: 180, + LEFT: 270, }; -export const Arrow = ({ direction = 'UP' }: { direction?: Direction }) => ( - - - - - - - - - - +export const Arrow = ({ direction = "UP" }: { direction?: Direction }) => ( + + + + + + + + + + ); diff --git a/docs/src/icons/Eye.tsx b/docs/src/icons/Eye.tsx index c986cd3..5ba9f9b 100644 --- a/docs/src/icons/Eye.tsx +++ b/docs/src/icons/Eye.tsx @@ -1,11 +1,11 @@ -import React from 'react'; +import React from "react"; export const Eye = ({ stroked }: { stroked: boolean }) => ( - - - {stroked && } - + + + {stroked && } + ); diff --git a/docs/src/icons/Spinner.tsx b/docs/src/icons/Spinner.tsx index c0313a1..fbaeb26 100644 --- a/docs/src/icons/Spinner.tsx +++ b/docs/src/icons/Spinner.tsx @@ -1,14 +1,22 @@ -import React from 'react'; +import React from "react"; export const Spinner = () => ( - - - - - - - - - - + + + + + + + + + + ); diff --git a/docs/src/index.tsx b/docs/src/index.tsx index a4e11ca..490d3a4 100644 --- a/docs/src/index.tsx +++ b/docs/src/index.tsx @@ -5,19 +5,18 @@ * */ -import '../assets/styles/index.scss'; +import "../assets/styles/index.scss"; +import React from "react"; +import { createRoot } from "react-dom/client"; +import { BrowserRouter } from "react-router-dom"; +import { App } from "./App"; -import React from 'react'; -import { createRoot } from 'react-dom/client'; -import { BrowserRouter } from 'react-router-dom'; -import { App } from './App'; - -const root = createRoot(document.getElementById('root')!); +const root = createRoot(document.getElementById("root")!); root.render( - - - - - + + + + + , ); diff --git a/docs/src/samples/async/AsyncValidationSample.tsx b/docs/src/samples/async/AsyncValidationSample.tsx index f7bbbbb..c1ebeb9 100644 --- a/docs/src/samples/async/AsyncValidationSample.tsx +++ b/docs/src/samples/async/AsyncValidationSample.tsx @@ -1,129 +1,160 @@ -import React, { useCallback, useRef, useState } from 'react'; -import { Validators } from '../../validators/validators'; -import { FormInput } from '../../fields/FormInput'; -import { MorfiData, FormValidation, Morfi } from 'morfi'; -import { useSafeState } from '../../hooks/useSafeState'; -import { Utils } from '../../tools/Utils'; -import { Button } from '../../fields/Basic'; +import React, { useCallback, useRef, useState } from "react"; +import { FormValidation, Morfi, MorfiData } from "morfi"; +import { Button } from "../../fields/Basic"; +import { FormInput } from "../../fields/FormInput"; +import { useSafeState } from "../../hooks/useSafeState"; +import { Utils } from "../../tools/Utils"; +import { Validators } from "../../validators/validators"; // some fake server state -const alreadyRegistered_userName = 'tom'; -const everySecondTimeFailing_userName = 'jack'; -const failingAfterSubmit_userName = 'mike'; +const alreadyRegistered_userName = "tom"; +const everySecondTimeFailing_userName = "jack"; +const failingAfterSubmit_userName = "mike"; let jackValidationCounter = 0; type FormValues = { userName: string; realName: string; alias: string }; -const initialValues: FormValues = { userName: '', realName: '', alias: '' }; +const initialValues: FormValues = { userName: "", realName: "", alias: "" }; const StaticValidations: FormValidation = { - realName: { - onChange: Validators.optionalOf( - Validators.regex({ - re: /^[a-zöüä][a-zöüä ]*$/i, - message: { id: 'AsyncValidationSample.realName.validation.requirements' }, - }) - ), - }, + realName: { + onChange: Validators.optionalOf( + Validators.regex({ + re: /^[a-zöüä][a-zöüä ]*$/i, + message: { + id: "AsyncValidationSample.realName.validation.requirements", + }, + }), + ), + }, }; -const onSubmit = ({ userName = '' }: FormValues): Promise => { - // simulate server request - const fakeServerRequest = Utils.sleep(1000); - return userName.toLowerCase() !== failingAfterSubmit_userName - ? fakeServerRequest - : fakeServerRequest.then(() => { - throw new Error('AsyncValidationSample.userName.submit.failed'); - }); +const onSubmit = ({ userName = "" }: FormValues): Promise => { + // simulate server request + const fakeServerRequest = Utils.sleep(1000); + return userName.toLowerCase() !== failingAfterSubmit_userName + ? fakeServerRequest + : fakeServerRequest.then(() => { + throw new Error("AsyncValidationSample.userName.submit.failed"); + }); }; const validateName = (setPending: (p: boolean) => void) => (name?: string) => { - const syncError = Validators.string({ min: 1 })(name); - if (syncError) { - return syncError; + const syncError = Validators.string({ min: 1 })(name); + if (syncError) { + return syncError; + } + const lowerCaseUserName = name!.toLowerCase(); + setPending(true); + lowerCaseUserName === everySecondTimeFailing_userName && + jackValidationCounter++; + return Utils.sleep(1000).then(() => { + setPending(false); + if (lowerCaseUserName === alreadyRegistered_userName) { + return { + id: "AsyncValidationSample.userName.already.registered", + values: { userName: name }, + }; + } else if ( + lowerCaseUserName === everySecondTimeFailing_userName && + jackValidationCounter % 2 === 0 + ) { + return { + id: "AsyncValidationSample.userName.already.registered", + values: { userName: name }, + }; } - const lowerCaseUserName = name!.toLowerCase(); - setPending(true); - lowerCaseUserName === everySecondTimeFailing_userName && jackValidationCounter++; - return Utils.sleep(1000).then(() => { - setPending(false); - if (lowerCaseUserName === alreadyRegistered_userName) { - return { id: 'AsyncValidationSample.userName.already.registered', values: { userName: name } }; - } else if (lowerCaseUserName === everySecondTimeFailing_userName && jackValidationCounter % 2 === 0) { - return { id: 'AsyncValidationSample.userName.already.registered', values: { userName: name } }; - } - }); + }); }; export const AsyncValidationSample = () => { - const [pendingUserName, setPendingUserName] = useSafeState(false); - const validateUserName = useCallback( - (name?: string) => validateName(setPendingUserName)(name), - [setPendingUserName] - ); + const [pendingUserName, setPendingUserName] = useSafeState(false); + const validateUserName = useCallback( + (name?: string) => validateName(setPendingUserName)(name), + [setPendingUserName], + ); - const [pendingAlias, setPendingAlias] = useSafeState(false); - const validateAlias = useCallback((alias?: string) => validateName(setPendingAlias)(alias), [setPendingAlias]); + const [pendingAlias, setPendingAlias] = useSafeState(false); + const validateAlias = useCallback( + (alias?: string) => validateName(setPendingAlias)(alias), + [setPendingAlias], + ); - const validation = useRef>({ - ...StaticValidations, - userName: { onBlur: validateUserName, onChange: Validators.string({ min: 1 }) }, - alias: { onChange: validateAlias }, - }); + const validation = useRef>({ + ...StaticValidations, + userName: { + onBlur: validateUserName, + onChange: Validators.string({ min: 1 }), + }, + alias: { onChange: validateAlias }, + }); - const [data, setData] = useState>(() => Morfi.initialData(initialValues)); + const [data, setData] = useState>(() => + Morfi.initialData(initialValues), + ); - const onSubmitFailed = useCallback((e: Error): void => { - Morfi.isValidationError(e) || - setData((data) => ({ - ...data, - errors: { ...data.errors, userName: { id: e.message } }, - })); - }, []); + const onSubmitFailed = useCallback((e: Error): void => { + Morfi.isValidationError(e) || + setData((data) => ({ + ...data, + errors: { ...data.errors, userName: { id: e.message } }, + })); + }, []); - const onSubmitFinished = useCallback((): void => { - setData(Morfi.initialData(initialValues)); - }, []); + const onSubmitFinished = useCallback((): void => { + setData(Morfi.initialData(initialValues)); + }, []); - const { fields, Form } = Morfi.useForm(); + const { fields, Form } = Morfi.useForm(); - return ( - <> -

- ATTENTION: The validation succeeds for all names, but the following: -
- Tom: Validation fails each time. -
- Jack: Validation fails each second time. -
- Mike: Validation succeeds but submitting fails. -

-
- - - -
- -
- - - ); + return ( + <> +

+ + ATTENTION: The validation succeeds for all names, but the following: + +
+ Tom: Validation fails each time. +
+ Jack: Validation fails each second time. +
+ Mike:{" "} + Validation succeeds but submitting fails. +

+
+ + + +
+ +
+ + + ); }; diff --git a/docs/src/samples/first/FirstSample.tsx b/docs/src/samples/first/FirstSample.tsx index 4c4cbe0..78ba39d 100644 --- a/docs/src/samples/first/FirstSample.tsx +++ b/docs/src/samples/first/FirstSample.tsx @@ -1,61 +1,82 @@ -import React, { useCallback, useState } from 'react'; -import { Validators } from '../../validators/validators'; -import { Morfi, type FormValidation } from 'morfi'; -import { type Gender, type Person, PersonTable } from './PersonTable'; -import { FormSelect, type SelectOption } from '../../fields/FormSelect'; -import { FormNumberInput } from '../../fields/FormNumberInput'; -import { FormInput } from '../../fields/FormInput'; -import { Button } from '../../fields/Basic'; +import React, { useCallback, useState } from "react"; +import { type FormValidation, Morfi } from "morfi"; +import { Button } from "../../fields/Basic"; +import { FormInput } from "../../fields/FormInput"; +import { FormNumberInput } from "../../fields/FormNumberInput"; +import { FormSelect, type SelectOption } from "../../fields/FormSelect"; +import { Validators } from "../../validators/validators"; +import { type Gender, type Person, PersonTable } from "./PersonTable"; type MyFormValues = { - firstName: string; - lastName: string; - gender: Gender; - age?: number; + firstName: string; + lastName: string; + gender: Gender; + age?: number; }; -const initialValues: MyFormValues = { firstName: 'Nick', lastName: '', gender: 'M', age: 21 }; +const initialValues: MyFormValues = { + firstName: "Nick", + lastName: "", + gender: "M", + age: 21, +}; const validation: FormValidation = { - firstName: { onChange: Validators.string({ min: 1, max: 10 }) }, - lastName: { onBlur: Validators.string({ min: 1, max: 10 }) }, - age: { onChange: Validators.number({ minLength: 1, maxLength: 3 }) }, + firstName: { onChange: Validators.string({ min: 1, max: 10 }) }, + lastName: { onBlur: Validators.string({ min: 1, max: 10 }) }, + age: { onChange: Validators.number({ minLength: 1, maxLength: 3 }) }, }; const genderOptions: SelectOption[] = [ - { value: 'M', label: 'male' }, - { value: 'F', label: 'female' }, + { value: "M", label: "male" }, + { value: "F", label: "female" }, ]; export const FirstSample: React.FC = () => { - const [data, setData] = useState(() => Morfi.initialData(initialValues)); - const [persons, setPersons] = useState([]); - - const onSubmit = useCallback(({ firstName, lastName, gender, age }: MyFormValues): void => { - setPersons((persons) => [...persons, { gender, firstName, lastName, age: age! }]); - }, []); - - const onClear = useCallback(() => { - setData(Morfi.initialData({ ...initialValues, firstName: '' })); - }, []); - - const { Form, fields } = Morfi.useForm(); - - return ( - <> -
- - - - -
- - -
- - - - ); + const [data, setData] = useState(() => Morfi.initialData(initialValues)); + const [persons, setPersons] = useState([]); + + const onSubmit = useCallback( + ({ firstName, lastName, gender, age }: MyFormValues): void => { + setPersons((persons) => [ + ...persons, + { gender, firstName, lastName, age: age! }, + ]); + }, + [], + ); + + const onClear = useCallback(() => { + setData(Morfi.initialData({ ...initialValues, firstName: "" })); + }, []); + + const { Form, fields } = Morfi.useForm(); + + return ( + <> +
+ + + + +
+ + +
+ + + + ); }; diff --git a/docs/src/samples/first/PersonTable.tsx b/docs/src/samples/first/PersonTable.tsx index 9358e5c..ca0a48e 100644 --- a/docs/src/samples/first/PersonTable.tsx +++ b/docs/src/samples/first/PersonTable.tsx @@ -1,29 +1,34 @@ -import React from 'react'; +import React from "react"; -export type Gender = 'M' | 'F'; -export type Person = { gender: Gender; firstName: string; lastName: string; age: number }; +export type Gender = "M" | "F"; +export type Person = { + gender: Gender; + firstName: string; + lastName: string; + age: number; +}; type PersonTableProps = { persons: Person[] }; export const PersonTable: React.FC = ({ persons }) => ( - - - - - - - - - - - {persons.map((person: Person, index: number) => ( - - - - - - - ))} - -
GenderFirstnameLastnameAge
{person.gender}{person.firstName}{person.lastName}{person.age}
+ + + + + + + + + + + {persons.map((person: Person, index: number) => ( + + + + + + + ))} + +
GenderFirstnameLastnameAge
{person.gender}{person.firstName}{person.lastName}{person.age}
); diff --git a/docs/src/samples/password-repeat/PasswordRepeatForm.tsx b/docs/src/samples/password-repeat/PasswordRepeatForm.tsx index d43fcd0..f52e53a 100644 --- a/docs/src/samples/password-repeat/PasswordRepeatForm.tsx +++ b/docs/src/samples/password-repeat/PasswordRepeatForm.tsx @@ -1,71 +1,85 @@ -import React, { useCallback, useMemo, useState } from 'react'; -import { FormInput } from '../../fields/FormInput'; -import { type MorfiData, Morfi } from 'morfi'; -import { Utils } from '../../tools/Utils'; -import { Button } from '../../fields/Basic'; +import React, { useCallback, useMemo, useState } from "react"; +import { Morfi, type MorfiData } from "morfi"; +import { Button } from "../../fields/Basic"; +import { FormInput } from "../../fields/FormInput"; +import { Utils } from "../../tools/Utils"; const staticValidation = { - password: { - onChange: (v?: string) => { - if (!v) return { id: 'PasswordRepeatForm.validation.password.required' }; - if (RegExp('[^0-9a-zA-Z]').test(v)) return { id: 'PasswordRepeatForm.validation.password.validChars' }; - }, - onBlur: (v?: string) => { - if (!v || v.length < 8) return { id: 'PasswordRepeatForm.validation.password.length' }; - if (!RegExp('[^0-9]').test(v) || !RegExp('[^a-zA-Z]').test(v)) - return { id: 'PasswordRepeatForm.validation.password.mixed' }; - }, + password: { + onChange: (v?: string) => { + if (!v) return { id: "PasswordRepeatForm.validation.password.required" }; + if (RegExp("[^0-9a-zA-Z]").test(v)) + return { id: "PasswordRepeatForm.validation.password.validChars" }; }, + onBlur: (v?: string) => { + if (!v || v.length < 8) + return { id: "PasswordRepeatForm.validation.password.length" }; + if (!RegExp("[^0-9]").test(v) || !RegExp("[^a-zA-Z]").test(v)) + return { id: "PasswordRepeatForm.validation.password.mixed" }; + }, + }, }; type MyFormValues = { password: string; repeat: string }; -const initialValues: MyFormValues = { password: '', repeat: '' }; +const initialValues: MyFormValues = { password: "", repeat: "" }; export const PasswordRepeatForm: React.FC = () => { - const [data, setData] = useState(() => Morfi.initialData(initialValues)); - const validation = useMemo( - () => ({ - ...staticValidation, - repeat: { - onChange: (v?: string) => { - if (!v || v !== data.values.password) return { id: 'PasswordRepeatForm.validation.repeat.wrong' }; - }, - }, - }), - [data.values.password] - ); + const [data, setData] = useState(() => Morfi.initialData(initialValues)); + const validation = useMemo( + () => ({ + ...staticValidation, + repeat: { + onChange: (v?: string) => { + if (!v || v !== data.values.password) + return { id: "PasswordRepeatForm.validation.repeat.wrong" }; + }, + }, + }), + [data.values.password], + ); - const onChange = useCallback((data: MorfiData) => { - setData((prevData) => { - if (prevData.values.password !== data.values.password) { - return { ...data, errors: { ...data.errors, repeat: undefined } }; - } else { - return data; - } - }); - }, []); + const onChange = useCallback((data: MorfiData) => { + setData((prevData) => { + if (prevData.values.password !== data.values.password) { + return { ...data, errors: { ...data.errors, repeat: undefined } }; + } else { + return data; + } + }); + }, []); - const onSubmit = useCallback(() => Utils.sleep(1000), []); + const onSubmit = useCallback(() => Utils.sleep(1000), []); - const onSubmitFinished = useCallback(() => setData(Morfi.initialData(initialValues)), []); + const onSubmitFinished = useCallback( + () => setData(Morfi.initialData(initialValues)), + [], + ); - const { fields, Form } = Morfi.useForm(); + const { fields, Form } = Morfi.useForm(); - return ( -
- - -
- -
- - ); + return ( +
+ + +
+ +
+ + ); }; diff --git a/docs/src/samples/readme/Readme.tsx b/docs/src/samples/readme/Readme.tsx index 45d7907..ac8e0af 100644 --- a/docs/src/samples/readme/Readme.tsx +++ b/docs/src/samples/readme/Readme.tsx @@ -1,42 +1,55 @@ -import React, { useCallback, useState } from 'react'; -import { MorfiData, FormField, Morfi } from 'morfi'; +import React, { useCallback, useState } from "react"; +import { FormField, Morfi, MorfiData } from "morfi"; type User = { ID: string; name: string }; -type UserPickerProps = { users: User[]; userID?: string; onPick: (user: User) => void }; +type UserPickerProps = { + users: User[]; + userID?: string; + onPick: (user: User) => void; +}; const UserPicker: React.FC = ({ users, userID, onPick }) => ( -
    - {users.map((user) => ( -
  • onPick(user)}> - {user.name} -
  • - ))} -
+
    + {users.map((user) => ( +
  • onPick(user)} + > + {user.name} +
  • + ))} +
); -type FormUserPickerProps = { field: FormField; users: User[] }; +type FormUserPickerProps = { + field: FormField; + users: User[]; +}; const FormUserPicker: React.FC = ({ users, field }) => { - const { value, onChange } = Morfi.useField(field); - const onPick = useCallback((user: User) => onChange(user.ID), [onChange]); + const { value, onChange } = Morfi.useField(field); + const onPick = useCallback((user: User) => onChange(user.ID), [onChange]); - return ; + return ; }; type FormValues = { userID?: string }; -type MyFormProps = { users: User[]; onSubmit: (values: FormValues) => Promise }; +type MyFormProps = { + users: User[]; + onSubmit: (values: FormValues) => Promise; +}; export const MyForm: React.FC = ({ users, onSubmit }) => { - const { Form, fields } = Morfi.useForm(); - const [data, setData] = useState>(Morfi.initialData({})); - - return ( -
- - - ); + const { Form, fields } = Morfi.useForm(); + const [data, setData] = useState>( + Morfi.initialData({}), + ); + + return ( +
+ + + ); }; diff --git a/docs/src/samples/validation-types/ValidationSample.tsx b/docs/src/samples/validation-types/ValidationSample.tsx index eb52966..cbaaa78 100644 --- a/docs/src/samples/validation-types/ValidationSample.tsx +++ b/docs/src/samples/validation-types/ValidationSample.tsx @@ -1,82 +1,108 @@ -import React, { useCallback, useMemo, useState } from 'react'; -import { type FormValidation, Morfi, type ValidationType } from 'morfi'; -import { Validators } from '../../validators/validators'; -import { DisplayValues } from '../../tools/DisplayValues'; -import { Select, type SelectOption } from '../../fields/FormSelect'; -import { FormInput } from '../../fields/FormInput'; -import { Utils } from '../../tools/Utils'; -import { Button } from '../../fields/Basic'; +import React, { useCallback, useMemo, useState } from "react"; +import { type FormValidation, Morfi, type ValidationType } from "morfi"; +import { Button } from "../../fields/Basic"; +import { FormInput } from "../../fields/FormInput"; +import { Select, type SelectOption } from "../../fields/FormSelect"; +import { DisplayValues } from "../../tools/DisplayValues"; +import { Utils } from "../../tools/Utils"; +import { Validators } from "../../validators/validators"; const ValidationTypeOptions: Array> = [ - { label: 'onChange', value: 'onChange' }, - { label: 'onBlur', value: 'onBlur' }, - { label: 'onSubmit', value: 'onSubmit' }, + { label: "onChange", value: "onChange" }, + { label: "onBlur", value: "onBlur" }, + { label: "onSubmit", value: "onSubmit" }, ]; const descriptionFor = (type: ValidationType) => { - switch (type) { - case 'onChange': - return ( - 'This validation type will automatically make a ' + - 'validation for each character you enter in the form fields.' - ); - case 'onBlur': - return 'This validation type will automatically make a validation each time you leave the form field.'; - case 'onSubmit': - return ( - 'This validation type will trigger the validators ' + - 'as soon as the form data was requested to be submitted.' - ); - default: - return ''; - } + switch (type) { + case "onChange": + return ( + "This validation type will automatically make a " + + "validation for each character you enter in the form fields." + ); + case "onBlur": + return "This validation type will automatically make a validation each time you leave the form field."; + case "onSubmit": + return ( + "This validation type will trigger the validators " + + "as soon as the form data was requested to be submitted." + ); + default: + return ""; + } }; type FormValues = { email: string; pw: string }; -const initialValues: FormValues = { email: '', pw: '' }; +const initialValues: FormValues = { email: "", pw: "" }; const validationFor = (type: ValidationType): FormValidation => ({ - email: { [type]: Validators.email }, - pw: { [type]: Validators.regex({ re: /^[a-zA-Z0-9]{8,}$/, message: { id: 'validation.pw.requirements' } }) }, + email: { [type]: Validators.email }, + pw: { + [type]: Validators.regex({ + re: /^[a-zA-Z0-9]{8,}$/, + message: { id: "validation.pw.requirements" }, + }), + }, }); export const ValidationSample: React.FC = () => { - const [data, setData] = useState(Morfi.initialData(initialValues)); - const [validationType, setValidationType] = useState('onChange'); - const validation = useMemo(() => validationFor(validationType), [validationType]); + const [data, setData] = useState(Morfi.initialData(initialValues)); + const [validationType, setValidationType] = + useState("onChange"); + const validation = useMemo( + () => validationFor(validationType), + [validationType], + ); - const onSubmit = useCallback( - () => - // simulate server request - Utils.sleep(2000), - [] - ); + const onSubmit = useCallback( + () => + // simulate server request + Utils.sleep(2000), + [], + ); - const { Form, fields } = Morfi.useForm(); + const { Form, fields } = Morfi.useForm(); - return ( - <> - +

{descriptionFor(validationType)}

+
+
+ + +
+ +
+ +
+ +
+ + ); }; diff --git a/docs/src/tools/DisplayValues.tsx b/docs/src/tools/DisplayValues.tsx index 2bb32b0..47032ad 100644 --- a/docs/src/tools/DisplayValues.tsx +++ b/docs/src/tools/DisplayValues.tsx @@ -1,47 +1,48 @@ -import React from 'react'; -import type { MorfiData } from 'morfi'; +import React from "react"; +import type { MorfiData } from "morfi"; -const sanitize = (str: string): string => str.replace(//g, '>'); +const sanitize = (str: string): string => + str.replace(//g, ">"); const htmlForObject = (o: { [key: string]: unknown }): string => { - let result = '

{

'; - let firstValue = true; - Object.keys(o).forEach((key: string) => { - const value = o[key]; - if (value !== undefined) { - if (!firstValue) { - result += ',

'; - } else { - firstValue = false; - } - result += `${key}: `; - if (value === null) { - result += 'null'; - return; - } - switch (typeof value) { - case 'string': - result += `"${sanitize(value)}"`; - return; - case 'boolean': - result += `${String(value)}`; - return; - case 'number': - result += `${value}`; - return; - default: - result += sanitize(JSON.stringify(value) || ''); - } - } - }); - result += '

}'; - return result; + let result = '

{

'; + let firstValue = true; + Object.keys(o).forEach((key: string) => { + const value = o[key]; + if (value !== undefined) { + if (!firstValue) { + result += ",

"; + } else { + firstValue = false; + } + result += `${key}: `; + if (value === null) { + result += 'null'; + return; + } + switch (typeof value) { + case "string": + result += `"${sanitize(value)}"`; + return; + case "boolean": + result += `${String(value)}`; + return; + case "number": + result += `${value}`; + return; + default: + result += sanitize(JSON.stringify(value) || ""); + } + } + }); + result += "

}"; + return result; }; type DisplayValuesProps = { data: MorfiData }; export const DisplayValues: React.FC = ({ data }) => ( -
-        
-    
+
+    
+  
); diff --git a/docs/src/tools/Utils.ts b/docs/src/tools/Utils.ts index 6868123..d7c6ad4 100644 --- a/docs/src/tools/Utils.ts +++ b/docs/src/tools/Utils.ts @@ -1,3 +1,4 @@ -const sleep = (ms: number): Promise => new Promise((r) => setTimeout(r, ms)); +const sleep = (ms: number): Promise => + new Promise((r) => setTimeout(r, ms)); export const Utils = { sleep }; diff --git a/docs/src/validators/validators.ts b/docs/src/validators/validators.ts index 80d73b1..1f088a5 100644 --- a/docs/src/validators/validators.ts +++ b/docs/src/validators/validators.ts @@ -1,70 +1,88 @@ -import type { ErrorMessage, Validator } from 'morfi'; +import type { ErrorMessage, Validator } from "morfi"; -const stringValidator = ({ min = 0, max = -1 }: { min?: number; max?: number }): Validator => { - const exactMessage = - min === max - ? { id: 'validation.characters.exactly.x', values: { num: min, s: min === 1 ? '' : 's' } } - : undefined; - const atMostMessage = exactMessage || { - id: 'validation.characters.atMost.x', - values: { num: max, s: max === 1 ? '' : 's' }, - }; - const atLeastMessage = exactMessage || { - id: 'validation.characters.atLeast.x', - values: { num: min, s: min === 1 ? '' : 's' }, - }; - return (v) => { - const val = v === undefined ? '' : v; - if (max >= 0 && val.length > max) { - return atMostMessage; - } - if (val.length < min) { - return atLeastMessage; +const stringValidator = ({ + min = 0, + max = -1, +}: { + min?: number; + max?: number; +}): Validator => { + const exactMessage = + min === max + ? { + id: "validation.characters.exactly.x", + values: { num: min, s: min === 1 ? "" : "s" }, } - }; + : undefined; + const atMostMessage = exactMessage || { + id: "validation.characters.atMost.x", + values: { num: max, s: max === 1 ? "" : "s" }, + }; + const atLeastMessage = exactMessage || { + id: "validation.characters.atLeast.x", + values: { num: min, s: min === 1 ? "" : "s" }, + }; + return (v) => { + const val = v === undefined ? "" : v; + if (max >= 0 && val.length > max) { + return atMostMessage; + } + if (val.length < min) { + return atLeastMessage; + } + }; }; const regexValidator = - ({ re, message }: { re: RegExp; message?: ErrorMessage }): Validator => - (v) => { - const val = v === undefined ? '' : v; - if (!re.test(val)) { - return message || { id: 'validation.value.mismatch' }; - } - }; + ({ + re, + message, + }: { + re: RegExp; + message?: ErrorMessage; + }): Validator => + (v) => { + const val = v === undefined ? "" : v; + if (!re.test(val)) { + return message || { id: "validation.value.mismatch" }; + } + }; -const __regexNumberValidator = regexValidator({ re: /^\d*$/, message: { id: 'validation.value.onlyNumbers' } }); +const __regexNumberValidator = regexValidator({ + re: /^\d*$/, + message: { id: "validation.value.onlyNumbers" }, +}); const numberValidator = ({ - minLength = 0, - maxLength = -1, + minLength = 0, + maxLength = -1, }: { - minLength?: number; - maxLength?: number; + minLength?: number; + maxLength?: number; }): Validator => { - const strValidator = stringValidator({ min: minLength, max: maxLength }); - return (val) => { - const str = val === undefined ? undefined : String(val); - const error = strValidator(str); - return error || __regexNumberValidator(str); - }; + const strValidator = stringValidator({ min: minLength, max: maxLength }); + return (val) => { + const str = val === undefined ? undefined : String(val); + const error = strValidator(str); + return error || __regexNumberValidator(str); + }; }; const optionalOf = - (validator: Validator): Validator => - (val) => { - if (val) { - return validator(val); - } - }; + (validator: Validator): Validator => + (val) => { + if (val) { + return validator(val); + } + }; export const Validators = { - string: stringValidator, - regex: regexValidator, - number: numberValidator, - email: regexValidator({ - re: /^[a-zA-Z0-9.-]+@[a-zA-Z0-9]+\.[a-z]+$/, - message: { id: 'validation.email.requirements' }, - }), - optionalOf, + string: stringValidator, + regex: regexValidator, + number: numberValidator, + email: regexValidator({ + re: /^[a-zA-Z0-9.-]+@[a-zA-Z0-9]+\.[a-z]+$/, + message: { id: "validation.email.requirements" }, + }), + optionalOf, }; diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..a6f86af --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,92 @@ +// @ts-check + +import js from "@eslint/js"; +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +import imp from "eslint-plugin-import"; +import prettier from "eslint-plugin-prettier"; +import react from "eslint-plugin-react"; +// import reactRecommended from "eslint-plugin-react/configs/recommended.js"; +import reactHooks from "eslint-plugin-react-hooks"; +// support will be added soon: https://github.com/facebook/react/pull/28773 +// import hooksPlugin from "eslint-plugin-react-hooks"; +import simpleImpSort from "eslint-plugin-simple-import-sort"; +import ts from "typescript-eslint"; + +/** @type {any} Not type safe sadly */ +// const hookRules = hooksPlugin.configs.recommended.rules; + +export default ts.config( + { ignores: ["node_modules", "**/dist"] }, + { + files: ["**/*.{j,t}s?(x)"], + extends: [ + js.configs.recommended, + ...ts.configs.recommended, + // reactRecommended, // not compatible currently + // reactHooks.configs.recommended, // not compatible currently + ], + plugins: { + prettier, + import: imp, + "simple-import-sort": simpleImpSort, + "react-hooks": reactHooks, + react, + }, + rules: { + "prettier/prettier": "warn", + "arrow-body-style": ["warn", "as-needed"], + "no-console": "warn", + eqeqeq: ["error", "always"], + "simple-import-sort/imports": [ + "warn", + { + groups: [ + [ + "vitest", + // scss and css file imports + "\\.s?css$", + // side effect (e.g. `import "./foo"`) + "^\\u0000", + // every import starting with "react" + "^react", + // things that start with a letter (or digit or underscore), or `@` followed by a letter + "^@?\\w", + // internal relative paths + "^\\.", + ], + ], + }, + ], + "simple-import-sort/exports": "warn", + "no-restricted-imports": [ + "error", + { + patterns: ["**/build/*", "**/dist/*"], + }, + ], + "import/no-duplicates": "warn", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-unused-vars": [ + "warn", + { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_", + caughtErrorsIgnorePattern: "^_", + }, + ], + }, + }, + { + files: ["**/*.d.ts"], + rules: { + "no-var": "off", + }, + }, + { + files: ["**/*.test.ts?(x)"], + rules: { + "@typescript-eslint/no-non-null-assertion": "off", + }, + }, +); diff --git a/package.json b/package.json index 24a58c8..7e32ccf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "morfi", "version": "2.1.1", + "type": "module", "main": "dist/index.cjs.js", "module": "dist/index.es.js", "types": "dist/index.d.ts", @@ -31,7 +32,7 @@ "test": "vitest --coverage", "lint": "pnpm lint:es && pnpm lint:ts", "lint:ts": "tsc", - "lint:es": "eslint --ext .ts,.tsx . --max-warnings 0", + "lint:es": "eslint . --max-warnings 0", "publish:prepare-core": "vite build && tsc -p tsconfig.publish.json", "publish:prepare-test-util": "rm -rf test-utils/dist && TEST_UTIL=true vite build && tsc -p tsconfig.publish.test-utils.json && mv test-utils/dist/test-utils/index.d.ts test-utils/dist/index.d.ts && rm -rf test-utils/dist/test-utils test-utils/dist/src", "publish:prepare": "pnpm publish:prepare-core && pnpm publish:prepare-test-util" @@ -40,30 +41,29 @@ "react": ">= 16.18" }, "devDependencies": { - "@testing-library/react": "^14.0.0", - "@types/node": "^18.14.4", - "@types/react": "^18.0.28", - "@types/react-dom": "^18.0.11", - "@typescript-eslint/eslint-plugin": "^5.54.0", - "@typescript-eslint/parser": "^5.54.0", - "@vitejs/plugin-react": "^3.1.0", - "@vitest/coverage-c8": "^0.29.2", - "coveralls": "^3.1.1", - "eslint": "8.35.0", - "eslint-config-prettier": "8.6.0", - "eslint-plugin-import": "2.27.5", - "eslint-plugin-prettier": "4.2.1", - "eslint-plugin-react": "7.32.2", - "eslint-plugin-react-hooks": "4.6.0", - "jsdom": "^21.1.0", - "prettier": "^2.8.4", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-router-dom": "^6.8.2", - "sass": "1.58.3", - "spy4js": "^3.4.1", - "typescript": "^4.9.5", - "vite": "^4.1.4", - "vitest": "^0.29.2" + "@testing-library/react": "15.0.7", + "@types/node": "20.12.12", + "@types/react": "18.3.2", + "@types/react-dom": "18.3.0", + "@vitejs/plugin-react": "4.2.1", + "@vitest/coverage-v8": "1.6.0", + "eslint": "9.2.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-import": "2.29.1", + "eslint-plugin-prettier": "5.1.3", + "eslint-plugin-react": "7.34.1", + "eslint-plugin-react-hooks": "4.6.2", + "eslint-plugin-simple-import-sort": "12.1.0", + "jsdom": "24.0.0", + "prettier": "3.2.5", + "react": "18.3.1", + "react-dom": "18.3.1", + "react-router-dom": "6.23.1", + "sass": "1.77.1", + "spy4js": "3.4.1", + "typescript": "5.4.5", + "typescript-eslint": "7.9.0", + "vite": "5.2.11", + "vitest": "1.6.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6327039..7046ce2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,80 +9,77 @@ importers: .: devDependencies: '@testing-library/react': - specifier: ^14.0.0 - version: 14.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 15.0.7 + version: 15.0.7(@types/react@18.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/node': - specifier: ^18.14.4 - version: 18.19.33 + specifier: 20.12.12 + version: 20.12.12 '@types/react': - specifier: ^18.0.28 + specifier: 18.3.2 version: 18.3.2 '@types/react-dom': - specifier: ^18.0.11 + specifier: 18.3.0 version: 18.3.0 - '@typescript-eslint/eslint-plugin': - specifier: ^5.54.0 - version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.35.0)(typescript@4.9.5))(eslint@8.35.0)(typescript@4.9.5) - '@typescript-eslint/parser': - specifier: ^5.54.0 - version: 5.62.0(eslint@8.35.0)(typescript@4.9.5) '@vitejs/plugin-react': - specifier: ^3.1.0 - version: 3.1.0(vite@4.5.3(@types/node@18.19.33)(sass@1.58.3)) - '@vitest/coverage-c8': - specifier: ^0.29.2 - version: 0.29.8(vitest@0.29.8(jsdom@21.1.2)(sass@1.58.3)) - coveralls: - specifier: ^3.1.1 - version: 3.1.1 + specifier: 4.2.1 + version: 4.2.1(vite@5.2.11(@types/node@20.12.12)(sass@1.77.1)) + '@vitest/coverage-v8': + specifier: 1.6.0 + version: 1.6.0(vitest@1.6.0(@types/node@20.12.12)(jsdom@24.0.0)(sass@1.77.1)) eslint: - specifier: 8.35.0 - version: 8.35.0 + specifier: 9.2.0 + version: 9.2.0 eslint-config-prettier: - specifier: 8.6.0 - version: 8.6.0(eslint@8.35.0) + specifier: 9.1.0 + version: 9.1.0(eslint@9.2.0) eslint-plugin-import: - specifier: 2.27.5 - version: 2.27.5(@typescript-eslint/parser@5.62.0(eslint@8.35.0)(typescript@4.9.5))(eslint@8.35.0) + specifier: 2.29.1 + version: 2.29.1(@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5))(eslint@9.2.0) eslint-plugin-prettier: - specifier: 4.2.1 - version: 4.2.1(eslint-config-prettier@8.6.0(eslint@8.35.0))(eslint@8.35.0)(prettier@2.8.8) + specifier: 5.1.3 + version: 5.1.3(eslint-config-prettier@9.1.0(eslint@9.2.0))(eslint@9.2.0)(prettier@3.2.5) eslint-plugin-react: - specifier: 7.32.2 - version: 7.32.2(eslint@8.35.0) + specifier: 7.34.1 + version: 7.34.1(eslint@9.2.0) eslint-plugin-react-hooks: - specifier: 4.6.0 - version: 4.6.0(eslint@8.35.0) + specifier: 4.6.2 + version: 4.6.2(eslint@9.2.0) + eslint-plugin-simple-import-sort: + specifier: 12.1.0 + version: 12.1.0(eslint@9.2.0) jsdom: - specifier: ^21.1.0 - version: 21.1.2 + specifier: 24.0.0 + version: 24.0.0 prettier: - specifier: ^2.8.4 - version: 2.8.8 + specifier: 3.2.5 + version: 3.2.5 react: - specifier: ^18.2.0 + specifier: 18.3.1 version: 18.3.1 react-dom: - specifier: ^18.2.0 + specifier: 18.3.1 version: 18.3.1(react@18.3.1) react-router-dom: - specifier: ^6.8.2 + specifier: 6.23.1 version: 6.23.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) sass: - specifier: 1.58.3 - version: 1.58.3 + specifier: 1.77.1 + version: 1.77.1 spy4js: - specifier: ^3.4.1 + specifier: 3.4.1 version: 3.4.1 typescript: - specifier: ^4.9.5 - version: 4.9.5 + specifier: 5.4.5 + version: 5.4.5 + typescript-eslint: + specifier: 7.9.0 + version: 7.9.0(eslint@9.2.0)(typescript@5.4.5) vite: - specifier: ^4.1.4 - version: 4.5.3(@types/node@18.19.33)(sass@1.58.3) + specifier: 5.2.11 + version: 5.2.11(@types/node@20.12.12)(sass@1.77.1) vitest: - specifier: ^0.29.2 - version: 0.29.8(jsdom@21.1.2)(sass@1.58.3) + specifier: 1.6.0 + version: 1.6.0(@types/node@20.12.12)(jsdom@24.0.0)(sass@1.77.1) packages: @@ -200,134 +197,140 @@ packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - '@esbuild/android-arm64@0.18.20': - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + '@esbuild/aix-ppc64@0.20.2': + resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.20.2': + resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} engines: {node: '>=12'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.18.20': - resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + '@esbuild/android-arm@0.20.2': + resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} engines: {node: '>=12'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.18.20': - resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + '@esbuild/android-x64@0.20.2': + resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} engines: {node: '>=12'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.18.20': - resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + '@esbuild/darwin-arm64@0.20.2': + resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.18.20': - resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + '@esbuild/darwin-x64@0.20.2': + resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} engines: {node: '>=12'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.18.20': - resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + '@esbuild/freebsd-arm64@0.20.2': + resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.18.20': - resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + '@esbuild/freebsd-x64@0.20.2': + resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.18.20': - resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + '@esbuild/linux-arm64@0.20.2': + resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} engines: {node: '>=12'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.18.20': - resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + '@esbuild/linux-arm@0.20.2': + resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} engines: {node: '>=12'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.18.20': - resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + '@esbuild/linux-ia32@0.20.2': + resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} engines: {node: '>=12'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.18.20': - resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} + '@esbuild/linux-loong64@0.20.2': + resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} engines: {node: '>=12'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.18.20': - resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + '@esbuild/linux-mips64el@0.20.2': + resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.18.20': - resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + '@esbuild/linux-ppc64@0.20.2': + resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.18.20': - resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + '@esbuild/linux-riscv64@0.20.2': + resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.18.20': - resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + '@esbuild/linux-s390x@0.20.2': + resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} engines: {node: '>=12'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.18.20': - resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + '@esbuild/linux-x64@0.20.2': + resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} engines: {node: '>=12'} cpu: [x64] os: [linux] - '@esbuild/netbsd-x64@0.18.20': - resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + '@esbuild/netbsd-x64@0.20.2': + resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-x64@0.18.20': - resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} + '@esbuild/openbsd-x64@0.20.2': + resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.18.20': - resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + '@esbuild/sunos-x64@0.20.2': + resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} engines: {node: '>=12'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.18.20': - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + '@esbuild/win32-arm64@0.20.2': + resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} engines: {node: '>=12'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.18.20': - resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} + '@esbuild/win32-ia32@0.20.2': + resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} engines: {node: '>=12'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.18.20': - resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} + '@esbuild/win32-x64@0.20.2': + resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -342,16 +345,16 @@ packages: resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/eslintrc@2.1.4': - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/eslintrc@3.0.2': + resolution: {integrity: sha512-wV19ZEGEMAC1eHgrS7UQPqsdEiCIbTKTasEfcXAigzoXICcqZSjBZEHlZwNVvKg6UBCjSlos84XiLqsRJnIcIg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@8.35.0': - resolution: {integrity: sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/js@9.2.0': + resolution: {integrity: sha512-ESiIudvhoYni+MdsI8oD7skpprZ89qKocwRM2KEvhhBJ9nl5MRh7BXU5GTod7Mdygq+AUl+QzId6iWJKR/wABA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@humanwhocodes/config-array@0.11.14': - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} engines: {node: '>=10.10.0'} '@humanwhocodes/module-importer@1.0.1': @@ -361,10 +364,18 @@ packages: '@humanwhocodes/object-schema@2.0.3': resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + '@humanwhocodes/retry@0.2.4': + resolution: {integrity: sha512-Ttl/jHpxfS3st5sxwICYfk4pOH0WrLI1SpW283GgQL7sCWU7EHIOhX4b4fkIxr3tkfzwg8+FNojtzsIEE7Ecgg==} + engines: {node: '>=18.18'} + '@istanbuljs/schema@0.1.3': resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -395,45 +406,135 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@pkgr/core@0.1.1': + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@remix-run/router@1.16.1': resolution: {integrity: sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==} engines: {node: '>=14.0.0'} - '@testing-library/dom@9.3.4': - resolution: {integrity: sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==} - engines: {node: '>=14'} + '@rollup/rollup-android-arm-eabi@4.17.2': + resolution: {integrity: sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==} + cpu: [arm] + os: [android] - '@testing-library/react@14.3.1': - resolution: {integrity: sha512-H99XjUhWQw0lTgyMN05W3xQG1Nh4lq574D8keFf1dDoNTJgp66VbJozRaczoF+wsiaPJNt/TcnfpLGufGxSrZQ==} - engines: {node: '>=14'} + '@rollup/rollup-android-arm64@4.17.2': + resolution: {integrity: sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.17.2': + resolution: {integrity: sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.17.2': + resolution: {integrity: sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-linux-arm-gnueabihf@4.17.2': + resolution: {integrity: sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.17.2': + resolution: {integrity: sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.17.2': + resolution: {integrity: sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.17.2': + resolution: {integrity: sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.17.2': + resolution: {integrity: sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.17.2': + resolution: {integrity: sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.17.2': + resolution: {integrity: sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.17.2': + resolution: {integrity: sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.17.2': + resolution: {integrity: sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.17.2': + resolution: {integrity: sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.17.2': + resolution: {integrity: sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.17.2': + resolution: {integrity: sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==} + cpu: [x64] + os: [win32] + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@testing-library/dom@10.1.0': + resolution: {integrity: sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==} + engines: {node: '>=18'} + + '@testing-library/react@15.0.7': + resolution: {integrity: sha512-cg0RvEdD1TIhhkm1IeYMQxrzy0MtUNfa3minv4MjbgcYzJAZ7yD0i0lwoPOTPr+INtiXFezt2o8xMSnyHhEn2Q==} + engines: {node: '>=18'} peerDependencies: + '@types/react': ^18.0.0 react: ^18.0.0 react-dom: ^18.0.0 - - '@tootallnate/once@2.0.0': - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} + peerDependenciesMeta: + '@types/react': + optional: true '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} - '@types/chai-subset@1.3.5': - resolution: {integrity: sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==} + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - '@types/chai@4.3.16': - resolution: {integrity: sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==} + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} - '@types/istanbul-lib-coverage@2.0.6': - resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/babel__traverse@7.20.5': + resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} + + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - '@types/node@18.19.33': - resolution: {integrity: sha512-NR9+KrpSajr2qBVp/Yt5TU/rp+b5Mayi3+OlMlcg2cVCfRmcG5PWZ7S4+MG9PZ5gWBoc9Pd0BKSRViuBCRPu0A==} + '@types/node@20.12.12': + resolution: {integrity: sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==} '@types/prop-types@15.7.12': resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} @@ -444,97 +545,89 @@ packages: '@types/react@18.3.2': resolution: {integrity: sha512-Btgg89dAnqD4vV7R3hlwOxgqobUQKgx3MmrQRi0yYbs/P0ym8XozIAlkqVilPqHQwXs4e9Tf63rrCgl58BcO4w==} - '@types/semver@7.5.8': - resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} - - '@typescript-eslint/eslint-plugin@5.62.0': - resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/eslint-plugin@7.9.0': + resolution: {integrity: sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/parser@5.62.0': - resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/parser@7.9.0': + resolution: {integrity: sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^8.56.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/scope-manager@5.62.0': - resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/scope-manager@7.9.0': + resolution: {integrity: sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==} + engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/type-utils@5.62.0': - resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/type-utils@7.9.0': + resolution: {integrity: sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: - eslint: '*' + eslint: ^8.56.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/types@5.62.0': - resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/types@7.9.0': + resolution: {integrity: sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==} + engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/typescript-estree@5.62.0': - resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/typescript-estree@7.9.0': + resolution: {integrity: sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/utils@5.62.0': - resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/utils@7.9.0': + resolution: {integrity: sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^8.56.0 - '@typescript-eslint/visitor-keys@5.62.0': - resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/visitor-keys@7.9.0': + resolution: {integrity: sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==} + engines: {node: ^18.18.0 || >=20.0.0} - '@vitejs/plugin-react@3.1.0': - resolution: {integrity: sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==} + '@vitejs/plugin-react@4.2.1': + resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - vite: ^4.1.0-beta.0 + vite: ^4.2.0 || ^5.0.0 - '@vitest/coverage-c8@0.29.8': - resolution: {integrity: sha512-y+sEMQMctWokjnSqm3FCQEYFkjLrYaznsxEZHxcx8z2aftpYg3A5tvI1S5himfdEFo7o+OeHzh40bPSWZHW4oQ==} - deprecated: v8 coverage is moved to @vitest/coverage-v8 package + '@vitest/coverage-v8@1.6.0': + resolution: {integrity: sha512-KvapcbMY/8GYIG0rlwwOKCVNRc0OL20rrhFkg/CHNzncV03TE2XWvO5w9uZYoxNiMEBacAJt3unSOiZ7svePew==} peerDependencies: - vitest: '>=0.29.0 <1' - - '@vitest/expect@0.29.8': - resolution: {integrity: sha512-xlcVXn5I5oTq6NiZSY3ykyWixBxr5mG8HYtjvpgg6KaqHm0mvhX18xuwl5YGxIRNt/A5jidd7CWcNHrSvgaQqQ==} + vitest: 1.6.0 - '@vitest/runner@0.29.8': - resolution: {integrity: sha512-FzdhnRDwEr/A3Oo1jtIk/B952BBvP32n1ObMEb23oEJNO+qO5cBet6M2XWIDQmA7BDKGKvmhUf2naXyp/2JEwQ==} + '@vitest/expect@1.6.0': + resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==} - '@vitest/spy@0.29.8': - resolution: {integrity: sha512-VdjBe9w34vOMl5I5mYEzNX8inTxrZ+tYUVk9jxaZJmHFwmDFC/GV3KBFTA/JKswr3XHvZL+FE/yq5EVhb6pSAw==} + '@vitest/runner@1.6.0': + resolution: {integrity: sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==} - '@vitest/utils@0.29.8': - resolution: {integrity: sha512-qGzuf3vrTbnoY+RjjVVIBYfuWMjn3UMUqyQtdGNZ6ZIIyte7B37exj6LaVkrZiUTvzSadVvO/tJm8AEgbGCBPg==} + '@vitest/snapshot@1.6.0': + resolution: {integrity: sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==} - abab@2.0.6: - resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} - deprecated: Use your platform's native atob() and btoa() methods instead + '@vitest/spy@1.6.0': + resolution: {integrity: sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==} - acorn-globals@7.0.1: - resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} + '@vitest/utils@1.6.0': + resolution: {integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -550,9 +643,9 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} + agent-base@7.1.1: + resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} + engines: {node: '>= 14'} ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -561,10 +654,6 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -577,22 +666,15 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - aria-query@5.1.3: - resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} array-buffer-byte-length@1.0.1: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} @@ -606,6 +688,14 @@ packages: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + array.prototype.flat@1.3.2: resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} engines: {node: '>= 0.4'} @@ -614,6 +704,9 @@ packages: resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} engines: {node: '>= 0.4'} + array.prototype.toreversed@1.1.2: + resolution: {integrity: sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==} + array.prototype.tosorted@1.1.3: resolution: {integrity: sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==} @@ -621,13 +714,6 @@ packages: resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} engines: {node: '>= 0.4'} - asn1@0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - - assert-plus@1.0.0: - resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} - engines: {node: '>=0.8'} - assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} @@ -638,18 +724,9 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - aws-sign2@0.7.0: - resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} - - aws4@1.12.0: - resolution: {integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==} - balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - bcrypt-pbkdf@1.0.2: - resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} - binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -657,6 +734,9 @@ packages: brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} @@ -666,11 +746,6 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - c8@7.14.0: - resolution: {integrity: sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw==} - engines: {node: '>=10.12.0'} - hasBin: true - cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -683,11 +758,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001617: - resolution: {integrity: sha512-mLyjzNI9I+Pix8zwcrpxEbGlfqOkF9kM3ptzmKNw5tizSyYwMe+nGLTqMK9cO+0E+Bh6TsBxNAaHWEM8xwSsmA==} - - caseless@0.12.0: - resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + caniuse-lite@1.0.30001620: + resolution: {integrity: sha512-WJvYsOjd1/BYUY6SNGUosK9DUidBPDTnOARHp3fSmFO1ekdxaY6nKRttEVrfMmYi80ctS0kz1wiWmm14fVc3ew==} chai@4.4.1: resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} @@ -708,13 +780,6 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} - cli-truncate@3.1.0: - resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - cliui@7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -741,32 +806,20 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - core-util-is@1.0.2: - resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} - - coveralls@3.1.1: - resolution: {integrity: sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==} - engines: {node: '>=6'} - hasBin: true - cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} - cssstyle@3.0.0: - resolution: {integrity: sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==} - engines: {node: '>=14'} + cssstyle@4.0.1: + resolution: {integrity: sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==} + engines: {node: '>=18'} csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - dashdash@1.14.1: - resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} - engines: {node: '>=0.10'} - - data-urls@4.0.0: - resolution: {integrity: sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==} - engines: {node: '>=14'} + data-urls@5.0.0: + resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} + engines: {node: '>=18'} data-view-buffer@1.0.1: resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} @@ -804,10 +857,6 @@ packages: resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} engines: {node: '>=6'} - deep-equal@2.2.3: - resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} - engines: {node: '>= 0.4'} - deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -823,9 +872,13 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - diff@5.2.0: - resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} - engines: {node: '>=0.3.1'} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} @@ -835,32 +888,11 @@ packages: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} - doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} - domexception@4.0.0: - resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} - engines: {node: '>=12'} - deprecated: Use your platform's native DOMException instead - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - ecc-jsbn@0.1.2: - resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} - - electron-to-chromium@1.4.763: - resolution: {integrity: sha512-k4J8NrtJ9QrvHLRo8Q18OncqBCB7tIUyqxRcJnlonQ0ioHKYB988GcDFF3ZePmnb8eHEopDs/wPHR/iGAFgoUQ==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + electron-to-chromium@1.4.773: + resolution: {integrity: sha512-87eHF+h3PlCRwbxVEAw9KtK3v7lWfc/sUDr0W76955AdYTG4bV/k0zrl585Qnj/skRMH2qOSiE+kqMeOQ+LOpw==} entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} @@ -878,8 +910,9 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-get-iterator@1.1.3: - resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} + es-iterator-helpers@1.0.19: + resolution: {integrity: sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==} + engines: {node: '>= 0.4'} es-object-atoms@1.0.0: resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} @@ -896,8 +929,8 @@ packages: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} engines: {node: '>= 0.4'} - esbuild@0.18.20: - resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + esbuild@0.20.2: + resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} engines: {node: '>=12'} hasBin: true @@ -913,13 +946,8 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - escodegen@2.1.0: - resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} - engines: {node: '>=6.0'} - hasBin: true - - eslint-config-prettier@8.6.0: - resolution: {integrity: sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==} + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true peerDependencies: eslint: '>=7.0.0' @@ -948,8 +976,8 @@ packages: eslint-import-resolver-webpack: optional: true - eslint-plugin-import@2.27.5: - resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} + eslint-plugin-import@2.29.1: + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -958,65 +986,58 @@ packages: '@typescript-eslint/parser': optional: true - eslint-plugin-prettier@4.2.1: - resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} - engines: {node: '>=12.0.0'} + eslint-plugin-prettier@5.1.3: + resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} + engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - eslint: '>=7.28.0' + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' eslint-config-prettier: '*' - prettier: '>=2.0.0' + prettier: '>=3.0.0' peerDependenciesMeta: + '@types/eslint': + optional: true eslint-config-prettier: optional: true - eslint-plugin-react-hooks@4.6.0: - resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} + eslint-plugin-react-hooks@4.6.2: + resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==} engines: {node: '>=10'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - eslint-plugin-react@7.32.2: - resolution: {integrity: sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==} + eslint-plugin-react@7.34.1: + resolution: {integrity: sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==} engines: {node: '>=4'} peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - - eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-utils@3.0.0: - resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} - engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + eslint-plugin-simple-import-sort@12.1.0: + resolution: {integrity: sha512-Y2fqAfC11TcG/WP3TrI1Gi3p3nc8XJyEOJYHyEPEGI/UAgNx6akxxlX74p7SbAQdLcgASKhj8M0GKvH3vq/+ig==} peerDependencies: - eslint: '>=5' + eslint: '>=5.0.0' - eslint-visitor-keys@2.1.0: - resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} - engines: {node: '>=10'} + eslint-scope@8.0.1: + resolution: {integrity: sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==} + 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@8.35.0: - resolution: {integrity: sha512-BxAf1fVL7w+JLRQhWl2pzGeSiGqbWumV4WNvc9Rhp6tiCtm4oHnyPBSEtMGZwrQgudFQ+otqzWoPB7x+hxoWsw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true - - espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-visitor-keys@4.0.0: + resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} + eslint@9.2.0: + resolution: {integrity: sha512-0n/I88vZpCOzO+PQpt0lbsqmn9AsnsJAQseIqhZFI8ibQT0U1AkEKRxA3EVMos0BoHSXDQvCXY25TUjB5tr8Og==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true + espree@10.0.1: + resolution: {integrity: sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + esquery@1.5.0: resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} engines: {node: '>=0.10'} @@ -1025,24 +1046,20 @@ packages: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} - estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - estraverse@5.3.0: 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'} - extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - - extsprintf@1.3.0: - resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} - engines: {'0': node >=0.6.0} + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1063,9 +1080,9 @@ packages: fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} - file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} @@ -1075,9 +1092,9 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - flat-cache@3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} @@ -1085,17 +1102,6 @@ packages: for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - foreground-child@2.0.0: - resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} - engines: {node: '>=8.0.0'} - - forever-agent@0.6.1: - resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} - - form-data@2.3.3: - resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} - engines: {node: '>= 0.12'} - form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -1122,10 +1128,6 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} @@ -1133,13 +1135,14 @@ packages: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + get-symbol-description@1.0.2: resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} - getpass@0.1.7: - resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} - glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1155,9 +1158,9 @@ packages: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} - globals@13.24.0: - resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} - engines: {node: '>=8'} + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} @@ -1170,21 +1173,9 @@ packages: gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} - grapheme-splitter@1.0.4: - resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} - graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - har-schema@2.0.0: - resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} - engines: {node: '>=4'} - - har-validator@5.1.5: - resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} - engines: {node: '>=6'} - deprecated: this library is no longer supported - has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} @@ -1211,32 +1202,28 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - has@1.0.4: - resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==} - engines: {node: '>= 0.4.0'} - hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} - html-encoding-sniffer@3.0.0: - resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} - engines: {node: '>=12'} + html-encoding-sniffer@4.0.0: + resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + engines: {node: '>=18'} html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - http-proxy-agent@5.0.0: - resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} - engines: {node: '>= 6'} + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} - http-signature@1.2.0: - resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} - engines: {node: '>=0.8', npm: '>=1.3.7'} + https-proxy-agent@7.0.4: + resolution: {integrity: sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==} + engines: {node: '>= 14'} - https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} @@ -1267,14 +1254,14 @@ packages: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} - is-arguments@1.1.1: - resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} - engines: {node: '>= 0.4'} - is-array-buffer@3.0.4: resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} engines: {node: '>= 0.4'} + is-async-function@2.0.0: + resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} + engines: {node: '>= 0.4'} + is-bigint@1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} @@ -1305,13 +1292,12 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} + is-finalizationregistry@1.0.2: + resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} - is-fullwidth-code-point@4.0.0: - resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} - engines: {node: '>=12'} + is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} @@ -1352,6 +1338,10 @@ packages: resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} engines: {node: '>= 0.4'} + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -1364,9 +1354,6 @@ packages: resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} engines: {node: '>= 0.4'} - is-typedarray@1.0.0: - resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} - is-weakmap@2.0.2: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} @@ -1384,9 +1371,6 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - isstream@0.1.2: - resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} - istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -1395,32 +1379,32 @@ packages: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} + istanbul-lib-source-maps@5.0.4: + resolution: {integrity: sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==} + engines: {node: '>=10'} + istanbul-reports@3.1.7: resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} - js-sdsl@4.4.2: - resolution: {integrity: sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==} + iterator.prototype@1.1.2: + resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true + js-tokens@9.0.0: + resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==} js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true - jsbn@0.1.1: - resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} - - jsdom@21.1.2: - resolution: {integrity: sha512-sCpFmK2jv+1sjff4u7fzft+pUh2KSUbUrEHYHyfSIbGTIcmnjyp83qg6qLwdJ/I3LpTXx33ACxeRL7Lsyc6lGQ==} - engines: {node: '>=14'} + jsdom@24.0.0: + resolution: {integrity: sha512-UDS2NayCvmXSXVP6mpTj+73JnNQadZlr9N68189xib2tx5Mls7swlTNao26IoHv46BZJFvXygyRtyXd1feAk1A==} + engines: {node: '>=18'} peerDependencies: - canvas: ^2.5.0 + canvas: ^2.11.2 peerDependenciesMeta: canvas: optional: true @@ -1436,15 +1420,9 @@ packages: json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true @@ -1454,10 +1432,6 @@ packages: engines: {node: '>=6'} hasBin: true - jsprim@1.4.2: - resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} - engines: {node: '>=0.6.0'} - jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} @@ -1465,16 +1439,12 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - lcov-parse@1.0.0: - resolution: {integrity: sha512-aprLII/vPzuQvYZnDRU78Fns9I2Ag3gi4Ipga/hxnVMCZC8DnR2nI7XBqrPoywGfxqIx/DgarGvDJZAD3YBTgQ==} - hasBin: true - levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - local-pkg@0.4.3: - resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} engines: {node: '>=14'} locate-path@6.0.0: @@ -1484,10 +1454,6 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - log-driver@1.2.7: - resolution: {integrity: sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==} - engines: {node: '>=0.8.6'} - loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -1502,14 +1468,19 @@ packages: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true - magic-string@0.27.0: - resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} - engines: {node: '>=12'} + magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + + magicast@0.3.4: + resolution: {integrity: sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==} make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -1526,9 +1497,17 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -1546,9 +1525,6 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - natural-compare-lite@1.4.0: - resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} - natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -1559,12 +1535,13 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + nwsapi@2.2.10: resolution: {integrity: sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==} - oauth-sign@0.9.0: - resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} - object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -1572,10 +1549,6 @@ packages: object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} - object-is@1.1.6: - resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} - engines: {node: '>= 0.4'} - object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} @@ -1592,6 +1565,10 @@ packages: resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} engines: {node: '>= 0.4'} + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + object.hasown@1.1.4: resolution: {integrity: sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==} engines: {node: '>= 0.4'} @@ -1603,6 +1580,10 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -1611,9 +1592,9 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} - p-limit@4.0.0: - resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} @@ -1638,6 +1619,10 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -1651,11 +1636,8 @@ packages: pathval@1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} - performance-now@2.1.0: - resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} - - picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -1680,15 +1662,19 @@ packages: resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} engines: {node: '>=6.0.0'} - prettier@2.8.8: - resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} - engines: {node: '>=10.13.0'} + prettier@3.2.5: + resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} + engines: {node: '>=14'} hasBin: true pretty-format@27.5.1: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -1699,10 +1685,6 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - qs@6.5.3: - resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} - engines: {node: '>=0.6'} - querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} @@ -1720,6 +1702,9 @@ packages: react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react-refresh@0.14.2: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} @@ -1745,6 +1730,10 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + reflect.getprototypeof@1.0.6: + resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==} + engines: {node: '>= 0.4'} + regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} @@ -1752,19 +1741,6 @@ packages: resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} engines: {node: '>= 0.4'} - regexpp@3.2.0: - resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} - engines: {node: '>=8'} - - request@2.88.2: - resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} - engines: {node: '>= 6'} - deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 - - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} @@ -1784,13 +1760,9 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true - - rollup@3.29.4: - resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} - engines: {node: '>=14.18.0', npm: '>=8.0.0'} + rollup@4.17.2: + resolution: {integrity: sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true rrweb-cssom@0.6.0: @@ -1803,9 +1775,6 @@ packages: resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} engines: {node: '>=0.4'} - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safe-regex-test@1.0.3: resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} engines: {node: '>= 0.4'} @@ -1813,9 +1782,9 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sass@1.58.3: - resolution: {integrity: sha512-Q7RaEtYf6BflYrQ+buPudKR26/lH+10EmO9bBqbmPh/KeLqv8bjpTNqxe71ocONqXq+jYiCbpPUmQMS+JJPk4A==} - engines: {node: '>=12.0.0'} + sass@1.77.1: + resolution: {integrity: sha512-OMEyfirt9XEfyvocduUIOlUSkWOXS/LAt6oblR/ISXCTukyavjex+zQNm51pPCOiFKY1QpWvEH1EeCkgyV3I6w==} + engines: {node: '>=14.0.0'} hasBin: true saxes@6.0.0: @@ -1860,54 +1829,27 @@ packages: siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - slice-ansi@5.0.0: - resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} - engines: {node: '>=12'} - source-map-js@1.2.0: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - spy4js@3.4.1: resolution: {integrity: sha512-PmulD9bC4sjnHM/9teawLfhxIBbdzFlm0QRTg00uwFqeVjtqQ1zvjkrkaaeDm2OrPmkKEspYZPQ6FqrtmEJQmA==} - sshpk@1.18.0: - resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} - engines: {node: '>=0.10.0'} - hasBin: true - stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} std-env@3.7.0: resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} - stop-iteration-iterator@1.0.0: - resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} - engines: {node: '>= 0.4'} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - string.prototype.matchall@4.0.11: resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} engines: {node: '>= 0.4'} @@ -1927,20 +1869,20 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strip-literal@1.3.0: - resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} + strip-literal@2.1.0: + resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} @@ -1957,6 +1899,10 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + synckit@0.8.8: + resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} + engines: {node: ^14.18.0 || >=16.0.0} + test-exclude@6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} @@ -1967,12 +1913,12 @@ packages: tinybench@2.8.0: resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} - tinypool@0.4.0: - resolution: {integrity: sha512-2ksntHOKf893wSAH4z/+JbPpi92esw8Gn9N2deXX+B0EO92hexAVI9GIZZPx7P5aYo5KULfeOSt3kMOmSOy6uA==} + tinypool@0.8.4: + resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} engines: {node: '>=14.0.0'} - tinyspy@1.1.1: - resolution: {integrity: sha512-UVq5AXt/gQlti7oxoIg5oi/9r0WpF7DGEVwXgqWSMmyN16+e3tl5lIvTaOpJ3TAtu5xFzWccFRM4R5NaWHF+4g==} + tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} engines: {node: '>=14.0.0'} to-fast-properties@2.0.0: @@ -1983,35 +1929,25 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - tough-cookie@2.5.0: - resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} - engines: {node: '>=0.8'} - tough-cookie@4.1.4: resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} engines: {node: '>=6'} - tr46@4.1.1: - resolution: {integrity: sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==} - engines: {node: '>=14'} - - tsconfig-paths@3.15.0: - resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} - - tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + tr46@5.0.0: + resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==} + engines: {node: '>=18'} - tsutils@3.21.0: - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + typescript: '>=4.2.0' - tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} - tweetnacl@0.14.5: - resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} @@ -2021,10 +1957,6 @@ packages: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} - type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - typed-array-buffer@1.0.2: resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} @@ -2041,9 +1973,19 @@ packages: resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} engines: {node: '>= 0.4'} - typescript@4.9.5: - resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} - engines: {node: '>=4.2.0'} + typescript-eslint@7.9.0: + resolution: {integrity: sha512-7iTn9c10teHHCys5Ud/yaJntXZrjt3h2mrx3feJGBOLgQkF3TB1X89Xs3aVQ/GgdXRAXpk2bPTdpRwHP4YkUow==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + typescript@5.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + engines: {node: '>=14.17'} hasBin: true ufo@1.5.3: @@ -2059,8 +2001,8 @@ packages: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} engines: {node: '>= 4.0.0'} - update-browserslist-db@1.0.15: - resolution: {integrity: sha512-K9HWH62x3/EalU1U6sjSZiylm9C8tgq2mSvshZpqc7QE69RaA2qjhkW2HlNA0tFpEbtyFz7HTqbSdN4MSwUodA==} + update-browserslist-db@1.0.16: + resolution: {integrity: sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -2071,30 +2013,17 @@ packages: url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - uuid@3.4.0: - resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} - deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + vite-node@1.6.0: + resolution: {integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true - v8-to-istanbul@9.2.0: - resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} - engines: {node: '>=10.12.0'} - - verror@1.10.0: - resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} - engines: {'0': node >=0.6.0} - - vite-node@0.29.8: - resolution: {integrity: sha512-b6OtCXfk65L6SElVM20q5G546yu10/kNrhg08afEoWlFRJXFq9/6glsvSVY+aI6YeC1tu2TtAqI2jHEQmOmsFw==} - engines: {node: '>=v14.16.0'} - hasBin: true - - vite@4.5.3: - resolution: {integrity: sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==} - engines: {node: ^14.18.0 || >=16.0.0} + vite@5.2.11: + resolution: {integrity: sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: - '@types/node': '>= 14' + '@types/node': ^18.0.0 || >=20.0.0 less: '*' lightningcss: ^1.21.0 sass: '*' @@ -2117,22 +2046,22 @@ packages: terser: optional: true - vitest@0.29.8: - resolution: {integrity: sha512-JIAVi2GK5cvA6awGpH0HvH/gEG9PZ0a/WoxdiV3PmqK+3CjQMf8c+J/Vhv4mdZ2nRyXFw66sAg6qz7VNkaHfDQ==} - engines: {node: '>=v14.16.0'} + vitest@1.6.0: + resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' - '@vitest/browser': '*' - '@vitest/ui': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 1.6.0 + '@vitest/ui': 1.6.0 happy-dom: '*' jsdom: '*' - playwright: '*' - safaridriver: '*' - webdriverio: '*' peerDependenciesMeta: '@edge-runtime/vm': optional: true + '@types/node': + optional: true '@vitest/browser': optional: true '@vitest/ui': @@ -2141,36 +2070,34 @@ packages: optional: true jsdom: optional: true - playwright: - optional: true - safaridriver: - optional: true - webdriverio: - optional: true - w3c-xmlserializer@4.0.0: - resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} - engines: {node: '>=14'} + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} webidl-conversions@7.0.0: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} - whatwg-encoding@2.0.0: - resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} - engines: {node: '>=12'} + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} - whatwg-mimetype@3.0.0: - resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} - engines: {node: '>=12'} + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} - whatwg-url@12.0.1: - resolution: {integrity: sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==} - engines: {node: '>=14'} + whatwg-url@14.0.0: + resolution: {integrity: sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==} + engines: {node: '>=18'} which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + which-builtin-type@1.1.3: + resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} + engines: {node: '>= 0.4'} + which-collection@1.0.2: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} @@ -2193,10 +2120,6 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -2212,28 +2135,16 @@ packages: utf-8-validate: optional: true - xml-name-validator@4.0.0: - resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} - engines: {node: '>=12'} + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} xmlchars@2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} - - yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -2252,7 +2163,7 @@ snapshots: '@babel/code-frame@7.24.2': dependencies: '@babel/highlight': 7.24.5 - picocolors: 1.0.0 + picocolors: 1.0.1 '@babel/compat-data@7.24.4': {} @@ -2344,7 +2255,7 @@ snapshots: '@babel/helper-validator-identifier': 7.24.5 chalk: 2.4.2 js-tokens: 4.0.0 - picocolors: 1.0.0 + picocolors: 1.0.1 '@babel/parser@7.24.5': dependencies: @@ -2393,85 +2304,88 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} - '@esbuild/android-arm64@0.18.20': + '@esbuild/aix-ppc64@0.20.2': optional: true - '@esbuild/android-arm@0.18.20': + '@esbuild/android-arm64@0.20.2': optional: true - '@esbuild/android-x64@0.18.20': + '@esbuild/android-arm@0.20.2': optional: true - '@esbuild/darwin-arm64@0.18.20': + '@esbuild/android-x64@0.20.2': optional: true - '@esbuild/darwin-x64@0.18.20': + '@esbuild/darwin-arm64@0.20.2': optional: true - '@esbuild/freebsd-arm64@0.18.20': + '@esbuild/darwin-x64@0.20.2': optional: true - '@esbuild/freebsd-x64@0.18.20': + '@esbuild/freebsd-arm64@0.20.2': optional: true - '@esbuild/linux-arm64@0.18.20': + '@esbuild/freebsd-x64@0.20.2': optional: true - '@esbuild/linux-arm@0.18.20': + '@esbuild/linux-arm64@0.20.2': optional: true - '@esbuild/linux-ia32@0.18.20': + '@esbuild/linux-arm@0.20.2': optional: true - '@esbuild/linux-loong64@0.18.20': + '@esbuild/linux-ia32@0.20.2': optional: true - '@esbuild/linux-mips64el@0.18.20': + '@esbuild/linux-loong64@0.20.2': optional: true - '@esbuild/linux-ppc64@0.18.20': + '@esbuild/linux-mips64el@0.20.2': optional: true - '@esbuild/linux-riscv64@0.18.20': + '@esbuild/linux-ppc64@0.20.2': optional: true - '@esbuild/linux-s390x@0.18.20': + '@esbuild/linux-riscv64@0.20.2': optional: true - '@esbuild/linux-x64@0.18.20': + '@esbuild/linux-s390x@0.20.2': optional: true - '@esbuild/netbsd-x64@0.18.20': + '@esbuild/linux-x64@0.20.2': optional: true - '@esbuild/openbsd-x64@0.18.20': + '@esbuild/netbsd-x64@0.20.2': optional: true - '@esbuild/sunos-x64@0.18.20': + '@esbuild/openbsd-x64@0.20.2': optional: true - '@esbuild/win32-arm64@0.18.20': + '@esbuild/sunos-x64@0.20.2': optional: true - '@esbuild/win32-ia32@0.18.20': + '@esbuild/win32-arm64@0.20.2': optional: true - '@esbuild/win32-x64@0.18.20': + '@esbuild/win32-ia32@0.20.2': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@8.35.0)': + '@esbuild/win32-x64@0.20.2': + optional: true + + '@eslint-community/eslint-utils@4.4.0(eslint@9.2.0)': dependencies: - eslint: 8.35.0 + eslint: 9.2.0 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.10.0': {} - '@eslint/eslintrc@2.1.4': + '@eslint/eslintrc@3.0.2': dependencies: ajv: 6.12.6 debug: 4.3.4 - espree: 9.6.1 - globals: 13.24.0 + espree: 10.0.1 + globals: 14.0.0 ignore: 5.3.1 import-fresh: 3.3.0 js-yaml: 4.1.0 @@ -2480,9 +2394,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@8.35.0': {} + '@eslint/js@9.2.0': {} - '@humanwhocodes/config-array@0.11.14': + '@humanwhocodes/config-array@0.13.0': dependencies: '@humanwhocodes/object-schema': 2.0.3 debug: 4.3.4 @@ -2494,8 +2408,14 @@ snapshots: '@humanwhocodes/object-schema@2.0.3': {} + '@humanwhocodes/retry@0.2.4': {} + '@istanbuljs/schema@0.1.3': {} + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 @@ -2525,44 +2445,109 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 + '@pkgr/core@0.1.1': {} + '@remix-run/router@1.16.1': {} - '@testing-library/dom@9.3.4': + '@rollup/rollup-android-arm-eabi@4.17.2': + optional: true + + '@rollup/rollup-android-arm64@4.17.2': + optional: true + + '@rollup/rollup-darwin-arm64@4.17.2': + optional: true + + '@rollup/rollup-darwin-x64@4.17.2': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.17.2': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.17.2': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.17.2': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.17.2': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.17.2': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.17.2': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.17.2': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.17.2': + optional: true + + '@rollup/rollup-linux-x64-musl@4.17.2': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.17.2': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.17.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.17.2': + optional: true + + '@sinclair/typebox@0.27.8': {} + + '@testing-library/dom@10.1.0': dependencies: '@babel/code-frame': 7.24.2 '@babel/runtime': 7.24.5 '@types/aria-query': 5.0.4 - aria-query: 5.1.3 + aria-query: 5.3.0 chalk: 4.1.2 dom-accessibility-api: 0.5.16 lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/react@14.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@testing-library/react@15.0.7(@types/react@18.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.5 - '@testing-library/dom': 9.3.4 + '@testing-library/dom': 10.1.0 '@types/react-dom': 18.3.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - - '@tootallnate/once@2.0.0': {} + optionalDependencies: + '@types/react': 18.3.2 '@types/aria-query@5.0.4': {} - '@types/chai-subset@1.3.5': + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.24.5 + '@babel/types': 7.24.5 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.5 + + '@types/babel__generator@7.6.8': dependencies: - '@types/chai': 4.3.16 + '@babel/types': 7.24.5 - '@types/chai@4.3.16': {} + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.24.5 + '@babel/types': 7.24.5 - '@types/istanbul-lib-coverage@2.0.6': {} + '@types/babel__traverse@7.20.5': + dependencies: + '@babel/types': 7.24.5 - '@types/json-schema@7.0.15': {} + '@types/estree@1.0.5': {} '@types/json5@0.0.29': {} - '@types/node@18.19.33': + '@types/node@20.12.12': dependencies: undici-types: 5.26.5 @@ -2577,139 +2562,145 @@ snapshots: '@types/prop-types': 15.7.12 csstype: 3.1.3 - '@types/semver@7.5.8': {} - - '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.35.0)(typescript@4.9.5))(eslint@8.35.0)(typescript@4.9.5)': + '@typescript-eslint/eslint-plugin@7.9.0(@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5))(eslint@9.2.0)(typescript@5.4.5)': dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 5.62.0(eslint@8.35.0)(typescript@4.9.5) - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0(eslint@8.35.0)(typescript@4.9.5) - '@typescript-eslint/utils': 5.62.0(eslint@8.35.0)(typescript@4.9.5) - debug: 4.3.4 - eslint: 8.35.0 + '@typescript-eslint/parser': 7.9.0(eslint@9.2.0)(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.9.0 + '@typescript-eslint/type-utils': 7.9.0(eslint@9.2.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.9.0(eslint@9.2.0)(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.9.0 + eslint: 9.2.0 graphemer: 1.4.0 ignore: 5.3.1 - natural-compare-lite: 1.4.0 - semver: 7.6.2 - tsutils: 3.21.0(typescript@4.9.5) + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.4.5) optionalDependencies: - typescript: 4.9.5 + typescript: 5.4.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@5.62.0(eslint@8.35.0)(typescript@4.9.5)': + '@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5)': dependencies: - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + '@typescript-eslint/scope-manager': 7.9.0 + '@typescript-eslint/types': 7.9.0 + '@typescript-eslint/typescript-estree': 7.9.0(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.9.0 debug: 4.3.4 - eslint: 8.35.0 + eslint: 9.2.0 optionalDependencies: - typescript: 4.9.5 + typescript: 5.4.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@5.62.0': + '@typescript-eslint/scope-manager@7.9.0': dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 + '@typescript-eslint/types': 7.9.0 + '@typescript-eslint/visitor-keys': 7.9.0 - '@typescript-eslint/type-utils@5.62.0(eslint@8.35.0)(typescript@4.9.5)': + '@typescript-eslint/type-utils@7.9.0(eslint@9.2.0)(typescript@5.4.5)': dependencies: - '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) - '@typescript-eslint/utils': 5.62.0(eslint@8.35.0)(typescript@4.9.5) + '@typescript-eslint/typescript-estree': 7.9.0(typescript@5.4.5) + '@typescript-eslint/utils': 7.9.0(eslint@9.2.0)(typescript@5.4.5) debug: 4.3.4 - eslint: 8.35.0 - tsutils: 3.21.0(typescript@4.9.5) + eslint: 9.2.0 + ts-api-utils: 1.3.0(typescript@5.4.5) optionalDependencies: - typescript: 4.9.5 + typescript: 5.4.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@5.62.0': {} + '@typescript-eslint/types@7.9.0': {} - '@typescript-eslint/typescript-estree@5.62.0(typescript@4.9.5)': + '@typescript-eslint/typescript-estree@7.9.0(typescript@5.4.5)': dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 + '@typescript-eslint/types': 7.9.0 + '@typescript-eslint/visitor-keys': 7.9.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 + minimatch: 9.0.4 semver: 7.6.2 - tsutils: 3.21.0(typescript@4.9.5) + ts-api-utils: 1.3.0(typescript@5.4.5) optionalDependencies: - typescript: 4.9.5 + typescript: 5.4.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@5.62.0(eslint@8.35.0)(typescript@4.9.5)': + '@typescript-eslint/utils@7.9.0(eslint@9.2.0)(typescript@5.4.5)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.35.0) - '@types/json-schema': 7.0.15 - '@types/semver': 7.5.8 - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) - eslint: 8.35.0 - eslint-scope: 5.1.1 - semver: 7.6.2 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.2.0) + '@typescript-eslint/scope-manager': 7.9.0 + '@typescript-eslint/types': 7.9.0 + '@typescript-eslint/typescript-estree': 7.9.0(typescript@5.4.5) + eslint: 9.2.0 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/visitor-keys@5.62.0': + '@typescript-eslint/visitor-keys@7.9.0': dependencies: - '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/types': 7.9.0 eslint-visitor-keys: 3.4.3 - '@vitejs/plugin-react@3.1.0(vite@4.5.3(@types/node@18.19.33)(sass@1.58.3))': + '@vitejs/plugin-react@4.2.1(vite@5.2.11(@types/node@20.12.12)(sass@1.77.1))': dependencies: '@babel/core': 7.24.5 '@babel/plugin-transform-react-jsx-self': 7.24.5(@babel/core@7.24.5) '@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/core@7.24.5) - magic-string: 0.27.0 + '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 4.5.3(@types/node@18.19.33)(sass@1.58.3) + vite: 5.2.11(@types/node@20.12.12)(sass@1.77.1) transitivePeerDependencies: - supports-color - '@vitest/coverage-c8@0.29.8(vitest@0.29.8(jsdom@21.1.2)(sass@1.58.3))': + '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@20.12.12)(jsdom@24.0.0)(sass@1.77.1))': dependencies: - c8: 7.14.0 - picocolors: 1.0.0 + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 0.2.3 + debug: 4.3.4 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.4 + istanbul-reports: 3.1.7 + magic-string: 0.30.10 + magicast: 0.3.4 + picocolors: 1.0.1 std-env: 3.7.0 - vitest: 0.29.8(jsdom@21.1.2)(sass@1.58.3) + strip-literal: 2.1.0 + test-exclude: 6.0.0 + vitest: 1.6.0(@types/node@20.12.12)(jsdom@24.0.0)(sass@1.77.1) + transitivePeerDependencies: + - supports-color - '@vitest/expect@0.29.8': + '@vitest/expect@1.6.0': dependencies: - '@vitest/spy': 0.29.8 - '@vitest/utils': 0.29.8 + '@vitest/spy': 1.6.0 + '@vitest/utils': 1.6.0 chai: 4.4.1 - '@vitest/runner@0.29.8': + '@vitest/runner@1.6.0': dependencies: - '@vitest/utils': 0.29.8 - p-limit: 4.0.0 + '@vitest/utils': 1.6.0 + p-limit: 5.0.0 pathe: 1.1.2 - '@vitest/spy@0.29.8': + '@vitest/snapshot@1.6.0': dependencies: - tinyspy: 1.1.1 + magic-string: 0.30.10 + pathe: 1.1.2 + pretty-format: 29.7.0 - '@vitest/utils@0.29.8': + '@vitest/spy@1.6.0': dependencies: - cli-truncate: 3.1.0 - diff: 5.2.0 - loupe: 2.3.7 - pretty-format: 27.5.1 + tinyspy: 2.2.1 - abab@2.0.6: {} - - acorn-globals@7.0.1: + '@vitest/utils@1.6.0': dependencies: - acorn: 8.11.3 - acorn-walk: 8.3.2 + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 acorn-jsx@5.3.2(acorn@8.11.3): dependencies: @@ -2719,7 +2710,7 @@ snapshots: acorn@8.11.3: {} - agent-base@6.0.2: + agent-base@7.1.1: dependencies: debug: 4.3.4 transitivePeerDependencies: @@ -2734,8 +2725,6 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.0.1: {} - ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 @@ -2746,22 +2735,16 @@ snapshots: ansi-styles@5.2.0: {} - ansi-styles@6.2.1: {} - anymatch@3.1.3: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 - argparse@1.0.10: - dependencies: - sprintf-js: 1.0.3 - argparse@2.0.1: {} - aria-query@5.1.3: + aria-query@5.3.0: dependencies: - deep-equal: 2.2.3 + dequal: 2.0.3 array-buffer-byte-length@1.0.1: dependencies: @@ -2779,6 +2762,24 @@ snapshots: array-union@2.1.0: {} + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + + array.prototype.findlastindex@1.2.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + array.prototype.flat@1.3.2: dependencies: call-bind: 1.0.7 @@ -2793,6 +2794,13 @@ snapshots: es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 + array.prototype.toreversed@1.1.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + array.prototype.tosorted@1.1.3: dependencies: call-bind: 1.0.7 @@ -2812,12 +2820,6 @@ snapshots: is-array-buffer: 3.0.4 is-shared-array-buffer: 1.0.3 - asn1@0.2.6: - dependencies: - safer-buffer: 2.1.2 - - assert-plus@1.0.0: {} - assertion-error@1.1.0: {} asynckit@0.4.0: {} @@ -2826,16 +2828,8 @@ snapshots: dependencies: possible-typed-array-names: 1.0.0 - aws-sign2@0.7.0: {} - - aws4@1.12.0: {} - balanced-match@1.0.2: {} - bcrypt-pbkdf@1.0.2: - dependencies: - tweetnacl: 0.14.5 - binary-extensions@2.3.0: {} brace-expansion@1.1.11: @@ -2843,31 +2837,20 @@ snapshots: balanced-match: 1.0.2 concat-map: 0.0.1 + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + braces@3.0.2: dependencies: fill-range: 7.0.1 browserslist@4.23.0: dependencies: - caniuse-lite: 1.0.30001617 - electron-to-chromium: 1.4.763 + caniuse-lite: 1.0.30001620 + electron-to-chromium: 1.4.773 node-releases: 2.0.14 - update-browserslist-db: 1.0.15(browserslist@4.23.0) - - c8@7.14.0: - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@istanbuljs/schema': 0.1.3 - find-up: 5.0.0 - foreground-child: 2.0.0 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-report: 3.0.1 - istanbul-reports: 3.1.7 - rimraf: 3.0.2 - test-exclude: 6.0.0 - v8-to-istanbul: 9.2.0 - yargs: 16.2.0 - yargs-parser: 20.2.9 + update-browserslist-db: 1.0.16(browserslist@4.23.0) cac@6.7.14: {} @@ -2881,9 +2864,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001617: {} - - caseless@0.12.0: {} + caniuse-lite@1.0.30001620: {} chai@4.4.1: dependencies: @@ -2922,17 +2903,6 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - cli-truncate@3.1.0: - dependencies: - slice-ansi: 5.0.0 - string-width: 5.1.2 - - cliui@7.0.4: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - color-convert@1.9.3: dependencies: color-name: 1.1.3 @@ -2955,37 +2925,22 @@ snapshots: convert-source-map@2.0.0: {} - core-util-is@1.0.2: {} - - coveralls@3.1.1: - dependencies: - js-yaml: 3.14.1 - lcov-parse: 1.0.0 - log-driver: 1.2.7 - minimist: 1.2.8 - request: 2.88.2 - cross-spawn@7.0.3: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 - cssstyle@3.0.0: + cssstyle@4.0.1: dependencies: rrweb-cssom: 0.6.0 csstype@3.1.3: {} - dashdash@1.14.1: - dependencies: - assert-plus: 1.0.0 - - data-urls@4.0.0: + data-urls@5.0.0: dependencies: - abab: 2.0.6 - whatwg-mimetype: 3.0.0 - whatwg-url: 12.0.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.0.0 data-view-buffer@1.0.1: dependencies: @@ -3019,27 +2974,6 @@ snapshots: dependencies: type-detect: 4.0.8 - deep-equal@2.2.3: - dependencies: - array-buffer-byte-length: 1.0.1 - call-bind: 1.0.7 - es-get-iterator: 1.1.3 - get-intrinsic: 1.2.4 - is-arguments: 1.1.1 - is-array-buffer: 3.0.4 - is-date-object: 1.0.5 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.3 - isarray: 2.0.5 - object-is: 1.1.6 - object-keys: 1.1.1 - object.assign: 4.1.5 - regexp.prototype.flags: 1.5.2 - side-channel: 1.0.6 - which-boxed-primitive: 1.0.2 - which-collection: 1.0.2 - which-typed-array: 1.1.15 - deep-is@0.1.4: {} define-data-property@1.1.4: @@ -3056,7 +2990,9 @@ snapshots: delayed-stream@1.0.0: {} - diff@5.2.0: {} + dequal@2.0.3: {} + + diff-sequences@29.6.3: {} dir-glob@3.0.1: dependencies: @@ -3066,28 +3002,9 @@ snapshots: dependencies: esutils: 2.0.3 - doctrine@3.0.0: - dependencies: - esutils: 2.0.3 - dom-accessibility-api@0.5.16: {} - domexception@4.0.0: - dependencies: - webidl-conversions: 7.0.0 - - eastasianwidth@0.2.0: {} - - ecc-jsbn@0.1.2: - dependencies: - jsbn: 0.1.1 - safer-buffer: 2.1.2 - - electron-to-chromium@1.4.763: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} + electron-to-chromium@1.4.773: {} entities@4.5.0: {} @@ -3146,17 +3063,22 @@ snapshots: es-errors@1.3.0: {} - es-get-iterator@1.1.3: + es-iterator-helpers@1.0.19: dependencies: call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-set-tostringtag: 2.0.3 + function-bind: 1.1.2 get-intrinsic: 1.2.4 + globalthis: 1.0.4 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 has-symbols: 1.0.3 - is-arguments: 1.1.1 - is-map: 2.0.3 - is-set: 2.0.3 - is-string: 1.0.7 - isarray: 2.0.5 - stop-iteration-iterator: 1.0.0 + internal-slot: 1.0.7 + iterator.prototype: 1.1.2 + safe-array-concat: 1.1.2 es-object-atoms@1.0.0: dependencies: @@ -3178,30 +3100,31 @@ snapshots: is-date-object: 1.0.5 is-symbol: 1.0.4 - esbuild@0.18.20: + esbuild@0.20.2: optionalDependencies: - '@esbuild/android-arm': 0.18.20 - '@esbuild/android-arm64': 0.18.20 - '@esbuild/android-x64': 0.18.20 - '@esbuild/darwin-arm64': 0.18.20 - '@esbuild/darwin-x64': 0.18.20 - '@esbuild/freebsd-arm64': 0.18.20 - '@esbuild/freebsd-x64': 0.18.20 - '@esbuild/linux-arm': 0.18.20 - '@esbuild/linux-arm64': 0.18.20 - '@esbuild/linux-ia32': 0.18.20 - '@esbuild/linux-loong64': 0.18.20 - '@esbuild/linux-mips64el': 0.18.20 - '@esbuild/linux-ppc64': 0.18.20 - '@esbuild/linux-riscv64': 0.18.20 - '@esbuild/linux-s390x': 0.18.20 - '@esbuild/linux-x64': 0.18.20 - '@esbuild/netbsd-x64': 0.18.20 - '@esbuild/openbsd-x64': 0.18.20 - '@esbuild/sunos-x64': 0.18.20 - '@esbuild/win32-arm64': 0.18.20 - '@esbuild/win32-ia32': 0.18.20 - '@esbuild/win32-x64': 0.18.20 + '@esbuild/aix-ppc64': 0.20.2 + '@esbuild/android-arm': 0.20.2 + '@esbuild/android-arm64': 0.20.2 + '@esbuild/android-x64': 0.20.2 + '@esbuild/darwin-arm64': 0.20.2 + '@esbuild/darwin-x64': 0.20.2 + '@esbuild/freebsd-arm64': 0.20.2 + '@esbuild/freebsd-x64': 0.20.2 + '@esbuild/linux-arm': 0.20.2 + '@esbuild/linux-arm64': 0.20.2 + '@esbuild/linux-ia32': 0.20.2 + '@esbuild/linux-loong64': 0.20.2 + '@esbuild/linux-mips64el': 0.20.2 + '@esbuild/linux-ppc64': 0.20.2 + '@esbuild/linux-riscv64': 0.20.2 + '@esbuild/linux-s390x': 0.20.2 + '@esbuild/linux-x64': 0.20.2 + '@esbuild/netbsd-x64': 0.20.2 + '@esbuild/openbsd-x64': 0.20.2 + '@esbuild/sunos-x64': 0.20.2 + '@esbuild/win32-arm64': 0.20.2 + '@esbuild/win32-ia32': 0.20.2 + '@esbuild/win32-x64': 0.20.2 escalade@3.1.2: {} @@ -3209,17 +3132,9 @@ snapshots: escape-string-regexp@4.0.0: {} - escodegen@2.1.0: - dependencies: - esprima: 4.0.1 - estraverse: 5.3.0 - esutils: 2.0.3 - optionalDependencies: - source-map: 0.6.1 - - eslint-config-prettier@8.6.0(eslint@8.35.0): + eslint-config-prettier@9.1.0(eslint@9.2.0): dependencies: - eslint: 8.35.0 + eslint: 9.2.0 eslint-import-resolver-node@0.3.9: dependencies: @@ -3229,60 +3144,66 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@5.62.0(eslint@8.35.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint@8.35.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@9.2.0): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.35.0)(typescript@4.9.5) - eslint: 8.35.0 + '@typescript-eslint/parser': 7.9.0(eslint@9.2.0)(typescript@5.4.5) + eslint: 9.2.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.62.0(eslint@8.35.0)(typescript@4.9.5))(eslint@8.35.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5))(eslint@9.2.0): dependencies: array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 array.prototype.flat: 1.3.2 array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.35.0 + eslint: 9.2.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@5.62.0(eslint@8.35.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint@8.35.0) - has: 1.0.4 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@9.2.0) + hasown: 2.0.2 is-core-module: 2.13.1 is-glob: 4.0.3 minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 object.values: 1.2.0 - resolve: 1.22.8 semver: 6.3.1 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.35.0)(typescript@4.9.5) + '@typescript-eslint/parser': 7.9.0(eslint@9.2.0)(typescript@5.4.5) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.6.0(eslint@8.35.0))(eslint@8.35.0)(prettier@2.8.8): + eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0(eslint@9.2.0))(eslint@9.2.0)(prettier@3.2.5): dependencies: - eslint: 8.35.0 - prettier: 2.8.8 + eslint: 9.2.0 + prettier: 3.2.5 prettier-linter-helpers: 1.0.0 + synckit: 0.8.8 optionalDependencies: - eslint-config-prettier: 8.6.0(eslint@8.35.0) + eslint-config-prettier: 9.1.0(eslint@9.2.0) - eslint-plugin-react-hooks@4.6.0(eslint@8.35.0): + eslint-plugin-react-hooks@4.6.2(eslint@9.2.0): dependencies: - eslint: 8.35.0 + eslint: 9.2.0 - eslint-plugin-react@7.32.2(eslint@8.35.0): + eslint-plugin-react@7.34.1(eslint@9.2.0): dependencies: array-includes: 3.1.8 + array.prototype.findlast: 1.2.5 array.prototype.flatmap: 1.3.2 + array.prototype.toreversed: 1.1.2 array.prototype.tosorted: 1.1.3 doctrine: 2.1.0 - eslint: 8.35.0 + es-iterator-helpers: 1.0.19 + eslint: 9.2.0 estraverse: 5.3.0 jsx-ast-utils: 3.3.5 minimatch: 3.1.2 @@ -3295,77 +3216,63 @@ snapshots: semver: 6.3.1 string.prototype.matchall: 4.0.11 - eslint-scope@5.1.1: + eslint-plugin-simple-import-sort@12.1.0(eslint@9.2.0): dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 + eslint: 9.2.0 - eslint-scope@7.2.2: + eslint-scope@8.0.1: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 - eslint-utils@3.0.0(eslint@8.35.0): - dependencies: - eslint: 8.35.0 - eslint-visitor-keys: 2.1.0 - - eslint-visitor-keys@2.1.0: {} - eslint-visitor-keys@3.4.3: {} - eslint@8.35.0: + eslint-visitor-keys@4.0.0: {} + + eslint@9.2.0: dependencies: - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.35.0 - '@humanwhocodes/config-array': 0.11.14 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.2.0) + '@eslint-community/regexpp': 4.10.0 + '@eslint/eslintrc': 3.0.2 + '@eslint/js': 9.2.0 + '@humanwhocodes/config-array': 0.13.0 '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.2.4 '@nodelib/fs.walk': 1.2.8 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 debug: 4.3.4 - doctrine: 3.0.0 escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-utils: 3.0.0(eslint@8.35.0) - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 + eslint-scope: 8.0.1 + eslint-visitor-keys: 4.0.0 + espree: 10.0.1 esquery: 1.5.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 + file-entry-cache: 8.0.0 find-up: 5.0.0 glob-parent: 6.0.2 - globals: 13.24.0 - grapheme-splitter: 1.0.4 ignore: 5.3.1 - import-fresh: 3.3.0 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 - js-sdsl: 4.4.2 - js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 - regexpp: 3.2.0 strip-ansi: 6.0.1 - strip-json-comments: 3.1.1 text-table: 0.2.0 transitivePeerDependencies: - supports-color - espree@9.6.1: + espree@10.0.1: dependencies: acorn: 8.11.3 acorn-jsx: 5.3.2(acorn@8.11.3) - eslint-visitor-keys: 3.4.3 - - esprima@4.0.1: {} + eslint-visitor-keys: 4.0.0 esquery@1.5.0: dependencies: @@ -3375,15 +3282,25 @@ snapshots: dependencies: estraverse: 5.3.0 - estraverse@4.3.0: {} - estraverse@5.3.0: {} - esutils@2.0.3: {} + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.5 - extend@3.0.2: {} + esutils@2.0.3: {} - extsprintf@1.3.0: {} + execa@8.0.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 fast-deep-equal@3.1.3: {} @@ -3405,9 +3322,9 @@ snapshots: dependencies: reusify: 1.0.4 - file-entry-cache@6.0.1: + file-entry-cache@8.0.0: dependencies: - flat-cache: 3.2.0 + flat-cache: 4.0.1 fill-range@7.0.1: dependencies: @@ -3418,11 +3335,10 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - flat-cache@3.2.0: + flat-cache@4.0.1: dependencies: flatted: 3.3.1 keyv: 4.5.4 - rimraf: 3.0.2 flatted@3.3.1: {} @@ -3430,19 +3346,6 @@ snapshots: dependencies: is-callable: 1.2.7 - foreground-child@2.0.0: - dependencies: - cross-spawn: 7.0.3 - signal-exit: 3.0.7 - - forever-agent@0.6.1: {} - - form-data@2.3.3: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - form-data@4.0.0: dependencies: asynckit: 0.4.0 @@ -3467,8 +3370,6 @@ snapshots: gensync@1.0.0-beta.2: {} - get-caller-file@2.0.5: {} - get-func-name@2.0.2: {} get-intrinsic@1.2.4: @@ -3479,16 +3380,14 @@ snapshots: has-symbols: 1.0.3 hasown: 2.0.2 + get-stream@8.0.1: {} + get-symbol-description@1.0.2: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 get-intrinsic: 1.2.4 - getpass@0.1.7: - dependencies: - assert-plus: 1.0.0 - glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -3508,9 +3407,7 @@ snapshots: globals@11.12.0: {} - globals@13.24.0: - dependencies: - type-fest: 0.20.2 + globals@14.0.0: {} globalthis@1.0.4: dependencies: @@ -3530,17 +3427,8 @@ snapshots: dependencies: get-intrinsic: 1.2.4 - grapheme-splitter@1.0.4: {} - graphemer@1.4.0: {} - har-schema@2.0.0: {} - - har-validator@5.1.5: - dependencies: - ajv: 6.12.6 - har-schema: 2.0.0 - has-bigints@1.0.2: {} has-flag@3.0.0: {} @@ -3559,39 +3447,32 @@ snapshots: dependencies: has-symbols: 1.0.3 - has@1.0.4: {} - hasown@2.0.2: dependencies: function-bind: 1.1.2 - html-encoding-sniffer@3.0.0: + html-encoding-sniffer@4.0.0: dependencies: - whatwg-encoding: 2.0.0 + whatwg-encoding: 3.1.1 html-escaper@2.0.2: {} - http-proxy-agent@5.0.0: + http-proxy-agent@7.0.2: dependencies: - '@tootallnate/once': 2.0.0 - agent-base: 6.0.2 + agent-base: 7.1.1 debug: 4.3.4 transitivePeerDependencies: - supports-color - http-signature@1.2.0: - dependencies: - assert-plus: 1.0.0 - jsprim: 1.4.2 - sshpk: 1.18.0 - - https-proxy-agent@5.0.1: + https-proxy-agent@7.0.4: dependencies: - agent-base: 6.0.2 + agent-base: 7.1.1 debug: 4.3.4 transitivePeerDependencies: - supports-color + human-signals@5.0.0: {} + iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -3620,16 +3501,15 @@ snapshots: hasown: 2.0.2 side-channel: 1.0.6 - is-arguments@1.1.1: - dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 - is-array-buffer@3.0.4: dependencies: call-bind: 1.0.7 get-intrinsic: 1.2.4 + is-async-function@2.0.0: + dependencies: + has-tostringtag: 1.0.2 + is-bigint@1.0.4: dependencies: has-bigints: 1.0.2 @@ -3659,9 +3539,13 @@ snapshots: is-extglob@2.1.1: {} - is-fullwidth-code-point@3.0.0: {} + is-finalizationregistry@1.0.2: + dependencies: + call-bind: 1.0.7 - is-fullwidth-code-point@4.0.0: {} + is-generator-function@1.0.10: + dependencies: + has-tostringtag: 1.0.2 is-glob@4.0.3: dependencies: @@ -3692,6 +3576,8 @@ snapshots: dependencies: call-bind: 1.0.7 + is-stream@3.0.0: {} + is-string@1.0.7: dependencies: has-tostringtag: 1.0.2 @@ -3704,8 +3590,6 @@ snapshots: dependencies: which-typed-array: 1.1.15 - is-typedarray@1.0.0: {} - is-weakmap@2.0.2: {} is-weakref@1.0.2: @@ -3721,8 +3605,6 @@ snapshots: isexe@2.0.0: {} - isstream@0.1.2: {} - istanbul-lib-coverage@3.2.2: {} istanbul-lib-report@3.0.1: @@ -3731,40 +3613,44 @@ snapshots: make-dir: 4.0.0 supports-color: 7.2.0 + istanbul-lib-source-maps@5.0.4: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + debug: 4.3.4 + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + istanbul-reports@3.1.7: dependencies: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 - js-sdsl@4.4.2: {} + iterator.prototype@1.1.2: + dependencies: + define-properties: 1.2.1 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + reflect.getprototypeof: 1.0.6 + set-function-name: 2.0.2 js-tokens@4.0.0: {} - js-yaml@3.14.1: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 + js-tokens@9.0.0: {} js-yaml@4.1.0: dependencies: argparse: 2.0.1 - jsbn@0.1.1: {} - - jsdom@21.1.2: + jsdom@24.0.0: dependencies: - abab: 2.0.6 - acorn: 8.11.3 - acorn-globals: 7.0.1 - cssstyle: 3.0.0 - data-urls: 4.0.0 + cssstyle: 4.0.1 + data-urls: 5.0.0 decimal.js: 10.4.3 - domexception: 4.0.0 - escodegen: 2.1.0 form-data: 4.0.0 - html-encoding-sniffer: 3.0.0 - http-proxy-agent: 5.0.0 - https-proxy-agent: 5.0.1 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.4 is-potential-custom-element-name: 1.0.1 nwsapi: 2.2.10 parse5: 7.1.2 @@ -3772,13 +3658,13 @@ snapshots: saxes: 6.0.0 symbol-tree: 3.2.4 tough-cookie: 4.1.4 - w3c-xmlserializer: 4.0.0 + w3c-xmlserializer: 5.0.0 webidl-conversions: 7.0.0 - whatwg-encoding: 2.0.0 - whatwg-mimetype: 3.0.0 - whatwg-url: 12.0.1 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.0.0 ws: 8.17.0 - xml-name-validator: 4.0.0 + xml-name-validator: 5.0.0 transitivePeerDependencies: - bufferutil - supports-color @@ -3790,25 +3676,14 @@ snapshots: json-schema-traverse@0.4.1: {} - json-schema@0.4.0: {} - json-stable-stringify-without-jsonify@1.0.1: {} - json-stringify-safe@5.0.1: {} - json5@1.0.2: dependencies: minimist: 1.2.8 json5@2.2.3: {} - jsprim@1.4.2: - dependencies: - assert-plus: 1.0.0 - extsprintf: 1.3.0 - json-schema: 0.4.0 - verror: 1.10.0 - jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.8 @@ -3820,14 +3695,15 @@ snapshots: dependencies: json-buffer: 3.0.1 - lcov-parse@1.0.0: {} - levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 - local-pkg@0.4.3: {} + local-pkg@0.5.0: + dependencies: + mlly: 1.7.0 + pkg-types: 1.1.1 locate-path@6.0.0: dependencies: @@ -3835,8 +3711,6 @@ snapshots: lodash.merge@4.6.2: {} - log-driver@1.2.7: {} - loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 @@ -3851,14 +3725,22 @@ snapshots: lz-string@1.5.0: {} - magic-string@0.27.0: + magic-string@0.30.10: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 + magicast@0.3.4: + dependencies: + '@babel/parser': 7.24.5 + '@babel/types': 7.24.5 + source-map-js: 1.2.0 + make-dir@4.0.0: dependencies: semver: 7.6.2 + merge-stream@2.0.0: {} + merge2@1.4.1: {} micromatch@4.0.5: @@ -3872,10 +3754,16 @@ snapshots: dependencies: mime-db: 1.52.0 + mimic-fn@4.0.0: {} + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 + minimatch@9.0.4: + dependencies: + brace-expansion: 2.0.1 + minimist@1.2.8: {} mlly@1.7.0: @@ -3891,27 +3779,22 @@ snapshots: nanoid@3.3.7: {} - natural-compare-lite@1.4.0: {} - natural-compare@1.4.0: {} node-releases@2.0.14: {} normalize-path@3.0.0: {} - nwsapi@2.2.10: {} + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 - oauth-sign@0.9.0: {} + nwsapi@2.2.10: {} object-assign@4.1.1: {} object-inspect@1.13.1: {} - object-is@1.1.6: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - object-keys@1.1.1: {} object.assign@4.1.5: @@ -3934,6 +3817,12 @@ snapshots: es-abstract: 1.23.3 es-object-atoms: 1.0.0 + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + object.hasown@1.1.4: dependencies: define-properties: 1.2.1 @@ -3950,6 +3839,10 @@ snapshots: dependencies: wrappy: 1.0.2 + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -3963,7 +3856,7 @@ snapshots: dependencies: yocto-queue: 0.1.0 - p-limit@4.0.0: + p-limit@5.0.0: dependencies: yocto-queue: 1.0.0 @@ -3985,6 +3878,8 @@ snapshots: path-key@3.1.1: {} + path-key@4.0.0: {} + path-parse@1.0.7: {} path-type@4.0.0: {} @@ -3993,9 +3888,7 @@ snapshots: pathval@1.1.1: {} - performance-now@2.1.0: {} - - picocolors@1.0.0: {} + picocolors@1.0.1: {} picomatch@2.3.1: {} @@ -4010,7 +3903,7 @@ snapshots: postcss@8.4.38: dependencies: nanoid: 3.3.7 - picocolors: 1.0.0 + picocolors: 1.0.1 source-map-js: 1.2.0 prelude-ls@1.2.1: {} @@ -4019,7 +3912,7 @@ snapshots: dependencies: fast-diff: 1.3.0 - prettier@2.8.8: {} + prettier@3.2.5: {} pretty-format@27.5.1: dependencies: @@ -4027,6 +3920,12 @@ snapshots: ansi-styles: 5.2.0 react-is: 17.0.2 + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 @@ -4037,8 +3936,6 @@ snapshots: punycode@2.3.1: {} - qs@6.5.3: {} - querystringify@2.2.0: {} queue-microtask@1.2.3: {} @@ -4053,6 +3950,8 @@ snapshots: react-is@17.0.2: {} + react-is@18.3.1: {} + react-refresh@0.14.2: {} react-router-dom@6.23.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): @@ -4075,6 +3974,16 @@ snapshots: dependencies: picomatch: 2.3.1 + reflect.getprototypeof@1.0.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + globalthis: 1.0.4 + which-builtin-type: 1.1.3 + regenerator-runtime@0.14.1: {} regexp.prototype.flags@1.5.2: @@ -4084,33 +3993,6 @@ snapshots: es-errors: 1.3.0 set-function-name: 2.0.2 - regexpp@3.2.0: {} - - request@2.88.2: - dependencies: - aws-sign2: 0.7.0 - aws4: 1.12.0 - caseless: 0.12.0 - combined-stream: 1.0.8 - extend: 3.0.2 - forever-agent: 0.6.1 - form-data: 2.3.3 - har-validator: 5.1.5 - http-signature: 1.2.0 - is-typedarray: 1.0.0 - isstream: 0.1.2 - json-stringify-safe: 5.0.1 - mime-types: 2.1.35 - oauth-sign: 0.9.0 - performance-now: 2.1.0 - qs: 6.5.3 - safe-buffer: 5.2.1 - tough-cookie: 2.5.0 - tunnel-agent: 0.6.0 - uuid: 3.4.0 - - require-directory@2.1.1: {} - requires-port@1.0.0: {} resolve-from@4.0.0: {} @@ -4129,12 +4011,26 @@ snapshots: reusify@1.0.4: {} - rimraf@3.0.2: + rollup@4.17.2: dependencies: - glob: 7.2.3 - - rollup@3.29.4: + '@types/estree': 1.0.5 optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.17.2 + '@rollup/rollup-android-arm64': 4.17.2 + '@rollup/rollup-darwin-arm64': 4.17.2 + '@rollup/rollup-darwin-x64': 4.17.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.17.2 + '@rollup/rollup-linux-arm-musleabihf': 4.17.2 + '@rollup/rollup-linux-arm64-gnu': 4.17.2 + '@rollup/rollup-linux-arm64-musl': 4.17.2 + '@rollup/rollup-linux-powerpc64le-gnu': 4.17.2 + '@rollup/rollup-linux-riscv64-gnu': 4.17.2 + '@rollup/rollup-linux-s390x-gnu': 4.17.2 + '@rollup/rollup-linux-x64-gnu': 4.17.2 + '@rollup/rollup-linux-x64-musl': 4.17.2 + '@rollup/rollup-win32-arm64-msvc': 4.17.2 + '@rollup/rollup-win32-ia32-msvc': 4.17.2 + '@rollup/rollup-win32-x64-msvc': 4.17.2 fsevents: 2.3.3 rrweb-cssom@0.6.0: {} @@ -4150,8 +4046,6 @@ snapshots: has-symbols: 1.0.3 isarray: 2.0.5 - safe-buffer@5.2.1: {} - safe-regex-test@1.0.3: dependencies: call-bind: 1.0.7 @@ -4160,7 +4054,7 @@ snapshots: safer-buffer@2.1.2: {} - sass@1.58.3: + sass@1.77.1: dependencies: chokidar: 3.6.0 immutable: 4.3.6 @@ -4211,57 +4105,20 @@ snapshots: siginfo@2.0.0: {} - signal-exit@3.0.7: {} + signal-exit@4.1.0: {} slash@3.0.0: {} - slice-ansi@5.0.0: - dependencies: - ansi-styles: 6.2.1 - is-fullwidth-code-point: 4.0.0 - source-map-js@1.2.0: {} - source-map@0.6.1: {} - - sprintf-js@1.0.3: {} - spy4js@3.4.1: dependencies: serialize-as-code: 2.0.2 - sshpk@1.18.0: - dependencies: - asn1: 0.2.6 - assert-plus: 1.0.0 - bcrypt-pbkdf: 1.0.2 - dashdash: 1.14.1 - ecc-jsbn: 0.1.2 - getpass: 0.1.7 - jsbn: 0.1.1 - safer-buffer: 2.1.2 - tweetnacl: 0.14.5 - stackback@0.0.2: {} std-env@3.7.0: {} - stop-iteration-iterator@1.0.0: - dependencies: - internal-slot: 1.0.7 - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - string.prototype.matchall@4.0.11: dependencies: call-bind: 1.0.7 @@ -4300,17 +4157,15 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.0.1 - strip-bom@3.0.0: {} + strip-final-newline@3.0.0: {} + strip-json-comments@3.1.1: {} - strip-literal@1.3.0: + strip-literal@2.1.0: dependencies: - acorn: 8.11.3 + js-tokens: 9.0.0 supports-color@5.5.0: dependencies: @@ -4324,6 +4179,11 @@ snapshots: symbol-tree@3.2.4: {} + synckit@0.8.8: + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.6.2 + test-exclude@6.0.0: dependencies: '@istanbuljs/schema': 0.1.3 @@ -4334,9 +4194,9 @@ snapshots: tinybench@2.8.0: {} - tinypool@0.4.0: {} + tinypool@0.8.4: {} - tinyspy@1.1.1: {} + tinyspy@2.2.1: {} to-fast-properties@2.0.0: {} @@ -4344,11 +4204,6 @@ snapshots: dependencies: is-number: 7.0.0 - tough-cookie@2.5.0: - dependencies: - psl: 1.9.0 - punycode: 2.3.1 - tough-cookie@4.1.4: dependencies: psl: 1.9.0 @@ -4356,10 +4211,14 @@ snapshots: universalify: 0.2.0 url-parse: 1.5.10 - tr46@4.1.1: + tr46@5.0.0: dependencies: punycode: 2.3.1 + ts-api-utils@1.3.0(typescript@5.4.5): + dependencies: + typescript: 5.4.5 + tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 @@ -4367,18 +4226,7 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 - tslib@1.14.1: {} - - tsutils@3.21.0(typescript@4.9.5): - dependencies: - tslib: 1.14.1 - typescript: 4.9.5 - - tunnel-agent@0.6.0: - dependencies: - safe-buffer: 5.2.1 - - tweetnacl@0.14.5: {} + tslib@2.6.2: {} type-check@0.4.0: dependencies: @@ -4386,8 +4234,6 @@ snapshots: type-detect@4.0.8: {} - type-fest@0.20.2: {} - typed-array-buffer@1.0.2: dependencies: call-bind: 1.0.7 @@ -4420,7 +4266,18 @@ snapshots: is-typed-array: 1.1.13 possible-typed-array-names: 1.0.0 - typescript@4.9.5: {} + typescript-eslint@7.9.0(eslint@9.2.0)(typescript@5.4.5): + dependencies: + '@typescript-eslint/eslint-plugin': 7.9.0(@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5))(eslint@9.2.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.9.0(eslint@9.2.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.9.0(eslint@9.2.0)(typescript@5.4.5) + eslint: 9.2.0 + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + typescript@5.4.5: {} ufo@1.5.3: {} @@ -4435,11 +4292,11 @@ snapshots: universalify@0.2.0: {} - update-browserslist-db@1.0.15(browserslist@4.23.0): + update-browserslist-db@1.0.16(browserslist@4.23.0): dependencies: browserslist: 4.23.0 escalade: 3.1.2 - picocolors: 1.0.0 + picocolors: 1.0.1 uri-js@4.4.1: dependencies: @@ -4450,28 +4307,13 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 - uuid@3.4.0: {} - - v8-to-istanbul@9.2.0: - dependencies: - '@jridgewell/trace-mapping': 0.3.25 - '@types/istanbul-lib-coverage': 2.0.6 - convert-source-map: 2.0.0 - - verror@1.10.0: - dependencies: - assert-plus: 1.0.0 - core-util-is: 1.0.2 - extsprintf: 1.3.0 - - vite-node@0.29.8(@types/node@18.19.33)(sass@1.58.3): + vite-node@1.6.0(@types/node@20.12.12)(sass@1.77.1): dependencies: cac: 6.7.14 debug: 4.3.4 - mlly: 1.7.0 pathe: 1.1.2 - picocolors: 1.0.0 - vite: 4.5.3(@types/node@18.19.33)(sass@1.58.3) + picocolors: 1.0.1 + vite: 5.2.11(@types/node@20.12.12)(sass@1.77.1) transitivePeerDependencies: - '@types/node' - less @@ -4482,44 +4324,41 @@ snapshots: - supports-color - terser - vite@4.5.3(@types/node@18.19.33)(sass@1.58.3): + vite@5.2.11(@types/node@20.12.12)(sass@1.77.1): dependencies: - esbuild: 0.18.20 + esbuild: 0.20.2 postcss: 8.4.38 - rollup: 3.29.4 + rollup: 4.17.2 optionalDependencies: - '@types/node': 18.19.33 + '@types/node': 20.12.12 fsevents: 2.3.3 - sass: 1.58.3 + sass: 1.77.1 - vitest@0.29.8(jsdom@21.1.2)(sass@1.58.3): + vitest@1.6.0(@types/node@20.12.12)(jsdom@24.0.0)(sass@1.77.1): dependencies: - '@types/chai': 4.3.16 - '@types/chai-subset': 1.3.5 - '@types/node': 18.19.33 - '@vitest/expect': 0.29.8 - '@vitest/runner': 0.29.8 - '@vitest/spy': 0.29.8 - '@vitest/utils': 0.29.8 - acorn: 8.11.3 + '@vitest/expect': 1.6.0 + '@vitest/runner': 1.6.0 + '@vitest/snapshot': 1.6.0 + '@vitest/spy': 1.6.0 + '@vitest/utils': 1.6.0 acorn-walk: 8.3.2 - cac: 6.7.14 chai: 4.4.1 debug: 4.3.4 - local-pkg: 0.4.3 + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.10 pathe: 1.1.2 - picocolors: 1.0.0 - source-map: 0.6.1 + picocolors: 1.0.1 std-env: 3.7.0 - strip-literal: 1.3.0 + strip-literal: 2.1.0 tinybench: 2.8.0 - tinypool: 0.4.0 - tinyspy: 1.1.1 - vite: 4.5.3(@types/node@18.19.33)(sass@1.58.3) - vite-node: 0.29.8(@types/node@18.19.33)(sass@1.58.3) + tinypool: 0.8.4 + vite: 5.2.11(@types/node@20.12.12)(sass@1.77.1) + vite-node: 1.6.0(@types/node@20.12.12)(sass@1.77.1) why-is-node-running: 2.2.2 optionalDependencies: - jsdom: 21.1.2 + '@types/node': 20.12.12 + jsdom: 24.0.0 transitivePeerDependencies: - less - lightningcss @@ -4529,21 +4368,21 @@ snapshots: - supports-color - terser - w3c-xmlserializer@4.0.0: + w3c-xmlserializer@5.0.0: dependencies: - xml-name-validator: 4.0.0 + xml-name-validator: 5.0.0 webidl-conversions@7.0.0: {} - whatwg-encoding@2.0.0: + whatwg-encoding@3.1.1: dependencies: iconv-lite: 0.6.3 - whatwg-mimetype@3.0.0: {} + whatwg-mimetype@4.0.0: {} - whatwg-url@12.0.1: + whatwg-url@14.0.0: dependencies: - tr46: 4.1.1 + tr46: 5.0.0 webidl-conversions: 7.0.0 which-boxed-primitive@1.0.2: @@ -4554,6 +4393,21 @@ snapshots: is-string: 1.0.7 is-symbol: 1.0.4 + which-builtin-type@1.1.3: + dependencies: + function.prototype.name: 1.1.6 + has-tostringtag: 1.0.2 + is-async-function: 2.0.0 + is-date-object: 1.0.5 + is-finalizationregistry: 1.0.2 + is-generator-function: 1.0.10 + is-regex: 1.1.4 + is-weakref: 1.0.2 + isarray: 2.0.5 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.2 + which-typed-array: 1.1.15 + which-collection@1.0.2: dependencies: is-map: 2.0.3 @@ -4580,36 +4434,16 @@ snapshots: word-wrap@1.2.5: {} - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrappy@1.0.2: {} ws@8.17.0: {} - xml-name-validator@4.0.0: {} + xml-name-validator@5.0.0: {} xmlchars@2.2.0: {} - y18n@5.0.8: {} - yallist@3.1.1: {} - yargs-parser@20.2.9: {} - - yargs@16.2.0: - dependencies: - cliui: 7.0.4 - escalade: 3.1.2 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - yocto-queue@0.1.0: {} yocto-queue@1.0.0: {} diff --git a/src/index.tsx b/src/index.tsx index 0997cee..60d08c0 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,81 +1,86 @@ import React, { - RefAttributes, - useCallback, - useContext, - useEffect, - useImperativeHandle, - useMemo, - useRef, - useState, -} from 'react'; - -export type ErrorMessage = string | { id: string; values?: { [key: string]: React.ReactNode } }; + RefAttributes, + useCallback, + useContext, + useEffect, + useImperativeHandle, + useMemo, + useRef, + useState, +} from "react"; + +export type ErrorMessage = + | string + | { id: string; values?: { [key: string]: React.ReactNode } }; type MaybeError = ErrorMessage | undefined; export type FormErrors = { [name: FormField]: ErrorMessage | undefined }; export type Validator = (value?: F) => MaybeError | Promise; -export type ValidationType = 'onChange' | 'onBlur' | 'onSubmit'; +export type ValidationType = "onChange" | "onBlur" | "onSubmit"; type NonUndefined = T extends undefined ? never : T; export type FieldValidation = { [t in ValidationType]?: Validator }; export type FormValidation = { - [name in keyof V]?: V[name] extends Record - ? FormValidation & FieldValidation - : FieldValidation>; + [name in keyof V]?: V[name] extends Record + ? FormValidation & FieldValidation + : FieldValidation>; }; export type FormDirty = { [name: FormField]: boolean | undefined }; // draw back by using "symbol" as part of the type: for nested objects accessing the "description" property can lead // to losing type safety, because "description" is a reserved property for symbols and results into type collision. export type FormField = { __TYPE__: F | ((t: F) => void) } & symbol; export type FormFields = { - [name in keyof V]-?: V[name] extends Record - ? FormFields & FormField - : FormField; + [name in keyof V]-?: V[name] extends Record + ? FormFields & FormField + : FormField; } & FormField; export type MorfiData> = { - values: V; - errors: FormErrors; - hasErrors: boolean; - dirty: FormDirty; - isDirty: boolean; - isSubmitting: boolean; + values: V; + errors: FormErrors; + hasErrors: boolean; + dirty: FormDirty; + isDirty: boolean; + isSubmitting: boolean; }; export type FormProps> = { - className?: string; - validation?: FormValidation; - data: MorfiData; - version?: number; - children: React.ReactNode; - onChange: (data: MorfiData) => void; - onSubmit?: (values: V) => void | Promise; - onSubmitFailed?: (err: Error, data: MorfiData) => void; - onSubmitFinished?: (data: MorfiData) => void; + className?: string; + validation?: FormValidation; + data: MorfiData; + version?: number; + children: React.ReactNode; + onChange: (data: MorfiData) => void; + onSubmit?: (values: V) => void | Promise; + onSubmitFailed?: (err: Error, data: MorfiData) => void; + onSubmitFinished?: (data: MorfiData) => void; }; export type FormRef> = { - submit: () => void; - updateInitialData: (mapper: (data: V) => V) => void; + submit: () => void; + updateInitialData: (mapper: (data: V) => V) => void; }; -type Updater> = ( - key: FormField, - valType: VT, - value: VT extends 'onChange' ? V[F] : undefined +type Updater> = < + F extends keyof V, + VT extends ValidationType, +>( + key: FormField, + valType: VT, + value: VT extends "onChange" ? V[F] : undefined, ) => void; export class MorfiError extends Error { - constructor(m: string) { - super(m); - Object.setPrototypeOf(this, new.target.prototype); - this.name = this.constructor.name; - } - /* c8 ignore next */ + constructor(m: string) { + super(m); + Object.setPrototypeOf(this, new.target.prototype); + this.name = this.constructor.name; + } + /* c8 ignore next */ } type MorfiContext> = { - getData: () => MorfiData; - update: Updater; - isRequired: (key: FormField) => boolean; - clearErrors: (key: FormField) => void; + getData: () => MorfiData; + update: Updater; + isRequired: (key: FormField) => boolean; + clearErrors: (key: FormField) => void; }; const morfiContext = React.createContext>(null as any); @@ -83,464 +88,528 @@ const morfiContext = React.createContext>(null as any); // no explicit promise detection, because we want to be able to use all other // promise frameworks (even if flow disallows this) // also promise.toString() === '[object Promise]' might not work on all browsers -const isPromise = (obj: any): boolean => Boolean(obj && typeof obj.then === 'function'); +const isPromise = (obj: any): boolean => + Boolean(obj && typeof obj.then === "function"); // this determines also the order in which the validations will be applied -const ValidationTypes: ValidationType[] = ['onChange', 'onBlur', 'onSubmit']; +const ValidationTypes: ValidationType[] = ["onChange", "onBlur", "onSubmit"]; const completeFieldValidation = ( - validators?: FieldValidation, - field?: F + validators?: FieldValidation, + field?: F, ): void | MaybeError | Promise => { - if (!validators) return; - const promises: Promise[] = []; - let syncError: MaybeError; - ValidationTypes.forEach((validationType) => { - const validator = validators[validationType]; - if (validator && !syncError) { - const error = validator(field); - if (error) { - if (isPromise(error)) { - // there might come an error, we have to await - promises.push(error as Promise); - } else { - // errors from sync validations will be favoured - syncError = error as MaybeError; - } - } + if (!validators) return; + const promises: Promise[] = []; + let syncError: MaybeError; + ValidationTypes.forEach((validationType) => { + const validator = validators[validationType]; + if (validator && !syncError) { + const error = validator(field); + if (error) { + if (isPromise(error)) { + // there might come an error, we have to await + promises.push(error as Promise); + } else { + // errors from sync validations will be favoured + syncError = error as MaybeError; } - }); - if (syncError) { - return syncError; - } - if (promises.length > 0) { - return new Promise((resolve) => { - Promise.all(promises).then((results: MaybeError[]) => { - resolve(results.find(Boolean)); - }); - }); + } } + }); + if (syncError) { + return syncError; + } + if (promises.length > 0) { + return new Promise((resolve) => { + Promise.all(promises).then((results: MaybeError[]) => { + resolve(results.find(Boolean)); + }); + }); + } }; -const getByFormField = (fieldId: FormField | string, nested?: Record): any => { - // if provided the "fields" returned by "Morfi.useForm" directly, this has a global meaning - const name = fieldId.toString(); - if (!name) return nested; - const fieldIdParts = name.split('.'); - return fieldIdParts.reduce((data, part) => data?.[part] as any, nested); +const getByFormField = ( + fieldId: FormField | string, + nested?: Record, +): any => { + // if provided the "fields" returned by "Morfi.useForm" directly, this has a global meaning + const name = fieldId.toString(); + if (!name) return nested; + const fieldIdParts = name.split("."); + return fieldIdParts.reduce((data, part) => data?.[part] as any, nested); }; -const dotPrefix = (name: string, prefix = ''): string => (prefix && prefix + '.') + name; +const dotPrefix = (name: string, prefix = ""): string => + (prefix && prefix + ".") + name; /** * Given a validation this function returns an object containing the field validations by field keys. */ const getAllValidators = >( - validation: FormValidation, - prefix?: string + validation: FormValidation, + prefix?: string, ): Record> => - Object.entries(validation).reduce((red, [name, val]) => { - const dottedPrefix = dotPrefix(name, prefix); - if (!val) return red; - const { onChange, onBlur, onSubmit, ...rest } = val as FieldValidation; - return { - ...red, - [dottedPrefix]: { onChange, onBlur, onSubmit }, - ...getAllValidators(rest, dottedPrefix), - }; - }, {} as Record); + Object.entries(validation).reduce( + (red, [name, val]) => { + const dottedPrefix = dotPrefix(name, prefix); + if (!val) return red; + const { onChange, onBlur, onSubmit, ...rest } = + val as FieldValidation; + return { + ...red, + [dottedPrefix]: { onChange, onBlur, onSubmit }, + ...getAllValidators(rest, dottedPrefix), + }; + }, + {} as Record, + ); const validateAll = >( - data: MorfiData, - validation: FormValidation + data: MorfiData, + validation: FormValidation, ): MorfiData | Promise> => { - const copy: MorfiData = deepCopyData(data); - const promises: Promise[] = []; - const allValidators = getAllValidators(validation); - - Object.entries(allValidators).forEach(([fieldId, validator]) => { - const error = completeFieldValidation(validator, getByFormField(fieldId, data.values)); - if (error) { - if (isPromise(error)) { - promises.push( - (error as Promise).then((err) => { - copy.errors[fieldId as any] = err; - }) - ); - } else { - copy.errors[fieldId as any] = error as MaybeError; - } - } - }); - - // if we have still async validations in the pipeline, we have to wait - // for all to get resolved - if (promises.length > 0) { - return new Promise((resolve) => { - Promise.all(promises).then(() => resolve(_nextData(copy))); - }); + const copy: MorfiData = deepCopyData(data); + const promises: Promise[] = []; + const allValidators = getAllValidators(validation); + + Object.entries(allValidators).forEach(([fieldId, validator]) => { + const error = completeFieldValidation( + validator, + getByFormField(fieldId, data.values), + ); + if (error) { + if (isPromise(error)) { + promises.push( + (error as Promise).then((err) => { + copy.errors[fieldId as any] = err; + }), + ); + } else { + copy.errors[fieldId as any] = error as MaybeError; + } } + }); - // no async validations, so we can handle this validation synchronous - return _nextData(copy); + // if we have still async validations in the pipeline, we have to wait + // for all to get resolved + if (promises.length > 0) { + return new Promise((resolve) => { + Promise.all(promises).then(() => resolve(_nextData(copy))); + }); + } + + // no async validations, so we can handle this validation synchronous + return _nextData(copy); }; const deepUpdateValue = ( - values: MorfiData['values'], - fieldKey: FormField, - value: any -): MorfiData['values'] => { - const fieldIdParts = fieldKey.toString().split('.'); - const result = { ...values }; - let cur = result; - fieldIdParts.forEach((part, index) => { - if (index === fieldIdParts.length - 1) { - cur[part] = value; - } else { - cur[part] = { ...cur[part] }; - cur = cur[part]; - } - }); - return result; + values: MorfiData["values"], + fieldKey: FormField, + value: any, +): MorfiData["values"] => { + const fieldIdParts = fieldKey.toString().split("."); + const result = { ...values }; + let cur = result; + fieldIdParts.forEach((part, index) => { + if (index === fieldIdParts.length - 1) { + cur[part] = value; + } else { + cur[part] = { ...cur[part] }; + cur = cur[part]; + } + }); + return result; }; const updateField = , FK extends keyof V>( - oldData: MorfiData, - fieldKey: FormField, - value: V[FK], - dirty: boolean, - error?: ErrorMessage + oldData: MorfiData, + fieldKey: FormField, + value: V[FK], + dirty: boolean, + error?: ErrorMessage, ): MorfiData => { - const result: MorfiData = deepCopyData(oldData); - result.values = deepUpdateValue(result.values, fieldKey, value); - result.dirty[fieldKey] = dirty; - result.errors[fieldKey] = error; - return _nextData(result); + const result: MorfiData = deepCopyData(oldData); + result.values = deepUpdateValue(result.values, fieldKey, value); + result.dirty[fieldKey] = dirty; + result.errors[fieldKey] = error; + return _nextData(result); }; // in order to mutate no references on old data objects, we need to create deep copies -const deepCopyData = >(data: MorfiData): MorfiData => ({ - ...data, - values: { ...data.values }, - errors: { ...data.errors }, - dirty: { ...data.dirty }, +const deepCopyData = >( + data: MorfiData, +): MorfiData => ({ + ...data, + values: { ...data.values }, + errors: { ...data.errors }, + dirty: { ...data.dirty }, }); -const _hasErrors = >(data: MorfiData): boolean => - Object.values(data.errors).some((e) => e !== undefined); -const _nextData = >(data: MorfiData): MorfiData => ({ - ...data, - hasErrors: _hasErrors(data), - isDirty: Object.values(data.dirty).some(Boolean), +const _hasErrors = >( + data: MorfiData, +): boolean => Object.values(data.errors).some((e) => e !== undefined); +const _nextData = >( + data: MorfiData, +): MorfiData => ({ + ...data, + hasErrors: _hasErrors(data), + isDirty: Object.values(data.dirty).some(Boolean), }); -type PropsRef> = React.MutableRefObject, 'children' | 'clasName'>>; +type PropsRef> = React.MutableRefObject< + Omit, "children" | "clasName"> +>; const useFormCallbacks = >( - propsRef: PropsRef -): Required, 'onChange' | 'onSubmitFinished' | 'onSubmitFailed'>> => { - const isMounted = useRef(true); - useEffect(() => { - isMounted.current = true; - return () => { - isMounted.current = false; - }; - }, []); - - const onChange = useCallback((data: MorfiData) => { - if (isMounted.current) propsRef.current.onChange(data); - }, []); // eslint-disable-line react-hooks/exhaustive-deps - const onSubmitFailed = useCallback((err: Error, data: MorfiData) => { - if (isMounted.current) - Promise.resolve().then(() => { - // we need to invoke this in the next tick, because of React18 automatic batching of updates - propsRef.current.onSubmitFailed?.(err, data); - }); - }, []); // eslint-disable-line react-hooks/exhaustive-deps - const onSubmitFinished = useCallback((data: MorfiData) => { - if (isMounted.current) - Promise.resolve().then(() => { - // we need to invoke this in the next tick, because of React18 automatic batching of updates - propsRef.current.onSubmitFinished?.(data); - }); - }, []); // eslint-disable-line react-hooks/exhaustive-deps - - return { onChange, onSubmitFinished, onSubmitFailed }; + propsRef: PropsRef, +): Required< + Pick, "onChange" | "onSubmitFinished" | "onSubmitFailed"> +> => { + const isMounted = useRef(true); + useEffect(() => { + isMounted.current = true; + return () => { + isMounted.current = false; + }; + }, []); + + const onChange = useCallback((data: MorfiData) => { + if (isMounted.current) propsRef.current.onChange(data); + }, []); + const onSubmitFailed = useCallback((err: Error, data: MorfiData) => { + if (isMounted.current) + Promise.resolve().then(() => { + // we need to invoke this in the next tick, because of React18 automatic batching of updates + propsRef.current.onSubmitFailed?.(err, data); + }); + }, []); + const onSubmitFinished = useCallback((data: MorfiData) => { + if (isMounted.current) + Promise.resolve().then(() => { + // we need to invoke this in the next tick, because of React18 automatic batching of updates + propsRef.current.onSubmitFinished?.(data); + }); + }, []); + + return { onChange, onSubmitFinished, onSubmitFailed }; }; const useFormUpdater = >( - propsRef: PropsRef, - initialRef: React.MutableRefObject, - onChange: FormProps['onChange'] + propsRef: PropsRef, + initialRef: React.MutableRefObject, + onChange: FormProps["onChange"], ): React.MutableRefObject> => { - const _onFieldChangeAfterValidation = useCallback( - (fieldKey: FormField, nextValue: V[FK], nextError?: ErrorMessage) => { - const { data } = propsRef.current; - // if the value did not change AND - // we had already an error or our validator did not return any error - // -> we return undefined to avoid a store update - if (getByFormField(fieldKey, data.values) !== nextValue || (nextError && !data.errors[fieldKey])) { - onChange( - updateField( - data, - fieldKey, - nextValue, - !morfiSetupOptions.comparator(nextValue, getByFormField(fieldKey, initialRef.current)), - nextError - ) - ); - } - }, - [onChange] // eslint-disable-line react-hooks/exhaustive-deps - ); - - const updateCB = useCallback>( - (fieldKey, type, val) => { - const { data, validation } = propsRef.current; - const value = - type === 'onChange' ? (val as NonNullable) : getByFormField(fieldKey, data.values); - const error = getByFormField(fieldKey, validation)?.[type]?.(value); - - if (isPromise(error)) { - if (getByFormField(fieldKey, data.values) !== value) { - // new value -> clear the previous error and update immediately - _onFieldChangeAfterValidation(fieldKey, value, undefined); - } - (error as Promise).then((e) => { - // async: get latest value again - if (getByFormField(fieldKey, propsRef.current.data.values) === value) { - // error corresponds to current value - _onFieldChangeAfterValidation(fieldKey, value, e); - } - }); - } else { - _onFieldChangeAfterValidation(fieldKey, value, error as MaybeError); - } - }, - [_onFieldChangeAfterValidation] // eslint-disable-line react-hooks/exhaustive-deps - ); - const update = useRef>(updateCB); - update.current = updateCB; - return update; + const _onFieldChangeAfterValidation = useCallback( + ( + fieldKey: FormField, + nextValue: V[FK], + nextError?: ErrorMessage, + ) => { + const { data } = propsRef.current; + // if the value did not change AND + // we had already an error or our validator did not return any error + // -> we return undefined to avoid a store update + if ( + getByFormField(fieldKey, data.values) !== nextValue || + (nextError && !data.errors[fieldKey]) + ) { + onChange( + updateField( + data, + fieldKey, + nextValue, + !morfiSetupOptions.comparator( + nextValue, + getByFormField(fieldKey, initialRef.current), + ), + nextError, + ), + ); + } + }, + [onChange], + ); + + const updateCB = useCallback>( + (fieldKey, type, val) => { + const { data, validation } = propsRef.current; + const value = + type === "onChange" + ? (val as NonNullable) + : getByFormField(fieldKey, data.values); + const error = getByFormField(fieldKey, validation)?.[type]?.(value); + + if (isPromise(error)) { + if (getByFormField(fieldKey, data.values) !== value) { + // new value -> clear the previous error and update immediately + _onFieldChangeAfterValidation(fieldKey, value, undefined); + } + (error as Promise).then((e) => { + // async: get latest value again + if ( + getByFormField(fieldKey, propsRef.current.data.values) === value + ) { + // error corresponds to current value + _onFieldChangeAfterValidation(fieldKey, value, e); + } + }); + } else { + _onFieldChangeAfterValidation(fieldKey, value, error as MaybeError); + } + }, + [_onFieldChangeAfterValidation], + ); + const update = useRef>(updateCB); + update.current = updateCB; + return update; }; // React strict mode calls all effects twice, so we need this helper // see: https://github.com/streamich/react-use/blob/master/src/useFirstMountState.ts const useFirstMountState = (): boolean => { - const isFirst = useRef(true); + const isFirst = useRef(true); - if (isFirst.current) { - isFirst.current = false; - return true; - } + if (isFirst.current) { + isFirst.current = false; + return true; + } - return isFirst.current; + return isFirst.current; }; const useFormSubmit = >( - propsRef: PropsRef, - onChange: FormProps['onChange'], - resetInitialRef: (values: V) => void, - onSubmitFinished: NonNullable['onSubmitFinished']>, - onSubmitFailed: NonNullable['onSubmitFailed']> + propsRef: PropsRef, + onChange: FormProps["onChange"], + resetInitialRef: (values: V) => void, + onSubmitFinished: NonNullable["onSubmitFinished"]>, + onSubmitFailed: NonNullable["onSubmitFailed"]>, ): ((e?: React.FormEvent) => void) => { - const _finishSubmit = useCallback((): void => { - const nextData: MorfiData = _nextData({ ...propsRef.current.data, isSubmitting: false, dirty: {} }); - resetInitialRef(nextData.values); + const _finishSubmit = useCallback((): void => { + const nextData: MorfiData = _nextData({ + ...propsRef.current.data, + isSubmitting: false, + dirty: {}, + }); + resetInitialRef(nextData.values); + onChange(nextData); + onSubmitFinished(nextData); + }, [onChange, onSubmitFinished]); + + const _onSubmitAfterValidation = useCallback( + (data: MorfiData): void => { + if (!data.hasErrors) { + ( + new Promise((r) => + r(propsRef.current.onSubmit?.(data.values)), + ) as Promise + ) + .then(_finishSubmit) + .catch((e: Error) => { + const nextData = { ...propsRef.current.data, isSubmitting: false }; + onChange(nextData); + // pass the encountered uncatched error to onSubmitFailed + onSubmitFailed(e, nextData); + }); + } else { + const nextData = { ...data, isSubmitting: false }; onChange(nextData); - onSubmitFinished(nextData); - }, [onChange, onSubmitFinished]); // eslint-disable-line react-hooks/exhaustive-deps - - const _onSubmitAfterValidation = useCallback( - (data: MorfiData): void => { - if (!data.hasErrors) { - (new Promise((r) => r(propsRef.current.onSubmit?.(data.values))) as Promise) - .then(_finishSubmit) - .catch((e: Error) => { - const nextData = { ...propsRef.current.data, isSubmitting: false }; - onChange(nextData); - // pass the encountered uncatched error to onSubmitFailed - onSubmitFailed(e, nextData); - }); - } else { - const nextData = { ...data, isSubmitting: false }; - onChange(nextData); - onSubmitFailed(new MorfiError('validation failed'), nextData); - } - }, - [_finishSubmit, onChange, onSubmitFailed] // eslint-disable-line react-hooks/exhaustive-deps - ); - - return useCallback( - (event?: React.FormEvent): void => { - event?.preventDefault(); - const { data, validation } = propsRef.current; - onChange({ ...data, isSubmitting: true }); - const validated = validation ? validateAll(data, validation) : data; - if (isPromise(validated)) { - (validated as Promise>).then((validatedData) => { - _onSubmitAfterValidation(validatedData); - }); - } else { - _onSubmitAfterValidation(validated as MorfiData); - } - }, - [_onSubmitAfterValidation, onChange] // eslint-disable-line react-hooks/exhaustive-deps - ); + onSubmitFailed(new MorfiError("validation failed"), nextData); + } + }, + [_finishSubmit, onChange, onSubmitFailed], + ); + + return useCallback( + (event?: React.FormEvent): void => { + event?.preventDefault(); + const { data, validation } = propsRef.current; + onChange({ ...data, isSubmitting: true }); + const validated = validation ? validateAll(data, validation) : data; + if (isPromise(validated)) { + (validated as Promise>).then((validatedData) => { + _onSubmitAfterValidation(validatedData); + }); + } else { + _onSubmitAfterValidation(validated as MorfiData); + } + }, + [_onSubmitAfterValidation, onChange], + ); }; const FormInner = >( - { className, children, version, ...props }: FormProps, - formRef: React.ForwardedRef> + { className, children, version, ...props }: FormProps, + formRef: React.ForwardedRef>, ) => { - // is used for value comparison for dirty checks - const initialRef = useRef(props.data.values); - const resetInitialRef = useCallback((values: V) => { - initialRef.current = values; - }, []); - - // using props ref container to avoid unnecessary re-renders - const propsRef = useRef(props); - propsRef.current = props; - const { onChange, onSubmitFinished, onSubmitFailed } = useFormCallbacks(propsRef); - const update = useFormUpdater(propsRef, initialRef, onChange); - const onSubmit = useFormSubmit(propsRef, onChange, resetInitialRef, onSubmitFinished, onSubmitFailed); - - const [ctx, setCtx] = useState>(() => ({ - getData: () => propsRef.current.data, - update: ((...args) => update.current(...args)) as Updater, - isRequired: (field: FormField) => - !!completeFieldValidation(getByFormField(field, propsRef.current.validation)), - clearErrors: (field: FormField) => - propsRef.current.onChange(Morfi.clearErrors(propsRef.current.data, field)), - })); - - // update all fields if parent component provides new data - const firstMount = useFirstMountState(); - - useEffect(() => { - if (firstMount) return; - // only purpose is flushing of context update - setCtx((prev) => ({ ...prev })); - }, [props.data]); // eslint-disable-line react-hooks/exhaustive-deps - - // update initial values on version change (can be used for multi submit forms) - useEffect(() => { - if (firstMount) return; - resetInitialRef(propsRef.current.data.values); - onChange(_nextData({ ...propsRef.current.data, errors: {}, dirty: {} })); - }, [version]); // eslint-disable-line react-hooks/exhaustive-deps - - useImperativeHandle | null, FormRef>( - formRef, - () => ({ - submit: () => onSubmit(), - updateInitialData: (mapper) => { - initialRef.current = mapper(initialRef.current); - }, - }), - [onSubmit] - ); - - const { Provider } = morfiContext; - - return ( -
- {children} -
- ); + // is used for value comparison for dirty checks + const initialRef = useRef(props.data.values); + const resetInitialRef = useCallback((values: V) => { + initialRef.current = values; + }, []); + + // using props ref container to avoid unnecessary re-renders + const propsRef = useRef(props); + propsRef.current = props; + const { onChange, onSubmitFinished, onSubmitFailed } = + useFormCallbacks(propsRef); + const update = useFormUpdater(propsRef, initialRef, onChange); + const onSubmit = useFormSubmit( + propsRef, + onChange, + resetInitialRef, + onSubmitFinished, + onSubmitFailed, + ); + + const [ctx, setCtx] = useState>(() => ({ + getData: () => propsRef.current.data, + update: ((...args) => update.current(...args)) as Updater, + isRequired: (field: FormField) => + !!completeFieldValidation( + getByFormField(field, propsRef.current.validation), + ), + clearErrors: (field: FormField) => + propsRef.current.onChange( + Morfi.clearErrors(propsRef.current.data, field), + ), + })); + + // update all fields if parent component provides new data + const firstMount = useFirstMountState(); + + useEffect(() => { + if (firstMount) return; + // only purpose is flushing of context update + setCtx((prev) => ({ ...prev })); + }, [props.data]); + + // update initial values on version change (can be used for multi submit forms) + useEffect(() => { + if (firstMount) return; + resetInitialRef(propsRef.current.data.values); + onChange(_nextData({ ...propsRef.current.data, errors: {}, dirty: {} })); + }, [version]); + + useImperativeHandle | null, FormRef>( + formRef, + () => ({ + submit: () => onSubmit(), + updateInitialData: (mapper) => { + initialRef.current = mapper(initialRef.current); + }, + }), + [onSubmit], + ); + + const { Provider } = morfiContext; + + return ( +
+ {children} +
+ ); }; -type FormComponent> = React.FC & RefAttributes>>; +type FormComponent> = React.FC< + FormProps & RefAttributes> +>; const Form: FormComponent = React.forwardRef(FormInner); export type FieldControls = { - onChange: (value: F) => void; - onBlur: () => void; - required: boolean; - dirty: boolean; - value: F; - error?: MaybeError; - name: string; + onChange: (value: F) => void; + onBlur: () => void; + required: boolean; + dirty: boolean; + value: F; + error?: MaybeError; + name: string; }; const useField = (field: FormField): FieldControls => { - const { update, getData, isRequired } = useContext(morfiContext); - const data = getData(); - return { - onChange: useCallback((v) => update(field, 'onChange', v), [update, field]), - onBlur: useCallback(() => update(field, 'onBlur', undefined), [update, field]), - value: getByFormField(field, data.values), - error: data.errors[field], - dirty: !!data.dirty[field], - required: isRequired(field), - name: field.toString(), - }; + const { update, getData, isRequired } = useContext(morfiContext); + const data = getData(); + return { + onChange: useCallback((v) => update(field, "onChange", v), [update, field]), + onBlur: useCallback( + () => update(field, "onBlur", undefined), + [update, field], + ), + value: getByFormField(field, data.values), + error: data.errors[field], + dirty: !!data.dirty[field], + required: isRequired(field), + name: field.toString(), + }; }; -const _createFieldNameProxy = (prefix = ''): any => - new Proxy({} as any, { - get(target, prop) { - if (prop === 'toString' || typeof prop === 'symbol') return () => prefix; // if used as symbol (e.g. object key) - // prevent creating new proxies on and on again - if (!target[prop]) target[prop] = _createFieldNameProxy(dotPrefix(prop, prefix)); - return target[prop]; - }, - }); +const _createFieldNameProxy = (prefix = ""): any => + new Proxy({} as any, { + get(target, prop) { + if (prop === "toString" || typeof prop === "symbol") return () => prefix; // if used as symbol (e.g. object key) + // prevent creating new proxies on and on again + if (!target[prop]) + target[prop] = _createFieldNameProxy(dotPrefix(prop, prefix)); + return target[prop]; + }, + }); export type MorfiContainer> = { - fields: FormFields; - Form: FormComponent; + fields: FormFields; + Form: FormComponent; }; const useForm = >(): MorfiContainer => - useMemo(() => ({ fields: _createFieldNameProxy(), Form }), []); - -const initialData = >(values: V): MorfiData => ({ - values, - errors: {}, - hasErrors: false, - dirty: {}, - isDirty: false, - isSubmitting: false, + useMemo(() => ({ fields: _createFieldNameProxy(), Form }), []); + +const initialData = >( + values: V, +): MorfiData => ({ + values, + errors: {}, + hasErrors: false, + dirty: {}, + isDirty: false, + isSubmitting: false, }); const notSubmittable = >( - { hasErrors, isDirty, isSubmitting }: MorfiData, - { skipDirty }: { skipDirty?: boolean } = {} + { hasErrors, isDirty, isSubmitting }: MorfiData, + { skipDirty }: { skipDirty?: boolean } = {}, ): boolean => hasErrors || isSubmitting || !(isDirty || skipDirty); const isValidationError = (err: any): boolean => err instanceof MorfiError; const clearErrors = (data: MorfiData, field: FormField) => { - const errorEntries = Object.entries(data.errors).filter( - ([name, value]) => value && !name.startsWith(field.toString()) - ); - const errors = Object.fromEntries(errorEntries); - return { ...data, errors, hasErrors: !!errorEntries.length }; + const errorEntries = Object.entries(data.errors).filter( + ([name, value]) => value && !name.startsWith(field.toString()), + ); + const errors = Object.fromEntries(errorEntries); + return { ...data, errors, hasErrors: !!errorEntries.length }; }; const useClearErrors = () => useContext(morfiContext).clearErrors; type MorfiSetupOptions = { - comparator: (a: T, b: T) => boolean; + comparator: (a: T, b: T) => boolean; }; const initialOptions: MorfiSetupOptions = { - comparator: (a, b) => a === b, + comparator: (a, b) => a === b, }; const morfiSetupOptions: MorfiSetupOptions = { - comparator: initialOptions.comparator, + comparator: initialOptions.comparator, }; -const configure = ({ comparator = initialOptions.comparator }: Partial) => { - morfiSetupOptions.comparator = comparator; +const configure = ({ + comparator = initialOptions.comparator, +}: Partial) => { + morfiSetupOptions.comparator = comparator; }; export const Morfi = { - configure, - useForm, - useField, - initialData, - notSubmittable, - isValidationError, - clearErrors, - useClearErrors, + configure, + useForm, + useField, + initialData, + notSubmittable, + isValidationError, + clearErrors, + useClearErrors, }; diff --git a/test-utils/index.tsx b/test-utils/index.tsx index 250026f..4590267 100644 --- a/test-utils/index.tsx +++ b/test-utils/index.tsx @@ -1,99 +1,105 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import { ErrorMessage, FormField, FormFields, FormProps, Morfi } from 'morfi'; -import { fireEvent, act } from '@testing-library/react'; +import React, { useCallback, useEffect, useState } from "react"; +import { act, fireEvent } from "@testing-library/react"; +import { ErrorMessage, FormField, FormFields, FormProps, Morfi } from "morfi"; type FieldData = { - props: Record; - error?: ErrorMessage; - dirty: boolean; - value: any; - required: boolean; - change: (v: any) => void; - blur: () => void; + props: Record; + error?: ErrorMessage; + dirty: boolean; + value: any; + required: boolean; + change: (v: any) => void; + blur: () => void; }; type FieldsData = Record; const clearFields = () => { - MorfiTestUtils.fields = {}; + MorfiTestUtils.fields = {}; }; -const Field: React.FC & { field: FormField }> = (props) => { - const { field } = props; - const { onChange, error, dirty, value, required, onBlur, name } = Morfi.useField(field); +const Field: React.FC & { field: FormField }> = ( + props, +) => { + const { field } = props; + const { onChange, error, dirty, value, required, onBlur, name } = + Morfi.useField(field); - const change = useCallback( - (v: any) => { - act(() => { - onChange(v); - }); - }, - [onChange] - ); - const blur = useCallback(() => { - act(() => { - onBlur(); - }); - }, [onBlur]); + const change = useCallback( + (v: any) => { + act(() => { + onChange(v); + }); + }, + [onChange], + ); + const blur = useCallback(() => { + act(() => { + onBlur(); + }); + }, [onBlur]); - MorfiTestUtils.fields[name] = { - props, - error, - dirty, - value, - required, - change, - blur, - }; + MorfiTestUtils.fields[name] = { + props, + error, + dirty, + value, + required, + change, + blur, + }; - useEffect( - () => () => { - delete MorfiTestUtils.fields[name]; - }, - [name] - ); + useEffect( + () => () => { + delete MorfiTestUtils.fields[name]; + }, + [name], + ); - return
; + return
; }; const submit = async (form?: HTMLFormElement) => { - fireEvent.submit(form || document.querySelector('form')!); - await act(() => new Promise((r) => setTimeout(r, 0))); + fireEvent.submit(form || document.querySelector("form")!); + await act(() => new Promise((r) => setTimeout(r, 0))); }; const getErrors = (): Record => - Object.fromEntries( - Object.entries(MorfiTestUtils.fields) - .map(([name, { error }]) => [name, error]) - .filter(([_name, error]) => !!error) - ); + Object.fromEntries( + Object.entries(MorfiTestUtils.fields) + .map(([name, { error }]) => [name, error]) + .filter(([_name, error]) => !!error), + ); const hasErrors = (): boolean => !!Object.keys(getErrors()).length; const Form = >({ - children, - initialData, - ...rest -}: Pick, 'onSubmit' | 'onSubmitFinished' | 'onSubmitFailed' | 'version' | 'validation'> & { - children: (fields: FormFields) => React.ReactNode; - initialData: T; + children, + initialData, + ...rest +}: Pick< + FormProps, + "onSubmit" | "onSubmitFinished" | "onSubmitFailed" | "version" | "validation" +> & { + children: (fields: FormFields) => React.ReactNode; + initialData: T; }) => { - const [data, setData] = useState(() => Morfi.initialData(initialData)); - const { Form: MorfiForm, fields } = Morfi.useForm(); + const [data, setData] = useState(() => Morfi.initialData(initialData)); + const { Form: MorfiForm, fields } = Morfi.useForm(); - return ( - - <>{children(fields)} -