diff --git a/.github/workflows/_vercel_deploy.yml b/.github/workflows/_vercel_deploy.yml index d85f6664fff..ffdb8fda37f 100644 --- a/.github/workflows/_vercel_deploy.yml +++ b/.github/workflows/_vercel_deploy.yml @@ -68,14 +68,16 @@ jobs: secrets: inherit with: isProd: false + isStaging: false - wallet-dashboard-prod: - name: Vercel Wallet Dashboard Production + wallet-dashboard-staging: + name: Vercel Wallet Dashboard Staging if: github.ref_name == 'develop' uses: ./.github/workflows/apps_wallet_dashboard_deploy.yml secrets: inherit with: - isProd: true + isProd: false + isStaging: true apps-backend-preview: name: Vercel apps-backend Preview diff --git a/.github/workflows/apps_wallet_dashboard_deploy.yml b/.github/workflows/apps_wallet_dashboard_deploy.yml index d3ae3f5f284..f533776b7bb 100644 --- a/.github/workflows/apps_wallet_dashboard_deploy.yml +++ b/.github/workflows/apps_wallet_dashboard_deploy.yml @@ -3,14 +3,25 @@ name: Deploy for Wallet Dashboard env: VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} VERCEL_PROJECT_ID: ${{ secrets.WALLET_DASHBOARD_VERCEL_PROJECT_ID }} + WALLET_DASHBOARD_VERCEL_PROJECT_STAGING_URL: ${{ secrets.WALLET_DASHBOARD_VERCEL_PROJECT_STAGING_URL }} on: workflow_dispatch: + inputs: + isProd: + type: boolean + required: true + isStaging: + type: boolean + required: true workflow_call: inputs: isProd: type: boolean required: true + isStaging: + type: boolean + required: true jobs: deploy: @@ -64,8 +75,11 @@ jobs: id: deploy_url if: ${{ inputs.isProd == false }} run: echo "DEPLOY_URL=$(cat vercel_output.txt | awk 'END{print}')" >> $GITHUB_OUTPUT + - name: Alias Staging deploy + if: ${{ inputs.isStaging }} + run: vercel alias ${{ steps.deploy_url.outputs.DEPLOY_URL }} $WALLET_DASHBOARD_VERCEL_PROJECT_STAGING_URL --token=${{ secrets.VERCEL_TOKEN }} --scope=${{ secrets.VERCEL_SCOPE }} - name: Comment on pull request - if: ${{ inputs.isProd == false }} + if: ${{ inputs.isProd == false && inputs.isStaging == false }} uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 with: github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/Cargo.lock b/Cargo.lock index c0b1c6e29bf..550aa462be0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -803,7 +803,7 @@ dependencies = [ "proc-macro2 1.0.86", "quote 1.0.37", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -5500,6 +5500,124 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -5508,12 +5626,23 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] @@ -8275,7 +8404,7 @@ version = "0.8.0-alpha" dependencies = [ "proc-macro2 1.0.86", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -8876,7 +9005,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -8972,6 +9101,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "lock_api" version = "0.4.12" @@ -10066,7 +10201,7 @@ dependencies = [ "proc-macro2 1.0.86", "quote 1.0.37", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -11040,9 +11175,9 @@ dependencies = [ [[package]] name = "passkey-authenticator" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017d27e98940a98358b43a3fe19cb3d7b7c821c3b35634d8087230e92445579" +checksum = "f9b065ce31354bcf23a333003c77f0d71f00eb95761b3390a069546e078a7a5b" dependencies = [ "async-trait", "coset", @@ -11054,9 +11189,9 @@ dependencies = [ [[package]] name = "passkey-client" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f14d42b14749cc7927add34a9932b3b3cc5349a633384850baa67183061439dd" +checksum = "5080bfafe23d139ae8be8b907453aee0b8af3ca7cf25d1f8d7bfcf7b079d3412" dependencies = [ "ciborium", "coset", @@ -11072,14 +11207,16 @@ dependencies = [ [[package]] name = "passkey-types" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "499cff8432e71c5f8784d9645aac0f9fca604d67f59b68a606170b5e229c6538" +checksum = "77144664f6aac5f629d7efa815f5098a054beeeca6ccafee5ec453fd2b0c53f9" dependencies = [ "bitflags 2.6.0", "ciborium", "coset", "data-encoding", + "getrandom 0.2.15", + "hmac", "indexmap 2.5.0", "rand 0.8.5", "serde", @@ -11087,6 +11224,7 @@ dependencies = [ "sha2 0.10.8", "strum 0.25.0", "typeshare", + "zeroize", ] [[package]] @@ -14337,6 +14475,17 @@ dependencies = [ "unicode-xid 0.2.6", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", +] + [[package]] name = "sysinfo" version = "0.31.4" @@ -14710,6 +14859,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -15338,7 +15497,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ "cfg-if", - "rand 0.8.5", + "rand 0.7.3", "static_assertions", ] @@ -15466,12 +15625,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - [[package]] name = "unicode-ident" version = "1.0.13" @@ -15563,9 +15716,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -15585,6 +15738,18 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -16218,6 +16383,18 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "ws_stream_wasm" version = "0.7.4" @@ -16328,6 +16505,30 @@ dependencies = [ "time", ] +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", + "synstructure 0.13.1", +] + [[package]] name = "yup-oauth2" version = "8.3.2" @@ -16376,6 +16577,27 @@ dependencies = [ "syn 2.0.77", ] +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", + "synstructure 0.13.1", +] + [[package]] name = "zeroize" version = "1.8.1" @@ -16397,6 +16619,28 @@ dependencies = [ "syn 2.0.77", ] +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", +] + [[package]] name = "zip" version = "0.6.6" diff --git a/Cargo.toml b/Cargo.toml index 277ac3a5492..9dbfc1385f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -284,9 +284,9 @@ object_store = { version = "0.10", features = ["aws", "gcp", "azure", "http"] } once_cell = "1.18.0" p256 = { version = "0.13.2", features = ["ecdsa"] } parking_lot = "0.12.1" -passkey-authenticator = { version = "0.2.0" } -passkey-client = { version = "0.2.0" } -passkey-types = { version = "0.2.0" } +passkey-authenticator = "0.4.0" +passkey-client = "0.4.0" +passkey-types = "0.4.0" pretty_assertions = "1.3.0" proc-macro2 = "1.0.47" prometheus = "0.13.3" diff --git a/apps/core/src/components/stake/StakedCard.tsx b/apps/core/src/components/stake/StakedCard.tsx index 58bc5c82f20..92f6b0e8184 100644 --- a/apps/core/src/components/stake/StakedCard.tsx +++ b/apps/core/src/components/stake/StakedCard.tsx @@ -37,7 +37,7 @@ export function StakedCard({ // For inactive validator, show principal + rewards const [principalStaked, symbol] = useFormatCoin( - inactiveValidator ? principal + rewards : principal, + inactiveValidator ? BigInt(principal) + rewards : principal, IOTA_TYPE_ARG, ); diff --git a/apps/core/src/components/transaction/info/UnstakeTransactionInfo.tsx b/apps/core/src/components/transaction/info/UnstakeTransactionInfo.tsx index bb69cf69226..94e120821d3 100644 --- a/apps/core/src/components/transaction/info/UnstakeTransactionInfo.tsx +++ b/apps/core/src/components/transaction/info/UnstakeTransactionInfo.tsx @@ -27,21 +27,21 @@ export function UnstakeTransactionInfo({ renderExplorerLink, }: UnstakeTransactionInfoProps) { const json = event.parsedJson as { - principal_amount?: number; - reward_amount?: number; + principal_amount?: string; + reward_amount?: string; validator_address?: string; }; - const principalAmount = json?.principal_amount || 0; - const rewardAmount = json?.reward_amount || 0; + const principalAmount = json?.principal_amount || '0'; + const rewardAmount = json?.reward_amount || '0'; const validatorAddress = json?.validator_address; - const totalAmount = Number(principalAmount) + Number(rewardAmount); + const totalAmount = BigInt(principalAmount) + BigInt(rewardAmount); const [formatPrinciple, symbol] = useFormatCoin(principalAmount, IOTA_TYPE_ARG); const [formatRewards] = useFormatCoin(rewardAmount || 0, IOTA_TYPE_ARG); return (
{validatorAddress && } - {totalAmount && ( + {totalAmount !== 0n && ( )} diff --git a/apps/core/src/hooks/useCountdownByTimestamp.ts b/apps/core/src/hooks/useCountdownByTimestamp.ts index 3b79b69b915..18a5a598292 100644 --- a/apps/core/src/hooks/useCountdownByTimestamp.ts +++ b/apps/core/src/hooks/useCountdownByTimestamp.ts @@ -9,7 +9,17 @@ import { MILLISECONDS_PER_SECOND, } from '../constants'; -export function useCountdownByTimestamp(initialTimestamp: number | null): string { +interface FormatCountdownOptions { + showSeconds?: boolean; + showMinutes?: boolean; + showHours?: boolean; + showDays?: boolean; +} + +export function useCountdownByTimestamp( + initialTimestamp: number | null, + options?: FormatCountdownOptions, +): string { const [timeRemainingMs, setTimeRemainingMs] = useState(0); useEffect(() => { @@ -22,11 +32,19 @@ export function useCountdownByTimestamp(initialTimestamp: number | null): string return () => clearInterval(interval); }, [initialTimestamp]); - const formattedCountdown = formatCountdown(timeRemainingMs); + const formattedCountdown = formatCountdown(timeRemainingMs, options); return formattedCountdown; } -function formatCountdown(totalMilliseconds: number) { +function formatCountdown( + totalMilliseconds: number, + { + showSeconds = true, + showMinutes = true, + showHours = true, + showDays = true, + }: FormatCountdownOptions = {}, +) { const days = Math.floor(totalMilliseconds / MILLISECONDS_PER_DAY); const hours = Math.floor((totalMilliseconds % MILLISECONDS_PER_DAY) / MILLISECONDS_PER_HOUR); const minutes = Math.floor( @@ -36,11 +54,11 @@ function formatCountdown(totalMilliseconds: number) { (totalMilliseconds % MILLISECONDS_PER_MINUTE) / MILLISECONDS_PER_SECOND, ); - const timeUnits = []; - if (days > 0) timeUnits.push(`${days}d`); - if (hours > 0) timeUnits.push(`${hours}h`); - if (minutes > 0) timeUnits.push(`${minutes}m`); - if (seconds > 0 || timeUnits.length === 0) timeUnits.push(`${seconds}s`); + const timeUnits: string[] = []; + if (showDays && days > 0) timeUnits.push(`${days}d`); + if (showHours && hours > 0) timeUnits.push(`${hours}h`); + if (showMinutes && minutes > 0) timeUnits.push(`${minutes}m`); + if (showSeconds && (seconds > 0 || timeUnits.length === 0)) timeUnits.push(`${seconds}s`); return timeUnits.join(' '); } diff --git a/apps/core/src/utils/getStakeIotaByIotaId.ts b/apps/core/src/utils/getStakeIotaByIotaId.ts index 5bdaa2a01ee..ba2e8837c99 100644 --- a/apps/core/src/utils/getStakeIotaByIotaId.ts +++ b/apps/core/src/utils/getStakeIotaByIotaId.ts @@ -10,7 +10,7 @@ export function getStakeIotaByIotaId(allDelegation: DelegatedStake[], stakeIotaI allDelegation.reduce((acc, curr) => { const total = BigInt( curr.stakes.find(({ stakedIotaId }) => stakedIotaId === stakeIotaId)?.principal || - 0, + 0n, ); return total + acc; }, 0n) || 0n diff --git a/apps/explorer/src/components/network/NetworkSelector.tsx b/apps/explorer/src/components/network/NetworkSelector.tsx index 34da8635f62..deb20e35e9b 100644 --- a/apps/explorer/src/components/network/NetworkSelector.tsx +++ b/apps/explorer/src/components/network/NetworkSelector.tsx @@ -99,11 +99,12 @@ export function NetworkSelector(): JSX.Element { key={idx} onClick={() => handleNetworkSwitch(network.id)} hideBottomBorder + isHighlighted={network === selectedNetwork} >
diff --git a/apps/explorer/src/pages/transaction-result/programmable-transaction-view/utils.ts b/apps/explorer/src/pages/transaction-result/programmable-transaction-view/utils.ts index 92e2e32d939..e239ce3a86e 100644 --- a/apps/explorer/src/pages/transaction-result/programmable-transaction-view/utils.ts +++ b/apps/explorer/src/pages/transaction-result/programmable-transaction-view/utils.ts @@ -24,10 +24,11 @@ export function flattenIotaArguments(data: (IotaArgument | IotaArgument[])[]): s } else if ('NestedResult' in value) { return `NestedResult(${value.NestedResult[0]}, ${value.NestedResult[1]})`; } + } else if (typeof value === 'string') { + return value; } else { throw new Error('Not a correct flattenable data'); } - return ''; }) .join(', '); } diff --git a/apps/ui-kit/package.json b/apps/ui-kit/package.json index ff323347fea..89e9785c466 100644 --- a/apps/ui-kit/package.json +++ b/apps/ui-kit/package.json @@ -66,7 +66,7 @@ "tailwindcss": "^3.3.3", "typescript": "^5.5.3", "vite": "^5.3.3", - "vite-plugin-dts": "^3.9.1", + "vite-plugin-dts": "^4.3.0", "vite-tsconfig-paths": "^4.2.0" } } diff --git a/apps/ui-kit/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx b/apps/ui-kit/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx index 569054372f2..d15da2af5de 100644 --- a/apps/ui-kit/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx +++ b/apps/ui-kit/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx @@ -57,6 +57,10 @@ interface KeyValueProps { * Reverse the KeyValue (optional). */ isReverse?: boolean; + /** + * Text shown on value hover. + */ + valueHoverTitle?: string; } export function KeyValueInfo({ @@ -72,6 +76,7 @@ export function KeyValueInfo({ onCopyError, fullwidth, isReverse = false, + valueHoverTitle, }: KeyValueProps): React.JSX.Element { const flexDirectionClass = isReverse ? 'flex-row-reverse' : 'flex-row'; async function handleCopyClick(event: React.MouseEvent) { @@ -119,6 +124,7 @@ export function KeyValueInfo({ })} > ): React.JSX.Element { function handleKeyDown(event: React.KeyboardEvent) { if ((event.key === 'Enter' || event.key === ' ') && !isDisabled && onClick) { @@ -63,7 +68,10 @@ export function ListItem({ className={cx( 'relative flex flex-row items-center justify-between px-md py-sm text-neutral-10 dark:text-neutral-92', !isDisabled && onClick ? 'cursor-pointer' : 'cursor-default', - { 'state-layer': !isDisabled }, + { + 'bg-shader-primary-dark-16 dark:bg-shader-inverted-dark-16': isHighlighted, + 'state-layer': !isDisabled, + }, )} > {children} diff --git a/apps/ui-kit/src/lib/components/atoms/loading-indicator/LoadingIndicator.tsx b/apps/ui-kit/src/lib/components/atoms/loading-indicator/LoadingIndicator.tsx index 6a0c8d5df45..86160c55771 100644 --- a/apps/ui-kit/src/lib/components/atoms/loading-indicator/LoadingIndicator.tsx +++ b/apps/ui-kit/src/lib/components/atoms/loading-indicator/LoadingIndicator.tsx @@ -18,16 +18,21 @@ export interface LoadingIndicatorProps { * The text to display next to the loading indicator. */ text?: string; + /** + * The 'data-testid' attribute value (used in e2e tests) + */ + testId?: string; } export function LoadingIndicator({ color = 'text-primary-30 dark:text-primary-80', size = 'w-5 h-5', text, + testId, }: LoadingIndicatorProps): React.JSX.Element { return (
- + {text && {text}}
); diff --git a/apps/wallet-dashboard/app/(protected)/assets/page.tsx b/apps/wallet-dashboard/app/(protected)/assets/page.tsx index ed96fe0a519..7007cc86c5c 100644 --- a/apps/wallet-dashboard/app/(protected)/assets/page.tsx +++ b/apps/wallet-dashboard/app/(protected)/assets/page.tsx @@ -29,7 +29,7 @@ export default function AssetsDashboardPage(): React.JSX.Element { const [selectedAsset, setSelectedAsset] = useState(null); const [selectedCategory, setSelectedCategory] = useState(AssetCategory.Visual); const account = useCurrentAccount(); - const { data, isFetching, fetchNextPage, hasNextPage } = useGetOwnedObjects( + const { data, isFetching, fetchNextPage, hasNextPage, refetch } = useGetOwnedObjects( account?.address, undefined, OBJECTS_PER_REQ, @@ -79,7 +79,11 @@ export default function AssetsDashboardPage(): React.JSX.Element { fetchNextPage={fetchNextPage} /> {selectedAsset && ( - setSelectedAsset(null)} asset={selectedAsset} /> + setSelectedAsset(null)} + asset={selectedAsset} + refetchAssets={refetch} + /> )}
diff --git a/apps/wallet-dashboard/app/(protected)/components/top-nav/TopNav.tsx b/apps/wallet-dashboard/app/(protected)/components/top-nav/TopNav.tsx index 2fe8eba32f3..3b802387ca8 100644 --- a/apps/wallet-dashboard/app/(protected)/components/top-nav/TopNav.tsx +++ b/apps/wallet-dashboard/app/(protected)/components/top-nav/TopNav.tsx @@ -1,18 +1,43 @@ // Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +import { SettingsDialog, useSettingsDialog } from '@/components'; import { Badge, BadgeType, Button, ButtonType } from '@iota/apps-ui-kit'; +import { ConnectButton, useIotaClientContext } from '@iota/dapp-kit'; +import { getNetwork, Network } from '@iota/iota-sdk/client'; import { ThemeSwitcher } from '@iota/core'; -import { ConnectButton } from '@iota/dapp-kit'; import { Settings } from '@iota/ui-icons'; export function TopNav() { + const { network } = useIotaClientContext(); + const { name: networkName } = getNetwork(network); + const { + isSettingsDialogOpen, + settingsDialogView, + setSettingsDialogView, + onCloseSettingsDialogClick, + onOpenSettingsDialogClick, + } = useSettingsDialog(); + return (
- + + -
); } diff --git a/apps/wallet-dashboard/app/(protected)/home/page.tsx b/apps/wallet-dashboard/app/(protected)/home/page.tsx index 61f55475702..d435d44f630 100644 --- a/apps/wallet-dashboard/app/(protected)/home/page.tsx +++ b/apps/wallet-dashboard/app/(protected)/home/page.tsx @@ -8,6 +8,7 @@ import { TransactionsOverview, StakingOverview, MigrationOverview, + SupplyIncreaseVestingOverview, } from '@/components'; import { useFeature } from '@growthbook/growthbook-react'; import { Feature } from '@iota/core'; @@ -18,12 +19,13 @@ function HomeDashboardPage(): JSX.Element { const account = useCurrentAccount(); const stardustMigrationEnabled = useFeature(Feature.StardustMigration).value; + const supplyIncreaseVestingEnabled = useFeature(Feature.SupplyIncreaseVesting).value; return (
{connectionStatus === 'connected' && account && ( <> -
+
@@ -31,12 +33,10 @@ function HomeDashboardPage(): JSX.Element {
{stardustMigrationEnabled && } -
+
-
- Vesting -
+ {supplyIncreaseVestingEnabled && }
diff --git a/apps/wallet-dashboard/app/(protected)/migrations/page.tsx b/apps/wallet-dashboard/app/(protected)/migrations/page.tsx index acc5dd6f40c..b042465c49e 100644 --- a/apps/wallet-dashboard/app/(protected)/migrations/page.tsx +++ b/apps/wallet-dashboard/app/(protected)/migrations/page.tsx @@ -6,9 +6,8 @@ import { useState, useMemo, useCallback } from 'react'; import { useQueryClient } from '@tanstack/react-query'; import clsx from 'clsx'; -import MigratePopup from '@/components/Popup/Popups/MigratePopup'; -import { useGetStardustMigratableObjects, usePopups } from '@/hooks'; -import { summarizeMigratableObjectValues, summarizeUnmigratableObjectValues } from '@/lib/utils'; +import { useGetStardustMigratableObjects } from '@/hooks'; +import { summarizeMigratableObjectValues, summarizeTimelockedObjectValues } from '@/lib/utils'; import { Button, ButtonSize, @@ -25,15 +24,14 @@ import { useCurrentAccount, useIotaClient } from '@iota/dapp-kit'; import { STARDUST_BASIC_OUTPUT_TYPE, STARDUST_NFT_OUTPUT_TYPE, useFormatCoin } from '@iota/core'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; import { StardustOutputMigrationStatus } from '@/lib/enums'; -import { MigrationObjectsPanel } from '@/components'; +import { MigrationObjectsPanel, MigrationDialog } from '@/components'; function MigrationDashboardPage(): JSX.Element { const account = useCurrentAccount(); const address = account?.address || ''; - const { openPopup, closePopup } = usePopups(); const queryClient = useQueryClient(); const iotaClient = useIotaClient(); - + const [isMigrationDialogOpen, setIsMigrationDialogOpen] = useState(false); const [selectedStardustObjectsCategory, setSelectedStardustObjectsCategory] = useState< StardustOutputMigrationStatus | undefined >(undefined); @@ -43,8 +41,8 @@ function MigrationDashboardPage(): JSX.Element { const { migratableBasicOutputs, migratableNftOutputs, - unmigratableBasicOutputs, - unmigratableNftOutputs, + timelockedBasicOutputs, + timelockedNftOutputs, } = stardustMigrationObjects || {}; const { @@ -56,9 +54,9 @@ function MigrationDashboardPage(): JSX.Element { nftOutputs: migratableNftOutputs, address, }); - const { totalUnmigratableObjects } = summarizeUnmigratableObjectValues({ - basicOutputs: unmigratableBasicOutputs, - nftOutputs: unmigratableNftOutputs, + const { totalTimelockedObjects } = summarizeTimelockedObjectValues({ + basicOutputs: timelockedBasicOutputs, + nftOutputs: timelockedNftOutputs, }); const hasMigratableObjects = @@ -108,7 +106,7 @@ function MigrationDashboardPage(): JSX.Element { const TIMELOCKED_ASSETS_CARDS: MigrationDisplayCardProps[] = [ { - title: `${totalUnmigratableObjects}`, + title: `${totalTimelockedObjects}`, subtitle: 'Time-locked', icon: Clock, }, @@ -125,23 +123,16 @@ function MigrationDashboardPage(): JSX.Element { selectedStardustObjectsCategory === StardustOutputMigrationStatus.TimeLocked ) { return [ - ...stardustMigrationObjects.unmigratableBasicOutputs, - ...stardustMigrationObjects.unmigratableNftOutputs, + ...stardustMigrationObjects.timelockedBasicOutputs, + ...stardustMigrationObjects.timelockedNftOutputs, ]; } } return []; }, [selectedStardustObjectsCategory, stardustMigrationObjects]); - function openMigratePopup(): void { - openPopup( - , - ); + function openMigrationDialog(): void { + setIsMigrationDialogOpen(true); } function handleCloseDetailsPanel() { @@ -157,6 +148,19 @@ function MigrationDashboardPage(): JSX.Element { )} >
+ {isMigrationDialogOpen && ( + + )} } @@ -212,7 +216,7 @@ function MigrationDashboardPage(): JSX.Element { disabled={ selectedStardustObjectsCategory === StardustOutputMigrationStatus.TimeLocked || - !totalUnmigratableObjects + !totalTimelockedObjects } onClick={() => setSelectedStardustObjectsCategory( diff --git a/apps/wallet-dashboard/app/(protected)/staking/page.tsx b/apps/wallet-dashboard/app/(protected)/staking/page.tsx index e33b1253b95..87f69eccffa 100644 --- a/apps/wallet-dashboard/app/(protected)/staking/page.tsx +++ b/apps/wallet-dashboard/app/(protected)/staking/page.tsx @@ -3,7 +3,6 @@ 'use client'; -import { StartStaking } from '@/components/staking-overview/StartStaking'; import { Button, ButtonSize, @@ -16,7 +15,15 @@ import { Title, TitleSize, } from '@iota/apps-ui-kit'; -import { StakeDialog, StakeDialogView } from '@/components'; +import { + StakeDialog, + StakeDialogView, + UnstakeDialog, + useUnstakeDialog, + UnstakeDialogView, + useStakeDialog, + StartStaking, +} from '@/components'; import { ExtendedDelegatedStake, formatDelegatedStake, @@ -32,8 +39,8 @@ import { useCurrentAccount, useIotaClient, useIotaClientQuery } from '@iota/dapp import { IotaSystemStateSummary } from '@iota/iota-sdk/client'; import { Info } from '@iota/ui-icons'; import { useMemo } from 'react'; -import { useStakeDialog } from '@/components/Dialogs/Staking/hooks/useStakeDialog'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; +import { IotaSignAndExecuteTransactionOutput } from '@iota/wallet-standard'; function StakingDashboardPage(): React.JSX.Element { const account = useCurrentAccount(); @@ -52,6 +59,14 @@ function StakingDashboardPage(): React.JSX.Element { handleCloseStakeDialog, handleNewStake, } = useStakeDialog(); + const { + isOpen: isUnstakeDialogOpen, + openUnstakeDialog, + defaultDialogProps, + handleClose: handleCloseUnstakeDialog, + setView: setUnstakeDialogView, + setTxDigest, + } = useUnstakeDialog(); const { data: delegatedStakeData, refetch: refetchDelegatedStakes } = useGetDelegatedStake({ address: account?.address || '', @@ -100,6 +115,34 @@ function StakingDashboardPage(): React.JSX.Element { .then(() => refetchDelegatedStakes()); } + function handleUnstakeClick() { + setStakeDialogView(undefined); + openUnstakeDialog(); + } + + function handleUnstakeDialogBack() { + setStakeDialogView(StakeDialogView.Details); + handleCloseUnstakeDialog(); + } + + function handleOnUnstakeBack(view: UnstakeDialogView): (() => void) | undefined { + if (view === UnstakeDialogView.Unstake) { + return handleUnstakeDialogBack; + } + } + + function handleOnUnstakeSuccess(tx: IotaSignAndExecuteTransactionOutput): void { + setUnstakeDialogView(UnstakeDialogView.TransactionDetails); + iotaClient + .waitForTransaction({ + digest: tx.digest, + }) + .then((tx) => { + refetchDelegatedStakes(); + setTxDigest(tx.digest); + }); + } + return ( <div className="flex justify-center"> <div className="w-3/4"> @@ -171,16 +214,27 @@ function StakingDashboardPage(): React.JSX.Element { </div> </div> </div> - <StakeDialog - stakedDetails={selectedStake} - onSuccess={handleOnStakeSuccess} - isOpen={isDialogStakeOpen} - handleClose={handleCloseStakeDialog} - view={stakeDialogView} - setView={setStakeDialogView} - selectedValidator={selectedValidator} - setSelectedValidator={setSelectedValidator} - /> + {isDialogStakeOpen && ( + <StakeDialog + stakedDetails={selectedStake} + onSuccess={handleOnStakeSuccess} + handleClose={handleCloseStakeDialog} + view={stakeDialogView} + setView={setStakeDialogView} + selectedValidator={selectedValidator} + setSelectedValidator={setSelectedValidator} + onUnstakeClick={handleUnstakeClick} + /> + )} + + {isUnstakeDialogOpen && selectedStake && ( + <UnstakeDialog + extendedStake={selectedStake} + onBack={handleOnUnstakeBack} + onSuccess={handleOnUnstakeSuccess} + {...defaultDialogProps} + /> + )} </Panel> ) : ( <div className="flex h-[270px] p-lg"> diff --git a/apps/wallet-dashboard/app/(protected)/vesting/page.tsx b/apps/wallet-dashboard/app/(protected)/vesting/page.tsx index b925d57e97c..e29d94a7fef 100644 --- a/apps/wallet-dashboard/app/(protected)/vesting/page.tsx +++ b/apps/wallet-dashboard/app/(protected)/vesting/page.tsx @@ -6,22 +6,15 @@ import { Banner, StakeDialog, - StakeDialogView, - TimelockedUnstakePopup, useStakeDialog, VestingScheduleDialog, + UnstakeDialog, + StakeDialogView, } from '@/components'; -import { useGetCurrentEpochStartTimestamp, useNotifications, usePopups } from '@/hooks'; -import { - buildSupplyIncreaseVestingSchedule, - formatDelegatedTimelockedStake, - getLatestOrEarliestSupplyIncreaseVestingPayout, - getVestingOverview, - groupTimelockedStakedObjects, - isTimelockedUnlockable, - mapTimelockObjects, - TimelockedStakedObjectsGrouped, -} from '@/lib/utils'; +import { UnstakeDialogView } from '@/components/Dialogs/unstake/enums'; +import { useUnstakeDialog } from '@/components/Dialogs/unstake/hooks'; +import { useGetSupplyIncreaseVestingObjects, useNotifications } from '@/hooks'; +import { groupTimelockedStakedObjects, TimelockedStakedObjectsGrouped } from '@/lib/utils'; import { NotificationType } from '@/stores/notificationStore'; import { useFeature } from '@growthbook/growthbook-react'; import { @@ -44,13 +37,9 @@ import { } from '@iota/apps-ui-kit'; import { Theme, - TIMELOCK_IOTA_TYPE, useFormatCoin, useGetActiveValidatorsInfo, - useGetAllOwnedObjects, - useGetTimelockedStakedObjects, useTheme, - useUnlockTimelockedObjectsTransaction, useCountdownByTimestamp, Feature, } from '@iota/core'; @@ -63,29 +52,22 @@ import { import { IotaValidatorSummary } from '@iota/iota-sdk/client'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; import { Calendar, StarHex } from '@iota/ui-icons'; -import { useQueryClient } from '@tanstack/react-query'; import { useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import { StakedTimelockObject } from '@/components'; +import { IotaSignAndExecuteTransactionOutput } from '@iota/wallet-standard'; -function VestingDashboardPage(): JSX.Element { +export default function VestingDashboardPage(): JSX.Element { + const [timelockedObjectsToUnstake, setTimelockedObjectsToUnstake] = + useState<TimelockedStakedObjectsGrouped | null>(null); const account = useCurrentAccount(); - const queryClient = useQueryClient(); + const address = account?.address || ''; const iotaClient = useIotaClient(); const router = useRouter(); const { data: system } = useIotaClientQuery('getLatestIotaSystemState'); const [isVestingScheduleDialogOpen, setIsVestingScheduleDialogOpen] = useState(false); const { addNotification } = useNotifications(); - const { openPopup, closePopup } = usePopups(); - const { data: currentEpochMs } = useGetCurrentEpochStartTimestamp(); const { data: activeValidators } = useGetActiveValidatorsInfo(); - const { data: timelockedObjects } = useGetAllOwnedObjects(account?.address || '', { - StructType: TIMELOCK_IOTA_TYPE, - }); - - const { data: timelockedStakedObjects, isLoading: istimelockedStakedObjectsLoading } = - useGetTimelockedStakedObjects(account?.address || ''); - const { mutateAsync: signAndExecuteTransaction } = useSignAndExecuteTransaction(); const { theme } = useTheme(); @@ -96,16 +78,19 @@ function VestingDashboardPage(): JSX.Element { const supplyIncreaseVestingEnabled = useFeature<boolean>(Feature.SupplyIncreaseVesting).value; - const timelockedMapped = mapTimelockObjects(timelockedObjects || []); - const timelockedstakedMapped = formatDelegatedTimelockedStake(timelockedStakedObjects || []); + const { + nextPayout, + supplyIncreaseVestingPortfolio, + supplyIncreaseVestingSchedule, + supplyIncreaseVestingMapped, + supplyIncreaseVestingStakedMapped, + isTimelockedStakedObjectsLoading, + unlockAllSupplyIncreaseVesting, + refreshStakeList, + } = useGetSupplyIncreaseVestingObjects(address); const timelockedStakedObjectsGrouped: TimelockedStakedObjectsGrouped[] = - groupTimelockedStakedObjects(timelockedstakedMapped || []); - - const vestingSchedule = getVestingOverview( - [...timelockedMapped, ...timelockedstakedMapped], - Number(currentEpochMs), - ); + groupTimelockedStakedObjects(supplyIncreaseVestingStakedMapped || []); const { isDialogStakeOpen, @@ -118,37 +103,30 @@ function VestingDashboardPage(): JSX.Element { handleNewStake, } = useStakeDialog(); - const nextPayout = getLatestOrEarliestSupplyIncreaseVestingPayout( - [...timelockedMapped, ...timelockedstakedMapped], - Number(currentEpochMs), - false, - ); - - const lastPayout = getLatestOrEarliestSupplyIncreaseVestingPayout( - [...timelockedMapped, ...timelockedstakedMapped], - Number(currentEpochMs), - true, - ); - - const vestingPortfolio = - lastPayout && buildSupplyIncreaseVestingSchedule(lastPayout, Number(currentEpochMs)); + const { + isOpen: isUnstakeDialogOpen, + openUnstakeDialog, + defaultDialogProps, + setTxDigest, + setView: setUnstakeDialogView, + } = useUnstakeDialog(); const formattedLastPayoutExpirationTime = useCountdownByTimestamp( Number(nextPayout?.expirationTimestampMs), ); const [formattedTotalVested, vestedSymbol] = useFormatCoin( - vestingSchedule.totalVested, + supplyIncreaseVestingSchedule.totalVested, IOTA_TYPE_ARG, ); const [formattedTotalLocked, lockedSymbol] = useFormatCoin( - vestingSchedule.totalLocked, + supplyIncreaseVestingSchedule.totalLocked, IOTA_TYPE_ARG, ); const [formattedAvailableClaiming, availableClaimingSymbol] = useFormatCoin( - vestingSchedule.availableClaiming, + supplyIncreaseVestingSchedule.availableClaiming, IOTA_TYPE_ARG, ); @@ -164,54 +142,33 @@ function VestingDashboardPage(): JSX.Element { } const [totalStakedFormatted, totalStakedSymbol] = useFormatCoin( - vestingSchedule.totalStaked, + supplyIncreaseVestingSchedule.totalStaked, IOTA_TYPE_ARG, ); const [totalEarnedFormatted, totalEarnedSymbol] = useFormatCoin( - vestingSchedule.totalEarned, + supplyIncreaseVestingSchedule.totalEarned, IOTA_TYPE_ARG, ); - const unlockedTimelockedObjects = timelockedMapped?.filter((timelockedObject) => - isTimelockedUnlockable(timelockedObject, Number(currentEpochMs)), - ); - const unlockedTimelockedObjectIds: string[] = - unlockedTimelockedObjects.map((timelocked) => timelocked.id.id) || []; - const { data: unlockAllTimelockedObjects } = useUnlockTimelockedObjectsTransaction( - account?.address || '', - unlockedTimelockedObjectIds, - ); - function handleOnSuccess(digest: string): void { + setTimelockedObjectsToUnstake(null); + iotaClient .waitForTransaction({ digest, }) - .then(() => { - queryClient.invalidateQueries({ - queryKey: ['get-timelocked-staked-objects', account?.address], - }); - queryClient.invalidateQueries({ - queryKey: [ - 'get-all-owned-objects', - account?.address, - { - StructType: TIMELOCK_IOTA_TYPE, - }, - ], - }); - }); + .then(refreshStakeList); } const handleCollect = () => { - if (!unlockAllTimelockedObjects?.transactionBlock) { + if (!unlockAllSupplyIncreaseVesting?.transactionBlock) { addNotification('Failed to create a Transaction', NotificationType.Error); return; } signAndExecuteTransaction( { - transaction: unlockAllTimelockedObjects.transactionBlock, + transaction: unlockAllSupplyIncreaseVesting.transactionBlock, }, { onSuccess: (tx) => { @@ -228,34 +185,29 @@ function VestingDashboardPage(): JSX.Element { }; function handleUnstake(delegatedTimelockedStake: TimelockedStakedObjectsGrouped): void { - const validatorInfo = getValidatorByAddress(delegatedTimelockedStake.validatorAddress); - if (!account || !validatorInfo) { - addNotification('Cannot create transaction', NotificationType.Error); - return; - } - - openPopup( - <TimelockedUnstakePopup - accountAddress={account.address} - delegatedStake={delegatedTimelockedStake} - validatorInfo={validatorInfo} - closePopup={closePopup} - onSuccess={handleOnSuccess} - />, - ); + setTimelockedObjectsToUnstake(delegatedTimelockedStake); + openUnstakeDialog(UnstakeDialogView.TimelockedUnstake); } - function openReceiveTokenPopup(): void { + function openReceiveTokenDialog(): void { setIsVestingScheduleDialogOpen(true); } + function handleOnSuccessUnstake(tx: IotaSignAndExecuteTransactionOutput): void { + setUnstakeDialogView(UnstakeDialogView.TransactionDetails); + iotaClient.waitForTransaction({ digest: tx.digest }).then((tx) => { + refreshStakeList(); + setTxDigest(tx.digest); + }); + } + useEffect(() => { if (!supplyIncreaseVestingEnabled) { router.push('/'); } }, [router, supplyIncreaseVestingEnabled]); - if (istimelockedStakedObjectsLoading) { + if (isTimelockedStakedObjectsLoading) { return ( <div className="flex w-full max-w-4xl items-start justify-center justify-self-center"> <LoadingIndicator /> @@ -264,152 +216,177 @@ function VestingDashboardPage(): JSX.Element { } return ( - <div className="flex w-full max-w-4xl flex-col items-stretch justify-center gap-lg justify-self-center md:flex-row"> - <div className="flex w-full flex-col gap-lg md:w-1/2"> - <Panel> - <Title title="Vesting" size={TitleSize.Medium} /> - <div className="flex flex-col gap-md p-lg pt-sm"> - <div className="flex h-24 flex-row gap-4"> - <DisplayStats - label="Total Vested" - value={formattedTotalVested} - supportingLabel={vestedSymbol} - /> - <DisplayStats - label="Total Locked" - value={formattedTotalLocked} - supportingLabel={lockedSymbol} - tooltipText="Total amount of IOTA that is still locked in your account." - tooltipPosition={TooltipPosition.Right} - /> - </div> - <Card type={CardType.Outlined}> - <CardImage type={ImageType.BgSolid} shape={ImageShape.SquareRounded}> - <StarHex className="h-5 w-5 text-primary-30 dark:text-primary-80" /> - </CardImage> - <CardBody - title={`${formattedAvailableClaiming} ${availableClaimingSymbol}`} - subtitle="Available Rewards" - /> - <CardAction - type={CardActionType.Button} - onClick={handleCollect} - title="Collect" - buttonType={ButtonType.Primary} - buttonDisabled={ - !vestingSchedule.availableClaiming || - vestingSchedule.availableClaiming === 0n - } - /> - </Card> - <Card type={CardType.Outlined}> - <CardImage type={ImageType.BgSolid} shape={ImageShape.SquareRounded}> - <Calendar className="h-5 w-5 text-primary-30 dark:text-primary-80" /> - </CardImage> - <CardBody - title={`${formattedNextPayout} ${nextPayoutSymbol}`} - subtitle={`Next payout ${ - nextPayout?.expirationTimestampMs - ? formattedLastPayoutExpirationTime - : '' - }`} - /> - <CardAction - type={CardActionType.Button} - onClick={openReceiveTokenPopup} - title="See All" - buttonType={ButtonType.Secondary} - buttonDisabled={!vestingPortfolio} - /> - </Card> - {vestingPortfolio && ( - <VestingScheduleDialog - open={isVestingScheduleDialogOpen} - setOpen={setIsVestingScheduleDialogOpen} - vestingPortfolio={vestingPortfolio} - /> - )} - </div> - </Panel> - - {timelockedstakedMapped.length === 0 ? ( - <Banner - videoSrc={videoSrc} - title="Stake Vested Tokens" - subtitle="Earn Rewards" - onButtonClick={() => handleNewStake()} - buttonText="Stake" - /> - ) : null} - </div> - - {timelockedstakedMapped.length !== 0 ? ( - <div className="flex w-full md:w-1/2"> + <> + <div className="flex w-full max-w-4xl flex-col items-stretch justify-center gap-lg justify-self-center md:flex-row"> + <div className="flex w-full flex-col gap-lg md:w-1/2"> <Panel> - <Title - title="Staked Vesting" - trailingElement={ - <Button - type={ButtonType.Primary} - text="Stake" - onClick={() => { - setStakeDialogView(StakeDialogView.SelectValidator); - }} - /> - } - /> - - <div className="flex flex-col px-lg py-sm"> - <div className="flex flex-row gap-md"> + <Title title="Vesting" size={TitleSize.Medium} /> + <div className="flex flex-col gap-md p-lg pt-sm"> + <div className="flex h-24 flex-row gap-4"> <DisplayStats - label="Your stake" - value={`${totalStakedFormatted} ${totalStakedSymbol}`} + label="Total Vested" + value={formattedTotalVested} + supportingLabel={vestedSymbol} /> <DisplayStats - label="Earned" - value={`${totalEarnedFormatted} ${totalEarnedSymbol}`} + label="Total Locked" + value={formattedTotalLocked} + supportingLabel={lockedSymbol} + tooltipText="Total amount of IOTA that is still locked in your account." + tooltipPosition={TooltipPosition.Right} /> </div> - </div> - <div className="flex flex-col px-lg py-sm"> - <div className="flex w-full flex-col items-center justify-center space-y-4 pt-4"> - {system && - timelockedStakedObjectsGrouped?.map( - (timelockedStakedObject) => { - return ( - <StakedTimelockObject - key={ - timelockedStakedObject.validatorAddress + - timelockedStakedObject.stakeRequestEpoch + - timelockedStakedObject.label - } - getValidatorByAddress={getValidatorByAddress} - timelockedStakedObject={timelockedStakedObject} - handleUnstake={handleUnstake} - currentEpoch={Number(system.epoch)} - /> - ); - }, - )} - </div> + <Card type={CardType.Outlined}> + <CardImage + type={ImageType.BgSolid} + shape={ImageShape.SquareRounded} + > + <StarHex className="h-5 w-5 text-primary-30 dark:text-primary-80" /> + </CardImage> + <CardBody + title={`${formattedAvailableClaiming} ${availableClaimingSymbol}`} + subtitle="Available Rewards" + /> + <CardAction + type={CardActionType.Button} + onClick={handleCollect} + title="Collect" + buttonType={ButtonType.Primary} + buttonDisabled={ + !supplyIncreaseVestingSchedule.availableClaiming || + supplyIncreaseVestingSchedule.availableClaiming === 0n + } + /> + </Card> + <Card type={CardType.Outlined}> + <CardImage + type={ImageType.BgSolid} + shape={ImageShape.SquareRounded} + > + <Calendar className="h-5 w-5 text-primary-30 dark:text-primary-80" /> + </CardImage> + <CardBody + title={`${formattedNextPayout} ${nextPayoutSymbol}`} + subtitle={`Next payout ${ + nextPayout?.expirationTimestampMs + ? formattedLastPayoutExpirationTime + : '' + }`} + /> + <CardAction + type={CardActionType.Button} + onClick={openReceiveTokenDialog} + title="See All" + buttonType={ButtonType.Secondary} + buttonDisabled={!supplyIncreaseVestingPortfolio} + /> + </Card> + {supplyIncreaseVestingPortfolio && ( + <VestingScheduleDialog + open={isVestingScheduleDialogOpen} + setOpen={setIsVestingScheduleDialogOpen} + vestingPortfolio={supplyIncreaseVestingPortfolio} + /> + )} </div> </Panel> + + {supplyIncreaseVestingMapped.length === 0 ? ( + <Banner + videoSrc={videoSrc} + title="Stake Vested Tokens" + subtitle="Earn Rewards" + onButtonClick={() => handleNewStake()} + buttonText="Stake" + /> + ) : null} </div> - ) : null} - <StakeDialog - isTimelockedStaking - stakedDetails={selectedStake} - onSuccess={handleOnSuccess} - isOpen={isDialogStakeOpen} - handleClose={handleCloseStakeDialog} - view={stakeDialogView} - setView={setStakeDialogView} - selectedValidator={selectedValidator} - setSelectedValidator={setSelectedValidator} - maxStakableTimelockedAmount={BigInt(vestingSchedule.availableStaking)} - /> - </div> + + {supplyIncreaseVestingMapped.length !== 0 ? ( + <div className="flex w-full md:w-1/2"> + <Panel> + <Title + title="Staked Vesting" + trailingElement={ + <Button + type={ButtonType.Primary} + text="Stake" + disabled={ + supplyIncreaseVestingSchedule.availableStaking === 0n + } + onClick={() => { + setStakeDialogView(StakeDialogView.SelectValidator); + }} + /> + } + /> + + <div className="flex flex-col px-lg py-sm"> + <div className="flex flex-row gap-md"> + <DisplayStats + label="Your stake" + value={`${totalStakedFormatted} ${totalStakedSymbol}`} + /> + <DisplayStats + label="Earned" + value={`${totalEarnedFormatted} ${totalEarnedSymbol}`} + /> + </div> + </div> + <div className="flex flex-col px-lg py-sm"> + <div className="flex w-full flex-col items-center justify-center space-y-4 pt-4"> + {system && + timelockedStakedObjectsGrouped?.map( + (timelockedStakedObject) => { + return ( + <StakedTimelockObject + key={ + timelockedStakedObject.validatorAddress + + timelockedStakedObject.stakeRequestEpoch + + timelockedStakedObject.label + } + getValidatorByAddress={ + getValidatorByAddress + } + timelockedStakedObject={ + timelockedStakedObject + } + handleUnstake={handleUnstake} + currentEpoch={Number(system.epoch)} + /> + ); + }, + )} + </div> + </div> + </Panel> + </div> + ) : null} + + {isDialogStakeOpen && ( + <StakeDialog + isTimelockedStaking + stakedDetails={selectedStake} + onSuccess={handleOnSuccess} + handleClose={handleCloseStakeDialog} + view={stakeDialogView} + setView={setStakeDialogView} + selectedValidator={selectedValidator} + setSelectedValidator={setSelectedValidator} + maxStakableTimelockedAmount={BigInt( + supplyIncreaseVestingSchedule.availableStaking, + )} + /> + )} + + {isUnstakeDialogOpen && timelockedObjectsToUnstake && ( + <UnstakeDialog + groupedTimelockedObjects={timelockedObjectsToUnstake} + onSuccess={handleOnSuccessUnstake} + {...defaultDialogProps} + /> + )} + </div> + </> ); } - -export default VestingDashboardPage; diff --git a/apps/wallet-dashboard/app/globals.css b/apps/wallet-dashboard/app/globals.css index 04c6811f389..69ca23f41f2 100644 --- a/apps/wallet-dashboard/app/globals.css +++ b/apps/wallet-dashboard/app/globals.css @@ -24,7 +24,6 @@ body { 'balance' 'staking' 'coins' - 'vesting' 'activity'; & @@ -36,13 +35,29 @@ body { height: 200px; } } - .home-page-grid-container:has(.with-migration) { + .home-page-grid-container:has(.with-vesting):not(:has(.with-migration)) { + grid-template-areas: + 'balance' + 'staking' + 'vesting' + 'coins' + 'activity'; + } + .home-page-grid-container:has(.with-migration):not(:has(.with-vesting)) { grid-template-areas: 'balance' 'staking' 'migration' 'coins' + 'activity'; + } + .home-page-grid-container:has(.with-migration):has(.with-vesting) { + grid-template-areas: + 'balance' + 'staking' + 'migration' 'vesting' + 'coins' 'activity'; } @@ -53,28 +68,56 @@ body { 'balance balance' 'staking staking' 'coins coins' + 'activity activity'; + } + .home-page-grid-container:has(.with-vesting):not(:has(.with-migration)) { + grid-template-areas: + 'balance balance' + 'staking staking' 'vesting vesting' + 'coins coins' 'activity activity'; } - .home-page-grid-container:has(.with-migration) { + .home-page-grid-container:has(.with-migration):not(:has(.with-vesting)) { grid-template-areas: 'balance balance' 'staking migration' 'coins coins' + 'activity activity'; + } + .home-page-grid-container:has(.with-migration):has(.with-vesting) { + grid-template-areas: + 'balance balance' + 'staking migration' 'vesting vesting' + 'coins coins' 'activity activity'; } } @screen md { .home-page-grid-container { + min-height: 700px; + height: calc(100vh - 140px); @apply grid-cols-3; + grid-template-areas: + 'balance staking staking' + 'coins activity activity'; + } + .home-page-grid-container:has(.with-vesting):not(:has(.with-migration)) { grid-template-areas: 'balance staking staking' 'coins vesting vesting' 'coins activity activity'; } - .home-page-grid-container:has(.with-migration) { + + .home-page-grid-container:has(.with-migration):not(:has(.with-vesting)) { + grid-template-areas: + 'balance staking migration' + 'coins activity activity'; + } + + .home-page-grid-container:has(.with-migration):has(.with-vesting) { grid-template-areas: 'balance staking migration' 'coins vesting vesting' diff --git a/apps/wallet-dashboard/app/page.tsx b/apps/wallet-dashboard/app/page.tsx index e3036bf38c2..3392c231d31 100644 --- a/apps/wallet-dashboard/app/page.tsx +++ b/apps/wallet-dashboard/app/page.tsx @@ -63,8 +63,10 @@ function HomeDashboardPage(): JSX.Element { <ConnectButton connectText="Connect" /> </div> </div> - <div className="text-body-lg text-neutral-60"> + <div className="text-center text-body-lg text-neutral-60"> © IOTA Foundation {CURRENT_YEAR} + <br /> + {process.env.NEXT_PUBLIC_DASHBOARD_REV} </div> </div> </> diff --git a/apps/wallet-dashboard/components/Dialogs/Assets/AssetDialog.tsx b/apps/wallet-dashboard/components/Dialogs/Assets/AssetDialog.tsx index ec3d8d38d11..c71390a33aa 100644 --- a/apps/wallet-dashboard/components/Dialogs/Assets/AssetDialog.tsx +++ b/apps/wallet-dashboard/components/Dialogs/Assets/AssetDialog.tsx @@ -4,17 +4,20 @@ import React, { useState } from 'react'; import { Dialog } from '@iota/apps-ui-kit'; import { FormikProvider, useFormik } from 'formik'; -import { useCurrentAccount } from '@iota/dapp-kit'; +import { useIotaClient, useCurrentAccount } from '@iota/dapp-kit'; import { createNftSendValidationSchema } from '@iota/core'; import { DetailsView, SendView } from './views'; import { IotaObjectData } from '@iota/iota-sdk/client'; import { AssetsDialogView } from './constants'; import { useCreateSendAssetTransaction, useNotifications } from '@/hooks'; import { NotificationType } from '@/stores/notificationStore'; +import { TransactionDetailsView } from '../SendToken'; +import { DialogLayout } from '../layout'; interface AssetsDialogProps { onClose: () => void; asset: IotaObjectData; + refetchAssets: () => void; } interface FormValues { @@ -25,12 +28,14 @@ const INITIAL_VALUES: FormValues = { to: '', }; -export function AssetDialog({ onClose, asset }: AssetsDialogProps): JSX.Element { +export function AssetDialog({ onClose, asset, refetchAssets }: AssetsDialogProps): JSX.Element { const [view, setView] = useState<AssetsDialogView>(AssetsDialogView.Details); const account = useCurrentAccount(); + const [digest, setDigest] = useState<string>(''); const activeAddress = account?.address ?? ''; const objectId = asset?.objectId ?? ''; const { addNotification } = useNotifications(); + const iotaClient = useIotaClient(); const validationSchema = createNftSendValidationSchema(activeAddress, objectId); const { mutation: sendAsset } = useCreateSendAssetTransaction(objectId); @@ -44,10 +49,16 @@ export function AssetDialog({ onClose, asset }: AssetsDialogProps): JSX.Element async function onSubmit(values: FormValues) { try { - await sendAsset.mutateAsync(values.to); + const executed = await sendAsset.mutateAsync(values.to); + + const tx = await iotaClient.waitForTransaction({ + digest: executed.digest, + }); + + setDigest(tx.digest); + refetchAssets(); addNotification('Transfer transaction successful', NotificationType.Success); - onClose(); - setView(AssetsDialogView.Details); + setView(AssetsDialogView.TransactionDetails); } catch { addNotification('Transfer transaction failed', NotificationType.Error); } @@ -66,16 +77,26 @@ export function AssetDialog({ onClose, asset }: AssetsDialogProps): JSX.Element } return ( <Dialog open onOpenChange={onOpenChange}> - <FormikProvider value={formik}> + <DialogLayout> <> {view === AssetsDialogView.Details && ( <DetailsView asset={asset} onClose={onOpenChange} onSend={onDetailsSend} /> )} {view === AssetsDialogView.Send && ( - <SendView asset={asset} onClose={onOpenChange} onBack={onSendViewBack} /> + <FormikProvider value={formik}> + <SendView + asset={asset} + onClose={onOpenChange} + onBack={onSendViewBack} + /> + </FormikProvider> )} + + {view === AssetsDialogView.TransactionDetails && !!digest ? ( + <TransactionDetailsView digest={digest} onClose={onOpenChange} /> + ) : null} </> - </FormikProvider> + </DialogLayout> </Dialog> ); } diff --git a/apps/wallet-dashboard/components/Dialogs/Assets/constants/AssetsDialogView.ts b/apps/wallet-dashboard/components/Dialogs/Assets/constants/AssetsDialogView.ts index 88cb34c15b1..242da33c2c3 100644 --- a/apps/wallet-dashboard/components/Dialogs/Assets/constants/AssetsDialogView.ts +++ b/apps/wallet-dashboard/components/Dialogs/Assets/constants/AssetsDialogView.ts @@ -4,4 +4,5 @@ export enum AssetsDialogView { Details = 'Details', Send = 'Send', + TransactionDetails = 'TransactionDetails', } diff --git a/apps/wallet-dashboard/components/Dialogs/Assets/views/DetailsView.tsx b/apps/wallet-dashboard/components/Dialogs/Assets/views/DetailsView.tsx index 3929ba0062f..8520d62a484 100644 --- a/apps/wallet-dashboard/components/Dialogs/Assets/views/DetailsView.tsx +++ b/apps/wallet-dashboard/components/Dialogs/Assets/views/DetailsView.tsx @@ -13,7 +13,7 @@ import { } from '@iota/apps-ui-kit'; import Link from 'next/link'; import { formatAddress } from '@iota/iota-sdk/utils'; -import { DialogLayout, DialogLayoutBody, DialogLayoutFooter } from '../../layout'; +import { DialogLayoutBody, DialogLayoutFooter } from '../../layout'; import { IotaObjectData } from '@iota/iota-sdk/client'; import { ExplorerLink } from '@/components/ExplorerLink'; import { useCurrentAccount } from '@iota/dapp-kit'; @@ -55,7 +55,7 @@ export function DetailsView({ onClose, asset, onSend }: DetailsViewProps) { } return ( - <DialogLayout> + <> <Header title="Asset" onClose={onClose} titleCentered /> <DialogLayoutBody> <div className="flex w-full flex-col items-center justify-center gap-xs"> @@ -195,6 +195,6 @@ export function DetailsView({ onClose, asset, onSend }: DetailsViewProps) { )} </div> </DialogLayoutFooter> - </DialogLayout> + </> ); } diff --git a/apps/wallet-dashboard/components/Dialogs/Assets/views/SendView.tsx b/apps/wallet-dashboard/components/Dialogs/Assets/views/SendView.tsx index b5757582c7b..3d0350478ac 100644 --- a/apps/wallet-dashboard/components/Dialogs/Assets/views/SendView.tsx +++ b/apps/wallet-dashboard/components/Dialogs/Assets/views/SendView.tsx @@ -4,7 +4,7 @@ import React from 'react'; import { AddressInput, useNftDetails } from '@iota/core'; import { useFormikContext } from 'formik'; -import { DialogLayout, DialogLayoutFooter, DialogLayoutBody } from '../../layout'; +import { DialogLayoutFooter, DialogLayoutBody } from '../../layout'; import { Button, ButtonHtmlType, @@ -33,7 +33,7 @@ export function SendView({ asset, onClose, onBack }: SendViewProps) { const { nftName, nftImageUrl } = useNftDetails(objectId, senderAddress); return ( - <DialogLayout> + <> <Header title="Send asset" onClose={onClose} titleCentered onBack={onBack} /> <DialogLayoutBody> <div className="flex w-full flex-col items-center justify-center gap-xs"> @@ -65,6 +65,6 @@ export function SendView({ asset, onClose, onBack }: SendViewProps) { onClick={submitForm} /> </DialogLayoutFooter> - </DialogLayout> + </> ); } diff --git a/apps/wallet-dashboard/components/Dialogs/MigrationDialog.tsx b/apps/wallet-dashboard/components/Dialogs/MigrationDialog.tsx new file mode 100644 index 00000000000..f1f661c2db4 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/MigrationDialog.tsx @@ -0,0 +1,176 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import React from 'react'; +import { VirtualList } from '@/components'; +import { useCurrentAccount, useSignAndExecuteTransaction } from '@iota/dapp-kit'; +import { IotaObjectData } from '@iota/iota-sdk/client'; +import { useMigrationTransaction } from '@/hooks/useMigrationTransaction'; +import { + Button, + Dialog, + Header, + InfoBox, + InfoBoxStyle, + InfoBoxType, + KeyValueInfo, + LoadingIndicator, + Panel, + Title, + TitleSize, +} from '@iota/apps-ui-kit'; +import { useGroupedMigrationObjectsByExpirationDate } from '@/hooks'; +import { Loader, Warning } from '@iota/ui-icons'; +import { DialogLayout, DialogLayoutBody, DialogLayoutFooter } from './layout'; +import { MigrationObjectDetailsCard } from '../migration/migration-object-details-card'; +import { Collapsible, useFormatCoin } from '@iota/core'; +import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; +import { summarizeMigratableObjectValues } from '@/lib/utils'; +import toast from 'react-hot-toast'; + +interface MigrationDialogProps { + basicOutputObjects: IotaObjectData[] | undefined; + nftOutputObjects: IotaObjectData[] | undefined; + onSuccess: (digest: string) => void; + setOpen: (bool: boolean) => void; + open: boolean; + isTimelocked: boolean; +} + +export function MigrationDialog({ + basicOutputObjects = [], + nftOutputObjects = [], + onSuccess, + open, + setOpen, + isTimelocked, +}: MigrationDialogProps): JSX.Element { + const account = useCurrentAccount(); + const { + data: migrateData, + isPending: isMigrationPending, + isError: isMigrationError, + } = useMigrationTransaction(account?.address || '', basicOutputObjects, nftOutputObjects); + + const { + data: resolvedObjects = [], + isLoading, + error: isGroupedMigrationError, + } = useGroupedMigrationObjectsByExpirationDate( + [...basicOutputObjects, ...nftOutputObjects], + isTimelocked, + ); + + const { mutateAsync: signAndExecuteTransaction, isPending: isSendingTransaction } = + useSignAndExecuteTransaction(); + const { totalNotOwnedStorageDepositReturnAmount } = summarizeMigratableObjectValues({ + basicOutputs: basicOutputObjects, + nftOutputs: nftOutputObjects, + address: account?.address || '', + }); + + const [gasFee, gasFeeSymbol] = useFormatCoin(migrateData?.gasBudget, IOTA_TYPE_ARG); + const [totalStorageDepositReturnAmountFormatted, totalStorageDepositReturnAmountSymbol] = + useFormatCoin(totalNotOwnedStorageDepositReturnAmount.toString(), IOTA_TYPE_ARG); + + async function handleMigrate(): Promise<void> { + if (!migrateData) return; + signAndExecuteTransaction( + { + transaction: migrateData.transaction, + }, + { + onSuccess: (tx) => { + onSuccess(tx.digest); + }, + }, + ) + .then(() => { + toast.success('Migration transaction has been sent'); + }) + .catch(() => { + toast.error('Migration transaction was not sent'); + }); + } + + return ( + <Dialog open={open} onOpenChange={setOpen}> + <DialogLayout> + <Header title="Confirmation" onClose={() => setOpen(false)} titleCentered /> + <DialogLayoutBody> + <div className="flex h-full flex-col gap-y-md overflow-y-auto"> + {isGroupedMigrationError && !isLoading && ( + <InfoBox + title="Error" + supportingText="Failed to load migration objects" + style={InfoBoxStyle.Elevated} + type={InfoBoxType.Error} + icon={<Warning />} + /> + )} + {isLoading ? ( + <LoadingIndicator text="Loading migration objects" /> + ) : ( + <> + <Collapsible + defaultOpen + render={() => ( + <Title size={TitleSize.Small} title="Assets to Migrate" /> + )} + > + <div className="h-[600px] pb-md--rs"> + <VirtualList + heightClassName="h-full" + overflowClassName="overflow-y-auto" + items={resolvedObjects} + estimateSize={() => 58} + render={(migrationObject) => ( + <MigrationObjectDetailsCard + migrationObject={migrationObject} + isTimelocked={isTimelocked} + /> + )} + /> + </div> + </Collapsible> + <Panel hasBorder> + <div className="flex flex-col gap-y-sm p-md"> + <KeyValueInfo + keyText="Legacy storage deposit" + value={totalStorageDepositReturnAmountFormatted || '-'} + supportingLabel={totalStorageDepositReturnAmountSymbol} + fullwidth + /> + <KeyValueInfo + keyText="Gas Fees" + value={gasFee || '-'} + supportingLabel={gasFeeSymbol} + fullwidth + /> + </div> + </Panel> + </> + )} + </div> + </DialogLayoutBody> + <DialogLayoutFooter> + <Button + text="Migrate" + disabled={isMigrationPending || isMigrationError || isSendingTransaction} + onClick={handleMigrate} + icon={ + isMigrationPending || isSendingTransaction ? ( + <Loader + className="h-4 w-4 animate-spin" + data-testid="loading-indicator" + /> + ) : null + } + iconAfterText + fullWidth + /> + </DialogLayoutFooter> + </DialogLayout> + </Dialog> + ); +} diff --git a/apps/wallet-dashboard/components/Dialogs/SendToken/SendTokenDialog.tsx b/apps/wallet-dashboard/components/Dialogs/SendToken/SendTokenDialog.tsx index 913e362e27d..a33f018a09c 100644 --- a/apps/wallet-dashboard/components/Dialogs/SendToken/SendTokenDialog.tsx +++ b/apps/wallet-dashboard/components/Dialogs/SendToken/SendTokenDialog.tsx @@ -13,7 +13,7 @@ import { INITIAL_VALUES } from './constants'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; import { useTransferTransactionMutation } from '@/hooks'; -interface SendCoinPopupProps { +interface SendCoinDialogProps { coin: CoinBalance; activeAddress: string; setOpen: (bool: boolean) => void; @@ -30,7 +30,7 @@ function SendTokenDialogBody({ coin, activeAddress, setOpen, -}: SendCoinPopupProps): React.JSX.Element { +}: SendCoinDialogProps): React.JSX.Element { const [step, setStep] = useState<FormStep>(FormStep.EnterValues); const [selectedCoin, setSelectedCoin] = useState<CoinBalance>(coin); const [formData, setFormData] = useState<FormDataValues>(INITIAL_VALUES); @@ -125,7 +125,7 @@ function SendTokenDialogBody({ ); } -export function SendTokenDialog(props: SendCoinPopupProps) { +export function SendTokenDialog(props: SendCoinDialogProps) { return ( <Dialog open={props.open} onOpenChange={props.setOpen}> <DialogContent containerId="overlay-portal-container" position={DialogPosition.Right}> diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/StakeDialog.tsx b/apps/wallet-dashboard/components/Dialogs/Staking/StakeDialog.tsx index 29f832afdf6..6829097f6c3 100644 --- a/apps/wallet-dashboard/components/Dialogs/Staking/StakeDialog.tsx +++ b/apps/wallet-dashboard/components/Dialogs/Staking/StakeDialog.tsx @@ -3,42 +3,28 @@ import React, { useMemo, useState } from 'react'; import { EnterAmountView, EnterTimelockedAmountView, SelectValidatorView } from './views'; -import { - useNotifications, - useNewStakeTransaction, - useGetCurrentEpochStartTimestamp, -} from '@/hooks'; import { ExtendedDelegatedStake, - GroupedTimelockObject, parseAmount, - TIMELOCK_IOTA_TYPE, useCoinMetadata, - useGetAllOwnedObjects, useGetValidatorsApy, useBalance, createValidationSchema, MIN_NUMBER_IOTA_TO_STAKE, } from '@iota/core'; import { FormikProvider, useFormik } from 'formik'; -import type { FormikHelpers } from 'formik'; -import { useCurrentAccount, useSignAndExecuteTransaction } from '@iota/dapp-kit'; +import { useCurrentAccount } from '@iota/dapp-kit'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; -import { NotificationType } from '@/stores/notificationStore'; -import { prepareObjectsForTimelockedStakingTransaction } from '@/lib/utils'; import { Dialog } from '@iota/apps-ui-kit'; -import { DetailsView, UnstakeView } from './views'; -import { FormValues } from './views/EnterAmountView'; +import { DetailsView } from './views'; import { TransactionDialogView } from '../TransactionDialog'; import { StakeDialogView } from './enums/view.enums'; -import { Transaction } from '@iota/iota-sdk/transactions'; const INITIAL_VALUES = { amount: '', }; interface StakeDialogProps { - isOpen: boolean; handleClose: () => void; view: StakeDialogView | undefined; setView: (view: StakeDialogView) => void; @@ -48,12 +34,12 @@ interface StakeDialogProps { onSuccess?: (digest: string) => void; selectedValidator?: string; setSelectedValidator?: (validator: string) => void; + onUnstakeClick?: () => void; } export function StakeDialog({ onSuccess, isTimelockedStaking, - isOpen, handleClose, view, setView, @@ -61,6 +47,7 @@ export function StakeDialog({ maxStakableTimelockedAmount, selectedValidator = '', setSelectedValidator, + onUnstakeClick, }: StakeDialogProps): JSX.Element { const account = useCurrentAccount(); const senderAddress = account?.address ?? ''; @@ -79,137 +66,69 @@ export function StakeDialog({ maxStakableTimelockedAmount ?? coinBalance, coinSymbol, coinDecimals, - view === StakeDialogView.Unstake, + false, minimumStake, ), - [maxStakableTimelockedAmount, coinBalance, coinSymbol, coinDecimals, view, minimumStake], + [maxStakableTimelockedAmount, coinBalance, coinSymbol, coinDecimals, minimumStake], ); const formik = useFormik({ initialValues: INITIAL_VALUES, validationSchema: validationSchema, - onSubmit: onSubmit, + onSubmit: () => undefined, validateOnMount: true, }); const amount = formik.values.amount || `${MIN_NUMBER_IOTA_TO_STAKE}`; const amountWithoutDecimals = parseAmount(amount, coinDecimals); - const { data: currentEpochMs } = useGetCurrentEpochStartTimestamp(); - const { data: timelockedObjects } = useGetAllOwnedObjects(senderAddress, { - StructType: TIMELOCK_IOTA_TYPE, - }); - let groupedTimelockObjects: GroupedTimelockObject[] = []; - if (isTimelockedStaking && timelockedObjects && currentEpochMs) { - groupedTimelockObjects = prepareObjectsForTimelockedStakingTransaction( - timelockedObjects, - amountWithoutDecimals, - currentEpochMs, - ); - } - - const { data: newStakeData, isLoading: isTransactionLoading } = useNewStakeTransaction( - selectedValidator, - amountWithoutDecimals, - senderAddress, - isTimelockedStaking, - groupedTimelockObjects, - ); - const { mutateAsync: signAndExecuteTransaction, isPending } = useSignAndExecuteTransaction(); - const { addNotification } = useNotifications(); const { data: rollingAverageApys } = useGetValidatorsApy(); const validators = Object.keys(rollingAverageApys ?? {}) ?? []; function handleBack(): void { - setView?.(StakeDialogView.SelectValidator); + setView(StakeDialogView.SelectValidator); } function handleValidatorSelect(validator: string): void { setSelectedValidator?.(validator); } + function setViewBasedOnStakingType() { + setView( + isTimelockedStaking + ? StakeDialogView.EnterTimelockedAmount + : StakeDialogView.EnterAmount, + ); + } + function selectValidatorHandleNext(): void { if (selectedValidator) { - setView?.( - isTimelockedStaking - ? StakeDialogView.EnterTimelockedAmount - : StakeDialogView.EnterAmount, - ); + setViewBasedOnStakingType(); } } - function detailsHandleUnstake() { - setView?.(StakeDialogView.Unstake); - } - function detailsHandleStake() { - setView?.(StakeDialogView.SelectValidator); - } - - function handleStake(): void { - if (isTimelockedStaking && groupedTimelockObjects.length === 0) { - addNotification('Invalid stake amount. Please try again.', NotificationType.Error); - return; - } - if (!newStakeData?.transaction) { - addNotification('Stake transaction was not created', NotificationType.Error); - return; + if (stakedDetails) { + setSelectedValidator?.(stakedDetails.validatorAddress); + setViewBasedOnStakingType(); } - signAndExecuteTransaction( - { - transaction: newStakeData?.transaction, - }, - { - onSuccess: (tx) => { - onSuccess?.(tx.digest); - addNotification('Stake transaction has been sent'); - setTxDigest(tx.digest); - setView?.(StakeDialogView.TransactionDetails); - }, - onError: () => { - addNotification('Stake transaction was not sent', NotificationType.Error); - }, - }, - ); } - function handleUnstake(transaction: Transaction): void { - if (!transaction) { - addNotification('Unstake transaction was not created', NotificationType.Error); - return; - } - signAndExecuteTransaction( - { - transaction: transaction, - }, - { - onSuccess: (tx) => { - onSuccess?.(tx.digest); - addNotification('Unstake transaction has been sent'); - setTxDigest(tx.digest); - setView?.(StakeDialogView.TransactionDetails); - }, - onError: () => { - addNotification('Unstake transaction was not sent', NotificationType.Error); - }, - }, - ); - } - - function onSubmit(_: FormValues, { resetForm }: FormikHelpers<FormValues>) { - handleStake(); - resetForm(); + function handleTransactionSuccess(digest: string) { + onSuccess?.(digest); + setTxDigest(digest); + setView(StakeDialogView.TransactionDetails); } return ( - <Dialog open={isOpen} onOpenChange={() => handleClose()}> + <Dialog open onOpenChange={() => handleClose()}> <FormikProvider value={formik}> <> {view === StakeDialogView.Details && stakedDetails && ( <DetailsView handleStake={detailsHandleStake} - handleUnstake={detailsHandleUnstake} + handleUnstake={onUnstakeClick} stakedDetails={stakedDetails} handleClose={handleClose} /> @@ -228,29 +147,20 @@ export function StakeDialog({ selectedValidator={selectedValidator} handleClose={handleClose} onBack={handleBack} - onStake={handleStake} - gasBudget={newStakeData?.gasBudget} - isTransactionLoading={isTransactionLoading} + amountWithoutDecimals={amountWithoutDecimals} + senderAddress={senderAddress} + onSuccess={handleTransactionSuccess} /> )} {view === StakeDialogView.EnterTimelockedAmount && ( <EnterTimelockedAmountView selectedValidator={selectedValidator} maxStakableTimelockedAmount={maxStakableTimelockedAmount ?? BigInt(0)} - hasGroupedTimelockObjects={groupedTimelockObjects.length > 0} handleClose={handleClose} onBack={handleBack} - onStake={handleStake} - gasBudget={newStakeData?.gasBudget} - isTransactionLoading={isTransactionLoading} - /> - )} - {view === StakeDialogView.Unstake && stakedDetails && ( - <UnstakeView - extendedStake={stakedDetails} - handleClose={handleClose} - onUnstake={handleUnstake} - isPending={isPending} + senderAddress={senderAddress} + onSuccess={handleTransactionSuccess} + amountWithoutDecimals={amountWithoutDecimals} /> )} {view === StakeDialogView.TransactionDetails && ( diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/enums/view.enums.ts b/apps/wallet-dashboard/components/Dialogs/Staking/enums/view.enums.ts index 1bdb66a93ed..eb4f6cf20f5 100644 --- a/apps/wallet-dashboard/components/Dialogs/Staking/enums/view.enums.ts +++ b/apps/wallet-dashboard/components/Dialogs/Staking/enums/view.enums.ts @@ -5,7 +5,6 @@ export enum StakeDialogView { Details = 'Details', SelectValidator = 'SelectValidator', EnterAmount = 'EnterAmount', - Unstake = 'Unstake', EnterTimelockedAmount = 'EnterTimelockedAmount', TransactionDetails = 'TransactionDetails', } diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/index.ts b/apps/wallet-dashboard/components/Dialogs/Staking/index.ts index bf9af6d49a4..e32885d1475 100644 --- a/apps/wallet-dashboard/components/Dialogs/Staking/index.ts +++ b/apps/wallet-dashboard/components/Dialogs/Staking/index.ts @@ -2,5 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 export * from './enums'; -export * from './StakeDialog'; export * from './hooks'; + +export * from './StakeDialog'; diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/views/DetailsView.tsx b/apps/wallet-dashboard/components/Dialogs/Staking/views/DetailsView.tsx index 0cdba0031e1..48ebf1b4f3c 100644 --- a/apps/wallet-dashboard/components/Dialogs/Staking/views/DetailsView.tsx +++ b/apps/wallet-dashboard/components/Dialogs/Staking/views/DetailsView.tsx @@ -33,11 +33,11 @@ import { formatAddress, IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; import { DialogLayout, DialogLayoutFooter, DialogLayoutBody } from '../../layout'; interface StakeDialogProps { - stakedDetails: ExtendedDelegatedStake; - showActiveStatus?: boolean; handleClose: () => void; - handleUnstake: () => void; handleStake: () => void; + stakedDetails: ExtendedDelegatedStake; + showActiveStatus?: boolean; + handleUnstake?: () => void; } export function DetailsView({ diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterAmountDialogLayout.tsx b/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterAmountDialogLayout.tsx new file mode 100644 index 00000000000..9ec233b1838 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterAmountDialogLayout.tsx @@ -0,0 +1,166 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import React from 'react'; +import { useFormatCoin, useStakeTxnInfo } from '@iota/core'; +import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; +import { + Button, + ButtonType, + KeyValueInfo, + Panel, + Divider, + Input, + InputType, + Header, + InfoBoxType, + InfoBoxStyle, + InfoBox, +} from '@iota/apps-ui-kit'; +import { Field, type FieldProps, useFormikContext } from 'formik'; +import { Exclamation, Loader } from '@iota/ui-icons'; +import { useIotaClientQuery } from '@iota/dapp-kit'; + +import { Validator } from './Validator'; +import { StakedInfo } from './StakedInfo'; +import { DialogLayout, DialogLayoutBody, DialogLayoutFooter } from '../../layout'; + +export interface FormValues { + amount: string; +} + +interface EnterAmountDialogLayoutProps { + selectedValidator: string; + senderAddress: string; + caption: string; + showInfo: boolean; + infoMessage: string; + isLoading: boolean; + onBack: () => void; + handleClose: () => void; + handleStake: () => void; + isStakeDisabled?: boolean; + gasBudget?: string | number | null; +} + +function EnterAmountDialogLayout({ + selectedValidator, + gasBudget, + senderAddress, + caption, + showInfo, + infoMessage, + isLoading, + isStakeDisabled, + onBack, + handleClose, + handleStake, +}: EnterAmountDialogLayoutProps): JSX.Element { + const { data: system } = useIotaClientQuery('getLatestIotaSystemState'); + const { values, errors } = useFormikContext<FormValues>(); + const amount = values.amount; + + const [gas, symbol] = useFormatCoin(gasBudget ?? 0, IOTA_TYPE_ARG); + + const { stakedRewardsStartEpoch, timeBeforeStakeRewardsRedeemableAgoDisplay } = useStakeTxnInfo( + system?.epoch, + ); + + return ( + <DialogLayout> + <Header title="Enter amount" onClose={handleClose} onBack={onBack} titleCentered /> + <DialogLayoutBody> + <div className="flex w-full flex-col justify-between"> + <div> + <div className="mb-md"> + <Validator address={selectedValidator} isSelected showAction={false} /> + </div> + <StakedInfo + validatorAddress={selectedValidator} + accountAddress={senderAddress} + /> + <div className="my-md w-full"> + <Field name="amount"> + {({ + field: { onChange, ...field }, + form: { setFieldValue }, + meta, + }: FieldProps<FormValues>) => { + return ( + <Input + {...field} + onValueChange={({ value }) => { + setFieldValue('amount', value, true); + }} + type={InputType.NumericFormat} + label="Amount" + value={amount} + suffix={` ${symbol}`} + placeholder="Enter amount to stake" + errorMessage={ + values.amount && meta.error ? meta.error : undefined + } + caption={caption} + /> + ); + }} + </Field> + {showInfo ? ( + <div className="mt-md"> + <InfoBox + type={InfoBoxType.Error} + supportingText={infoMessage} + style={InfoBoxStyle.Elevated} + icon={<Exclamation />} + /> + </div> + ) : null} + </div> + + <Panel hasBorder> + <div className="flex flex-col gap-y-sm p-md"> + <KeyValueInfo + keyText="Staking Rewards Start" + value={stakedRewardsStartEpoch} + fullwidth + /> + <KeyValueInfo + keyText="Redeem Rewards" + value={timeBeforeStakeRewardsRedeemableAgoDisplay} + fullwidth + /> + <Divider /> + <KeyValueInfo + keyText="Gas fee" + value={gas || '--'} + supportingLabel={symbol} + fullwidth + /> + </div> + </Panel> + </div> + </div> + </DialogLayoutBody> + <DialogLayoutFooter> + <div className="flex w-full justify-between gap-sm"> + <Button fullWidth type={ButtonType.Secondary} onClick={onBack} text="Back" /> + <Button + fullWidth + type={ButtonType.Primary} + disabled={!amount || !!errors?.amount || isLoading || isStakeDisabled} + onClick={handleStake} + text="Stake" + icon={ + isLoading ? ( + <Loader className="animate-spin" data-testid="loading-indicator" /> + ) : null + } + iconAfterText + /> + </div> + </DialogLayoutFooter> + </DialogLayout> + ); +} + +export default EnterAmountDialogLayout; diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterAmountView.tsx b/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterAmountView.tsx index b3869faed2b..b90de664794 100644 --- a/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterAmountView.tsx +++ b/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterAmountView.tsx @@ -2,35 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 import React from 'react'; -import { - useFormatCoin, - useBalance, - CoinFormat, - parseAmount, - useCoinMetadata, - useStakeTxnInfo, -} from '@iota/core'; +import { useFormatCoin, useBalance, CoinFormat, parseAmount, useCoinMetadata } from '@iota/core'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; -import { - Button, - ButtonType, - KeyValueInfo, - Panel, - Divider, - Input, - InputType, - Header, - InfoBoxType, - InfoBoxStyle, - InfoBox, -} from '@iota/apps-ui-kit'; -import { Field, type FieldProps, useFormikContext } from 'formik'; -import { Exclamation } from '@iota/ui-icons'; -import { useCurrentAccount, useIotaClientQuery } from '@iota/dapp-kit'; - -import { Validator } from './Validator'; -import { StakedInfo } from './StakedInfo'; -import { DialogLayout, DialogLayoutBody, DialogLayoutFooter } from '../../layout'; +import { useFormikContext } from 'formik'; +import { useSignAndExecuteTransaction } from '@iota/dapp-kit'; +import { useNewStakeTransaction, useNotifications } from '@/hooks'; +import { NotificationType } from '@/stores/notificationStore'; +import EnterAmountDialogLayout from './EnterAmountDialogLayout'; export interface FormValues { amount: string; @@ -39,38 +17,39 @@ export interface FormValues { interface EnterAmountViewProps { selectedValidator: string; onBack: () => void; - onStake: () => void; showActiveStatus?: boolean; - gasBudget?: string | number | null; handleClose: () => void; - isTransactionLoading?: boolean; + amountWithoutDecimals: bigint; + senderAddress: string; + onSuccess: (digest: string) => void; } function EnterAmountView({ - selectedValidator: selectedValidatorAddress, + selectedValidator, onBack, - onStake, - gasBudget = 0, handleClose, - isTransactionLoading, + amountWithoutDecimals, + senderAddress, + onSuccess, }: EnterAmountViewProps): JSX.Element { + const { addNotification } = useNotifications(); + const { mutateAsync: signAndExecuteTransaction } = useSignAndExecuteTransaction(); + const { values, resetForm } = useFormikContext<FormValues>(); + const coinType = IOTA_TYPE_ARG; const { data: metadata } = useCoinMetadata(coinType); const decimals = metadata?.decimals ?? 0; - const account = useCurrentAccount(); - const accountAddress = account?.address; - - const { values, errors } = useFormikContext<FormValues>(); - const amount = values.amount; - - const { data: system } = useIotaClientQuery('getLatestIotaSystemState'); - const { data: iotaBalance } = useBalance(accountAddress!); + const { data: iotaBalance } = useBalance(senderAddress); const coinBalance = BigInt(iotaBalance?.totalBalance || 0); - const gasBudgetBigInt = BigInt(gasBudget ?? 0); - const [gas, symbol] = useFormatCoin(gasBudget, IOTA_TYPE_ARG); + const { data: newStakeData, isLoading: isTransactionLoading } = useNewStakeTransaction( + selectedValidator, + amountWithoutDecimals, + senderAddress, + ); + const gasBudgetBigInt = BigInt(newStakeData?.gasBudget ?? 0); const maxTokenBalance = coinBalance - gasBudgetBigInt; const [maxTokenFormatted, maxTokenFormattedSymbol] = useFormatCoin( maxTokenBalance, @@ -78,109 +57,47 @@ function EnterAmountView({ CoinFormat.FULL, ); - const caption = isTransactionLoading - ? '--' - : `${maxTokenFormatted} ${maxTokenFormattedSymbol} Available`; - - const { stakedRewardsStartEpoch, timeBeforeStakeRewardsRedeemableAgoDisplay } = useStakeTxnInfo( - system?.epoch, - ); - + const caption = `${maxTokenFormatted} ${maxTokenFormattedSymbol} Available`; + const infoMessage = + 'You have selected an amount that will leave you with insufficient funds to pay for gas fees for unstaking or any other transactions.'; const hasEnoughRemaingBalance = maxTokenBalance > parseAmount(values.amount, decimals) + BigInt(2) * gasBudgetBigInt; - return ( - <DialogLayout> - <Header title="Enter amount" onClose={handleClose} onBack={onBack} titleCentered /> - <DialogLayoutBody> - <div className="flex w-full flex-col justify-between"> - <div> - <div className="mb-md"> - <Validator - address={selectedValidatorAddress} - isSelected - showAction={false} - /> - </div> - <StakedInfo - validatorAddress={selectedValidatorAddress} - accountAddress={accountAddress!} - /> - <div className="my-md w-full"> - <Field name="amount"> - {({ - field: { onChange, ...field }, - form: { setFieldValue }, - meta, - }: FieldProps<FormValues>) => { - return ( - <Input - {...field} - onValueChange={({ value }) => { - setFieldValue('amount', value, true); - }} - type={InputType.NumericFormat} - label="Amount" - value={amount} - suffix={` ${symbol}`} - placeholder="Enter amount to stake" - errorMessage={ - values.amount && meta.error ? meta.error : undefined - } - caption={coinBalance ? caption : ''} - /> - ); - }} - </Field> - {!hasEnoughRemaingBalance ? ( - <div className="mt-md"> - <InfoBox - type={InfoBoxType.Error} - supportingText="You have selected an amount that will leave you with insufficient funds to pay for gas fees for unstaking or any other transactions." - style={InfoBoxStyle.Elevated} - icon={<Exclamation />} - /> - </div> - ) : null} - </div> + function handleStake(): void { + if (!newStakeData?.transaction) { + addNotification('Stake transaction was not created', NotificationType.Error); + return; + } + signAndExecuteTransaction( + { + transaction: newStakeData?.transaction, + }, + { + onSuccess: (tx) => { + onSuccess(tx.digest); + addNotification('Stake transaction has been sent'); + resetForm(); + }, + onError: () => { + addNotification('Stake transaction was not sent', NotificationType.Error); + }, + }, + ); + } - <Panel hasBorder> - <div className="flex flex-col gap-y-sm p-md"> - <KeyValueInfo - keyText="Staking Rewards Start" - value={stakedRewardsStartEpoch} - fullwidth - /> - <KeyValueInfo - keyText="Redeem Rewards" - value={timeBeforeStakeRewardsRedeemableAgoDisplay} - fullwidth - /> - <Divider /> - <KeyValueInfo - keyText="Gas fee" - value={gas || '--'} - supportingLabel={symbol} - fullwidth - /> - </div> - </Panel> - </div> - </div> - </DialogLayoutBody> - <DialogLayoutFooter> - <div className="flex w-full justify-between gap-sm"> - <Button fullWidth type={ButtonType.Secondary} onClick={onBack} text="Back" /> - <Button - fullWidth - type={ButtonType.Primary} - onClick={onStake} - disabled={!amount || !!errors?.amount} - text="Stake" - /> - </div> - </DialogLayoutFooter> - </DialogLayout> + return ( + <EnterAmountDialogLayout + selectedValidator={selectedValidator} + gasBudget={newStakeData?.gasBudget} + senderAddress={senderAddress} + caption={caption} + showInfo={!hasEnoughRemaingBalance} + infoMessage={infoMessage} + isLoading={isTransactionLoading} + onBack={onBack} + handleClose={handleClose} + handleStake={handleStake} + /> ); } diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterTimelockedAmountView.tsx b/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterTimelockedAmountView.tsx index 9eaeb41b6a2..b21a6ad3bd1 100644 --- a/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterTimelockedAmountView.tsx +++ b/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterTimelockedAmountView.tsx @@ -1,29 +1,25 @@ // Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -import React from 'react'; -import { useFormatCoin, CoinFormat, useStakeTxnInfo } from '@iota/core'; +import React, { useEffect, useState } from 'react'; +import { + useFormatCoin, + CoinFormat, + GroupedTimelockObject, + useGetAllOwnedObjects, + TIMELOCK_IOTA_TYPE, +} from '@iota/core'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; +import { useFormikContext } from 'formik'; +import { useSignAndExecuteTransaction } from '@iota/dapp-kit'; import { - Button, - ButtonType, - KeyValueInfo, - Panel, - Divider, - Input, - InputType, - Header, - InfoBoxType, - InfoBoxStyle, - InfoBox, -} from '@iota/apps-ui-kit'; -import { Field, type FieldProps, useFormikContext } from 'formik'; -import { Exclamation, Loader } from '@iota/ui-icons'; -import { useCurrentAccount, useIotaClientQuery } from '@iota/dapp-kit'; - -import { Validator } from './Validator'; -import { StakedInfo } from './StakedInfo'; -import { DialogLayout, DialogLayoutBody, DialogLayoutFooter } from '../../layout'; + useGetCurrentEpochStartTimestamp, + useNewStakeTimelockedTransaction, + useNotifications, +} from '@/hooks'; +import { NotificationType } from '@/stores/notificationStore'; +import { prepareObjectsForTimelockedStakingTransaction } from '@/lib/utils'; +import EnterAmountDialogLayout from './EnterAmountDialogLayout'; export interface FormValues { amount: string; @@ -32,32 +28,49 @@ export interface FormValues { interface EnterTimelockedAmountViewProps { selectedValidator: string; maxStakableTimelockedAmount: bigint; + amountWithoutDecimals: bigint; + senderAddress: string; onBack: () => void; - onStake: () => void; - gasBudget?: string | number | null; handleClose: () => void; - hasGroupedTimelockObjects?: boolean; - isTransactionLoading?: boolean; + onSuccess: (digest: string) => void; } function EnterTimelockedAmountView({ - selectedValidator: selectedValidatorAddress, + selectedValidator, maxStakableTimelockedAmount, - hasGroupedTimelockObjects, + amountWithoutDecimals, + senderAddress, onBack, - onStake, - gasBudget, handleClose, - isTransactionLoading, + onSuccess, }: EnterTimelockedAmountViewProps): JSX.Element { - const account = useCurrentAccount(); - const accountAddress = account?.address; + const { addNotification } = useNotifications(); + const { mutateAsync: signAndExecuteTransaction } = useSignAndExecuteTransaction(); + const { resetForm } = useFormikContext<FormValues>(); + + const { data: currentEpochMs } = useGetCurrentEpochStartTimestamp(); + const { data: timelockedObjects } = useGetAllOwnedObjects(senderAddress, { + StructType: TIMELOCK_IOTA_TYPE, + }); + const [groupedTimelockObjects, setGroupedTimelockObjects] = useState<GroupedTimelockObject[]>( + [], + ); - const { values, errors } = useFormikContext<FormValues>(); - const amount = values.amount; + const { data: newStakeData, isLoading: isTransactionLoading } = + useNewStakeTimelockedTransaction(selectedValidator, senderAddress, groupedTimelockObjects); - const { data: system } = useIotaClientQuery('getLatestIotaSystemState'); - const [gas, symbol] = useFormatCoin(gasBudget ?? 0, IOTA_TYPE_ARG); + useEffect(() => { + if (timelockedObjects && currentEpochMs) { + const groupedTimelockObjects = prepareObjectsForTimelockedStakingTransaction( + timelockedObjects, + amountWithoutDecimals, + currentEpochMs, + ); + setGroupedTimelockObjects(groupedTimelockObjects); + } + }, [timelockedObjects, currentEpochMs, amountWithoutDecimals]); + + const hasGroupedTimelockObjects = groupedTimelockObjects.length > 0; const [maxTokenFormatted, maxTokenFormattedSymbol] = useFormatCoin( maxStakableTimelockedAmount, @@ -66,114 +79,49 @@ function EnterTimelockedAmountView({ ); const caption = `${maxTokenFormatted} ${maxTokenFormattedSymbol} Available`; + const infoMessage = + 'It is not possible to combine timelocked objects to stake the entered amount. Please try a different amount.'; - const { stakedRewardsStartEpoch, timeBeforeStakeRewardsRedeemableAgoDisplay } = useStakeTxnInfo( - system?.epoch, - ); + function handleStake(): void { + if (groupedTimelockObjects.length === 0) { + addNotification('Invalid stake amount. Please try again.', NotificationType.Error); + return; + } + if (!newStakeData?.transaction) { + addNotification('Stake transaction was not created', NotificationType.Error); + return; + } + signAndExecuteTransaction( + { + transaction: newStakeData?.transaction, + }, + { + onSuccess: (tx) => { + onSuccess?.(tx.digest); + addNotification('Stake transaction has been sent'); + resetForm(); + }, + onError: () => { + addNotification('Stake transaction was not sent', NotificationType.Error); + }, + }, + ); + } return ( - <DialogLayout> - <Header title="Enter amount" onClose={handleClose} onBack={onBack} titleCentered /> - <DialogLayoutBody> - <div className="flex w-full flex-col justify-between"> - <div> - <div className="mb-md"> - <Validator - address={selectedValidatorAddress} - isSelected - showAction={false} - /> - </div> - <StakedInfo - validatorAddress={selectedValidatorAddress} - accountAddress={accountAddress!} - /> - <div className="my-md w-full"> - <Field name="amount"> - {({ - field: { onChange, ...field }, - form: { setFieldValue }, - meta, - }: FieldProps<FormValues>) => { - return ( - <Input - {...field} - onValueChange={({ value }) => { - setFieldValue('amount', value, true); - }} - type={InputType.NumericFormat} - label="Amount" - value={amount} - suffix={` ${symbol}`} - placeholder="Enter amount to stake" - errorMessage={ - values.amount && meta.error ? meta.error : undefined - } - caption={caption} - /> - ); - }} - </Field> - {!hasGroupedTimelockObjects && !isTransactionLoading ? ( - <div className="mt-md"> - <InfoBox - type={InfoBoxType.Error} - supportingText="It is not possible to combine timelocked objects to stake the entered amount. Please try a different amount." - style={InfoBoxStyle.Elevated} - icon={<Exclamation />} - /> - </div> - ) : null} - </div> - - <Panel hasBorder> - <div className="flex flex-col gap-y-sm p-md"> - <KeyValueInfo - keyText="Staking Rewards Start" - value={stakedRewardsStartEpoch} - fullwidth - /> - <KeyValueInfo - keyText="Redeem Rewards" - value={timeBeforeStakeRewardsRedeemableAgoDisplay} - fullwidth - /> - <Divider /> - <KeyValueInfo - keyText="Gas fee" - value={gas || '--'} - supportingLabel={symbol} - fullwidth - /> - </div> - </Panel> - </div> - </div> - </DialogLayoutBody> - <DialogLayoutFooter> - <div className="flex w-full justify-between gap-sm"> - <Button fullWidth type={ButtonType.Secondary} onClick={onBack} text="Back" /> - <Button - fullWidth - type={ButtonType.Primary} - disabled={ - !amount || - !!errors?.amount || - isTransactionLoading || - !hasGroupedTimelockObjects - } - onClick={onStake} - text="Stake" - icon={ - isTransactionLoading ? ( - <Loader className="animate-spin" data-testid="loading-indicator" /> - ) : null - } - iconAfterText - /> - </div> - </DialogLayoutFooter> - </DialogLayout> + <EnterAmountDialogLayout + selectedValidator={selectedValidator} + gasBudget={newStakeData?.gasBudget} + senderAddress={senderAddress} + caption={caption} + showInfo={!hasGroupedTimelockObjects} + infoMessage={infoMessage} + isLoading={isTransactionLoading} + isStakeDisabled={!hasGroupedTimelockObjects} + onBack={onBack} + handleClose={handleClose} + handleStake={handleStake} + /> ); } diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/views/UnstakeView.tsx b/apps/wallet-dashboard/components/Dialogs/Staking/views/UnstakeView.tsx deleted file mode 100644 index 302d1de5514..00000000000 --- a/apps/wallet-dashboard/components/Dialogs/Staking/views/UnstakeView.tsx +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -import { - Header, - Button, - KeyValueInfo, - Divider, - ButtonType, - Panel, - LoadingIndicator, - InfoBoxType, - InfoBoxStyle, - InfoBox, -} from '@iota/apps-ui-kit'; -import { - createUnstakeTransaction, - ExtendedDelegatedStake, - GAS_SYMBOL, - TimeUnit, - useFormatCoin, - useGetTimeBeforeEpochNumber, - useGetStakingValidatorDetails, - useTimeAgo, - useTransactionGasBudget, -} from '@iota/core'; -import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; -import { useMemo } from 'react'; -import { useCurrentAccount } from '@iota/dapp-kit'; -import { Loader, Warning } from '@iota/ui-icons'; -import { useUnstakeTransaction } from '@/hooks'; -import { ValidatorStakingData } from '@/components'; -import { DialogLayout, DialogLayoutFooter, DialogLayoutBody } from '../../layout'; -import { Transaction } from '@iota/iota-sdk/transactions'; - -interface UnstakeViewProps { - extendedStake: ExtendedDelegatedStake; - handleClose: () => void; - onUnstake: (unstakeTransaction: Transaction) => void; - isPending: boolean; -} - -export function UnstakeView({ - extendedStake, - handleClose, - onUnstake, - isPending, -}: UnstakeViewProps): JSX.Element { - const stakingReward = BigInt(extendedStake.estimatedReward ?? '').toString(); - const [rewards, rewardSymbol] = useFormatCoin(stakingReward, IOTA_TYPE_ARG); - const activeAddress = useCurrentAccount()?.address ?? null; - - const { - totalStake: [tokenBalance], - totalStakeOriginal, - epoch, - systemDataResult, - delegatedStakeDataResult, - } = useGetStakingValidatorDetails({ - accountAddress: activeAddress, - validatorAddress: extendedStake.validatorAddress, - stakeId: extendedStake.stakedIotaId, - unstake: true, - }); - - const { isLoading: loadingValidators, error: errorValidators } = systemDataResult; - const { - isLoading: isLoadingDelegatedStakeData, - isError, - error: delegatedStakeDataError, - } = delegatedStakeDataResult; - - const delegationId = extendedStake?.stakedIotaId; - - const [totalIota] = useFormatCoin( - BigInt(stakingReward || 0) + totalStakeOriginal, - IOTA_TYPE_ARG, - ); - - const transaction = useMemo( - () => createUnstakeTransaction(extendedStake.stakedIotaId), - [extendedStake], - ); - const { data: gasBudget } = useTransactionGasBudget(activeAddress, transaction); - - const { data: currentEpochEndTime } = useGetTimeBeforeEpochNumber(epoch + 1 || 0); - const currentEpochEndTimeAgo = useTimeAgo({ - timeFrom: currentEpochEndTime, - endLabel: '--', - shortedTimeLabel: false, - shouldEnd: true, - maxTimeUnit: TimeUnit.ONE_HOUR, - }); - - const { data: unstakeData } = useUnstakeTransaction( - extendedStake.stakedIotaId, - activeAddress || '', - ); - - function handleUnstake(): void { - if (!unstakeData) return; - onUnstake(unstakeData.transaction); - } - - const currentEpochEndTimeFormatted = - currentEpochEndTime > 0 ? currentEpochEndTimeAgo : `Epoch #${epoch}`; - - if (isLoadingDelegatedStakeData || loadingValidators) { - return ( - <div className="flex h-full w-full items-center justify-center p-2"> - <LoadingIndicator /> - </div> - ); - } - - if (isError || errorValidators) { - return ( - <div className="mb-2 flex h-full w-full items-center justify-center p-2"> - <InfoBox - title="Something went wrong" - supportingText={delegatedStakeDataError?.message ?? 'An error occurred'} - style={InfoBoxStyle.Default} - type={InfoBoxType.Error} - icon={<Warning />} - /> - </div> - ); - } - - return ( - <DialogLayout> - <Header title="Unstake" onClose={handleClose} onBack={handleClose} titleCentered /> - <DialogLayoutBody> - <div className="flex flex-col gap-y-md"> - <ValidatorStakingData - validatorAddress={extendedStake.validatorAddress} - stakeId={extendedStake.stakedIotaId} - isUnstake - /> - - <Panel hasBorder> - <div className="flex flex-col gap-y-sm p-md"> - <KeyValueInfo - keyText="Current Epoch Ends" - value={currentEpochEndTimeFormatted} - fullwidth - /> - <Divider /> - <KeyValueInfo - keyText="Your Stake" - value={tokenBalance} - supportingLabel={GAS_SYMBOL} - fullwidth - /> - <KeyValueInfo - keyText="Rewards Earned" - value={rewards} - supportingLabel={rewardSymbol} - fullwidth - /> - <Divider /> - <KeyValueInfo - keyText="Total unstaked IOTA" - value={totalIota} - supportingLabel={GAS_SYMBOL} - fullwidth - /> - </div> - </Panel> - - <Panel hasBorder> - <div className="flex flex-col gap-y-sm p-md"> - <KeyValueInfo - keyText="Gas Fees" - value={gasBudget || '-'} - supportingLabel={GAS_SYMBOL} - fullwidth - /> - </div> - </Panel> - </div> - </DialogLayoutBody> - - <DialogLayoutFooter> - <Button - type={ButtonType.Secondary} - fullWidth - onClick={handleUnstake} - disabled={isPending || !delegationId} - text="Unstake" - icon={ - isPending ? ( - <Loader className="animate-spin" data-testid="loading-indicator" /> - ) : null - } - iconAfterText - /> - </DialogLayoutFooter> - </DialogLayout> - ); -} diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/views/index.ts b/apps/wallet-dashboard/components/Dialogs/Staking/views/index.ts index 8ed3cfb4dee..5a0ffed2be6 100644 --- a/apps/wallet-dashboard/components/Dialogs/Staking/views/index.ts +++ b/apps/wallet-dashboard/components/Dialogs/Staking/views/index.ts @@ -3,6 +3,6 @@ export { default as EnterAmountView } from './EnterAmountView'; export { default as EnterTimelockedAmountView } from './EnterTimelockedAmountView'; +export { default as EnterAmountDialogLayout } from './EnterAmountDialogLayout'; export { default as SelectValidatorView } from './SelectValidatorView'; export * from './DetailsView'; -export * from './UnstakeView'; diff --git a/apps/wallet-dashboard/components/Dialogs/TransactionDialog.tsx b/apps/wallet-dashboard/components/Dialogs/TransactionDialog.tsx index c1b6a845b01..8b78f53d190 100644 --- a/apps/wallet-dashboard/components/Dialogs/TransactionDialog.tsx +++ b/apps/wallet-dashboard/components/Dialogs/TransactionDialog.tsx @@ -46,7 +46,9 @@ export function TransactionDialogView({ renderValidatorLogo={Validator} /> ) : ( - <LoadingIndicator /> + <div className="flex h-full w-full justify-center"> + <LoadingIndicator /> + </div> )} </DialogLayoutBody> <DialogLayoutFooter> diff --git a/apps/wallet-dashboard/components/Dialogs/index.ts b/apps/wallet-dashboard/components/Dialogs/index.ts index 97ee2fabbad..db380d17927 100644 --- a/apps/wallet-dashboard/components/Dialogs/index.ts +++ b/apps/wallet-dashboard/components/Dialogs/index.ts @@ -4,4 +4,7 @@ export * from './SendToken'; export * from './ReceiveFundsDialog'; export * from './Staking'; +export * from './unstake'; export * from './vesting'; +export * from './settings'; +export * from './MigrationDialog'; diff --git a/apps/wallet-dashboard/components/Dialogs/settings/SettingsDialog.tsx b/apps/wallet-dashboard/components/Dialogs/settings/SettingsDialog.tsx new file mode 100644 index 00000000000..2c87b522af2 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/settings/SettingsDialog.tsx @@ -0,0 +1,38 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import React from 'react'; +import { Dialog } from '@iota/apps-ui-kit'; +import { SettingsDialogView } from './enums'; +import { SettingsListView, NetworkSelectorView } from './views'; + +interface SettingsDialogProps { + isOpen: boolean; + handleClose: () => void; + view: SettingsDialogView | undefined; + setView: (view: SettingsDialogView) => void; +} + +export function SettingsDialog({ + isOpen, + handleClose, + view, + setView, +}: SettingsDialogProps): JSX.Element { + function onBack(): void { + setView(SettingsDialogView.SelectSetting); + } + + return ( + <Dialog open={isOpen} onOpenChange={() => handleClose()}> + <> + {view === SettingsDialogView.SelectSetting && ( + <SettingsListView handleClose={handleClose} setView={setView} /> + )} + {view === SettingsDialogView.NetworkSettings && ( + <NetworkSelectorView handleClose={handleClose} onBack={onBack} /> + )} + </> + </Dialog> + ); +} diff --git a/apps/wallet-dashboard/contexts/index.ts b/apps/wallet-dashboard/components/Dialogs/settings/enums/index.ts similarity index 70% rename from apps/wallet-dashboard/contexts/index.ts rename to apps/wallet-dashboard/components/Dialogs/settings/enums/index.ts index d356e2485ed..6f408e39b8c 100644 --- a/apps/wallet-dashboard/contexts/index.ts +++ b/apps/wallet-dashboard/components/Dialogs/settings/enums/index.ts @@ -1,4 +1,4 @@ // Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -export * from './PopupContext'; +export * from './view.enums'; diff --git a/apps/wallet-dashboard/components/Dialogs/settings/enums/view.enums.ts b/apps/wallet-dashboard/components/Dialogs/settings/enums/view.enums.ts new file mode 100644 index 00000000000..b3f17bb2130 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/settings/enums/view.enums.ts @@ -0,0 +1,7 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export enum SettingsDialogView { + SelectSetting = 'SelectSetting', + NetworkSettings = 'NetworkSettings', +} diff --git a/apps/wallet-dashboard/components/Dialogs/settings/hooks/index.ts b/apps/wallet-dashboard/components/Dialogs/settings/hooks/index.ts new file mode 100644 index 00000000000..dfc58ee2f8b --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/settings/hooks/index.ts @@ -0,0 +1,4 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './useSettingsDialog'; diff --git a/apps/wallet-dashboard/components/Dialogs/settings/hooks/useSettingsDialog.ts b/apps/wallet-dashboard/components/Dialogs/settings/hooks/useSettingsDialog.ts new file mode 100644 index 00000000000..6691f971e6c --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/settings/hooks/useSettingsDialog.ts @@ -0,0 +1,27 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { useState } from 'react'; +import { SettingsDialogView } from '../enums'; + +export function useSettingsDialog() { + const [settingsDialogView, setSettingsDialogView] = useState<SettingsDialogView | undefined>(); + + const isSettingsDialogOpen = settingsDialogView !== undefined; + + function onCloseSettingsDialogClick() { + setSettingsDialogView(undefined); + } + + function onOpenSettingsDialogClick() { + setSettingsDialogView(SettingsDialogView.SelectSetting); + } + + return { + isSettingsDialogOpen, + settingsDialogView, + setSettingsDialogView, + onCloseSettingsDialogClick, + onOpenSettingsDialogClick, + }; +} diff --git a/apps/wallet-dashboard/components/Dialogs/settings/index.ts b/apps/wallet-dashboard/components/Dialogs/settings/index.ts new file mode 100644 index 00000000000..00a59c7b679 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/settings/index.ts @@ -0,0 +1,7 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './enums'; +export * from './SettingsDialog'; +export * from './hooks'; +export * from './views'; diff --git a/apps/wallet-dashboard/components/Dialogs/settings/views/NetworkSelectorView.tsx b/apps/wallet-dashboard/components/Dialogs/settings/views/NetworkSelectorView.tsx new file mode 100644 index 00000000000..cc9b573a9a9 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/settings/views/NetworkSelectorView.tsx @@ -0,0 +1,53 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import React from 'react'; +import { Header, RadioButton } from '@iota/apps-ui-kit'; +import { DialogLayout, DialogLayoutBody } from '../../layout'; +import { NetworkConfiguration } from '@iota/iota-sdk/client'; +import { useIotaClientContext } from '@iota/dapp-kit'; +import toast from 'react-hot-toast'; + +interface NetworkSelectorViewProps { + handleClose: () => void; + onBack: () => void; +} + +export function NetworkSelectorView({ + handleClose, + onBack, +}: NetworkSelectorViewProps): JSX.Element { + const clientContext = useIotaClientContext(); + const activeNetwork = clientContext.network; + + async function handleNetworkChange(network: NetworkConfiguration) { + if (activeNetwork === network.id) { + return; + } + clientContext.selectNetwork(network.id); + toast.success(`Switched to ${network.name}`); + } + return ( + <DialogLayout> + <Header title="Network" onClose={handleClose} onBack={onBack} titleCentered /> + <DialogLayoutBody> + <div className="flex w-full flex-col gap-md"> + {Object.keys(clientContext.networks).map((network) => { + const networkConfig = clientContext.networks[ + network + ] as NetworkConfiguration; + return ( + <div className="px-md" key={networkConfig.id}> + <RadioButton + label={networkConfig.name} + isChecked={activeNetwork === networkConfig.id} + onChange={() => handleNetworkChange(networkConfig)} + /> + </div> + ); + })} + </div> + </DialogLayoutBody> + </DialogLayout> + ); +} diff --git a/apps/wallet-dashboard/components/Dialogs/settings/views/SettingsListView.tsx b/apps/wallet-dashboard/components/Dialogs/settings/views/SettingsListView.tsx new file mode 100644 index 00000000000..5ed55017ab9 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/settings/views/SettingsListView.tsx @@ -0,0 +1,63 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import React from 'react'; +import { + Card, + CardAction, + CardActionType, + CardBody, + CardImage, + CardType, + Header, + ImageType, +} from '@iota/apps-ui-kit'; +import { DialogLayout, DialogLayoutBody } from '../../layout'; +import { SettingsDialogView } from '../enums'; +import { getNetwork } from '@iota/iota-sdk/client'; +import { useIotaClientContext } from '@iota/dapp-kit'; +import { Globe } from '@iota/ui-icons'; + +interface SettingsListViewProps { + handleClose: () => void; + setView: (view: SettingsDialogView) => void; +} + +export function SettingsListView({ handleClose, setView }: SettingsListViewProps): JSX.Element { + const { network } = useIotaClientContext(); + const { name: networkName } = getNetwork(network); + function onSelectSettingClick(view: SettingsDialogView): void { + setView(view); + } + const MENU_ITEMS = [ + { + title: 'Network', + subtitle: networkName, + icon: <Globe />, + onClick: () => onSelectSettingClick(SettingsDialogView.NetworkSettings), + }, + ]; + return ( + <DialogLayout> + <Header title="Settings" onClose={handleClose} onBack={handleClose} titleCentered /> + <DialogLayoutBody> + <div className="flex h-full flex-col content-stretch"> + <div className="flex h-full w-full flex-col gap-md"> + {MENU_ITEMS.map((item, index) => ( + <Card key={index} type={CardType.Default} onClick={item.onClick}> + <CardImage type={ImageType.BgSolid}> + <div className="flex h-10 w-10 items-center justify-center rounded-full text-neutral-10 dark:text-neutral-92 [&_svg]:h-5 [&_svg]:w-5"> + <span className="text-2xl">{item.icon}</span> + </div> + </CardImage> + <CardBody title={item.title} subtitle={item.subtitle} /> + <CardAction type={CardActionType.Link} /> + </Card> + ))} + </div> + <p className="text-center">{process.env.NEXT_PUBLIC_DASHBOARD_REV}</p> + </div> + </DialogLayoutBody> + </DialogLayout> + ); +} diff --git a/apps/wallet-dashboard/components/Dialogs/settings/views/index.ts b/apps/wallet-dashboard/components/Dialogs/settings/views/index.ts new file mode 100644 index 00000000000..738311af3ac --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/settings/views/index.ts @@ -0,0 +1,5 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './SettingsListView'; +export * from './NetworkSelectorView'; diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/UnstakeDialog.tsx b/apps/wallet-dashboard/components/Dialogs/unstake/UnstakeDialog.tsx new file mode 100644 index 00000000000..16ef52b41bb --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/UnstakeDialog.tsx @@ -0,0 +1,56 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Dialog } from '@iota/apps-ui-kit'; +import { UnstakeTimelockedObjectsView, UnstakeView } from './views'; +import { ExtendedDelegatedStake } from '@iota/core'; +import { TimelockedStakedObjectsGrouped } from '@/lib/utils'; +import { UnstakeDialogView } from './enums'; +import { IotaSignAndExecuteTransactionOutput } from '@iota/wallet-standard'; +import { TransactionDialogView } from '../TransactionDialog'; + +interface UnstakeDialogProps { + view: UnstakeDialogView; + handleClose: () => void; + onSuccess: (tx: IotaSignAndExecuteTransactionOutput) => void; + onBack?: (view: UnstakeDialogView) => (() => void) | undefined; + groupedTimelockedObjects?: TimelockedStakedObjectsGrouped; + extendedStake?: ExtendedDelegatedStake; + txDigest?: string; +} + +export function UnstakeDialog({ + view, + handleClose, + onSuccess, + extendedStake, + groupedTimelockedObjects, + onBack, + txDigest, +}: UnstakeDialogProps): React.JSX.Element { + return ( + <Dialog open onOpenChange={handleClose}> + {view === UnstakeDialogView.Unstake && extendedStake && ( + <UnstakeView + extendedStake={extendedStake} + handleClose={handleClose} + onBack={onBack?.(UnstakeDialogView.Unstake)} + showActiveStatus + onSuccess={onSuccess} + /> + )} + + {view === UnstakeDialogView.TimelockedUnstake && groupedTimelockedObjects && ( + <UnstakeTimelockedObjectsView + onClose={handleClose} + groupedTimelockedObjects={groupedTimelockedObjects} + onBack={onBack?.(UnstakeDialogView.TimelockedUnstake)} + onSuccess={onSuccess} + /> + )} + {view === UnstakeDialogView.TransactionDetails && ( + <TransactionDialogView txDigest={txDigest} onClose={handleClose} /> + )} + </Dialog> + ); +} diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/enums/index.ts b/apps/wallet-dashboard/components/Dialogs/unstake/enums/index.ts new file mode 100644 index 00000000000..75ff18fcbaf --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/enums/index.ts @@ -0,0 +1,4 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './views.enums'; diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/enums/views.enums.ts b/apps/wallet-dashboard/components/Dialogs/unstake/enums/views.enums.ts new file mode 100644 index 00000000000..1b0b313dcce --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/enums/views.enums.ts @@ -0,0 +1,8 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export enum UnstakeDialogView { + Unstake = 'unstake', + TimelockedUnstake = 'timelockedUnstake', + TransactionDetails = 'transactionDetails', +} diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/hooks/index.ts b/apps/wallet-dashboard/components/Dialogs/unstake/hooks/index.ts new file mode 100644 index 00000000000..8834415eafd --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/hooks/index.ts @@ -0,0 +1,4 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './useUnstakeDialog'; diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/hooks/useUnstakeDialog.ts b/apps/wallet-dashboard/components/Dialogs/unstake/hooks/useUnstakeDialog.ts new file mode 100644 index 00000000000..88de6c40f25 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/hooks/useUnstakeDialog.ts @@ -0,0 +1,41 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { ComponentProps, useState } from 'react'; +import { UnstakeDialogView } from '../enums'; +import type { UnstakeDialog } from '../UnstakeDialog'; + +export function useUnstakeDialog() { + const [isOpen, setIsOpen] = useState(false); + const [view, setView] = useState<UnstakeDialogView>(UnstakeDialogView.Unstake); + const [txDigest, setTxDigest] = useState<string | undefined>(); + + function openUnstakeDialog(view?: UnstakeDialogView) { + setIsOpen(true); + if (view) { + setView(view); + } + } + + function handleClose() { + setIsOpen(false); + } + + const defaultDialogProps: Omit<ComponentProps<typeof UnstakeDialog>, 'onSuccess'> = { + view, + handleClose: () => setIsOpen(false), + txDigest, + }; + + return { + isOpen, + setIsOpen, + view, + setView, + openUnstakeDialog, + txDigest, + setTxDigest, + defaultDialogProps, + handleClose, + }; +} diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/index.ts b/apps/wallet-dashboard/components/Dialogs/unstake/index.ts new file mode 100644 index 00000000000..05b9b934af5 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/index.ts @@ -0,0 +1,8 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './views'; +export * from './enums'; +export * from './hooks'; + +export * from './UnstakeDialog'; diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeTimelockedObjectsView.tsx b/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeTimelockedObjectsView.tsx new file mode 100644 index 00000000000..45e34ee5cf0 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeTimelockedObjectsView.tsx @@ -0,0 +1,213 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { StakeRewardsPanel, ValidatorStakingData } from '@/components'; +import { DialogLayout, DialogLayoutBody, DialogLayoutFooter } from '../../layout'; +import { Validator } from '../../Staking/views/Validator'; +import { useNewUnstakeTimelockedTransaction, useNotifications } from '@/hooks'; +import { + Collapsible, + TimeUnit, + useFormatCoin, + useGetActiveValidatorsInfo, + useTimeAgo, +} from '@iota/core'; +import { ExtendedDelegatedTimelockedStake, TimelockedStakedObjectsGrouped } from '@/lib/utils'; +import { formatAddress, IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; +import { + Panel, + LoadingIndicator, + KeyValueInfo, + Header, + ButtonType, + Button, +} from '@iota/apps-ui-kit'; +import { useCurrentAccount, useSignAndExecuteTransaction } from '@iota/dapp-kit'; +import { IotaSignAndExecuteTransactionOutput } from '@iota/wallet-standard'; +import { NotificationType } from '@/stores/notificationStore'; + +interface UnstakeTimelockedObjectsViewProps { + onClose: () => void; + groupedTimelockedObjects: TimelockedStakedObjectsGrouped; + onSuccess: (tx: IotaSignAndExecuteTransactionOutput) => void; + onBack?: () => void; +} + +export function UnstakeTimelockedObjectsView({ + groupedTimelockedObjects, + onClose, + onBack, + onSuccess, +}: UnstakeTimelockedObjectsViewProps) { + const { addNotification } = useNotifications(); + const activeAddress = useCurrentAccount()?.address ?? ''; + const { data: activeValidators } = useGetActiveValidatorsInfo(); + + const stakes = groupedTimelockedObjects.stakes; + const timelockedStakedIotaIds = stakes.map((stake) => stake.timelockedStakedIotaId); + + const { data: unstakeData, isPending: isUnstakeTxPending } = useNewUnstakeTimelockedTransaction( + activeAddress, + timelockedStakedIotaIds, + ); + const { mutateAsync: signAndExecuteTransaction, isPending: isTransactionPending } = + useSignAndExecuteTransaction(); + + const validatorInfo = activeValidators?.find( + ({ iotaAddress: validatorAddress }) => + validatorAddress === groupedTimelockedObjects.validatorAddress, + ); + + const stakeId = stakes[0].timelockedStakedIotaId; + const totalStakedAmount = stakes.reduce((acc, stake) => acc + parseInt(stake.principal), 0); + const totalRewards = stakes.reduce( + (acc, stake) => acc + (stake.status === 'Active' ? parseInt(stake.estimatedReward) : 0), + 0, + ); + + const [rewardsPoolFormatted, rewardsToken] = useFormatCoin( + validatorInfo?.rewardsPool, + IOTA_TYPE_ARG, + ); + + function handleCopySuccess() { + addNotification('Copied to clipboard'); + } + + async function handleUnstake(): Promise<void> { + if (!unstakeData) return; + + await signAndExecuteTransaction( + { + transaction: unstakeData.transaction, + }, + { + onSuccess: (tx) => { + addNotification('Unstake transaction has been sent'); + onSuccess(tx); + }, + }, + ).catch(() => { + addNotification('Unstake transaction was not sent', NotificationType.Error); + }); + } + + return ( + <DialogLayout> + <Header title="Unstake" onClose={onClose} onBack={onBack} /> + <DialogLayoutBody> + <div className="flex flex-col gap-md"> + <Validator + address={groupedTimelockedObjects.validatorAddress} + isSelected + showActiveStatus + /> + + {stakeId && ( + <ValidatorStakingData + key={stakeId} + validatorAddress={groupedTimelockedObjects.validatorAddress} + stakeId={stakeId} + isUnstake + /> + )} + + <StakeRewardsPanel + stakingRewards={totalRewards} + totalStaked={totalStakedAmount} + isTimelocked + /> + + <Panel hasBorder> + <div className="flex flex-col gap-y-sm p-md"> + <KeyValueInfo + keyText="Stake Request Epoch" + value={groupedTimelockedObjects.stakeRequestEpoch} + fullwidth + /> + {rewardsPoolFormatted && ( + <KeyValueInfo + keyText="Rewards Pool" + value={rewardsPoolFormatted} + supportingLabel={rewardsToken} + fullwidth + /> + )} + <KeyValueInfo keyText="Total Stakes" value={stakes.length} fullwidth /> + </div> + </Panel> + + {stakes.map((stake, index) => ( + <TimelockedStakeCollapsible + title={`Stake Nº${index + 1}`} + key={stake.timelockedStakedIotaId} + stake={stake} + handleCopySuccess={handleCopySuccess} + /> + ))} + </div> + </DialogLayoutBody> + <DialogLayoutFooter> + <Button + onClick={handleUnstake} + text="Unstake" + icon={!unstakeData || isUnstakeTxPending ? <LoadingIndicator /> : undefined} + disabled={!unstakeData || isTransactionPending || isUnstakeTxPending} + type={ButtonType.Secondary} + fullWidth + /> + </DialogLayoutFooter> + </DialogLayout> + ); +} + +interface TimelockedStakeCollapsibleProps { + stake: ExtendedDelegatedTimelockedStake; + title: string; + handleCopySuccess: () => void; +} +function TimelockedStakeCollapsible({ + stake, + title, + handleCopySuccess, +}: TimelockedStakeCollapsibleProps) { + const currentEpochEndTimeAgo = useTimeAgo({ + timeFrom: Number(stake.expirationTimestampMs), + endLabel: '--', + shortedTimeLabel: false, + shouldEnd: true, + maxTimeUnit: TimeUnit.ONE_DAY, + }); + return ( + <Collapsible defaultOpen key={stake.timelockedStakedIotaId} title={title}> + <Panel> + <div className="flex flex-col gap-y-sm p-md--rs py-sm"> + <KeyValueInfo + keyText="Stake ID" + value={formatAddress(stake.timelockedStakedIotaId)} + valueHoverTitle={stake.timelockedStakedIotaId} + onCopySuccess={handleCopySuccess} + copyText={stake.timelockedStakedIotaId} + fullwidth + /> + <KeyValueInfo + keyText="Expiration time" + value={currentEpochEndTimeAgo} + fullwidth + /> + {stake.label && ( + <KeyValueInfo + keyText="Label" + value={formatAddress(stake.label)} + copyText={stake.label} + valueHoverTitle={stake.label} + onCopySuccess={handleCopySuccess} + fullwidth + /> + )} + <KeyValueInfo keyText="Status" value={stake.status} fullwidth /> + </div> + </Panel> + </Collapsible> + ); +} diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeView.tsx b/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeView.tsx new file mode 100644 index 00000000000..5d07eadcec3 --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeView.tsx @@ -0,0 +1,167 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { + Header, + Button, + KeyValueInfo, + ButtonType, + Panel, + LoadingIndicator, + InfoBoxType, + InfoBoxStyle, + InfoBox, +} from '@iota/apps-ui-kit'; +import { + ExtendedDelegatedStake, + GAS_SYMBOL, + useFormatCoin, + useGetStakingValidatorDetails, +} from '@iota/core'; +import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; +import { useCurrentAccount, useSignAndExecuteTransaction } from '@iota/dapp-kit'; +import { Warning } from '@iota/ui-icons'; +import { StakeRewardsPanel, ValidatorStakingData } from '@/components'; +import { DialogLayout, DialogLayoutFooter, DialogLayoutBody } from '../../layout'; +import { Validator } from '../../Staking/views/Validator'; +import { useNewUnstakeTransaction, useNotifications } from '@/hooks'; +import { IotaSignAndExecuteTransactionOutput } from '@iota/wallet-standard'; +import { NotificationType } from '@/stores/notificationStore'; + +interface UnstakeDialogProps { + extendedStake: ExtendedDelegatedStake; + handleClose: () => void; + onSuccess: (tx: IotaSignAndExecuteTransactionOutput) => void; + showActiveStatus?: boolean; + onBack?: () => void; +} + +export function UnstakeView({ + extendedStake, + handleClose, + onBack, + onSuccess, + showActiveStatus, +}: UnstakeDialogProps): JSX.Element { + const activeAddress = useCurrentAccount()?.address ?? ''; + const { addNotification } = useNotifications(); + const { data: unstakeData, isPending: isUnstakeTxPending } = useNewUnstakeTransaction( + activeAddress, + extendedStake.stakedIotaId, + ); + const [gasFormatted] = useFormatCoin(unstakeData?.gasBudget, IOTA_TYPE_ARG); + + const { mutateAsync: signAndExecuteTransaction, isPending: isTransactionPending } = + useSignAndExecuteTransaction(); + + const { totalStakeOriginal, systemDataResult, delegatedStakeDataResult } = + useGetStakingValidatorDetails({ + accountAddress: activeAddress, + validatorAddress: extendedStake.validatorAddress, + stakeId: extendedStake.stakedIotaId, + unstake: true, + }); + + const { isLoading: loadingValidators, error: errorValidators } = systemDataResult; + const { + isLoading: isLoadingDelegatedStakeData, + isError, + error: delegatedStakeDataError, + } = delegatedStakeDataResult; + + const delegationId = extendedStake?.stakedIotaId; + const isPreparingUnstake = !unstakeData || isUnstakeTxPending; + + async function handleUnstake(): Promise<void> { + if (!unstakeData) return; + + await signAndExecuteTransaction( + { + transaction: unstakeData.transaction, + }, + { + onSuccess: (tx) => { + addNotification('Unstake transaction has been sent'); + onSuccess(tx); + }, + }, + ).catch(() => { + addNotification('Unstake transaction was not sent', NotificationType.Error); + }); + } + + if (isLoadingDelegatedStakeData || loadingValidators) { + return ( + <div className="flex h-full w-full items-center justify-center p-2"> + <LoadingIndicator /> + </div> + ); + } + + if (isError || errorValidators) { + return ( + <div className="mb-2 flex h-full w-full items-center justify-center p-2"> + <InfoBox + title="Something went wrong" + supportingText={delegatedStakeDataError?.message ?? 'An error occurred'} + style={InfoBoxStyle.Default} + type={InfoBoxType.Error} + icon={<Warning />} + /> + </div> + ); + } + + return ( + <DialogLayout> + <Header title="Unstake" onClose={handleClose} onBack={onBack} titleCentered /> + <DialogLayoutBody> + <div className="flex flex-col gap-y-md"> + <Validator + address={extendedStake.validatorAddress} + isSelected + showActiveStatus={showActiveStatus} + /> + + <ValidatorStakingData + validatorAddress={extendedStake.validatorAddress} + stakeId={extendedStake.stakedIotaId} + isUnstake + /> + + <StakeRewardsPanel + stakingRewards={extendedStake.estimatedReward} + totalStaked={totalStakeOriginal} + /> + + <Panel hasBorder> + <div className="flex flex-col gap-y-sm p-md"> + <KeyValueInfo + keyText="Gas Fees" + value={gasFormatted || '-'} + supportingLabel={GAS_SYMBOL} + fullwidth + /> + </div> + </Panel> + </div> + </DialogLayoutBody> + + <DialogLayoutFooter> + <Button + type={ButtonType.Secondary} + fullWidth + onClick={handleUnstake} + disabled={isPreparingUnstake || isTransactionPending || !delegationId} + text="Unstake" + icon={ + isPreparingUnstake ? ( + <LoadingIndicator data-testid="loading-indicator" /> + ) : null + } + iconAfterText + /> + </DialogLayoutFooter> + </DialogLayout> + ); +} diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/views/index.ts b/apps/wallet-dashboard/components/Dialogs/unstake/views/index.ts new file mode 100644 index 00000000000..88b177871cd --- /dev/null +++ b/apps/wallet-dashboard/components/Dialogs/unstake/views/index.ts @@ -0,0 +1,5 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './UnstakeView'; +export * from './UnstakeTimelockedObjectsView'; diff --git a/apps/wallet-dashboard/components/Dialogs/vesting/VestingScheduleBox.tsx b/apps/wallet-dashboard/components/Dialogs/vesting/VestingScheduleBox.tsx index 25f861590a0..d9a93fc8d7c 100644 --- a/apps/wallet-dashboard/components/Dialogs/vesting/VestingScheduleBox.tsx +++ b/apps/wallet-dashboard/components/Dialogs/vesting/VestingScheduleBox.tsx @@ -8,7 +8,7 @@ import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; import { LockLocked } from '@iota/ui-icons'; interface VestingScheduleBoxProps { - amount: number; + amount: bigint; expirationTimestampMs: number; } diff --git a/apps/wallet-dashboard/components/Popup/Popup.tsx b/apps/wallet-dashboard/components/Popup/Popup.tsx deleted file mode 100644 index e16a915882c..00000000000 --- a/apps/wallet-dashboard/components/Popup/Popup.tsx +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -import React from 'react'; -import { usePopups } from '@/hooks'; - -function Popup(): JSX.Element { - const { popups, closePopup } = usePopups(); - - return ( - <> - {popups.map((popup, index) => ( - <div - key={index} - className="fixed left-0 top-0 z-[1000] flex h-full w-full items-center justify-center bg-black/20" - > - <div className="relative"> - <div className="absolute left-2/4 top-2/4 flex max-h-[80vh] min-w-[200px] -translate-x-2/4 -translate-y-2/4 flex-col gap-3 overflow-y-auto rounded-lg bg-white p-5 text-black"> - <button className="cursor-pointer self-end" onClick={closePopup}> - X - </button> - {popup} - </div> - </div> - </div> - ))} - </> - ); -} - -export default Popup; diff --git a/apps/wallet-dashboard/components/Popup/PopupProvider.tsx b/apps/wallet-dashboard/components/Popup/PopupProvider.tsx deleted file mode 100644 index 8eb6fbfc3a3..00000000000 --- a/apps/wallet-dashboard/components/Popup/PopupProvider.tsx +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 -'use client'; -import { PopupContext } from '@/contexts'; -import React, { useState, ReactNode } from 'react'; - -interface PopupProviderProps { - children: ReactNode; -} - -function PopupProvider({ children }: PopupProviderProps): JSX.Element { - const [popups, setPopups] = useState<ReactNode[]>([]); - - const openPopup = (content: ReactNode) => { - setPopups((prevPopups) => [...prevPopups, content]); - }; - - const closePopup = () => { - setPopups((prevPopups) => prevPopups.slice(0, prevPopups.length - 1)); - }; - - return ( - <PopupContext.Provider value={{ popups, openPopup, closePopup }}> - {children} - </PopupContext.Provider> - ); -} - -export default PopupProvider; diff --git a/apps/wallet-dashboard/components/Popup/Popups/MigratePopup.tsx b/apps/wallet-dashboard/components/Popup/Popups/MigratePopup.tsx deleted file mode 100644 index e824e41a24d..00000000000 --- a/apps/wallet-dashboard/components/Popup/Popups/MigratePopup.tsx +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -import React from 'react'; -import { VirtualList } from '@/components'; -import { - useCurrentAccount, - useIotaClientContext, - useSignAndExecuteTransaction, -} from '@iota/dapp-kit'; -import { getNetwork, IotaObjectData } from '@iota/iota-sdk/client'; -import { useMigrationTransaction } from '@/hooks/useMigrationTransaction'; -import { Button, InfoBox, InfoBoxStyle, InfoBoxType } from '@iota/apps-ui-kit'; -import { useNotifications } from '@/hooks'; -import { NotificationType } from '@/stores/notificationStore'; -import { Loader, Warning } from '@iota/ui-icons'; - -interface MigratePopupProps { - basicOutputObjects: IotaObjectData[] | undefined; - nftOutputObjects: IotaObjectData[] | undefined; - closePopup: () => void; - onSuccess?: (digest: string) => void; -} - -function MigratePopup({ - basicOutputObjects = [], - nftOutputObjects = [], - closePopup, - onSuccess, -}: MigratePopupProps): JSX.Element { - const account = useCurrentAccount(); - const { addNotification } = useNotifications(); - const { - data: migrateData, - isPending, - isError, - error, - } = useMigrationTransaction(account?.address || '', basicOutputObjects, nftOutputObjects); - - const { network } = useIotaClientContext(); - const { explorer } = getNetwork(network); - const { mutateAsync: signAndExecuteTransaction, isPending: isSendingTransaction } = - useSignAndExecuteTransaction(); - - async function handleMigrate(): Promise<void> { - if (!migrateData) return; - signAndExecuteTransaction( - { - transaction: migrateData.transaction, - }, - { - onSuccess: (tx) => { - if (onSuccess) { - onSuccess(tx.digest); - } - }, - }, - ) - .then(() => { - closePopup(); - addNotification('Migration transaction has been sent'); - }) - .catch(() => { - addNotification('Migration transaction was not sent', NotificationType.Error); - }); - } - - const virtualItem = (asset: IotaObjectData): JSX.Element => ( - <a href={`${explorer}/object/${asset.objectId}`} target="_blank" rel="noreferrer"> - {asset.objectId} - </a> - ); - return ( - <div className="flex min-w-[300px] flex-col gap-2"> - <div className="flex flex-col"> - <h1>Migratable Basic Outputs: {basicOutputObjects?.length}</h1> - <VirtualList - items={basicOutputObjects ?? []} - estimateSize={() => 30} - render={virtualItem} - /> - </div> - <div className="flex flex-col"> - <h1>Migratable Nft Outputs: {nftOutputObjects?.length}</h1> - <VirtualList - items={nftOutputObjects ?? []} - estimateSize={() => 30} - render={virtualItem} - /> - </div> - <p>Gas Fees: {migrateData?.gasBudget?.toString() || '--'}</p> - {isError ? ( - <InfoBox - type={InfoBoxType.Error} - title={error?.message || 'Error creating migration transcation'} - icon={<Warning />} - style={InfoBoxStyle.Elevated} - /> - ) : null} - <Button - text="Migrate" - disabled={isPending || isError || isSendingTransaction} - onClick={handleMigrate} - icon={ - isPending || isSendingTransaction ? ( - <Loader className="h-4 w-4 animate-spin" /> - ) : null - } - iconAfterText - /> - </div> - ); -} - -export default MigratePopup; diff --git a/apps/wallet-dashboard/components/Popup/Popups/SendAssetPopup.tsx b/apps/wallet-dashboard/components/Popup/Popups/SendAssetPopup.tsx deleted file mode 100644 index 679c4002d96..00000000000 --- a/apps/wallet-dashboard/components/Popup/Popups/SendAssetPopup.tsx +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -import React, { useCallback, useState } from 'react'; -import { IotaObjectData } from '@iota/iota-sdk/client'; -import { VisualAssetTile, Input } from '@/components'; -import { Button } from '@/components/Buttons'; -import { FlexDirection } from '@/lib/ui/enums'; -import { useCurrentAccount } from '@iota/dapp-kit'; -import { createNftSendValidationSchema, ValidationError } from '@iota/core'; -import { useRouter } from 'next/navigation'; -import { useNotifications } from '@/hooks'; -import { NotificationType } from '@/stores/notificationStore'; -import { useCreateSendAssetTransaction } from '@/hooks'; -import { ASSETS_ROUTE } from '@/lib/constants/routes.constants'; - -interface SendAssetPopupProps { - asset: IotaObjectData; - onClose: () => void; -} - -export default function SendAssetPopup({ asset, onClose }: SendAssetPopupProps): JSX.Element { - const [recipientAddress, setRecipientAddress] = useState<string>(''); - const [errors, setErrors] = useState<string[]>([]); - const activeAddress = useCurrentAccount()?.address; - const router = useRouter(); - const { addNotification } = useNotifications(); - const { mutation: sendAsset } = useCreateSendAssetTransaction( - asset.objectId, - onSendAssetSuccess, - onSendAssetError, - ); - - const schema = createNftSendValidationSchema(activeAddress || '', asset.objectId); - - async function handleAddressChange(address: string): Promise<void> { - setRecipientAddress(address); - - try { - await schema.validate({ to: address }); - setErrors([]); - } catch (error) { - if (error instanceof ValidationError) { - setErrors(error.errors); - } - } - } - - function onSendAssetSuccess() { - addNotification('Transfer transaction successful', NotificationType.Success); - onClose?.(); - router.push(ASSETS_ROUTE.path + '/assets'); - } - - function onSendAssetError() { - addNotification('Transfer transaction failed', NotificationType.Error); - onClose?.(); - } - - const handleSendAsset = useCallback(async () => { - try { - await sendAsset.mutateAsync(recipientAddress); - } catch (error) { - addNotification('Transfer transaction failed', NotificationType.Error); - } - }, [recipientAddress, sendAsset, addNotification]); - - return ( - <div className="flex flex-col space-y-4"> - <VisualAssetTile asset={asset} flexDirection={FlexDirection.Column} /> - <div className="flex flex-col space-y-2"> - <Input - type="text" - value={recipientAddress} - placeholder="Enter Address" - onChange={(e) => handleAddressChange(e.target.value)} - label="Enter recipient address" - error={errors[0]} - /> - </div> - <Button onClick={handleSendAsset}>Send</Button> - <Button onClick={onClose}>Cancel</Button> - </div> - ); -} diff --git a/apps/wallet-dashboard/components/Popup/Popups/UnstakePopup.tsx b/apps/wallet-dashboard/components/Popup/Popups/UnstakePopup.tsx deleted file mode 100644 index 0518809fced..00000000000 --- a/apps/wallet-dashboard/components/Popup/Popups/UnstakePopup.tsx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -import React from 'react'; -import { Button } from '@/components'; -import { useUnstakeTransaction } from '@/hooks'; -import { useCurrentAccount, useSignAndExecuteTransaction } from '@iota/dapp-kit'; -import { ExtendedDelegatedStake } from '@iota/core'; - -interface UnstakePopupProps { - extendedStake: ExtendedDelegatedStake; - closePopup: () => void; -} - -function UnstakePopup({ extendedStake, closePopup }: UnstakePopupProps): JSX.Element { - const account = useCurrentAccount(); - const { data: unstakeData } = useUnstakeTransaction( - extendedStake.stakedIotaId, - account?.address || '', - ); - const { mutateAsync: signAndExecuteTransaction, isPending } = useSignAndExecuteTransaction(); - - async function handleUnstake(): Promise<void> { - if (!unstakeData) return; - await signAndExecuteTransaction({ - transaction: unstakeData.transaction, - }); - closePopup(); - } - - return ( - <div className="flex min-w-[300px] flex-col gap-2"> - <p>Stake ID: {extendedStake.stakedIotaId}</p> - <p>Validator: {extendedStake.validatorAddress}</p> - <p>Stake: {extendedStake.principal}</p> - {extendedStake.status === 'Active' && ( - <p>Estimated reward: {extendedStake.estimatedReward}</p> - )} - <p>Gas Fees: {unstakeData?.gasBudget?.toString() || '--'}</p> - {isPending ? ( - <Button disabled>Loading...</Button> - ) : ( - <Button onClick={handleUnstake}>Confirm Unstake</Button> - )} - </div> - ); -} - -export default UnstakePopup; diff --git a/apps/wallet-dashboard/components/Popup/Popups/VestingPopup/TimelockedUnstakePopup.tsx b/apps/wallet-dashboard/components/Popup/Popups/VestingPopup/TimelockedUnstakePopup.tsx deleted file mode 100644 index 9cfdc96f035..00000000000 --- a/apps/wallet-dashboard/components/Popup/Popups/VestingPopup/TimelockedUnstakePopup.tsx +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -import React from 'react'; -import { Button } from '@/components'; -import { useNotifications, useTimelockedUnstakeTransaction } from '@/hooks'; -import { useSignAndExecuteTransaction } from '@iota/dapp-kit'; -import { IotaValidatorSummary } from '@iota/iota-sdk/client'; -import { NotificationType } from '@/stores/notificationStore'; -import { TimelockedStakedObjectsGrouped } from '@/lib/utils'; - -interface UnstakePopupProps { - accountAddress: string; - delegatedStake: TimelockedStakedObjectsGrouped; - validatorInfo: IotaValidatorSummary; - closePopup: () => void; - onSuccess?: (digest: string) => void; -} - -function TimelockedUnstakePopup({ - accountAddress, - delegatedStake, - validatorInfo, - closePopup, - onSuccess, -}: UnstakePopupProps): JSX.Element { - const objectIds = delegatedStake.stakes.map((stake) => stake.timelockedStakedIotaId); - const { data: timelockedUnstake } = useTimelockedUnstakeTransaction(objectIds, accountAddress); - const { mutateAsync: signAndExecuteTransaction, isPending } = useSignAndExecuteTransaction(); - const { addNotification } = useNotifications(); - - async function handleTimelockedUnstake(): Promise<void> { - if (!timelockedUnstake) return; - signAndExecuteTransaction( - { - transaction: timelockedUnstake.transaction, - }, - { - onSuccess: (tx) => { - if (onSuccess) { - onSuccess(tx.digest); - } - }, - }, - ) - .then(() => { - closePopup(); - addNotification('Unstake transaction has been sent'); - }) - .catch(() => { - addNotification('Unstake transaction was not sent', NotificationType.Error); - }); - } - - return ( - <div className="flex min-w-[300px] flex-col gap-2"> - <p>Validator Name: {validatorInfo.name}</p> - <p>Validator Address: {delegatedStake.validatorAddress}</p> - <p>Stake Request Epoch: {delegatedStake.stakeRequestEpoch}</p> - <p>Rewards: {validatorInfo.rewardsPool}</p> - <p>Total Stakes: {delegatedStake.stakes.length}</p> - {delegatedStake.stakes.map((stake, index) => { - return ( - <div key={stake.timelockedStakedIotaId} className="m-4 flex flex-col"> - <span> - Stake {index + 1}: {stake.timelockedStakedIotaId} - </span> - <span>Expiration time: {stake.expirationTimestampMs}</span> - <span>Label: {stake.label}</span> - <span>Status: {stake.status}</span> - </div> - ); - })} - <p>Gas Fees: {timelockedUnstake?.gasBudget?.toString() || '--'}</p> - {isPending ? ( - <Button disabled>Loading...</Button> - ) : ( - <Button onClick={handleTimelockedUnstake}>Confirm Unstake</Button> - )} - </div> - ); -} - -export default TimelockedUnstakePopup; diff --git a/apps/wallet-dashboard/components/Popup/Popups/VestingPopup/index.ts b/apps/wallet-dashboard/components/Popup/Popups/VestingPopup/index.ts deleted file mode 100644 index 2a8ca3b61df..00000000000 --- a/apps/wallet-dashboard/components/Popup/Popups/VestingPopup/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -export { default as TimelockedUnstakePopup } from './TimelockedUnstakePopup'; diff --git a/apps/wallet-dashboard/components/Popup/Popups/index.ts b/apps/wallet-dashboard/components/Popup/Popups/index.ts deleted file mode 100644 index ebdfc7f7391..00000000000 --- a/apps/wallet-dashboard/components/Popup/Popups/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -export { default as UnstakePopup } from './UnstakePopup'; -export { default as SendAssetPopup } from './SendAssetPopup'; - -export * from './VestingPopup'; diff --git a/apps/wallet-dashboard/components/Popup/index.ts b/apps/wallet-dashboard/components/Popup/index.ts deleted file mode 100644 index baeafee23a7..00000000000 --- a/apps/wallet-dashboard/components/Popup/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -export { default as Popup } from './Popup'; -export { default as PopupProvider } from './PopupProvider'; - -export * from './Popups'; diff --git a/apps/wallet-dashboard/components/StakeRewardsPanel.tsx b/apps/wallet-dashboard/components/StakeRewardsPanel.tsx new file mode 100644 index 00000000000..a7e5e84619c --- /dev/null +++ b/apps/wallet-dashboard/components/StakeRewardsPanel.tsx @@ -0,0 +1,70 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Divider, KeyValueInfo, Panel } from '@iota/apps-ui-kit'; +import { TimeUnit, useFormatCoin, useGetTimeBeforeEpochNumber, useTimeAgo } from '@iota/core'; +import { useIotaClientQuery } from '@iota/dapp-kit'; +import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; + +interface StakeRewardsPanelProps { + stakingRewards: string | number | undefined; + totalStaked: number | bigint; + isTimelocked?: boolean; +} +export function StakeRewardsPanel({ + stakingRewards, + totalStaked, + isTimelocked, +}: StakeRewardsPanelProps) { + const { epoch = '0' } = useIotaClientQuery('getLatestIotaSystemState')?.data || {}; + const [rewards, symbol] = useFormatCoin(stakingRewards ?? 0, IOTA_TYPE_ARG); + const [stakedBalance] = useFormatCoin(totalStaked, IOTA_TYPE_ARG); + const [stakedAndRewards] = useFormatCoin( + BigInt(stakingRewards || 0) + BigInt(totalStaked), + IOTA_TYPE_ARG, + ); + + const { data: currentEpochEndTime } = useGetTimeBeforeEpochNumber(Number(epoch) + 1); + const currentEpochEndTimeAgo = useTimeAgo({ + timeFrom: currentEpochEndTime, + endLabel: '--', + shortedTimeLabel: false, + shouldEnd: true, + maxTimeUnit: TimeUnit.ONE_HOUR, + }); + + const currentEpochEndTimeFormatted = + currentEpochEndTime > 0 ? currentEpochEndTimeAgo : `Epoch #${epoch}`; + + return ( + <Panel hasBorder> + <div className="flex flex-col gap-y-sm p-md"> + <KeyValueInfo + keyText="Current Epoch Ends" + value={currentEpochEndTimeFormatted} + fullwidth + /> + <Divider /> + <KeyValueInfo + keyText="Your Stake" + value={stakedBalance} + supportingLabel={symbol} + fullwidth + /> + <KeyValueInfo + keyText="Rewards Earned" + value={rewards} + supportingLabel={symbol} + fullwidth + /> + <Divider /> + <KeyValueInfo + keyText={'Total unstaked ' + (isTimelocked ? 'Timelocked' : 'IOTA')} + value={stakedAndRewards} + supportingLabel={symbol} + fullwidth + /> + </div> + </Panel> + ); +} diff --git a/apps/wallet-dashboard/components/SupplyIncreaseVestingOverview.tsx b/apps/wallet-dashboard/components/SupplyIncreaseVestingOverview.tsx new file mode 100644 index 00000000000..7608bda1a3a --- /dev/null +++ b/apps/wallet-dashboard/components/SupplyIncreaseVestingOverview.tsx @@ -0,0 +1,151 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { useCurrentAccount, useIotaClient } from '@iota/dapp-kit'; +import { useGetSupplyIncreaseVestingObjects } from '@/hooks'; +import { + ButtonType, + Card, + CardAction, + CardActionType, + CardBody, + CardType, + LabelText, + LabelTextSize, + Panel, + Title, +} from '@iota/apps-ui-kit'; +import { StakeDialog, useStakeDialog } from './Dialogs'; +import { TIMELOCK_IOTA_TYPE, useCountdownByTimestamp, useFormatCoin } from '@iota/core'; +import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; +import SvgClock from '@iota/ui-icons/src/Clock'; +import { useQueryClient } from '@tanstack/react-query'; + +export function SupplyIncreaseVestingOverview() { + const account = useCurrentAccount(); + const address = account?.address || ''; + const iotaClient = useIotaClient(); + const queryClient = useQueryClient(); + const { + nextPayout, + supplyIncreaseVestingSchedule, + supplyIncreaseVestingMapped, + supplyIncreaseVestingStakedMapped, + } = useGetSupplyIncreaseVestingObjects(address); + + const { + stakeDialogView, + setStakeDialogView, + selectedStake, + selectedValidator, + setSelectedValidator, + handleCloseStakeDialog, + handleNewStake, + } = useStakeDialog(); + + const formattedLastPayoutExpirationTime = useCountdownByTimestamp( + Number(nextPayout?.expirationTimestampMs), + { showSeconds: false, showMinutes: false }, + ); + const [formattedNextPayout, nextPayoutSymbol, nextPayoutResult] = useFormatCoin( + nextPayout?.amount, + IOTA_TYPE_ARG, + ); + + const [formattedAvailableStaking, availableStakingSymbol] = useFormatCoin( + supplyIncreaseVestingSchedule.availableStaking, + IOTA_TYPE_ARG, + ); + + const showSupplyIncreaseVestingOverview = + supplyIncreaseVestingMapped.length > 0 || supplyIncreaseVestingStakedMapped.length > 0; + + function handleOnSuccess(digest: string): void { + iotaClient + .waitForTransaction({ + digest, + }) + .then(() => { + queryClient.invalidateQueries({ + queryKey: ['get-timelocked-staked-objects', account?.address], + }); + queryClient.invalidateQueries({ + queryKey: [ + 'get-all-owned-objects', + account?.address, + { + StructType: TIMELOCK_IOTA_TYPE, + }, + ], + }); + }); + } + + return showSupplyIncreaseVestingOverview ? ( + <div style={{ gridArea: 'vesting' }} className="with-vesting flex grow overflow-hidden"> + <Panel> + <Title title="Vesting" /> + <div className="flex h-full w-full items-center gap-md p-md--rs"> + <div className="w-1/2"> + <Card type={CardType.Filled}> + <CardBody + title="" + subtitle={ + <LabelText + size={LabelTextSize.Large} + label="Next reward" + text={ + nextPayoutResult.isPending + ? '-' + : `${formattedNextPayout} ` + } + supportingLabel={nextPayoutSymbol} + /> + } + /> + <CardAction + type={CardActionType.Button} + buttonType={ButtonType.Ghost} + title={formattedLastPayoutExpirationTime} + icon={<SvgClock />} + /> + </Card> + </div> + <div className="w-1/2"> + <Card type={CardType.Filled}> + <CardBody + title="" + subtitle={ + <LabelText + size={LabelTextSize.Large} + label="Available for staking" + text={formattedAvailableStaking} + supportingLabel={availableStakingSymbol} + /> + } + /> + <CardAction + type={CardActionType.Button} + buttonType={ButtonType.Primary} + title={'Stake'} + onClick={() => handleNewStake()} + buttonDisabled={!supplyIncreaseVestingSchedule.availableStaking} + /> + </Card> + </div> + </div> + </Panel> + <StakeDialog + isTimelockedStaking={true} + stakedDetails={selectedStake} + onSuccess={handleOnSuccess} + handleClose={handleCloseStakeDialog} + view={stakeDialogView} + setView={setStakeDialogView} + selectedValidator={selectedValidator} + setSelectedValidator={setSelectedValidator} + maxStakableTimelockedAmount={BigInt(supplyIncreaseVestingSchedule.availableStaking)} + /> + </div> + ) : null; +} diff --git a/apps/wallet-dashboard/components/VirtualList.tsx b/apps/wallet-dashboard/components/VirtualList.tsx index 54920f7d64c..58dc598a364 100644 --- a/apps/wallet-dashboard/components/VirtualList.tsx +++ b/apps/wallet-dashboard/components/VirtualList.tsx @@ -27,7 +27,7 @@ function VirtualList<T>({ estimateSize, render, onClick, - heightClassName = 'h-full', + heightClassName = 'h-fit', overflowClassName, }: VirtualListProps<T>): JSX.Element { const containerRef = React.useRef<HTMLDivElement | null>(null); @@ -56,14 +56,7 @@ function VirtualList<T>({ if (lastItem.index >= items.length - 1 && hasNextPage && !isFetchingNextPage) { fetchNextPage(); } - }, [ - hasNextPage, - fetchNextPage, - items.length, - isFetchingNextPage, - virtualizer, - virtualizer.getVirtualItems(), - ]); + }, [hasNextPage, fetchNextPage, items.length, isFetchingNextPage, virtualizer, virtualItems]); return ( <div diff --git a/apps/wallet-dashboard/components/account-balance/AccountBalance.tsx b/apps/wallet-dashboard/components/account-balance/AccountBalance.tsx index 151a46d473f..9bb3f297b27 100644 --- a/apps/wallet-dashboard/components/account-balance/AccountBalance.tsx +++ b/apps/wallet-dashboard/components/account-balance/AccountBalance.tsx @@ -22,11 +22,11 @@ export function AccountBalance() { const [isSendTokenDialogOpen, setIsSendTokenDialogOpen] = useState(false); const explorerLink = `${explorer}/address/${address}`; - function openSendTokenPopup(): void { + function openSendTokenDialog(): void { setIsSendTokenDialogOpen(true); } - function openReceiveTokenPopup(): void { + function openReceiveTokenDialog(): void { setIsReceiveDialogOpen(true); } @@ -56,7 +56,7 @@ export function AccountBalance() { </span> <div className="flex w-full max-w-56 gap-xs"> <Button - onClick={openSendTokenPopup} + onClick={openSendTokenDialog} text="Send" size={ButtonSize.Small} disabled={!address} @@ -64,7 +64,7 @@ export function AccountBalance() { fullWidth /> <Button - onClick={openReceiveTokenPopup} + onClick={openReceiveTokenDialog} type={ButtonType.Secondary} text="Receive" size={ButtonSize.Small} diff --git a/apps/wallet-dashboard/components/coins/MyCoins.tsx b/apps/wallet-dashboard/components/coins/MyCoins.tsx index fc441d76148..411d7cdc702 100644 --- a/apps/wallet-dashboard/components/coins/MyCoins.tsx +++ b/apps/wallet-dashboard/components/coins/MyCoins.tsx @@ -71,9 +71,9 @@ function MyCoins(): React.JSX.Element { return ( <Panel> - <div className="flex w-full flex-col"> + <div className="flex h-full w-full flex-col"> <Title title="My Coins" /> - <div className="px-sm pb-md pt-sm"> + <div className="px-sm py-sm"> <div className="inline-flex"> <SegmentedButton type={SegmentedButtonType.Filled}> {TOKEN_CATEGORIES.map(({ label, value }) => { @@ -96,37 +96,35 @@ function MyCoins(): React.JSX.Element { })} </SegmentedButton> </div> - <div className="pb-md pt-sm"> - {[TokenCategory.All, TokenCategory.Recognized].includes( - selectedTokenCategory, - ) && - recognized?.map((coin, index) => { - return ( - <CoinItem - key={index} - coinType={coin.coinType} - balance={BigInt(coin.totalBalance)} - onClick={() => openSendTokenDialog(coin)} - icon={ - <RecognizedBadge className="h-4 w-4 text-primary-40" /> - } - /> - ); - })} - {[TokenCategory.All, TokenCategory.Unrecognized].includes( - selectedTokenCategory, - ) && - unrecognized?.map((coin, index) => { - return ( - <CoinItem - key={index} - coinType={coin.coinType} - balance={BigInt(coin.totalBalance)} - onClick={() => openSendTokenDialog(coin)} - /> - ); - })} - </div> + </div> + <div className="h-full overflow-y-auto px-sm pb-md pt-sm"> + {[TokenCategory.All, TokenCategory.Recognized].includes( + selectedTokenCategory, + ) && + recognized?.map((coin, index) => { + return ( + <CoinItem + key={index} + coinType={coin.coinType} + balance={BigInt(coin.totalBalance)} + onClick={() => openSendTokenDialog(coin)} + icon={<RecognizedBadge className="h-4 w-4 text-primary-40" />} + /> + ); + })} + {[TokenCategory.All, TokenCategory.Unrecognized].includes( + selectedTokenCategory, + ) && + unrecognized?.map((coin, index) => { + return ( + <CoinItem + key={index} + coinType={coin.coinType} + balance={BigInt(coin.totalBalance)} + onClick={() => openSendTokenDialog(coin)} + /> + ); + })} </div> </div> {selectedCoin && activeAccountAddress && ( diff --git a/apps/wallet-dashboard/components/index.ts b/apps/wallet-dashboard/components/index.ts index 1e655a49bdc..fcccf7b3a95 100644 --- a/apps/wallet-dashboard/components/index.ts +++ b/apps/wallet-dashboard/components/index.ts @@ -13,7 +13,6 @@ export * from './PaginationOptions'; export * from './account-balance/AccountBalance'; export * from './coins'; -export * from './Popup'; export * from './AppList'; export * from './Cards'; export * from './Buttons'; @@ -26,5 +25,7 @@ export * from './tiles'; export * from './migration'; export * from './Toaster'; export * from './Banner'; +export * from './StakeRewardsPanel'; export * from './MigrationOverview'; +export * from './SupplyIncreaseVestingOverview'; export * from './staked-timelock-object'; diff --git a/apps/wallet-dashboard/components/migration/MigrationObjectsPanel.tsx b/apps/wallet-dashboard/components/migration/MigrationObjectsPanel.tsx index 4d5d80d0af3..915cc56dda5 100644 --- a/apps/wallet-dashboard/components/migration/MigrationObjectsPanel.tsx +++ b/apps/wallet-dashboard/components/migration/MigrationObjectsPanel.tsx @@ -6,7 +6,7 @@ import { useGroupedMigrationObjectsByExpirationDate } from '@/hooks'; import { STARDUST_MIGRATABLE_OBJECTS_FILTER_LIST, - STARDUST_UNMIGRATABLE_OBJECTS_FILTER_LIST, + STARDUST_TIMELOCKED_OBJECTS_FILTER_LIST, } from '@/lib/constants'; import { StardustOutputDetailsFilter } from '@/lib/enums'; import { @@ -33,7 +33,7 @@ import { filterMigrationObjects } from '@/lib/utils'; const FILTERS = { migratable: STARDUST_MIGRATABLE_OBJECTS_FILTER_LIST, - unmigratable: STARDUST_UNMIGRATABLE_OBJECTS_FILTER_LIST, + timelocked: STARDUST_TIMELOCKED_OBJECTS_FILTER_LIST, }; interface MigrationObjectsPanelProps { @@ -58,7 +58,7 @@ export function MigrationObjectsPanel({ const filteredObjects = filterMigrationObjects(resolvedObjects, stardustOutputDetailsFilter); - const filters = isTimelocked ? FILTERS.unmigratable : FILTERS.migratable; + const filters = isTimelocked ? FILTERS.timelocked : FILTERS.migratable; const isHidden = selectedObjects.length === 0; return ( diff --git a/apps/wallet-dashboard/components/staked-timelock-object/StakedTimelockObject.tsx b/apps/wallet-dashboard/components/staked-timelock-object/StakedTimelockObject.tsx index 8696705bc12..f7e21915a3a 100644 --- a/apps/wallet-dashboard/components/staked-timelock-object/StakedTimelockObject.tsx +++ b/apps/wallet-dashboard/components/staked-timelock-object/StakedTimelockObject.tsx @@ -27,11 +27,11 @@ export function StakedTimelockObject({ // TODO probably we could calculate estimated reward on grouping stage. const summary = timelockedStakedObject.stakes.reduce( (acc, stake) => { - const estimatedReward = stake.status === 'Active' ? stake.estimatedReward : 0; + const estimatedReward = stake.status === 'Active' ? BigInt(stake.estimatedReward) : 0n; return { principal: BigInt(stake.principal) + acc.principal, - estimatedReward: BigInt(estimatedReward) + acc.estimatedReward, + estimatedReward: estimatedReward + acc.estimatedReward, stakeRequestEpoch: stake.stakeRequestEpoch, }; }, diff --git a/apps/wallet-dashboard/components/staking-overview/StartStaking.tsx b/apps/wallet-dashboard/components/staking-overview/StartStaking.tsx index 828abc974ab..573a254a3d2 100644 --- a/apps/wallet-dashboard/components/staking-overview/StartStaking.tsx +++ b/apps/wallet-dashboard/components/staking-overview/StartStaking.tsx @@ -35,7 +35,6 @@ export function StartStaking() { {isDialogStakeOpen && stakeDialogView && ( <StakeDialog stakedDetails={selectedStake} - isOpen={isDialogStakeOpen} handleClose={handleCloseStakeDialog} view={stakeDialogView} setView={setStakeDialogView} diff --git a/apps/wallet-dashboard/components/staking-overview/index.ts b/apps/wallet-dashboard/components/staking-overview/index.ts index 88d8d1794ef..a2fdb941d58 100644 --- a/apps/wallet-dashboard/components/staking-overview/index.ts +++ b/apps/wallet-dashboard/components/staking-overview/index.ts @@ -2,3 +2,4 @@ // SPDX-License-Identifier: Apache-2.0 export * from './StakingOverview'; +export * from './StartStaking'; diff --git a/apps/wallet-dashboard/components/transactions/TransactionAmount.tsx b/apps/wallet-dashboard/components/transactions/TransactionAmount.tsx index ae7654b0273..498ebc19522 100644 --- a/apps/wallet-dashboard/components/transactions/TransactionAmount.tsx +++ b/apps/wallet-dashboard/components/transactions/TransactionAmount.tsx @@ -5,7 +5,7 @@ import { useFormatCoin } from '@iota/core'; interface TransactionAmountProps { - amount: string | number; + amount: string | number | bigint; coinType: string; label: string; approximation?: boolean; diff --git a/apps/wallet-dashboard/components/transactions/TransactionsOverview.tsx b/apps/wallet-dashboard/components/transactions/TransactionsOverview.tsx index a590e3abcdb..fcaf74eddaa 100644 --- a/apps/wallet-dashboard/components/transactions/TransactionsOverview.tsx +++ b/apps/wallet-dashboard/components/transactions/TransactionsOverview.tsx @@ -9,7 +9,7 @@ function TransactionsOverview() { return ( <Panel> <Title title="Activity" /> - <div className="px-sm pb-md pt-sm"> + <div className="h-full overflow-y-auto px-sm pb-md pt-sm"> <TransactionsList /> </div> </Panel> diff --git a/apps/wallet-dashboard/contexts/PopupContext.ts b/apps/wallet-dashboard/contexts/PopupContext.ts deleted file mode 100644 index ced7b13cc33..00000000000 --- a/apps/wallet-dashboard/contexts/PopupContext.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -import { ReactNode, createContext } from 'react'; - -export interface PopupManager { - popups: ReactNode[]; - openPopup: (content: ReactNode) => void; - closePopup: () => void; -} - -export const PopupContext = createContext<PopupManager>({} as PopupManager); diff --git a/apps/wallet-dashboard/hooks/index.ts b/apps/wallet-dashboard/hooks/index.ts index f33eda9c3fc..5ad872afeed 100644 --- a/apps/wallet-dashboard/hooks/index.ts +++ b/apps/wallet-dashboard/hooks/index.ts @@ -1,8 +1,7 @@ // Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -export * from './useUnstakeTransaction'; -export * from './usePopups'; +export * from './useNewUnstakeTransaction'; export * from './useNewStakeTransaction'; export * from './useNotifications'; export * from './useSendCoinTransaction'; @@ -11,5 +10,6 @@ export * from './useGetCurrentEpochStartTimestamp'; export * from './useTimelockedUnstakeTransaction'; export * from './useExplorerLinkGetter'; export * from './useGetStardustMigratableObjects'; +export * from './useGetSupplyIncreaseVestingObjects'; export * from './useGroupedMigrationObjectsByExpirationDate'; export * from './useTransferTransaction'; diff --git a/apps/wallet-dashboard/hooks/useGetStardustMigratableObjects.ts b/apps/wallet-dashboard/hooks/useGetStardustMigratableObjects.ts index 8480e9d9e2a..e17bb3d6b3b 100644 --- a/apps/wallet-dashboard/hooks/useGetStardustMigratableObjects.ts +++ b/apps/wallet-dashboard/hooks/useGetStardustMigratableObjects.ts @@ -31,17 +31,17 @@ export function useGetStardustMigratableObjects(address: string) { queryFn: () => { const epochMs = Number(currentEpochMs) || 0; - const { migratable: migratableBasicOutputs, unmigratable: unmigratableBasicOutputs } = + const { migratable: migratableBasicOutputs, timelocked: timelockedBasicOutputs } = groupStardustObjectsByMigrationStatus(basicOutputObjects ?? [], epochMs, address); - const { migratable: migratableNftOutputs, unmigratable: unmigratableNftOutputs } = + const { migratable: migratableNftOutputs, timelocked: timelockedNftOutputs } = groupStardustObjectsByMigrationStatus(nftOutputObjects ?? [], epochMs, address); return { migratableBasicOutputs, - unmigratableBasicOutputs, + timelockedBasicOutputs, migratableNftOutputs, - unmigratableNftOutputs, + timelockedNftOutputs, }; }, enabled: @@ -52,9 +52,9 @@ export function useGetStardustMigratableObjects(address: string) { staleTime: TimeUnit.ONE_SECOND * TimeUnit.ONE_MINUTE * 5, placeholderData: { migratableBasicOutputs: [], - unmigratableBasicOutputs: [], + timelockedBasicOutputs: [], migratableNftOutputs: [], - unmigratableNftOutputs: [], + timelockedNftOutputs: [], }, }); } diff --git a/apps/wallet-dashboard/hooks/useGetSupplyIncreaseVestingObjects.ts b/apps/wallet-dashboard/hooks/useGetSupplyIncreaseVestingObjects.ts new file mode 100644 index 00000000000..58d19d63641 --- /dev/null +++ b/apps/wallet-dashboard/hooks/useGetSupplyIncreaseVestingObjects.ts @@ -0,0 +1,112 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { useGetCurrentEpochStartTimestamp } from '@/hooks'; +import { + SupplyIncreaseVestingPayout, + SupplyIncreaseVestingPortfolio, + TimelockedObject, + VestingOverview, +} from '@/lib/interfaces'; +import { + buildSupplyIncreaseVestingSchedule, + ExtendedDelegatedTimelockedStake, + formatDelegatedTimelockedStake, + getLatestOrEarliestSupplyIncreaseVestingPayout, + getVestingOverview, + isSupplyIncreaseVestingObject, + isTimelockedUnlockable, + mapTimelockObjects, +} from '@/lib/utils'; +import { + TIMELOCK_IOTA_TYPE, + useGetAllOwnedObjects, + useGetTimelockedStakedObjects, + useUnlockTimelockedObjectsTransaction, +} from '@iota/core'; +import { Transaction } from '@iota/iota-sdk/transactions'; + +export function useGetSupplyIncreaseVestingObjects(address: string): { + nextPayout: SupplyIncreaseVestingPayout | undefined; + lastPayout: SupplyIncreaseVestingPayout | undefined; + supplyIncreaseVestingSchedule: VestingOverview; + supplyIncreaseVestingPortfolio: SupplyIncreaseVestingPortfolio | undefined; + supplyIncreaseVestingMapped: TimelockedObject[]; + supplyIncreaseVestingStakedMapped: ExtendedDelegatedTimelockedStake[]; + isTimelockedStakedObjectsLoading: boolean; + unlockAllSupplyIncreaseVesting: + | { + transactionBlock: Transaction; + } + | undefined; + refreshStakeList: () => void; +} { + const { data: currentEpochMs } = useGetCurrentEpochStartTimestamp(); + + const { data: timelockedObjects, refetch: refetchGetAllOwnedObjects } = useGetAllOwnedObjects( + address || '', + { + StructType: TIMELOCK_IOTA_TYPE, + }, + ); + const { + data: timelockedStakedObjects, + isLoading: isTimelockedStakedObjectsLoading, + refetch: refetchTimelockedStakedObjects, + } = useGetTimelockedStakedObjects(address || ''); + + const supplyIncreaseVestingMapped = mapTimelockObjects(timelockedObjects || []).filter( + isSupplyIncreaseVestingObject, + ); + const supplyIncreaseVestingStakedMapped = formatDelegatedTimelockedStake( + timelockedStakedObjects || [], + ).filter(isSupplyIncreaseVestingObject); + + const supplyIncreaseVestingSchedule = getVestingOverview( + [...supplyIncreaseVestingMapped, ...supplyIncreaseVestingStakedMapped], + Number(currentEpochMs), + ); + + const nextPayout = getLatestOrEarliestSupplyIncreaseVestingPayout( + [...supplyIncreaseVestingMapped, ...supplyIncreaseVestingStakedMapped], + Number(currentEpochMs), + false, + ); + + const lastPayout = getLatestOrEarliestSupplyIncreaseVestingPayout( + [...supplyIncreaseVestingMapped, ...supplyIncreaseVestingStakedMapped], + Number(currentEpochMs), + true, + ); + + const supplyIncreaseVestingPortfolio = + lastPayout && buildSupplyIncreaseVestingSchedule(lastPayout, Number(currentEpochMs)); + + const supplyIncreaseVestingUnlocked = supplyIncreaseVestingMapped?.filter( + (supplyIncreaseVestingObject) => + isTimelockedUnlockable(supplyIncreaseVestingObject, Number(currentEpochMs)), + ); + const supplyIncreaseVestingUnlockedObjectIds: string[] = + supplyIncreaseVestingUnlocked.map((unlockedObject) => unlockedObject.id.id) || []; + const { data: unlockAllSupplyIncreaseVesting } = useUnlockTimelockedObjectsTransaction( + address || '', + supplyIncreaseVestingUnlockedObjectIds, + ); + + function refreshStakeList() { + refetchTimelockedStakedObjects(); + refetchGetAllOwnedObjects(); + } + + return { + nextPayout, + lastPayout, + supplyIncreaseVestingSchedule, + supplyIncreaseVestingPortfolio, + supplyIncreaseVestingMapped, + supplyIncreaseVestingStakedMapped, + isTimelockedStakedObjectsLoading, + unlockAllSupplyIncreaseVesting, + refreshStakeList, + }; +} diff --git a/apps/wallet-dashboard/hooks/useNewStakeTransaction.ts b/apps/wallet-dashboard/hooks/useNewStakeTransaction.ts index 7bd856cf77d..3e45ccd6144 100644 --- a/apps/wallet-dashboard/hooks/useNewStakeTransaction.ts +++ b/apps/wallet-dashboard/hooks/useNewStakeTransaction.ts @@ -9,26 +9,54 @@ import { import { useIotaClient } from '@iota/dapp-kit'; import { useQuery } from '@tanstack/react-query'; -export function useNewStakeTransaction( +export function useNewStakeTransaction(validator: string, amount: bigint, senderAddress: string) { + const client = useIotaClient(); + return useQuery({ + // eslint-disable-next-line @tanstack/query/exhaustive-deps + queryKey: ['stake-transaction', validator, amount.toString(), senderAddress], + queryFn: async () => { + const transaction = createStakeTransaction(amount, validator); + transaction.setSender(senderAddress); + await transaction.build({ client }); + return transaction; + }, + enabled: !!amount && !!validator && !!senderAddress, + gcTime: 0, + select: (transaction) => { + return { + transaction, + gasBudget: transaction.getData().gasData.budget, + }; + }, + }); +} + +export function useNewStakeTimelockedTransaction( validator: string, - amount: bigint, senderAddress: string, - isTimelockedStaking: boolean = false, - groupedTimelockObjects?: GroupedTimelockObject[], + groupedTimelockObjects: GroupedTimelockObject[], ) { + const amount = groupedTimelockObjects.reduce( + (acc, obj) => acc + (obj.totalLockedAmount - (obj.splitAmount ?? 0n)), + 0n, + ); const client = useIotaClient(); return useQuery({ // eslint-disable-next-line @tanstack/query/exhaustive-deps - queryKey: ['stake-transaction', validator, amount.toString(), senderAddress], + queryKey: [ + 'stake-timelocked-transaction', + validator, + senderAddress, + amount.toString(), + groupedTimelockObjects.length, + ], queryFn: async () => { - const transaction = isTimelockedStaking - ? createTimelockedStakeTransaction(groupedTimelockObjects || [], validator) - : createStakeTransaction(amount, validator); + const transaction = createTimelockedStakeTransaction(groupedTimelockObjects, validator); transaction.setSender(senderAddress); await transaction.build({ client }); return transaction; }, - enabled: !!amount && !!validator && !!senderAddress, + enabled: !!(validator && senderAddress && groupedTimelockObjects?.length), gcTime: 0, select: (transaction) => { return { diff --git a/apps/wallet-dashboard/hooks/useNewUnstakeTransaction.ts b/apps/wallet-dashboard/hooks/useNewUnstakeTransaction.ts new file mode 100644 index 00000000000..5704507f448 --- /dev/null +++ b/apps/wallet-dashboard/hooks/useNewUnstakeTransaction.ts @@ -0,0 +1,55 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { createTimelockedUnstakeTransaction, createUnstakeTransaction } from '@iota/core'; +import { useIotaClient } from '@iota/dapp-kit'; +import { useQuery } from '@tanstack/react-query'; + +export function useNewUnstakeTransaction(senderAddress: string, unstakeIotaId: string) { + const client = useIotaClient(); + + return useQuery({ + // eslint-disable-next-line @tanstack/query/exhaustive-deps + queryKey: ['unstake-transaction', unstakeIotaId, senderAddress], + queryFn: async () => { + const transaction = createUnstakeTransaction(unstakeIotaId); + transaction.setSender(senderAddress); + await transaction.build({ client }); + return transaction; + }, + enabled: !!(senderAddress && unstakeIotaId), + gcTime: 0, + select: (transaction) => { + return { + transaction, + gasBudget: transaction.getData().gasData.budget, + }; + }, + }); +} + +export function useNewUnstakeTimelockedTransaction( + senderAddress: string, + timelockedUnstakeIotaIds: string[], +) { + const client = useIotaClient(); + + return useQuery({ + // eslint-disable-next-line @tanstack/query/exhaustive-deps + queryKey: ['timelocked-unstake-transaction', timelockedUnstakeIotaIds, senderAddress], + queryFn: async () => { + const transaction = createTimelockedUnstakeTransaction(timelockedUnstakeIotaIds); + transaction.setSender(senderAddress); + await transaction.build({ client }); + return transaction; + }, + enabled: !!(senderAddress && timelockedUnstakeIotaIds?.length), + gcTime: 0, + select: (transaction) => { + return { + transaction, + gasBudget: transaction.getData().gasData.budget, + }; + }, + }); +} diff --git a/apps/wallet-dashboard/hooks/usePopups.ts b/apps/wallet-dashboard/hooks/usePopups.ts deleted file mode 100644 index b4867bbac73..00000000000 --- a/apps/wallet-dashboard/hooks/usePopups.ts +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -import { PopupContext, PopupManager } from '@/contexts'; -import { useContext } from 'react'; - -export const usePopups = (): PopupManager => { - return useContext(PopupContext); -}; diff --git a/apps/wallet-dashboard/hooks/useUnstakeTransaction.ts b/apps/wallet-dashboard/hooks/useUnstakeTransaction.ts deleted file mode 100644 index 9f8644eda4c..00000000000 --- a/apps/wallet-dashboard/hooks/useUnstakeTransaction.ts +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -import { createUnstakeTransaction } from '@iota/core'; -import { useIotaClient } from '@iota/dapp-kit'; -import { useQuery } from '@tanstack/react-query'; - -export function useUnstakeTransaction(stakedIotaId: string, senderAddress: string) { - const client = useIotaClient(); - return useQuery({ - // eslint-disable-next-line @tanstack/query/exhaustive-deps - queryKey: ['unstake-transaction', stakedIotaId, senderAddress], - queryFn: async () => { - const transaction = createUnstakeTransaction(stakedIotaId); - transaction.setSender(senderAddress); - await transaction.build({ client }); - return transaction; - }, - enabled: !!stakedIotaId && !!senderAddress, - gcTime: 0, - select: (transaction) => { - return { - transaction, - gasBudget: transaction.getData().gasData.budget, - }; - }, - }); -} diff --git a/apps/wallet-dashboard/lib/constants/migration.constants.ts b/apps/wallet-dashboard/lib/constants/migration.constants.ts index 5aa2c5a5c0f..1a203fc50e9 100644 --- a/apps/wallet-dashboard/lib/constants/migration.constants.ts +++ b/apps/wallet-dashboard/lib/constants/migration.constants.ts @@ -7,9 +7,8 @@ export const STARDUST_MIGRATABLE_OBJECTS_FILTER_LIST: StardustOutputDetailsFilte StardustOutputDetailsFilter, ); -export const STARDUST_UNMIGRATABLE_OBJECTS_FILTER_LIST: StardustOutputDetailsFilter[] = - Object.values(StardustOutputDetailsFilter).filter( - (element) => element !== StardustOutputDetailsFilter.WithExpiration, - ); +export const STARDUST_TIMELOCKED_OBJECTS_FILTER_LIST: StardustOutputDetailsFilter[] = Object.values( + StardustOutputDetailsFilter, +).filter((element) => element !== StardustOutputDetailsFilter.WithExpiration); export const MIGRATION_OBJECT_WITHOUT_UC_KEY = 'no-unlock-condition-timestamp'; diff --git a/apps/wallet-dashboard/lib/constants/vesting.constants.ts b/apps/wallet-dashboard/lib/constants/vesting.constants.ts index 5e290e70e06..51ace2168a7 100644 --- a/apps/wallet-dashboard/lib/constants/vesting.constants.ts +++ b/apps/wallet-dashboard/lib/constants/vesting.constants.ts @@ -32,7 +32,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xfe755ca67e3a0714f97ec3c49cfc6f3ecdab2673d96b5840294d3a5db376c99', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1697320800000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -42,7 +42,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x682d14613231dd1dde39397977cdfafb6b6263b5683b6782348c597c104b834', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1698530400000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -52,7 +52,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x93f2bf2d044e45e1a85c010c22357892d1625436b8c95b26dcdb6f309319064', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1699740000000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -62,7 +62,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x44fa510ba216cd555ecd6b99d1ebd612f82e2bf421091c973bca49b064dc72b', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1700949600000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -72,7 +72,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xacd861b6dc5d108af03655a2175545ac6d432c526bcbe294b90e722fa36b459', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1702159200000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -82,7 +82,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x8f9eeb5953c77d53dcff3057619af7a29be1d9ce67bf66c86ad5309379d17e5', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1703368800000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -92,7 +92,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x70b1063c1104760afc06df5217bebdf02f937e1aff51211fc0472e677ba8c74', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1704578400000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -102,7 +102,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xb0aa6f655d08f630c15a2cfb4e3e13e307ce9d96c52c1e91c65a71a204819bd', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1705788000000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -112,7 +112,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x65224b9a3b9eadc55be4cb6efa363f283b924607496d60c02deef2aa6bf9e22', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1706997600000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -122,7 +122,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x68f9a2af0ebd0bcd9e3cc836ac7103670a9602e8dca8fd28e7b2b5a693898f2', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1708207200000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -132,7 +132,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x637e6b758efdb8d49ee96397ca909d579bb77b79f8b64e7e7f1af13ad4f7ce4', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1709416800000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -142,7 +142,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xbd0f349c21b67faec992b6c9a1b9b6343b4ff1f2ad5f33b0b4cd0fc31be2b31', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1710626400000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -152,7 +152,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xfb8c3539b22e4086bd03417027e70515e6fb6d18f366876ad5ad0d8da3bde0f', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1711836000000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -162,7 +162,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xbfb7c1a941885cc55a191e579c7c6d5dc345d6b5b9cfa439f724a343d354032', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1713045600000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -172,7 +172,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x8935a904f90e23f6f453cb0c85a03859e07f1c9e5a5d1644b2fbe7005d8e158', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1714255200000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -182,7 +182,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x73be6f8df4b73b83f8ccf909d61aabb56c56c56aa597d2806eccf3ab4fac66b', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1715464800000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -192,7 +192,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x20075cc2ebd5fa6e069829e58e55e6e010ad115e8cbc48d7a3d98d079ce649a', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1716674400000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -202,7 +202,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xce03433d496cb231ead90a661fe08b924eb9b0cfb43dd560ea02a8060f6afd0', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1717884000000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -212,7 +212,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xf111b8705ba276f8c6b76bdf72a4a46889cb8207cc5a80d3df0f40d9576116a', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1719093600000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -222,7 +222,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xbc27940fb9c6f96ae9e2c11ad151446e30de5281172e48aac7f600d1da92c10', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1720303200000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -232,7 +232,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x016fae8797d3d12a26e215ec1815ee8adce70bb93149b4d55eb06a81c476ff9', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1721512800000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -242,7 +242,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x06f1e354ff551d76da8dc890eab728a65319defb3608991b4c70a1a2b30e8f1', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1722722400000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -252,7 +252,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xc4cf3ea32480aab7d78784c6f00b9210ce0ffaabbcbb8cddd846073e7455386', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1723932000000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -262,7 +262,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x6dc10a8008855549b8d92e7704c799253a953d9835af001970426414fdd3ba7', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1725141600000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -272,7 +272,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xa5f7a66c575db3f74c5fe7043c28f7231a2127aec4dc2de88f5b9d3cf020511', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1726351200000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -282,7 +282,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xde0a4c2e0f16541983302c596339815ffa4d4743509e8115bc06fcf7f71ea8f', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1727560800000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -292,7 +292,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0xccc5d23ab69789b934b9bf7f5006e43eef45c2d7a251e3eec8b7dd24bc20a07', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1728770400000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -302,7 +302,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x503dc8844b0cd6e74e735433751328e8283569e81b4602aaa6941ce3fe826bb', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1729980000000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -312,7 +312,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x0fac98b5ac955644dffa0700933aababe438fae6fc58b8a4bd1f740c8aba941', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1731189600000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -322,7 +322,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x756483e3c7dd3491ea405f682df6c5dc1e4a59d8b5c9725b0d194815a25ea95', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1732399200000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -332,7 +332,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x72c4318876f51bed94c2228b395d18f5dce5f243039c7e3d8fad690dfe918fc', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1733608800000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -342,7 +342,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x37f68fd72af05b4c923268b64a0baa7511f27bc4cbd90641e444e7116f02604', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1734818400000, label: SUPPLY_INCREASE_VESTING_LABEL, @@ -352,7 +352,7 @@ export const MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS: TimelockedObject id: '0x97bedf66e48392a0b9baf8a8280e72fcce9b32ff980832edfe1a90a14ce9047', }, locked: { - value: 2_000_000_000, + value: 2_000_000_000n, }, expirationTimestampMs: 1736028000000, label: SUPPLY_INCREASE_VESTING_LABEL, diff --git a/apps/wallet-dashboard/lib/interfaces/timelock.interface.ts b/apps/wallet-dashboard/lib/interfaces/timelock.interface.ts index 12b26daeecb..2cb58e1a988 100644 --- a/apps/wallet-dashboard/lib/interfaces/timelock.interface.ts +++ b/apps/wallet-dashboard/lib/interfaces/timelock.interface.ts @@ -6,7 +6,7 @@ export interface UID { } export interface Balance { - value: number; + value: bigint; } export interface TimelockedObject { diff --git a/apps/wallet-dashboard/lib/interfaces/vesting.interface.ts b/apps/wallet-dashboard/lib/interfaces/vesting.interface.ts index ba846d71e6c..4eac7bcc774 100644 --- a/apps/wallet-dashboard/lib/interfaces/vesting.interface.ts +++ b/apps/wallet-dashboard/lib/interfaces/vesting.interface.ts @@ -7,7 +7,7 @@ export enum SupplyIncreaseUserType { } export interface SupplyIncreaseVestingPayout { - amount: number; + amount: bigint; expirationTimestampMs: number; } diff --git a/apps/wallet-dashboard/lib/utils/migration/groupMigrationObjects.ts b/apps/wallet-dashboard/lib/utils/migration/groupMigrationObjects.ts index 98badabacdd..73991f4ac09 100644 --- a/apps/wallet-dashboard/lib/utils/migration/groupMigrationObjects.ts +++ b/apps/wallet-dashboard/lib/utils/migration/groupMigrationObjects.ts @@ -16,7 +16,7 @@ import { STARDUST_BASIC_OUTPUT_TYPE, STARDUST_NFT_OUTPUT_TYPE, } from '@iota/core'; -import { extractMigrationOutputFields, extractStorageDepositReturnAmount } from '.'; +import { extractMigrationOutputFields, extractOwnedStorageDepositReturnAmount } from '.'; import { IotaClient, IotaObjectData } from '@iota/iota-sdk/client'; import { MIGRATION_OBJECT_WITHOUT_UC_KEY } from '@/lib/constants'; @@ -56,7 +56,10 @@ export async function groupMigrationObjectsByUnlockCondition( if (object.type === STARDUST_BASIC_OUTPUT_TYPE) { const existing = basicObjectMap.get(groupKey); - const gasReturn = extractStorageDepositReturnAmount(objectFields, currentAddress); + const gasReturn = extractOwnedStorageDepositReturnAmount( + objectFields, + currentAddress, + ); const newBalance = (existing ? existing.balance : 0n) + BigInt(objectFields.balance) + diff --git a/apps/wallet-dashboard/lib/utils/migration/groupStardustObjectsByMigrationStatus.ts b/apps/wallet-dashboard/lib/utils/migration/groupStardustObjectsByMigrationStatus.ts index c7aa8f0e784..b10f1cf4218 100644 --- a/apps/wallet-dashboard/lib/utils/migration/groupStardustObjectsByMigrationStatus.ts +++ b/apps/wallet-dashboard/lib/utils/migration/groupStardustObjectsByMigrationStatus.ts @@ -6,7 +6,7 @@ import { IotaObjectData } from '@iota/iota-sdk/client'; export type StardustMigrationGroupedObjects = { migratable: IotaObjectData[]; - unmigratable: IotaObjectData[]; + timelocked: IotaObjectData[]; }; export function groupStardustObjectsByMigrationStatus( @@ -15,13 +15,21 @@ export function groupStardustObjectsByMigrationStatus( address: string, ): StardustMigrationGroupedObjects { const migratable: IotaObjectData[] = []; - const unmigratable: IotaObjectData[] = []; + const timelocked: IotaObjectData[] = []; const epochUnix = epochTimestampMs / MILLISECONDS_PER_SECOND; for (const outputObject of stardustOutputObjects) { const outputObjectFields = extractMigrationOutputFields(outputObject); + if ( + outputObjectFields.timelock_uc && + outputObjectFields.timelock_uc.fields.unix_time > epochUnix + ) { + timelocked.push(outputObject); + continue; + } + if (outputObjectFields.expiration_uc) { const unlockableAddress = outputObjectFields.expiration_uc.fields.unix_time <= epochUnix @@ -29,29 +37,21 @@ export function groupStardustObjectsByMigrationStatus( : outputObjectFields.expiration_uc.fields.owner; if (unlockableAddress !== address) { - unmigratable.push(outputObject); continue; } } - if ( - outputObjectFields.timelock_uc && - outputObjectFields.timelock_uc.fields.unix_time > epochUnix - ) { - unmigratable.push(outputObject); - continue; - } - migratable.push(outputObject); } - return { migratable, unmigratable }; + return { migratable, timelocked }; } interface MigratableObjectsData { totalNativeTokens: number; totalVisualAssets: number; totalIotaAmount: bigint; + totalNotOwnedStorageDepositReturnAmount: bigint; } interface SummarizeMigrationObjectParams { @@ -67,6 +67,7 @@ export function summarizeMigratableObjectValues({ }: SummarizeMigrationObjectParams): MigratableObjectsData { let totalNativeTokens = 0; let totalIotaAmount: bigint = 0n; + let totalNotOwnedStorageDepositReturnAmount: bigint = 0n; const totalVisualAssets = nftOutputs.length; const outputObjects = [...basicOutputs, ...nftOutputs]; @@ -76,17 +77,25 @@ export function summarizeMigratableObjectValues({ totalIotaAmount += BigInt(outputObjectFields.balance); totalNativeTokens += parseInt(outputObjectFields.native_tokens.fields.size); - totalIotaAmount += extractStorageDepositReturnAmount(outputObjectFields, address) || 0n; + totalIotaAmount += + extractOwnedStorageDepositReturnAmount(outputObjectFields, address) || 0n; + totalNotOwnedStorageDepositReturnAmount += + extractNotOwnedStorageDepositReturnAmount(outputObjectFields, address) || 0n; } - return { totalNativeTokens, totalVisualAssets, totalIotaAmount }; + return { + totalNativeTokens, + totalVisualAssets, + totalIotaAmount, + totalNotOwnedStorageDepositReturnAmount, + }; } interface UnmmigratableObjectsData { - totalUnmigratableObjects: number; + totalTimelockedObjects: number; } -export function summarizeUnmigratableObjectValues({ +export function summarizeTimelockedObjectValues({ basicOutputs = [], nftOutputs = [], }: Omit<SummarizeMigrationObjectParams, 'address'>): UnmmigratableObjectsData { @@ -100,12 +109,12 @@ export function summarizeUnmigratableObjectValues({ nativeTokens += parseInt(outputObjectFields.native_tokens.fields.size); } - const totalUnmigratableObjects = basicObjects + nativeTokens + nftObjects; + const totalTimelockedObjects = basicObjects + nativeTokens + nftObjects; - return { totalUnmigratableObjects }; + return { totalTimelockedObjects }; } -export function extractStorageDepositReturnAmount( +export function extractOwnedStorageDepositReturnAmount( { storage_deposit_return_uc }: CommonOutputObjectWithUc, address: string, ): bigint | null { @@ -127,3 +136,16 @@ export function extractMigrationOutputFields( } ).fields; } + +export function extractNotOwnedStorageDepositReturnAmount( + { storage_deposit_return_uc }: CommonOutputObjectWithUc, + address: string, +): bigint | null { + if ( + storage_deposit_return_uc?.fields && + storage_deposit_return_uc?.fields.return_address !== address + ) { + return BigInt(storage_deposit_return_uc?.fields.return_amount); + } + return null; +} diff --git a/apps/wallet-dashboard/lib/utils/timelock.ts b/apps/wallet-dashboard/lib/utils/timelock.ts index 90c77c0ba9f..f8e06340922 100644 --- a/apps/wallet-dashboard/lib/utils/timelock.ts +++ b/apps/wallet-dashboard/lib/utils/timelock.ts @@ -42,14 +42,14 @@ export function mapTimelockObjects(iotaObjects: IotaObjectData[]): TimelockedObj if (!iotaObject?.content?.dataType || iotaObject.content.dataType !== 'moveObject') { return { id: { id: '' }, - locked: { value: 0 }, + locked: { value: 0n }, expirationTimestampMs: 0, }; } const fields = iotaObject.content.fields as unknown as TimelockedIotaResponse; return { id: fields.id, - locked: { value: Number(fields.locked) }, + locked: { value: BigInt(fields.locked) }, expirationTimestampMs: Number(fields.expiration_timestamp_ms), label: fields.label, }; diff --git a/apps/wallet-dashboard/lib/utils/vesting/vesting.spec.ts b/apps/wallet-dashboard/lib/utils/vesting/vesting.spec.ts index e0bb1f37bd5..3612418d48b 100644 --- a/apps/wallet-dashboard/lib/utils/vesting/vesting.spec.ts +++ b/apps/wallet-dashboard/lib/utils/vesting/vesting.spec.ts @@ -21,10 +21,6 @@ import { const MOCKED_CURRENT_EPOCH_TIMESTAMP = Date.now() + MILLISECONDS_PER_HOUR * 6; // 6 hours later -function bigIntRound(n: number) { - return BigInt(Math.floor(n)); -} - describe('get last supply increase vesting payout', () => { it('should get the object with highest expirationTimestampMs', () => { const timelockedObjects = MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS; @@ -48,7 +44,7 @@ describe('get last supply increase vesting payout', () => { describe('get supply increase user type', () => { it('should return staker, if last payout is two years away from vesting starting year (2023)', () => { const vestingPayout: SupplyIncreaseVestingPayout = { - amount: 1000, + amount: 1000n, expirationTimestampMs: 1735689661000, // Wednesday, 1 January 2025 00:01:01 }; const userType = getSupplyIncreaseVestingUserType([vestingPayout]); @@ -57,7 +53,7 @@ describe('get supply increase user type', () => { it('should return entity, if last payout is more than two years away from vesting starting year (2023)', () => { const vestingPayout: SupplyIncreaseVestingPayout = { - amount: 1000, + amount: 1000n, expirationTimestampMs: 1798761661000, // Friday, 1 January 2027 00:01:01 }; const userType = getSupplyIncreaseVestingUserType([vestingPayout]); @@ -125,12 +121,12 @@ describe('vesting overview', () => { it('should get correct vesting overview data with timelocked objects', () => { const timelockedObjects = MOCKED_SUPPLY_INCREASE_VESTING_TIMELOCKED_OBJECTS; const lastPayout = timelockedObjects[timelockedObjects.length - 1]; - const totalAmount = bigIntRound( - (SUPPLY_INCREASE_STAKER_VESTING_DURATION * - SUPPLY_INCREASE_VESTING_PAYOUTS_IN_1_YEAR * + const totalAmount = + (BigInt(SUPPLY_INCREASE_STAKER_VESTING_DURATION) * + BigInt(SUPPLY_INCREASE_VESTING_PAYOUTS_IN_1_YEAR) * + 10n * lastPayout.locked.value) / - 0.9, - ); + 9n; const vestingOverview = getVestingOverview(timelockedObjects, Date.now()); expect(vestingOverview.totalVested).toEqual(totalAmount); @@ -145,9 +141,7 @@ describe('vesting overview', () => { const lockedAmount = vestingPortfolio.reduce( (acc, current) => - current.expirationTimestampMs > Date.now() - ? acc + bigIntRound(current.amount) - : acc, + current.expirationTimestampMs > Date.now() ? acc + current.amount : acc, 0n, ); @@ -159,16 +153,12 @@ describe('vesting overview', () => { const lockedObjectsAmount = timelockedObjects.reduce( (acc, current) => - current.expirationTimestampMs > Date.now() - ? acc + bigIntRound(current.locked.value) - : acc, + current.expirationTimestampMs > Date.now() ? acc + current.locked.value : acc, 0n, ); const unlockedObjectsAmount = timelockedObjects.reduce( (acc, current) => - current.expirationTimestampMs <= Date.now() - ? acc + bigIntRound(current.locked.value) - : acc, + current.expirationTimestampMs <= Date.now() ? acc + current.locked.value : acc, 0n, ); @@ -182,20 +172,20 @@ describe('vesting overview', () => { formatDelegatedTimelockedStake(timelockedStakedObjects); const lastPayout = extendedTimelockedStakedObjects[extendedTimelockedStakedObjects.length - 1]; - const lastPayoutValue = Number(lastPayout.principal); - const totalAmount = bigIntRound( - (SUPPLY_INCREASE_STAKER_VESTING_DURATION * - SUPPLY_INCREASE_VESTING_PAYOUTS_IN_1_YEAR * - lastPayoutValue) / - 0.9, - ); + const lastPayoutValue = BigInt(lastPayout.principal); + const totalAmount = + (BigInt(SUPPLY_INCREASE_STAKER_VESTING_DURATION) * + BigInt(SUPPLY_INCREASE_VESTING_PAYOUTS_IN_1_YEAR) * + lastPayoutValue * + 10n) / + 9n; const vestingOverview = getVestingOverview(extendedTimelockedStakedObjects, Date.now()); expect(vestingOverview.totalVested).toEqual(totalAmount); const vestingPortfolio = buildVestingPortfolio( { - amount: lastPayoutValue, + amount: BigInt(lastPayoutValue), expirationTimestampMs: Number(lastPayout.expirationTimestampMs), }, Date.now(), @@ -203,9 +193,7 @@ describe('vesting overview', () => { const lockedAmount = vestingPortfolio.reduce( (acc, current) => - current.expirationTimestampMs > Date.now() - ? acc + bigIntRound(current.amount) - : acc, + current.expirationTimestampMs > Date.now() ? acc + current.amount : acc, 0n, ); @@ -215,7 +203,7 @@ describe('vesting overview', () => { let totalStaked = 0n; for (const timelockedStakedObject of timelockedStakedObjects) { const stakesAmount = timelockedStakedObject.stakes.reduce( - (acc, current) => acc + bigIntRound(Number(current.principal)), + (acc, current) => acc + BigInt(current.principal), 0n, ); totalStaked += stakesAmount; @@ -239,12 +227,12 @@ describe('vesting overview', () => { mixedObjects, MOCKED_CURRENT_EPOCH_TIMESTAMP, )!; - const totalAmount = bigIntRound( - (SUPPLY_INCREASE_STAKER_VESTING_DURATION * - SUPPLY_INCREASE_VESTING_PAYOUTS_IN_1_YEAR * + const totalAmount = + (BigInt(SUPPLY_INCREASE_STAKER_VESTING_DURATION) * + BigInt(SUPPLY_INCREASE_VESTING_PAYOUTS_IN_1_YEAR) * + 10n * lastPayout.amount) / - 0.9, - ); + 9n; const vestingOverview = getVestingOverview(mixedObjects, Date.now()); expect(vestingOverview.totalVested).toEqual(totalAmount); @@ -259,9 +247,7 @@ describe('vesting overview', () => { const lockedAmount = vestingPortfolio.reduce( (acc, current) => - current.expirationTimestampMs > Date.now() - ? acc + bigIntRound(current.amount) - : acc, + current.expirationTimestampMs > Date.now() ? acc + current.amount : acc, 0n, ); @@ -269,7 +255,7 @@ describe('vesting overview', () => { expect(vestingOverview.totalUnlocked).toEqual(totalAmount - lockedAmount); const totalStaked = extendedTimelockedStakedObjects.reduce( - (acc, current) => acc + bigIntRound(Number(current.principal)), + (acc, current) => acc + BigInt(current.principal), 0n, ); @@ -278,16 +264,12 @@ describe('vesting overview', () => { const timelockObjects = mixedObjects.filter(isTimelockedObject); const availableClaiming = timelockObjects.reduce( (acc, current) => - current.expirationTimestampMs <= Date.now() - ? acc + bigIntRound(current.locked.value) - : acc, + current.expirationTimestampMs <= Date.now() ? acc + current.locked.value : acc, 0n, ); const availableStaking = timelockObjects.reduce( (acc, current) => - current.expirationTimestampMs > Date.now() - ? acc + bigIntRound(current.locked.value) - : acc, + current.expirationTimestampMs > Date.now() ? acc + current.locked.value : acc, 0n, ); expect(vestingOverview.availableClaiming).toEqual(availableClaiming); diff --git a/apps/wallet-dashboard/lib/utils/vesting/vesting.ts b/apps/wallet-dashboard/lib/utils/vesting/vesting.ts index e0bb8a29158..374d9a19204 100644 --- a/apps/wallet-dashboard/lib/utils/vesting/vesting.ts +++ b/apps/wallet-dashboard/lib/utils/vesting/vesting.ts @@ -53,7 +53,7 @@ export function getLatestOrEarliestSupplyIncreaseVestingPayout( } function addVestingPayoutToSupplyIncreaseMap( - value: number, + value: bigint, expirationTimestampMs: number, supplyIncreaseMap: Map<number, SupplyIncreaseVestingPayout>, ) { @@ -85,7 +85,7 @@ function supplyIncreaseVestingObjectsToPayoutMap( expirationToVestingPayout, ); } else if (isTimelockedStakedIota(vestingObject)) { - const objectValue = Number(vestingObject.principal); + const objectValue = BigInt(vestingObject.principal); const expirationTimestampMs = Number(vestingObject.expirationTimestampMs); addVestingPayoutToSupplyIncreaseMap( objectValue, @@ -162,7 +162,7 @@ export function getVestingOverview( const userType = getSupplyIncreaseVestingUserType([latestPayout]); const vestingPayoutsCount = getSupplyIncreaseVestingPayoutsCount(userType!); // Note: we add the initial payout to the total rewards, 10% of the total rewards are paid out immediately - const totalVestedAmount = BigInt(Math.floor((vestingPayoutsCount * latestPayout.amount) / 0.9)); + const totalVestedAmount = (BigInt(vestingPayoutsCount) * latestPayout.amount * 10n) / 9n; const vestingPortfolio = buildSupplyIncreaseVestingSchedule( latestPayout, currentEpochTimestamp, @@ -326,7 +326,7 @@ export function prepareObjectsForTimelockedStakingTransaction( targetAmount: bigint, currentEpochMs: string, ): GroupedTimelockObject[] { - if (Number(targetAmount) === 0) { + if (targetAmount === 0n) { return []; } const timelockedMapped = mapTimelockObjects(timelockedObjects); @@ -368,7 +368,7 @@ export function prepareObjectsForTimelockedStakingTransaction( const remainingAmount = totalLocked - targetAmount; // Add splitAmount property to the vesting objects that need to be split - if (remainingAmount > 0) { + if (remainingAmount > 0n) { selectedGroupedTimelockObjects = adjustSplitAmountsInGroupedTimelockObjects( selectedGroupedTimelockObjects, remainingAmount, diff --git a/apps/wallet-dashboard/next.config.mjs b/apps/wallet-dashboard/next.config.mjs index a7417e613fd..533cbcccda9 100644 --- a/apps/wallet-dashboard/next.config.mjs +++ b/apps/wallet-dashboard/next.config.mjs @@ -1,6 +1,9 @@ // Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +import { execSync } from 'child_process'; +const NEXT_PUBLIC_DASHBOARD_REV = execSync('git rev-parse HEAD').toString().trim().toString(); + /** @type {import('next').NextConfig} */ const nextConfig = { async redirects() { @@ -16,6 +19,9 @@ const nextConfig = { // Remove this domain when fetching data domains: ['d315pvdvxi2gex.cloudfront.net'], }, + env: { + NEXT_PUBLIC_DASHBOARD_REV, + }, }; export default nextConfig; diff --git a/apps/wallet-dashboard/package.json b/apps/wallet-dashboard/package.json index 3cf781bca2f..9cff8865c4d 100644 --- a/apps/wallet-dashboard/package.json +++ b/apps/wallet-dashboard/package.json @@ -22,11 +22,12 @@ "@iota/dapp-kit": "workspace:*", "@iota/iota-sdk": "workspace:*", "@iota/ui-icons": "workspace:*", + "@iota/wallet-standard": "workspace:*", "@tanstack/react-query": "^5.50.1", "@tanstack/react-virtual": "^3.5.0", "clsx": "^2.1.1", "formik": "^2.4.2", - "next": "14.2.10", + "next": "14.2.15", "react": "^18.3.1", "react-hot-toast": "^2.4.1", "zustand": "^4.4.1" diff --git a/apps/wallet-dashboard/providers/AppProviders.tsx b/apps/wallet-dashboard/providers/AppProviders.tsx index 27744398f86..26be321a43b 100644 --- a/apps/wallet-dashboard/providers/AppProviders.tsx +++ b/apps/wallet-dashboard/providers/AppProviders.tsx @@ -3,7 +3,7 @@ 'use client'; -import { PopupProvider, Toaster } from '@/components'; +import { Toaster } from '@/components'; import { GrowthBookProvider } from '@growthbook/growthbook-react'; import { IotaClientProvider, lightTheme, darkTheme, WalletProvider } from '@iota/dapp-kit'; import { getAllNetworks, getDefaultNetwork } from '@iota/iota-sdk/client'; @@ -11,7 +11,6 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { useState } from 'react'; import { KioskClientProvider } from '@iota/core'; import { growthbook } from '@/lib/utils'; -import { Popup } from '@/components/Popup'; import { ThemeProvider } from '@iota/core'; growthbook.init(); @@ -20,11 +19,18 @@ export function AppProviders({ children }: React.PropsWithChildren) { const [queryClient] = useState(() => new QueryClient()); const allNetworks = getAllNetworks(); const defaultNetwork = getDefaultNetwork(); - + function handleNetworkChange() { + queryClient.resetQueries(); + queryClient.clear(); + } return ( <GrowthBookProvider growthbook={growthbook}> <QueryClientProvider client={queryClient}> - <IotaClientProvider networks={allNetworks} defaultNetwork={defaultNetwork}> + <IotaClientProvider + networks={allNetworks} + defaultNetwork={defaultNetwork} + onNetworkChange={handleNetworkChange} + > <KioskClientProvider> <WalletProvider autoConnect={true} @@ -39,11 +45,8 @@ export function AppProviders({ children }: React.PropsWithChildren) { ]} > <ThemeProvider appId="iota-dashboard"> - <PopupProvider> - {children} - <Toaster /> - <Popup /> - </PopupProvider> + {children} + <Toaster /> </ThemeProvider> </WalletProvider> </KioskClientProvider> diff --git a/apps/wallet/package.json b/apps/wallet/package.json index a240f6170bb..59ad3cd44ec 100644 --- a/apps/wallet/package.json +++ b/apps/wallet/package.json @@ -1,6 +1,6 @@ { "name": "iota-wallet", - "version": "0.3.1", + "version": "0.4.0", "private": true, "description": "A wallet for IOTA", "main": "./dist/ui.js", @@ -81,7 +81,7 @@ "vite": "^5.3.3", "vite-tsconfig-paths": "^4.2.0", "vitest": "^2.0.1", - "web-ext": "^7.6.2", + "web-ext": "^8.3.0", "webpack": "^5.79.0", "webpack-cli": "^5.0.1", "webpack-merge": "^5.8.0" @@ -117,7 +117,7 @@ "@reduxjs/toolkit": "^1.9.5", "@scure/bip32": "^1.4.0", "@scure/bip39": "^1.3.0", - "@sentry/browser": "^7.61.0", + "@sentry/browser": "^7.120.2", "@tanstack/react-query": "^5.50.1", "@tanstack/react-query-persist-client": "^5.40.1", "axios": "^1.7.4", @@ -132,7 +132,6 @@ "formik": "^2.4.2", "framer-motion": "^10.12.22", "idb-keyval": "^6.2.1", - "jose": "^5.2.3", "mitt": "^3.0.1", "poseidon-lite": "^0.2.0", "react": "^18.3.1", diff --git a/apps/wallet/src/ui/app/components/accounts/AccountIcon.tsx b/apps/wallet/src/ui/app/components/accounts/AccountIcon.tsx index ffcc77d28dc..5ae5de338f1 100644 --- a/apps/wallet/src/ui/app/components/accounts/AccountIcon.tsx +++ b/apps/wallet/src/ui/app/components/accounts/AccountIcon.tsx @@ -11,7 +11,7 @@ interface AccountIconProps { export function AccountIcon({ account }: AccountIconProps) { if (account.type === AccountType.LedgerDerived) { - return <Ledger className="h-5 w-5" />; + return <Ledger className="h-5 w-5 text-neutral-10 dark:text-neutral-92" />; } - return <IotaLogoMark className="h-5 w-5" />; + return <IotaLogoMark className="h-5 w-5 text-neutral-10 dark:text-neutral-92" />; } diff --git a/apps/wallet/src/ui/app/pages/accounts/WelcomePage.tsx b/apps/wallet/src/ui/app/pages/accounts/WelcomePage.tsx index a9ac8919e66..c9f6d36ddd7 100644 --- a/apps/wallet/src/ui/app/pages/accounts/WelcomePage.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/WelcomePage.tsx @@ -23,7 +23,11 @@ export function WelcomePage() { return ( <Loading loading={isInitializedLoading || isFullscreenGuardLoading}> <div className="flex h-full w-full flex-col items-center justify-between bg-neutral-100 px-md py-2xl shadow-wallet-content dark:bg-neutral-6"> - <IotaLogoWeb width={130} height={32} /> + <IotaLogoWeb + width={130} + height={32} + className="text-neutral-10 dark:text-neutral-92" + /> <div className="flex flex-col items-center gap-8 text-center"> <div className="flex flex-col items-center gap-4"> <span className="text-headline-sm text-neutral-40">Welcome to</span> diff --git a/crates/bin-version/src/lib.rs b/crates/bin-version/src/lib.rs index 7af360af7fe..76f534af1e1 100644 --- a/crates/bin-version/src/lib.rs +++ b/crates/bin-version/src/lib.rs @@ -12,11 +12,11 @@ pub mod _hidden { /// /// Defines two global `const`s: /// `GIT_REVISION`: The git revision as specified by the `GIT_REVISION` env -/// variable provided at compile time, or the current git revision as -/// discovered by running `git describe`. +/// variable provided at compile time, or the current git revision as discovered +/// by running `git describe`. /// /// `VERSION`: The value of the `CARGO_PKG_VERSION` environment variable -/// concatenated with the value of `GIT_REVISION`. +/// concatenated with the value of `GIT_REVISION` if it is not empty. /// /// Note: This macro must only be used from a binary, if used inside a library /// this will fail to compile. @@ -25,16 +25,19 @@ macro_rules! bin_version { () => { $crate::git_revision!(); - const VERSION: &str = - $crate::_hidden::concat!(env!("CARGO_PKG_VERSION"), "-", GIT_REVISION); + const VERSION: &str = if GIT_REVISION.is_empty() { + env!("CARGO_PKG_VERSION") + } else { + $crate::_hidden::concat!(env!("CARGO_PKG_VERSION"), "-", GIT_REVISION) + }; }; } /// Defines constant that holds the git revision at build time. /// /// `GIT_REVISION`: The git revision as specified by the `GIT_REVISION` env -/// variable provided at compile time, or the current git revision as -/// discovered by running `git describe`. +/// variable provided at compile time, or the current git revision as discovered +/// by running `git describe`. /// /// Note: This macro must only be used from a binary, if used inside a library /// this will fail to compile. diff --git a/crates/iota-e2e-tests/tests/passkey_e2e_tests.rs b/crates/iota-e2e-tests/tests/passkey_e2e_tests.rs index 0f7a1cf583a..82c9c4a9d91 100644 --- a/crates/iota-e2e-tests/tests/passkey_e2e_tests.rs +++ b/crates/iota-e2e-tests/tests/passkey_e2e_tests.rs @@ -17,11 +17,11 @@ use iota_types::{ transaction::{Transaction, TransactionData}, }; use p256::pkcs8::DecodePublicKey; -use passkey_authenticator::{Authenticator, UserValidationMethod}; +use passkey_authenticator::{Authenticator, UserCheck, UserValidationMethod}; use passkey_client::Client; use passkey_types::{ Bytes, Passkey, - ctap2::Aaguid, + ctap2::{Aaguid, Ctap2Error}, rand::random_vec, webauthn::{ AttestationConveyancePreference, CredentialCreationOptions, CredentialRequestOptions, @@ -35,14 +35,21 @@ use test_cluster::{TestCluster, TestClusterBuilder}; use url::Url; struct MyUserValidationMethod {} + #[async_trait::async_trait] impl UserValidationMethod for MyUserValidationMethod { - async fn check_user_presence(&self) -> bool { - true - } + type PasskeyItem = Passkey; - async fn check_user_verification(&self) -> bool { - true + async fn check_user<'a>( + &self, + _credential: Option<&'a Self::PasskeyItem>, + _presence: bool, + _verification: bool, + ) -> Result<UserCheck, Ctap2Error> { + Ok(UserCheck { + presence: true, + verification: true, + }) } fn is_verification_enabled(&self) -> Option<bool> { diff --git a/crates/iota-types/src/unit_tests/passkey_authenticator_test.rs b/crates/iota-types/src/unit_tests/passkey_authenticator_test.rs index 5d4f451ebe6..41645f17c22 100644 --- a/crates/iota-types/src/unit_tests/passkey_authenticator_test.rs +++ b/crates/iota-types/src/unit_tests/passkey_authenticator_test.rs @@ -11,11 +11,11 @@ use fastcrypto::{ traits::ToFromBytes, }; use p256::pkcs8::DecodePublicKey; -use passkey_authenticator::{Authenticator, UserValidationMethod}; +use passkey_authenticator::{Authenticator, UserCheck, UserValidationMethod}; use passkey_client::Client; use passkey_types::{ Bytes, Passkey, - ctap2::Aaguid, + ctap2::{Aaguid, Ctap2Error}, rand::random_vec, webauthn::{ AttestationConveyancePreference, CredentialCreationOptions, CredentialRequestOptions, @@ -41,15 +41,10 @@ use crate::{ /// Helper struct to initialize passkey client. pub struct MyUserValidationMethod {} + #[async_trait::async_trait] impl UserValidationMethod for MyUserValidationMethod { - async fn check_user_presence(&self) -> bool { - true - } - - async fn check_user_verification(&self) -> bool { - true - } + type PasskeyItem = Passkey; fn is_verification_enabled(&self) -> Option<bool> { Some(true) @@ -58,6 +53,18 @@ impl UserValidationMethod for MyUserValidationMethod { fn is_presence_enabled(&self) -> bool { true } + + async fn check_user<'a>( + &self, + _credential: Option<&'a Self::PasskeyItem>, + _presence: bool, + _verification: bool, + ) -> Result<UserCheck, Ctap2Error> { + Ok(UserCheck { + presence: true, + verification: true, + }) + } } /// Response with fields from passkey authentication. diff --git a/deny.toml b/deny.toml index 73541741be8..04e8c2cb6f6 100644 --- a/deny.toml +++ b/deny.toml @@ -88,6 +88,7 @@ allow = [ "BSL-1.0", "Unicode-DFS-2016", "OpenSSL", + "Unicode-3.0", # "Apache-2.0 WITH LLVM-exception", ] # The confidence threshold for detecting a license from license text. @@ -98,7 +99,7 @@ confidence-threshold = 0.8 # Allow 1 or more licenses on a per-crate basis, so that particular licenses # aren't accepted for every possible crate as with the normal allow list exceptions = [ - { allow = ["GPL-2.0"], name = "mysqlclient-src" }, + # Each entry is the crate and version constraint, and its specific allow # list diff --git a/docs/content/about-iota/iota-wallet/how-to/integrate-ledger.mdx b/docs/content/about-iota/iota-wallet/how-to/integrate-ledger.mdx index 093140c0f72..735c8d02253 100644 --- a/docs/content/about-iota/iota-wallet/how-to/integrate-ledger.mdx +++ b/docs/content/about-iota/iota-wallet/how-to/integrate-ledger.mdx @@ -17,7 +17,10 @@ Before connecting your Ledger device to IOTA Wallet, ensure the following: ## Install the IOTA Rebased App on Your Ledger Device -To use IOTA Wallet with Ledger, install the IOTA Rebased app on your device through Ledger Live. +To use IOTA Wallet with Ledger, install the IOTA Rebased app on your device through Ledger Live or manually. +Ledger Live is preferred, but you need to install the app manually for deprecated devices like the Ledger Nano S. + +### Ledger Live (preferred) 1. Unlock your Ledger device. 2. Open Ledger Live and navigate to **My Ledger** in the left panel. @@ -26,6 +29,25 @@ To use IOTA Wallet with Ledger, install the IOTA Rebased app on your device thro 5. Click **Install** to download the IOTA Rebased app to your device. 6. Your device will show the installation progress. +### Manually (for deprecated devices such as Ledger Nano S) + +:::warning + +Make sure you have enough space left for an additional app on your device. + +::: + +1. Go to the latest release on https://github.com/iotaledger/ledger-app-iota/releases. +2. Download the archive matching your device, e.g. `nanos.tar.gz` for the Ledger Nano S. +3. Verify that the checksum (`shasum -a 256 nanos.tar.gz`) matches the one from the release. +4. Extract the archive `tar -xvzf nanos.tar.gz`. +5. Move to the app folder `cd nanos`. +6. Follow the steps on https://github.com/LedgerHQ/ledgerctl to install `ledgerctl`. +7. Install the app on your device `ledgerctl install -f app_nanos.json`. +8. Accept `Allow unsafe manager` on your device. +9. Accept `Perform installation` on your device. +10. Enter your pin on your device. + ## Import Accounts from Your Ledger Device To import accounts from your Ledger into IOTA Wallet: diff --git a/docs/content/developer/iota-101/using-events.mdx b/docs/content/developer/iota-101/using-events.mdx index f808f9e1e07..5e6182ddc78 100644 --- a/docs/content/developer/iota-101/using-events.mdx +++ b/docs/content/developer/iota-101/using-events.mdx @@ -28,13 +28,13 @@ An event object in IOTA consists of the following attributes: - `bcs`: Binary canonical serialization value. - `timestampMs`: Unix epoch timestamp in milliseconds. -## Exploring Available Events +### Exploring Available Events -To subscribe to on-chain events, you first need to identify which events are available. While you can easily track events emitted by your own code, discovering events from external packages can be more challenging. The IOTA RPC provides the [`queryEvents`](/iota-api-ref#iotax_queryevents) method, which allows you to query on-chain packages and obtain a list of events you can subscribe to. +To [subscribe to on-chain events](#subscribing-to-events), you first need to identify which events are available. While you can easily track events emitted by your own code, discovering events from external packages can be more challenging. The IOTA RPC provides the [`queryEvents`](/iota-api-ref#iotax_queryevents) method, which allows you to query on-chain packages and obtain a list of events you can subscribe to. -## Applying Event Filters +### Applying Event Filters -When targeting specific events for querying or subscribing, you can use filters to refine your results. Although the filtering options for querying and subscribing are similar, there are notable differences to be aware of. +When targeting specific events for [querying](#querying-events) or [subscribing](#subscribing-to-events), you can use [filters](#filtering-events) to refine your results. Although the filtering options for querying and subscribing are similar, there are notable differences to be aware of. ## Emitting Events in Move @@ -49,65 +49,117 @@ use iota::event; Then, within your function, you can emit an event using the [`emit`](../../references/framework/iota-framework/event.mdx#function-emit) function. For example: -```move -/// Take coin from `DonutShop` and transfer it to tx sender. -/// Requires authorization with `ShopOwnerCap`. -public fun collect_profits( _: &ShopOwnerCap, shop: &mut DonutShop, ctx: &mut TxContext ) { - let amount = balance::value(&shop.balance); - let profits = coin::take(&mut shop.balance, amount, ctx); - // simply create new type instance and emit it. - event::emit(ProfitsCollected { amount }); - transfer::public_transfer(profits, tx_context::sender(ctx)); -} +```move file=<rootDir>/examples/trading/contracts/escrow/sources/lock.move#L42-L63 ``` -## Subscribing to Events +## Querying Events + +<Tabs> + +<TabItem value="RPC" label="IOTA RPC"> +The IOTA RPC provides a [`queryEvents`](/iota-api-ref#iotax_queryevents) method to query on-chain packages and return available events. As an example, the following `curl` command queries the Deepbook package on Mainnet for a specific type of event: + +```sh +curl -X POST https://api.testnet.iota.cafe:443 \ +-H "Content-Type: application/json" \ +-d '{ + "jsonrpc": "2.0", + "id": 1, + "method": "iotax_queryEvents", + "params": [ + { + "MoveModule": { + "package": "0x0000000000000000000000000000000000000000000000000000000000000002", + "module": "display", + "type": "0x0000…0002::display::Display<0xba68…286b::testnet_nft::TestnetNFT>" + } + }, + null, + 3, + false + ] +}' +``` + +The TypeScript SDK provides a wrapper for the `iotax_queryEvents` method: +[`client.queryEvents`](../../references/ts-sdk/api/client/classes/IotaClient#queryevents). -To react to events emitted by Move modules, you need to subscribe to them. -IOTA full nodes support event subscriptions via JSON-RPC notifications over WebSocket. You can interact with the [RPC directly][iotax_subscribeEvent](/iota-api-ref#iotax_subscribeevent), [iotax_subscribeTransaction](/iota-api-ref#iotax_subscribetransaction) or use an SDK like the [IOTA TypeScript SDK](../../references/ts-sdk/typescript/index.mdx). +</TabItem> +<TabItem value="rs" label="Rust"> -The following excerpt from one of the examples uses the TypeScript SDK to create an asynchronous subscription to the filter identified in the filter. +You can use the following as an example on how to query for events using the `query_events` function. You should update +the `PACKAGE_ID_CONST` with a package of your choice. -```move -let unsubscribe = await provider.subscribeEvent({ - filter: { <PACKAGE_ID> }, - onMessage: (event) => { - console.log("subscribeEvent", JSON.stringify(event, null, 2)) +```rust +use iota_sdk::{rpc_types::EventFilter, types::Identifier, IotaClientBuilder}; + +const PACKAGE_ID_CONST: &str = ""; + +#[tokio::main] +async fn main() -> Result<(), anyhow::Error> { + let iota_testnet = IotaClientBuilder::default() + .build("https://api.testnet.iota.cafe:443") + .await?; + + let events = iota_testnet + .event_api() + .query_events( + EventFilter::MoveModule { + package: PACKAGE_ID_CONST.parse()?, + module: Identifier::new("dev_trophy")?, + }, + None, + None, + false, + ) + .await?; + + for event in events.data { + println!("Event: {:?}", event.parsed_json); } -}); + + Ok(()) +} ``` +</TabItem> +<TabItem value="graphql" label="GraphQL"> -Move smart contracts can call other smart contracts that emit events. For example, `0x107a::nft` calls the `0x2::display::new_with_fields` smart contract and emits a `0x2::display::DisplayCreated` event. Note that using package and transaction module to query for `0x2::display` misses the following event even though it is actually an event the `0x2` package emits. The current workaround for this issue is to know all the `packageId`s you care about and search those in the `queryEvent` call. +You can use GraphQL to query events instead of JSON RPC. The following example queries are in the +[`iota-graphql-rpc` crate](https://github.com/iotaledger/iota/tree/develop/crates/iota-graphql-rpc/examples/event_connection) in the IOTA repo. -```json -{ - "id": { - "txDigest": "DrZmtQDDCUKooLzFCi29VhUB4w6AT8phCsT9d62BAf8g", - "eventSeq": "0" - }, - "packageId": "0x000000000000000000000000000000000000000000000000000000000000107a", - "transactionModule": "nft", - "sender": "0x0000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2::display::DisplayCreated<0x107a::nft::Nft>", - "parsedJson": { - "id": "0xa12d72c159d57d4c7f540b2b9e985327628d856b20c1d6cdfd3028a2a605abfe" - }, - "bcs": "CFbAeqXAwwkyTxUD36FtzTGEcMGrVj4zgcTR1G7AaRjb", - "timestampMs": "1521456213521" -} +#### Event Connection + +```graphql file=<rootDir>/crates/iota-graphql-rpc/examples/event_connection/event_connection.graphql +``` + +#### Filter Events By Sender + +```graphql file=<rootDir>/crates/iota-graphql-rpc/examples/event_connection/filter_by_sender.graphql ``` -## Examples +#### Filter Events By Emitting Package and Type -### Subscribe to Event +```graphql file=<rootDir>/crates/iota-graphql-rpc/examples/event_connection/filter_by_sender.graphql +``` + +:::tip + +The [TypeScript SDK](../../references/ts-sdk/api/graphql/classes/IotaGraphQLClient) provides functionality to +interact with the IOTA GraphQL service. + +::: + +</TabItem> +</Tabs> + + +## Subscribing to Events This example leverages the IOTA TypeScript SDK to subscribe to events the package with ID `<PACKAGE_ID>` emits. Each time the event fires, the code displays the response to the console. <Tabs> <TabItem value="rs" label="Rust"> -### Rust - See [Rust SDK](../../references/rust-sdk.mdx). ```rust @@ -132,8 +184,6 @@ async fn main() -> Result<()> { </TabItem> <TabItem value="ts" label="TypeScript"> -### TypeScript - To create the event subscription, you can use a basic Node.js app. You need the [IOTA TypeScript SDK](../../references/ts-sdk/typescript/index.mdx), so install the module using `npm install @iota/iota-sdk` at the root of your project. In your TypeScript code, import `JsonRpcProvider` and a connection from the library. ```ts @@ -199,9 +249,19 @@ subscribeEvent { </TabItem> </Tabs> +## Monitoring Events + +Firing events is not very useful in a vacuum. You also need the ability to respond to those events. +There are two methods from which to choose when you need to monitor on-chain events: +- Incorporate a [custom indexer](../advanced/custom-indexer.mdx) to take advantage of IOTA's micro-data ingestion framework. +- Poll the IOTA network on a schedule to query events. + +Using a custom indexer provides a near-real time monitoring of events, so is most useful when your project requires immediate reaction to the firing of events. Polling the network is most useful when the events you're monitoring don't fire often or the need to act on those events are not immediate. The following section provides a polling example. + + ## Filtering Events -You can filter events when querying or subscribing to receive only the events you are interested in. +You can filter events when [querying](#querying-events) or [subscribing](#subscribing-to-events) to receive only the events you are interested in. :::info diff --git a/docs/content/sidebars/developer.js b/docs/content/sidebars/developer.js index e8ac1eb1bb5..d1500f346fc 100644 --- a/docs/content/sidebars/developer.js +++ b/docs/content/sidebars/developer.js @@ -57,7 +57,6 @@ const developer = [ label: 'Typescript SDK', href: '/references/ts-sdk/typescript', }, - 'developer/iota-101/using-events', ], }, { @@ -70,6 +69,8 @@ const developer = [ 'developer/iota-101/move-overview/init', 'developer/iota-101/move-overview/visibility', 'developer/iota-101/move-overview/entry-functions', + 'developer/iota-101/using-events', + 'developer/iota-101/access-time', { type: 'category', label: 'Structs and Abilities', @@ -107,7 +108,6 @@ const developer = [ 'developer/iota-101/move-overview/patterns/id-pointer', ], }, - 'developer/iota-101/access-time', 'developer/iota-101/move-overview/conventions', ], }, diff --git a/docs/site/docusaurus.config.js b/docs/site/docusaurus.config.js index 8fe33d66342..8786b53334b 100644 --- a/docs/site/docusaurus.config.js +++ b/docs/site/docusaurus.config.js @@ -191,29 +191,15 @@ const config = { type: "text/css", }, ], - themes: ["@docusaurus/theme-mermaid", 'docusaurus-theme-search-typesense', + themes: ["@docusaurus/theme-mermaid", '@saucelabs/theme-github-codeblock', '@docusaurus/theme-live-codeblock'], themeConfig: /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ ({ - typesense: { - // Replace this with the name of your index/collection. - // It should match the "index_name" entry in the scraper's "config.json" file. - typesenseCollectionName: 'IOTADocs', - typesenseServerConfig: { - nodes: [ - { - host: 'docs-search.iota.org', - port: '', - protocol: 'https', - }, - ], - apiKey: 'C!jA3iCujG*PjK!eUVWFBxnU', - }, - // Optional: Typesense search parameters: https://typesense.org/docs/0.24.0/api/search.html#search-parameters - typesenseSearchParameters: {}, - // Optional - contextualSearch: true, + algolia: { + apiKey: '24b141ea7e65db2181463e44dbe564a5', + appId: '9PMBZGRP3B', + indexName: 'iota', }, image: "img/iota-doc-og.png", docs: { diff --git a/docs/site/package.json b/docs/site/package.json index 7263d5ad11e..48dfbddde29 100644 --- a/docs/site/package.json +++ b/docs/site/package.json @@ -45,7 +45,6 @@ "axios": "^1.7.4", "clsx": "^2.1.1", "copy-text-to-clipboard": "^3.2.0", - "docusaurus-theme-search-typesense": "0.20.0-0", "dotenv": "^16.4.5", "graphql": "^16.9.0", "graphql-config": "^5.0.3", diff --git a/package.json b/package.json index 76d65042397..9ceeb891cd9 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "semver@<7.5.2": ">=7.5.2", "postcss@<8.4.31": ">=8.4.31", "braces": ">=3.0.3", - "path-to-regexp@0.1.7": "0.1.10", + "path-to-regexp@<0.1.12": "0.1.12", "path-to-regexp@2.2.1": "3.3.0", "path-to-regexp@3.2.0": "3.3.0", "body-parser": ">=1.20.3", @@ -46,7 +46,12 @@ "mermaid@10.9.1": "10.9.3", "http-proxy-middleware": "2.0.7", "cross-spawn": "7.0.5", - "ws": "8.18.0" + "axios@<0.28.0": "0.28.0", + "tough-cookie@<4.1.3": "4.1.3", + "ws": "8.18.0", + "@sentry/browser": "7.120.2", + "nanoid@3.3.7": "3.3.8", + "nanoid@5.0.7": "5.0.9" } }, "engines": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6aba893215d..dc5cd8b2bf3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,7 +12,7 @@ overrides: semver@<7.5.2: '>=7.5.2' postcss@<8.4.31: '>=8.4.31' braces: '>=3.0.3' - path-to-regexp@0.1.7: 0.1.10 + path-to-regexp@<0.1.12: 0.1.12 path-to-regexp@2.2.1: 3.3.0 path-to-regexp@3.2.0: 3.3.0 body-parser: '>=1.20.3' @@ -21,7 +21,12 @@ overrides: mermaid@10.9.1: 10.9.3 http-proxy-middleware: 2.0.7 cross-spawn: 7.0.5 + axios@<0.28.0: 0.28.0 + tough-cookie@<4.1.3: 4.1.3 ws: 8.18.0 + '@sentry/browser': 7.120.2 + nanoid@3.3.7: 3.3.8 + nanoid@5.0.7: 5.0.9 importers: @@ -654,8 +659,8 @@ importers: specifier: ^5.3.3 version: 5.4.8(@types/node@20.16.9)(sass@1.79.3)(terser@5.34.0) vite-plugin-dts: - specifier: ^3.9.1 - version: 3.9.1(@types/node@20.16.9)(rollup@4.22.4)(typescript@5.6.2)(vite@5.4.8(@types/node@20.16.9)(sass@1.79.3)(terser@5.34.0)) + specifier: ^4.3.0 + version: 4.3.0(@types/node@20.16.9)(rollup@4.22.4)(typescript@5.6.2)(vite@5.4.8(@types/node@20.16.9)(sass@1.79.3)(terser@5.34.0)) vite-tsconfig-paths: specifier: ^4.2.0 version: 4.3.2(typescript@5.6.2)(vite@5.4.8(@types/node@20.16.9)(sass@1.79.3)(terser@5.34.0)) @@ -753,8 +758,8 @@ importers: specifier: ^1.3.0 version: 1.4.0 '@sentry/browser': - specifier: ^7.61.0 - version: 7.119.0 + specifier: 7.120.2 + version: 7.120.2 '@tanstack/react-query': specifier: ^5.50.1 version: 5.56.2(react@18.3.1) @@ -797,9 +802,6 @@ importers: idb-keyval: specifier: ^6.2.1 version: 6.2.1 - jose: - specifier: ^5.2.3 - version: 5.9.3 mitt: specifier: ^3.0.1 version: 3.0.1 @@ -991,8 +993,8 @@ importers: specifier: ^2.0.1 version: 2.1.1(@types/node@20.16.9)(@vitest/ui@0.33.0)(happy-dom@15.11.7)(jsdom@24.1.3)(msw@2.4.9(typescript@5.6.2))(sass@1.79.3)(terser@5.34.0) web-ext: - specifier: ^7.6.2 - version: 7.12.0(body-parser@1.20.3) + specifier: ^8.3.0 + version: 8.3.0(body-parser@1.20.3) webpack: specifier: ^5.79.0 version: 5.95.0(@swc/core@1.7.28)(webpack-cli@5.1.4) @@ -1026,6 +1028,9 @@ importers: '@iota/ui-icons': specifier: workspace:* version: link:../ui-icons + '@iota/wallet-standard': + specifier: workspace:* + version: link:../../sdk/wallet-standard '@tanstack/react-query': specifier: ^5.50.1 version: 5.56.2(react@18.3.1) @@ -1039,8 +1044,8 @@ importers: specifier: ^2.4.2 version: 2.4.6(react@18.3.1) next: - specifier: 14.2.10 - version: 14.2.10(@babel/core@7.25.2)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.79.3) + specifier: 14.2.15 + version: 14.2.15(@babel/core@7.25.2)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.79.3) react: specifier: ^18.3.1 version: 18.3.1 @@ -1320,25 +1325,25 @@ importers: version: 3.6.1(@algolia/client-search@4.24.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/core': specifier: 3.5.2 - version: 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + version: 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/preset-classic': specifier: 3.5.2 - version: 3.5.2(@algolia/client-search@4.24.0)(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + version: 3.5.2(@algolia/client-search@4.24.0)(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/remark-plugin-npm2yarn': specifier: ^3.5.2 version: 3.5.2 '@docusaurus/theme-common': specifier: ^3.5.2 - version: 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + version: 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/theme-live-codeblock': specifier: ^3.5.2 - version: 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + version: 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/theme-mermaid': specifier: ^3.5.2 - version: 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + version: 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/theme-search-algolia': specifier: ^3.5.2 - version: 3.5.2(@algolia/client-search@4.24.0)(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + version: 3.5.2(@algolia/client-search@4.24.0)(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@emotion/react': specifier: ^11.11.4 version: 11.13.3(@types/react@18.3.9)(react@18.3.1) @@ -1381,9 +1386,6 @@ importers: copy-text-to-clipboard: specifier: ^3.2.0 version: 3.2.0 - docusaurus-theme-search-typesense: - specifier: 0.20.0-0 - version: 0.20.0-0(@algolia/client-search@4.24.0)(@babel/runtime@7.25.6)(@docusaurus/core@3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/theme-common@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.9)(algoliasearch@4.24.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) dotenv: specifier: ^16.4.5 version: 16.4.5 @@ -1560,128 +1562,6 @@ importers: specifier: ^5.5.3 version: 5.6.2 - sdk/create-dapp/templates/react-client-dapp: - dependencies: - '@iota/dapp-kit': - specifier: workspace:* - version: link:../../../dapp-kit - '@iota/iota-sdk': - specifier: workspace:* - version: link:../../../typescript - '@radix-ui/colors': - specifier: ^3.0.0 - version: 3.0.0 - '@radix-ui/react-icons': - specifier: ^1.3.0 - version: 1.3.0(react@18.3.1) - '@radix-ui/themes': - specifier: ^3.1.1 - version: 3.1.4(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@tanstack/react-query': - specifier: ^5.50.1 - version: 5.56.2(react@18.3.1) - react: - specifier: ^18.3.1 - version: 18.3.1 - react-dom: - specifier: ^18.3.1 - version: 18.3.1(react@18.3.1) - devDependencies: - '@types/react': - specifier: ^18.3.3 - version: 18.3.9 - '@types/react-dom': - specifier: ^18.3.0 - version: 18.3.0 - '@typescript-eslint/eslint-plugin': - specifier: ^7.16.0 - version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1)(typescript@5.6.2) - '@typescript-eslint/parser': - specifier: ^7.16.0 - version: 7.18.0(eslint@8.57.1)(typescript@5.6.2) - '@vitejs/plugin-react-swc': - specifier: ^3.7.0 - version: 3.7.0(@swc/helpers@0.5.5)(vite@5.4.8(@types/node@22.7.3)(sass@1.79.3)(terser@5.34.0)) - eslint: - specifier: 8.57.1 - version: 8.57.1 - eslint-plugin-react-hooks: - specifier: ^4.6.2 - version: 4.6.2(eslint@8.57.1) - eslint-plugin-react-refresh: - specifier: ^0.4.7 - version: 0.4.12(eslint@8.57.1) - prettier: - specifier: ^3.3.2 - version: 3.3.3 - typescript: - specifier: ^5.5.3 - version: 5.6.2 - vite: - specifier: ^5.3.3 - version: 5.4.8(@types/node@22.7.3)(sass@1.79.3)(terser@5.34.0) - - sdk/create-dapp/templates/react-e2e-counter: - dependencies: - '@iota/dapp-kit': - specifier: workspace:* - version: link:../../../dapp-kit - '@iota/iota-sdk': - specifier: workspace:* - version: link:../../../typescript - '@radix-ui/colors': - specifier: ^3.0.0 - version: 3.0.0 - '@radix-ui/react-icons': - specifier: ^1.3.0 - version: 1.3.0(react@18.3.1) - '@radix-ui/themes': - specifier: ^3.1.1 - version: 3.1.4(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@tanstack/react-query': - specifier: ^5.50.1 - version: 5.56.2(react@18.3.1) - react: - specifier: ^18.3.1 - version: 18.3.1 - react-dom: - specifier: ^18.3.1 - version: 18.3.1(react@18.3.1) - devDependencies: - '@types/react': - specifier: ^18.3.3 - version: 18.3.9 - '@types/react-dom': - specifier: ^18.3.0 - version: 18.3.0 - '@typescript-eslint/eslint-plugin': - specifier: ^6.1.0 - version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1)(typescript@5.6.2) - '@typescript-eslint/parser': - specifier: ^6.1.0 - version: 6.21.0(eslint@8.57.1)(typescript@5.6.2) - '@vitejs/plugin-react-swc': - specifier: ^3.7.0 - version: 3.7.0(@swc/helpers@0.5.5)(vite@5.4.8(@types/node@22.7.3)(sass@1.79.3)(terser@5.34.0)) - eslint: - specifier: 8.57.1 - version: 8.57.1 - eslint-plugin-react-hooks: - specifier: ^4.6.2 - version: 4.6.2(eslint@8.57.1) - eslint-plugin-react-refresh: - specifier: ^0.4.7 - version: 0.4.12(eslint@8.57.1) - prettier: - specifier: ^3.3.2 - version: 3.3.3 - typescript: - specifier: ^5.5.3 - version: 5.6.2 - vite: - specifier: ^5.3.3 - version: 5.4.8(@types/node@22.7.3)(sass@1.79.3)(terser@5.34.0) - sdk/dapp-kit: dependencies: '@iota/iota-sdk': @@ -2064,9 +1944,6 @@ packages: '@adraffy/ens-normalize@1.11.0': resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} - '@algolia/autocomplete-core@1.8.2': - resolution: {integrity: sha512-mTeshsyFhAqw/ebqNsQpMtbnjr+qVOSKXArEj4K0d7sqc8It1XD0gkASwecm9mF/jlOQ4Z9RNg1HbdA8JPdRwQ==} - '@algolia/autocomplete-core@1.9.3': resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} @@ -2075,21 +1952,12 @@ packages: peerDependencies: search-insights: '>= 1 < 3' - '@algolia/autocomplete-preset-algolia@1.8.2': - resolution: {integrity: sha512-J0oTx4me6ZM9kIKPuL3lyU3aB8DEvpVvR6xWmHVROx5rOYJGQcZsdG4ozxwcOyiiu3qxMkIbzntnV1S1VWD8yA==} - peerDependencies: - '@algolia/client-search': '>= 4.9.1 < 6' - algoliasearch: '>= 4.9.1 < 6' - '@algolia/autocomplete-preset-algolia@1.9.3': resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==} peerDependencies: '@algolia/client-search': '>= 4.9.1 < 6' algoliasearch: '>= 4.9.1 < 6' - '@algolia/autocomplete-shared@1.8.2': - resolution: {integrity: sha512-b6Z/X4MczChMcfhk6kfRmBzPgjoPzuS9KGR4AFsiLulLNRAAqhP+xZTKtMnZGhLuc61I20d5WqlId02AZvcO6g==} - '@algolia/autocomplete-shared@1.9.3': resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==} peerDependencies: @@ -2922,10 +2790,6 @@ packages: resolution: {integrity: sha512-Gz0Nrobx8szge6kQQ5Z5MX9L3ObqNwCQY1PSwSNzreFL7aHGxv8Fp2j3ETV6/wWdbiV+mW6OSm8oQhg3Tcsniw==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.21.0': - resolution: {integrity: sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==} - engines: {node: '>=6.9.0'} - '@babel/runtime@7.25.6': resolution: {integrity: sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==} engines: {node: '>=6.9.0'} @@ -3281,8 +3145,8 @@ packages: resolution: {integrity: sha512-ZzZY/b66W2Jd6NHbAhLyDWOEIBWC11VizGFk7Wx7M61JZRz7HR9Cq5P+65RKWUU7u6wgsE8Lmh9nE4Mz+U2eTg==} engines: {node: '>= 0.10.4'} - '@devicefarmer/adbkit@3.2.3': - resolution: {integrity: sha512-wK9rVrabs4QU0oK8Jnwi+HRBEm+s1x/o63kgthUe0y7K1bfcYmgLuQf41/adsj/5enddlSxzkJavl2EwOu+r1g==} + '@devicefarmer/adbkit@3.2.6': + resolution: {integrity: sha512-8lO1hSeTgtxcOHhp4tTWq/JaOysp5KNbbyFoxNEBnwkCDZu/Bji3ZfOaG++Riv9jN6c9bgdLBOZqJTC5VJPRKQ==} engines: {node: '>= 0.10.4'} hasBin: true @@ -3310,14 +3174,6 @@ packages: search-insights: optional: true - '@docusaurus/core@3.4.0': - resolution: {integrity: sha512-g+0wwmN2UJsBqy2fQRQ6fhXruoEa62JDeEa5d8IdTJlMoaDaEDfHh7WjwGRn4opuTQWpjAwP/fbcgyHKlE+64w==} - engines: {node: '>=18.0'} - hasBin: true - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - '@docusaurus/core@3.5.2': resolution: {integrity: sha512-4Z1WkhCSkX4KO0Fw5m/Vuc7Q3NxBG53NE5u59Rs96fWkMPZVSrzEPP16/Nk6cWb/shK7xXPndTmalJtw7twL/w==} engines: {node: '>=18.0'} @@ -3327,29 +3183,14 @@ packages: react: ^18.0.0 react-dom: ^18.0.0 - '@docusaurus/cssnano-preset@3.4.0': - resolution: {integrity: sha512-qwLFSz6v/pZHy/UP32IrprmH5ORce86BGtN0eBtG75PpzQJAzp9gefspox+s8IEOr0oZKuQ/nhzZ3xwyc3jYJQ==} - engines: {node: '>=18.0'} - '@docusaurus/cssnano-preset@3.5.2': resolution: {integrity: sha512-D3KiQXOMA8+O0tqORBrTOEQyQxNIfPm9jEaJoALjjSjc2M/ZAWcUfPQEnwr2JB2TadHw2gqWgpZckQmrVWkytA==} engines: {node: '>=18.0'} - '@docusaurus/logger@3.4.0': - resolution: {integrity: sha512-bZwkX+9SJ8lB9kVRkXw+xvHYSMGG4bpYHKGXeXFvyVc79NMeeBSGgzd4TQLHH+DYeOJoCdl8flrFJVxlZ0wo/Q==} - engines: {node: '>=18.0'} - '@docusaurus/logger@3.5.2': resolution: {integrity: sha512-LHC540SGkeLfyT3RHK3gAMK6aS5TRqOD4R72BEU/DE2M/TY8WwEUAMY576UUc/oNJXv8pGhBmQB6N9p3pt8LQw==} engines: {node: '>=18.0'} - '@docusaurus/mdx-loader@3.4.0': - resolution: {integrity: sha512-kSSbrrk4nTjf4d+wtBA9H+FGauf2gCax89kV8SUSJu3qaTdSIKdWERlngsiHaCFgZ7laTJ8a67UFf+xlFPtuTw==} - engines: {node: '>=18.0'} - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - '@docusaurus/mdx-loader@3.5.2': resolution: {integrity: sha512-ku3xO9vZdwpiMIVd8BzWV0DCqGEbCP5zs1iHfKX50vw6jX8vQo0ylYo1YJMZyz6e+JFJ17HYHT5FzVidz2IflA==} engines: {node: '>=18.0'} @@ -3357,12 +3198,6 @@ packages: react: ^18.0.0 react-dom: ^18.0.0 - '@docusaurus/module-type-aliases@3.4.0': - resolution: {integrity: sha512-A1AyS8WF5Bkjnb8s+guTDuYmUiwJzNrtchebBHpc0gz0PyHJNMaybUlSrmJjHVcGrya0LKI4YcR3lBDQfXRYLw==} - peerDependencies: - react: '*' - react-dom: '*' - '@docusaurus/module-type-aliases@3.5.2': resolution: {integrity: sha512-Z+Xu3+2rvKef/YKTMxZHsEXp1y92ac0ngjDiExRdqGTmEKtCUpkbNYH8v5eXo5Ls+dnW88n6WTa+Q54kLOkwPg==} peerDependencies: @@ -3377,13 +3212,6 @@ packages: react: ^18.0.0 react-dom: ^18.0.0 - '@docusaurus/plugin-content-docs@3.4.0': - resolution: {integrity: sha512-HkUCZffhBo7ocYheD9oZvMcDloRnGhBMOZRyVcAQRFmZPmNqSyISlXA1tQCIxW+r478fty97XXAGjNYzBjpCsg==} - engines: {node: '>=18.0'} - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - '@docusaurus/plugin-content-docs@3.5.2': resolution: {integrity: sha512-Bt+OXn/CPtVqM3Di44vHjE7rPCEsRCB/DMo2qoOuozB9f7+lsdrHvD0QCHdBs0uhz6deYJDppAr2VgqybKPlVQ==} engines: {node: '>=18.0'} @@ -3485,10 +3313,6 @@ packages: react: ^18.0.0 react-dom: ^18.0.0 - '@docusaurus/theme-translations@3.4.0': - resolution: {integrity: sha512-zSxCSpmQCCdQU5Q4CnX/ID8CSUUI3fvmq4hU/GNP/XoAWtXo9SAVnM3TzpU8Gb//H3WCsT8mJcTfyOk3d9ftNg==} - engines: {node: '>=18.0'} - '@docusaurus/theme-translations@3.5.2': resolution: {integrity: sha512-GPZLcu4aT1EmqSTmbdpVrDENGR2yObFEX8ssEFYTCiAIVc0EihNSdOIBTazUvgNqwvnoU1A8vIs1xyzc3LITTw==} engines: {node: '>=18.0'} @@ -3496,27 +3320,12 @@ packages: '@docusaurus/tsconfig@3.5.2': resolution: {integrity: sha512-rQ7toURCFnWAIn8ubcquDs0ewhPwviMzxh6WpRjBW7sJVCXb6yzwUaY3HMNa0VXCFw+qkIbFywrMTf+Pb4uHWQ==} - '@docusaurus/types@3.4.0': - resolution: {integrity: sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A==} - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - '@docusaurus/types@3.5.2': resolution: {integrity: sha512-N6GntLXoLVUwkZw7zCxwy9QiuEXIcTVzA9AkmNw16oc0AP3SXLrMmDMMBIfgqwuKWa6Ox6epHol9kMtJqekACw==} peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - '@docusaurus/utils-common@3.4.0': - resolution: {integrity: sha512-NVx54Wr4rCEKsjOH5QEVvxIqVvm+9kh7q8aYTU5WzUU9/Hctd6aTrcZ3G0Id4zYJ+AeaG5K5qHA4CY5Kcm2iyQ==} - engines: {node: '>=18.0'} - peerDependencies: - '@docusaurus/types': '*' - peerDependenciesMeta: - '@docusaurus/types': - optional: true - '@docusaurus/utils-common@3.5.2': resolution: {integrity: sha512-i0AZjHiRgJU6d7faQngIhuHKNrszpL/SHQPgF1zH4H+Ij6E9NBYGy6pkcGWToIv7IVPbs+pQLh1P3whn0gWXVg==} engines: {node: '>=18.0'} @@ -3526,23 +3335,10 @@ packages: '@docusaurus/types': optional: true - '@docusaurus/utils-validation@3.4.0': - resolution: {integrity: sha512-hYQ9fM+AXYVTWxJOT1EuNaRnrR2WGpRdLDQG07O8UOpsvCPWUVOeo26Rbm0JWY2sGLfzAb+tvJ62yF+8F+TV0g==} - engines: {node: '>=18.0'} - '@docusaurus/utils-validation@3.5.2': resolution: {integrity: sha512-m+Foq7augzXqB6HufdS139PFxDC5d5q2QKZy8q0qYYvGdI6nnlNsGH4cIGsgBnV7smz+mopl3g4asbSDvMV0jA==} engines: {node: '>=18.0'} - '@docusaurus/utils@3.4.0': - resolution: {integrity: sha512-fRwnu3L3nnWaXOgs88BVBmG1yGjcQqZNHG+vInhEa2Sz2oQB+ZjbEMO5Rh9ePFpZ0YDiDUhpaVjwmS+AU2F14g==} - engines: {node: '>=18.0'} - peerDependencies: - '@docusaurus/types': '*' - peerDependenciesMeta: - '@docusaurus/types': - optional: true - '@docusaurus/utils@3.5.2': resolution: {integrity: sha512-33QvcNFh+Gv+C2dP9Y9xWEzMgf3JzrpL2nW9PopidiohS1nDcyknKRx2DWaFvyVTTYIkkABVSr073VTj/NITNA==} engines: {node: '>=18.0'} @@ -4645,8 +4441,8 @@ packages: resolution: {integrity: sha512-3lBouSuF7CqlseLB+FKES0K4FQ02JrbEoRtJhxnsyB1s5v4AP03gsoohN8jp7DcOImhaR9scYdztq3/sLfk/qQ==} engines: {node: '>=14.18.0'} - '@mdn/browser-compat-data@5.5.29': - resolution: {integrity: sha512-NHdG3QOiAsxh8ygBSKMa/WaNJwpNt87uVqW+S2RlnSqgeRdk+L3foNWTX6qd0I3NHSlCFb47rgopeNCJtRDY5A==} + '@mdn/browser-compat-data@5.6.0': + resolution: {integrity: sha512-xArvLyzuk0r2m6hFVjTMYoLvhWwys3h7W8pO15tjSAea+U39cErWDNfoUs4g2C08HVg6bDHyDMBc0LC6FKRpVw==} '@mdx-js/mdx@3.0.1': resolution: {integrity: sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==} @@ -4681,19 +4477,25 @@ packages: resolution: {integrity: sha512-ihb3B0T/wJm1eUuArYP4lCTSEoZsClHhuWyfo/kMX3m/odpqNcPfsz5O2A3NT7dXCAgWPGDQGPqygCpgeniKMw==} engines: {node: '>=12.0.0'} - '@microsoft/api-extractor-model@7.28.13': - resolution: {integrity: sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==} + '@microsoft/api-extractor-model@7.30.1': + resolution: {integrity: sha512-CTS2PlASJHxVY8hqHORVb1HdECWOEMcMnM6/kDkPr0RZapAFSIHhg9D4jxuE8g+OWYHtPc10LCpmde5pylTRlA==} - '@microsoft/api-extractor@7.43.0': - resolution: {integrity: sha512-GFhTcJpB+MI6FhvXEI9b2K0snulNLWHqC/BbcJtyNYcKUiw7l3Lgis5ApsYncJ0leALX7/of4XfmXk+maT111w==} + '@microsoft/api-extractor@7.48.1': + resolution: {integrity: sha512-HN9Osa1WxqLM66RaqB5nPAadx+nTIQmY/XtkFdaJvusjG8Tus++QqZtD7KPZDSkhEMGHsYeSyeU8qUzCDUXPjg==} hasBin: true '@microsoft/tsdoc-config@0.16.2': resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==} + '@microsoft/tsdoc-config@0.17.1': + resolution: {integrity: sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw==} + '@microsoft/tsdoc@0.14.2': resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} + '@microsoft/tsdoc@0.15.1': + resolution: {integrity: sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==} + '@mswjs/interceptors@0.35.8': resolution: {integrity: sha512-PFfqpHplKa7KMdoQdj5td03uG05VK2Ng1dG0sP4pT9h0dGSX2v9txYt/AnrzPb/vAmfyBBC0NQV7VaBEX+efgQ==} engines: {node: '>=18'} @@ -4865,62 +4667,62 @@ packages: '@nestjs/platform-express': optional: true - '@next/env@14.2.10': - resolution: {integrity: sha512-dZIu93Bf5LUtluBXIv4woQw2cZVZ2DJTjax5/5DOs3lzEOeKLy7GxRSr4caK9/SCPdaW6bCgpye6+n4Dh9oJPw==} + '@next/env@14.2.15': + resolution: {integrity: sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ==} '@next/eslint-plugin-next@14.2.3': resolution: {integrity: sha512-L3oDricIIjgj1AVnRdRor21gI7mShlSwU/1ZGHmqM3LzHhXXhdkrfeNY5zif25Bi5Dd7fiJHsbhoZCHfXYvlAw==} - '@next/swc-darwin-arm64@14.2.10': - resolution: {integrity: sha512-V3z10NV+cvMAfxQUMhKgfQnPbjw+Ew3cnr64b0lr8MDiBJs3eLnM6RpGC46nhfMZsiXgQngCJKWGTC/yDcgrDQ==} + '@next/swc-darwin-arm64@14.2.15': + resolution: {integrity: sha512-Rvh7KU9hOUBnZ9TJ28n2Oa7dD9cvDBKua9IKx7cfQQ0GoYUwg9ig31O2oMwH3wm+pE3IkAQ67ZobPfEgurPZIA==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@14.2.10': - resolution: {integrity: sha512-Y0TC+FXbFUQ2MQgimJ/7Ina2mXIKhE7F+GUe1SgnzRmwFY3hX2z8nyVCxE82I2RicspdkZnSWMn4oTjIKz4uzA==} + '@next/swc-darwin-x64@14.2.15': + resolution: {integrity: sha512-5TGyjFcf8ampZP3e+FyCax5zFVHi+Oe7sZyaKOngsqyaNEpOgkKB3sqmymkZfowy3ufGA/tUgDPPxpQx931lHg==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@14.2.10': - resolution: {integrity: sha512-ZfQ7yOy5zyskSj9rFpa0Yd7gkrBnJTkYVSya95hX3zeBG9E55Z6OTNPn1j2BTFWvOVVj65C3T+qsjOyVI9DQpA==} + '@next/swc-linux-arm64-gnu@14.2.15': + resolution: {integrity: sha512-3Bwv4oc08ONiQ3FiOLKT72Q+ndEMyLNsc/D3qnLMbtUYTQAmkx9E/JRu0DBpHxNddBmNT5hxz1mYBphJ3mfrrw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@14.2.10': - resolution: {integrity: sha512-n2i5o3y2jpBfXFRxDREr342BGIQCJbdAUi/K4q6Env3aSx8erM9VuKXHw5KNROK9ejFSPf0LhoSkU/ZiNdacpQ==} + '@next/swc-linux-arm64-musl@14.2.15': + resolution: {integrity: sha512-k5xf/tg1FBv/M4CMd8S+JL3uV9BnnRmoe7F+GWC3DxkTCD9aewFRH1s5rJ1zkzDa+Do4zyN8qD0N8c84Hu96FQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-x64-gnu@14.2.10': - resolution: {integrity: sha512-GXvajAWh2woTT0GKEDlkVhFNxhJS/XdDmrVHrPOA83pLzlGPQnixqxD8u3bBB9oATBKB//5e4vpACnx5Vaxdqg==} + '@next/swc-linux-x64-gnu@14.2.15': + resolution: {integrity: sha512-kE6q38hbrRbKEkkVn62reLXhThLRh6/TvgSP56GkFNhU22TbIrQDEMrO7j0IcQHcew2wfykq8lZyHFabz0oBrA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@14.2.10': - resolution: {integrity: sha512-opFFN5B0SnO+HTz4Wq4HaylXGFV+iHrVxd3YvREUX9K+xfc4ePbRrxqOuPOFjtSuiVouwe6uLeDtabjEIbkmDA==} + '@next/swc-linux-x64-musl@14.2.15': + resolution: {integrity: sha512-PZ5YE9ouy/IdO7QVJeIcyLn/Rc4ml9M2G4y3kCM9MNf1YKvFY4heg3pVa/jQbMro+tP6yc4G2o9LjAz1zxD7tQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@14.2.10': - resolution: {integrity: sha512-9NUzZuR8WiXTvv+EiU/MXdcQ1XUvFixbLIMNQiVHuzs7ZIFrJDLJDaOF1KaqttoTujpcxljM/RNAOmw1GhPPQQ==} + '@next/swc-win32-arm64-msvc@14.2.15': + resolution: {integrity: sha512-2raR16703kBvYEQD9HNLyb0/394yfqzmIeyp2nDzcPV4yPjqNUG3ohX6jX00WryXz6s1FXpVhsCo3i+g4RUX+g==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-ia32-msvc@14.2.10': - resolution: {integrity: sha512-fr3aEbSd1GeW3YUMBkWAu4hcdjZ6g4NBl1uku4gAn661tcxd1bHs1THWYzdsbTRLcCKLjrDZlNp6j2HTfrw+Bg==} + '@next/swc-win32-ia32-msvc@14.2.15': + resolution: {integrity: sha512-fyTE8cklgkyR1p03kJa5zXEaZ9El+kDNM5A+66+8evQS5e/6v0Gk28LqA0Jet8gKSOyP+OTm/tJHzMlGdQerdQ==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] - '@next/swc-win32-x64-msvc@14.2.10': - resolution: {integrity: sha512-UjeVoRGKNL2zfbcQ6fscmgjBAS/inHBh63mjIlfPg/NG8Yn2ztqylXt5qilYb6hoHIwaU2ogHknHWWmahJjgZQ==} + '@next/swc-win32-x64-msvc@14.2.15': + resolution: {integrity: sha512-SzqGbsLsP9OwKNUG9nekShTwhj6JSB9ZLMWQ8g1gG6hdE5gQLncbnbymrwy2yVmH9nikSLYRYxYMFu78Ggp7/g==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -5166,15 +4968,9 @@ packages: '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} - '@radix-ui/colors@3.0.0': - resolution: {integrity: sha512-FUOsGBkHrYJwCSEtWRCIfQbZG7q1e6DgxCIOe1SUQzDe/7rXXeA47s8yCn6fuTNQAj1Zq4oTFi9Yjp3wzElcxg==} - '@radix-ui/number@1.0.1': resolution: {integrity: sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==} - '@radix-ui/number@1.1.0': - resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==} - '@radix-ui/primitive@1.0.0': resolution: {integrity: sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==} @@ -5184,32 +4980,6 @@ packages: '@radix-ui/primitive@1.1.0': resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==} - '@radix-ui/react-accessible-icon@1.1.0': - resolution: {integrity: sha512-i9Zg4NOSXlfUva0agzI2DjWrvFJm9uO4L6CMW7nmMa5CIOOX/Yin894W7WwjodFQWPwe5kmAJ4JF33R8slKI2g==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-alert-dialog@1.1.1': - resolution: {integrity: sha512-wmCoJwj7byuVuiLKqDLlX7ClSUU0vd9sdCeM+2Ls+uf13+cpSJoMgwysHq1SGVVkJj5Xn0XWi1NoRCdkMpr6Mw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-arrow@1.0.3': resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==} peerDependencies: @@ -5236,45 +5006,6 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-aspect-ratio@1.1.0': - resolution: {integrity: sha512-dP87DM/Y7jFlPgUZTlhx6FF5CEzOiaxp2rBCKlaXlpH5Ip/9Fg5zZ9lDOQ5o/MOfUlf36eak14zoWYpgcgGoOg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-avatar@1.1.0': - resolution: {integrity: sha512-Q/PbuSMk/vyAd/UoIShVGZ7StHHeRFYU7wXmi5GV+8cLXflZAEpHL/F697H1klrzxKXNtZ97vWiC0q3RKUH8UA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-checkbox@1.1.0': - resolution: {integrity: sha512-3+kSzVfMONtP3B6CvaOrXLVTyGYws7tGmG5kOY0AfyH9sexkLytIwciNwjZhY0RoGOEbxI7bMS21XYB8H5itWQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-checkbox@1.1.1': resolution: {integrity: sha512-0i/EKJ222Afa1FE0C6pNJxDq1itzcl3HChE9DwskA4th4KRse8ojx8a1nVcOjwJdbpDLcz7uol77yYnQNMHdKw==} peerDependencies: @@ -5350,19 +5081,6 @@ packages: '@types/react': optional: true - '@radix-ui/react-context-menu@2.2.1': - resolution: {integrity: sha512-wvMKKIeb3eOrkJ96s722vcidZ+2ZNfcYZWBPRHIB1VWrF+fiF851Io6LX0kmK5wTDQFKdulCCKJk2c3SBaQHvA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-context@1.0.0': resolution: {integrity: sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==} peerDependencies: @@ -5523,37 +5241,6 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-form@0.1.0': - resolution: {integrity: sha512-1/oVYPDjbFILOLIarcGcMKo+y6SbTVT/iUKVEw59CF4offwZgBgC3ZOeSBewjqU0vdA6FWTPWTN63obj55S/tQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-hover-card@1.1.1': - resolution: {integrity: sha512-IwzAOP97hQpDADYVKrEEHUH/b2LA+9MgB0LgdmnbFO2u/3M5hmEofjjr2M6CyzUblaAqJdFm6B7oFtU72DPXrA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-icons@1.3.0': - resolution: {integrity: sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==} - peerDependencies: - react: ^16.x || ^17.x || ^18.x - '@radix-ui/react-id@1.0.0': resolution: {integrity: sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==} peerDependencies: @@ -5738,32 +5425,6 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-progress@1.1.0': - resolution: {integrity: sha512-aSzvnYpP725CROcxAOEBVZZSIQVQdHgBr2QQFKySsaD14u8dNT0batuXI+AAGDdAHfXH8rbnHmjYFqVJ21KkRg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-radio-group@1.2.0': - resolution: {integrity: sha512-yv+oiLaicYMBpqgfpSPw6q+RyXlLdIpQWDHZbUKURxe+nEh53hFXPPlfhfQQtYkS5MMK/5IWIa76SksleQZSzw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-roving-focus@1.1.0': resolution: {integrity: sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==} peerDependencies: @@ -5777,19 +5438,6 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-scroll-area@1.1.0': - resolution: {integrity: sha512-9ArIZ9HWhsrfqS765h+GZuLoxaRHD/j0ZWOWilsCvYTpYJp8XwCqNG7Dt9Nu/TItKOdgLGkOPCodQvDc+UMwYg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-select@1.2.2': resolution: {integrity: sha512-zI7McXr8fNaSrUY9mZe4x/HC0jTLY9fWNhO1oLWYMQGDXuV4UCivIGTxwioSzO0ZCYX9iSLyWmAh/1TOmX3Cnw==} peerDependencies: @@ -5803,19 +5451,6 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-select@2.1.1': - resolution: {integrity: sha512-8iRDfyLtzxlprOo9IicnzvpsO1wNCkuwzzCM+Z5Rb5tNOpCdMvcc2AkzX0Fz+Tz9v6NJ5B/7EEgyZveo4FBRfQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-separator@1.1.0': resolution: {integrity: sha512-3uBAs+egzvJBDZAzvb/n4NxxOYpnspmWxO2u5NbZ8Y6FM/NdrGSF9bop3Cf6F6C71z1rTSn8KV0Fo2ZVd79lGA==} peerDependencies: @@ -5829,19 +5464,6 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-slider@1.2.0': - resolution: {integrity: sha512-dAHCDA4/ySXROEPaRtaMV5WHL8+JB/DbtyTbJjYkY0RXmKMO2Ln8DFZhywG5/mVQ4WqHDBc8smc14yPXPqZHYA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-slot@1.0.0': resolution: {integrity: sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==} peerDependencies: @@ -5930,19 +5552,6 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-tooltip@1.1.1': - resolution: {integrity: sha512-LLE8nzNE4MzPMw3O2zlVlkLFid3y9hMUs7uCbSHyKSo+tCN4yMCf+ZCCcfrYgsOC0TiHBPQ1mtpJ2liY3ZT3SQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-use-callback-ref@1.0.0': resolution: {integrity: sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==} peerDependencies: @@ -6121,19 +5730,6 @@ packages: '@radix-ui/rect@1.1.0': resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==} - '@radix-ui/themes@3.1.4': - resolution: {integrity: sha512-HmyU8UpoYPmdfXSQIwbEnJS2Wv/5wbzxe/Niw/sMLMJTrlZiUKM/dEOM7N+bc7w2OMpUaQ8OH9czCGpcjHx98w==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: 16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: 16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - '@reduxjs/toolkit@1.9.7': resolution: {integrity: sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==} peerDependencies: @@ -6247,27 +5843,27 @@ packages: '@rushstack/eslint-patch@1.10.4': resolution: {integrity: sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==} - '@rushstack/node-core-library@4.0.2': - resolution: {integrity: sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==} + '@rushstack/node-core-library@5.10.1': + resolution: {integrity: sha512-BSb/KcyBHmUQwINrgtzo6jiH0HlGFmrUy33vO6unmceuVKTEyL2q+P0fQq2oB5hvXVWOEUhxB2QvlkZluvUEmg==} peerDependencies: '@types/node': '*' peerDependenciesMeta: '@types/node': optional: true - '@rushstack/rig-package@0.5.2': - resolution: {integrity: sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==} + '@rushstack/rig-package@0.5.3': + resolution: {integrity: sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==} - '@rushstack/terminal@0.10.0': - resolution: {integrity: sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==} + '@rushstack/terminal@0.14.4': + resolution: {integrity: sha512-NxACqERW0PHq8Rpq1V6v5iTHEwkRGxenjEW+VWqRYQ8T9puUzgmGHmEZUaUEDHAe9Qyvp0/Ew04sAiQw9XjhJg==} peerDependencies: '@types/node': '*' peerDependenciesMeta: '@types/node': optional: true - '@rushstack/ts-command-line@4.19.1': - resolution: {integrity: sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==} + '@rushstack/ts-command-line@4.23.2': + resolution: {integrity: sha512-JJ7XZX5K3ThBBva38aomgsPv1L7FV6XmSOcR6HtM7HDFZJkepqT65imw26h9ggGqMjsY0R9jcl30tzKcVj9aOQ==} '@saucelabs/theme-github-codeblock@0.3.0': resolution: {integrity: sha512-+8xWxBfN+I8StJ0QXERMbGf+BHwRXHWV3mFl9uDayXERiZ/rR93d0nAS3s9s/rKjqh/YSm/4dThEkBNBLnGs4Q==} @@ -6287,20 +5883,20 @@ packages: '@scure/bip39@1.4.0': resolution: {integrity: sha512-BEEm6p8IueV/ZTfQLp/0vhw4NPnT9oWf5+28nvmeUICjP99f4vr2d+qc7AVGDDtwRep6ifR43Yed9ERVmiITzw==} - '@sentry-internal/feedback@7.119.0': - resolution: {integrity: sha512-om8TkAU5CQGO8nkmr7qsSBVkP+/vfeS4JgtW3sjoTK0fhj26+DljR6RlfCGWtYQdPSP6XV7atcPTjbSnsmG9FQ==} + '@sentry-internal/feedback@7.120.2': + resolution: {integrity: sha512-AAKW/Qii2qFA/jIZc9HK/CgQLfJ/9zBCqC9FF3bUTnAxzZAbJHO1TLnHqDl5k5wYtt449NrpObHORpopSk7TBg==} engines: {node: '>=12'} - '@sentry-internal/replay-canvas@7.119.0': - resolution: {integrity: sha512-NL02VQx6ekPxtVRcsdp1bp5Tb5w6vnfBKSIfMKuDRBy5A10Uc3GSoy/c3mPyHjOxB84452A+xZSx6bliEzAnuA==} + '@sentry-internal/replay-canvas@7.120.2': + resolution: {integrity: sha512-2Xm9rJxUA5/CCUYRHNH4VxG13eQpXvM05/cHQKn+pmjaPq/+3fbOHrZZM84gF1FSHjeN8Kg1igoMSekU2kavOQ==} engines: {node: '>=12'} - '@sentry-internal/tracing@7.119.0': - resolution: {integrity: sha512-oKdFJnn+56f0DHUADlL8o9l8jTib3VDLbWQBVkjD9EprxfaCwt2m8L5ACRBdQ8hmpxCEo4I8/6traZ7qAdBUqA==} + '@sentry-internal/tracing@7.120.2': + resolution: {integrity: sha512-eo2F8cP6X+vr54Mp6vu+NoQEDz0M5O24Tz8jPY0T1CpiWdwCmHb7Sln+oLXeQ3/LlWdVQihBfKDBZfBdUfsBTg==} engines: {node: '>=8'} - '@sentry/browser@7.119.0': - resolution: {integrity: sha512-WwmW1Y4D764kVGeKmdsNvQESZiAn9t8LmCWO0ucBksrjL2zw9gBPtOpRcO6l064sCLeSxxzCN+kIxhRm1gDFEA==} + '@sentry/browser@7.120.2': + resolution: {integrity: sha512-o5ll2Yv5MfnblbWxTvMlKK3RVXIbeJ+SPC+uw12b4j/pkrQg+/y7dyTLBXh6t0EgokSOsRUyYosQwSvxG/xs/Q==} engines: {node: '>=8'} '@sentry/cli@1.77.3': @@ -6316,12 +5912,16 @@ packages: resolution: {integrity: sha512-CS2kUv9rAJJEjiRat6wle3JATHypB0SyD7pt4cpX5y0dN5dZ1JrF57oLHRMnga9fxRivydHz7tMTuBhSSwhzjw==} engines: {node: '>=8'} + '@sentry/core@7.120.2': + resolution: {integrity: sha512-eurLBFQJC7WWWYoEna25Z9I/GJjqAmH339tv52XP8sqXV7B5hRcHDcfrsT/UGHpU316M24p3lWhj0eimtCZ0SQ==} + engines: {node: '>=8'} + '@sentry/hub@6.19.7': resolution: {integrity: sha512-y3OtbYFAqKHCWezF0EGGr5lcyI2KbaXW2Ik7Xp8Mu9TxbSTuwTe4rTntwg8ngPjUQU3SUHzgjqVB8qjiGqFXCA==} engines: {node: '>=6'} - '@sentry/integrations@7.119.0': - resolution: {integrity: sha512-OHShvtsRW0A+ZL/ZbMnMqDEtJddPasndjq+1aQXw40mN+zeP7At/V1yPZyFaURy86iX7Ucxw5BtmzuNy7hLyTA==} + '@sentry/integrations@7.120.2': + resolution: {integrity: sha512-bMvL2fD3TGLM5YAUoQ2Qz6bYeVU8f7YRFNSjKNxK4EbvFgAU9j1FD6EKg0V0RNOJYnJjGIZYMmcWTXBbVTJL6w==} engines: {node: '>=8'} '@sentry/minimal@6.19.7': @@ -6338,8 +5938,8 @@ packages: peerDependencies: react: 15.x || 16.x || 17.x || 18.x - '@sentry/replay@7.119.0': - resolution: {integrity: sha512-BnNsYL+X5I4WCH6wOpY6HQtp4MgVt0NVlhLUsEyrvMUiTs0bPkDBrulsgZQBUKJsbOr3l9nHrFoNVB/0i6WNLA==} + '@sentry/replay@7.120.2': + resolution: {integrity: sha512-UAw0anHwXeej0Rfx+7qZVbRb3rj3mQ0DuHqdpPTSd9WpfRGOvCfthMIKD7rfHX7GjMnPMgdmsaU8K3lpe60h+w==} engines: {node: '>=12'} '@sentry/types@6.19.7': @@ -6350,6 +5950,10 @@ packages: resolution: {integrity: sha512-27qQbutDBPKGbuJHROxhIWc1i0HJaGLA90tjMu11wt0E4UNxXRX+UQl4Twu68v4EV3CPvQcEpQfgsViYcXmq+w==} engines: {node: '>=8'} + '@sentry/types@7.120.2': + resolution: {integrity: sha512-FWVoiblHQJ892GaOqdXx/5/n5XDLF28z81vJ0lCY49PMh8waz8LJ0b9RSmt9tasSDl0OQ7eUlPl1xu1jTrv1NA==} + engines: {node: '>=8'} + '@sentry/utils@6.19.7': resolution: {integrity: sha512-z95ECmE3i9pbWoXQrD/7PgkBAzJYR+iXtPuTkpBjDKs86O3mT+PXOT3BAn79w2wkn7/i3vOGD2xVr1uiMl26dA==} engines: {node: '>=6'} @@ -6358,6 +5962,10 @@ packages: resolution: {integrity: sha512-ZwyXexWn2ZIe2bBoYnXJVPc2esCSbKpdc6+0WJa8eutXfHq3FRKg4ohkfCBpfxljQGEfP1+kfin945lA21Ka+A==} engines: {node: '>=8'} + '@sentry/utils@7.120.2': + resolution: {integrity: sha512-jgnQlw11mRfQrQRAXbq4zEd+tbYwHel5eqeS/oU6EImXRjmHNtS79nB8MHvJeQu1FMCpFs1Ymrrs5FICwS6VeQ==} + engines: {node: '>=8'} + '@sentry/webpack-plugin@1.21.0': resolution: {integrity: sha512-x0PYIMWcsTauqxgl7vWUY6sANl+XGKtx7DCVnnY7aOIIlIna0jChTAPANTfA2QrK+VK+4I/4JxatCEZBnXh3Og==} engines: {node: '>= 8'} @@ -7726,14 +7334,14 @@ packages: '@vitest/utils@2.1.1': resolution: {integrity: sha512-Y6Q9TsI+qJ2CC0ZKj6VBb+T8UPz593N113nnUykqwANqhgf3QkZeHFlusgKLTqrnVHbj/XDKZcDHol+dxVT+rQ==} - '@volar/language-core@1.11.1': - resolution: {integrity: sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==} + '@volar/language-core@2.4.11': + resolution: {integrity: sha512-lN2C1+ByfW9/JRPpqScuZt/4OrUUse57GLI6TbLgTIqBVemdl1wNcZ1qYGEo2+Gw8coYLgCy7SuKqn6IrQcQgg==} - '@volar/source-map@1.11.1': - resolution: {integrity: sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==} + '@volar/source-map@2.4.11': + resolution: {integrity: sha512-ZQpmafIGvaZMn/8iuvCFGrW3smeqkq/IIh9F1SdSx9aUl0J4Iurzd6/FhmjNO5g2ejF3rT45dKskgXWiofqlZQ==} - '@volar/typescript@1.11.1': - resolution: {integrity: sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==} + '@volar/typescript@2.4.11': + resolution: {integrity: sha512-2DT+Tdh88Spp5PyPbqhyoYavYCPDsqbHLFwcUI9K1NlY1YgUJvujGdrqUp0zWxnW7KWNTr3xSpMuv2WnaTKDAw==} '@vue/compiler-core@3.5.9': resolution: {integrity: sha512-KE1sCdwqSKq0CQ/ltg3XnlMTKeinjegIkuFsuq9DKvNPmqLGdmI51ChZdGBBRXIvEYTLm8X/JxOuBQ1HqF/+PA==} @@ -7741,8 +7349,11 @@ packages: '@vue/compiler-dom@3.5.9': resolution: {integrity: sha512-gEAURwPo902AsJF50vl59VaWR+Cx6cX9SoqLYHu1jq9hDbmQlXvpZyYNIIbxa2JTJ+FD/oBQweVUwuTQv79KTg==} - '@vue/language-core@1.8.27': - resolution: {integrity: sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==} + '@vue/compiler-vue2@2.7.16': + resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} + + '@vue/language-core@2.1.6': + resolution: {integrity: sha512-MW569cSky9R/ooKMh6xa2g1D0AtRKbL56k83dzus/bx//RDJk24RHWkMzbAlXjMdDNyxAaagKPRquBIxkxlCkg==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -7941,19 +7552,24 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - addons-linter@6.28.0: - resolution: {integrity: sha512-fCTjXL/yG4hwq74JG8tQdrvEu0OvGrEN9yU+Df0020RDtHl3g/tTCyMeC4G1uyk8IuyMzp4myCBNnOGC7MWSQQ==} - engines: {node: '>=16.0.0'} + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} + hasBin: true + + addons-linter@7.1.0: + resolution: {integrity: sha512-UmkUB3dZSpf8bqhlulGDbpoxBwcfOk8JvaJTRvJ+AAXKHvTjqeNlFC+GRMqa0EjJJh/0yqpBaJzyaUIx+fjl+A==} + engines: {node: '>=18.0.0'} hasBin: true addons-moz-compare@1.3.0: resolution: {integrity: sha512-/rXpQeaY0nOKhNx00pmZXdk5Mu+KhVlL3/pSBuAYwrxRrNiTvI/9xfQI8Lmm7DMMl+PDhtfAHY/0ibTpdeoQQQ==} - addons-scanner-utils@9.10.1: - resolution: {integrity: sha512-Tz9OUQx9Ja0TyQ+H2GakB9KlJ50myI6ESBGRlA8N80nHBzMjjPRFGm0APADSaCd5NP74SrFtEvL4TRpDwZXETA==} + addons-scanner-utils@9.11.0: + resolution: {integrity: sha512-X95V8ymnue9EHmOLz3zJTGHvHDFlWKiavlH+kJKOlv2sJDWFvD3TWeJMHJgxS9GKOqT/545mOXvX3vuuGGum+g==} peerDependencies: body-parser: '>=1.20.3' - express: 4.18.3 + express: 4.19.2 node-fetch: 2.6.11 safe-compare: 1.1.4 peerDependenciesMeta: @@ -7990,9 +7606,20 @@ packages: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} + ajv-draft-04@1.0.0: + resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} + peerDependencies: + ajv: ^8.5.0 + peerDependenciesMeta: + ajv: + optional: true + ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + ajv-keywords@3.5.2: resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} peerDependencies: @@ -8169,17 +7796,10 @@ packages: asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} - asn1@0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - asn1js@3.0.5: resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==} engines: {node: '>=12.0.0'} - assert-plus@1.0.0: - resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} - engines: {node: '>=0.8'} - assert@2.1.0: resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} @@ -8216,6 +7836,9 @@ packages: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} + atomically@2.0.3: + resolution: {integrity: sha512-kU6FmrwZ3Lx7/7y3hPS5QnbJfaohcIul5fGqf7ok+4KklIEk9tJ0C2IQPdacSbVUWv6zVHXEBWoWd6NrVMT7Cw==} + auto-bind@4.0.0: resolution: {integrity: sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==} engines: {node: '>=8'} @@ -8231,18 +7854,12 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - aws-sign2@0.7.0: - resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} - - aws4@1.13.2: - resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} - axe-core@4.10.0: resolution: {integrity: sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==} engines: {node: '>=4'} - axios@0.26.1: - resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==} + axios@0.28.0: + resolution: {integrity: sha512-Tu7NYoGY4Yoc7I+Npf9HhUMtEEpV7ZiLH9yndTCoNhcpBH0kwcvFbzYN9/u5QKI5A6uefjsNNWaz5olJVYS62Q==} axios@1.7.7: resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} @@ -8336,9 +7953,6 @@ packages: batch@0.6.1: resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} - bcrypt-pbkdf@1.0.2: - resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} - bech32@2.0.0: resolution: {integrity: sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==} @@ -8395,6 +8009,10 @@ packages: resolution: {integrity: sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==} engines: {node: '>=14.16'} + boxen@8.0.1: + resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==} + engines: {node: '>=18'} + bplist-parser@0.2.0: resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==} engines: {node: '>= 5.10.0'} @@ -8433,9 +8051,6 @@ packages: buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - buffer-equal-constant-time@1.0.1: - resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} - buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -8448,10 +8063,9 @@ packages: builtins@1.0.3: resolution: {integrity: sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==} - bunyan@1.8.15: - resolution: {integrity: sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==} - engines: {'0': node >=0.10.0} - hasBin: true + bundle-name@3.0.0: + resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==} + engines: {node: '>=12'} busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} @@ -8519,6 +8133,10 @@ packages: resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} engines: {node: '>=14.16'} + camelcase@8.0.0: + resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} + engines: {node: '>=16'} + caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} @@ -8532,9 +8150,6 @@ packages: resolution: {integrity: sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==} hasBin: true - caseless@0.12.0: - resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} - ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -8634,8 +8249,8 @@ packages: '@chromatic-com/playwright': optional: true - chrome-launcher@0.15.1: - resolution: {integrity: sha512-UugC8u59/w2AyX5sHLZUHoxBAiSiunUhZa3zZwMH6zPVis0C3dDKiRWyUGIo14tTbZHGVviWxv3PQWZ7taZ4fg==} + chrome-launcher@1.1.2: + resolution: {integrity: sha512-YclTJey34KUm5jB1aEJCq807bSievi7Nb/TU4Gu504fUYi3jw3KCIaH6L7nFWQhdEgH3V+wCh+kKD1P5cXnfxw==} engines: {node: '>=12.13.0'} hasBin: true @@ -8656,9 +8271,6 @@ packages: class-variance-authority@0.7.0: resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==} - classnames@2.3.2: - resolution: {integrity: sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==} - classnames@2.5.1: resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} @@ -8741,10 +8353,6 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} - clsx@1.2.1: - resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} - engines: {node: '>=6'} - clsx@2.0.0: resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==} engines: {node: '>=6'} @@ -8863,6 +8471,9 @@ packages: commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + compare-versions@6.1.1: + resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} + component-emitter@1.3.1: resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} @@ -8896,6 +8507,9 @@ packages: confbox@0.1.7: resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + config-chain@1.1.13: resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} @@ -8903,6 +8517,10 @@ packages: resolution: {integrity: sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==} engines: {node: '>=12'} + configstore@7.0.0: + resolution: {integrity: sha512-yk7/5PN5im4qwz0WFZW3PXnzHgPu9mX29Y8uZ3aefe2lBPC1FYttWZRcaW9fKkT0pBCJyuQ2HfbmPVaODi9jcQ==} + engines: {node: '>=18'} + connect-history-api-fallback@2.0.0: resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} engines: {node: '>=0.8'} @@ -8969,15 +8587,9 @@ packages: core-js-pure@3.38.1: resolution: {integrity: sha512-BY8Etc1FZqdw1glX0XNOq2FDwfrg/VGqoZOZCdaL+UmdaqDwQwYXkMJT4t6In+zfEfOJDcM9T0KdbBeJg8KKCQ==} - core-js@3.29.0: - resolution: {integrity: sha512-VG23vuEisJNkGl6XQmFJd3rEG/so/CNatqeE+7uZAwTSwFeB/qaO0be8xZYUNWprJ/GIwL8aMt9cj1kvbpTZhg==} - core-js@3.38.1: resolution: {integrity: sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==} - core-util-is@1.0.2: - resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} - core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -9348,18 +8960,10 @@ packages: damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} - dashdash@1.14.1: - resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} - engines: {node: '>=0.10'} - dashify@2.0.0: resolution: {integrity: sha512-hpA5C/YrPjucXypHPPc0oJ1l9Hf6wWbiOL7Ik42cxnsUOhWiCB/fylKbKqqJalW9FgkNQCw16YO8uW9Hs0Iy1A==} engines: {node: '>=4'} - data-uri-to-buffer@4.0.1: - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} - engines: {node: '>= 12'} - data-urls@5.0.0: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} @@ -9465,9 +9069,6 @@ packages: deep-object-diff@1.1.9: resolution: {integrity: sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==} - deepcopy@2.1.0: - resolution: {integrity: sha512-8cZeTb1ZKC3bdSCP6XOM1IsTczIO73fdqtwa2B0N15eAz7gmyhQo+mc5gnFuulsgN3vIQYmTgbmQVKalH1dKvQ==} - deepmerge@2.2.1: resolution: {integrity: sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==} engines: {node: '>=0.10.0'} @@ -9480,6 +9081,10 @@ packages: resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==} engines: {node: '>=12'} + default-browser@4.0.0: + resolution: {integrity: sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==} + engines: {node: '>=14.16'} + default-gateway@6.0.3: resolution: {integrity: sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==} engines: {node: '>= 10'} @@ -9499,6 +9104,10 @@ packages: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} @@ -9627,15 +9236,6 @@ packages: peerDependencies: typedoc-plugin-markdown: '>=4.0.0' - docusaurus-theme-search-typesense@0.20.0-0: - resolution: {integrity: sha512-MW6fLJsZYfKKDRXC6pTe77OMhyQBishJO/L1M14hZymavKW2IyYFy+Mczp8TXL9QqvkLsW7Ja7YtnWXjmt5sCw==} - engines: {node: '>=18'} - peerDependencies: - '@docusaurus/core': 3.4.0 - '@docusaurus/theme-common': 3.4.0 - react: ^18.0.0 - react-dom: ^18.0.0 - dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} @@ -9689,6 +9289,10 @@ packages: resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} engines: {node: '>=10'} + dot-prop@9.0.0: + resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} + engines: {node: '>=18'} + dotenv-expand@10.0.0: resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} engines: {node: '>=12'} @@ -9705,10 +9309,6 @@ packages: resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} engines: {node: '>=4'} - dtrace-provider@0.8.8: - resolution: {integrity: sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==} - engines: {node: '>=0.10'} - duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} @@ -9718,12 +9318,6 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - ecc-jsbn@0.1.2: - resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} - - ecdsa-sig-formatter@1.0.11: - resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} - ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} @@ -9846,10 +9440,6 @@ packages: es6-error@4.1.1: resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} - es6-promisify@7.0.0: - resolution: {integrity: sha512-ginqzK3J90Rd4/Yz7qRrqUeIpe3TwSXTPPZtPne7tGBPeAaQiU8qt4fpKApnxHcq1AwtUdHVg5P77x/yrggG8Q==} - engines: {node: '>=6'} - esbuild-plugin-alias@0.2.1: resolution: {integrity: sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==} @@ -10003,11 +9593,6 @@ packages: peerDependencies: eslint: 8.57.1 - eslint-plugin-react-refresh@0.4.12: - resolution: {integrity: sha512-9neVjoGv20FwYtCP6CB1dzR1vr57ZDNOXst21wd2xJ/cTlM2xLq0GWVlSNTdMn/4BtP6cHYBMCSp1wFBJ9jBsg==} - peerDependencies: - eslint: 8.57.1 - eslint-plugin-react@7.37.0: resolution: {integrity: sha512-IHBePmfWH5lKhJnJ7WB1V+v/GolbB0rjS8XYVCSQCZKaQCAUhMoVoOEn1Ef8Z8Wf0a7l8KTJvuZg5/e4qrZ6nA==} engines: {node: '>=4'} @@ -10070,8 +9655,8 @@ packages: deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true - espree@10.0.1: - resolution: {integrity: sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==} + espree@10.1.0: + resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} espree@9.6.1: @@ -10170,6 +9755,10 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} + execa@7.2.0: + resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} + engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} @@ -10220,10 +9809,6 @@ packages: resolution: {integrity: sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==} hasBin: true - extsprintf@1.3.0: - resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} - engines: {'0': node >=0.6.0} - fast-decode-uri-component@1.0.1: resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} @@ -10309,10 +9894,6 @@ packages: resolution: {integrity: sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==} engines: {node: '>=0.4.0'} - fetch-blob@3.2.0: - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} - engines: {node: ^12.20 || >= 14.13} - fetch-retry@5.0.6: resolution: {integrity: sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ==} @@ -10390,8 +9971,9 @@ packages: resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - firefox-profile@4.3.2: - resolution: {integrity: sha512-/C+Eqa0YgIsQT2p66p7Ygzqe7NlE/GNTbhw2SBCm5V3OsWDPITNdTPEcH2Q2fe7eMpYYNPKdUcuVioZBZiR6kA==} + firefox-profile@4.7.0: + resolution: {integrity: sha512-aGApEu5bfCNbA4PGUZiRJAIU6jKmghV2UVdklXAofnNtiDjqYw0czLS46W7IfFqVKgKhFB8Ao2YoNGHY4BoIMQ==} + engines: {node: '>=18'} hasBin: true first-chunk-stream@3.0.0: @@ -10429,9 +10011,6 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} - forever-agent@0.6.1: - resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} - fork-ts-checker-webpack-plugin@6.5.3: resolution: {integrity: sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==} engines: {node: '>=10', yarn: '>=1.0.0'} @@ -10457,10 +10036,6 @@ packages: resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} engines: {node: '>= 14.17'} - form-data@2.3.3: - resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} - engines: {node: '>= 0.12'} - form-data@3.0.1: resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} engines: {node: '>= 6'} @@ -10473,10 +10048,6 @@ packages: resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} engines: {node: '>=0.4.x'} - formdata-polyfill@4.0.10: - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} - engines: {node: '>=12.20.0'} - formidable@2.1.2: resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==} @@ -10517,10 +10088,6 @@ packages: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} - fs-extra@11.1.0: - resolution: {integrity: sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==} - engines: {node: '>=14.14'} - fs-extra@11.1.1: resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} engines: {node: '>=14.14'} @@ -10537,10 +10104,6 @@ packages: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} - fs-extra@9.0.1: - resolution: {integrity: sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==} - engines: {node: '>=10'} - fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} @@ -10636,9 +10199,6 @@ packages: get-tsconfig@4.8.1: resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} - getpass@0.1.7: - resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} - giget@1.2.3: resolution: {integrity: sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==} hasBin: true @@ -10671,11 +10231,6 @@ packages: engines: {node: '>=16 || 14 >=14.17'} hasBin: true - glob@10.4.1: - resolution: {integrity: sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==} - engines: {node: '>=16 || 14 >=14.18'} - hasBin: true - glob@10.4.2: resolution: {integrity: sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==} engines: {node: '>=16 || 14 >=14.18'} @@ -10685,10 +10240,6 @@ packages: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true - glob@6.0.4: - resolution: {integrity: sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==} - deprecated: Glob versions prior to v9 are no longer supported - glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported @@ -10698,6 +10249,10 @@ packages: engines: {node: '>=12'} deprecated: Glob versions prior to v9 are no longer supported + global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} + global-dirs@3.0.1: resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} engines: {node: '>=10'} @@ -10837,15 +10392,6 @@ packages: resolution: {integrity: sha512-KyrFvnl+J9US63TEzwoiJOQzZBJY7KgBushJA8X61DMbNsH+2ONkDuLDnCnwUiPTF42tLoEmrPyoqbenVA5zrg==} engines: {node: '>=18.0.0'} - har-schema@2.0.0: - resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} - engines: {node: '>=4'} - - har-validator@5.1.5: - resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} - engines: {node: '>=6'} - deprecated: this library is no longer supported - has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} @@ -11065,10 +10611,6 @@ packages: resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} engines: {node: '>=8.0.0'} - http-signature@1.2.0: - resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} - engines: {node: '>=0.8', npm: '>=1.3.7'} - http2-wrapper@2.2.1: resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} engines: {node: '>=10.19.0'} @@ -11096,6 +10638,10 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} + human-signals@4.3.1: + resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} + engines: {node: '>=14.18.0'} + human-signals@5.0.0: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} @@ -11204,6 +10750,14 @@ packages: resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} engines: {node: '>=10'} + ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + ini@4.1.3: + resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + inline-style-parser@0.1.1: resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} @@ -11349,6 +10903,11 @@ packages: engines: {node: '>=8'} hasBin: true + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + is-extendable@0.1.1: resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} engines: {node: '>=0.10.0'} @@ -11394,10 +10953,24 @@ packages: is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-in-ci@1.0.0: + resolution: {integrity: sha512-eUuAjybVTHMYWm/U+vBO1sY/JOCgoPCXRxzdju0K+K0BiGW0SChEL1MLC0PoCIR1OlPo5YAp8HuQoUlsWEICwg==} + engines: {node: '>=18'} + hasBin: true + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + is-installed-globally@0.4.0: resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} engines: {node: '>=10'} + is-installed-globally@1.0.0: + resolution: {integrity: sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==} + engines: {node: '>=18'} + is-interactive@1.0.0: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} @@ -11409,9 +10982,6 @@ packages: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} - is-mergeable-object@1.1.1: - resolution: {integrity: sha512-CPduJfuGg8h8vW74WOxHtHmtQutyQBzR+3MjQ6iDHIYdbOnm1YC7jv43SqCoU8OPGTJD4nibmiryA4kmogbGrA==} - is-nan@1.3.2: resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} engines: {node: '>= 0.4'} @@ -11451,6 +11021,10 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} + is-path-inside@4.0.0: + resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} + engines: {node: '>=12'} + is-plain-obj@3.0.0: resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} engines: {node: '>=10'} @@ -11593,9 +11167,6 @@ packages: peerDependencies: ws: 8.18.0 - isstream@0.1.2: - resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} - istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -11792,8 +11363,8 @@ packages: joi@17.13.3: resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} - jose@4.13.1: - resolution: {integrity: sha512-MSJQC5vXco5Br38mzaQKiq9mwt7lwj2eXpgpRyQYNHYt2lq1PjkWa7DLXX0WVcQLE9HhMh3jPiufS7fhJf+CLQ==} + jose@5.9.2: + resolution: {integrity: sha512-ILI2xx/I57b20sd7rHZvgiiQrmp2mcotwsAH+5ajbpFQbrYVQdNHYlQhoA5cFb78CgtBOxtC05TeA+mcgkuCqQ==} jose@5.9.3: resolution: {integrity: sha512-egLIoYSpcd+QUF+UHgobt5YzI2Pkw/H39ou9suW687MY6PmCwPmkNV/4TNjn1p2tX5xO3j0d0sq5hiYE24bSlg==} @@ -11809,9 +11380,6 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true - jsbn@0.1.1: - resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} - jscodeshift@0.15.2: resolution: {integrity: sha512-FquR7Okgmc4Sd0aEDwqho3rEiKR3BdvuG9jfdHjLJ6JQoWSMpavug3AoIfnfWhxFlf+5pzQh8qjqz0DWFrNQzA==} hasBin: true @@ -11851,6 +11419,10 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-parse-even-better-errors@3.0.2: + resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + json-rpc-engine@6.1.0: resolution: {integrity: sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ==} engines: {node: '>=10.0.0'} @@ -11868,15 +11440,9 @@ packages: json-schema-typed@7.0.3: resolution: {integrity: sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==} - json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - json-to-pretty-yaml@1.2.2: resolution: {integrity: sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A==} engines: {node: '>= 0.2.0'} @@ -11902,14 +11468,6 @@ packages: jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - jsonwebtoken@9.0.0: - resolution: {integrity: sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==} - engines: {node: '>=12', npm: '>=6'} - - jsprim@1.4.2: - resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} - engines: {node: '>=0.6.0'} - jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} @@ -11917,12 +11475,6 @@ packages: jszip@3.10.1: resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} - jwa@1.4.1: - resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} - - jws@3.2.2: - resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} - katex@0.16.11: resolution: {integrity: sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==} hasBin: true @@ -11948,6 +11500,10 @@ packages: kolorist@1.8.0: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + ky@1.7.3: + resolution: {integrity: sha512-Sz49ZWR/BjNOq+2UK1k9ONZUVq8eyuCj30Zgc8VrRNtFlTBZduzuvehUd5kjQF6/Fms3Ir3EYqzJryw9tRvsSw==} + engines: {node: '>=18'} + language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -11959,6 +11515,10 @@ packages: resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} engines: {node: '>=14.16'} + latest-version@9.0.0: + resolution: {integrity: sha512-7W0vV3rqv5tokqkBAFV1LbR7HPOWzXQDpDgEuib/aJ1jsZZx6x3c2mBI+TJhJzOhkGeaLbCKEHXEXLfirtG2JA==} + engines: {node: '>=18'} + launch-editor@2.9.1: resolution: {integrity: sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==} @@ -11991,8 +11551,8 @@ packages: lie@3.3.0: resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} - lighthouse-logger@1.4.2: - resolution: {integrity: sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==} + lighthouse-logger@2.0.1: + resolution: {integrity: sha512-ioBrW3s2i97noEmnXxmUq7cjIcVRjT5HBpAYy8zE11CxU9HqlWHHeRxfeN1tn8F7OEMVPIC9x1f8t3Z7US9ehQ==} lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} @@ -12042,6 +11602,10 @@ packages: resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==} engines: {node: '>= 12.13.0'} + local-pkg@0.5.1: + resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} + engines: {node: '>=14'} + localforage@1.10.0: resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==} @@ -12073,12 +11637,6 @@ packages: lodash.deburr@4.1.0: resolution: {integrity: sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==} - lodash.get@4.4.2: - resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} - - lodash.isequal@4.5.0: - resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} - lodash.isnumber@3.0.3: resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} @@ -12123,10 +11681,6 @@ packages: resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} engines: {node: '>=18'} - loglevel@1.9.2: - resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} - engines: {node: '>= 0.6.0'} - longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -12686,6 +12240,9 @@ packages: mlly@1.7.1: resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + mlly@1.7.3: + resolution: {integrity: sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==} + modern-ahocorasick@1.0.1: resolution: {integrity: sha512-yoe+JbhTClckZ67b2itRtistFKf8yPYelHLc7e5xAwtNAXxM6wJTUx2C7QeVSJFDzKT7bCIFyBVybPMKvmB9AA==} @@ -12716,8 +12273,8 @@ packages: typescript: optional: true - muggle-string@0.3.1: - resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==} + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} multer@1.4.4-lts.1: resolution: {integrity: sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg==} @@ -12738,23 +12295,16 @@ packages: resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - mv@2.1.1: - resolution: {integrity: sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==} - engines: {node: '>=0.8.0'} - mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nan@2.20.0: - resolution: {integrity: sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==} - - nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - nanoid@5.0.7: - resolution: {integrity: sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==} + nanoid@5.0.9: + resolution: {integrity: sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==} engines: {node: ^18 || >=20} hasBin: true @@ -12767,10 +12317,6 @@ packages: natural-orderby@2.0.3: resolution: {integrity: sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q==} - ncp@2.0.0: - resolution: {integrity: sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==} - hasBin: true - negotiator@0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} @@ -12778,8 +12324,8 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - next@14.2.10: - resolution: {integrity: sha512-sDDExXnh33cY3RkS9JuFEKaS4HmlWmDKP1VJioucCG6z5KuA008DPsDZOzi8UfqEk3Ii+2NCQSJrfbEWtZZfww==} + next@14.2.15: + resolution: {integrity: sha512-h9ctmOokpoDphRvMGnwOJAedT6zKhwqyZML9mDtspgf4Rh3Pn7UTYKqePNoDvhsWBAO5GoPNYshnAUGIazVGmw==} engines: {node: '>=18.17.0'} hasBin: true peerDependencies: @@ -12809,10 +12355,6 @@ packages: resolution: {integrity: sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==} engines: {node: '>= 0.10.5'} - node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} - node-emoji@1.11.0: resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} @@ -12832,10 +12374,6 @@ packages: encoding: optional: true - node-fetch@3.3.1: - resolution: {integrity: sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - node-forge@1.3.1: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} @@ -12900,9 +12438,6 @@ packages: engines: {node: ^14.16.0 || >=16.10.0} hasBin: true - oauth-sign@0.9.0: - resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} - object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -12995,6 +12530,10 @@ packages: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} + open@9.1.0: + resolution: {integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==} + engines: {node: '>=14.16'} + opener@1.5.2: resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} hasBin: true @@ -13096,6 +12635,10 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-json@10.0.1: + resolution: {integrity: sha512-ua1L4OgXSBdsu1FPb7F3tYH0F48a6kxvod4pLUlGY9COeJAJQNX/sNH2IiEmsxw7lqYiAwrdHMjz1FctOsyDQg==} + engines: {node: '>=18'} + package-json@8.1.1: resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} engines: {node: '>=14.16'} @@ -13139,9 +12682,9 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} - parse-json@6.0.2: - resolution: {integrity: sha512-SA5aMiaIjXkAiBrW/yPgLgQAQg42f7K3ACO+2l/zOvtQBwX58DMUsFJXelW2fx3yMBmWOVkR6j1MGsdSbCA4UA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + parse-json@7.1.1: + resolution: {integrity: sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==} + engines: {node: '>=16'} parse-numeric-range@1.3.0: resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==} @@ -13216,8 +12759,8 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-to-regexp@0.1.10: - resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} + path-to-regexp@0.1.12: + resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} path-to-regexp@1.9.0: resolution: {integrity: sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==} @@ -13248,9 +12791,6 @@ packages: pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - performance-now@2.1.0: - resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} - periscopic@3.1.0: resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} @@ -13291,10 +12831,17 @@ packages: pino-std-serializers@6.2.2: resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==} + pino-std-serializers@7.0.0: + resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} + pino@8.20.0: resolution: {integrity: sha512-uhIfMj5TVp+WynVASaVEJFTncTUe4dHBq6CWplu/vBgvGHhvBvQfxz+vcOrnnBQdORH3izaGEurLfNlq3YxdFQ==} hasBin: true + pino@9.4.0: + resolution: {integrity: sha512-nbkQb5+9YPhQRz/BeQmrWpEknAaqjpAqRK8NwJpmrX/JHu7JuZC5G1CeAwJDJfGes4h+YihC6in3Q2nGb+Y09w==} + hasBin: true + pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} @@ -13321,6 +12868,9 @@ packages: pkg-types@1.2.0: resolution: {integrity: sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==} + pkg-types@1.2.1: + resolution: {integrity: sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==} + pkg-up@3.1.0: resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} engines: {node: '>=8'} @@ -13926,6 +13476,9 @@ packages: process-warning@3.0.0: resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} + process-warning@4.0.0: + resolution: {integrity: sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw==} + process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} @@ -14026,10 +13579,6 @@ packages: resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} engines: {node: '>=0.6'} - qs@6.5.3: - resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} - engines: {node: '>=0.6'} - querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} @@ -14221,16 +13770,6 @@ packages: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} - react-remove-scroll-bar@2.3.4: - resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - react-remove-scroll-bar@2.3.6: resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} engines: {node: '>=10'} @@ -14452,9 +13991,6 @@ packages: regenerate@1.4.2: resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} - regenerator-runtime@0.13.11: - resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} - regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} @@ -14571,11 +14107,6 @@ packages: resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} engines: {node: '>=0.10'} - request@2.88.2: - resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} - engines: {node: '>= 6'} - deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 - require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -14655,11 +14186,6 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - rimraf@2.4.5: - resolution: {integrity: sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - rimraf@2.6.3: resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} deprecated: Rimraf versions prior to v4 are no longer supported @@ -14703,6 +14229,10 @@ packages: engines: {node: '>=12.0.0'} hasBin: true + run-applescript@5.0.0: + resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==} + engines: {node: '>=12'} + run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -14734,9 +14264,6 @@ packages: safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safe-json-stringify@1.2.0: - resolution: {integrity: sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==} - safe-regex-test@1.0.3: resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} engines: {node: '>= 0.4'} @@ -14820,11 +14347,6 @@ packages: engines: {node: '>=10'} hasBin: true - semver@7.6.2: - resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} - engines: {node: '>=10'} - hasBin: true - semver@7.6.3: resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} @@ -14874,10 +14396,6 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - sha.js@2.4.11: - resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} - hasBin: true - shallow-clone@3.0.1: resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} engines: {node: '>=8'} @@ -14917,10 +14435,6 @@ packages: siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - sign-addon@5.3.0: - resolution: {integrity: sha512-7nHlCzhQgVMLBNiXVEgbG/raq48awOW0lYMN5uo1BaB3mp0+k8M8pvDwbfTlr3apcxZJsk9HQsAW1POwoJugpQ==} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -14985,6 +14499,9 @@ packages: sonic-boom@3.8.1: resolution: {integrity: sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==} + sonic-boom@4.2.0: + resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} + sort-css-media-queries@2.2.0: resolution: {integrity: sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==} engines: {node: '>= 6.3.0'} @@ -15069,11 +14586,6 @@ packages: resolution: {integrity: sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==} engines: {node: '>=12'} - sshpk@1.18.0: - resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} - engines: {node: '>=0.10.0'} - hasBin: true - stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} @@ -15124,13 +14636,6 @@ packages: stream-shift@1.0.3: resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} - stream-to-array@2.3.0: - resolution: {integrity: sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==} - - stream-to-promise@3.0.0: - resolution: {integrity: sha512-h+7wLeFiYegOdgTfTxjRsrT7/Op7grnKEIHWgaO1RTHwcwk7xRreMr3S8XpDfDMesSxzgM2V4CxNCFAGo6ssnA==} - engines: {node: '>= 10'} - streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} @@ -15255,10 +14760,13 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strip-json-comments@5.0.0: - resolution: {integrity: sha512-V1LGY4UUo0jgwC+ELQ2BNWfPa17TIuwBLg+j1AA/9RPzKINl1lhxVEu2r+ZTTO8aetIsUzE5Qj6LMSBkoGYKKw==} + strip-json-comments@5.0.1: + resolution: {integrity: sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==} engines: {node: '>=14.16'} + stubborn-fs@1.2.5: + resolution: {integrity: sha512-H2N9c26eXjzL/S/K+i/RHHcFanE74dptvvjM8iwzwbVcWY/zjBbgRqF3K0DY4+OD+uTTASTBvDoxPDaPN02D7g==} + style-to-js@1.1.16: resolution: {integrity: sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==} @@ -15450,6 +14958,9 @@ packages: thread-stream@2.7.0: resolution: {integrity: sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==} + thread-stream@3.1.0: + resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + throttle-debounce@5.0.2: resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==} engines: {node: '>=12.22'} @@ -15500,14 +15011,14 @@ packages: title-case@3.0.3: resolution: {integrity: sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==} + titleize@3.0.0: + resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==} + engines: {node: '>=12'} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} - tmp@0.2.1: - resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} - engines: {node: '>=8.17.0'} - tmp@0.2.3: resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} engines: {node: '>=14.14'} @@ -15539,18 +15050,10 @@ packages: toposort@2.0.2: resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} - tosource@1.0.0: - resolution: {integrity: sha512-N6g8eQ1eerw6Y1pBhdgkubWIiPFwXa2POSUrlL8jth5CyyEWNWzoGKRkO3CaO7Jx27hlJP54muB3btIAbx4MPg==} - engines: {node: '>=0.4.0'} - totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} - tough-cookie@2.5.0: - resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} - engines: {node: '>=0.8'} - tough-cookie@4.1.4: resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} engines: {node: '>=6'} @@ -15720,9 +15223,6 @@ packages: tween-functions@1.2.0: resolution: {integrity: sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA==} - tweetnacl@0.14.5: - resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} - tweetnacl@1.0.3: resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} @@ -15734,10 +15234,6 @@ packages: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} - type-detect@4.1.0: - resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} - engines: {node: '>=4'} - type-fest@0.16.0: resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==} engines: {node: '>=10'} @@ -15766,6 +15262,10 @@ packages: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} + type-fest@3.13.1: + resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} + engines: {node: '>=14.16'} + type-fest@4.26.1: resolution: {integrity: sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==} engines: {node: '>=16'} @@ -15848,35 +15348,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - typesense-docsearch-css@0.4.1: - resolution: {integrity: sha512-mN8K18pfIpCrhzsMAJBzoS7l/YDcC4P3f9vsScenUceXmC8n3FCPldmF10dKDJmK3Lr7aAScQt70jCA5126y2w==} - - typesense-docsearch-react@3.4.1: - resolution: {integrity: sha512-d0PQym/B/p5oP+hfdFEOH6goiKa1JLR63bikZSDGq1+jT2FtuwNrdMGVBZZMNFUsXVsJRA8ULHJpsREmfSJmVw==} - peerDependencies: - '@types/react': '>= 16.8.0 < 19.0.0' - react: '>= 16.8.0 < 19.0.0' - react-dom: '>= 16.8.0 < 19.0.0' - peerDependenciesMeta: - '@types/react': - optional: true - react: - optional: true - react-dom: - optional: true - - typesense-instantsearch-adapter@2.8.0: - resolution: {integrity: sha512-2q4QVpHoUV0ncf1XOqIC0dufOTkFRxQ0mHzg//H3WK02ZYqdNNPCAacZODhQlltl1cNJdTI8Y4uuGVd6fJuGzw==} - engines: {node: '>=16'} - peerDependencies: - '@babel/runtime': ^7.17.2 - - typesense@1.8.2: - resolution: {integrity: sha512-aBpePjA99Qvo+OP2pJwMpvga4Jrm1Y2oV5NsrWXBxlqUDNEUCPZBIksPv2Hq0jxQxHhLLyJVbjXjByXsvpCDVA==} - engines: {node: '>=18'} - peerDependencies: - '@babel/runtime': ^7.23.2 - ua-parser-js@1.0.39: resolution: {integrity: sha512-k24RCVWlEcjkdOxYmVJgeD/0a1TiSpqLg+ZalVGV9lsnr4yqu0w7tX/x2xX6G4zpkgQnRf89lxuZ1wsbjXM8lw==} hasBin: true @@ -15996,10 +15467,6 @@ packages: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} engines: {node: '>= 4.0.0'} - universalify@1.0.0: - resolution: {integrity: sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==} - engines: {node: '>= 10.0.0'} - universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} @@ -16039,6 +15506,10 @@ packages: resolution: {integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==} engines: {node: '>=14.16'} + update-notifier@7.3.1: + resolution: {integrity: sha512-+dwUY4L35XFYEzE+OAL3sarJdUioVovq+8f7lcIJ7wnmnYQV5UD1Y/lcwaMSyaQ6Bj3JMj1XSTjZbNLHn/19yA==} + engines: {node: '>=18'} + upper-case-first@2.0.2: resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} @@ -16147,11 +15618,6 @@ packages: resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} hasBin: true - uuid@3.4.0: - resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} - deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. - hasBin: true - uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true @@ -16181,10 +15647,6 @@ packages: validate-npm-package-name@3.0.0: resolution: {integrity: sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==} - validator@13.12.0: - resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==} - engines: {node: '>= 0.10'} - value-equal@1.0.1: resolution: {integrity: sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==} @@ -16199,10 +15661,6 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - verror@1.10.0: - resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} - engines: {'0': node >=0.6.0} - vfile-location@5.0.3: resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} @@ -16228,8 +15686,8 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} hasBin: true - vite-plugin-dts@3.9.1: - resolution: {integrity: sha512-rVp2KM9Ue22NGWB8dNtWEr+KekN3rIgz1tWD050QnRGlriUCmaDwa7qA5zDEjbXg5lAXhYMSBJtx3q3hQIJZSg==} + vite-plugin-dts@4.3.0: + resolution: {integrity: sha512-LkBJh9IbLwL6/rxh0C1/bOurDrIEmRE7joC+jFdOEEciAFPbpEKOLSAr5nNh5R7CJ45cMbksTrFfy52szzC5eA==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -16307,19 +15765,13 @@ packages: jsdom: optional: true + vscode-uri@3.0.8: + resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} + vue-parser@1.1.6: resolution: {integrity: sha512-v3/R7PLbaFVF/c8IIzWs1HgRpT2gN0dLRkaLIT5q+zJGVgmhN4VuZJF4Y9N4hFtFjS4B1EHxAOP6/tzqM4Ug2g==} engines: {node: '>= 4.0.0', npm: '>= 3.0.0'} - vue-template-compiler@2.7.16: - resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==} - - vue-tsc@1.8.27: - resolution: {integrity: sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==} - hasBin: true - peerDependencies: - typescript: '*' - w3c-xmlserializer@5.0.0: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} @@ -16341,10 +15793,6 @@ packages: resolution: {integrity: sha512-AmboGZEnZoIcVCzSlkLEmNFEqJN+IwgshJ5S7pi30uNUTce4LvWkifQzsQRxnWj47G8gkqZxlyGlyQplsnIS7w==} hasBin: true - watchpack@2.4.0: - resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} - engines: {node: '>=10.13.0'} - watchpack@2.4.2: resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} engines: {node: '>=10.13.0'} @@ -16355,9 +15803,9 @@ packages: wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - web-ext@7.12.0: - resolution: {integrity: sha512-h+uWOYBlHlPKy5CqxuZKocgOdL8J7I4ctMw/rAGbQl7jq7tr+NmY/Lhh2FPMSlJ1Y0T2VeUqwBVighK0MM1+zA==} - engines: {node: '>=14.0.0', npm: '>=6.9.0'} + web-ext@8.3.0: + resolution: {integrity: sha512-mXSOiDtmm3n0KNpSuQ65fJpypAoNLAmZv3QkdlVbJ6etn0BK+hl/k+tjHefSIKdbzGUIeFbhn2oxWMe9Tdyrdg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true web-namespaces@2.0.1: @@ -16575,6 +16023,9 @@ packages: whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + when-exit@2.1.3: + resolution: {integrity: sha512-uVieSTccFIr/SFQdFWN/fFaQYmV37OKtuaGphMAzi4DmmUlrvRBJW5WSLkHyjNQY/ePJMz3LoiX9R3yy1Su6Hw==} + when@3.7.7: resolution: {integrity: sha512-9lFZp/KHoqH6bPKjbWqa+3Dg/K/r2v0X/3/G2x4DBGchVS2QX2VXL3cZV994WQVnTM1/PD71Az25nAzryEUugw==} @@ -16622,6 +16073,10 @@ packages: resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} engines: {node: '>=12'} + widest-line@5.0.0: + resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} + engines: {node: '>=18'} + wildcard@2.0.1: resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} @@ -16688,8 +16143,8 @@ packages: resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} engines: {node: '>=18'} - xml2js@0.5.0: - resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} + xml2js@0.6.2: + resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} engines: {node: '>=4.0.0'} xmlbuilder@11.0.1: @@ -16736,10 +16191,6 @@ packages: resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} engines: {node: '>=8'} - yargs@17.7.1: - resolution: {integrity: sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==} - engines: {node: '>=12'} - yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} @@ -16766,11 +16217,6 @@ packages: yup@1.4.0: resolution: {integrity: sha512-wPbgkJRCqIf+OHyiTBQoJiP5PFuAXaWiJK6AmYkzQAh5/c2K9hzSApBZG5wV9KoKSePF7sAxmNSvh/13YHkFDg==} - z-schema@5.0.5: - resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} - engines: {node: '>=8.0.0'} - hasBin: true - zip-dir@2.0.0: resolution: {integrity: sha512-uhlsJZWz26FLYXOD6WVuq+fIcZ3aBPGo/cFdiLlv3KNwpa52IF3ISV8fLhQLiqVu5No3VhlqlgthN6gehil1Dg==} @@ -16814,10 +16260,6 @@ snapshots: '@adraffy/ens-normalize@1.11.0': {} - '@algolia/autocomplete-core@1.8.2': - dependencies: - '@algolia/autocomplete-shared': 1.8.2 - '@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)': dependencies: '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) @@ -16834,20 +16276,12 @@ snapshots: - '@algolia/client-search' - algoliasearch - '@algolia/autocomplete-preset-algolia@1.8.2(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)': - dependencies: - '@algolia/autocomplete-shared': 1.8.2 - '@algolia/client-search': 4.24.0 - algoliasearch: 4.24.0 - '@algolia/autocomplete-preset-algolia@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)': dependencies: '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) '@algolia/client-search': 4.24.0 algoliasearch: 4.24.0 - '@algolia/autocomplete-shared@1.8.2': {} - '@algolia/autocomplete-shared@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)': dependencies: '@algolia/client-search': 4.24.0 @@ -18029,10 +17463,6 @@ snapshots: core-js-pure: 3.38.1 regenerator-runtime: 0.14.1 - '@babel/runtime@7.21.0': - dependencies: - regenerator-runtime: 0.13.11 - '@babel/runtime@7.25.6': dependencies: regenerator-runtime: 0.14.1 @@ -18489,7 +17919,7 @@ snapshots: '@devicefarmer/adbkit-monkey@1.2.1': {} - '@devicefarmer/adbkit@3.2.3': + '@devicefarmer/adbkit@3.2.6': dependencies: '@devicefarmer/adbkit-logcat': 2.1.3 '@devicefarmer/adbkit-monkey': 1.2.1 @@ -18518,98 +17948,7 @@ snapshots: transitivePeerDependencies: - '@algolia/client-search' - '@docusaurus/core@3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': - dependencies: - '@babel/core': 7.25.2 - '@babel/generator': 7.25.6 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-transform-runtime': 7.25.4(@babel/core@7.25.2) - '@babel/preset-env': 7.25.4(@babel/core@7.25.2) - '@babel/preset-react': 7.24.7(@babel/core@7.25.2) - '@babel/preset-typescript': 7.24.7(@babel/core@7.25.2) - '@babel/runtime': 7.25.6 - '@babel/runtime-corejs3': 7.25.6 - '@babel/traverse': 7.25.6 - '@docusaurus/cssnano-preset': 3.4.0 - '@docusaurus/logger': 3.4.0 - '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - autoprefixer: 10.4.20(postcss@8.4.47) - babel-loader: 9.2.1(@babel/core@7.25.2)(webpack@5.95.0) - babel-plugin-dynamic-import-node: 2.3.3 - boxen: 6.2.1 - chalk: 4.1.2 - chokidar: 3.6.0 - clean-css: 5.3.3 - cli-table3: 0.6.5 - combine-promises: 1.2.0 - commander: 5.1.0 - copy-webpack-plugin: 11.0.0(webpack@5.95.0) - core-js: 3.38.1 - css-loader: 6.11.0(webpack@5.95.0) - css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.95.0) - cssnano: 6.1.2(postcss@8.4.47) - del: 6.1.1 - detect-port: 1.6.1 - escape-html: 1.0.3 - eta: 2.2.0 - eval: 0.1.8 - file-loader: 6.2.0(webpack@5.95.0) - fs-extra: 11.2.0 - html-minifier-terser: 7.2.0 - html-tags: 3.3.1 - html-webpack-plugin: 5.6.0(webpack@5.95.0) - leven: 3.1.0 - lodash: 4.17.21 - mini-css-extract-plugin: 2.9.1(webpack@5.95.0) - p-map: 4.0.0 - postcss: 8.4.47 - postcss-loader: 7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0) - prompts: 2.4.2 - react: 18.3.1 - react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)(webpack@5.95.0) - react-dom: 18.3.1(react@18.3.1) - react-helmet-async: 1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' - react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.95.0) - react-router: 5.3.4(react@18.3.1) - react-router-config: 5.1.1(react-router@5.3.4(react@18.3.1))(react@18.3.1) - react-router-dom: 5.3.4(react@18.3.1) - rtl-detect: 1.1.2 - semver: 7.6.3 - serve-handler: 6.1.5 - shelljs: 0.8.5 - terser-webpack-plugin: 5.3.10(webpack@5.95.0) - tslib: 2.7.0 - update-notifier: 6.0.2 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) - webpack: 5.95.0 - webpack-bundle-analyzer: 4.10.2 - webpack-dev-server: 4.15.2(webpack@5.95.0) - webpack-merge: 5.10.0 - webpackbar: 5.0.2(webpack@5.95.0) - transitivePeerDependencies: - - '@docusaurus/types' - - '@parcel/css' - - '@rspack/core' - - '@swc/core' - - '@swc/css' - - bufferutil - - csso - - debug - - esbuild - - eslint - - lightningcss - - supports-color - - typescript - - uglify-js - - utf-8-validate - - vue-template-compiler - - webpack-cli - - '@docusaurus/core@3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/core@3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: '@babel/core': 7.25.2 '@babel/generator': 7.25.6 @@ -18661,7 +18000,7 @@ snapshots: postcss-loader: 7.3.4(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0) prompts: 2.4.2 react: 18.3.1 - react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)(webpack@5.95.0) + react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.6.2)(webpack@5.95.0) react-dom: 18.3.1(react@18.3.1) react-helmet-async: 1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' @@ -18701,13 +18040,6 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/cssnano-preset@3.4.0': - dependencies: - cssnano-preset-advanced: 6.1.2(postcss@8.4.47) - postcss: 8.4.47 - postcss-sort-media-queries: 5.2.0(postcss@8.4.47) - tslib: 2.7.0 - '@docusaurus/cssnano-preset@3.5.2': dependencies: cssnano-preset-advanced: 6.1.2(postcss@8.4.47) @@ -18715,53 +18047,11 @@ snapshots: postcss-sort-media-queries: 5.2.0(postcss@8.4.47) tslib: 2.7.0 - '@docusaurus/logger@3.4.0': - dependencies: - chalk: 4.1.2 - tslib: 2.7.0 - '@docusaurus/logger@3.5.2': dependencies: chalk: 4.1.2 tslib: 2.7.0 - '@docusaurus/mdx-loader@3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': - dependencies: - '@docusaurus/logger': 3.4.0 - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@mdx-js/mdx': 3.0.1 - '@slorber/remark-comment': 1.0.0 - escape-html: 1.0.3 - estree-util-value-to-estree: 3.1.2 - file-loader: 6.2.0(webpack@5.95.0) - fs-extra: 11.2.0 - image-size: 1.1.1 - mdast-util-mdx: 3.0.0 - mdast-util-to-string: 4.0.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - rehype-raw: 7.0.0 - remark-directive: 3.0.0 - remark-emoji: 4.0.1 - remark-frontmatter: 5.0.0 - remark-gfm: 4.0.0 - stringify-object: 3.3.0 - tslib: 2.7.0 - unified: 11.0.5 - unist-util-visit: 5.0.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) - vfile: 6.0.3 - webpack: 5.95.0 - transitivePeerDependencies: - - '@docusaurus/types' - - '@swc/core' - - esbuild - - supports-color - - typescript - - uglify-js - - webpack-cli - '@docusaurus/mdx-loader@3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: '@docusaurus/logger': 3.5.2 @@ -18799,24 +18089,6 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/module-type-aliases@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@types/history': 4.7.11 - '@types/react': 18.3.9 - '@types/react-router-config': 5.0.11 - '@types/react-router-dom': 5.3.3 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-helmet-async: 2.0.5(react@18.3.1) - react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' - transitivePeerDependencies: - - '@swc/core' - - esbuild - - supports-color - - uglify-js - - webpack-cli - '@docusaurus/module-type-aliases@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -18835,13 +18107,13 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/plugin-content-blog@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-content-blog@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/logger': 3.5.2 '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) @@ -18877,51 +18149,13 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-content-docs@3.4.0(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: - '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/logger': 3.4.0 - '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/module-type-aliases': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@types/react-router-config': 5.0.11 - combine-promises: 1.2.0 - fs-extra: 11.2.0 - js-yaml: 4.1.0 - lodash: 4.17.21 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - tslib: 2.7.0 - utility-types: 3.11.0 - webpack: 5.95.0 - transitivePeerDependencies: - - '@parcel/css' - - '@rspack/core' - - '@swc/core' - - '@swc/css' - - bufferutil - - csso - - debug - - esbuild - - eslint - - lightningcss - - supports-color - - typescript - - uglify-js - - utf-8-validate - - vue-template-compiler - - webpack-cli - - '@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': - dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/logger': 3.5.2 '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/module-type-aliases': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) @@ -18955,9 +18189,9 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-content-pages@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-content-pages@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) @@ -18986,9 +18220,9 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-debug@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-debug@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) fs-extra: 11.2.0 @@ -19015,9 +18249,9 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-google-analytics@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-google-analytics@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) react: 18.3.1 @@ -19042,9 +18276,9 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-google-gtag@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-google-gtag@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) '@types/gtag.js': 0.0.12 @@ -19070,9 +18304,9 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-google-tag-manager@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-google-tag-manager@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) react: 18.3.1 @@ -19097,9 +18331,9 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-sitemap@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-sitemap@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/logger': 3.5.2 '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) @@ -19129,20 +18363,20 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/preset-classic@3.5.2(@algolia/client-search@4.24.0)(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': - dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-blog': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-pages': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-debug': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-google-analytics': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-google-gtag': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-google-tag-manager': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-sitemap': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/theme-classic': 3.5.2(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/theme-search-algolia': 3.5.2(@algolia/client-search@4.24.0)(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/preset-classic@3.5.2(@algolia/client-search@4.24.0)(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': + dependencies: + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/plugin-content-blog': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/plugin-content-pages': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/plugin-debug': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/plugin-google-analytics': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/plugin-google-gtag': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/plugin-google-tag-manager': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/plugin-sitemap': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/theme-classic': 3.5.2(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/theme-search-algolia': 3.5.2(@algolia/client-search@4.24.0)(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -19183,15 +18417,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@docusaurus/theme-classic@3.5.2(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/theme-classic@3.5.2(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/module-type-aliases': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-blog': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-pages': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/plugin-content-blog': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/plugin-content-pages': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/theme-translations': 3.5.2 '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) @@ -19231,11 +18465,11 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/theme-common@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': + '@docusaurus/theme-common@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: '@docusaurus/mdx-loader': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/module-type-aliases': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) '@docusaurus/utils-common': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@types/history': 4.7.11 @@ -19257,10 +18491,10 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/theme-live-codeblock@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/theme-live-codeblock@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/theme-translations': 3.5.2 '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) '@philpl/buble': 0.19.7 @@ -19291,11 +18525,11 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/theme-mermaid@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/theme-mermaid@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/module-type-aliases': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) mermaid: 10.9.3 @@ -19322,13 +18556,13 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/theme-search-algolia@3.5.2(@algolia/client-search@4.24.0)(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)': + '@docusaurus/theme-search-algolia@3.5.2(@algolia/client-search@4.24.0)(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(@types/react@18.3.9)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)': dependencies: '@docsearch/react': 3.6.1(@algolia/client-search@4.24.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/logger': 3.5.2 - '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/plugin-content-docs': 3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) + '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) '@docusaurus/theme-translations': 3.5.2 '@docusaurus/utils': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) '@docusaurus/utils-validation': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) @@ -19365,11 +18599,6 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/theme-translations@3.4.0': - dependencies: - fs-extra: 11.2.0 - tslib: 2.7.0 - '@docusaurus/theme-translations@3.5.2': dependencies: fs-extra: 11.2.0 @@ -19377,26 +18606,6 @@ snapshots: '@docusaurus/tsconfig@3.5.2': {} - '@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@mdx-js/mdx': 3.0.1 - '@types/history': 4.7.11 - '@types/react': 18.3.9 - commander: 5.1.0 - joi: 17.13.3 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-helmet-async: 1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - utility-types: 3.11.0 - webpack: 5.95.0 - webpack-merge: 5.10.0 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - supports-color - - uglify-js - - webpack-cli - '@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@mdx-js/mdx': 3.0.1 @@ -19417,62 +18626,12 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils-common@3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': - dependencies: - tslib: 2.7.0 - optionalDependencies: - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - - '@docusaurus/utils-common@3.4.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': - dependencies: - tslib: 2.7.0 - optionalDependencies: - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-common@3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': dependencies: tslib: 2.7.0 optionalDependencies: '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation@3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2)': - dependencies: - '@docusaurus/logger': 3.4.0 - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - fs-extra: 11.2.0 - joi: 17.13.3 - js-yaml: 4.1.0 - lodash: 4.17.21 - tslib: 2.7.0 - transitivePeerDependencies: - - '@docusaurus/types' - - '@swc/core' - - esbuild - - supports-color - - typescript - - uglify-js - - webpack-cli - - '@docusaurus/utils-validation@3.4.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2)': - dependencies: - '@docusaurus/logger': 3.4.0 - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - fs-extra: 11.2.0 - joi: 17.13.3 - js-yaml: 4.1.0 - lodash: 4.17.21 - tslib: 2.7.0 - transitivePeerDependencies: - - '@docusaurus/types' - - '@swc/core' - - esbuild - - supports-color - - typescript - - uglify-js - - webpack-cli - '@docusaurus/utils-validation@3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2)': dependencies: '@docusaurus/logger': 3.5.2 @@ -19492,70 +18651,6 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils@3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2)': - dependencies: - '@docusaurus/logger': 3.4.0 - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@svgr/webpack': 8.1.0(typescript@5.6.2) - escape-string-regexp: 4.0.0 - file-loader: 6.2.0(webpack@5.95.0) - fs-extra: 11.2.0 - github-slugger: 1.5.0 - globby: 11.1.0 - gray-matter: 4.0.3 - jiti: 1.21.6 - js-yaml: 4.1.0 - lodash: 4.17.21 - micromatch: 4.0.8 - prompts: 2.4.2 - resolve-pathname: 3.0.0 - shelljs: 0.8.5 - tslib: 2.7.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) - utility-types: 3.11.0 - webpack: 5.95.0 - optionalDependencies: - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - transitivePeerDependencies: - - '@swc/core' - - esbuild - - supports-color - - typescript - - uglify-js - - webpack-cli - - '@docusaurus/utils@3.4.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2)': - dependencies: - '@docusaurus/logger': 3.4.0 - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@svgr/webpack': 8.1.0(typescript@5.6.2) - escape-string-regexp: 4.0.0 - file-loader: 6.2.0(webpack@5.95.0) - fs-extra: 11.2.0 - github-slugger: 1.5.0 - globby: 11.1.0 - gray-matter: 4.0.3 - jiti: 1.21.6 - js-yaml: 4.1.0 - lodash: 4.17.21 - micromatch: 4.0.8 - prompts: 2.4.2 - resolve-pathname: 3.0.0 - shelljs: 0.8.5 - tslib: 2.7.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) - utility-types: 3.11.0 - webpack: 5.95.0 - optionalDependencies: - '@docusaurus/types': 3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - transitivePeerDependencies: - - '@swc/core' - - esbuild - - supports-color - - typescript - - uglify-js - - webpack-cli - '@docusaurus/utils@3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2)': dependencies: '@docusaurus/logger': 3.5.2 @@ -20931,7 +20026,7 @@ snapshots: jju: 1.4.0 js-yaml: 4.1.0 - '@mdn/browser-compat-data@5.5.29': {} + '@mdn/browser-compat-data@5.6.0': {} '@mdx-js/mdx@3.0.1': dependencies: @@ -21000,23 +20095,23 @@ snapshots: '@metamask/safe-event-emitter@3.1.1': {} - '@microsoft/api-extractor-model@7.28.13(@types/node@20.16.9)': + '@microsoft/api-extractor-model@7.30.1(@types/node@20.16.9)': dependencies: - '@microsoft/tsdoc': 0.14.2 - '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 4.0.2(@types/node@20.16.9) + '@microsoft/tsdoc': 0.15.1 + '@microsoft/tsdoc-config': 0.17.1 + '@rushstack/node-core-library': 5.10.1(@types/node@20.16.9) transitivePeerDependencies: - '@types/node' - '@microsoft/api-extractor@7.43.0(@types/node@20.16.9)': + '@microsoft/api-extractor@7.48.1(@types/node@20.16.9)': dependencies: - '@microsoft/api-extractor-model': 7.28.13(@types/node@20.16.9) - '@microsoft/tsdoc': 0.14.2 - '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 4.0.2(@types/node@20.16.9) - '@rushstack/rig-package': 0.5.2 - '@rushstack/terminal': 0.10.0(@types/node@20.16.9) - '@rushstack/ts-command-line': 4.19.1(@types/node@20.16.9) + '@microsoft/api-extractor-model': 7.30.1(@types/node@20.16.9) + '@microsoft/tsdoc': 0.15.1 + '@microsoft/tsdoc-config': 0.17.1 + '@rushstack/node-core-library': 5.10.1(@types/node@20.16.9) + '@rushstack/rig-package': 0.5.3 + '@rushstack/terminal': 0.14.4(@types/node@20.16.9) + '@rushstack/ts-command-line': 4.23.2(@types/node@20.16.9) lodash: 4.17.21 minimatch: 3.0.8 resolve: 1.22.8 @@ -21033,8 +20128,17 @@ snapshots: jju: 1.4.0 resolve: 1.19.0 + '@microsoft/tsdoc-config@0.17.1': + dependencies: + '@microsoft/tsdoc': 0.15.1 + ajv: 8.12.0 + jju: 1.4.0 + resolve: 1.22.8 + '@microsoft/tsdoc@0.14.2': {} + '@microsoft/tsdoc@0.15.1': {} + '@mswjs/interceptors@0.35.8': dependencies: '@open-draft/deferred-promise': 2.2.0 @@ -21241,37 +20345,37 @@ snapshots: optionalDependencies: '@nestjs/platform-express': 10.4.4(@nestjs/common@10.4.4(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.4) - '@next/env@14.2.10': {} + '@next/env@14.2.15': {} '@next/eslint-plugin-next@14.2.3': dependencies: glob: 10.3.10 - '@next/swc-darwin-arm64@14.2.10': + '@next/swc-darwin-arm64@14.2.15': optional: true - '@next/swc-darwin-x64@14.2.10': + '@next/swc-darwin-x64@14.2.15': optional: true - '@next/swc-linux-arm64-gnu@14.2.10': + '@next/swc-linux-arm64-gnu@14.2.15': optional: true - '@next/swc-linux-arm64-musl@14.2.10': + '@next/swc-linux-arm64-musl@14.2.15': optional: true - '@next/swc-linux-x64-gnu@14.2.10': + '@next/swc-linux-x64-gnu@14.2.15': optional: true - '@next/swc-linux-x64-musl@14.2.10': + '@next/swc-linux-x64-musl@14.2.15': optional: true - '@next/swc-win32-arm64-msvc@14.2.10': + '@next/swc-win32-arm64-msvc@14.2.15': optional: true - '@next/swc-win32-ia32-msvc@14.2.10': + '@next/swc-win32-ia32-msvc@14.2.15': optional: true - '@next/swc-win32-x64-msvc@14.2.10': + '@next/swc-win32-x64-msvc@14.2.15': optional: true '@noble/curves@1.4.2': @@ -21588,14 +20692,10 @@ snapshots: '@popperjs/core@2.11.8': {} - '@radix-ui/colors@3.0.0': {} - '@radix-ui/number@1.0.1': dependencies: '@babel/runtime': 7.25.6 - '@radix-ui/number@1.1.0': {} - '@radix-ui/primitive@1.0.0': dependencies: '@babel/runtime': 7.25.6 @@ -21606,29 +20706,6 @@ snapshots: '@radix-ui/primitive@1.1.0': {} - '@radix-ui/react-accessible-icon@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.9 - '@types/react-dom': 18.3.0 - - '@radix-ui/react-alert-dialog@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-context': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-dialog': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.0(@types/react@18.3.9)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.9 - '@types/react-dom': 18.3.0 - '@radix-ui/react-arrow@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.25.6 @@ -21648,43 +20725,6 @@ snapshots: '@types/react': 18.3.9 '@types/react-dom': 18.3.0 - '@radix-ui/react-aspect-ratio@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.9 - '@types/react-dom': 18.3.0 - - '@radix-ui/react-avatar@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-context': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.9)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.9 - '@types/react-dom': 18.3.0 - - '@radix-ui/react-checkbox@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-context': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.9)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.9 - '@types/react-dom': 18.3.0 - '@radix-ui/react-checkbox@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.0 @@ -21760,20 +20800,6 @@ snapshots: optionalDependencies: '@types/react': 18.3.9 - '@radix-ui/react-context-menu@2.2.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-context': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-menu': 2.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.9)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.9 - '@types/react-dom': 18.3.0 - '@radix-ui/react-context@1.0.0(react@18.3.1)': dependencies: '@babel/runtime': 7.25.6 @@ -21952,41 +20978,6 @@ snapshots: '@types/react': 18.3.9 '@types/react-dom': 18.3.0 - '@radix-ui/react-form@0.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-context': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-label': 2.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.9 - '@types/react-dom': 18.3.0 - - '@radix-ui/react-hover-card@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-context': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.9)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.9 - '@types/react-dom': 18.3.0 - - '@radix-ui/react-icons@1.3.0(react@18.3.1)': - dependencies: - react: 18.3.1 - '@radix-ui/react-id@1.0.0(react@18.3.1)': dependencies: '@babel/runtime': 7.25.6 @@ -22196,34 +21187,6 @@ snapshots: '@types/react': 18.3.9 '@types/react-dom': 18.3.0 - '@radix-ui/react-progress@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-context': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.9 - '@types/react-dom': 18.3.0 - - '@radix-ui/react-radio-group@1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-context': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.9)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.9 - '@types/react-dom': 18.3.0 - '@radix-ui/react-roving-focus@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.0 @@ -22241,23 +21204,6 @@ snapshots: '@types/react': 18.3.9 '@types/react-dom': 18.3.0 - '@radix-ui/react-scroll-area@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/number': 1.1.0 - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-context': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.9)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.9 - '@types/react-dom': 18.3.0 - '@radix-ui/react-select@1.2.2(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.25.6 @@ -22288,35 +21234,6 @@ snapshots: '@types/react': 18.3.9 '@types/react-dom': 18.3.0 - '@radix-ui/react-select@2.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/number': 1.1.0 - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-context': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - aria-hidden: 1.2.4 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.5.7(@types/react@18.3.9)(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.9 - '@types/react-dom': 18.3.0 - '@radix-ui/react-separator@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -22326,25 +21243,6 @@ snapshots: '@types/react': 18.3.9 '@types/react-dom': 18.3.0 - '@radix-ui/react-slider@1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/number': 1.1.0 - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-context': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.9)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.9 - '@types/react-dom': 18.3.0 - '@radix-ui/react-slot@1.0.0(react@18.3.1)': dependencies: '@babel/runtime': 7.25.6 @@ -22438,26 +21336,6 @@ snapshots: '@types/react': 18.3.9 '@types/react-dom': 18.3.0 - '@radix-ui/react-tooltip@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-context': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.9 - '@types/react-dom': 18.3.0 - '@radix-ui/react-use-callback-ref@1.0.0(react@18.3.1)': dependencies: '@babel/runtime': 7.25.6 @@ -22604,49 +21482,6 @@ snapshots: '@radix-ui/rect@1.1.0': {} - '@radix-ui/themes@3.1.4(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/colors': 3.0.0 - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-accessible-icon': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-alert-dialog': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-aspect-ratio': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-avatar': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-checkbox': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-context': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-context-menu': 2.2.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-dialog': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-dropdown-menu': 2.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-form': 0.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-hover-card': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-navigation-menu': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-popover': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-progress': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-radio-group': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-scroll-area': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-select': 2.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slider': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-switch': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-tabs': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toggle-group': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-tooltip': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.9)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - classnames: 2.3.2 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-remove-scroll-bar: 2.3.4(@types/react@18.3.9)(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.9 - '@types/react-dom': 18.3.0 - '@reduxjs/toolkit@1.9.7(react-redux@8.1.3(@types/react-dom@18.3.0)(@types/react@18.3.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1))(react@18.3.1)': dependencies: immer: 9.0.21 @@ -22721,32 +21556,34 @@ snapshots: '@rushstack/eslint-patch@1.10.4': {} - '@rushstack/node-core-library@4.0.2(@types/node@20.16.9)': + '@rushstack/node-core-library@5.10.1(@types/node@20.16.9)': dependencies: + ajv: 8.13.0 + ajv-draft-04: 1.0.0(ajv@8.13.0) + ajv-formats: 3.0.1 fs-extra: 7.0.1 import-lazy: 4.0.0 jju: 1.4.0 resolve: 1.22.8 semver: 7.5.4 - z-schema: 5.0.5 optionalDependencies: '@types/node': 20.16.9 - '@rushstack/rig-package@0.5.2': + '@rushstack/rig-package@0.5.3': dependencies: resolve: 1.22.8 strip-json-comments: 3.1.1 - '@rushstack/terminal@0.10.0(@types/node@20.16.9)': + '@rushstack/terminal@0.14.4(@types/node@20.16.9)': dependencies: - '@rushstack/node-core-library': 4.0.2(@types/node@20.16.9) + '@rushstack/node-core-library': 5.10.1(@types/node@20.16.9) supports-color: 8.1.1 optionalDependencies: '@types/node': 20.16.9 - '@rushstack/ts-command-line@4.19.1(@types/node@20.16.9)': + '@rushstack/ts-command-line@4.23.2(@types/node@20.16.9)': dependencies: - '@rushstack/terminal': 0.10.0(@types/node@20.16.9) + '@rushstack/terminal': 0.14.4(@types/node@20.16.9) '@types/argparse': 1.0.38 argparse: 1.0.10 string-argv: 0.3.2 @@ -22779,35 +21616,35 @@ snapshots: '@noble/hashes': 1.5.0 '@scure/base': 1.1.9 - '@sentry-internal/feedback@7.119.0': + '@sentry-internal/feedback@7.120.2': dependencies: - '@sentry/core': 7.119.0 - '@sentry/types': 7.119.0 - '@sentry/utils': 7.119.0 + '@sentry/core': 7.120.2 + '@sentry/types': 7.120.2 + '@sentry/utils': 7.120.2 - '@sentry-internal/replay-canvas@7.119.0': + '@sentry-internal/replay-canvas@7.120.2': dependencies: - '@sentry/core': 7.119.0 - '@sentry/replay': 7.119.0 - '@sentry/types': 7.119.0 - '@sentry/utils': 7.119.0 + '@sentry/core': 7.120.2 + '@sentry/replay': 7.120.2 + '@sentry/types': 7.120.2 + '@sentry/utils': 7.120.2 - '@sentry-internal/tracing@7.119.0': + '@sentry-internal/tracing@7.120.2': dependencies: - '@sentry/core': 7.119.0 - '@sentry/types': 7.119.0 - '@sentry/utils': 7.119.0 + '@sentry/core': 7.120.2 + '@sentry/types': 7.120.2 + '@sentry/utils': 7.120.2 - '@sentry/browser@7.119.0': + '@sentry/browser@7.120.2': dependencies: - '@sentry-internal/feedback': 7.119.0 - '@sentry-internal/replay-canvas': 7.119.0 - '@sentry-internal/tracing': 7.119.0 - '@sentry/core': 7.119.0 - '@sentry/integrations': 7.119.0 - '@sentry/replay': 7.119.0 - '@sentry/types': 7.119.0 - '@sentry/utils': 7.119.0 + '@sentry-internal/feedback': 7.120.2 + '@sentry-internal/replay-canvas': 7.120.2 + '@sentry-internal/tracing': 7.120.2 + '@sentry/core': 7.120.2 + '@sentry/integrations': 7.120.2 + '@sentry/replay': 7.120.2 + '@sentry/types': 7.120.2 + '@sentry/utils': 7.120.2 '@sentry/cli@1.77.3': dependencies: @@ -22834,17 +21671,22 @@ snapshots: '@sentry/types': 7.119.0 '@sentry/utils': 7.119.0 + '@sentry/core@7.120.2': + dependencies: + '@sentry/types': 7.120.2 + '@sentry/utils': 7.120.2 + '@sentry/hub@6.19.7': dependencies: '@sentry/types': 6.19.7 '@sentry/utils': 6.19.7 tslib: 1.14.1 - '@sentry/integrations@7.119.0': + '@sentry/integrations@7.120.2': dependencies: - '@sentry/core': 7.119.0 - '@sentry/types': 7.119.0 - '@sentry/utils': 7.119.0 + '@sentry/core': 7.120.2 + '@sentry/types': 7.120.2 + '@sentry/utils': 7.120.2 localforage: 1.10.0 '@sentry/minimal@6.19.7': @@ -22868,24 +21710,26 @@ snapshots: '@sentry/react@7.119.0(react@18.3.1)': dependencies: - '@sentry/browser': 7.119.0 + '@sentry/browser': 7.120.2 '@sentry/core': 7.119.0 '@sentry/types': 7.119.0 '@sentry/utils': 7.119.0 hoist-non-react-statics: 3.3.2 react: 18.3.1 - '@sentry/replay@7.119.0': + '@sentry/replay@7.120.2': dependencies: - '@sentry-internal/tracing': 7.119.0 - '@sentry/core': 7.119.0 - '@sentry/types': 7.119.0 - '@sentry/utils': 7.119.0 + '@sentry-internal/tracing': 7.120.2 + '@sentry/core': 7.120.2 + '@sentry/types': 7.120.2 + '@sentry/utils': 7.120.2 '@sentry/types@6.19.7': {} '@sentry/types@7.119.0': {} + '@sentry/types@7.120.2': {} + '@sentry/utils@6.19.7': dependencies: '@sentry/types': 6.19.7 @@ -22895,6 +21739,10 @@ snapshots: dependencies: '@sentry/types': 7.119.0 + '@sentry/utils@7.120.2': + dependencies: + '@sentry/types': 7.120.2 + '@sentry/webpack-plugin@1.21.0': dependencies: '@sentry/cli': 1.77.3 @@ -22957,7 +21805,7 @@ snapshots: '@size-limit/esbuild@11.1.5(size-limit@11.1.5)': dependencies: esbuild: 0.23.1 - nanoid: 5.0.7 + nanoid: 5.0.9 size-limit: 11.1.5 '@size-limit/file@11.1.5(size-limit@11.1.5)': @@ -24882,13 +23730,6 @@ snapshots: transitivePeerDependencies: - '@swc/helpers' - '@vitejs/plugin-react-swc@3.7.0(@swc/helpers@0.5.5)(vite@5.4.8(@types/node@22.7.3)(sass@1.79.3)(terser@5.34.0))': - dependencies: - '@swc/core': 1.7.28(@swc/helpers@0.5.5) - vite: 5.4.8(@types/node@22.7.3)(sass@1.79.3)(terser@5.34.0) - transitivePeerDependencies: - - '@swc/helpers' - '@vitejs/plugin-react@3.1.0(vite@5.4.8(@types/node@20.16.9)(sass@1.79.3)(terser@5.34.0))': dependencies: '@babel/core': 7.25.2 @@ -25011,18 +23852,17 @@ snapshots: loupe: 3.1.1 tinyrainbow: 1.2.0 - '@volar/language-core@1.11.1': + '@volar/language-core@2.4.11': dependencies: - '@volar/source-map': 1.11.1 + '@volar/source-map': 2.4.11 - '@volar/source-map@1.11.1': - dependencies: - muggle-string: 0.3.1 + '@volar/source-map@2.4.11': {} - '@volar/typescript@1.11.1': + '@volar/typescript@2.4.11': dependencies: - '@volar/language-core': 1.11.1 + '@volar/language-core': 2.4.11 path-browserify: 1.0.1 + vscode-uri: 3.0.8 '@vue/compiler-core@3.5.9': dependencies: @@ -25037,17 +23877,21 @@ snapshots: '@vue/compiler-core': 3.5.9 '@vue/shared': 3.5.9 - '@vue/language-core@1.8.27(typescript@5.6.2)': + '@vue/compiler-vue2@2.7.16': dependencies: - '@volar/language-core': 1.11.1 - '@volar/source-map': 1.11.1 + de-indent: 1.0.2 + he: 1.2.0 + + '@vue/language-core@2.1.6(typescript@5.6.2)': + dependencies: + '@volar/language-core': 2.4.11 '@vue/compiler-dom': 3.5.9 + '@vue/compiler-vue2': 2.7.16 '@vue/shared': 3.5.9 computeds: 0.0.1 minimatch: 9.0.5 - muggle-string: 0.3.1 + muggle-string: 0.4.1 path-browserify: 1.0.1 - vue-template-compiler: 2.7.16 optionalDependencies: typescript: 5.6.2 @@ -25265,13 +24109,15 @@ snapshots: acorn@8.12.1: {} - addons-linter@6.28.0(body-parser@1.20.3)(node-fetch@3.3.1): + acorn@8.14.0: {} + + addons-linter@7.1.0(body-parser@1.20.3): dependencies: '@fluent/syntax': 0.19.0 - '@mdn/browser-compat-data': 5.5.29 + '@mdn/browser-compat-data': 5.6.0 addons-moz-compare: 1.3.0 - addons-scanner-utils: 9.10.1(body-parser@1.20.3)(node-fetch@3.3.1) - ajv: 8.13.0 + addons-scanner-utils: 9.11.0(body-parser@1.20.3) + ajv: 8.17.1 chalk: 4.1.2 cheerio: 1.0.0-rc.12 columnify: 1.6.0 @@ -25280,21 +24126,17 @@ snapshots: eslint: 8.57.1 eslint-plugin-no-unsanitized: 4.0.2(eslint@8.57.1) eslint-visitor-keys: 4.0.0 - espree: 10.0.1 + espree: 10.1.0 esprima: 4.0.1 fast-json-patch: 3.1.1 - glob: 10.4.1 image-size: 1.1.1 - is-mergeable-object: 1.1.1 jed: 1.1.1 json-merge-patch: 1.0.2 os-locale: 5.0.0 pino: 8.20.0 relaxed-json: 1.0.3 - semver: 7.6.2 - sha.js: 2.4.11 + semver: 7.6.3 source-map-support: 0.5.21 - tosource: 1.0.0 upath: 2.0.1 yargs: 17.7.2 yauzl: 2.10.0 @@ -25307,7 +24149,7 @@ snapshots: addons-moz-compare@1.3.0: {} - addons-scanner-utils@9.10.1(body-parser@1.20.3)(node-fetch@3.3.1): + addons-scanner-utils@9.11.0(body-parser@1.20.3): dependencies: '@types/yauzl': 2.10.3 common-tags: 1.8.2 @@ -25317,7 +24159,6 @@ snapshots: yauzl: 2.10.0 optionalDependencies: body-parser: 1.20.3 - node-fetch: 3.3.1 address@1.2.2: {} @@ -25342,10 +24183,18 @@ snapshots: clean-stack: 2.2.0 indent-string: 4.0.0 + ajv-draft-04@1.0.0(ajv@8.13.0): + optionalDependencies: + ajv: 8.13.0 + ajv-formats@2.1.1: dependencies: ajv: 8.17.1 + ajv-formats@3.0.1: + dependencies: + ajv: 8.17.1 + ajv-keywords@3.5.2(ajv@6.12.6): dependencies: ajv: 6.12.6 @@ -25556,18 +24405,12 @@ snapshots: asap@2.0.6: {} - asn1@0.2.6: - dependencies: - safer-buffer: 2.1.2 - asn1js@3.0.5: dependencies: pvtsutils: 1.3.5 pvutils: 1.1.3 tslib: 2.7.0 - assert-plus@1.0.0: {} - assert@2.1.0: dependencies: call-bind: 1.0.7 @@ -25596,6 +24439,11 @@ snapshots: atomic-sleep@1.0.0: {} + atomically@2.0.3: + dependencies: + stubborn-fs: 1.2.5 + when-exit: 2.1.3 + auto-bind@4.0.0: {} autoprefixer@10.4.20(postcss@8.4.47): @@ -25612,15 +24460,13 @@ snapshots: dependencies: possible-typed-array-names: 1.0.0 - aws-sign2@0.7.0: {} - - aws4@1.13.2: {} - axe-core@4.10.0: {} - axios@0.26.1: + axios@0.28.0: dependencies: follow-redirects: 1.15.9(debug@4.3.7) + form-data: 4.0.0 + proxy-from-env: 1.1.0 transitivePeerDependencies: - debug @@ -25781,10 +24627,6 @@ snapshots: batch@0.6.1: {} - bcrypt-pbkdf@1.0.2: - dependencies: - tweetnacl: 0.14.5 - bech32@2.0.0: {} better-opn@3.0.2: @@ -25805,7 +24647,7 @@ snapshots: binary-install@1.1.0: dependencies: - axios: 0.26.1 + axios: 0.28.0 rimraf: 3.0.2 tar: 6.2.1 transitivePeerDependencies: @@ -25867,6 +24709,17 @@ snapshots: widest-line: 4.0.1 wrap-ansi: 8.1.0 + boxen@8.0.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 8.0.0 + chalk: 5.3.0 + cli-boxes: 3.0.0 + string-width: 7.2.0 + type-fest: 4.26.1 + widest-line: 5.0.0 + wrap-ansi: 9.0.0 + bplist-parser@0.2.0: dependencies: big-integer: 1.6.52 @@ -25911,8 +24764,6 @@ snapshots: buffer-crc32@0.2.13: {} - buffer-equal-constant-time@1.0.1: {} - buffer-from@1.1.2: {} buffer@5.7.1: @@ -25927,12 +24778,9 @@ snapshots: builtins@1.0.3: {} - bunyan@1.8.15: - optionalDependencies: - dtrace-provider: 0.8.8 - moment: 2.30.1 - mv: 2.1.1 - safe-json-stringify: 1.2.0 + bundle-name@3.0.0: + dependencies: + run-applescript: 5.0.0 busboy@1.6.0: dependencies: @@ -25992,6 +24840,8 @@ snapshots: camelcase@7.0.1: {} + camelcase@8.0.0: {} + caniuse-api@3.0.0: dependencies: browserslist: 4.24.0 @@ -26012,8 +24862,6 @@ snapshots: ansicolors: 0.3.2 redeyed: 2.1.1 - caseless@0.12.0: {} - ccount@2.0.1: {} chai@5.1.1: @@ -26133,12 +24981,12 @@ snapshots: chromatic@11.10.4: {} - chrome-launcher@0.15.1: + chrome-launcher@1.1.2: dependencies: '@types/node': 20.16.9 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 - lighthouse-logger: 1.4.2 + lighthouse-logger: 2.0.1 transitivePeerDependencies: - supports-color @@ -26156,8 +25004,6 @@ snapshots: dependencies: clsx: 2.0.0 - classnames@2.3.2: {} - classnames@2.5.1: {} clean-css@5.3.3: @@ -26262,8 +25108,6 @@ snapshots: clone@1.0.4: {} - clsx@1.2.1: {} - clsx@2.0.0: {} clsx@2.1.1: {} @@ -26351,6 +25195,8 @@ snapshots: commondir@1.0.1: {} + compare-versions@6.1.1: {} + component-emitter@1.3.1: {} compressible@2.0.18: @@ -26407,6 +25253,8 @@ snapshots: confbox@0.1.7: {} + confbox@0.1.8: {} + config-chain@1.1.13: dependencies: ini: 1.3.8 @@ -26420,6 +25268,13 @@ snapshots: write-file-atomic: 3.0.3 xdg-basedir: 5.1.0 + configstore@7.0.0: + dependencies: + atomically: 2.0.3 + dot-prop: 9.0.0 + graceful-fs: 4.2.11 + xdg-basedir: 5.1.0 + connect-history-api-fallback@2.0.0: {} consola@2.15.3: {} @@ -26482,12 +25337,8 @@ snapshots: core-js-pure@3.38.1: {} - core-js@3.29.0: {} - core-js@3.38.1: {} - core-util-is@1.0.2: {} - core-util-is@1.0.3: {} cors@2.8.5: @@ -26948,14 +25799,8 @@ snapshots: damerau-levenshtein@1.0.8: {} - dashdash@1.14.1: - dependencies: - assert-plus: 1.0.0 - dashify@2.0.0: {} - data-uri-to-buffer@4.0.1: {} - data-urls@5.0.0: dependencies: whatwg-mimetype: 4.0.0 @@ -27056,10 +25901,6 @@ snapshots: deep-object-diff@1.1.9: {} - deepcopy@2.1.0: - dependencies: - type-detect: 4.1.0 - deepmerge@2.2.1: {} deepmerge@4.3.1: {} @@ -27069,6 +25910,13 @@ snapshots: bplist-parser: 0.2.0 untildify: 4.0.0 + default-browser@4.0.0: + dependencies: + bundle-name: 3.0.0 + default-browser-id: 3.0.0 + execa: 7.2.0 + titleize: 3.0.0 + default-gateway@6.0.3: dependencies: execa: 5.1.1 @@ -27087,6 +25935,8 @@ snapshots: define-lazy-prop@2.0.0: {} + define-lazy-prop@3.0.0: {} + define-properties@1.2.1: dependencies: define-data-property: 1.1.4 @@ -27197,49 +26047,6 @@ snapshots: dependencies: typedoc-plugin-markdown: 4.2.10(typedoc@0.26.11(typescript@5.6.2)) - docusaurus-theme-search-typesense@0.20.0-0(@algolia/client-search@4.24.0)(@babel/runtime@7.25.6)(@docusaurus/core@3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/theme-common@3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.9)(algoliasearch@4.24.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16): - dependencies: - '@docusaurus/core': 3.5.2(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/logger': 3.4.0 - '@docusaurus/plugin-content-docs': 3.4.0(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16) - '@docusaurus/theme-common': 3.5.2(@docusaurus/plugin-content-docs@3.5.2(@mdx-js/react@3.0.1(@types/react@18.3.9)(react@18.3.1))(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(vue-template-compiler@2.7.16))(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.2) - '@docusaurus/theme-translations': 3.4.0 - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.2) - algoliasearch-helper: 3.22.5(algoliasearch@4.24.0) - clsx: 1.2.1 - eta: 2.2.0 - fs-extra: 10.1.0 - lodash: 4.17.21 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - tslib: 2.7.0 - typesense-docsearch-react: 3.4.1(@algolia/client-search@4.24.0)(@babel/runtime@7.25.6)(@types/react@18.3.9)(algoliasearch@4.24.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - typesense-instantsearch-adapter: 2.8.0(@babel/runtime@7.25.6) - utility-types: 3.11.0 - transitivePeerDependencies: - - '@algolia/client-search' - - '@babel/runtime' - - '@docusaurus/types' - - '@parcel/css' - - '@rspack/core' - - '@swc/core' - - '@swc/css' - - '@types/react' - - algoliasearch - - bufferutil - - csso - - debug - - esbuild - - eslint - - lightningcss - - supports-color - - typescript - - uglify-js - - utf-8-validate - - vue-template-compiler - - webpack-cli - dom-accessibility-api@0.5.16: {} dom-accessibility-api@0.6.3: {} @@ -27304,6 +26111,10 @@ snapshots: dependencies: is-obj: 2.0.0 + dot-prop@9.0.0: + dependencies: + type-fest: 4.26.1 + dotenv-expand@10.0.0: {} dotenv@16.4.5: {} @@ -27312,11 +26123,6 @@ snapshots: dset@3.1.4: {} - dtrace-provider@0.8.8: - dependencies: - nan: 2.20.0 - optional: true - duplexer@0.1.2: {} duplexify@3.7.1: @@ -27328,15 +26134,6 @@ snapshots: eastasianwidth@0.2.0: {} - ecc-jsbn@0.1.2: - dependencies: - jsbn: 0.1.1 - safer-buffer: 2.1.2 - - ecdsa-sig-formatter@1.0.11: - dependencies: - safe-buffer: 5.2.1 - ee-first@1.1.1: {} ejs@3.1.10: @@ -27503,8 +26300,6 @@ snapshots: es6-error@4.1.1: {} - es6-promisify@7.0.0: {} - esbuild-plugin-alias@0.2.1: {} esbuild-register@3.6.0(esbuild@0.18.20): @@ -27775,10 +26570,6 @@ snapshots: dependencies: eslint: 8.57.1 - eslint-plugin-react-refresh@0.4.12(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - eslint-plugin-react@7.37.0(eslint@8.57.1): dependencies: array-includes: 3.1.8 @@ -27888,7 +26679,7 @@ snapshots: transitivePeerDependencies: - supports-color - espree@10.0.1: + espree@10.1.0: dependencies: acorn: 8.12.1 acorn-jsx: 5.3.2(acorn@8.12.1) @@ -28012,6 +26803,18 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 + execa@7.2.0: + dependencies: + cross-spawn: 7.0.5 + get-stream: 6.0.1 + human-signals: 4.3.1 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 3.0.7 + strip-final-newline: 3.0.0 + execa@8.0.1: dependencies: cross-spawn: 7.0.5 @@ -28055,7 +26858,7 @@ snapshots: methods: 1.1.2 on-finished: 2.4.1 parseurl: 1.3.3 - path-to-regexp: 0.1.10 + path-to-regexp: 0.1.12 proxy-addr: 2.0.7 qs: 6.13.0 range-parser: 1.2.1 @@ -28103,8 +26906,6 @@ snapshots: transitivePeerDependencies: - supports-color - extsprintf@1.3.0: {} - fast-decode-uri-component@1.0.1: {} fast-deep-equal@2.0.1: {} @@ -28191,11 +26992,6 @@ snapshots: dependencies: xml-js: 1.6.11 - fetch-blob@3.2.0: - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 3.3.3 - fetch-retry@5.0.6: {} fflate@0.8.2: {} @@ -28283,13 +27079,13 @@ snapshots: locate-path: 7.2.0 path-exists: 5.0.0 - firefox-profile@4.3.2: + firefox-profile@4.7.0: dependencies: adm-zip: 0.5.16 - fs-extra: 9.0.1 - ini: 2.0.0 + fs-extra: 11.2.0 + ini: 4.1.3 minimist: 1.2.8 - xml2js: 0.5.0 + xml2js: 0.6.2 first-chunk-stream@3.0.0: {} @@ -28318,9 +27114,7 @@ snapshots: cross-spawn: 7.0.5 signal-exit: 4.1.0 - forever-agent@0.6.1: {} - - fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)(webpack@5.95.0): + fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@5.6.2)(webpack@5.95.0): dependencies: '@babel/code-frame': 7.24.7 '@types/json-schema': 7.0.15 @@ -28339,7 +27133,6 @@ snapshots: webpack: 5.95.0 optionalDependencies: eslint: 8.57.1 - vue-template-compiler: 2.7.16 fork-ts-checker-webpack-plugin@9.0.2(typescript@5.3.3)(webpack@5.94.0(@swc/core@1.7.28)): dependencies: @@ -28360,12 +27153,6 @@ snapshots: form-data-encoder@2.1.4: {} - form-data@2.3.3: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - form-data@3.0.1: dependencies: asynckit: 0.4.0 @@ -28380,10 +27167,6 @@ snapshots: format@0.2.2: {} - formdata-polyfill@4.0.10: - dependencies: - fetch-blob: 3.2.0 - formidable@2.1.2: dependencies: dezalgo: 1.0.4 @@ -28427,12 +27210,6 @@ snapshots: jsonfile: 6.1.0 universalify: 2.0.1 - fs-extra@11.1.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - fs-extra@11.1.1: dependencies: graceful-fs: 4.2.11 @@ -28457,13 +27234,6 @@ snapshots: jsonfile: 4.0.0 universalify: 0.1.2 - fs-extra@9.0.1: - dependencies: - at-least-node: 1.0.0 - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 1.0.0 - fs-extra@9.1.0: dependencies: at-least-node: 1.0.0 @@ -28549,10 +27319,6 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 - getpass@0.1.7: - dependencies: - assert-plus: 1.0.0 - giget@1.2.3: dependencies: citty: 0.1.6 @@ -28595,14 +27361,6 @@ snapshots: minipass: 7.1.2 path-scurry: 1.11.1 - glob@10.4.1: - dependencies: - foreground-child: 3.3.0 - jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 - path-scurry: 1.11.1 - glob@10.4.2: dependencies: foreground-child: 3.3.0 @@ -28621,15 +27379,6 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 - glob@6.0.4: - dependencies: - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - optional: true - glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -28647,6 +27396,10 @@ snapshots: minimatch: 5.1.6 once: 1.4.0 + global-directory@4.0.1: + dependencies: + ini: 4.1.1 + global-dirs@3.0.1: dependencies: ini: 2.0.0 @@ -28862,13 +27615,6 @@ snapshots: webidl-conversions: 7.0.0 whatwg-mimetype: 3.0.0 - har-schema@2.0.0: {} - - har-validator@5.1.5: - dependencies: - ajv: 6.12.6 - har-schema: 2.0.0 - has-bigints@1.0.2: {} has-flag@3.0.0: {} @@ -29239,12 +27985,6 @@ snapshots: transitivePeerDependencies: - debug - http-signature@1.2.0: - dependencies: - assert-plus: 1.0.0 - jsprim: 1.4.2 - sshpk: 1.18.0 - http2-wrapper@2.2.1: dependencies: quick-lru: 5.1.1 @@ -29277,6 +28017,8 @@ snapshots: human-signals@2.1.0: {} + human-signals@4.3.1: {} + human-signals@5.0.0: {} husky@9.1.6: {} @@ -29352,6 +28094,10 @@ snapshots: ini@2.0.0: {} + ini@4.1.1: {} + + ini@4.1.3: {} + inline-style-parser@0.1.1: {} inline-style-parser@0.2.4: {} @@ -29511,6 +28257,8 @@ snapshots: is-docker@2.2.1: {} + is-docker@3.0.0: {} + is-extendable@0.1.1: {} is-extglob@2.1.1: {} @@ -29543,11 +28291,22 @@ snapshots: is-hexadecimal@2.0.1: {} + is-in-ci@1.0.0: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + is-installed-globally@0.4.0: dependencies: global-dirs: 3.0.1 is-path-inside: 3.0.3 + is-installed-globally@1.0.0: + dependencies: + global-directory: 4.0.1 + is-path-inside: 4.0.0 + is-interactive@1.0.0: {} is-lower-case@2.0.2: @@ -29556,8 +28315,6 @@ snapshots: is-map@2.0.3: {} - is-mergeable-object@1.1.1: {} - is-nan@1.3.2: dependencies: call-bind: 1.0.7 @@ -29583,6 +28340,8 @@ snapshots: is-path-inside@3.0.3: {} + is-path-inside@4.0.0: {} + is-plain-obj@3.0.0: {} is-plain-obj@4.1.0: {} @@ -29691,8 +28450,6 @@ snapshots: dependencies: ws: 8.18.0 - isstream@0.1.2: {} - istanbul-lib-coverage@3.2.2: {} istanbul-lib-instrument@5.2.1: @@ -30103,7 +28860,7 @@ snapshots: '@sideway/formula': 3.0.1 '@sideway/pinpoint': 2.0.0 - jose@4.13.1: {} + jose@5.9.2: {} jose@5.9.3: {} @@ -30118,8 +28875,6 @@ snapshots: dependencies: argparse: 2.0.1 - jsbn@0.1.1: {} - jscodeshift@0.15.2(@babel/preset-env@7.25.4(@babel/core@7.25.2)): dependencies: '@babel/core': 7.25.2 @@ -30189,6 +28944,8 @@ snapshots: json-parse-even-better-errors@2.3.1: {} + json-parse-even-better-errors@3.0.2: {} + json-rpc-engine@6.1.0: dependencies: '@metamask/safe-event-emitter': 2.0.0 @@ -30206,12 +28963,8 @@ snapshots: json-schema-typed@7.0.3: {} - json-schema@0.4.0: {} - json-stable-stringify-without-jsonify@1.0.1: {} - json-stringify-safe@5.0.1: {} - json-to-pretty-yaml@1.2.2: dependencies: remedial: 1.0.8 @@ -30237,20 +28990,6 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 - jsonwebtoken@9.0.0: - dependencies: - jws: 3.2.2 - lodash: 4.17.21 - ms: 2.1.3 - semver: 7.6.3 - - jsprim@1.4.2: - dependencies: - assert-plus: 1.0.0 - extsprintf: 1.3.0 - json-schema: 0.4.0 - verror: 1.10.0 - jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.8 @@ -30265,17 +29004,6 @@ snapshots: readable-stream: 2.3.8 setimmediate: 1.0.5 - jwa@1.4.1: - dependencies: - buffer-equal-constant-time: 1.0.1 - ecdsa-sig-formatter: 1.0.11 - safe-buffer: 5.2.1 - - jws@3.2.2: - dependencies: - jwa: 1.4.1 - safe-buffer: 5.2.1 - katex@0.16.11: dependencies: commander: 8.3.0 @@ -30294,6 +29022,8 @@ snapshots: kolorist@1.8.0: {} + ky@1.7.3: {} + language-subtag-registry@0.3.23: {} language-tags@1.0.9: @@ -30304,6 +29034,10 @@ snapshots: dependencies: package-json: 8.1.1 + latest-version@9.0.0: + dependencies: + package-json: 10.0.1 + launch-editor@2.9.1: dependencies: picocolors: 1.1.0 @@ -30338,7 +29072,7 @@ snapshots: dependencies: immediate: 3.0.6 - lighthouse-logger@1.4.2: + lighthouse-logger@2.0.1: dependencies: debug: 2.6.9 marky: 1.2.5 @@ -30404,6 +29138,11 @@ snapshots: loader-utils@3.3.1: {} + local-pkg@0.5.1: + dependencies: + mlly: 1.7.3 + pkg-types: 1.2.1 + localforage@1.10.0: dependencies: lie: 3.1.1 @@ -30433,10 +29172,6 @@ snapshots: lodash.deburr@4.1.0: {} - lodash.get@4.4.2: {} - - lodash.isequal@4.5.0: {} - lodash.isnumber@3.0.3: {} lodash.memoize@4.1.2: {} @@ -30481,8 +29216,6 @@ snapshots: strip-ansi: 7.1.0 wrap-ansi: 9.0.0 - loglevel@1.9.2: {} - longest-streak@3.1.0: {} loose-envify@1.4.0: @@ -31434,6 +30167,13 @@ snapshots: pkg-types: 1.2.0 ufo: 1.5.4 + mlly@1.7.3: + dependencies: + acorn: 8.14.0 + pathe: 1.1.2 + pkg-types: 1.2.1 + ufo: 1.5.4 + modern-ahocorasick@1.0.1: {} moment@2.30.1: {} @@ -31468,7 +30208,7 @@ snapshots: optionalDependencies: typescript: 5.6.2 - muggle-string@0.3.1: {} + muggle-string@0.4.1: {} multer@1.4.4-lts.1: dependencies: @@ -31496,25 +30236,15 @@ snapshots: mute-stream@1.0.0: {} - mv@2.1.1: - dependencies: - mkdirp: 0.5.6 - ncp: 2.0.0 - rimraf: 2.4.5 - optional: true - mz@2.7.0: dependencies: any-promise: 1.3.0 object-assign: 4.1.1 thenify-all: 1.6.0 - nan@2.20.0: - optional: true - - nanoid@3.3.7: {} + nanoid@3.3.8: {} - nanoid@5.0.7: {} + nanoid@5.0.9: {} nanospinner@1.1.0: dependencies: @@ -31524,16 +30254,13 @@ snapshots: natural-orderby@2.0.3: {} - ncp@2.0.0: - optional: true - negotiator@0.6.3: {} neo-async@2.6.2: {} - next@14.2.10(@babel/core@7.25.2)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.79.3): + next@14.2.15(@babel/core@7.25.2)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.79.3): dependencies: - '@next/env': 14.2.10 + '@next/env': 14.2.15 '@swc/helpers': 0.5.5 busboy: 1.6.0 caniuse-lite: 1.0.30001664 @@ -31543,15 +30270,15 @@ snapshots: react-dom: 18.3.1(react@18.3.1) styled-jsx: 5.1.1(@babel/core@7.25.2)(babel-plugin-macros@3.1.0)(react@18.3.1) optionalDependencies: - '@next/swc-darwin-arm64': 14.2.10 - '@next/swc-darwin-x64': 14.2.10 - '@next/swc-linux-arm64-gnu': 14.2.10 - '@next/swc-linux-arm64-musl': 14.2.10 - '@next/swc-linux-x64-gnu': 14.2.10 - '@next/swc-linux-x64-musl': 14.2.10 - '@next/swc-win32-arm64-msvc': 14.2.10 - '@next/swc-win32-ia32-msvc': 14.2.10 - '@next/swc-win32-x64-msvc': 14.2.10 + '@next/swc-darwin-arm64': 14.2.15 + '@next/swc-darwin-x64': 14.2.15 + '@next/swc-linux-arm64-gnu': 14.2.15 + '@next/swc-linux-arm64-musl': 14.2.15 + '@next/swc-linux-x64-gnu': 14.2.15 + '@next/swc-linux-x64-musl': 14.2.15 + '@next/swc-win32-arm64-msvc': 14.2.15 + '@next/swc-win32-ia32-msvc': 14.2.15 + '@next/swc-win32-x64-msvc': 14.2.15 '@playwright/test': 1.47.2 sass: 1.79.3 transitivePeerDependencies: @@ -31571,8 +30298,6 @@ snapshots: dependencies: minimatch: 3.1.2 - node-domexception@1.0.0: {} - node-emoji@1.11.0: dependencies: lodash: 4.17.21 @@ -31590,12 +30315,6 @@ snapshots: dependencies: whatwg-url: 5.0.0 - node-fetch@3.3.1: - dependencies: - data-uri-to-buffer: 4.0.1 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 - node-forge@1.3.1: {} node-int64@0.4.0: {} @@ -31659,8 +30378,6 @@ snapshots: pkg-types: 1.2.0 ufo: 1.5.4 - oauth-sign@0.9.0: {} - object-assign@4.1.1: {} object-hash@3.0.0: {} @@ -31761,6 +30478,13 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 + open@9.1.0: + dependencies: + default-browser: 4.0.0 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 2.2.0 + opener@1.5.2: {} optionator@0.9.4: @@ -31864,6 +30588,13 @@ snapshots: package-json-from-dist@1.0.1: {} + package-json@10.0.1: + dependencies: + ky: 1.7.3 + registry-auth-token: 5.0.2 + registry-url: 6.0.1 + semver: 7.6.3 + package-json@8.1.1: dependencies: got: 12.6.1 @@ -31926,12 +30657,13 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - parse-json@6.0.2: + parse-json@7.1.1: dependencies: '@babel/code-frame': 7.24.7 error-ex: 1.3.2 - json-parse-even-better-errors: 2.3.1 + json-parse-even-better-errors: 3.0.2 lines-and-columns: 2.0.4 + type-fest: 3.13.1 parse-numeric-range@1.3.0: {} @@ -31996,7 +30728,7 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 - path-to-regexp@0.1.10: {} + path-to-regexp@0.1.12: {} path-to-regexp@1.9.0: dependencies: @@ -32024,8 +30756,6 @@ snapshots: pend@1.2.0: {} - performance-now@2.1.0: {} - periscopic@3.1.0: dependencies: '@types/estree': 1.0.6 @@ -32055,6 +30785,8 @@ snapshots: pino-std-serializers@6.2.2: {} + pino-std-serializers@7.0.0: {} + pino@8.20.0: dependencies: atomic-sleep: 1.0.0 @@ -32069,6 +30801,20 @@ snapshots: sonic-boom: 3.8.1 thread-stream: 2.7.0 + pino@9.4.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 1.2.0 + pino-std-serializers: 7.0.0 + process-warning: 4.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 4.2.0 + thread-stream: 3.1.0 + pirates@4.0.6: {} pkce-challenge@2.2.0: {} @@ -32095,6 +30841,12 @@ snapshots: mlly: 1.7.1 pathe: 1.1.2 + pkg-types@1.2.1: + dependencies: + confbox: 0.1.8 + mlly: 1.7.3 + pathe: 1.1.2 + pkg-up@3.1.0: dependencies: find-up: 3.0.0 @@ -32628,13 +31380,13 @@ snapshots: postcss@8.4.31: dependencies: - nanoid: 3.3.7 + nanoid: 3.3.8 picocolors: 1.1.0 source-map-js: 1.2.1 postcss@8.4.47: dependencies: - nanoid: 3.3.7 + nanoid: 3.3.8 picocolors: 1.1.0 source-map-js: 1.2.1 @@ -32689,6 +31441,8 @@ snapshots: process-warning@3.0.0: {} + process-warning@4.0.0: {} + process@0.11.10: {} progress@2.0.3: {} @@ -32796,8 +31550,6 @@ snapshots: dependencies: side-channel: 1.0.6 - qs@6.5.3: {} - querystringify@2.2.0: {} queue-microtask@1.2.3: {} @@ -32850,7 +31602,7 @@ snapshots: react: 18.3.1 tween-functions: 1.2.0 - react-dev-utils@12.0.1(eslint@8.57.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)(webpack@5.95.0): + react-dev-utils@12.0.1(eslint@8.57.1)(typescript@5.6.2)(webpack@5.95.0): dependencies: '@babel/code-frame': 7.24.7 address: 1.2.2 @@ -32861,7 +31613,7 @@ snapshots: escape-string-regexp: 4.0.0 filesize: 8.0.7 find-up: 5.0.0 - fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@5.6.2)(vue-template-compiler@2.7.16)(webpack@5.95.0) + fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@5.6.2)(webpack@5.95.0) global-modules: 2.0.0 globby: 11.1.0 gzip-size: 6.0.0 @@ -33007,14 +31759,6 @@ snapshots: react-refresh@0.14.2: {} - react-remove-scroll-bar@2.3.4(@types/react@18.3.9)(react@18.3.1): - dependencies: - react: 18.3.1 - react-style-singleton: 2.2.1(@types/react@18.3.9)(react@18.3.1) - tslib: 2.7.0 - optionalDependencies: - '@types/react': 18.3.9 - react-remove-scroll-bar@2.3.6(@types/react@18.3.9)(react@18.3.1): dependencies: react: 18.3.1 @@ -33289,8 +32033,6 @@ snapshots: regenerate@1.4.2: {} - regenerator-runtime@0.13.11: {} - regenerator-runtime@0.14.1: {} regenerator-transform@0.15.2: @@ -33490,29 +32232,6 @@ snapshots: repeat-string@1.6.1: {} - request@2.88.2: - dependencies: - aws-sign2: 0.7.0 - aws4: 1.13.2 - caseless: 0.12.0 - combined-stream: 1.0.8 - extend: 3.0.2 - forever-agent: 0.6.1 - form-data: 2.3.3 - har-validator: 5.1.5 - http-signature: 1.2.0 - is-typedarray: 1.0.0 - isstream: 0.1.2 - json-stringify-safe: 5.0.1 - mime-types: 2.1.35 - oauth-sign: 0.9.0 - performance-now: 2.1.0 - qs: 6.5.3 - safe-buffer: 5.2.1 - tough-cookie: 2.5.0 - tunnel-agent: 0.6.0 - uuid: 3.4.0 - require-directory@2.1.1: {} require-from-string@2.0.2: {} @@ -33578,11 +32297,6 @@ snapshots: rfdc@1.4.1: {} - rimraf@2.4.5: - dependencies: - glob: 6.0.4 - optional: true - rimraf@2.6.3: dependencies: glob: 7.2.3 @@ -33638,6 +32352,10 @@ snapshots: postcss: 8.4.47 strip-json-comments: 3.1.1 + run-applescript@5.0.0: + dependencies: + execa: 5.1.1 + run-async@2.4.1: {} run-async@3.0.0: {} @@ -33667,9 +32385,6 @@ snapshots: safe-buffer@5.2.1: {} - safe-json-stringify@1.2.0: - optional: true - safe-regex-test@1.0.3: dependencies: call-bind: 1.0.7 @@ -33749,8 +32464,6 @@ snapshots: dependencies: lru-cache: 6.0.0 - semver@7.6.2: {} - semver@7.6.3: {} send@0.19.0: @@ -33843,11 +32556,6 @@ snapshots: setprototypeof@1.2.0: {} - sha.js@2.4.11: - dependencies: - inherits: 2.0.4 - safe-buffer: 5.2.1 - shallow-clone@3.0.1: dependencies: kind-of: 6.0.3 @@ -33890,19 +32598,6 @@ snapshots: siginfo@2.0.0: {} - sign-addon@5.3.0: - dependencies: - common-tags: 1.8.2 - core-js: 3.29.0 - deepcopy: 2.1.0 - es6-error: 4.1.1 - es6-promisify: 7.0.0 - jsonwebtoken: 9.0.0 - mz: 2.7.0 - request: 2.88.2 - source-map-support: 0.5.21 - stream-to-promise: 3.0.0 - signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -33979,6 +32674,10 @@ snapshots: dependencies: atomic-sleep: 1.0.0 + sonic-boom@4.2.0: + dependencies: + atomic-sleep: 1.0.0 + sort-css-media-queries@2.2.0: {} source-map-js@1.2.1: {} @@ -34070,18 +32769,6 @@ snapshots: srcset@4.0.0: {} - sshpk@1.18.0: - dependencies: - asn1: 0.2.6 - assert-plus: 1.0.0 - bcrypt-pbkdf: 1.0.2 - dashdash: 1.14.1 - ecc-jsbn: 0.1.2 - getpass: 0.1.7 - jsbn: 0.1.1 - safer-buffer: 2.1.2 - tweetnacl: 0.14.5 - stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 @@ -34150,16 +32837,6 @@ snapshots: stream-shift@1.0.3: {} - stream-to-array@2.3.0: - dependencies: - any-promise: 1.3.0 - - stream-to-promise@3.0.0: - dependencies: - any-promise: 1.3.0 - end-of-stream: 1.4.4 - stream-to-array: 2.3.0 - streamsearch@1.1.0: {} strict-event-emitter@0.5.1: {} @@ -34299,7 +32976,9 @@ snapshots: strip-json-comments@3.1.1: {} - strip-json-comments@5.0.0: {} + strip-json-comments@5.0.1: {} + + stubborn-fs@1.2.5: {} style-to-js@1.1.16: dependencies: @@ -34596,6 +33275,10 @@ snapshots: dependencies: real-require: 0.2.0 + thread-stream@3.1.0: + dependencies: + real-require: 0.2.0 + throttle-debounce@5.0.2: {} through2@2.0.5: @@ -34634,14 +33317,12 @@ snapshots: dependencies: tslib: 2.7.0 + titleize@3.0.0: {} + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 - tmp@0.2.1: - dependencies: - rimraf: 3.0.2 - tmp@0.2.3: {} tmpl@1.0.5: {} @@ -34667,15 +33348,8 @@ snapshots: toposort@2.0.2: {} - tosource@1.0.0: {} - totalist@3.0.1: {} - tough-cookie@2.5.0: - dependencies: - psl: 1.9.0 - punycode: 2.3.1 - tough-cookie@4.1.4: dependencies: psl: 1.9.0 @@ -34881,8 +33555,6 @@ snapshots: tween-functions@1.2.0: {} - tweetnacl@0.14.5: {} - tweetnacl@1.0.3: {} type-check@0.4.0: @@ -34891,8 +33563,6 @@ snapshots: type-detect@4.0.8: {} - type-detect@4.1.0: {} - type-fest@0.16.0: {} type-fest@0.20.2: {} @@ -34907,6 +33577,8 @@ snapshots: type-fest@2.19.0: {} + type-fest@3.13.1: {} + type-fest@4.26.1: {} type-is@1.6.18: @@ -35000,40 +33672,6 @@ snapshots: typescript@5.6.2: {} - typesense-docsearch-css@0.4.1: {} - - typesense-docsearch-react@3.4.1(@algolia/client-search@4.24.0)(@babel/runtime@7.25.6)(@types/react@18.3.9)(algoliasearch@4.24.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@algolia/autocomplete-core': 1.8.2 - '@algolia/autocomplete-preset-algolia': 1.8.2(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) - typesense: 1.8.2(@babel/runtime@7.25.6) - typesense-docsearch-css: 0.4.1 - typesense-instantsearch-adapter: 2.8.0(@babel/runtime@7.25.6) - optionalDependencies: - '@types/react': 18.3.9 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - transitivePeerDependencies: - - '@algolia/client-search' - - '@babel/runtime' - - algoliasearch - - debug - - typesense-instantsearch-adapter@2.8.0(@babel/runtime@7.25.6): - dependencies: - '@babel/runtime': 7.25.6 - typesense: 1.8.2(@babel/runtime@7.25.6) - transitivePeerDependencies: - - debug - - typesense@1.8.2(@babel/runtime@7.25.6): - dependencies: - '@babel/runtime': 7.25.6 - axios: 1.7.7(debug@4.3.7) - loglevel: 1.9.2 - transitivePeerDependencies: - - debug - ua-parser-js@1.0.39: {} uc.micro@2.1.0: {} @@ -35168,8 +33806,6 @@ snapshots: universalify@0.2.0: {} - universalify@1.0.0: {} - universalify@2.0.1: {} unixify@1.0.0: @@ -35212,6 +33848,19 @@ snapshots: semver-diff: 4.0.0 xdg-basedir: 5.1.0 + update-notifier@7.3.1: + dependencies: + boxen: 8.0.1 + chalk: 5.3.0 + configstore: 7.0.0 + is-in-ci: 1.0.0 + is-installed-globally: 1.0.0 + is-npm: 6.0.0 + latest-version: 9.0.0 + pupa: 3.1.0 + semver: 7.6.3 + xdg-basedir: 5.1.0 + upper-case-first@2.0.2: dependencies: tslib: 2.7.0 @@ -35306,8 +33955,6 @@ snapshots: uuid@10.0.0: {} - uuid@3.4.0: {} - uuid@8.3.2: {} uuid@9.0.1: {} @@ -35338,8 +33985,6 @@ snapshots: dependencies: builtins: 1.0.3 - validator@13.12.0: {} - value-equal@1.0.1: {} value-or-promise@1.0.12: {} @@ -35348,12 +33993,6 @@ snapshots: vary@1.1.2: {} - verror@1.10.0: - dependencies: - assert-plus: 1.0.0 - core-util-is: 1.0.2 - extsprintf: 1.3.0 - vfile-location@5.0.3: dependencies: '@types/unist': 3.0.3 @@ -35451,16 +34090,18 @@ snapshots: - supports-color - terser - vite-plugin-dts@3.9.1(@types/node@20.16.9)(rollup@4.22.4)(typescript@5.6.2)(vite@5.4.8(@types/node@20.16.9)(sass@1.79.3)(terser@5.34.0)): + vite-plugin-dts@4.3.0(@types/node@20.16.9)(rollup@4.22.4)(typescript@5.6.2)(vite@5.4.8(@types/node@20.16.9)(sass@1.79.3)(terser@5.34.0)): dependencies: - '@microsoft/api-extractor': 7.43.0(@types/node@20.16.9) + '@microsoft/api-extractor': 7.48.1(@types/node@20.16.9) '@rollup/pluginutils': 5.1.2(rollup@4.22.4) - '@vue/language-core': 1.8.27(typescript@5.6.2) + '@volar/typescript': 2.4.11 + '@vue/language-core': 2.1.6(typescript@5.6.2) + compare-versions: 6.1.1 debug: 4.3.7(supports-color@8.1.1) kolorist: 1.8.0 + local-pkg: 0.5.1 magic-string: 0.30.11 typescript: 5.6.2 - vue-tsc: 1.8.27(typescript@5.6.2) optionalDependencies: vite: 5.4.8(@types/node@20.16.9)(sass@1.79.3)(terser@5.34.0) transitivePeerDependencies: @@ -35596,22 +34237,12 @@ snapshots: - supports-color - terser + vscode-uri@3.0.8: {} + vue-parser@1.1.6: dependencies: parse5: 3.0.3 - vue-template-compiler@2.7.16: - dependencies: - de-indent: 1.0.2 - he: 1.2.0 - - vue-tsc@1.8.27(typescript@5.6.2): - dependencies: - '@volar/typescript': 1.11.1 - '@vue/language-core': 1.8.27(typescript@5.6.2) - semver: 7.6.3 - typescript: 5.6.2 - w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 @@ -35646,11 +34277,6 @@ snapshots: transitivePeerDependencies: - debug - watchpack@2.4.0: - dependencies: - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - watchpack@2.4.2: dependencies: glob-to-regexp: 0.4.1 @@ -35664,44 +34290,41 @@ snapshots: dependencies: defaults: 1.0.4 - web-ext@7.12.0(body-parser@1.20.3): + web-ext@8.3.0(body-parser@1.20.3): dependencies: - '@babel/runtime': 7.21.0 - '@devicefarmer/adbkit': 3.2.3 - addons-linter: 6.28.0(body-parser@1.20.3)(node-fetch@3.3.1) - bunyan: 1.8.15 - camelcase: 7.0.1 - chrome-launcher: 0.15.1 + '@babel/runtime': 7.25.6 + '@devicefarmer/adbkit': 3.2.6 + addons-linter: 7.1.0(body-parser@1.20.3) + camelcase: 8.0.0 + chrome-launcher: 1.1.2 debounce: 1.2.1 decamelize: 6.0.0 es6-error: 4.1.1 - firefox-profile: 4.3.2 - fs-extra: 11.1.0 + firefox-profile: 4.7.0 fx-runner: 1.4.0 - import-fresh: 3.3.0 - jose: 4.13.1 - mkdirp: 1.0.4 + https-proxy-agent: 7.0.5 + jose: 5.9.2 + jszip: 3.10.1 multimatch: 6.0.0 - mz: 2.7.0 - node-fetch: 3.3.1 node-notifier: 10.0.0 - open: 8.4.2 - parse-json: 6.0.2 + open: 9.1.0 + parse-json: 7.1.1 + pino: 9.4.0 promise-toolbox: 0.21.0 - sign-addon: 5.3.0 source-map-support: 0.5.21 strip-bom: 5.0.0 - strip-json-comments: 5.0.0 - tmp: 0.2.1 - update-notifier: 6.0.2 - watchpack: 2.4.0 + strip-json-comments: 5.0.1 + tmp: 0.2.3 + update-notifier: 7.3.1 + watchpack: 2.4.2 ws: 8.18.0 - yargs: 17.7.1 + yargs: 17.7.2 zip-dir: 2.0.0 transitivePeerDependencies: - body-parser - bufferutil - express + - node-fetch - safe-compare - supports-color - utf-8-validate @@ -36209,6 +34832,8 @@ snapshots: tr46: 0.0.3 webidl-conversions: 3.0.1 + when-exit@2.1.3: {} + when@3.7.7: {} which-boxed-primitive@1.0.2: @@ -36277,6 +34902,10 @@ snapshots: dependencies: string-width: 5.1.2 + widest-line@5.0.0: + dependencies: + string-width: 7.2.0 + wildcard@2.0.1: {} winreg@0.0.12: {} @@ -36339,7 +34968,7 @@ snapshots: xml-name-validator@5.0.0: {} - xml2js@0.5.0: + xml2js@0.6.2: dependencies: sax: 1.4.1 xmlbuilder: 11.0.1 @@ -36383,16 +35012,6 @@ snapshots: y18n: 4.0.3 yargs-parser: 18.1.3 - yargs@17.7.1: - dependencies: - cliui: 8.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - yargs@17.7.2: dependencies: cliui: 8.0.1 @@ -36423,14 +35042,6 @@ snapshots: toposort: 2.0.2 type-fest: 2.19.0 - z-schema@5.0.5: - dependencies: - lodash.get: 4.4.2 - lodash.isequal: 4.5.0 - validator: 13.12.0 - optionalDependencies: - commander: 9.5.0 - zip-dir@2.0.0: dependencies: async: 3.2.2 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 58699ae570b..3ad2792cd72 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -5,7 +5,7 @@ packages: - "sdk/**" - "!**/dist/**" - "!**/.next/**" - - "!sdk/create-dapp/templates" + - "!sdk/create-dapp/templates/*" - "!sdk/typescript/bcs" - "!sdk/typescript/client" - "!sdk/typescript/cryptography" diff --git a/scripts/simtest/clippy.sh b/scripts/simtest/clippy.sh index 951e372c211..9b64233cc5e 100755 --- a/scripts/simtest/clippy.sh +++ b/scripts/simtest/clippy.sh @@ -5,6 +5,7 @@ # verify that git repo is clean if [[ -n $(git status -s) ]]; then echo "Working directory is not clean. Please commit all changes before running this script." + git status -s exit 1 fi diff --git a/scripts/simtest/simtest-cov.sh b/scripts/simtest/simtest-cov.sh index a8701b87c0c..acd415165eb 100755 --- a/scripts/simtest/simtest-cov.sh +++ b/scripts/simtest/simtest-cov.sh @@ -6,7 +6,7 @@ # verify that git repo is clean if [[ -n $(git status -s) ]]; then echo "Working directory is not clean. Please commit all changes before running this script." - echo $(git status -s) + git status -s exit 1 fi diff --git a/sdk/create-dapp/CHANGELOG.md b/sdk/create-dapp/CHANGELOG.md index d04a319a617..567b062afe9 100644 --- a/sdk/create-dapp/CHANGELOG.md +++ b/sdk/create-dapp/CHANGELOG.md @@ -1,5 +1,12 @@ # @iota/create-dapp +## 0.3.0 + +### Minor Changes + +- 8c3a220: Update some outdated eslint dependencies of the `@iota/create-dapp` templates, to their + eslint v9-compatible versions + ## 0.2.2 ### Patch Changes diff --git a/sdk/create-dapp/package.json b/sdk/create-dapp/package.json index 29361e97cce..b709ffd341d 100644 --- a/sdk/create-dapp/package.json +++ b/sdk/create-dapp/package.json @@ -3,7 +3,7 @@ "author": "IOTA Foundation <info@iota.org>", "description": "A CLI for creating new IOTA dApps", "homepage": "https://docs.iota.org/references/ts-sdk/typescript/", - "version": "0.2.2", + "version": "0.3.0", "license": "Apache-2.0", "files": [ "CHANGELOG.md", diff --git a/sdk/create-dapp/templates/react-client-dapp/eslint.config.js b/sdk/create-dapp/templates/react-client-dapp/eslint.config.js new file mode 100644 index 00000000000..7c663262678 --- /dev/null +++ b/sdk/create-dapp/templates/react-client-dapp/eslint.config.js @@ -0,0 +1,28 @@ +import eslint from "@eslint/js"; +import tseslint from "typescript-eslint"; +import react from "eslint-plugin-react"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; + +export default tseslint.config( + { + files: ["**/*.{js,jsx,mjs,cjs,ts,tsx}"], + plugins: { + react, + reactHooks, + reactRefresh, + }, + settings: { + version: "18", + }, + languageOptions: { + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + }, + }, + eslint.configs.recommended, + tseslint.configs.recommended, +); diff --git a/sdk/create-dapp/templates/react-client-dapp/package.json b/sdk/create-dapp/templates/react-client-dapp/package.json index 8e79c61bd6b..611f666329d 100644 --- a/sdk/create-dapp/templates/react-client-dapp/package.json +++ b/sdk/create-dapp/templates/react-client-dapp/package.json @@ -6,28 +6,30 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "preview": "vite preview" + "lint": "eslint .", + "preview": "vite preview", + "format": "prettier -w ." }, "dependencies": { "@iota/dapp-kit": "workspace:*", "@iota/iota-sdk": "workspace:*", - "@radix-ui/colors": "^3.0.0", - "@radix-ui/react-icons": "^1.3.0", "@radix-ui/themes": "^3.1.1", "@tanstack/react-query": "^5.50.1", "react": "^18.3.1", "react-dom": "^18.3.1" }, "devDependencies": { + "@eslint/js": "^9.17.0", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^7.16.0", - "@typescript-eslint/parser": "^7.16.0", + "@typescript-eslint/eslint-plugin": "^8.18.0", + "@typescript-eslint/parser": "^8.18.0", "@vitejs/plugin-react-swc": "^3.7.0", - "eslint": "^9.6.0", - "eslint-plugin-react-hooks": "^4.6.2", + "eslint": "^9.17.0", + "eslint-plugin-react-hooks": "^5.1.0", "eslint-plugin-react-refresh": "^0.4.7", + "eslint-plugin-react": "^7.37.2", + "typescript-eslint": "^8.18.0", "prettier": "^3.3.2", "typescript": "^5.5.3", "vite": "^5.3.3" diff --git a/sdk/create-dapp/templates/react-e2e-counter/eslint.config.js b/sdk/create-dapp/templates/react-e2e-counter/eslint.config.js new file mode 100644 index 00000000000..7c663262678 --- /dev/null +++ b/sdk/create-dapp/templates/react-e2e-counter/eslint.config.js @@ -0,0 +1,28 @@ +import eslint from "@eslint/js"; +import tseslint from "typescript-eslint"; +import react from "eslint-plugin-react"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; + +export default tseslint.config( + { + files: ["**/*.{js,jsx,mjs,cjs,ts,tsx}"], + plugins: { + react, + reactHooks, + reactRefresh, + }, + settings: { + version: "18", + }, + languageOptions: { + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + }, + }, + eslint.configs.recommended, + tseslint.configs.recommended, +); diff --git a/sdk/create-dapp/templates/react-e2e-counter/package.json b/sdk/create-dapp/templates/react-e2e-counter/package.json index 607acf6b606..0be7053cb16 100644 --- a/sdk/create-dapp/templates/react-e2e-counter/package.json +++ b/sdk/create-dapp/templates/react-e2e-counter/package.json @@ -6,28 +6,30 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "preview": "vite preview" + "lint": "eslint .", + "preview": "vite preview", + "format": "prettier -w ." }, "dependencies": { "@iota/dapp-kit": "workspace:*", "@iota/iota-sdk": "workspace:*", - "@radix-ui/colors": "^3.0.0", - "@radix-ui/react-icons": "^1.3.0", "@radix-ui/themes": "^3.1.1", "@tanstack/react-query": "^5.50.1", "react": "^18.3.1", "react-dom": "^18.3.1" }, "devDependencies": { + "@eslint/js": "^9.17.0", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", + "@typescript-eslint/eslint-plugin": "^8.18.0", + "@typescript-eslint/parser": "^8.18.0", "@vitejs/plugin-react-swc": "^3.7.0", - "eslint": "^8.45.0", - "eslint-plugin-react-hooks": "^4.6.2", + "eslint": "^9.17.0", + "eslint-plugin-react-hooks": "^5.1.0", "eslint-plugin-react-refresh": "^0.4.7", + "eslint-plugin-react": "^7.37.2", + "typescript-eslint": "^8.18.0", "prettier": "^3.3.2", "typescript": "^5.5.3", "vite": "^5.3.3" diff --git a/sdk/typescript/src/client/types/params.ts b/sdk/typescript/src/client/types/params.ts index feb1c6ccf3c..6d6a88d5b48 100644 --- a/sdk/typescript/src/client/types/params.ts +++ b/sdk/typescript/src/client/types/params.ts @@ -326,7 +326,8 @@ export interface GetValidatorsApyParams {} /** Return list of events for a specified query criteria. */ export interface QueryEventsParams { /** - * The event query criteria. See [Event filter](https://docs.iota.org/developer/iota-101/using-events#applying-event-filters) + * The event query criteria. See + * [Event filter](https://docs.iota.org/developer/iota-101/using-events#applying-event-filters) * documentation for examples. */ query: RpcTypes.IotaEventFilter; @@ -353,7 +354,8 @@ export type QueryTransactionBlocksParams = { export interface SubscribeEventParams { /** * The filter criteria of the event stream. See - * [Event filter](https://docs.iota.org/developer/iota-101/using-events#applying-event-filters) documentation for examples. + * [Event filter](https://docs.iota.org/developer/iota-101/using-events#applying-event-filters) + * documentation for examples. */ filter: RpcTypes.IotaEventFilter; }