From 12cd5175b1b5b5b2faf79824fe88b599d8884b4f Mon Sep 17 00:00:00 2001 From: Gabe Rodriguez Date: Tue, 6 Feb 2024 12:31:21 +0100 Subject: [PATCH] Refactor balances.ts to use protobuf types (#453) * Refactor balances.ts to use protobuf types * Review updates --- apps/extension/package.json | 4 +- .../extension/src/routes/popup/home/index.tsx | 6 +- apps/extension/src/state/wallets.ts | 23 +- apps/webapp/package.json | 6 +- apps/webapp/src/clients/penumbra-port.ts | 2 +- .../src/components/dashboard/assets-table.tsx | 110 +- .../src/components/send/ibc/ibc-form.tsx | 26 +- apps/webapp/src/components/send/receive.tsx | 4 +- .../src/components/send/send-form/index.tsx | 26 +- .../src/components/shared/asset-icon.tsx | 14 +- .../src/components/shared/input-token.tsx | 32 +- .../components/shared/select-token-modal.tsx | 65 +- .../src/components/swap/asset-out-box.tsx | 48 +- .../components/swap/asset-out-selector.tsx | 12 +- apps/webapp/src/components/swap/layout.tsx | 17 +- apps/webapp/src/components/swap/swap-form.tsx | 8 +- apps/webapp/src/fetchers/address.ts | 10 +- apps/webapp/src/fetchers/balances.ts | 152 -- .../src/fetchers/balances/by-account.ts | 40 + apps/webapp/src/fetchers/balances/by-asset.ts | 48 + apps/webapp/src/fetchers/balances/index.ts | 98 ++ apps/webapp/src/state/ibc.test.ts | 64 +- apps/webapp/src/state/ibc.ts | 27 +- apps/webapp/src/state/send.test.ts | 81 +- apps/webapp/src/state/send.ts | 71 +- apps/webapp/src/state/swap.test.ts | 50 +- apps/webapp/src/state/swap.ts | 41 +- apps/webapp/src/state/types.ts | 7 - package.json | 10 +- packages/eslint-config-custom/package.json | 6 +- .../asset-metadata-by-id.ts | 13 + .../src/grpc/view-protocol-server/helpers.ts | 19 + .../src/grpc/view-protocol-server/index.ts | 5 +- .../transaction-planner.ts | 27 +- packages/tsconfig/base.json | 1 - packages/types/src/account.ts | 4 - packages/types/src/amount.test.ts | 15 +- packages/types/src/amount.ts | 7 +- packages/types/src/index.ts | 5 +- packages/types/src/schemas/address-index.ts | 6 + packages/types/src/schemas/address.ts | 6 + packages/types/src/schemas/asset-id.ts | 7 + .../types/src/schemas/asset-image--theme.ts | 7 + packages/types/src/schemas/asset-image.ts | 8 + packages/types/src/schemas/denom-metadata.ts | 15 + packages/types/src/schemas/denom-unit.ts | 7 + packages/types/src/schemas/index.ts | 7 + .../types/src/type-predicates/address-view.ts | 25 + packages/types/src/type-predicates/index.ts | 2 + .../types/src/type-predicates/value-view.ts | 14 + packages/types/src/validation.test.ts | 31 +- packages/types/src/validation.ts | 35 +- packages/types/src/value-view.ts | 21 + .../components/ui/address-component.test.tsx | 29 + .../ui/components/ui/address-component.tsx | 21 + packages/ui/components/ui/address-icon.tsx | 16 +- packages/ui/components/ui/address.test.tsx | 27 - packages/ui/components/ui/address.tsx | 17 - packages/ui/components/ui/identicon/index.tsx | 12 +- packages/ui/components/ui/identicon/types.ts | 2 +- packages/ui/components/ui/select-account.tsx | 40 +- .../ui/components/ui/tx/view/address-view.tsx | 7 +- packages/ui/components/ui/tx/view/value.tsx | 16 +- packages/ui/components/ui/types/address.tsx | 0 packages/ui/components/ui/types/value.tsx | 0 packages/ui/package.json | 8 +- pnpm-lock.yaml | 1229 +++++++++-------- 67 files changed, 1568 insertions(+), 1251 deletions(-) delete mode 100644 apps/webapp/src/fetchers/balances.ts create mode 100644 apps/webapp/src/fetchers/balances/by-account.ts create mode 100644 apps/webapp/src/fetchers/balances/by-asset.ts create mode 100644 apps/webapp/src/fetchers/balances/index.ts delete mode 100644 apps/webapp/src/state/types.ts create mode 100644 packages/router/src/grpc/view-protocol-server/asset-metadata-by-id.ts create mode 100644 packages/router/src/grpc/view-protocol-server/helpers.ts delete mode 100644 packages/types/src/account.ts create mode 100644 packages/types/src/schemas/address-index.ts create mode 100644 packages/types/src/schemas/address.ts create mode 100644 packages/types/src/schemas/asset-id.ts create mode 100644 packages/types/src/schemas/asset-image--theme.ts create mode 100644 packages/types/src/schemas/asset-image.ts create mode 100644 packages/types/src/schemas/denom-metadata.ts create mode 100644 packages/types/src/schemas/denom-unit.ts create mode 100644 packages/types/src/schemas/index.ts create mode 100644 packages/types/src/type-predicates/address-view.ts create mode 100644 packages/types/src/type-predicates/index.ts create mode 100644 packages/types/src/type-predicates/value-view.ts create mode 100644 packages/types/src/value-view.ts create mode 100644 packages/ui/components/ui/address-component.test.tsx create mode 100644 packages/ui/components/ui/address-component.tsx delete mode 100644 packages/ui/components/ui/address.test.tsx delete mode 100644 packages/ui/components/ui/types/address.tsx delete mode 100644 packages/ui/components/ui/types/value.tsx diff --git a/apps/extension/package.json b/apps/extension/package.json index 635df58dc0..a6963da975 100644 --- a/apps/extension/package.json +++ b/apps/extension/package.json @@ -38,13 +38,13 @@ "@types/chrome": "0.0.260", "@types/firefox-webext-browser": "^120.0.0", "@types/node": "^20.11.16", - "@types/react": "^18.2.53", + "@types/react": "^18.2.55", "@types/react-dom": "^18.2.18", "autoprefixer": "^10.4.17", "copy-webpack-plugin": "^12.0.2", "css-loader": "^6.10.0", "html-webpack-plugin": "^5.6.0", - "postcss": "^8.4.33", + "postcss": "^8.4.34", "postcss-loader": "^8.1.0", "style-loader": "^3.3.4", "tailwindcss": "^3.4.1", diff --git a/apps/extension/src/routes/popup/home/index.tsx b/apps/extension/src/routes/popup/home/index.tsx index 41f4c521b7..f491c14e88 100644 --- a/apps/extension/src/routes/popup/home/index.tsx +++ b/apps/extension/src/routes/popup/home/index.tsx @@ -5,7 +5,7 @@ import { IndexHeader } from './index-header'; import { useStore } from '../../../state'; import { BlockSync } from './block-sync'; import { localExtStorage, sessionExtStorage } from '@penumbra-zone/storage'; -import { accountAddrSelector } from '../../../state/wallets'; +import { addrByIndexSelector } from '../../../state/wallets'; export interface PopupLoaderData { lastBlockSynced: number; @@ -32,14 +32,14 @@ export const popupIndexLoader = async (): Promise => }; export const PopupIndex = () => { - const getAccount = useStore(accountAddrSelector); + const getAddrByIndex = useStore(addrByIndexSelector); return (
- +
diff --git a/apps/extension/src/state/wallets.ts b/apps/extension/src/state/wallets.ts index a3e07e058e..1424334a5d 100644 --- a/apps/extension/src/state/wallets.ts +++ b/apps/extension/src/state/wallets.ts @@ -8,7 +8,8 @@ import { } from '@penumbra-zone/wasm-ts'; import { Key } from '@penumbra-zone/crypto-web'; import { ExtensionStorage, LocalStorageState } from '@penumbra-zone/storage'; -import { Wallet, WalletCreate, bech32Address } from '@penumbra-zone/types'; +import { Wallet, WalletCreate } from '@penumbra-zone/types'; +import { Address } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1alpha1/keys_pb'; export interface WalletsSlice { all: Wallet[]; @@ -74,17 +75,13 @@ export const createWalletsSlice = export const walletsSelector = (state: AllSlices) => state.wallets; export const getActiveWallet = (state: AllSlices) => state.wallets.all[0]; -export const accountAddrSelector = (state: AllSlices) => (index: number, ephemeral: boolean) => { - const active = getActiveWallet(state); - if (!active) return; +export const addrByIndexSelector = + (state: AllSlices) => + (index: number, ephemeral: boolean): Address => { + const active = getActiveWallet(state); + if (!active) throw new Error('No active wallet'); - const addr = ephemeral - ? getEphemeralByIndex(active.fullViewingKey, index) - : getAddressByIndex(active.fullViewingKey, index); - const bech32Addr = bech32Address(addr); - - return { - address: bech32Addr, - index, + return ephemeral + ? getEphemeralByIndex(active.fullViewingKey, index) + : getAddressByIndex(active.fullViewingKey, index); }; -}; diff --git a/apps/webapp/package.json b/apps/webapp/package.json index afa6358daf..16de641c77 100644 --- a/apps/webapp/package.json +++ b/apps/webapp/package.json @@ -19,23 +19,25 @@ "@radix-ui/react-icons": "^1.3.0", "@tanstack/react-query": "^5.18.1", "bignumber.js": "^9.1.2", + "immer": "^10.0.3", "react": "^18.2.0", "react-dom": "^18.2.0", "react-helmet": "^6.1.0", "react-loader-spinner": "^6.1.6", "react-router-dom": "^6.22.0", "tailwindcss": "^3.4.1", + "zod": "^3.22.4", "zustand": "^4.5.0" }, "devDependencies": { "@types/node": "^20.11.16", - "@types/react": "^18.2.53", + "@types/react": "^18.2.55", "@types/react-dom": "^18.2.18", "@types/react-helmet": "^6.1.11", "@vitejs/plugin-react-swc": "^3.6.0", "autoprefixer": "^10.4.17", "firebase-tools": "^13.1.0", - "postcss": "^8.4.33", + "postcss": "^8.4.34", "vite": "^5.0.12", "vitest": "^1.2.2" } diff --git a/apps/webapp/src/clients/penumbra-port.ts b/apps/webapp/src/clients/penumbra-port.ts index 584afbf72e..4a40660214 100644 --- a/apps/webapp/src/clients/penumbra-port.ts +++ b/apps/webapp/src/clients/penumbra-port.ts @@ -16,7 +16,7 @@ declare global { export const getPenumbraPort = (serviceTypeName: string) => { const { port1: port, port2: transferPort } = new MessageChannel(); if (!(penumbra in window)) throw Error('No Penumbra global (extension not installed)'); - const initPort = window[penumbra].services?.[serviceTypeName]; + const initPort = window[penumbra]?.services?.[serviceTypeName]; if (!initPort) throw Error(`No init port for service ${serviceTypeName}`); initPort.postMessage( { diff --git a/apps/webapp/src/components/dashboard/assets-table.tsx b/apps/webapp/src/components/dashboard/assets-table.tsx index e151c737db..51cebc8c80 100644 --- a/apps/webapp/src/components/dashboard/assets-table.tsx +++ b/apps/webapp/src/components/dashboard/assets-table.tsx @@ -1,19 +1,23 @@ -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@penumbra-zone/ui'; -import { displayUsd, fromBaseUnitAmountAndMetadata } from '@penumbra-zone/types'; import { LoaderFunction, useLoaderData } from 'react-router-dom'; import { throwIfExtNotInstalled } from '../../fetchers/is-connected.ts'; -import { AccountBalance, getBalancesByAccount } from '../../fetchers/balances.ts'; -import { AssetIcon } from '../shared/asset-icon.tsx'; import { AddressIcon } from '@penumbra-zone/ui/components/ui/address-icon'; -import { Address } from '@penumbra-zone/ui/components/ui/address.tsx'; +import { AddressComponent } from '@penumbra-zone/ui/components/ui/address-component'; +import { + AccountGroupedBalances, + getBalancesByAccount, +} from '../../fetchers/balances/by-account.ts'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@penumbra-zone/ui'; +import { AssetIcon } from '../shared/asset-icon.tsx'; +import { displayUsd, hasDenomMetadata } from '@penumbra-zone/types'; +import { ValueViewComponent } from '@penumbra-zone/ui/components/ui/tx/view/value.tsx'; -export const AssetsLoader: LoaderFunction = async (): Promise => { +export const AssetsLoader: LoaderFunction = async (): Promise => { throwIfExtNotInstalled(); return await getBalancesByAccount(); }; export default function AssetsTable() { - const data = useLoaderData() as AccountBalance[]; + const data = useLoaderData() as AccountGroupedBalances[]; if (data.length === 0) { return ( @@ -31,73 +35,63 @@ export default function AssetsTable() { return (
- {data.map(a => { - return ( -
-
-
-
- -

Account #{a.index}

{' '} -
- -
+ {data.map((a, index) => ( +
+
+
+
+ +

Account #{a.index.account}

+
-
- {a.balances.map((asset, i) => ( -
-
- -

{asset.metadata.display}

-
-

- {fromBaseUnitAmountAndMetadata(asset.amount, asset.metadata).toFormat()} -

-

- {asset.usdcValue == 0 ? '$–' : `$${displayUsd(asset.usdcValue)}`} -

-
- ))} -
- - - - Asset - Balance - Value - - - - {a.balances.map((asset, i) => ( - + + +
+ + + Asset + Balance + Value + + + + {a.balances.map((assetBalance, index) => { + return ( +
- -

{asset.metadata.display}

+ {hasDenomMetadata(assetBalance.value) && ( + <> + +

+ {assetBalance.value.valueView.value.metadata.display} +

+ + )}
-
-

- {fromBaseUnitAmountAndMetadata(asset.amount, asset.metadata).toFormat()} -

+
+

- {asset.usdcValue == 0 ? '$–' : `$${displayUsd(asset.usdcValue)}`} + {assetBalance.usdcValue == 0 + ? '$–' + : `$${displayUsd(assetBalance.usdcValue)}`}

- ))} - -
-
- ); - })} + ); + })} + + +
+ ))}
); } diff --git a/apps/webapp/src/components/send/ibc/ibc-form.tsx b/apps/webapp/src/components/send/ibc/ibc-form.tsx index fc158a822a..617ca2c684 100644 --- a/apps/webapp/src/components/send/ibc/ibc-form.tsx +++ b/apps/webapp/src/components/send/ibc/ibc-form.tsx @@ -8,28 +8,24 @@ import InputToken from '../../shared/input-token'; import { sendValidationErrors } from '../../../state/send'; import { useMemo } from 'react'; import { LoaderFunction, useLoaderData } from 'react-router-dom'; -import { AccountBalance, getBalancesByAccount } from '../../../fetchers/balances'; +import { AssetBalance, getAssetBalances } from '../../../fetchers/balances'; import { penumbraAddrValidation } from '../helpers'; -export const IbcAssetBalanceLoader: LoaderFunction = async (): Promise => { - const balancesByAccount = await getBalancesByAccount(); +export const IbcAssetBalanceLoader: LoaderFunction = async (): Promise => { + const assetBalances = await getAssetBalances(); - if (balancesByAccount[0]) { + if (assetBalances[0]) { // set initial account if accounts exist and asset if account has asset list useStore.setState(state => { - state.ibc.selection = { - address: balancesByAccount[0]?.address, - accountIndex: balancesByAccount[0]?.index, - asset: balancesByAccount[0]?.balances[0], - }; + state.ibc.selection = assetBalances[0]; }); } - return balancesByAccount; + return assetBalances; }; export default function IbcForm() { - const accountBalances = useLoaderData() as AccountBalance[]; + const assetBalances = useLoaderData() as AssetBalance[]; const { toast } = useToast(); const { sendIbcWithdraw, @@ -42,8 +38,8 @@ export default function IbcForm() { } = useStore(ibcSelector); const validationErrors = useMemo(() => { - return sendValidationErrors(selection?.asset, amount, destinationChainAddress); - }, [selection?.asset, amount, destinationChainAddress]); + return sendValidationErrors(selection, amount, destinationChainAddress); + }, [selection, amount, destinationChainAddress]); return (
validationErrors.amountErr, }, ]} - balances={accountBalances} + balances={assetBalances} /> Send diff --git a/apps/webapp/src/components/send/receive.tsx b/apps/webapp/src/components/send/receive.tsx index fcffc15512..f3dd665d36 100644 --- a/apps/webapp/src/components/send/receive.tsx +++ b/apps/webapp/src/components/send/receive.tsx @@ -1,10 +1,10 @@ import { SelectAccount } from '@penumbra-zone/ui'; -import { getAccountAddr } from '../../fetchers/address'; +import { getAddrByIndex } from '../../fetchers/address'; export const Receive = () => { return (
- +
); }; diff --git a/apps/webapp/src/components/send/send-form/index.tsx b/apps/webapp/src/components/send/send-form/index.tsx index 4730d93078..6d61b97cf6 100644 --- a/apps/webapp/src/components/send/send-form/index.tsx +++ b/apps/webapp/src/components/send/send-form/index.tsx @@ -4,7 +4,7 @@ import { sendSelector, sendValidationErrors } from '../../../state/send.ts'; import { useToast } from '@penumbra-zone/ui/components/ui/use-toast'; import { InputBlock } from '../../shared/input-block'; import { LoaderFunction, useLoaderData } from 'react-router-dom'; -import { AccountBalance, getBalancesByAccount } from '../../../fetchers/balances'; +import { AssetBalance, getAssetBalances } from '../../../fetchers/balances'; import { useMemo } from 'react'; import { penumbraAddrValidation } from '../helpers'; import { throwIfExtNotInstalled } from '../../../fetchers/is-connected'; @@ -12,26 +12,22 @@ import InputToken from '../../shared/input-token.tsx'; import { useRefreshFee } from './use-refresh-fee.ts'; import { GasFee } from '../../shared/gas-fee.tsx'; -export const SendAssetBalanceLoader: LoaderFunction = async (): Promise => { +export const SendAssetBalanceLoader: LoaderFunction = async (): Promise => { throwIfExtNotInstalled(); - const balancesByAccount = await getBalancesByAccount(); + const assetBalances = await getAssetBalances(); - if (balancesByAccount[0]) { + if (assetBalances[0]) { // set initial account if accounts exist and asset if account has asset list useStore.setState(state => { - state.send.selection = { - address: balancesByAccount[0]?.address, - accountIndex: balancesByAccount[0]?.index, - asset: balancesByAccount[0]?.balances[0], - }; + state.send.selection = assetBalances[0]; }); } - return balancesByAccount; + return assetBalances; }; export const SendForm = () => { - const accountBalances = useLoaderData() as AccountBalance[]; + const assetBalances = useLoaderData() as AssetBalance[]; const { toast } = useToast(); const { selection, @@ -52,8 +48,8 @@ export const SendForm = () => { useRefreshFee(); const validationErrors = useMemo(() => { - return sendValidationErrors(selection?.asset, amount, recipient); - }, [selection?.asset, amount, recipient]); + return sendValidationErrors(selection, amount, recipient); + }, [selection, amount, recipient]); return ( { checkFn: () => validationErrors.amountErr, }, ]} - balances={accountBalances} + balances={assetBalances} /> @@ -128,7 +124,7 @@ export const SendForm = () => { !recipient || !!Object.values(validationErrors).find(Boolean) || txInProgress || - !selection?.asset + !selection } > Send diff --git a/apps/webapp/src/components/shared/asset-icon.tsx b/apps/webapp/src/components/shared/asset-icon.tsx index 3bf79b30fb..841bc635e4 100644 --- a/apps/webapp/src/components/shared/asset-icon.tsx +++ b/apps/webapp/src/components/shared/asset-icon.tsx @@ -1,21 +1,27 @@ import { localAssets } from '@penumbra-zone/constants'; import { Identicon } from '@penumbra-zone/ui'; import { useMemo } from 'react'; +import { Metadata } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; -export const AssetIcon = ({ name }: { name: string }) => { +export const AssetIcon = ({ metadata }: { metadata: Metadata }) => { const icon = useMemo(() => { - const assetImage = localAssets.find(i => i.display === name)?.images[0]; + const assetImage = localAssets.find(d => d.display === metadata.display)?.images[0]; // Image default is "" and thus cannot do nullish-coalescing // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing return assetImage?.png || assetImage?.svg; - }, [name]); + }, [metadata]); return ( <> {icon ? ( Asset icon ) : ( - + )} ); diff --git a/apps/webapp/src/components/shared/input-token.tsx b/apps/webapp/src/components/shared/input-token.tsx index 525f7edbb2..1f23d3837f 100644 --- a/apps/webapp/src/components/shared/input-token.tsx +++ b/apps/webapp/src/components/shared/input-token.tsx @@ -2,40 +2,20 @@ import { Input, InputProps } from '@penumbra-zone/ui'; import { cn } from '@penumbra-zone/ui/lib/utils'; import SelectTokenModal from './select-token-modal'; import { Validation } from './validation-result'; -import { AccountBalance, AssetBalance } from '../../fetchers/balances'; -import { Selection } from '../../state/types'; +import { AssetBalance } from '../../fetchers/balances'; import { ValueViewComponent } from '@penumbra-zone/ui/components/ui/tx/view/value'; -import { ValueView } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; import { InputBlock } from './input-block'; -const getCurrentBalanceValueView = (assetBalance: AssetBalance | undefined): ValueView => { - if (assetBalance?.metadata) - return new ValueView({ - valueView: { - case: 'knownAssetId', - value: { amount: assetBalance.amount, metadata: assetBalance.metadata }, - }, - }); - else if (assetBalance?.assetId) - return new ValueView({ - valueView: { - case: 'unknownAssetId', - value: { amount: assetBalance.amount, assetId: assetBalance.assetId }, - }, - }); - else return new ValueView(); -}; - interface InputTokenProps extends InputProps { label: string; - selection: Selection | undefined; + selection: AssetBalance | undefined; placeholder: string; className?: string; inputClassName?: string; value: string; - setSelection: (selection: Selection) => void; + setSelection: (selection: AssetBalance) => void; validations?: Validation[]; - balances: AccountBalance[]; + balances: AssetBalance[]; } export default function InputToken({ @@ -50,8 +30,6 @@ export default function InputToken({ balances, ...props }: InputTokenProps) { - const currentBalanceValueView = getCurrentBalanceValueView(selection?.asset); - return (
@@ -72,7 +50,7 @@ export default function InputToken({
Wallet - +
diff --git a/apps/webapp/src/components/shared/select-token-modal.tsx b/apps/webapp/src/components/shared/select-token-modal.tsx index 5d8f0c11ff..a74abf05af 100644 --- a/apps/webapp/src/components/shared/select-token-modal.tsx +++ b/apps/webapp/src/components/shared/select-token-modal.tsx @@ -8,16 +8,16 @@ import { DialogTrigger, Input, } from '@penumbra-zone/ui'; -import { fromBaseUnitAmountAndMetadata } from '@penumbra-zone/types'; import { cn } from '@penumbra-zone/ui/lib/utils'; -import { AccountBalance } from '../../fetchers/balances'; +import { AssetBalance } from '../../fetchers/balances'; import { AssetIcon } from './asset-icon'; -import { Selection } from '../../state/types'; +import { ValueViewComponent } from '@penumbra-zone/ui/components/ui/tx/view/value.tsx'; +import { getDisplayDenomFromView } from '@penumbra-zone/types'; interface SelectTokenModalProps { - selection: Selection | undefined; - setSelection: (selection: Selection) => void; - balances: AccountBalance[]; + selection: AssetBalance | undefined; + setSelection: (selection: AssetBalance) => void; + balances: AssetBalance[]; } export default function SelectTokenModal({ @@ -27,16 +27,16 @@ export default function SelectTokenModal({ }: SelectTokenModalProps) { const [search, setSearch] = useState(''); + const displayDenom = selection && getDisplayDenomFromView(selection.value); + const denomMetadata = + selection?.value.valueView.case === 'knownAssetId' && selection.value.valueView.value.metadata; + return (
- {selection?.asset?.metadata.display && ( - - )} -

- {selection?.asset?.metadata.display} -

+ {denomMetadata && } +

{displayDenom}

@@ -60,34 +60,39 @@ export default function SelectTokenModal({

Balance

- {balances.map(b => ( -
- {b.balances.map((k, j) => ( - + {balances.map((b, i) => { + const index = + b.address.addressView.case === 'decoded' && + b.address.addressView.value.index?.account; + + return ( +
+
- setSelection({ accountIndex: b.index, address: b.address, asset: k }) - } + onClick={() => setSelection(b)} > -

{b.index}

+

{index}

- -

{k.metadata.display}

+ {b.value.valueView.case === 'knownAssetId' && + b.value.valueView.value.metadata && ( + + )} +

{getDisplayDenomFromView(b.value)}

+
+
+
-

- {fromBaseUnitAmountAndMetadata(k.amount, k.metadata).toFormat()} -

- ))} -
- ))} +
+ ); + })}
diff --git a/apps/webapp/src/components/swap/asset-out-box.tsx b/apps/webapp/src/components/swap/asset-out-box.tsx index 5d9a9bd9f8..40256e01d6 100644 --- a/apps/webapp/src/components/swap/asset-out-box.tsx +++ b/apps/webapp/src/components/swap/asset-out-box.tsx @@ -1,6 +1,6 @@ import { useStore } from '../../state'; import { swapSelector } from '../../state/swap'; -import { AccountBalance, AssetBalance, groupByAsset } from '../../fetchers/balances'; +import { AssetBalance } from '../../fetchers/balances'; import { Input } from '@penumbra-zone/ui'; import { AssetOutSelector } from './asset-out-selector'; import { @@ -8,34 +8,30 @@ import { ValueView, } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; import { ValueViewComponent } from '@penumbra-zone/ui/components/ui/tx/view/value'; +import { groupByAsset } from '../../fetchers/balances/by-asset.ts'; + +const findMatchingBalance = ( + denom: Metadata | undefined, + balances: AssetBalance[], +): ValueView | undefined => { + if (!denom?.penumbraAssetId) return undefined; + const grouped = balances.reduce(groupByAsset, []); + console.log(grouped); + + return balances.reduce(groupByAsset, []).find(v => { + if (v.valueView.case !== 'knownAssetId') return false; + return v.valueView.value.metadata?.penumbraAssetId?.equals(denom.penumbraAssetId); + }); +}; interface AssetOutBoxProps { - balances: AccountBalance[]; + balances: AssetBalance[]; } export const AssetOutBox = ({ balances }: AssetOutBoxProps) => { const { assetOut, setAssetOut } = useStore(swapSelector); - const aggregatedBalances = balances - .flatMap(b => b.balances) - .reduce(groupByAsset, []); - - // TODO: with https://github.com/penumbra-zone/web/issues/392 convert to use `getValueViewByAccount` - const balanceOfDenom = aggregatedBalances.find(b => b.assetId.equals(assetOut?.penumbraAssetId)); - const valueView = balanceOfDenom - ? new ValueView({ - valueView: { - case: 'knownAssetId', - value: { - amount: balanceOfDenom.amount, - metadata: new Metadata({ - display: balanceOfDenom.metadata.display, - denomUnits: balanceOfDenom.metadata.denomUnits, - }), - }, - }, - }) - : new ValueView(); + const matchingBalance = findMatchingBalance(assetOut, balances); return (
@@ -50,17 +46,13 @@ export const AssetOutBox = ({ balances }: AssetOutBoxProps) => { // TODO: estimate actual swap out amount button: https://github.com/penumbra-zone/web/issues/421 value='' /> - +
Wallet - + {matchingBalance && }
diff --git a/apps/webapp/src/components/swap/asset-out-selector.tsx b/apps/webapp/src/components/swap/asset-out-selector.tsx index c6dea61e24..3e2b86b8e4 100644 --- a/apps/webapp/src/components/swap/asset-out-selector.tsx +++ b/apps/webapp/src/components/swap/asset-out-selector.tsx @@ -15,7 +15,7 @@ export const AssetOutSelector = ({ balances, setAssetOut, assetOut }: AssetOutSe
- {assetOut?.display && } + {assetOut?.display && }

{assetOut?.display}

@@ -24,16 +24,16 @@ export const AssetOutSelector = ({ balances, setAssetOut, assetOut }: AssetOutSe Select asset
- {localAssets.map(a => ( -
+ {localAssets.map(d => ( +
setAssetOut(a)} + onClick={() => setAssetOut(d)} >
- -

{a.display}

+ +

{d.display}

diff --git a/apps/webapp/src/components/swap/layout.tsx b/apps/webapp/src/components/swap/layout.tsx index fa5749109c..a8e8554656 100644 --- a/apps/webapp/src/components/swap/layout.tsx +++ b/apps/webapp/src/components/swap/layout.tsx @@ -1,6 +1,6 @@ import { Card } from '@penumbra-zone/ui'; import { LoaderFunction } from 'react-router-dom'; -import { AccountBalance, getBalancesByAccount } from '../../fetchers/balances'; +import { AssetBalance, getAssetBalances } from '../../fetchers/balances'; import { useStore } from '../../state'; import { throwIfExtNotInstalled } from '../../fetchers/is-connected'; import { EduInfoCard } from '../shared/edu-panels/edu-info-card'; @@ -8,24 +8,19 @@ import { EduPanel } from '../shared/edu-panels/content'; import { SwapForm } from './swap-form'; import { localAssets } from '@penumbra-zone/constants'; -export const SwapLoader: LoaderFunction = async (): Promise => { +export const SwapLoader: LoaderFunction = async (): Promise => { throwIfExtNotInstalled(); - const balancesByAccount = await getBalancesByAccount(); + const assetBalances = await getAssetBalances(); // set initial denom in if there is an available balance - if (balancesByAccount[0]) { + if (assetBalances[0]) { useStore.setState(state => { - state.swap.assetIn = { - address: balancesByAccount[0]?.address, - accountIndex: balancesByAccount[0]?.index, - asset: balancesByAccount[0]?.balances[0], - }; - + state.swap.assetIn = assetBalances[0]; state.swap.assetOut = localAssets[0]; }); } - return balancesByAccount; + return assetBalances; }; export const SwapLayout = () => { diff --git a/apps/webapp/src/components/swap/swap-form.tsx b/apps/webapp/src/components/swap/swap-form.tsx index 3a021caadc..f95e67a44c 100644 --- a/apps/webapp/src/components/swap/swap-form.tsx +++ b/apps/webapp/src/components/swap/swap-form.tsx @@ -2,13 +2,13 @@ import { Button } from '@penumbra-zone/ui'; import { useToast } from '@penumbra-zone/ui/components/ui/use-toast'; import InputToken from '../shared/input-token'; import { useLoaderData } from 'react-router-dom'; -import { AccountBalance } from '../../fetchers/balances'; +import { AssetBalance } from '../../fetchers/balances'; import { useStore } from '../../state'; import { swapSelector } from '../../state/swap'; import { AssetOutBox } from './asset-out-box'; export const SwapForm = () => { - const accountBalances = useLoaderData() as AccountBalance[]; + const assetBalances = useLoaderData() as AssetBalance[]; const { toast } = useToast(); const { assetIn, setAssetIn, amount, setAmount, initiateSwapTx } = useStore(swapSelector); @@ -32,9 +32,9 @@ export const SwapForm = () => { setAmount(e.target.value); }} validations={[]} - balances={accountBalances} + balances={assetBalances} /> - + diff --git a/apps/webapp/src/fetchers/address.ts b/apps/webapp/src/fetchers/address.ts index 01ffb56e04..35cf0602b7 100644 --- a/apps/webapp/src/fetchers/address.ts +++ b/apps/webapp/src/fetchers/address.ts @@ -36,12 +36,6 @@ export const getEphemeralAddress = async (account = 0): Promise
=> { return address; }; -export const getAccountAddr = async (index: number, ephemeral: boolean) => { - const address = ephemeral ? await getEphemeralAddress(index) : await getAddressByIndex(index); - const bech32 = bech32Address(address); - - return { - address: bech32, - index, - }; +export const getAddrByIndex = async (index: number, ephemeral: boolean) => { + return ephemeral ? await getEphemeralAddress(index) : await getAddressByIndex(index); }; diff --git a/apps/webapp/src/fetchers/balances.ts b/apps/webapp/src/fetchers/balances.ts deleted file mode 100644 index cd19da3b1e..0000000000 --- a/apps/webapp/src/fetchers/balances.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { - AssetsResponse, - BalancesRequest, - BalancesResponse, -} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/view/v1alpha1/view_pb'; -import { - AssetId, - Metadata, -} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; -import { getAddresses, IndexAddrRecord } from './address'; -import { getAllAssets } from './assets'; -import { Amount } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/num/v1alpha1/num_pb'; -import { addAmounts, joinLoHiAmount, uint8ArrayToBase64 } from '@penumbra-zone/types'; -import { AddressIndex } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1alpha1/keys_pb'; -import { viewClient } from '../clients/grpc'; -import { streamToPromise } from './stream'; - -export interface AssetBalance { - metadata: Metadata; - assetId: AssetId; - amount: Amount; - usdcValue: number; -} - -export interface AccountBalance { - index: number; - address: string; - balances: AssetBalance[]; -} - -type NormalizedBalance = AssetBalance & { - account: { index: number; address: string }; -}; - -const getDenomAmount = ( - res: BalancesResponse, - metadata: AssetsResponse[], -): { amount: Amount; metadata: Metadata } => { - const assetId = uint8ArrayToBase64(res.balance!.assetId!.inner); - const match = metadata.find(m => { - if (!m.denomMetadata?.penumbraAssetId?.inner) return false; - return assetId === uint8ArrayToBase64(m.denomMetadata.penumbraAssetId.inner); - }); - - const amount = res.balance?.amount ?? new Amount(); - - return { amount, metadata: match?.denomMetadata ?? new Metadata() }; -}; - -const normalize = - (assetResponses: AssetsResponse[], indexAddrRecord: IndexAddrRecord | undefined) => - (res: BalancesResponse): NormalizedBalance => { - const index = res.account?.account ?? 0; - const address = indexAddrRecord?.[index] ?? ''; - - const { metadata, amount } = getDenomAmount(res, assetResponses); - - return { - metadata, - assetId: res.balance!.assetId!, - amount, - //usdcValue: amount * 0.93245, // TODO: Temporary until pricing implemented - usdcValue: 0, // Important not to imply that testnet balances have any value - account: { index, address }, - }; - }; - -const groupByAccount = (balances: AccountBalance[], curr: NormalizedBalance): AccountBalance[] => { - const match = balances.find(b => b.index === curr.account.index); - const newBalance = { - metadata: curr.metadata, - amount: curr.amount, - usdcValue: curr.usdcValue, - assetId: curr.assetId, - } satisfies AssetBalance; - - if (match) { - match.balances.push(newBalance); - match.balances.sort(sortByAmount); - } else { - balances.push({ - address: curr.account.address, - index: curr.account.index, - balances: [newBalance], - }); - } - return balances; -}; - -const sortByAmount = (a: AssetBalance, b: AssetBalance): number => { - // First, sort by asset value in descending order (largest to smallest). - if (a.usdcValue !== b.usdcValue) return b.usdcValue - a.usdcValue; - - // If values are equal, sort by amount descending - if (!a.amount.equals(b.amount)) - return Number(joinLoHiAmount(b.amount) - joinLoHiAmount(a.amount)); - - // If both are equal, sort by asset name in ascending order - return a.metadata.display.localeCompare(b.metadata.display); -}; - -// Sort by account (lowest first) -const sortByAccount = (a: AccountBalance, b: AccountBalance): number => a.index - b.index; - -// Accumulates totals per asset across accounts -export const groupByAsset = (balances: AssetBalance[], curr: AssetBalance): AssetBalance[] => { - const match = balances.find(b => b.assetId.equals(curr.assetId)); - if (match) { - match.amount = addAmounts(match.amount, curr.amount); - } else { - balances.push({ ...curr }); - } - return balances; -}; - -interface BalancesProps { - accountFilter?: AddressIndex; - assetIdFilter?: AssetId; -} - -export const getBalances = ({ accountFilter, assetIdFilter }: BalancesProps = {}) => { - const req = new BalancesRequest(); - if (accountFilter) req.accountFilter = accountFilter; - if (assetIdFilter) req.assetIdFilter = assetIdFilter; - - const iterable = viewClient.balances(req); - return streamToPromise(iterable); -}; - -const getBalancesWithMetadata = async (): Promise => { - const balances = await getBalances(); - const accounts = [...new Set(balances.map(b => b.account?.account))]; - const accountAddrs = await getAddresses(accounts); - const assets = await getAllAssets(); - return balances.map(normalize(assets, accountAddrs)); -}; - -// TODO: When simulation endpoint is supported, add pricing data here -export const getBalancesByAccount = async (): Promise => { - const balances = await getBalancesWithMetadata(); - const grouped = balances.reduce(groupByAccount, []); - grouped.sort(sortByAccount); - return grouped; -}; - -export const getBalancesByAccountIndex = async (accountIndex?: number): Promise => { - const balances = await getBalancesByAccount(); - return balances - .filter(a => !accountIndex || a.index === accountIndex) - .flatMap(a => a.balances) - .reduce(groupByAsset, []); -}; diff --git a/apps/webapp/src/fetchers/balances/by-account.ts b/apps/webapp/src/fetchers/balances/by-account.ts new file mode 100644 index 0000000000..c4f964f8df --- /dev/null +++ b/apps/webapp/src/fetchers/balances/by-account.ts @@ -0,0 +1,40 @@ +import { + Address, + AddressIndex, +} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1alpha1/keys_pb'; +import { AssetBalance, getAssetBalances } from './index.ts'; + +export interface AccountGroupedBalances { + index: AddressIndex; + address: Address; + balances: AssetBalance[]; +} + +const groupByAccount = ( + acc: AccountGroupedBalances[], + curr: AssetBalance, +): AccountGroupedBalances[] => { + if (curr.address.addressView.case !== 'decoded') throw new Error('address is not decoded'); + if (!curr.address.addressView.value.address) throw new Error('no address in address view'); + if (!curr.address.addressView.value.index) throw new Error('no index in address view'); + + const index = curr.address.addressView.value.index; + const grouping = acc.find(a => a.index.equals(index)); + + if (grouping) { + grouping.balances.push(curr); + } else { + acc.push({ + index, + address: curr.address.addressView.value.address, + balances: [curr], + }); + } + + return acc; +}; + +export const getBalancesByAccount = async (): Promise => { + const balances = await getAssetBalances(); + return balances.reduce(groupByAccount, []); +}; diff --git a/apps/webapp/src/fetchers/balances/by-asset.ts b/apps/webapp/src/fetchers/balances/by-asset.ts new file mode 100644 index 0000000000..44e230a62d --- /dev/null +++ b/apps/webapp/src/fetchers/balances/by-asset.ts @@ -0,0 +1,48 @@ +import { AssetBalance } from './index.ts'; +import { + AssetId, + ValueView, +} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; +import { addAmounts } from '@penumbra-zone/types'; + +const getAssetId = (v: ValueView): AssetId => { + if (v.valueView.case === 'knownAssetId') { + const assetId = v.valueView.value.metadata?.penumbraAssetId; + if (!assetId) throw new Error('No asset id in value view'); + return assetId; + } + + if (v.valueView.case === 'unknownAssetId') { + const assetId = v.valueView.value.assetId; + if (!assetId) throw new Error('No asset id in value view'); + return assetId; + } + + throw new Error('unrecognized value view case'); +}; + +const hasMatchingAssetId = (vA: ValueView, vB: ValueView) => { + return getAssetId(vA).equals(getAssetId(vB)); +}; + +// Use for doing a .reduce() on AssetBalance[] +export const groupByAsset = (acc: ValueView[], curr: AssetBalance): ValueView[] => { + if (!curr.value.valueView.value?.amount) throw new Error('No amount in value view'); + + const grouping = acc.find(v => hasMatchingAssetId(v, curr.value)); + + if (grouping) { + // Combine the amounts + if (!grouping.valueView.value?.amount) throw new Error('Grouping without amount'); + grouping.valueView.value.amount = addAmounts( + grouping.valueView.value.amount, + curr.value.valueView.value.amount, + ); + } else { + // Add a new entry to the array + // clone so we don't mutate the original + acc.push(curr.value.clone()); + } + + return acc; +}; diff --git a/apps/webapp/src/fetchers/balances/index.ts b/apps/webapp/src/fetchers/balances/index.ts new file mode 100644 index 0000000000..4bc768369d --- /dev/null +++ b/apps/webapp/src/fetchers/balances/index.ts @@ -0,0 +1,98 @@ +import { + BalancesRequest, + BalancesResponse, +} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/view/v1alpha1/view_pb'; +import { + AssetId, + Value, + ValueView, +} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; +import { getAddressByIndex } from '../address.ts'; +import { + AddressIndex, + AddressView, +} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1alpha1/keys_pb'; +import { viewClient } from '../../clients/grpc.ts'; +import { streamToPromise } from '../stream.ts'; + +export interface AssetBalance { + value: ValueView; + address: AddressView; + usdcValue: number; +} + +interface BalancesProps { + accountFilter?: AddressIndex; + assetIdFilter?: AssetId; +} + +const getBalances = ({ accountFilter, assetIdFilter }: BalancesProps = {}) => { + const req = new BalancesRequest(); + if (accountFilter) req.accountFilter = accountFilter; + if (assetIdFilter) req.assetIdFilter = assetIdFilter; + + const iterable = viewClient.balances(req); + return streamToPromise(iterable); +}; + +export const getAssetBalances = async (): Promise => { + const balances = await getBalances(); + const balancePromises = balances.map(constructAssetBalanceWithMetadata); + return Promise.all(balancePromises); +}; + +const constructAssetBalanceWithMetadata = async ({ + balance, + account, +}: BalancesResponse): Promise => { + if (!balance) throw new Error('No balance in response'); + if (!account) throw new Error('No account in response'); + + const value = await getValueView(balance); + const address = await getAddressView(account); + const usdcValue = await calculateUsdcValue(balance); + + return { value, address, usdcValue }; +}; + +const getValueView = async (balance: Value): Promise => { + if (!balance.assetId) throw new Error('no asset id in balance'); + if (!balance.amount) throw new Error('no amount in balance'); + + const { denomMetadata } = await viewClient.assetMetadataById({ assetId: balance.assetId }); + + if (!denomMetadata) { + return new ValueView({ + valueView: { case: 'unknownAssetId', value: balance }, + }); + } else { + return new ValueView({ + valueView: { + case: 'knownAssetId', + value: { + amount: balance.amount, + metadata: denomMetadata, + }, + }, + }); + } +}; + +// @ts-expect-error TODO: implement actual pricing +// eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/require-await +const calculateUsdcValue = async (balance: Value): Promise => { + return 0; +}; + +const getAddressView = async (index: AddressIndex): Promise => { + const address = await getAddressByIndex(index.account); + return new AddressView({ + addressView: { + case: 'decoded', + value: { + address, + index, + }, + }, + }); +}; diff --git a/apps/webapp/src/state/ibc.test.ts b/apps/webapp/src/state/ibc.test.ts index 9f920e9905..96520153b1 100644 --- a/apps/webapp/src/state/ibc.test.ts +++ b/apps/webapp/src/state/ibc.test.ts @@ -1,32 +1,48 @@ import { beforeEach, describe, expect, test } from 'vitest'; import { create, StoreApi, UseBoundStore } from 'zustand'; import { AllSlices, initializeStore } from './index.ts'; -import { Chain } from '@penumbra-zone/types'; +import { bech32ToUint8Array, Chain } from '@penumbra-zone/types'; import { - AssetId, Metadata, + ValueView, } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; import { Amount } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/num/v1alpha1/num_pb'; import { sendValidationErrors } from './send.ts'; -import { Selection } from './types.ts'; +import { AssetBalance } from '../fetchers/balances'; +import { AddressView } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1alpha1/keys_pb'; +import { produce } from 'immer'; // TODO: Revisit tests when re-implementing ibc form describe.skip('IBC Slice', () => { const selectionExample = { - asset: { - amount: new Amount({ - lo: 0n, - hi: 0n, - }), - metadata: new Metadata({ display: 'test_usd', denomUnits: [{ exponent: 18 }] }), - usdcValue: 0, - assetId: new AssetId().fromJson({ inner: 'reum7wQmk/owgvGMWMZn/6RFPV24zIKq3W6In/WwZgg=' }), - }, - address: - 'penumbra1e8k5c3ds484dxvapeamwveh5khqv4jsvyvaf5wwxaaccgfghm229qw03pcar3ryy8smptevstycch0qk3uurrgkvtjpny3cu3rjd0agawqtlz6erev28a6sg69u7cxy0t02nd1', - accountIndex: 0, - } satisfies Selection; + value: new ValueView({ + valueView: { + case: 'knownAssetId', + value: { + amount: new Amount({ + lo: 0n, + hi: 0n, + }), + metadata: new Metadata({ display: 'test_usd', denomUnits: [{ exponent: 18 }] }), + }, + }, + }), + address: new AddressView({ + addressView: { + case: 'opaque', + value: { + address: { + inner: bech32ToUint8Array( + 'penumbra1e8k5cyds484dxvapeamwveh5khqv4jsvyvaf5wwxaaccgfghm229qw03pcar3ryy8smptevstycch0qk3uu0rgkvtjpxy3cu3rjd0agawqtlz6erev28a6sg69u7cxy0t02nd4', + ), + }, + }, + }, + }), + usdcValue: 0, + } satisfies AssetBalance; + let useStore: UseBoundStore>; beforeEach(() => { @@ -47,26 +63,26 @@ describe.skip('IBC Slice', () => { test('validate high enough amount validates', () => { const assetBalance = new Amount({ hi: 1n }); - useStore.getState().send.setSelection({ - ...selectionExample, - asset: { ...selectionExample.asset, amount: assetBalance }, + const state = produce(selectionExample, draft => { + draft.value.valueView.value!.amount = assetBalance; }); + useStore.getState().send.setSelection(state); useStore.getState().send.setAmount('1'); const { selection, amount } = useStore.getState().send; - const { amountErr } = sendValidationErrors(selection?.asset, amount, 'xyz'); + const { amountErr } = sendValidationErrors(selection, amount, 'xyz'); expect(amountErr).toBeFalsy(); }); test('validate error when too low the balance of the asset', () => { const assetBalance = new Amount({ lo: 2n }); - useStore.getState().send.setSelection({ - ...selectionExample, - asset: { ...selectionExample.asset, amount: assetBalance }, + const state = produce(selectionExample, draft => { + draft.value.valueView.value!.amount = assetBalance; }); + useStore.getState().send.setSelection(state); useStore.getState().send.setAmount('6'); const { selection, amount } = useStore.getState().send; - const { amountErr } = sendValidationErrors(selection?.asset, amount, 'xyz'); + const { amountErr } = sendValidationErrors(selection, amount, 'xyz'); expect(amountErr).toBeTruthy(); }); }); diff --git a/apps/webapp/src/state/ibc.ts b/apps/webapp/src/state/ibc.ts index 15277c9d42..89d1ba6f5e 100644 --- a/apps/webapp/src/state/ibc.ts +++ b/apps/webapp/src/state/ibc.ts @@ -1,4 +1,4 @@ -import { Chain, toBaseUnit } from '@penumbra-zone/types'; +import { Chain, getDisplayDenomExponent, toBaseUnit } from '@penumbra-zone/types'; import { AllSlices, SliceCreator } from '.'; import { toast } from '@penumbra-zone/ui/components/ui/use-toast'; import { TransactionPlannerRequest } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/view/v1alpha1/view_pb'; @@ -7,15 +7,13 @@ import BigNumber from 'bignumber.js'; import { typeRegistry } from '@penumbra-zone/types/src/registry'; import { ClientState } from '@buf/cosmos_ibc.bufbuild_es/ibc/lightclients/tendermint/v1/tendermint_pb'; import { Height } from '@buf/cosmos_ibc.bufbuild_es/ibc/core/client/v1/client_pb'; -import { AddressIndex } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1alpha1/keys_pb'; -import { Selection } from './types'; import { ibcClient, viewClient } from '../clients/grpc'; import { planWitnessBuildBroadcast } from './helpers'; -import { getDisplayDenomExponent } from '@penumbra-zone/types/src/denom-metadata'; +import { AssetBalance } from '../fetchers/balances'; export interface IbcSendSlice { - selection: Selection | undefined; - setSelection: (selection: Selection) => void; + selection: AssetBalance | undefined; + setSelection: (selection: AssetBalance) => void; amount: string; setAmount: (amount: string) => void; chain: Chain | undefined; @@ -117,9 +115,11 @@ const getPlanRequest = async ({ }: IbcSendSlice): Promise => { if (!destinationChainAddress) throw new Error('no destination chain address set'); if (!chain?.ibcChannel) throw new Error('Chain ibc channel not available'); - - if (typeof selection?.accountIndex === 'undefined') throw new Error('no selected account'); - if (!selection.asset) throw new Error('no selected asset'); + if (selection?.value.valueView.case !== 'knownAssetId') throw new Error('unknown denom selected'); + if (!selection.value.valueView.value.metadata) throw new Error('no metadata in valueView'); + if (selection.address.addressView.case !== 'decoded') + throw new Error('address in view is not decoded'); + if (!selection.address.addressView.value.index) throw new Error('no index in addressView'); // TODO: implement source address in future, should correspond with asset selector? // TODO: change planner to fill this in automatically ? @@ -131,8 +131,11 @@ const getPlanRequest = async ({ return new TransactionPlannerRequest({ ics20Withdrawals: [ { - amount: toBaseUnit(BigNumber(amount), getDisplayDenomExponent(selection.asset.metadata)), - denom: { denom: selection.asset.metadata.display }, + amount: toBaseUnit( + BigNumber(amount), + getDisplayDenomExponent(selection.value.valueView.value.metadata), + ), + denom: { denom: selection.value.valueView.value.metadata.base }, destinationChainAddress, returnAddress, timeoutHeight, @@ -140,7 +143,7 @@ const getPlanRequest = async ({ sourceChannel: chain.ibcChannel, }, ], - source: new AddressIndex({ account: selection.accountIndex }), + source: selection.address.addressView.value.index, }); }; diff --git a/apps/webapp/src/state/send.test.ts b/apps/webapp/src/state/send.test.ts index 5c16f0d426..cb5e51e9c8 100644 --- a/apps/webapp/src/state/send.test.ts +++ b/apps/webapp/src/state/send.test.ts @@ -3,17 +3,20 @@ import { create, StoreApi, UseBoundStore } from 'zustand'; import { AllSlices, initializeStore } from './index.ts'; import { Amount } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/num/v1alpha1/num_pb'; import { sendValidationErrors } from './send.ts'; +import { AssetBalance } from '../fetchers/balances'; +import { AddressView } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1alpha1/keys_pb'; +import { bech32ToUint8Array, stringToUint8Array } from '@penumbra-zone/types'; import { - AssetId, Metadata, + ValueView, } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; -import { Fee } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/component/fee/v1alpha1/fee_pb'; +import { produce } from 'immer'; import { viewClient } from '../clients/grpc.ts'; import { AddressByIndexResponse, TransactionPlannerResponse, } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/view/v1alpha1/view_pb'; -import { Selection } from './types.ts'; +import { Fee } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/component/fee/v1alpha1/fee_pb'; vi.mock('../fetchers/address', () => ({ getAddressByIndex: vi.fn(), @@ -21,19 +24,37 @@ vi.mock('../fetchers/address', () => ({ describe('Send Slice', () => { const selectionExample = { - asset: { - amount: new Amount({ - lo: 0n, - hi: 0n, - }), - metadata: new Metadata({ display: 'test_usd', denomUnits: [{ exponent: 18 }] }), - usdcValue: 0, - assetId: new AssetId().fromJson({ inner: 'reum7wQmk/owgvGMWMZn/6RFPV24zIKq3W6In/WwZgg=' }), - }, - address: - 'penumbra1e8k5c3ds484dxvapeamwveh5khqv4jsvyvaf5wwxaaccgfghm229qw03pcar3ryy8smptevstycch0qk3uurrgkvtjpny3cu3rjd0agawqtlz6erev28a6sg69u7cxy0t02nd1', - accountIndex: 0, - } satisfies Selection; + value: new ValueView({ + valueView: { + case: 'knownAssetId', + value: { + amount: new Amount({ + lo: 0n, + hi: 0n, + }), + metadata: new Metadata({ + display: 'test_usd', + denomUnits: [{ exponent: 18 }], + penumbraAssetId: { inner: stringToUint8Array('passet1239049023') }, + }), + }, + }, + }), + address: new AddressView({ + addressView: { + case: 'decoded', + value: { + address: { + inner: bech32ToUint8Array( + 'penumbra1e8k5cyds484dxvapeamwveh5khqv4jsvyvaf5wwxaaccgfghm229qw03pcar3ryy8smptevstycch0qk3uu0rgkvtjpxy3cu3rjd0agawqtlz6erev28a6sg69u7cxy0t02nd4', + ), + }, + index: { account: 12 }, + }, + }, + }), + usdcValue: 0, + } satisfies AssetBalance; let useStore: UseBoundStore>; @@ -52,7 +73,7 @@ describe('Send Slice', () => { expect(txInProgress).toBeFalsy(); const { amountErr, recipientErr } = sendValidationErrors( - selectionExample.asset, + selectionExample, amount, recipient, memo, @@ -69,26 +90,26 @@ describe('Send Slice', () => { test('validate high enough amount validates', () => { const assetBalance = new Amount({ hi: 1n }); - useStore.getState().send.setSelection({ - ...selectionExample, - asset: { ...selectionExample.asset, amount: assetBalance }, + const state = produce(selectionExample, draft => { + draft.value.valueView.value!.amount = assetBalance; }); - useStore.getState().send.setAmount('1'); + useStore.getState().send.setSelection(state); + useStore.getState().send.setAmount('1000'); const { selection, amount } = useStore.getState().send; - const { amountErr } = sendValidationErrors(selection?.asset, amount, 'xyz', 'a memo'); + const { amountErr } = sendValidationErrors(selection, amount, 'xyz', 'a memo'); expect(amountErr).toBeFalsy(); }); test('validate error when too low the balance of the asset', () => { const assetBalance = new Amount({ lo: 2n }); - useStore.getState().send.setSelection({ - ...selectionExample, - asset: { ...selectionExample.asset, amount: assetBalance }, + const state = produce(selectionExample, draft => { + draft.value.valueView.value!.amount = assetBalance; }); + useStore.getState().send.setSelection(state); useStore.getState().send.setAmount('6'); const { selection, amount } = useStore.getState().send; - const { amountErr } = sendValidationErrors(selection?.asset, amount, 'xyz', 'a memo'); + const { amountErr } = sendValidationErrors(selection, amount, 'xyz', 'a memo'); expect(amountErr).toBeTruthy(); }); }); @@ -109,7 +130,7 @@ describe('Send Slice', () => { useStore.getState().send.setRecipient(rightAddress); expect(useStore.getState().send.recipient).toBe(rightAddress); const { selection, amount, recipient, memo } = useStore.getState().send; - const { recipientErr } = sendValidationErrors(selection?.asset, amount, recipient, memo); + const { recipientErr } = sendValidationErrors(selection, amount, recipient, memo); expect(recipientErr).toBeFalsy(); }); @@ -120,7 +141,7 @@ describe('Send Slice', () => { useStore.getState().send.setSelection(selectionExample); useStore.getState().send.setRecipient(badAddressLength); const { selection, amount, recipient, memo } = useStore.getState().send; - const { recipientErr } = sendValidationErrors(selection?.asset, amount, recipient, memo); + const { recipientErr } = sendValidationErrors(selection, amount, recipient, memo); expect(recipientErr).toBeTruthy(); }); @@ -131,14 +152,14 @@ describe('Send Slice', () => { useStore.getState().send.setSelection(selectionExample); useStore.getState().send.setRecipient(badAddressPrefix); const { selection, amount, recipient, memo } = useStore.getState().send; - const { recipientErr } = sendValidationErrors(selection?.asset, amount, recipient, memo); + const { recipientErr } = sendValidationErrors(selection, amount, recipient, memo); expect(recipientErr).toBeTruthy(); }); test('recipient will have a validation error after entering a very long memo', () => { useStore.getState().send.setMemo('b'.repeat(512)); const { selection, amount, recipient, memo } = useStore.getState().send; - const { memoErr } = sendValidationErrors(selection?.asset, amount, recipient, memo); + const { memoErr } = sendValidationErrors(selection, amount, recipient, memo); expect(memoErr).toBeTruthy(); }); }); diff --git a/apps/webapp/src/state/send.ts b/apps/webapp/src/state/send.ts index 15fe8daa8e..31275e6dc4 100644 --- a/apps/webapp/src/state/send.ts +++ b/apps/webapp/src/state/send.ts @@ -1,24 +1,32 @@ import { AllSlices, SliceCreator } from './index'; -import { fromBaseUnitAmountAndMetadata, isPenumbraAddr, toBaseUnit } from '@penumbra-zone/types'; +import { + address, + addressIndex, + assetId, + denomMetadata, + fromValueView, + getDisplayDenomExponent, + isPenumbraAddr, + toBaseUnit, +} from '@penumbra-zone/types'; import { TransactionPlannerRequest } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/view/v1alpha1/view_pb'; import { toast } from '@penumbra-zone/ui/components/ui/use-toast'; import BigNumber from 'bignumber.js'; import { errorTxToast, loadingTxToast, successTxToast } from '../components/shared/toast-content'; import { AssetBalance } from '../fetchers/balances'; -import { AddressIndex } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1alpha1/keys_pb'; -import { Selection } from './types'; import { MemoPlaintext } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/transaction/v1alpha1/transaction_pb'; -import { getAddressByIndex } from '../fetchers/address'; -import { getTransactionPlan, planWitnessBuildBroadcast } from './helpers.ts'; -import { getDisplayDenomExponent } from '@penumbra-zone/types/src/denom-metadata.ts'; +import { getTransactionPlan, planWitnessBuildBroadcast } from './helpers'; + import { Fee, FeeTier_Tier, } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/component/fee/v1alpha1/fee_pb'; +import { z } from 'zod'; +import { Metadata } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; export interface SendSlice { - selection: Selection | undefined; - setSelection: (selection: Selection) => void; + selection: AssetBalance | undefined; + setSelection: (selection: AssetBalance) => void; amount: string; setAmount: (amount: string) => void; recipient: string; @@ -72,7 +80,7 @@ export const createSendSlice = (): SliceCreator => (set, get) => { return; } - const txnPlanReq = await assembleRequest(get().send); + const txnPlanReq = assembleRequest(get().send); const plan = await getTransactionPlan(txnPlanReq); const fee = plan?.transactionParameters?.fee; if (!fee?.amount) return; @@ -94,7 +102,7 @@ export const createSendSlice = (): SliceCreator => (set, get) => { const { dismiss } = toastFn(loadingTxToast); try { - const req = await assembleRequest(get().send); + const req = assembleRequest(get().send); const txHash = await planWitnessBuildBroadcast(req); dismiss(); toastFn(successTxToast(txHash)); @@ -116,21 +124,46 @@ export const createSendSlice = (): SliceCreator => (set, get) => { }; }; -const assembleRequest = async ({ amount, feeTier, recipient, selection, memo }: SendSlice) => { - if (typeof selection?.accountIndex === 'undefined') throw new Error('no selected account'); - if (!selection.asset) throw new Error('no selected asset'); +export const selectionSchema = z.object({ + value: z.object({ + valueView: z.object({ + case: z.literal('knownAssetId'), + value: z.object({ + metadata: denomMetadata.extend({ penumbraAssetId: assetId }).required(), + }), + }), + }), + + address: z.object({ + addressView: z.object({ + case: z.literal('decoded'), + value: z.object({ + address, + index: addressIndex, + }), + }), + }), +}); + +const assembleRequest = ({ amount, feeTier, recipient, selection, memo }: SendSlice) => { + const validatedSelection = selectionSchema.parse(selection); return new TransactionPlannerRequest({ outputs: [ { address: { altBech32m: recipient }, value: { - amount: toBaseUnit(BigNumber(amount), getDisplayDenomExponent(selection.asset.metadata)), - assetId: { inner: selection.asset.assetId.inner }, + amount: toBaseUnit( + BigNumber(amount), + getDisplayDenomExponent( + new Metadata(validatedSelection.value.valueView.value.metadata), + ), + ), + assetId: validatedSelection.value.valueView.value.metadata.penumbraAssetId, }, }, ], - source: new AddressIndex({ account: selection.accountIndex }), + source: validatedSelection.address.addressView.value.index, // Note: we currently don't provide a UI for setting the fee manually. Thus, // a `feeMode` of `manualFee` is not supported here. @@ -143,7 +176,7 @@ const assembleRequest = async ({ amount, feeTier, recipient, selection, memo }: }, memo: new MemoPlaintext({ - returnAddress: await getAddressByIndex(selection.accountIndex), + returnAddress: validatedSelection.address.addressView.value.address, text: memo, }), }); @@ -157,7 +190,9 @@ const validateAmount = ( */ amountInDisplayDenom: string, ): boolean => { - const balanceAmt = fromBaseUnitAmountAndMetadata(asset.amount, asset.metadata); + if (asset.value.valueView.case !== 'knownAssetId') throw new Error('unknown asset selected'); + + const balanceAmt = fromValueView(asset.value.valueView.value); return Boolean(amountInDisplayDenom) && BigNumber(amountInDisplayDenom).gt(balanceAmt); }; diff --git a/apps/webapp/src/state/swap.test.ts b/apps/webapp/src/state/swap.test.ts index 48ee879829..45fb9eac03 100644 --- a/apps/webapp/src/state/swap.test.ts +++ b/apps/webapp/src/state/swap.test.ts @@ -3,30 +3,42 @@ import { AllSlices, initializeStore } from './index'; import { beforeEach, describe, expect, test } from 'vitest'; import { AssetBalance } from '../fetchers/balances'; import { - AssetId, Metadata, + ValueView, } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; import { Amount } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/num/v1alpha1/num_pb'; -import { stringToUint8Array } from '@penumbra-zone/types'; -import { Selection } from './types'; +import { bech32ToUint8Array } from '@penumbra-zone/types'; import { localAssets } from '@penumbra-zone/constants'; +import { AddressView } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1alpha1/keys_pb'; describe('Swap Slice', () => { - const assetBalance: AssetBalance = { - metadata: new Metadata({ - display: 'xyz', - denomUnits: [{ denom: 'xyz', exponent: 3 }], + const selectionExample = { + value: new ValueView({ + valueView: { + case: 'knownAssetId', + value: { + amount: new Amount({ + lo: 0n, + hi: 0n, + }), + metadata: new Metadata({ display: 'test_usd', denomUnits: [{ exponent: 18 }] }), + }, + }, }), - assetId: new AssetId({ inner: stringToUint8Array('abcdefg') }), - amount: new Amount(), - usdcValue: 1234, - }; - - const selection: Selection = { - address: 'address123', - accountIndex: 4, - asset: assetBalance, - }; + address: new AddressView({ + addressView: { + case: 'opaque', + value: { + address: { + inner: bech32ToUint8Array( + 'penumbra1e8k5cyds484dxvapeamwveh5khqv4jsvyvaf5wwxaaccgfghm229qw03pcar3ryy8smptevstycch0qk3uu0rgkvtjpxy3cu3rjd0agawqtlz6erev28a6sg69u7cxy0t02nd4', + ), + }, + }, + }, + }), + usdcValue: 0, + } satisfies AssetBalance; let useStore: UseBoundStore>; @@ -43,8 +55,8 @@ describe('Swap Slice', () => { test('assetIn can be set', () => { expect(useStore.getState().swap.assetIn).toBeUndefined(); - useStore.getState().swap.setAssetIn(selection); - expect(useStore.getState().swap.assetIn).toBe(selection); + useStore.getState().swap.setAssetIn(selectionExample); + expect(useStore.getState().swap.assetIn).toBe(selectionExample); }); test('assetOut can be set', () => { diff --git a/apps/webapp/src/state/swap.ts b/apps/webapp/src/state/swap.ts index 0666280a83..1312720ff4 100644 --- a/apps/webapp/src/state/swap.ts +++ b/apps/webapp/src/state/swap.ts @@ -1,19 +1,17 @@ import { AllSlices, SliceCreator } from './index'; -import { Selection } from './types'; import { errorTxToast, loadingTxToast, successTxToast } from '../components/shared/toast-content'; -import { toBaseUnit } from '@penumbra-zone/types'; import { toast } from '@penumbra-zone/ui/components/ui/use-toast'; import { TransactionPlannerRequest } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/view/v1alpha1/view_pb'; -import { AddressIndex } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1alpha1/keys_pb'; -import { getAddressByIndex } from '../fetchers/address'; -import BigNumber from 'bignumber.js'; import { planWitnessBuildBroadcast } from './helpers'; import { Metadata } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; -import { getDisplayDenomExponent } from '@penumbra-zone/types/src/denom-metadata'; +import { AssetBalance } from '../fetchers/balances'; +import { getDisplayDenomExponent, toBaseUnit } from '@penumbra-zone/types'; +import BigNumber from 'bignumber.js'; +import { getAddressByIndex } from '../fetchers/address'; export interface SwapSlice { - assetIn: Selection | undefined; - setAssetIn: (selection: Selection) => void; + assetIn: AssetBalance | undefined; + setAssetIn: (asset: AssetBalance) => void; amount: string; setAmount: (amount: string) => void; assetOut: Metadata | undefined; @@ -74,28 +72,39 @@ export const createSwapSlice = (): SliceCreator => (set, get) => { }; const assembleRequest = async ({ assetIn, amount, assetOut }: SwapSlice) => { - if (assetIn?.accountIndex === undefined || !assetIn.asset || !assetOut?.penumbraAssetId) - throw new Error('missing selected tokens'); + if (assetIn?.value.valueView.case !== 'knownAssetId') throw new Error('unknown denom selected'); + if (!assetIn.value.valueView.value.metadata?.penumbraAssetId) + throw new Error('missing metadata for assetIn'); + if (assetIn.address.addressView.case !== 'decoded') + throw new Error('address in view is not decoded'); + if (!assetIn.address.addressView.value.index) throw new Error('No index for assetIn address'); + if (assetOut?.penumbraAssetId === undefined) throw new Error('assetOut has no asset id'); return new TransactionPlannerRequest({ swaps: [ { targetAsset: assetOut.penumbraAssetId, value: { - amount: toBaseUnit(BigNumber(amount), getDisplayDenomExponent(assetIn.asset.metadata)), - assetId: assetIn.asset.assetId, + amount: toBaseUnit( + BigNumber(amount), + getDisplayDenomExponent(assetIn.value.valueView.value.metadata), + ), + assetId: assetIn.value.valueView.value.metadata.penumbraAssetId, }, - claimAddress: await getAddressByIndex(assetIn.accountIndex), + claimAddress: await getAddressByIndex(assetIn.address.addressView.value.index.account), // TODO: Calculate this properly in subsequent PR // Asset Id should almost certainly be upenumbra, // may need to indicate native denom in registry fee: { - amount: toBaseUnit(BigNumber(amount), getDisplayDenomExponent(assetIn.asset.metadata)), - assetId: assetIn.asset.assetId, + amount: toBaseUnit( + BigNumber(amount), + getDisplayDenomExponent(assetIn.value.valueView.value.metadata), + ), + assetId: assetIn.value.valueView.value.metadata.penumbraAssetId, }, }, ], - source: new AddressIndex({ account: assetIn.accountIndex }), + source: assetIn.address.addressView.value.index, }); }; diff --git a/apps/webapp/src/state/types.ts b/apps/webapp/src/state/types.ts deleted file mode 100644 index c830430e9c..0000000000 --- a/apps/webapp/src/state/types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { AssetBalance } from '../fetchers/balances'; - -export interface Selection { - address: string | undefined; - accountIndex: number | undefined; - asset: AssetBalance | undefined; -} diff --git a/package.json b/package.json index a6de5a3a4a..e583407c2f 100644 --- a/package.json +++ b/package.json @@ -11,13 +11,13 @@ "clean": "turbo clean", "format": "prettier --write .", "format-check": "prettier --check .", - "all-check": "pnpm install && pnpm format && pnpm format-check && pnpm lint && pnpm test && pnpm build" + "all-check": "pnpm install && pnpm format-check && pnpm lint && pnpm test && pnpm build" }, "dependencies": { "@buf/cosmos_ibc.bufbuild_es": "1.7.2-20240123184419-30c7be3837b0.1", "@buf/cosmos_ibc.connectrpc_es": "1.3.0-20240123184419-30c7be3837b0.1", - "@buf/penumbra-zone_penumbra.bufbuild_es": "1.7.2-20240203052248-18996dcd17a4.1", - "@buf/penumbra-zone_penumbra.connectrpc_es": "1.3.0-20240203052248-18996dcd17a4.1", + "@buf/penumbra-zone_penumbra.bufbuild_es": "1.7.2-20240206003852-3cc57ebd3e94.1", + "@buf/penumbra-zone_penumbra.connectrpc_es": "1.3.0-20240206003852-3cc57ebd3e94.1", "@bufbuild/protobuf": "^1.7.2", "@connectrpc/connect": "^1.3.0", "@connectrpc/connect-web": "^1.3.0", @@ -27,8 +27,8 @@ "@penumbra-zone/types": "workspace:*", "@penumbra-zone/wasm-nodejs": "0.65.0-alpha.1c", "@turbo/gen": "^1.12.2", - "@typescript-eslint/eslint-plugin": "^6.20.0", - "@typescript-eslint/parser": "^6.20.0", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", "eslint": "^8.56.0", "eslint-config-custom": "workspace:*", "playwright": "^1.41.2", diff --git a/packages/eslint-config-custom/package.json b/packages/eslint-config-custom/package.json index 469bf51f70..080c298a05 100644 --- a/packages/eslint-config-custom/package.json +++ b/packages/eslint-config-custom/package.json @@ -4,15 +4,15 @@ "main": "index.js", "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "^6.20.0", - "@typescript-eslint/parser": "^6.20.0", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", "eslint-config-next": "^14.1.0", "eslint-config-prettier": "^9.1.0", "eslint-config-turbo": "^1.12.2", "eslint-plugin-react": "7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.5", - "eslint-plugin-tailwindcss": "^3.14.1", + "eslint-plugin-tailwindcss": "^3.14.2", "eslint-plugin-turbo": "^1.12.2", "eslint-plugin-vitest": "^0.3.21" }, diff --git a/packages/router/src/grpc/view-protocol-server/asset-metadata-by-id.ts b/packages/router/src/grpc/view-protocol-server/asset-metadata-by-id.ts new file mode 100644 index 0000000000..c152b72ecd --- /dev/null +++ b/packages/router/src/grpc/view-protocol-server/asset-metadata-by-id.ts @@ -0,0 +1,13 @@ +import type { Impl } from '.'; +import { servicesCtx } from '../../ctx'; +import { getAssetMetadata } from './helpers'; + +export const assetMetadataById: Impl['assetMetadataById'] = async (req, ctx) => { + if (!req.assetId) throw new Error('No asset id passed in request'); + + const services = ctx.values.get(servicesCtx); + const { indexedDb, querier } = await services.getWalletServices(); + const denomMetadata = await getAssetMetadata(req.assetId, indexedDb, querier); + + return { denomMetadata }; +}; diff --git a/packages/router/src/grpc/view-protocol-server/helpers.ts b/packages/router/src/grpc/view-protocol-server/helpers.ts new file mode 100644 index 0000000000..e9b2297f2e --- /dev/null +++ b/packages/router/src/grpc/view-protocol-server/helpers.ts @@ -0,0 +1,19 @@ +import { AssetId } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; +import { IndexedDbInterface, RootQuerierInterface } from '@penumbra-zone/types'; + +export const getAssetMetadata = async ( + targetAsset: AssetId, + indexedDb: IndexedDbInterface, + querier: RootQuerierInterface, +) => { + // First, try to get the metadata from the internal database. + const localMetadata = await indexedDb.getAssetsMetadata(targetAsset); + if (localMetadata) return localMetadata; + + // If not available locally, query the metadata from the node. + const nodeMetadata = await querier.shieldedPool.assetMetadata(targetAsset); + if (nodeMetadata) return nodeMetadata; + + // If the metadata is not found, throw an error with details about the asset. + throw new Error(`No denom metadata found for asset: ${JSON.stringify(targetAsset.toJson())}`); +}; diff --git a/packages/router/src/grpc/view-protocol-server/index.ts b/packages/router/src/grpc/view-protocol-server/index.ts index 0dd31fb78c..d0eab1c002 100644 --- a/packages/router/src/grpc/view-protocol-server/index.ts +++ b/packages/router/src/grpc/view-protocol-server/index.ts @@ -1,11 +1,13 @@ import type { ViewService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumbra/view/v1alpha1/view_connect'; import type { ServiceImpl } from '@connectrpc/connect'; + import { addressByIndex } from './address-by-index'; import { appParameters } from './app-parameters'; import { assets } from './assets'; import { authorizeAndBuild } from './authorize-and-build'; import { balances } from './balances'; import { broadcastTransaction } from './broadcast-transaction'; +import { assetMetadataById } from './asset-metadata-by-id'; import { ephemeralAddress } from './ephemeral-address'; import { fMDParameters } from './fmd-parameters'; import { gasPrices } from './gas-prices'; @@ -28,13 +30,14 @@ import { witnessAndBuild } from './witness-and-build'; export type Impl = ServiceImpl; -export const viewImpl: Omit = { +export const viewImpl: Impl = { addressByIndex, appParameters, assets, authorizeAndBuild, balances, broadcastTransaction, + assetMetadataById, ephemeralAddress, fMDParameters, gasPrices, diff --git a/packages/router/src/grpc/view-protocol-server/transaction-planner.ts b/packages/router/src/grpc/view-protocol-server/transaction-planner.ts index 80ae8b862e..7b5450b5fa 100644 --- a/packages/router/src/grpc/view-protocol-server/transaction-planner.ts +++ b/packages/router/src/grpc/view-protocol-server/transaction-planner.ts @@ -1,32 +1,11 @@ import type { Impl } from '.'; import { servicesCtx } from '../../ctx'; - import { getAddressByIndex, TxPlanner } from '@penumbra-zone/wasm-ts'; - import { AddressIndex } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1alpha1/keys_pb'; - import { Code, ConnectError } from '@connectrpc/connect'; -import { AssetId } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; -import { IndexedDbInterface, RootQuerierInterface } from '@penumbra-zone/types'; import { gasPrices } from './gas-prices'; import { GasPrices } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/component/fee/v1alpha1/fee_pb'; - -async function getAssetMetadata( - indexedDb: IndexedDbInterface, - targetAsset: AssetId, - querier: RootQuerierInterface, -) { - // First, try to get the metadata from the internal database. - const localMetadata = await indexedDb.getAssetsMetadata(targetAsset); - if (localMetadata) return localMetadata; - - // If not available locally, query the metadata from the node. - const nodeMetadata = await querier.shieldedPool.assetMetadata(targetAsset); - if (nodeMetadata) return nodeMetadata; - - // If the metadata is not found, throw an error with details about the asset. - throw new Error(`No denom metadata found for asset: ${JSON.stringify(targetAsset.toJson())}`); -} +import { getAssetMetadata } from './helpers'; export const transactionPlanner: Impl['transactionPlanner'] = async (req, ctx) => { const services = ctx.values.get(servicesCtx); @@ -68,8 +47,8 @@ export const transactionPlanner: Impl['transactionPlanner'] = async (req, ctx) = if (!value || !targetAsset || !fee || !claimAddress) throw new Error('no value, targetAsset, fee or claimAddress in swap'); - const intoDenomMetadata = await getAssetMetadata(indexedDb, targetAsset, querier); - planner.swap(value, intoDenomMetadata, fee, claimAddress); + const intoAssetMetadata = await getAssetMetadata(targetAsset, indexedDb, querier); + planner.swap(value, intoAssetMetadata, fee, claimAddress); } for (const { swapCommitment } of req.swapClaims) { diff --git a/packages/tsconfig/base.json b/packages/tsconfig/base.json index a5c4543606..efe11b0f3b 100644 --- a/packages/tsconfig/base.json +++ b/packages/tsconfig/base.json @@ -16,7 +16,6 @@ "strictNullChecks": true, "allowUnreachableCode": false, "allowUnusedLabels": false, - "exactOptionalPropertyTypes": true, "noFallthroughCasesInSwitch": true, "noImplicitOverride": true, "noImplicitReturns": true, diff --git a/packages/types/src/account.ts b/packages/types/src/account.ts deleted file mode 100644 index deaeb23404..0000000000 --- a/packages/types/src/account.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface Account { - address: string; - index: number; -} diff --git a/packages/types/src/amount.test.ts b/packages/types/src/amount.test.ts index d2853b2498..ef4100ecb4 100644 --- a/packages/types/src/amount.test.ts +++ b/packages/types/src/amount.test.ts @@ -4,11 +4,14 @@ import { displayAmount, displayUsd, fromBaseUnitAmount, - fromBaseUnitAmountAndMetadata, + fromValueView, joinLoHiAmount, } from './amount'; import { Amount } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/num/v1alpha1/num_pb'; -import { Metadata } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; +import { + Metadata, + ValueView_KnownAssetId, +} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; describe('lohi helpers', () => { it('fromBaseUnitAmount works', () => { @@ -41,9 +44,11 @@ describe('lohi helpers', () => { ], }); - const result = fromBaseUnitAmountAndMetadata( - new Amount({ lo: 123456789n, hi: 0n }), - penumbraMetadata, + const result = fromValueView( + new ValueView_KnownAssetId({ + amount: { lo: 123456789n, hi: 0n }, + metadata: penumbraMetadata, + }), ); expect(result.toString()).toBe('123.456789'); diff --git a/packages/types/src/amount.ts b/packages/types/src/amount.ts index b7dcc37ec1..78f45811c4 100644 --- a/packages/types/src/amount.ts +++ b/packages/types/src/amount.ts @@ -1,7 +1,7 @@ import { Amount } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/num/v1alpha1/num_pb'; import { fromBaseUnit, joinLoHi, splitLoHi } from './lo-hi'; import BigNumber from 'bignumber.js'; -import { Metadata } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; +import { ValueView_KnownAssetId } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; import { getDisplayDenomExponent } from './denom-metadata'; export const joinLoHiAmount = (amount: Amount): bigint => { @@ -12,7 +12,10 @@ export const fromBaseUnitAmount = (amount: Amount, exponent = 0): BigNumber => { return fromBaseUnit(amount.lo, amount.hi, exponent); }; -export const fromBaseUnitAmountAndMetadata = (amount: Amount, metadata: Metadata): BigNumber => { +export const fromValueView = ({ amount, metadata }: ValueView_KnownAssetId): BigNumber => { + if (!amount) throw new Error('No amount in value view'); + if (!metadata) throw new Error('No denom in value view'); + return fromBaseUnitAmount(amount, getDisplayDenomExponent(metadata)); }; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index d6dc485816..b79fbacfc2 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -20,5 +20,8 @@ export * from './querier'; export * from './std-route'; export * from './amount'; export * from './chain'; -export * from './account'; +export * from './denom-metadata'; export * from './jsonified'; +export * from './schemas'; +export * from './type-predicates'; +export * from './value-view'; diff --git a/packages/types/src/schemas/address-index.ts b/packages/types/src/schemas/address-index.ts new file mode 100644 index 0000000000..d632898f71 --- /dev/null +++ b/packages/types/src/schemas/address-index.ts @@ -0,0 +1,6 @@ +import { z } from 'zod'; + +export const addressIndex = z.object({ + account: z.number().int(), + randomizer: z.instanceof(Uint8Array), +}); diff --git a/packages/types/src/schemas/address.ts b/packages/types/src/schemas/address.ts new file mode 100644 index 0000000000..8647e9de4a --- /dev/null +++ b/packages/types/src/schemas/address.ts @@ -0,0 +1,6 @@ +import { z } from 'zod'; + +export const address = z.object({ + inner: z.instanceof(Uint8Array), + altBech32m: z.string(), +}); diff --git a/packages/types/src/schemas/asset-id.ts b/packages/types/src/schemas/asset-id.ts new file mode 100644 index 0000000000..d681178319 --- /dev/null +++ b/packages/types/src/schemas/asset-id.ts @@ -0,0 +1,7 @@ +import { z } from 'zod'; + +export const assetId = z.object({ + inner: z.instanceof(Uint8Array), + altBech32m: z.string(), + altBaseDenom: z.string(), +}); diff --git a/packages/types/src/schemas/asset-image--theme.ts b/packages/types/src/schemas/asset-image--theme.ts new file mode 100644 index 0000000000..cf700877b2 --- /dev/null +++ b/packages/types/src/schemas/asset-image--theme.ts @@ -0,0 +1,7 @@ +import { z } from 'zod'; + +export const assetImage_Theme = z.object({ + primaryColorHex: z.string(), + circle: z.boolean(), + darkMode: z.boolean(), +}); diff --git a/packages/types/src/schemas/asset-image.ts b/packages/types/src/schemas/asset-image.ts new file mode 100644 index 0000000000..bb370dd17d --- /dev/null +++ b/packages/types/src/schemas/asset-image.ts @@ -0,0 +1,8 @@ +import { z } from 'zod'; +import { assetImage_Theme } from './asset-image--theme'; + +export const assetImage = z.object({ + png: z.string(), + svg: z.string(), + theme: assetImage_Theme.optional(), +}); diff --git a/packages/types/src/schemas/denom-metadata.ts b/packages/types/src/schemas/denom-metadata.ts new file mode 100644 index 0000000000..be5ab9d165 --- /dev/null +++ b/packages/types/src/schemas/denom-metadata.ts @@ -0,0 +1,15 @@ +import { z } from 'zod'; +import { denomUnit } from './denom-unit'; +import { assetId } from './asset-id'; +import { assetImage } from './asset-image'; + +export const denomMetadata = z.object({ + description: z.string(), + denomUnits: z.array(denomUnit), + base: z.string(), + display: z.string(), + name: z.string(), + symbol: z.string(), + penumbraAssetId: assetId.optional(), + images: z.array(assetImage), +}); diff --git a/packages/types/src/schemas/denom-unit.ts b/packages/types/src/schemas/denom-unit.ts new file mode 100644 index 0000000000..41d3b02d3c --- /dev/null +++ b/packages/types/src/schemas/denom-unit.ts @@ -0,0 +1,7 @@ +import { z } from 'zod'; + +export const denomUnit = z.object({ + denom: z.string(), + exponent: z.number().int(), + aliases: z.array(z.string()), +}); diff --git a/packages/types/src/schemas/index.ts b/packages/types/src/schemas/index.ts new file mode 100644 index 0000000000..a21cbc0fb1 --- /dev/null +++ b/packages/types/src/schemas/index.ts @@ -0,0 +1,7 @@ +export * from './address'; +export * from './address-index'; +export * from './asset-id'; +export * from './asset-image'; +export * from './asset-image--theme'; +export * from './denom-metadata'; +export * from './denom-unit'; diff --git a/packages/types/src/type-predicates/address-view.ts b/packages/types/src/type-predicates/address-view.ts new file mode 100644 index 0000000000..39ae064485 --- /dev/null +++ b/packages/types/src/type-predicates/address-view.ts @@ -0,0 +1,25 @@ +import { address } from '../schemas/address'; +import { isType } from '../validation'; +import { z } from 'zod'; + +export const hasAccountIndex = isType( + z.object({ + addressView: z.object({ + case: z.literal('decoded'), + value: z.object({ + index: z.object({ + account: z.number(), + }), + }), + }), + }), +); + +export const hasAddress = isType( + z.object({ + addressView: z.object({ + case: z.enum(['decoded', 'opaque']), + value: z.object({ address }), + }), + }), +); diff --git a/packages/types/src/type-predicates/index.ts b/packages/types/src/type-predicates/index.ts new file mode 100644 index 0000000000..ffec9bd128 --- /dev/null +++ b/packages/types/src/type-predicates/index.ts @@ -0,0 +1,2 @@ +export * from './address-view'; +export * from './value-view'; diff --git a/packages/types/src/type-predicates/value-view.ts b/packages/types/src/type-predicates/value-view.ts new file mode 100644 index 0000000000..f26cc0d272 --- /dev/null +++ b/packages/types/src/type-predicates/value-view.ts @@ -0,0 +1,14 @@ +import { denomMetadata } from '../schemas/denom-metadata'; +import { isType } from '../validation'; +import { z } from 'zod'; + +export const hasDenomMetadata = isType( + z.object({ + valueView: z.object({ + case: z.literal('knownAssetId'), + value: z.object({ + metadata: denomMetadata, + }), + }), + }), +); diff --git a/packages/types/src/validation.test.ts b/packages/types/src/validation.test.ts index fe7214e183..95a53ac583 100644 --- a/packages/types/src/validation.test.ts +++ b/packages/types/src/validation.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, Mock, vi } from 'vitest'; import { z } from 'zod'; -import { validateSchema } from './validation'; +import { isType, validateSchema } from './validation'; describe('validation', () => { describe('validateSchema()', () => { @@ -98,4 +98,33 @@ describe('validation', () => { expect(mockLogger).toHaveBeenCalledOnce(); }); }); + + describe("isType()'s returned type predicate function", () => { + interface Person { + name: string; + age?: number; + } + + const personWithAgeSchema = z.object({ + name: z.string(), + age: z.number(), + }); + + it('returns `true` if the passed-in value matches the schema', () => { + const matchingPerson: Person = { + name: 'Ada Lovelace', + age: 30, + }; + + expect(isType(personWithAgeSchema)(matchingPerson)).toBe(true); + }); + + it('returns `false` if the passed-in value does not match the schema', () => { + const nonMatchingPerson: Person = { + name: 'Ada Lovelace', + }; + + expect(isType(personWithAgeSchema)(nonMatchingPerson)).toBe(false); + }); + }); }); diff --git a/packages/types/src/validation.ts b/packages/types/src/validation.ts index 8a2055c8c9..ff6e6c471c 100644 --- a/packages/types/src/validation.ts +++ b/packages/types/src/validation.ts @@ -1,4 +1,4 @@ -import { z } from 'zod'; +import { z, ZodTypeAny } from 'zod'; import { isDevEnv } from './environment'; // In production, we do not want to throw validation errors, but log them. @@ -18,3 +18,36 @@ export const validateSchema = (schema: z.ZodSchema, data: unknown): T => { } } }; + +/** + * Returns a type predicate that allows safe property access. + * + * @example + * ```TS + * const visibleAddressViewWithAccountIndexSchema = z.object({ + * addressView: z.object({ + * case: z.literal('visible'), + * value: z.object({ + * index: z.object({ + * account: z.number(), + * }), + * }), + * }), + * }); + * + * const addressView = new AddressView(); + * + * const hasAccountIndex = isType(visibleAddressViewWithAccountIndexSchema); + * + * if (hasAccountIndex(addressView)) { + * // No need for `?`, `!`, or `case === 'visible'`. + * console.log(addressView.addressView.value.index.account); + * } + * ```` + * + * @see https://github.com/colinhacks/zod/issues/2345 + */ +export const isType = + (schema: T) => + (data: unknown): data is z.infer => + schema.safeParse(data).success; diff --git a/packages/types/src/value-view.ts b/packages/types/src/value-view.ts new file mode 100644 index 0000000000..374eeb059c --- /dev/null +++ b/packages/types/src/value-view.ts @@ -0,0 +1,21 @@ +import { ValueView } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; +import { bech32AssetId } from './asset'; + +export const getDisplayDenomFromView = (view: ValueView) => { + if (view.valueView.case === 'unknownAssetId') { + if (!view.valueView.value.assetId) throw new Error('no asset id for unknown denom'); + return bech32AssetId(view.valueView.value.assetId); + } + + if (view.valueView.case === 'knownAssetId') { + const displayDenom = view.valueView.value.metadata?.display; + if (displayDenom) return displayDenom; + + const assetId = view.valueView.value.metadata?.penumbraAssetId; + if (assetId) return bech32AssetId(assetId); + + return 'unknown'; + } + + return 'unknown'; +}; diff --git a/packages/ui/components/ui/address-component.test.tsx b/packages/ui/components/ui/address-component.test.tsx new file mode 100644 index 0000000000..c31fffa834 --- /dev/null +++ b/packages/ui/components/ui/address-component.test.tsx @@ -0,0 +1,29 @@ +import { AddressComponent } from './address-component'; +import { describe, expect, test } from 'vitest'; +import { render } from '@testing-library/react'; +import { bech32ToUint8Array, shortenAddress } from '@penumbra-zone/types'; +import { Address } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1alpha1/keys_pb'; + +describe('', () => { + const address = + 'penumbra1u7dk4qw6fz3vlwyjl88vlj6gqv4hcmz2vesm87t7rm0lvwmgqqkrp3zrdmfg6et86ggv4nwmnc8vy39uxyacwm8g7trk77ad0c8n4qt76ncvuukx6xlj8mskhyjpn4twkpwwl2'; + const pbAddress = new Address({ inner: bech32ToUint8Array(address) }); + + test('renders the shortened address', () => { + const { baseElement } = render(); + + expect(baseElement).toHaveTextContent(shortenAddress(address)); + }); + + test('uses text-muted-foreground for non-ephemeral addresses', () => { + const { getByText } = render(); + + expect(getByText(shortenAddress(address))).toHaveClass('text-muted-foreground'); + }); + + test('uses colored text for ephemeral addresses', () => { + const { getByText } = render(); + + expect(getByText(shortenAddress(address))).toHaveClass('text-[#8D5728]'); + }); +}); diff --git a/packages/ui/components/ui/address-component.tsx b/packages/ui/components/ui/address-component.tsx new file mode 100644 index 0000000000..c3db089edc --- /dev/null +++ b/packages/ui/components/ui/address-component.tsx @@ -0,0 +1,21 @@ +import { bech32Address, shortenAddress } from '@penumbra-zone/types'; +import { Address } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1alpha1/keys_pb'; + +interface AddressComponentProps { + address: Address; + ephemeral?: boolean; +} + +/** + * Displays an address. The address is truncated to the prefix plus 24 + * characters, and rendered in color when it is ephemeral. + */ +export const AddressComponent = ({ address, ephemeral }: AddressComponentProps) => { + const bech32Addr = bech32Address(address); + + return ( + + {shortenAddress(bech32Addr)} + + ); +}; diff --git a/packages/ui/components/ui/address-icon.tsx b/packages/ui/components/ui/address-icon.tsx index e854895e5d..74280e7991 100644 --- a/packages/ui/components/ui/address-icon.tsx +++ b/packages/ui/components/ui/address-icon.tsx @@ -1,8 +1,20 @@ import { Identicon } from './identicon'; +import { Address } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1alpha1/keys_pb'; +import { bech32Address } from '@penumbra-zone/types'; + +interface AddressIconProps { + address: Address; + size: number; +} /** * A simple component to display a consistently styled icon for a given address. */ -export const AddressIcon = ({ address, size }: { address: string; size: number }) => ( - +export const AddressIcon = ({ address, size }: AddressIconProps) => ( + ); diff --git a/packages/ui/components/ui/address.test.tsx b/packages/ui/components/ui/address.test.tsx deleted file mode 100644 index a504f5190c..0000000000 --- a/packages/ui/components/ui/address.test.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { Address } from './address'; -import { describe, expect, test } from 'vitest'; -import { render } from '@testing-library/react'; -import { shortenAddress } from '@penumbra-zone/types'; - -describe('
', () => { - const address = - 'penumbra1nzxd3wqautgr8hmwwvvgwnsgtpnl3rexwyj0srpcyaf75968mq3wseftwzwcsx458la09m3am7x2qlk7jfchuvpv6uvw79ctzpnrt7c2wd6n9j9xgk8regdwkrjple9uh2tekf'; - - test('renders the shortened address', () => { - const { baseElement } = render(
); - - expect(baseElement).toHaveTextContent(shortenAddress(address)); - }); - - test('uses text-muted-foreground for non-ephemeral addresses', () => { - const { getByText } = render(
); - - expect(getByText(shortenAddress(address))).toHaveClass('text-muted-foreground'); - }); - - test('uses colored text for ephemeral addresses', () => { - const { getByText } = render(
); - - expect(getByText(shortenAddress(address))).toHaveClass('text-[#8D5728]'); - }); -}); diff --git a/packages/ui/components/ui/address.tsx b/packages/ui/components/ui/address.tsx index d68a0c3099..e69de29bb2 100644 --- a/packages/ui/components/ui/address.tsx +++ b/packages/ui/components/ui/address.tsx @@ -1,17 +0,0 @@ -import { shortenAddress } from '@penumbra-zone/types'; - -/** - * Displays an address. The address is truncated to the prefix plus 24 - * characters, and rendered in color when it is ephemeral. - */ -export const Address = ({ - address, - ephemeral = false, -}: { - address: string; - ephemeral?: boolean; -}) => ( - - {shortenAddress(address)} - -); diff --git a/packages/ui/components/ui/identicon/index.tsx b/packages/ui/components/ui/identicon/index.tsx index 8c9dd9def7..f93fbe7525 100644 --- a/packages/ui/components/ui/identicon/index.tsx +++ b/packages/ui/components/ui/identicon/index.tsx @@ -7,9 +7,9 @@ export const Identicon = ({ type, ...props }: IdenticonProps & { type: 'gradient return ; }; -const IdenticonGradient = ({ name, size = 120, className }: IdenticonProps) => { - const gradient = useMemo(() => generateGradient(name), [name]); - const gradientId = useMemo(() => `gradient-${name}`, [name]); +const IdenticonGradient = ({ uniqueIdentifier, size = 120, className }: IdenticonProps) => { + const gradient = useMemo(() => generateGradient(uniqueIdentifier), [uniqueIdentifier]); + const gradientId = useMemo(() => `gradient-${uniqueIdentifier}`, [uniqueIdentifier]); return ( { ); }; -const IdenticonSolid = ({ name, size = 120, className }: IdenticonProps) => { - const color = useMemo(() => generateSolidColor(name), [name]); +const IdenticonSolid = ({ uniqueIdentifier, size = 120, className }: IdenticonProps) => { + const color = useMemo(() => generateSolidColor(uniqueIdentifier), [uniqueIdentifier]); return ( { dy='.3em' className='uppercase' > - {name[0]} + {uniqueIdentifier[0]} ); diff --git a/packages/ui/components/ui/identicon/types.ts b/packages/ui/components/ui/identicon/types.ts index 6962c6ff74..248ecd8c2b 100644 --- a/packages/ui/components/ui/identicon/types.ts +++ b/packages/ui/components/ui/identicon/types.ts @@ -1,5 +1,5 @@ export interface IdenticonProps { - name: string; + uniqueIdentifier: string; size?: number; className?: string; } diff --git a/packages/ui/components/ui/select-account.tsx b/packages/ui/components/ui/select-account.tsx index c9f9e22ac5..93ba07560d 100644 --- a/packages/ui/components/ui/select-account.tsx +++ b/packages/ui/components/ui/select-account.tsx @@ -1,5 +1,3 @@ -import { Account } from '@penumbra-zone/types'; -import { Address } from './address'; import { AddressIcon } from './address-icon'; import { ArrowLeftIcon, ArrowRightIcon, InfoIcon } from 'lucide-react'; import { cn } from '../../lib/utils'; @@ -10,45 +8,49 @@ import { Input } from './input'; import { Switch } from './switch'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './tooltip'; import { useEffect, useState } from 'react'; +import { AddressComponent } from './address-component'; +import { Address } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1alpha1/keys_pb'; +import { bech32Address } from '@penumbra-zone/types'; interface SelectAccountProps { - getAccount: (index: number, ephemeral: boolean) => Promise | Account | undefined; + getAddrByIndex: (index: number, ephemeral: boolean) => Promise
| Address; } + const MAX_INDEX = 2 ** 32; -export const SelectAccount = ({ getAccount }: SelectAccountProps) => { +export const SelectAccount = ({ getAddrByIndex }: SelectAccountProps) => { const [index, setIndex] = useState(0); const [ephemeral, setEphemeral] = useState(false); const [width, setWidth] = useState(index.toString().length); - const [account, setAccount] = useState(); + const [address, setAddress] = useState
(); useEffect(() => { void (async () => { - const account = await getAccount(index, ephemeral); - setAccount(account); + const address = await getAddrByIndex(index, ephemeral); + setAddress(address); })(); - // getAccount updates the address every block + // getAddrByIndex updates the address every block // eslint-disable-next-line react-hooks/exhaustive-deps }, [index, ephemeral]); return ( <> - {!account ? ( + {!address ? ( <> ) : (
@@ -84,13 +86,13 @@ export const SelectAccount = ({ getAccount }: SelectAccountProps) => {
- +

-

+

- +
diff --git a/packages/ui/components/ui/tx/view/address-view.tsx b/packages/ui/components/ui/tx/view/address-view.tsx index b3edb8da08..6eeb862105 100644 --- a/packages/ui/components/ui/tx/view/address-view.tsx +++ b/packages/ui/components/ui/tx/view/address-view.tsx @@ -1,8 +1,8 @@ -import { Address } from '../../address'; import { AddressIcon } from '../../address-icon'; import { AddressView } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1alpha1/keys_pb'; import { bech32Address } from '@penumbra-zone/types'; import { CopyToClipboardIconButton } from '../../copy-to-clipboard-icon-button'; +import { AddressComponent } from '../../address-component'; interface AddressViewProps { view: AddressView | undefined; @@ -31,15 +31,14 @@ export const AddressViewComponent = ({ view, copyable = true }: AddressViewProps
{accountIndex !== undefined ? ( <> - - + {addressIndexLabel} {accountIndex} ) : ( -
+ )} {copyable && } diff --git a/packages/ui/components/ui/tx/view/value.tsx b/packages/ui/components/ui/tx/view/value.tsx index 3196d17701..248783efeb 100644 --- a/packages/ui/components/ui/tx/view/value.tsx +++ b/packages/ui/components/ui/tx/view/value.tsx @@ -1,21 +1,25 @@ import { ValueView } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1alpha1/asset_pb'; -import { bech32AssetId, fromBaseUnitAmount } from '@penumbra-zone/types'; +import { + fromBaseUnitAmount, + getDisplayDenomExponent, + getDisplayDenomFromView, +} from '@penumbra-zone/types'; import { CopyToClipboard } from '../../copy-to-clipboard'; import { CopyIcon } from '@radix-ui/react-icons'; import { Amount } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/num/v1alpha1/num_pb'; -import { getDisplayDenomExponent } from '@penumbra-zone/types/src/denom-metadata'; interface ValueViewProps { view: ValueView | undefined; + showDenom?: boolean; } -export const ValueViewComponent = ({ view }: ValueViewProps) => { +export const ValueViewComponent = ({ view, showDenom = true }: ValueViewProps) => { if (!view) return <>; if (view.valueView.case === 'unknownAssetId') { const value = view.valueView.value; const amount = value.amount ?? new Amount(); - const encodedAssetId = bech32AssetId(value.assetId!); + const encodedAssetId = getDisplayDenomFromView(view); return (

{fromBaseUnitAmount(amount, 0).toFormat()}

@@ -36,12 +40,12 @@ export const ValueViewComponent = ({ view }: ValueViewProps) => { if (view.valueView.case === 'knownAssetId') { const value = view.valueView.value; const amount = value.amount ?? new Amount(); - const display_denom = value.metadata?.display ?? ''; + const displayDenom = getDisplayDenomFromView(view); const exponent = value.metadata ? getDisplayDenomExponent(value.metadata) : 0; return (
- {fromBaseUnitAmount(amount, exponent).toFormat()} {display_denom} + {fromBaseUnitAmount(amount, exponent).toFormat()} {showDenom && displayDenom}
); } diff --git a/packages/ui/components/ui/types/address.tsx b/packages/ui/components/ui/types/address.tsx deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/ui/components/ui/types/value.tsx b/packages/ui/components/ui/types/value.tsx deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/ui/package.json b/packages/ui/package.json index c765a9ae44..5e38184e49 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -24,12 +24,12 @@ "@radix-ui/react-toast": "^1.1.5", "@radix-ui/react-toggle": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", - "@testing-library/jest-dom": "^6.4.1", + "@testing-library/jest-dom": "^6.4.2", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "djb2a": "^2.0.0", "framer-motion": "^11.0.3", - "lucide-react": "^0.321.0", + "lucide-react": "^0.323.0", "react-dom": "^18.2.0", "react-json-view": "^1.21.3", "tailwind-merge": "^2.2.1", @@ -47,14 +47,14 @@ "@storybook/react-vite": "^7.6.12", "@testing-library/react": "^14.2.1", "@types/node": "^20.11.16", - "@types/react": "^18.2.53", + "@types/react": "^18.2.55", "@types/react-dom": "^18.2.18", "@types/tinycolor2": "^1.4.6", "@vitest/browser": "^1.2.2", "autoprefixer": "^10.4.17", "eslint-plugin-storybook": "^0.6.15", "jsdom": "^24.0.0", - "postcss": "^8.4.33", + "postcss": "^8.4.34", "prop-types": "^15.8.1", "react": "^18.2.0", "storybook": "^7.6.12", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 34e950d5ab..5271711249 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,11 +15,11 @@ importers: specifier: 1.3.0-20240123184419-30c7be3837b0.1 version: 1.3.0-20240123184419-30c7be3837b0.1(@bufbuild/protobuf@1.7.2)(@connectrpc/connect@1.3.0) '@buf/penumbra-zone_penumbra.bufbuild_es': - specifier: 1.7.2-20240203052248-18996dcd17a4.1 - version: 1.7.2-20240203052248-18996dcd17a4.1(@bufbuild/protobuf@1.7.2) + specifier: 1.7.2-20240206003852-3cc57ebd3e94.1 + version: 1.7.2-20240206003852-3cc57ebd3e94.1(@bufbuild/protobuf@1.7.2) '@buf/penumbra-zone_penumbra.connectrpc_es': - specifier: 1.3.0-20240203052248-18996dcd17a4.1 - version: 1.3.0-20240203052248-18996dcd17a4.1(@bufbuild/protobuf@1.7.2)(@connectrpc/connect@1.3.0) + specifier: 1.3.0-20240206003852-3cc57ebd3e94.1 + version: 1.3.0-20240206003852-3cc57ebd3e94.1(@bufbuild/protobuf@1.7.2)(@connectrpc/connect@1.3.0) '@bufbuild/protobuf': specifier: ^1.7.2 version: 1.7.2 @@ -43,11 +43,11 @@ importers: specifier: ^1.12.2 version: 1.12.2(@types/node@20.11.16)(typescript@5.3.3) '@typescript-eslint/eslint-plugin': - specifier: ^6.20.0 - version: 6.20.0(@typescript-eslint/parser@6.20.0)(eslint@8.56.0)(typescript@5.3.3) + specifier: ^6.21.0 + version: 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3) '@typescript-eslint/parser': - specifier: ^6.20.0 - version: 6.20.0(eslint@8.56.0)(typescript@5.3.3) + specifier: ^6.21.0 + version: 6.21.0(eslint@8.56.0)(typescript@5.3.3) eslint: specifier: ^8.56.0 version: 8.56.0 @@ -131,7 +131,7 @@ importers: version: 2.12.1(react@18.2.0) zustand: specifier: ^4.5.0 - version: 4.5.0(@types/react@18.2.53)(immer@10.0.3)(react@18.2.0) + version: 4.5.0(@types/react@18.2.55)(immer@10.0.3)(react@18.2.0) devDependencies: '@radix-ui/react-icons': specifier: ^1.3.0 @@ -146,14 +146,14 @@ importers: specifier: ^20.11.16 version: 20.11.16 '@types/react': - specifier: ^18.2.53 - version: 18.2.53 + specifier: ^18.2.55 + version: 18.2.55 '@types/react-dom': specifier: ^18.2.18 version: 18.2.18 autoprefixer: specifier: ^10.4.17 - version: 10.4.17(postcss@8.4.33) + version: 10.4.17(postcss@8.4.34) copy-webpack-plugin: specifier: ^12.0.2 version: 12.0.2(webpack@5.90.1) @@ -164,11 +164,11 @@ importers: specifier: ^5.6.0 version: 5.6.0(webpack@5.90.1) postcss: - specifier: ^8.4.33 - version: 8.4.33 + specifier: ^8.4.34 + version: 8.4.34 postcss-loader: specifier: ^8.1.0 - version: 8.1.0(postcss@8.4.33)(typescript@5.3.3)(webpack@5.90.1) + version: 8.1.0(postcss@8.4.34)(typescript@5.3.3)(webpack@5.90.1) style-loader: specifier: ^3.3.4 version: 3.3.4(webpack@5.90.1) @@ -220,6 +220,9 @@ importers: bignumber.js: specifier: ^9.1.2 version: 9.1.2 + immer: + specifier: ^10.0.3 + version: 10.0.3 react: specifier: ^18.2.0 version: 18.2.0 @@ -238,16 +241,19 @@ importers: tailwindcss: specifier: ^3.4.1 version: 3.4.1 + zod: + specifier: ^3.22.4 + version: 3.22.4 zustand: specifier: ^4.5.0 - version: 4.5.0(@types/react@18.2.53)(immer@10.0.3)(react@18.2.0) + version: 4.5.0(@types/react@18.2.55)(immer@10.0.3)(react@18.2.0) devDependencies: '@types/node': specifier: ^20.11.16 version: 20.11.16 '@types/react': - specifier: ^18.2.53 - version: 18.2.53 + specifier: ^18.2.55 + version: 18.2.55 '@types/react-dom': specifier: ^18.2.18 version: 18.2.18 @@ -259,13 +265,13 @@ importers: version: 3.6.0(vite@5.0.12) autoprefixer: specifier: ^10.4.17 - version: 10.4.17(postcss@8.4.33) + version: 10.4.17(postcss@8.4.34) firebase-tools: specifier: ^13.1.0 version: 13.1.0 postcss: - specifier: ^8.4.33 - version: 8.4.33 + specifier: ^8.4.34 + version: 8.4.34 vite: specifier: ^5.0.12 version: 5.0.12(@types/node@20.11.16) @@ -300,11 +306,11 @@ importers: packages/eslint-config-custom: dependencies: '@typescript-eslint/eslint-plugin': - specifier: ^6.20.0 - version: 6.20.0(@typescript-eslint/parser@6.20.0)(eslint@8.56.0)(typescript@5.3.3) + specifier: ^6.21.0 + version: 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3) '@typescript-eslint/parser': - specifier: ^6.20.0 - version: 6.20.0(eslint@8.56.0)(typescript@5.3.3) + specifier: ^6.21.0 + version: 6.21.0(eslint@8.56.0)(typescript@5.3.3) eslint-config-next: specifier: ^14.1.0 version: 14.1.0(eslint@8.56.0)(typescript@5.3.3) @@ -324,14 +330,14 @@ importers: specifier: ^0.4.5 version: 0.4.5(eslint@8.56.0) eslint-plugin-tailwindcss: - specifier: ^3.14.1 - version: 3.14.1(tailwindcss@3.4.1) + specifier: ^3.14.2 + version: 3.14.2(tailwindcss@3.4.1) eslint-plugin-turbo: specifier: ^1.12.2 version: 1.12.2(eslint@8.56.0) eslint-plugin-vitest: specifier: ^0.3.21 - version: 0.3.21(@typescript-eslint/eslint-plugin@6.20.0)(eslint@8.56.0)(typescript@5.3.3) + version: 0.3.21(@typescript-eslint/eslint-plugin@6.21.0)(eslint@8.56.0)(typescript@5.3.3) packages/query: dependencies: @@ -463,46 +469,46 @@ importers: dependencies: '@radix-ui/react-checkbox': specifier: ^1.0.4 - version: 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-dialog': specifier: 1.0.5 - version: 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-icons': specifier: ^1.3.0 version: 1.3.0(react@18.2.0) '@radix-ui/react-navigation-menu': specifier: ^1.1.4 - version: 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + version: 1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-popover': specifier: ^1.0.7 - version: 1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-progress': specifier: ^1.0.3 - version: 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-select': specifier: ^2.0.0 - version: 2.0.0(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + version: 2.0.0(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-slot': specifier: ^1.0.2 - version: 1.0.2(@types/react@18.2.53)(react@18.2.0) + version: 1.0.2(@types/react@18.2.55)(react@18.2.0) '@radix-ui/react-switch': specifier: ^1.0.3 - version: 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-tabs': specifier: ^1.0.4 - version: 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-toast': specifier: ^1.1.5 - version: 1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + version: 1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-toggle': specifier: ^1.0.3 - version: 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-tooltip': specifier: ^1.0.7 - version: 1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@testing-library/jest-dom': - specifier: ^6.4.1 - version: 6.4.1(vitest@1.2.2) + specifier: ^6.4.2 + version: 6.4.2(vitest@1.2.2) class-variance-authority: specifier: ^0.7.0 version: 0.7.0 @@ -516,14 +522,14 @@ importers: specifier: ^11.0.3 version: 11.0.3(react-dom@18.2.0)(react@18.2.0) lucide-react: - specifier: ^0.321.0 - version: 0.321.0(react@18.2.0) + specifier: ^0.323.0 + version: 0.323.0(react@18.2.0) react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) react-json-view: specifier: ^1.21.3 - version: 1.21.3(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + version: 1.21.3(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) tailwind-merge: specifier: ^2.2.1 version: 2.2.1 @@ -536,7 +542,7 @@ importers: devDependencies: '@storybook/addon-essentials': specifier: ^7.6.12 - version: 7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + version: 7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@storybook/addon-interactions': specifier: ^7.6.12 version: 7.6.12 @@ -548,7 +554,7 @@ importers: version: 2.0.0(webpack@5.90.1) '@storybook/blocks': specifier: ^7.6.12 - version: 7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + version: 7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@storybook/preview-api': specifier: ^7.6.12 version: 7.6.12 @@ -565,8 +571,8 @@ importers: specifier: ^20.11.16 version: 20.11.16 '@types/react': - specifier: ^18.2.53 - version: 18.2.53 + specifier: ^18.2.55 + version: 18.2.55 '@types/react-dom': specifier: ^18.2.18 version: 18.2.18 @@ -578,7 +584,7 @@ importers: version: 1.2.2(playwright@1.41.2)(vitest@1.2.2) autoprefixer: specifier: ^10.4.17 - version: 10.4.17(postcss@8.4.33) + version: 10.4.17(postcss@8.4.34) eslint-plugin-storybook: specifier: ^0.6.15 version: 0.6.15(eslint@8.56.0)(typescript@5.3.3) @@ -586,8 +592,8 @@ importers: specifier: ^24.0.0 version: 24.0.0 postcss: - specifier: ^8.4.33 - version: 8.4.33 + specifier: ^8.4.34 + version: 8.4.34 prop-types: specifier: ^15.8.1 version: 15.8.1 @@ -2296,8 +2302,8 @@ packages: - '@bufbuild/protobuf' dev: false - /@buf/penumbra-zone_penumbra.bufbuild_es@1.6.0-20240203052248-18996dcd17a4.1(@bufbuild/protobuf@1.7.2): - resolution: {tarball: https://buf.build/gen/npm/v1/@buf/penumbra-zone_penumbra.bufbuild_es/-/penumbra-zone_penumbra.bufbuild_es-1.6.0-20240203052248-18996dcd17a4.1.tgz} + /@buf/penumbra-zone_penumbra.bufbuild_es@1.6.0-20240206003852-3cc57ebd3e94.1(@bufbuild/protobuf@1.7.2): + resolution: {tarball: https://buf.build/gen/npm/v1/@buf/penumbra-zone_penumbra.bufbuild_es/-/penumbra-zone_penumbra.bufbuild_es-1.6.0-20240206003852-3cc57ebd3e94.1.tgz} peerDependencies: '@bufbuild/protobuf': ^1.6.0 dependencies: @@ -2310,8 +2316,8 @@ packages: '@bufbuild/protobuf': 1.7.2 dev: false - /@buf/penumbra-zone_penumbra.bufbuild_es@1.7.2-20240203052248-18996dcd17a4.1(@bufbuild/protobuf@1.7.2): - resolution: {tarball: https://buf.build/gen/npm/v1/@buf/penumbra-zone_penumbra.bufbuild_es/-/penumbra-zone_penumbra.bufbuild_es-1.7.2-20240203052248-18996dcd17a4.1.tgz} + /@buf/penumbra-zone_penumbra.bufbuild_es@1.7.2-20240206003852-3cc57ebd3e94.1(@bufbuild/protobuf@1.7.2): + resolution: {tarball: https://buf.build/gen/npm/v1/@buf/penumbra-zone_penumbra.bufbuild_es/-/penumbra-zone_penumbra.bufbuild_es-1.7.2-20240206003852-3cc57ebd3e94.1.tgz} peerDependencies: '@bufbuild/protobuf': ^1.7.2 dependencies: @@ -2324,8 +2330,8 @@ packages: '@bufbuild/protobuf': 1.7.2 dev: false - /@buf/penumbra-zone_penumbra.connectrpc_es@1.3.0-20240203052248-18996dcd17a4.1(@bufbuild/protobuf@1.7.2)(@connectrpc/connect@1.3.0): - resolution: {tarball: https://buf.build/gen/npm/v1/@buf/penumbra-zone_penumbra.connectrpc_es/-/penumbra-zone_penumbra.connectrpc_es-1.3.0-20240203052248-18996dcd17a4.1.tgz} + /@buf/penumbra-zone_penumbra.connectrpc_es@1.3.0-20240206003852-3cc57ebd3e94.1(@bufbuild/protobuf@1.7.2)(@connectrpc/connect@1.3.0): + resolution: {tarball: https://buf.build/gen/npm/v1/@buf/penumbra-zone_penumbra.connectrpc_es/-/penumbra-zone_penumbra.connectrpc_es-1.3.0-20240206003852-3cc57ebd3e94.1.tgz} peerDependencies: '@connectrpc/connect': ^1.3.0 dependencies: @@ -2335,7 +2341,7 @@ packages: '@buf/cosmos_ibc.connectrpc_es': 1.3.0-20230913112312-7ab44ae956a0.1(@bufbuild/protobuf@1.7.2)(@connectrpc/connect@1.3.0) '@buf/cosmos_ics23.connectrpc_es': 1.3.0-20221207100654-55085f7c710a.1(@bufbuild/protobuf@1.7.2)(@connectrpc/connect@1.3.0) '@buf/googleapis_googleapis.connectrpc_es': 1.3.0-20221214150216-75b4300737fb.1(@bufbuild/protobuf@1.7.2)(@connectrpc/connect@1.3.0) - '@buf/penumbra-zone_penumbra.bufbuild_es': 1.6.0-20240203052248-18996dcd17a4.1(@bufbuild/protobuf@1.7.2) + '@buf/penumbra-zone_penumbra.bufbuild_es': 1.6.0-20240206003852-3cc57ebd3e94.1(@bufbuild/protobuf@1.7.2) '@connectrpc/connect': 1.3.0(@bufbuild/protobuf@1.7.2) transitivePeerDependencies: - '@bufbuild/protobuf' @@ -3115,7 +3121,7 @@ packages: react: '>=16' dependencies: '@types/mdx': 2.0.11 - '@types/react': 18.2.53 + '@types/react': 18.2.55 react: 18.2.0 dev: true @@ -3154,10 +3160,10 @@ packages: engines: {node: '>= 8'} dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.17.0 + fastq: 1.17.1 - /@npmcli/agent@2.2.0: - resolution: {integrity: sha512-2yThA1Es98orMkpSLVqlDZAMPK3jHJhifP2gnNUdk1754uZ8yI5c+ulCoVG+WlntQA6MzhrURMXjSd9Z7dJ2/Q==} + /@npmcli/agent@2.2.1: + resolution: {integrity: sha512-H4FrOVtNyWC8MUwL3UfjOsAihHvT1Pe8POj3JvjXhSTJipsZMtgUALCT4mGyYZNxymkUfOw3PUj6dE4QPp6osQ==} engines: {node: ^16.14.0 || >=18.0.0} requiresBuild: true dependencies: @@ -3176,7 +3182,7 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} requiresBuild: true dependencies: - semver: 7.5.4 + semver: 7.6.0 dev: true optional: true @@ -3281,7 +3287,7 @@ packages: dependencies: '@babel/runtime': 7.23.9 - /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==} peerDependencies: '@types/react': '*' @@ -3295,13 +3301,13 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - /@radix-ui/react-checkbox@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-checkbox@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg==} peerDependencies: '@types/react': '*' @@ -3316,20 +3322,20 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-collection@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-collection@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==} peerDependencies: '@types/react': '*' @@ -3343,16 +3349,16 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - /@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.53)(react@18.2.0): + /@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} peerDependencies: '@types/react': '*' @@ -3362,10 +3368,10 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@types/react': 18.2.53 + '@types/react': 18.2.55 react: 18.2.0 - /@radix-ui/react-context@1.0.1(@types/react@18.2.53)(react@18.2.0): + /@radix-ui/react-context@1.0.1(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==} peerDependencies: '@types/react': '*' @@ -3375,10 +3381,10 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@types/react': 18.2.53 + '@types/react': 18.2.55 react: 18.2.0 - /@radix-ui/react-dialog@1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-dialog@1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} peerDependencies: '@types/react': '*' @@ -3393,26 +3399,26 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 aria-hidden: 1.2.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-remove-scroll: 2.5.5(@types/react@18.2.53)(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.55)(react@18.2.0) dev: false - /@radix-ui/react-direction@1.0.1(@types/react@18.2.53)(react@18.2.0): + /@radix-ui/react-direction@1.0.1(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==} peerDependencies: '@types/react': '*' @@ -3422,10 +3428,10 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@types/react': 18.2.53 + '@types/react': 18.2.55 react: 18.2.0 - /@radix-ui/react-dismissable-layer@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-dismissable-layer@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-7UpBa/RKMoHJYjie1gkF1DlK8l1fdU/VKDpoS3rCCo8YBJR294GwcEHyxHw72yvphJ7ld0AXEcSLAzY2F/WyCg==} peerDependencies: '@types/react': '*' @@ -3440,17 +3446,17 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true - /@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==} peerDependencies: '@types/react': '*' @@ -3465,17 +3471,17 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.53)(react@18.2.0): + /@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==} peerDependencies: '@types/react': '*' @@ -3485,10 +3491,10 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@types/react': 18.2.53 + '@types/react': 18.2.55 react: 18.2.0 - /@radix-ui/react-focus-scope@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-focus-scope@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-upXdPfqI4islj2CslyfUBNlaJCPybbqRHAi1KER7Isel9Q2AtSJ0zRBZv8mWQiFXD2nyAJ4BhC3yXgZ6kMBSrQ==} peerDependencies: '@types/react': '*' @@ -3502,16 +3508,16 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true - /@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==} peerDependencies: '@types/react': '*' @@ -3525,10 +3531,10 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -3541,7 +3547,7 @@ packages: dependencies: react: 18.2.0 - /@radix-ui/react-id@1.0.1(@types/react@18.2.53)(react@18.2.0): + /@radix-ui/react-id@1.0.1(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==} peerDependencies: '@types/react': '*' @@ -3551,11 +3557,11 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 react: 18.2.0 - /@radix-ui/react-navigation-menu@1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-navigation-menu@1.1.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Cc+seCS3PmWmjI51ufGG7zp1cAAIRqHVw7C9LOA2TZ+R4hG6rDvHcTqIsEEFLmZO3zNVH72jOOE7kKNy8W+RtA==} peerDependencies: '@types/react': '*' @@ -3570,26 +3576,26 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-direction': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-popover@1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-popover@1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==} peerDependencies: '@types/react': '*' @@ -3604,27 +3610,27 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 aria-hidden: 1.2.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-remove-scroll: 2.5.5(@types/react@18.2.53)(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.55)(react@18.2.0) dev: false - /@radix-ui/react-popper@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-popper@1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-1CnGGfFi/bbqtJZZ0P/NQY20xdG3E0LALJaLUEoKwPLwl6PPPfbeiCqMVQnhoFRAxjJj4RpBRJzDmUgsex2tSg==} peerDependencies: '@types/react': '*' @@ -3639,22 +3645,22 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@floating-ui/react-dom': 2.0.8(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.53)(react@18.2.0) + '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.55)(react@18.2.0) '@radix-ui/rect': 1.0.1 - '@types/react': 18.2.53 + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true - /@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==} peerDependencies: '@types/react': '*' @@ -3669,22 +3675,22 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@floating-ui/react-dom': 2.0.8(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.53)(react@18.2.0) + '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.55)(react@18.2.0) '@radix-ui/rect': 1.0.1 - '@types/react': 18.2.53 + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-portal@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-portal@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-xLYZeHrWoPmA5mEKEfZZevoVRK/Q43GfzRXkWV6qawIWWK8t6ifIiLQdd7rmQ4Vk1bmI21XhqF9BN3jWf+phpA==} peerDependencies: '@types/react': '*' @@ -3698,14 +3704,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true - /@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==} peerDependencies: '@types/react': '*' @@ -3719,14 +3725,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} peerDependencies: '@types/react': '*' @@ -3740,15 +3746,15 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} peerDependencies: '@types/react': '*' @@ -3762,13 +3768,13 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - /@radix-ui/react-progress@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-progress@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-5G6Om/tYSxjSeEdrb1VfKkfZfn/1IlPWd731h2RfPuSbIfNUgfqAwbKfJCg/PP6nuUCTrYzalwHSpSinoWoCag==} peerDependencies: '@types/react': '*' @@ -3782,15 +3788,15 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-roving-focus@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-roving-focus@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==} peerDependencies: '@types/react': '*' @@ -3805,20 +3811,20 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-direction': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - /@radix-ui/react-select@1.2.2(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-select@1.2.2(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-zI7McXr8fNaSrUY9mZe4x/HC0jTLY9fWNhO1oLWYMQGDXuV4UCivIGTxwioSzO0ZCYX9iSLyWmAh/1TOmX3Cnw==} peerDependencies: '@types/react': '*' @@ -3834,32 +3840,32 @@ packages: '@babel/runtime': 7.23.9 '@radix-ui/number': 1.0.1 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-direction': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-dismissable-layer': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-focus-scope': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-popper': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-portal': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-popper': 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 aria-hidden: 1.2.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-remove-scroll: 2.5.5(@types/react@18.2.53)(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.55)(react@18.2.0) dev: true - /@radix-ui/react-select@2.0.0(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-select@2.0.0(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-RH5b7af4oHtkcHS7pG6Sgv5rk5Wxa7XI8W5gvB1N/yiuDGZxko1ynvOiVhFM7Cis2A8zxF9bTOUVbRDzPepe6w==} peerDependencies: '@types/react': '*' @@ -3875,32 +3881,32 @@ packages: '@babel/runtime': 7.23.9 '@radix-ui/number': 1.0.1 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-direction': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 aria-hidden: 1.2.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-remove-scroll: 2.5.5(@types/react@18.2.53)(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.55)(react@18.2.0) dev: false - /@radix-ui/react-separator@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-separator@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-itYmTy/kokS21aiV5+Z56MZB54KrhPgn6eHDKkFeOLR34HMN2s8PaN47qZZAGnvupcjxHaFZnW4pQEh0BvvVuw==} peerDependencies: '@types/react': '*' @@ -3914,14 +3920,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true - /@radix-ui/react-slot@1.0.2(@types/react@18.2.53)(react@18.2.0): + /@radix-ui/react-slot@1.0.2(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} peerDependencies: '@types/react': '*' @@ -3931,11 +3937,11 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 react: 18.2.0 - /@radix-ui/react-switch@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-switch@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-mxm87F88HyHztsI7N+ZUmEoARGkC22YVW5CaC+Byc+HRpuvCrOBPTAnXgf+tZ/7i0Sg/eOePGdMhUKhPaQEqow==} peerDependencies: '@types/react': '*' @@ -3950,19 +3956,19 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-tabs@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-tabs@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog==} peerDependencies: '@types/react': '*' @@ -3977,20 +3983,20 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-direction': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-toast@1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-toast@1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-fRLn227WHIBRSzuRzGJ8W+5YALxofH23y0MlPLddaIpLpCDqdE0NZlS2NRQDRiptfxDeeCjgFIpexB1/zkxDlw==} peerDependencies: '@types/react': '*' @@ -4005,24 +4011,24 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-toggle-group@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-toggle-group@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Uaj/M/cMyiyT9Bx6fOZO0SAG4Cls0GptBWiBmBxofmDbNVnYYoyRWj/2M/6VCi/7qcXFWnHhRUfdfZFvvkuu8A==} peerDependencies: '@types/react': '*' @@ -4037,19 +4043,19 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-direction': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-toggle': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-toggle': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true - /@radix-ui/react-toggle@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-toggle@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Pkqg3+Bc98ftZGsl60CLANXQBBQ4W3mTFS9EJvNxKMZ7magklKV69/id1mlAlOFDDfHvlCms0fx8fA4CMKDJHg==} peerDependencies: '@types/react': '*' @@ -4064,14 +4070,14 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - /@radix-ui/react-toolbar@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-toolbar@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-tBgmM/O7a07xbaEkYJWYTXkIdU/1pW4/KZORR43toC/4XWyBCURK0ei9kMUdp+gTPPKBgYLxXmRSH1EVcIDp8Q==} peerDependencies: '@types/react': '*' @@ -4086,19 +4092,19 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-direction': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-separator': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-toggle-group': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-separator': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-toggle-group': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true - /@radix-ui/react-tooltip@1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-tooltip@1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==} peerDependencies: '@types/react': '*' @@ -4113,24 +4119,24 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.53)(react@18.2.0): + /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} peerDependencies: '@types/react': '*' @@ -4140,10 +4146,10 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@types/react': 18.2.53 + '@types/react': 18.2.55 react: 18.2.0 - /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.53)(react@18.2.0): + /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==} peerDependencies: '@types/react': '*' @@ -4153,11 +4159,11 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 react: 18.2.0 - /@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.53)(react@18.2.0): + /@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==} peerDependencies: '@types/react': '*' @@ -4167,11 +4173,11 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 react: 18.2.0 - /@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.53)(react@18.2.0): + /@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==} peerDependencies: '@types/react': '*' @@ -4181,10 +4187,10 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@types/react': 18.2.53 + '@types/react': 18.2.55 react: 18.2.0 - /@radix-ui/react-use-previous@1.0.1(@types/react@18.2.53)(react@18.2.0): + /@radix-ui/react-use-previous@1.0.1(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==} peerDependencies: '@types/react': '*' @@ -4194,10 +4200,10 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@types/react': 18.2.53 + '@types/react': 18.2.55 react: 18.2.0 - /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.53)(react@18.2.0): + /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==} peerDependencies: '@types/react': '*' @@ -4208,10 +4214,10 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@radix-ui/rect': 1.0.1 - '@types/react': 18.2.53 + '@types/react': 18.2.55 react: 18.2.0 - /@radix-ui/react-use-size@1.0.1(@types/react@18.2.53)(react@18.2.0): + /@radix-ui/react-use-size@1.0.1(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==} peerDependencies: '@types/react': '*' @@ -4221,11 +4227,11 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.53)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.55)(react@18.2.0) + '@types/react': 18.2.55 react: 18.2.0 - /@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==} peerDependencies: '@types/react': '*' @@ -4239,8 +4245,8 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.53 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.55 '@types/react-dom': 18.2.18 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -4391,10 +4397,10 @@ packages: ts-dedent: 2.2.0 dev: true - /@storybook/addon-controls@7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@storybook/addon-controls@7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-NX4KajscOsuXyYE3hhniF+y0E59E6rM0FgIaZ48P9c0DD+wDo8bAISHjZvmKXtDVajLk4/JySvByx1eN6V3hmA==} dependencies: - '@storybook/blocks': 7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + '@storybook/blocks': 7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) lodash: 4.17.21 ts-dedent: 2.2.0 transitivePeerDependencies: @@ -4406,7 +4412,7 @@ packages: - supports-color dev: true - /@storybook/addon-docs@7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@storybook/addon-docs@7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-AzMgnGYfEg+Z1ycJh8MEp44x1DfjRijKCVYNaPFT6o+TjN/9GBaAkV4ydxmQzMEMnnnh/0E9YeHO+ivBVSkNog==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4414,9 +4420,9 @@ packages: dependencies: '@jest/transform': 29.7.0 '@mdx-js/react': 2.3.0(react@18.2.0) - '@storybook/blocks': 7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + '@storybook/blocks': 7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@storybook/client-logger': 7.6.12 - '@storybook/components': 7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + '@storybook/components': 7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@storybook/csf-plugin': 7.6.12 '@storybook/csf-tools': 7.6.12 '@storybook/global': 5.0.0 @@ -4440,7 +4446,7 @@ packages: - supports-color dev: true - /@storybook/addon-essentials@7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@storybook/addon-essentials@7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Pl6n+19QC/T+cuU8DZjCwILXVxrdRTivNxPOiy8SEX+jjR4H0uAfXC9+RXCPjRFn64t4j1K7oIyoNokEn39cNw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4448,8 +4454,8 @@ packages: dependencies: '@storybook/addon-actions': 7.6.12 '@storybook/addon-backgrounds': 7.6.12 - '@storybook/addon-controls': 7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@storybook/addon-docs': 7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-controls': 7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-docs': 7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@storybook/addon-highlight': 7.6.12 '@storybook/addon-measure': 7.6.12 '@storybook/addon-outline': 7.6.12 @@ -4536,7 +4542,7 @@ packages: memoizerific: 1.11.3 dev: true - /@storybook/blocks@7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@storybook/blocks@7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-T47KOAjgZmhV+Ov59A70inE5edInh1Jh5w/5J5cjpk9a2p4uhd337SnK4B8J5YLhcM2lbKRWJjzIJ0nDZQTdnQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4544,7 +4550,7 @@ packages: dependencies: '@storybook/channels': 7.6.12 '@storybook/client-logger': 7.6.12 - '@storybook/components': 7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + '@storybook/components': 7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@storybook/core-events': 7.6.12 '@storybook/csf': 0.1.2 '@storybook/docs-tools': 7.6.12 @@ -4627,7 +4633,7 @@ packages: express: 4.18.2 find-cache-dir: 3.3.2 fs-extra: 11.2.0 - magic-string: 0.30.6 + magic-string: 0.30.7 rollup: 3.29.4 typescript: 5.3.3 vite: 5.0.12(@types/node@20.11.16) @@ -4686,7 +4692,7 @@ packages: prompts: 2.4.2 puppeteer-core: 2.1.1 read-pkg-up: 7.0.1 - semver: 7.5.4 + semver: 7.6.0 strip-json-comments: 3.1.1 tempy: 1.0.1 ts-dedent: 2.2.0 @@ -4725,14 +4731,14 @@ packages: - supports-color dev: true - /@storybook/components@7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /@storybook/components@7.6.12(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-PCijPqmlZd7qyTzNr+vD0Kf8sAI9vWJIaxbSjXwn/De3e63m4fsEcIf8FaUT8cMZ46AWZvaxaxX5km2u0UISJQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@radix-ui/react-select': 1.2.2(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-toolbar': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-select': 1.2.2(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-toolbar': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@storybook/client-logger': 7.6.12 '@storybook/csf': 0.1.2 '@storybook/global': 5.0.0 @@ -4828,7 +4834,7 @@ packages: pretty-hrtime: 1.0.3 prompts: 2.4.2 read-pkg-up: 7.0.1 - semver: 7.5.4 + semver: 7.6.0 telejson: 7.2.0 tiny-invariant: 1.3.1 ts-dedent: 2.2.0 @@ -4847,7 +4853,7 @@ packages: resolution: {integrity: sha512-fe/84AyctJcrpH1F/tTBxKrbjv0ilmG3ZTwVcufEiAzupZuYjQ/0P+Pxs8m8VxiGJZZ1pWofFFDbYi+wERjamQ==} dependencies: '@storybook/csf-tools': 7.6.12 - unplugin: 1.6.0 + unplugin: 1.7.1 transitivePeerDependencies: - supports-color dev: true @@ -4997,7 +5003,7 @@ packages: '@storybook/builder-vite': 7.6.12(typescript@5.3.3)(vite@5.0.12) '@storybook/react': 7.6.12(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3) '@vitejs/plugin-react': 3.1.0(vite@5.0.12) - magic-string: 0.30.6 + magic-string: 0.30.7 react: 18.2.0 react-docgen: 7.0.3 react-dom: 18.2.0(react@18.2.0) @@ -5248,8 +5254,8 @@ packages: pretty-format: 27.5.1 dev: true - /@testing-library/jest-dom@6.4.1(vitest@1.2.2): - resolution: {integrity: sha512-Z7qMM3J2Zw5H/nC2/5CYx5YcuaD56JmDFKNIozZ89VIo6o6Y9FMhssics4e2madEKYDNEpZz3+glPGz0yWMOag==} + /@testing-library/jest-dom@6.4.2(vitest@1.2.2): + resolution: {integrity: sha512-CzqH0AFymEMG48CpzXFriYYkOjk6ZGPCLMhW9e9jg3KMCn5OfJecF8GtGW7yGfR/IgCe3SX8BSwjdzI6BBbZLw==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} peerDependencies: '@jest/globals': '>= 28' @@ -5351,7 +5357,7 @@ packages: js-yaml: 4.1.0 ora: 4.1.1 rimraf: 3.0.2 - semver: 7.5.4 + semver: 7.6.0 update-check: 1.5.4 dev: true @@ -5656,16 +5662,16 @@ packages: /@types/react-dom@18.2.18: resolution: {integrity: sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==} dependencies: - '@types/react': 18.2.53 + '@types/react': 18.2.55 /@types/react-helmet@6.1.11: resolution: {integrity: sha512-0QcdGLddTERotCXo3VFlUSWO3ztraw8nZ6e3zJSgG7apwV5xt+pJUS8ewPBqT4NYB1optGLprNQzFleIY84u/g==} dependencies: - '@types/react': 18.2.53 + '@types/react': 18.2.55 dev: true - /@types/react@18.2.53: - resolution: {integrity: sha512-52IHsMDT8qATp9B9zoOyobW8W3/0QhaJQTw1HwRj0UY2yBpCAQ7+S/CqHYQ8niAm3p4ji+rWUQ9UCib0GxQ60w==} + /@types/react@18.2.55: + resolution: {integrity: sha512-Y2Tz5P4yz23brwm2d7jNon39qoAtMMmalOQv6+fEFt1mT+FcM3D841wDpoUvFXhaYenuROCy3FZYqdTjM7qVyA==} dependencies: '@types/prop-types': 15.7.11 '@types/scheduler': 0.16.8 @@ -5745,8 +5751,8 @@ packages: '@types/yargs-parser': 21.0.3 dev: true - /@typescript-eslint/eslint-plugin@6.20.0(@typescript-eslint/parser@6.20.0)(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg==} + /@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -5757,24 +5763,24 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 6.20.0(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/scope-manager': 6.20.0 - '@typescript-eslint/type-utils': 6.20.0(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/utils': 6.20.0(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 6.20.0 + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/type-utils': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.4 eslint: 8.56.0 graphemer: 1.4.0 ignore: 5.3.1 natural-compare: 1.4.0 - semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.3.3) + semver: 7.6.0 + ts-api-utils: 1.2.0(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color - /@typescript-eslint/parser@6.20.0(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-bYerPDF/H5v6V76MdMYhjwmwgMA+jlPVqjSDq2cRqMi8bP5sR3Z+RLOiOMad3nsnmDVmn2gAFCyNgh/dIrfP/w==} + /@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -5783,10 +5789,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 6.20.0 - '@typescript-eslint/types': 6.20.0 - '@typescript-eslint/typescript-estree': 6.20.0(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 6.20.0 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.4 eslint: 8.56.0 typescript: 5.3.3 @@ -5801,15 +5807,15 @@ packages: '@typescript-eslint/visitor-keys': 5.62.0 dev: true - /@typescript-eslint/scope-manager@6.20.0: - resolution: {integrity: sha512-p4rvHQRDTI1tGGMDFQm+GtxP1ZHyAh64WANVoyEcNMpaTFn3ox/3CcgtIlELnRfKzSs/DwYlDccJEtr3O6qBvA==} + /@typescript-eslint/scope-manager@6.21.0: + resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.20.0 - '@typescript-eslint/visitor-keys': 6.20.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 - /@typescript-eslint/type-utils@6.20.0(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-qnSobiJQb1F5JjN0YDRPHruQTrX7ICsmltXhkV536mp4idGAYrIyr47zF/JmkJtEcAVnIz4gUYJ7gOZa6SmN4g==} + /@typescript-eslint/type-utils@6.21.0(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -5818,11 +5824,11 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.20.0(typescript@5.3.3) - '@typescript-eslint/utils': 6.20.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.56.0)(typescript@5.3.3) debug: 4.3.4 eslint: 8.56.0 - ts-api-utils: 1.0.3(typescript@5.3.3) + ts-api-utils: 1.2.0(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color @@ -5832,8 +5838,8 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/types@6.20.0: - resolution: {integrity: sha512-MM9mfZMAhiN4cOEcUOEx+0HmuaW3WBfukBZPCfwSqFnQy0grXYtngKCqpQN339X3RrwtzspWJrpbrupKYUSBXQ==} + /@typescript-eslint/types@6.21.0: + resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} engines: {node: ^16.0.0 || >=18.0.0} /@typescript-eslint/typescript-estree@5.62.0(typescript@5.3.3): @@ -5850,15 +5856,15 @@ packages: debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.5.4 + semver: 7.6.0 tsutils: 3.21.0(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/typescript-estree@6.20.0(typescript@5.3.3): - resolution: {integrity: sha512-RnRya9q5m6YYSpBN7IzKu9FmLcYtErkDkc8/dKv81I9QiLLtVBHrjz+Ev/crAqgMNW2FCsoZF4g2QUylMnJz+g==} + /@typescript-eslint/typescript-estree@6.21.0(typescript@5.3.3): + resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -5866,14 +5872,14 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.20.0 - '@typescript-eslint/visitor-keys': 6.20.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 - semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.3.3) + semver: 7.6.0 + ts-api-utils: 1.2.0(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color @@ -5892,14 +5898,14 @@ packages: '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.3.3) eslint: 8.56.0 eslint-scope: 5.1.1 - semver: 7.5.4 + semver: 7.6.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/utils@6.20.0(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-/EKuw+kRu2vAqCoDwDCBtDRU6CTKbUmwwI7SH7AashZ+W+7o8eiyy6V2cdOqN49KsTcASWsC5QeghYuRDTyOOg==} + /@typescript-eslint/utils@6.21.0(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -5907,11 +5913,11 @@ packages: '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) '@types/json-schema': 7.0.15 '@types/semver': 7.5.6 - '@typescript-eslint/scope-manager': 6.20.0 - '@typescript-eslint/types': 6.20.0 - '@typescript-eslint/typescript-estree': 6.20.0(typescript@5.3.3) + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) eslint: 8.56.0 - semver: 7.5.4 + semver: 7.6.0 transitivePeerDependencies: - supports-color - typescript @@ -5924,11 +5930,11 @@ packages: eslint-visitor-keys: 3.4.3 dev: true - /@typescript-eslint/visitor-keys@6.20.0: - resolution: {integrity: sha512-E8Cp98kRe4gKHjJD4NExXKz/zOJ1A2hhZc+IMVD6i7w4yjIvh6VyuRI0gRtxAsXtoC35uGMaQ9rjI2zJaXDEAw==} + /@typescript-eslint/visitor-keys@6.21.0: + resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.20.0 + '@typescript-eslint/types': 6.21.0 eslint-visitor-keys: 3.4.3 /@ungap/structured-clone@1.2.0: @@ -5977,7 +5983,7 @@ packages: optional: true dependencies: '@vitest/utils': 1.2.2 - magic-string: 0.30.6 + magic-string: 0.30.7 playwright: 1.41.2 sirv: 2.0.4 vitest: 1.2.2(@types/node@20.11.16)(@vitest/browser@1.2.2)(jsdom@24.0.0) @@ -5999,7 +6005,7 @@ packages: /@vitest/snapshot@1.2.2: resolution: {integrity: sha512-SmGY4saEw1+bwE1th6S/cZmPxz/Q4JWsl7LvbQIky2tKE35US4gd0Mjzqfr84/4OD0tikGWaWdMja/nWL5NIPA==} dependencies: - magic-string: 0.30.6 + magic-string: 0.30.7 pathe: 1.1.2 pretty-format: 29.7.0 @@ -6503,7 +6509,7 @@ packages: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 is-array-buffer: 3.0.4 /array-flatten@1.1.1: @@ -6518,10 +6524,10 @@ packages: resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 - get-intrinsic: 1.2.3 + get-intrinsic: 1.2.4 is-string: 1.0.7 dev: false @@ -6533,29 +6539,29 @@ packages: resolution: {integrity: sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 es-array-method-boxes-properly: 1.0.0 is-string: 1.0.7 dev: false - /array.prototype.findlastindex@1.2.3: - resolution: {integrity: sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==} + /array.prototype.findlastindex@1.2.4: + resolution: {integrity: sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 + es-errors: 1.3.0 es-shim-unscopables: 1.0.2 - get-intrinsic: 1.2.3 dev: false /array.prototype.flat@1.3.2: resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 es-shim-unscopables: 1.0.2 @@ -6565,7 +6571,7 @@ packages: resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 es-shim-unscopables: 1.0.2 @@ -6574,7 +6580,7 @@ packages: /array.prototype.tosorted@1.1.3: resolution: {integrity: sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 es-errors: 1.3.0 @@ -6586,11 +6592,11 @@ packages: engines: {node: '>= 0.4'} dependencies: array-buffer-byte-length: 1.0.1 - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 es-errors: 1.3.0 - get-intrinsic: 1.2.3 + get-intrinsic: 1.2.4 is-array-buffer: 3.0.4 is-shared-array-buffer: 1.0.2 dev: false @@ -6611,7 +6617,7 @@ packages: /assert@2.1.0: resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 is-nan: 1.3.2 object-is: 1.1.5 object.assign: 4.1.5 @@ -6666,7 +6672,7 @@ packages: /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - /autoprefixer@10.4.17(postcss@8.4.33): + /autoprefixer@10.4.17(postcss@8.4.34): resolution: {integrity: sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==} engines: {node: ^10 || ^12 || >=14} hasBin: true @@ -6678,7 +6684,7 @@ packages: fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.0 - postcss: 8.4.33 + postcss: 8.4.34 postcss-value-parser: 4.2.0 dev: true @@ -6923,7 +6929,7 @@ packages: hasBin: true dependencies: caniuse-lite: 1.0.30001584 - electron-to-chromium: 1.4.656 + electron-to-chromium: 1.4.657 node-releases: 2.0.14 update-browserslist-db: 1.0.13(browserslist@4.22.3) dev: true @@ -6963,7 +6969,7 @@ packages: /builtins@5.0.1: resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} dependencies: - semver: 7.5.4 + semver: 7.6.0 dev: true /bytes@3.0.0: @@ -7000,11 +7006,13 @@ packages: dev: true optional: true - /call-bind@1.0.5: - resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} + /call-bind@1.0.6: + resolution: {integrity: sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==} + engines: {node: '>= 0.4'} dependencies: + es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.3 + get-intrinsic: 1.2.4 set-function-length: 1.2.0 /call-me-maybe@1.0.2: @@ -7655,14 +7663,14 @@ packages: webpack: optional: true dependencies: - icss-utils: 5.1.0(postcss@8.4.33) - postcss: 8.4.33 - postcss-modules-extract-imports: 3.0.0(postcss@8.4.33) - postcss-modules-local-by-default: 4.0.4(postcss@8.4.33) - postcss-modules-scope: 3.1.1(postcss@8.4.33) - postcss-modules-values: 4.0.0(postcss@8.4.33) + icss-utils: 5.1.0(postcss@8.4.34) + postcss: 8.4.34 + postcss-modules-extract-imports: 3.0.0(postcss@8.4.34) + postcss-modules-local-by-default: 4.0.4(postcss@8.4.34) + postcss-modules-scope: 3.1.1(postcss@8.4.34) + postcss-modules-values: 4.0.0(postcss@8.4.34) postcss-value-parser: 4.2.0 - semver: 7.5.4 + semver: 7.6.0 webpack: 5.90.1(webpack-cli@5.1.4) dev: true @@ -7798,9 +7806,9 @@ packages: engines: {node: '>= 0.4'} dependencies: array-buffer-byte-length: 1.0.1 - call-bind: 1.0.5 + call-bind: 1.0.6 es-get-iterator: 1.1.3 - get-intrinsic: 1.2.3 + get-intrinsic: 1.2.4 is-arguments: 1.1.1 is-array-buffer: 3.0.4 is-date-object: 1.0.5 @@ -7843,11 +7851,12 @@ packages: clone: 1.0.4 dev: true - /define-data-property@1.1.1: - resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} + /define-data-property@1.1.2: + resolution: {integrity: sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 gopd: 1.0.1 has-property-descriptors: 1.0.1 @@ -7860,7 +7869,7 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.1 + define-data-property: 1.1.2 has-property-descriptors: 1.0.1 object-keys: 1.1.1 @@ -8107,8 +8116,8 @@ packages: jake: 10.8.7 dev: true - /electron-to-chromium@1.4.656: - resolution: {integrity: sha512-9AQB5eFTHyR3Gvt2t/NwR0le2jBSUNwCnMbUCejFWHD+so4tH40/dRLgoE+jxlPeWS43XJewyvCv+I8LPMl49Q==} + /electron-to-chromium@1.4.657: + resolution: {integrity: sha512-On2ymeleg6QbRuDk7wNgDdXtNqlJLM2w4Agx1D/RiTmItiL+a9oq5p7HUa2ZtkAtGBe/kil2dq/7rPfkbe0r5w==} dev: true /emoji-regex@8.0.0: @@ -8196,19 +8205,19 @@ packages: array-buffer-byte-length: 1.0.1 arraybuffer.prototype.slice: 1.0.3 available-typed-arrays: 1.0.6 - call-bind: 1.0.5 + call-bind: 1.0.6 es-set-tostringtag: 2.0.2 es-to-primitive: 1.2.1 function.prototype.name: 1.1.6 - get-intrinsic: 1.2.3 - get-symbol-description: 1.0.0 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.1 globalthis: 1.0.3 gopd: 1.0.1 has-property-descriptors: 1.0.1 has-proto: 1.0.1 has-symbols: 1.0.3 hasown: 2.0.0 - internal-slot: 1.0.6 + internal-slot: 1.0.7 is-array-buffer: 3.0.4 is-callable: 1.2.7 is-negative-zero: 2.0.2 @@ -8245,8 +8254,8 @@ packages: /es-get-iterator@1.1.3: resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.3 + call-bind: 1.0.6 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 is-arguments: 1.1.1 is-map: 2.0.2 @@ -8260,17 +8269,17 @@ packages: resolution: {integrity: sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==} dependencies: asynciterator.prototype: 1.0.0 - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 es-set-tostringtag: 2.0.2 function-bind: 1.1.2 - get-intrinsic: 1.2.3 + get-intrinsic: 1.2.4 globalthis: 1.0.3 has-property-descriptors: 1.0.1 has-proto: 1.0.1 has-symbols: 1.0.3 - internal-slot: 1.0.6 + internal-slot: 1.0.7 iterator.prototype: 1.1.2 safe-array-concat: 1.1.0 dev: false @@ -8287,7 +8296,7 @@ packages: resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.3 + get-intrinsic: 1.2.4 has-tostringtag: 1.0.2 hasown: 2.0.0 dev: false @@ -8382,8 +8391,8 @@ packages: '@esbuild/win32-ia32': 0.19.12 '@esbuild/win32-x64': 0.19.12 - /escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + /escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} engines: {node: '>=6'} dev: true @@ -8446,11 +8455,11 @@ packages: dependencies: '@next/eslint-plugin-next': 14.1.0 '@rushstack/eslint-patch': 1.7.2 - '@typescript-eslint/parser': 6.20.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.20.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.20.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.56.0) eslint-plugin-react: 7.33.2(eslint@8.56.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.56.0) @@ -8488,7 +8497,7 @@ packages: - supports-color dev: false - /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.20.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0): + /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0): resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -8498,8 +8507,8 @@ packages: debug: 4.3.4 enhanced-resolve: 5.15.0 eslint: 8.56.0 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.20.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.20.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) fast-glob: 3.3.2 get-tsconfig: 4.7.2 is-core-module: 2.13.1 @@ -8511,7 +8520,7 @@ packages: - supports-color dev: false - /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.20.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0): + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -8532,16 +8541,16 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 6.20.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) debug: 3.2.7 eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.20.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0) transitivePeerDependencies: - supports-color dev: false - /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.20.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0): + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0): resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} peerDependencies: @@ -8551,16 +8560,16 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 6.20.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) array-includes: 3.1.7 - array.prototype.findlastindex: 1.2.3 + array.prototype.findlastindex: 1.2.4 array.prototype.flat: 1.3.2 array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.20.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) hasown: 2.0.0 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -8659,14 +8668,14 @@ packages: - typescript dev: true - /eslint-plugin-tailwindcss@3.14.1(tailwindcss@3.4.1): - resolution: {integrity: sha512-orNkVzJ1fdCkj5d8AHE3tAbixNpMJRoKoHPnxZbZ6iBHTsNvOEmeBz62C3THPhFnXCXaD55SRbNjqGzMEXRoZA==} + /eslint-plugin-tailwindcss@3.14.2(tailwindcss@3.4.1): + resolution: {integrity: sha512-fNzdf4poZP2yQC0xC2prQxMuArMSb5mnellLQvwb9HC3NcLzxs+0IVKWIg1BqUqyui0c+bbjMmhWcKUWK67SLQ==} engines: {node: '>=12.13.0'} peerDependencies: tailwindcss: ^3.4.0 dependencies: fast-glob: 3.3.2 - postcss: 8.4.33 + postcss: 8.4.34 tailwindcss: 3.4.1 dev: false @@ -8679,7 +8688,7 @@ packages: eslint: 8.56.0 dev: false - /eslint-plugin-vitest@0.3.21(@typescript-eslint/eslint-plugin@6.20.0)(eslint@8.56.0)(typescript@5.3.3): + /eslint-plugin-vitest@0.3.21(@typescript-eslint/eslint-plugin@6.21.0)(eslint@8.56.0)(typescript@5.3.3): resolution: {integrity: sha512-oYwR1MrwaBw/OG6CKU+SJYleAc442w6CWL1RTQl5WLwy8X3sh0bgHIQk5iEtmTak3Q+XAvZglr0bIoDOjFdkcw==} engines: {node: ^18.0.0 || >= 20.0.0} peerDependencies: @@ -8692,8 +8701,8 @@ packages: vitest: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 6.20.0(@typescript-eslint/parser@6.20.0)(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/utils': 6.20.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.56.0)(typescript@5.3.3) eslint: 8.56.0 transitivePeerDependencies: - supports-color @@ -8890,7 +8899,7 @@ packages: pump: 3.0.0 qs: 6.11.2 raw-body: 2.5.2 - semver: 7.5.4 + semver: 7.6.0 transitivePeerDependencies: - supports-color dev: true @@ -9001,8 +9010,8 @@ packages: engines: {node: '>= 4.9.1'} dev: true - /fastq@1.17.0: - resolution: {integrity: sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w==} + /fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} dependencies: reusify: 1.0.4 @@ -9216,7 +9225,7 @@ packages: proxy-agent: 6.3.1 retry: 0.13.1 rimraf: 3.0.2 - semver: 7.5.4 + semver: 7.6.0 stream-chain: 2.2.5 stream-json: 1.8.0 strip-ansi: 6.0.1 @@ -9415,7 +9424,7 @@ packages: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 functions-have-names: 1.2.3 @@ -9501,8 +9510,8 @@ packages: /get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - /get-intrinsic@1.2.3: - resolution: {integrity: sha512-JIcZczvcMVE7AUOP+X72bh8HqHBRxFdz5PDHYtNG/lE3yk9b3KZBJlwFcTyPYjg3L4RLLmZJzvjxhaZVapxFrQ==} + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} dependencies: es-errors: 1.3.0 @@ -9539,12 +9548,12 @@ packages: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} - /get-symbol-description@1.0.0: - resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + /get-symbol-description@1.0.1: + resolution: {integrity: sha512-KmuibvwbWaM4BHcBRYwJfZ1JxyJeBwB8ct9YYu67SvYdbEIlcQ2e56dHxfbobqW38GXo8/zDFqJeGtHiVbWyQw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.3 + call-bind: 1.0.6 + es-errors: 1.3.0 dev: false /get-tsconfig@4.7.2: @@ -9795,7 +9804,7 @@ packages: /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: - get-intrinsic: 1.2.3 + get-intrinsic: 1.2.4 /graceful-fs@4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} @@ -9879,7 +9888,7 @@ packages: /has-property-descriptors@1.0.1: resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} dependencies: - get-intrinsic: 1.2.3 + get-intrinsic: 1.2.4 /has-proto@1.0.1: resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} @@ -10070,13 +10079,13 @@ packages: postcss: 7.0.39 dev: true - /icss-utils@5.1.0(postcss@8.4.33): + /icss-utils@5.1.0(postcss@8.4.34): resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.33 + postcss: 8.4.34 dev: true /idb@8.0.0: @@ -10189,11 +10198,11 @@ packages: dev: true optional: true - /internal-slot@1.0.6: - resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} + /internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.3 + es-errors: 1.3.0 hasown: 2.0.0 side-channel: 1.0.4 @@ -10234,7 +10243,7 @@ packages: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 has-tostringtag: 1.0.2 dev: true @@ -10242,8 +10251,8 @@ packages: resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.3 + call-bind: 1.0.6 + get-intrinsic: 1.2.4 /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -10275,7 +10284,7 @@ packages: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 has-tostringtag: 1.0.2 /is-callable@1.2.7: @@ -10317,7 +10326,7 @@ packages: /is-finalizationregistry@1.0.2: resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 dev: false /is-fullwidth-code-point@3.0.0: @@ -10374,7 +10383,7 @@ packages: resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 dev: true @@ -10431,7 +10440,7 @@ packages: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 has-tostringtag: 1.0.2 /is-set@2.0.2: @@ -10440,7 +10449,7 @@ packages: /is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 /is-stream-ended@0.1.4: resolution: {integrity: sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==} @@ -10498,14 +10507,14 @@ packages: /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 dev: false /is-weakset@2.0.2: resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.3 + call-bind: 1.0.6 + get-intrinsic: 1.2.4 /is-wsl@1.1.0: resolution: {integrity: sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==} @@ -10594,7 +10603,7 @@ packages: resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} dependencies: define-properties: 1.2.1 - get-intrinsic: 1.2.3 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 reflect.getprototypeof: 1.0.5 set-function-name: 2.0.1 @@ -10899,7 +10908,7 @@ packages: lodash.isstring: 4.0.1 lodash.once: 4.1.1 ms: 2.1.3 - semver: 7.5.4 + semver: 7.6.0 dev: true /jsx-ast-utils@3.3.5: @@ -11259,8 +11268,8 @@ packages: engines: {node: '>=12'} dev: true - /lucide-react@0.321.0(react@18.2.0): - resolution: {integrity: sha512-Fi9VahIna6642U+2nAGSjnXwUBV3WyfFFPQq4yi3w30jtqxDLfSyiYCtCYCYQZ2KWNZc1MDI+rcsa0t+ChdYpw==} + /lucide-react@0.323.0(react@18.2.0): + resolution: {integrity: sha512-rTXZFILl2Y4d1SG9p1Mdcf17AcPvPvpc/egFIzUrp7IUy60MUQo3Oi1mu8LGYXUVwuRZYsSMt3csHRW5mAovJg==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 dependencies: @@ -11279,8 +11288,8 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /magic-string@0.30.6: - resolution: {integrity: sha512-n62qCLbPjNjyo+owKtveQxZFZTBm+Ms6YoGD23Wew6Vw337PElFNifQpknPruVRQV57kVShPnLGo9vWxVhpPvA==} + /magic-string@0.30.7: + resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==} engines: {node: '>=12'} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 @@ -11309,7 +11318,7 @@ packages: engines: {node: ^16.14.0 || >=18.0.0} requiresBuild: true dependencies: - '@npmcli/agent': 2.2.0 + '@npmcli/agent': 2.2.1 cacache: 18.0.2 http-cache-semantics: 4.1.1 is-lambda: 1.0.1 @@ -11739,7 +11748,7 @@ packages: make-fetch-happen: 13.0.0 nopt: 7.2.0 proc-log: 3.0.0 - semver: 7.5.4 + semver: 7.6.0 tar: 6.2.0 which: 4.0.0 transitivePeerDependencies: @@ -11857,7 +11866,7 @@ packages: resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 dev: true @@ -11869,7 +11878,7 @@ packages: resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 @@ -11878,7 +11887,7 @@ packages: resolution: {integrity: sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 dev: false @@ -11887,7 +11896,7 @@ packages: resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 dev: false @@ -11896,7 +11905,7 @@ packages: resolution: {integrity: sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==} dependencies: array.prototype.filter: 1.0.3 - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 es-errors: 1.3.0 @@ -11913,7 +11922,7 @@ packages: resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 dev: false @@ -12354,27 +12363,27 @@ packages: - supports-color dev: true - /postcss-import@15.1.0(postcss@8.4.33): + /postcss-import@15.1.0(postcss@8.4.34): resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} peerDependencies: postcss: ^8.0.0 dependencies: - postcss: 8.4.33 + postcss: 8.4.34 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.8 - /postcss-js@4.0.1(postcss@8.4.33): + /postcss-js@4.0.1(postcss@8.4.34): resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 dependencies: camelcase-css: 2.0.1 - postcss: 8.4.33 + postcss: 8.4.34 - /postcss-load-config@4.0.2(postcss@8.4.33): + /postcss-load-config@4.0.2(postcss@8.4.34): resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} engines: {node: '>= 14'} peerDependencies: @@ -12387,7 +12396,7 @@ packages: optional: true dependencies: lilconfig: 3.0.0 - postcss: 8.4.33 + postcss: 8.4.34 yaml: 2.3.4 /postcss-loader@4.3.0(postcss@7.0.39)(webpack@5.90.1): @@ -12402,11 +12411,11 @@ packages: loader-utils: 2.0.4 postcss: 7.0.39 schema-utils: 3.3.0 - semver: 7.5.4 + semver: 7.6.0 webpack: 5.90.1(esbuild@0.18.20) dev: true - /postcss-loader@8.1.0(postcss@8.4.33)(typescript@5.3.3)(webpack@5.90.1): + /postcss-loader@8.1.0(postcss@8.4.34)(typescript@5.3.3)(webpack@5.90.1): resolution: {integrity: sha512-AbperNcX3rlob7Ay7A/HQcrofug1caABBkopoFeOQMspZBqcqj6giYn1Bwey/0uiOPAcR+NQD0I2HC7rXzk91w==} engines: {node: '>= 18.12.0'} peerDependencies: @@ -12421,8 +12430,8 @@ packages: dependencies: cosmiconfig: 9.0.0(typescript@5.3.3) jiti: 1.21.0 - postcss: 8.4.33 - semver: 7.5.4 + postcss: 8.4.34 + semver: 7.6.0 webpack: 5.90.1(webpack-cli@5.1.4) transitivePeerDependencies: - typescript @@ -12435,13 +12444,13 @@ packages: postcss: 7.0.39 dev: true - /postcss-modules-extract-imports@3.0.0(postcss@8.4.33): + /postcss-modules-extract-imports@3.0.0(postcss@8.4.34): resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.33 + postcss: 8.4.34 dev: true /postcss-modules-local-by-default@3.0.3: @@ -12454,14 +12463,14 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-modules-local-by-default@4.0.4(postcss@8.4.33): + /postcss-modules-local-by-default@4.0.4(postcss@8.4.34): resolution: {integrity: sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - icss-utils: 5.1.0(postcss@8.4.33) - postcss: 8.4.33 + icss-utils: 5.1.0(postcss@8.4.34) + postcss: 8.4.34 postcss-selector-parser: 6.0.15 postcss-value-parser: 4.2.0 dev: true @@ -12474,13 +12483,13 @@ packages: postcss-selector-parser: 6.0.15 dev: true - /postcss-modules-scope@3.1.1(postcss@8.4.33): + /postcss-modules-scope@3.1.1(postcss@8.4.34): resolution: {integrity: sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.33 + postcss: 8.4.34 postcss-selector-parser: 6.0.15 dev: true @@ -12491,23 +12500,23 @@ packages: postcss: 7.0.39 dev: true - /postcss-modules-values@4.0.0(postcss@8.4.33): + /postcss-modules-values@4.0.0(postcss@8.4.34): resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - icss-utils: 5.1.0(postcss@8.4.33) - postcss: 8.4.33 + icss-utils: 5.1.0(postcss@8.4.34) + postcss: 8.4.34 dev: true - /postcss-nested@6.0.1(postcss@8.4.33): + /postcss-nested@6.0.1(postcss@8.4.34): resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.2.14 dependencies: - postcss: 8.4.33 + postcss: 8.4.34 postcss-selector-parser: 6.0.15 /postcss-selector-parser@6.0.15: @@ -12537,8 +12546,8 @@ packages: source-map-js: 1.0.2 dev: false - /postcss@8.4.33: - resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==} + /postcss@8.4.34: + resolution: {integrity: sha512-4eLTO36woPSocqZ1zIrFD2K1v6wH7pY1uBh0JIM2KKfrVtGvPFiAku6aNOP0W1Wr9qwnaCsF0Z+CrVnryB2A8Q==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.7 @@ -12677,7 +12686,7 @@ packages: jsdoc: 4.0.2 minimist: 1.2.8 protobufjs: 7.2.4 - semver: 7.5.4 + semver: 7.6.0 tmp: 0.2.1 uglify-js: 3.17.4 dev: true @@ -12967,7 +12976,7 @@ packages: /react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - /react-json-view@1.21.3(@types/react@18.2.53)(react-dom@18.2.0)(react@18.2.0): + /react-json-view@1.21.3(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-13p8IREj9/x/Ye4WI/JpjhoIwuzEgUAtgJZNBJckfzJt1qyh24BdTm6UQNGnyTq9dapQdrqvquZTo3dz1X6Cjw==} peerDependencies: react: ^17.0.0 || ^16.3.0 || ^15.5.4 @@ -12978,7 +12987,7 @@ packages: react-base16-styling: 0.6.0 react-dom: 18.2.0(react@18.2.0) react-lifecycles-compat: 3.0.4 - react-textarea-autosize: 8.5.3(@types/react@18.2.53)(react@18.2.0) + react-textarea-autosize: 8.5.3(@types/react@18.2.55)(react@18.2.0) transitivePeerDependencies: - '@types/react' - encoding @@ -13006,7 +13015,7 @@ packages: engines: {node: '>=0.10.0'} dev: true - /react-remove-scroll-bar@2.3.4(@types/react@18.2.53)(react@18.2.0): + /react-remove-scroll-bar@2.3.4(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} engines: {node: '>=10'} peerDependencies: @@ -13016,12 +13025,12 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.53 + '@types/react': 18.2.55 react: 18.2.0 - react-style-singleton: 2.2.1(@types/react@18.2.53)(react@18.2.0) + react-style-singleton: 2.2.1(@types/react@18.2.55)(react@18.2.0) tslib: 2.6.2 - /react-remove-scroll@2.5.5(@types/react@18.2.53)(react@18.2.0): + /react-remove-scroll@2.5.5(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==} engines: {node: '>=10'} peerDependencies: @@ -13031,13 +13040,13 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.53 + '@types/react': 18.2.55 react: 18.2.0 - react-remove-scroll-bar: 2.3.4(@types/react@18.2.53)(react@18.2.0) - react-style-singleton: 2.2.1(@types/react@18.2.53)(react@18.2.0) + react-remove-scroll-bar: 2.3.4(@types/react@18.2.55)(react@18.2.0) + react-style-singleton: 2.2.1(@types/react@18.2.55)(react@18.2.0) tslib: 2.6.2 - use-callback-ref: 1.3.1(@types/react@18.2.53)(react@18.2.0) - use-sidecar: 1.1.2(@types/react@18.2.53)(react@18.2.0) + use-callback-ref: 1.3.1(@types/react@18.2.55)(react@18.2.0) + use-sidecar: 1.1.2(@types/react@18.2.55)(react@18.2.0) /react-router-dom@6.22.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-z2w+M4tH5wlcLmH3BMMOMdrtrJ9T3oJJNsAlBJbwk+8Syxd5WFJ7J5dxMEW0/GEXD1BBis4uXRrNIz3mORr0ag==} @@ -13070,7 +13079,7 @@ packages: react: 18.2.0 dev: false - /react-style-singleton@2.2.1(@types/react@18.2.53)(react@18.2.0): + /react-style-singleton@2.2.1(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} engines: {node: '>=10'} peerDependencies: @@ -13080,13 +13089,13 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.53 + '@types/react': 18.2.55 get-nonce: 1.0.1 invariant: 2.2.4 react: 18.2.0 tslib: 2.6.2 - /react-textarea-autosize@8.5.3(@types/react@18.2.53)(react@18.2.0): + /react-textarea-autosize@8.5.3(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ==} engines: {node: '>=10'} peerDependencies: @@ -13095,7 +13104,7 @@ packages: '@babel/runtime': 7.23.9 react: 18.2.0 use-composed-ref: 1.3.0(react@18.2.0) - use-latest: 1.2.1(@types/react@18.2.53)(react@18.2.0) + use-latest: 1.2.1(@types/react@18.2.55)(react@18.2.0) transitivePeerDependencies: - '@types/react' dev: false @@ -13210,11 +13219,11 @@ packages: resolution: {integrity: sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 es-errors: 1.3.0 - get-intrinsic: 1.2.3 + get-intrinsic: 1.2.4 globalthis: 1.0.3 which-builtin-type: 1.1.3 dev: false @@ -13243,7 +13252,7 @@ packages: resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 set-function-name: 2.0.1 @@ -13516,8 +13525,8 @@ packages: resolution: {integrity: sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==} engines: {node: '>=0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.3 + call-bind: 1.0.6 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 isarray: 2.0.5 dev: false @@ -13534,8 +13543,8 @@ packages: resolution: {integrity: sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.3 + call-bind: 1.0.6 + get-intrinsic: 1.2.4 is-regex: 1.1.4 dev: false @@ -13602,8 +13611,8 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - /semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + /semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} engines: {node: '>=10'} hasBin: true dependencies: @@ -13663,9 +13672,9 @@ packages: resolution: {integrity: sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.1 + define-data-property: 1.1.2 function-bind: 1.1.2 - get-intrinsic: 1.2.3 + get-intrinsic: 1.2.4 gopd: 1.0.1 has-property-descriptors: 1.0.1 @@ -13673,7 +13682,7 @@ packages: resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.1 + define-data-property: 1.1.2 functions-have-names: 1.2.3 has-property-descriptors: 1.0.1 @@ -13721,8 +13730,8 @@ packages: /side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.3 + call-bind: 1.0.6 + get-intrinsic: 1.2.4 object-inspect: 1.13.1 /siginfo@2.0.0: @@ -13879,7 +13888,7 @@ packages: resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} engines: {node: '>= 0.4'} dependencies: - internal-slot: 1.0.6 + internal-slot: 1.0.7 dev: true /store2@2.14.2: @@ -13933,12 +13942,12 @@ packages: /string.prototype.matchall@4.0.10: resolution: {integrity: sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 - get-intrinsic: 1.2.3 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 - internal-slot: 1.0.6 + internal-slot: 1.0.7 regexp.prototype.flags: 1.5.1 set-function-name: 2.0.1 side-channel: 1.0.4 @@ -13948,7 +13957,7 @@ packages: resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 dev: false @@ -13956,7 +13965,7 @@ packages: /string.prototype.trimend@1.0.7: resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 dev: false @@ -13964,7 +13973,7 @@ packages: /string.prototype.trimstart@1.0.7: resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 define-properties: 1.2.1 es-abstract: 1.22.3 dev: false @@ -14202,11 +14211,11 @@ packages: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.0.0 - postcss: 8.4.33 - postcss-import: 15.1.0(postcss@8.4.33) - postcss-js: 4.0.1(postcss@8.4.33) - postcss-load-config: 4.0.2(postcss@8.4.33) - postcss-nested: 6.0.1(postcss@8.4.33) + postcss: 8.4.34 + postcss-import: 15.1.0(postcss@8.4.34) + postcss-js: 4.0.1(postcss@8.4.34) + postcss-load-config: 4.0.2(postcss@8.4.34) + postcss-nested: 6.0.1(postcss@8.4.34) postcss-selector-parser: 6.0.15 resolve: 1.22.8 sucrase: 3.35.0 @@ -14488,9 +14497,9 @@ packages: engines: {node: '>= 14.0.0'} dev: true - /ts-api-utils@1.0.3(typescript@5.3.3): - resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} - engines: {node: '>=16.13.0'} + /ts-api-utils@1.2.0(typescript@5.3.3): + resolution: {integrity: sha512-d+3WxW4r8WQy2cZWpNRPPGExX8ffOLGcIhheUANKbL5Sqjbhkneki76fRAWeXkaslV2etTb4tSJBSxOsH5+CJw==} + engines: {node: '>=18'} peerDependencies: typescript: '>=4.2.0' dependencies: @@ -14514,7 +14523,7 @@ packages: chalk: 4.1.2 enhanced-resolve: 5.15.0 micromatch: 4.0.5 - semver: 7.5.4 + semver: 7.6.0 source-map: 0.7.4 typescript: 5.3.3 webpack: 5.90.1(webpack-cli@5.1.4) @@ -14715,8 +14724,8 @@ packages: resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.3 + call-bind: 1.0.6 + get-intrinsic: 1.2.4 is-typed-array: 1.1.13 dev: false @@ -14724,7 +14733,7 @@ packages: resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.13 @@ -14735,7 +14744,7 @@ packages: engines: {node: '>= 0.4'} dependencies: available-typed-arrays: 1.0.6 - call-bind: 1.0.5 + call-bind: 1.0.6 for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.13 @@ -14744,7 +14753,7 @@ packages: /typed-array-length@1.0.4: resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 for-each: 0.3.3 is-typed-array: 1.1.13 dev: false @@ -14785,7 +14794,7 @@ packages: /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.6 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 @@ -14899,8 +14908,8 @@ packages: engines: {node: '>= 0.8'} dev: true - /unplugin@1.6.0: - resolution: {integrity: sha512-BfJEpWBu3aE/AyHx8VaNE/WgouoQxgH9baAiH82JjX8cqVyi3uJQstqwD5J+SZxIK326SZIhsSZlALXVBCknTQ==} + /unplugin@1.7.1: + resolution: {integrity: sha512-JqzORDAPxxs8ErLV4x+LL7bk5pk3YlcWqpSNsIkAZj972KzFZLClc/ekppahKkOczGkwIG6ElFgdOgOlK4tXZw==} dependencies: acorn: 8.11.3 chokidar: 3.5.3 @@ -14920,7 +14929,7 @@ packages: browserslist: '>= 4.21.0' dependencies: browserslist: 4.22.3 - escalade: 3.1.1 + escalade: 3.1.2 picocolors: 1.0.0 dev: true @@ -14948,7 +14957,7 @@ packages: pupa: 2.1.1 registry-auth-token: 5.0.2 registry-url: 5.1.0 - semver: 7.5.4 + semver: 7.6.0 semver-diff: 3.1.1 xdg-basedir: 4.0.0 transitivePeerDependencies: @@ -14980,7 +14989,7 @@ packages: querystringify: 2.2.0 requires-port: 1.0.0 - /use-callback-ref@1.3.1(@types/react@18.2.53)(react@18.2.0): + /use-callback-ref@1.3.1(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-Lg4Vx1XZQauB42Hw3kK7JM6yjVjgFmFC5/Ab797s79aARomD2nEErc4mCgM8EZrARLmmbWpi5DGCadmK50DcAQ==} engines: {node: '>=10'} peerDependencies: @@ -14990,7 +14999,7 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.53 + '@types/react': 18.2.55 react: 18.2.0 tslib: 2.6.2 @@ -15002,7 +15011,7 @@ packages: react: 18.2.0 dev: false - /use-isomorphic-layout-effect@1.1.2(@types/react@18.2.53)(react@18.2.0): + /use-isomorphic-layout-effect@1.1.2(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==} peerDependencies: '@types/react': '*' @@ -15011,11 +15020,11 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.53 + '@types/react': 18.2.55 react: 18.2.0 dev: false - /use-latest@1.2.1(@types/react@18.2.53)(react@18.2.0): + /use-latest@1.2.1(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==} peerDependencies: '@types/react': '*' @@ -15024,9 +15033,9 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.53 + '@types/react': 18.2.55 react: 18.2.0 - use-isomorphic-layout-effect: 1.1.2(@types/react@18.2.53)(react@18.2.0) + use-isomorphic-layout-effect: 1.1.2(@types/react@18.2.55)(react@18.2.0) dev: false /use-resize-observer@9.1.0(react-dom@18.2.0)(react@18.2.0): @@ -15040,7 +15049,7 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /use-sidecar@1.1.2(@types/react@18.2.53)(react@18.2.0): + /use-sidecar@1.1.2(@types/react@18.2.55)(react@18.2.0): resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} engines: {node: '>=10'} peerDependencies: @@ -15050,7 +15059,7 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.53 + '@types/react': 18.2.55 detect-node-es: 1.1.0 react: 18.2.0 tslib: 2.6.2 @@ -15182,7 +15191,7 @@ packages: dependencies: '@types/node': 20.11.16 esbuild: 0.19.12 - postcss: 8.4.33 + postcss: 8.4.34 rollup: 4.9.6 optionalDependencies: fsevents: 2.3.3 @@ -15226,7 +15235,7 @@ packages: execa: 8.0.1 jsdom: 24.0.0 local-pkg: 0.5.0 - magic-string: 0.30.6 + magic-string: 0.30.7 pathe: 1.1.2 picocolors: 1.0.0 std-env: 3.7.0 @@ -15482,7 +15491,7 @@ packages: engines: {node: '>= 0.4'} dependencies: available-typed-arrays: 1.0.6 - call-bind: 1.0.5 + call-bind: 1.0.6 for-each: 0.3.3 gopd: 1.0.1 has-tostringtag: 1.0.2 @@ -15716,7 +15725,7 @@ packages: engines: {node: '>=12'} dependencies: cliui: 8.0.1 - escalade: 3.1.1 + escalade: 3.1.2 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 @@ -15757,7 +15766,7 @@ packages: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} dev: false - /zustand@4.5.0(@types/react@18.2.53)(immer@10.0.3)(react@18.2.0): + /zustand@4.5.0(@types/react@18.2.55)(immer@10.0.3)(react@18.2.0): resolution: {integrity: sha512-zlVFqS5TQ21nwijjhJlx4f9iGrXSL0o/+Dpy4txAP22miJ8Ti6c1Ol1RLNN98BMib83lmDH/2KmLwaNXpjrO1A==} engines: {node: '>=12.7.0'} peerDependencies: @@ -15772,7 +15781,7 @@ packages: react: optional: true dependencies: - '@types/react': 18.2.53 + '@types/react': 18.2.55 immer: 10.0.3 react: 18.2.0 use-sync-external-store: 1.2.0(react@18.2.0)