diff --git a/packages/react-native-adapter/README.md b/packages/react-native-adapter/README.md index c7031f464ab..d2eb074e6cb 100644 --- a/packages/react-native-adapter/README.md +++ b/packages/react-native-adapter/README.md @@ -15,7 +15,7 @@ npx expo install thirdweb @thirdweb-dev/react-native-adapter Since react native requires installing native dependencies directly, you also have to install these required peer dependencies: ```shell -npx expo install react-native-get-random-values @react-native-community/netinfo expo-application @react-native-async-storage/async-storage expo-web-browser expo-linking react-native-aes-gcm-crypto react-native-quick-crypto@0.7.0-rc.6 amazon-cognito-identity-js @coinbase/wallet-mobile-sdk react-native-mmkv react-native-svg +npx expo install react-native-get-random-values @react-native-community/netinfo expo-application @react-native-async-storage/async-storage expo-web-browser expo-linking react-native-aes-gcm-crypto react-native-quick-crypto@0.7.0-rc.6 amazon-cognito-identity-js @coinbase/wallet-mobile-sdk react-native-mmkv react-native-svg @react-native-clipboard/clipboard ``` Here's an explanation of each peer dependency and why its needed: @@ -34,6 +34,10 @@ expo-web-browser // for oauth flows amazon-cognito-identity-js // for authentication react-native-aes-gcm-crypto // for encryption react-native-quick-crypto@0.7.0-rc.6 //for fast hashing + +// needed for the prebuilt UIs +react-native-svg +@react-native-clipboard/clipboard ``` ### 2. Edit your `metro.config.js` diff --git a/packages/react-native-adapter/package.json b/packages/react-native-adapter/package.json index 23fb2ef5176..68acdfd1c53 100644 --- a/packages/react-native-adapter/package.json +++ b/packages/react-native-adapter/package.json @@ -34,6 +34,7 @@ "typescript": ">=5.0.4", "@coinbase/wallet-mobile-sdk": "^1", "@react-native-async-storage/async-storage": "^1", + "@react-native-clipboard/clipboard": "^1", "@react-native-community/netinfo": "^11", "amazon-cognito-identity-js": "^6", "expo-application": "^5", diff --git a/packages/thirdweb/package.json b/packages/thirdweb/package.json index de39603d58f..23d04bdb573 100644 --- a/packages/thirdweb/package.json +++ b/packages/thirdweb/package.json @@ -117,54 +117,22 @@ }, "typesVersions": { "*": { - "adapters/*": [ - "./dist/types/exports/adapters/*.d.ts" - ], - "auth": [ - "./dist/types/exports/auth.d.ts" - ], - "chains": [ - "./dist/types/exports/chains.d.ts" - ], - "contract": [ - "./dist/types/exports/contract.d.ts" - ], - "deploys": [ - "./dist/types/exports/deploys.d.ts" - ], - "event": [ - "./dist/types/exports/event.d.ts" - ], - "extensions/*": [ - "./dist/types/exports/extensions/*.d.ts" - ], - "pay": [ - "./dist/types/exports/pay.d.ts" - ], - "react": [ - "./dist/types/exports/react.d.ts" - ], - "react-native": [ - "./dist/types/exports/react-native.d.ts" - ], - "rpc": [ - "./dist/types/exports/rpc.d.ts" - ], - "storage": [ - "./dist/types/exports/storage.d.ts" - ], - "transaction": [ - "./dist/types/exports/transaction.d.ts" - ], - "utils": [ - "./dist/types/exports/utils.d.ts" - ], - "wallets": [ - "./dist/types/exports/wallets.d.ts" - ], - "wallets/*": [ - "./dist/types/exports/wallets/*.d.ts" - ] + "adapters/*": ["./dist/types/exports/adapters/*.d.ts"], + "auth": ["./dist/types/exports/auth.d.ts"], + "chains": ["./dist/types/exports/chains.d.ts"], + "contract": ["./dist/types/exports/contract.d.ts"], + "deploys": ["./dist/types/exports/deploys.d.ts"], + "event": ["./dist/types/exports/event.d.ts"], + "extensions/*": ["./dist/types/exports/extensions/*.d.ts"], + "pay": ["./dist/types/exports/pay.d.ts"], + "react": ["./dist/types/exports/react.d.ts"], + "react-native": ["./dist/types/exports/react-native.d.ts"], + "rpc": ["./dist/types/exports/rpc.d.ts"], + "storage": ["./dist/types/exports/storage.d.ts"], + "transaction": ["./dist/types/exports/transaction.d.ts"], + "utils": ["./dist/types/exports/utils.d.ts"], + "wallets": ["./dist/types/exports/wallets.d.ts"], + "wallets/*": ["./dist/types/exports/wallets/*.d.ts"] } }, "browser": { @@ -212,6 +180,7 @@ "@expo/vector-icons": "^14", "@coinbase/wallet-mobile-sdk": "^1", "@react-native-async-storage/async-storage": "^1", + "@react-native-clipboard/clipboard": "^1", "amazon-cognito-identity-js": "^6", "aws-amplify": "^5", "ethers": "^5 || ^6", @@ -270,6 +239,9 @@ "@react-native-async-storage/async-storage": { "optional": true }, + "@react-native-clipboard/clipboard": { + "optional": true + }, "@coinbase/wallet-mobile-sdk": { "optional": true } @@ -310,6 +282,7 @@ "@expo/vector-icons": "^14.0.0", "@coinbase/wallet-mobile-sdk": "1.0.13", "@react-native-async-storage/async-storage": "^1.23.1", + "@react-native-clipboard/clipboard": "1.14.1", "@testing-library/jest-dom": "^6.4.6", "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.5.2", @@ -329,4 +302,4 @@ "react-native-svg": "15.3.0", "vitest": "1.6.0" } -} \ No newline at end of file +} diff --git a/packages/thirdweb/src/exports/react.ts b/packages/thirdweb/src/exports/react.ts index 45e32fbdc33..646de3a9576 100644 --- a/packages/thirdweb/src/exports/react.ts +++ b/packages/thirdweb/src/exports/react.ts @@ -28,8 +28,8 @@ export { ThirdwebProvider } from "../react/core/providers/thirdweb-provider.js"; export type { SupportedTokens, TokenInfo, -} from "../react/web/ui/ConnectWallet/defaultTokens.js"; -export { defaultTokens } from "../react/web/ui/ConnectWallet/defaultTokens.js"; +} from "../react/core/utils/defaultTokens.js"; +export { defaultTokens } from "../react/core/utils/defaultTokens.js"; // Media Renderer export { MediaRenderer } from "../react/web/ui/MediaRenderer/MediaRenderer.js"; diff --git a/packages/thirdweb/src/exports/wallets/in-app.ts b/packages/thirdweb/src/exports/wallets/in-app.ts index e83775bd113..2dcbd50cdd6 100644 --- a/packages/thirdweb/src/exports/wallets/in-app.ts +++ b/packages/thirdweb/src/exports/wallets/in-app.ts @@ -13,4 +13,4 @@ export { type GetAuthenticatedUserParams } from "../../wallets/in-app/core/authe export { hasStoredPasskey } from "../../wallets/in-app/web/lib/auth/passkeys.js"; -export { socialIcons } from "../../react/web/wallets/in-app/socialIcons.js"; +export { socialIcons } from "../../react/core/utils/socialIcons.js"; diff --git a/packages/thirdweb/src/react/core/hooks/connection/ConnectButtonProps.ts b/packages/thirdweb/src/react/core/hooks/connection/ConnectButtonProps.ts index 254fe962f0f..1d29f36158e 100644 --- a/packages/thirdweb/src/react/core/hooks/connection/ConnectButtonProps.ts +++ b/packages/thirdweb/src/react/core/hooks/connection/ConnectButtonProps.ts @@ -4,10 +4,10 @@ import type { Account, Wallet } from "../../../../wallets/interfaces/wallet.js"; import type { SmartWalletOptions } from "../../../../wallets/smart/types.js"; import type { AppMetadata } from "../../../../wallets/types.js"; import type { NetworkSelectorProps } from "../../../web/ui/ConnectWallet/NetworkSelector.js"; -import type { SupportedTokens } from "../../../web/ui/ConnectWallet/defaultTokens.js"; import type { WelcomeScreen } from "../../../web/ui/ConnectWallet/screens/types.js"; import type { LocaleId } from "../../../web/ui/types.js"; import type { Theme } from "../../design-system/index.js"; +import type { SupportedTokens } from "../../utils/defaultTokens.js"; import type { SiweAuthOptions } from "../auth/useSiweAuth.js"; export type PayUIOptions = { @@ -699,10 +699,7 @@ export type ConnectButtonProps = { * /> * ``` */ - onDisconnect?: (info: { - wallet: Wallet; - account: Account; - }) => void; + onDisconnect?: (info: { wallet: Wallet; account: Account }) => void; /** * Configure options for WalletConnect diff --git a/packages/thirdweb/src/react/core/hooks/connection/types.ts b/packages/thirdweb/src/react/core/hooks/connection/types.ts index ca751fe1049..8c2175cb635 100644 --- a/packages/thirdweb/src/react/core/hooks/connection/types.ts +++ b/packages/thirdweb/src/react/core/hooks/connection/types.ts @@ -28,7 +28,7 @@ export type AutoConnectProps = { * } * ``` */ - wallets: Wallet[]; + wallets?: Wallet[]; /** * A client is the entry point to the thirdweb SDK. diff --git a/packages/thirdweb/src/react/core/hooks/transaction/useSendTransaction.ts b/packages/thirdweb/src/react/core/hooks/transaction/useSendTransaction.ts index 22e37903846..c762618cee2 100644 --- a/packages/thirdweb/src/react/core/hooks/transaction/useSendTransaction.ts +++ b/packages/thirdweb/src/react/core/hooks/transaction/useSendTransaction.ts @@ -11,10 +11,10 @@ import { type GetWalletBalanceResult, getWalletBalance, } from "../../../../wallets/utils/getWalletBalance.js"; -import type { SupportedTokens } from "../../../web/ui/ConnectWallet/defaultTokens.js"; import { fetchBuySupportedDestinations } from "../../../web/ui/ConnectWallet/screens/Buy/swap/useSwapSupportedChains.js"; import type { LocaleId } from "../../../web/ui/types.js"; import type { Theme } from "../../design-system/index.js"; +import type { SupportedTokens } from "../../utils/defaultTokens.js"; /** * Configuration for the "Pay Modal" that opens when the user doesn't have enough funds to send a transaction. diff --git a/packages/thirdweb/src/react/core/hooks/wallets/useAutoConnect.ts b/packages/thirdweb/src/react/core/hooks/wallets/useAutoConnect.ts index c1abc1e6669..e3b39cd9537 100644 --- a/packages/thirdweb/src/react/core/hooks/wallets/useAutoConnect.ts +++ b/packages/thirdweb/src/react/core/hooks/wallets/useAutoConnect.ts @@ -15,7 +15,7 @@ import { useSetActiveWalletConnectionStatusCore } from "./useSetActiveWalletConn export function useAutoConnectCore( manager: ConnectionManager, storage: AsyncStorage, - props: AutoConnectProps, + props: AutoConnectProps & { wallets: Wallet[] }, getInstalledWallets?: () => Wallet[], ) { const setConnectionStatus = useSetActiveWalletConnectionStatusCore(manager); diff --git a/packages/thirdweb/src/react/core/hooks/wallets/useSendToken.ts b/packages/thirdweb/src/react/core/hooks/wallets/useSendToken.ts new file mode 100644 index 00000000000..6983dda567f --- /dev/null +++ b/packages/thirdweb/src/react/core/hooks/wallets/useSendToken.ts @@ -0,0 +1,94 @@ +import { useMutation } from "@tanstack/react-query"; +import type { ThirdwebClient } from "../../../../client/client.js"; +import { getContract } from "../../../../contract/contract.js"; +import { resolveAddress } from "../../../../extensions/ens/resolve-address.js"; +import { transfer } from "../../../../extensions/erc20/write/transfer.js"; +import { sendTransaction } from "../../../../transaction/actions/send-transaction.js"; +import { prepareTransaction } from "../../../../transaction/prepare-transaction.js"; +import { isAddress } from "../../../../utils/address.js"; +import { toWei } from "../../../../utils/units.js"; +import type { Wallet } from "../../../../wallets/interfaces/wallet.js"; + +/** + * Send Native or ERC20 tokens from active wallet to given address. + * @internal + */ +export function useSendTokenCore(client: ThirdwebClient, wallet?: Wallet) { + return useMutation({ + async mutationFn(option: { + tokenAddress?: string; + receiverAddress: string; + amount: string; + }) { + const { tokenAddress, receiverAddress, amount } = option; + const activeChain = wallet?.getChain(); + const account = wallet?.getAccount(); + + // state validation + if (!activeChain) { + throw new Error("No active chain"); + } + if (!account) { + throw new Error("No active account"); + } + + // input validation + if ( + !receiverAddress || + (!receiverAddress.endsWith(".eth") && !isAddress(receiverAddress)) + ) { + throw new Error("Invalid address"); + } + + if (!amount || Number.isNaN(Number(amount)) || Number(amount) < 0) { + throw new Error("Invalid amount"); + } + + let to = receiverAddress; + // resolve ENS if needed + try { + to = await resolveAddress({ + client, + name: receiverAddress, + }); + } catch (e) { + throw new Error("Failed to resolve address"); + } + + // native token transfer + if (!tokenAddress) { + const sendNativeTokenTx = prepareTransaction({ + chain: activeChain, + client, + to, + value: toWei(amount), + }); + + await sendTransaction({ + transaction: sendNativeTokenTx, + account, + }); + } + + // erc20 token transfer + else { + const contract = getContract({ + address: tokenAddress, + client, + chain: activeChain, + }); + + const tx = transfer({ + amount, + contract, + to, + }); + + await sendTransaction({ + transaction: tx, + account, + }); + } + }, + }); +} diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/defaultTokens.ts b/packages/thirdweb/src/react/core/utils/defaultTokens.ts similarity index 98% rename from packages/thirdweb/src/react/web/ui/ConnectWallet/defaultTokens.ts rename to packages/thirdweb/src/react/core/utils/defaultTokens.ts index c7d1ce31515..a76d320a105 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/defaultTokens.ts +++ b/packages/thirdweb/src/react/core/utils/defaultTokens.ts @@ -5,7 +5,7 @@ export type TokenInfo = { icon?: string; }; -const wrappedEthIcon = +export const wrappedEthIcon = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTAwIiBoZWlnaHQ9IjI1MDAiIHZpZXdCb3g9IjAgMCAzMiAzMiI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIxNiIgZmlsbD0iIzYyN0VFQSIvPjxnIGZpbGw9IiNGRkYiIGZpbGwtcnVsZT0ibm9uemVybyI+PHBhdGggZmlsbC1vcGFjaXR5PSIuNjAyIiBkPSJNMTYuNDk4IDR2OC44N2w3LjQ5NyAzLjM1eiIvPjxwYXRoIGQ9Ik0xNi40OTggNEw5IDE2LjIybDcuNDk4LTMuMzV6Ii8+PHBhdGggZmlsbC1vcGFjaXR5PSIuNjAyIiBkPSJNMTYuNDk4IDIxLjk2OHY2LjAyN0wyNCAxNy42MTZ6Ii8+PHBhdGggZD0iTTE2LjQ5OCAyNy45OTV2LTYuMDI4TDkgMTcuNjE2eiIvPjxwYXRoIGZpbGwtb3BhY2l0eT0iLjIiIGQ9Ik0xNi40OTggMjAuNTczbDcuNDk3LTQuMzUzLTcuNDk3LTMuMzQ4eiIvPjxwYXRoIGZpbGwtb3BhY2l0eT0iLjYwMiIgZD0iTTkgMTYuMjJsNy40OTggNC4zNTN2LTcuNzAxeiIvPjwvZz48L2c+PC9zdmc+"; const tetherUsdIcon = @@ -88,20 +88,6 @@ export const defaultTokens: SupportedTokens = { icon: maticIcon, }, ], - "5": [ - { - address: "0xb4fbf271143f4fbf7b91a5ded31805e42b2208d6", - name: "Wrapped Ether", - symbol: "WETH", - icon: wrappedEthIcon, - }, - { - address: "0x07865c6E87B9F70255377e024ace6630C1Eaa37F", - name: "USD Coin", - symbol: "USDC", - icon: usdcIcon, - }, - ], "10": [ { address: "0x4200000000000000000000000000000000000006", @@ -327,4 +313,13 @@ export const defaultTokens: SupportedTokens = { icon: usdcIcon, }, ], + // Base sepolia + "84532": [ + { + address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + name: "USD Coin", + symbol: "USDC", + icon: usdcIcon, + }, + ], }; diff --git a/packages/thirdweb/src/react/web/utils/isSmartWallet.ts b/packages/thirdweb/src/react/core/utils/isSmartWallet.ts similarity index 100% rename from packages/thirdweb/src/react/web/utils/isSmartWallet.ts rename to packages/thirdweb/src/react/core/utils/isSmartWallet.ts diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/icons/dataUris.ts b/packages/thirdweb/src/react/core/utils/socialIcons.ts similarity index 54% rename from packages/thirdweb/src/react/web/ui/ConnectWallet/icons/dataUris.ts rename to packages/thirdweb/src/react/core/utils/socialIcons.ts index 8240463cfd1..02d624d37ff 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/icons/dataUris.ts +++ b/packages/thirdweb/src/react/core/utils/socialIcons.ts @@ -1,3 +1,27 @@ +// TODO make the social icons usable in RN too +export const googleIconUri = + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDUuNiIgaGVpZ2h0PSI3MjAiIHZpZXdCb3g9IjAgMCAxODYuNjkgMTkwLjUiIHhtbG5zOnY9Imh0dHBzOi8vdmVjdGEuaW8vbmFubyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTE4NC41ODMgNzY1LjE3MSkiPjxwYXRoIGNsaXAtcGF0aD0ibm9uZSIgbWFzaz0ibm9uZSIgZD0iTS0xMDg5LjMzMy02ODcuMjM5djM2Ljg4OGg1MS4yNjJjLTIuMjUxIDExLjg2My05LjAwNiAyMS45MDgtMTkuMTM3IDI4LjY2MmwzMC45MTMgMjMuOTg2YzE4LjAxMS0xNi42MjUgMjguNDAyLTQxLjA0NCAyOC40MDItNzAuMDUyIDAtNi43NTQtLjYwNi0xMy4yNDktMS43MzItMTkuNDgzeiIgZmlsbD0iIzQyODVmNCIvPjxwYXRoIGNsaXAtcGF0aD0ibm9uZSIgbWFzaz0ibm9uZSIgZD0iTS0xMTQyLjcxNC02NTEuNzkxbC02Ljk3MiA1LjMzNy0yNC42NzkgMTkuMjIzaDBjMTUuNjczIDMxLjA4NiA0Ny43OTYgNTIuNTYxIDg1LjAzIDUyLjU2MSAyNS43MTcgMCA0Ny4yNzgtOC40ODYgNjMuMDM4LTIzLjAzM2wtMzAuOTEzLTIzLjk4NmMtOC40ODYgNS43MTUtMTkuMzEgOS4xNzktMzIuMTI1IDkuMTc5LTI0Ljc2NSAwLTQ1LjgwNi0xNi43MTItNTMuMzQtMzkuMjI2eiIgZmlsbD0iIzM0YTg1MyIvPjxwYXRoIGNsaXAtcGF0aD0ibm9uZSIgbWFzaz0ibm9uZSIgZD0iTS0xMTc0LjM2NS03MTIuNjFjLTYuNDk0IDEyLjgxNS0xMC4yMTcgMjcuMjc2LTEwLjIxNyA0Mi42ODlzMy43MjMgMjkuODc0IDEwLjIxNyA0Mi42ODljMCAuMDg2IDMxLjY5My0yNC41OTIgMzEuNjkzLTI0LjU5Mi0xLjkwNS01LjcxNS0zLjAzMS0xMS43NzYtMy4wMzEtMTguMDk4czEuMTI2LTEyLjM4MyAzLjAzMS0xOC4wOTh6IiBmaWxsPSIjZmJiYzA1Ii8+PHBhdGggZD0iTS0xMDg5LjMzMy03MjcuMjQ0YzE0LjAyOCAwIDI2LjQ5NyA0Ljg0OSAzNi40NTUgMTQuMjAxbDI3LjI3Ni0yNy4yNzZjLTE2LjUzOS0xNS40MTMtMzguMDEzLTI0Ljg1Mi02My43MzEtMjQuODUyLTM3LjIzNCAwLTY5LjM1OSAyMS4zODgtODUuMDMyIDUyLjU2MWwzMS42OTIgMjQuNTkyYzcuNTMzLTIyLjUxNCAyOC41NzUtMzkuMjI2IDUzLjM0LTM5LjIyNnoiIGZpbGw9IiNlYTQzMzUiIGNsaXAtcGF0aD0ibm9uZSIgbWFzaz0ibm9uZSIvPjwvZz48L3N2Zz4="; +export const facebookIconUri = + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGRhdGEtbmFtZT0iRWJlbmUgMSIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgaWQ9ImZhY2Vib29rLWxvZ28tMjAxOSI+PHBhdGggZmlsbD0iIzE4NzdmMiIgZD0iTTEwMjQsNTEyQzEwMjQsMjI5LjIzMDE2LDc5NC43Njk3OCwwLDUxMiwwUzAsMjI5LjIzMDE2LDAsNTEyYzAsMjU1LjU1NCwxODcuMjMxLDQ2Ny4zNzAxMiw0MzIsNTA1Ljc3Nzc3VjY2MEgzMDJWNTEySDQzMlYzOTkuMkM0MzIsMjcwLjg3OTgyLDUwOC40Mzg1NCwyMDAsNjI1LjM4OTIyLDIwMCw2ODEuNDA3NjUsMjAwLDc0MCwyMTAsNzQwLDIxMFYzMzZINjc1LjQzNzEzQzYxMS44MzUwOCwzMzYsNTkyLDM3NS40NjY2Nyw1OTIsNDE1Ljk1NzI4VjUxMkg3MzRMNzExLjMsNjYwSDU5MnYzNTcuNzc3NzdDODM2Ljc2OSw5NzkuMzcwMTIsMTAyNCw3NjcuNTU0LDEwMjQsNTEyWiI+PC9wYXRoPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik03MTEuMyw2NjAsNzM0LDUxMkg1OTJWNDE1Ljk1NzI4QzU5MiwzNzUuNDY2NjcsNjExLjgzNTA4LDMzNiw2NzUuNDM3MTMsMzM2SDc0MFYyMTBzLTU4LjU5MjM1LTEwLTExNC42MTA3OC0xMEM1MDguNDM4NTQsMjAwLDQzMiwyNzAuODc5ODIsNDMyLDM5OS4yVjUxMkgzMDJWNjYwSDQzMnYzNTcuNzc3NzdhNTE3LjM5NjE5LDUxNy4zOTYxOSwwLDAsMCwxNjAsMFY2NjBaIj48L3BhdGg+PC9zdmc+"; +export const twitterIconUri = + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiIgaWQ9InR3aXR0ZXIiPjxwYXRoIGZpbGw9IiMwM0E5RjQiIGQ9Ik0xNiAzLjUzOWE2LjgzOSA2LjgzOSAwIDAgMS0xLjg5LjUxOCAzLjI2MiAzLjI2MiAwIDAgMCAxLjQ0My0xLjgxMyA2LjU1NSA2LjU1NSAwIDAgMS0yLjA4Ljc5NCAzLjI4IDMuMjggMCAwIDAtNS42NzQgMi4yNDNjMCAuMjYuMDIyLjUxLjA3Ni43NDhhOS4yODQgOS4yODQgMCAwIDEtNi43NjEtMy40MzEgMy4yODUgMy4yODUgMCAwIDAgMS4wMDggNC4zODRBMy4yNCAzLjI0IDAgMCAxIC42NCA2LjU3OHYuMDM2YTMuMjk1IDMuMjk1IDAgMCAwIDIuNjI4IDMuMjIzIDMuMjc0IDMuMjc0IDAgMCAxLS44Ni4xMDggMi45IDIuOSAwIDAgMS0uNjIxLS4wNTYgMy4zMTEgMy4zMTEgMCAwIDAgMy4wNjUgMi4yODUgNi41OSA2LjU5IDAgMCAxLTQuMDY3IDEuMzk5Yy0uMjY5IDAtLjUyNy0uMDEyLS43ODUtLjA0NUE5LjIzNCA5LjIzNCAwIDAgMCA1LjAzMiAxNWM2LjAzNiAwIDkuMzM2LTUgOS4zMzYtOS4zMzQgMC0uMTQ1LS4wMDUtLjI4NS0uMDEyLS40MjRBNi41NDQgNi41NDQgMCAwIDAgMTYgMy41Mzl6Ij48L3BhdGg+PC9zdmc+"; +export const githubIconUri = + "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzEwXzIpIj4KPHBhdGggZD0iTTcuOTk5IDBDMy41ODIwMSAwIDQuNjE2NDhlLTA2IDMuNTk2IDQuNjE2NDhlLTA2IDguMDMyQy0wLjAwMTggOS43MTU1NSAwLjUyNTUxOSAxMS4zNTcxIDEuNTA3NDQgMTIuNzI0NkMyLjQ4OTM1IDE0LjA5MjIgMy44NzYyMSAxNS4xMTY2IDUuNDcyIDE1LjY1M0M1Ljg3MiAxNS43MjcgNi4wMTggMTUuNDc5IDYuMDE4IDE1LjI2NkM2LjAxOCAxNS4wNzUgNi4wMTEgMTQuNTcgNi4wMDcgMTMuOUMzLjc4MiAxNC4zODUgMy4zMTIgMTIuODIzIDMuMzEyIDEyLjgyM0MyLjk0OSAxMS44OTUgMi40MjQgMTEuNjQ4IDIuNDI0IDExLjY0OEMxLjY5NyAxMS4xNSAyLjQ3OCAxMS4xNiAyLjQ3OCAxMS4xNkMzLjI4MSAxMS4yMTcgMy43MDMgMTEuOTg4IDMuNzAzIDExLjk4OEM0LjQxNyAxMy4yMTUgNS41NzYgMTIuODYxIDYuMDMyIDEyLjY1NUM2LjEwNCAxMi4xMzYgNi4zMTEgMTEuNzgyIDYuNTQgMTEuNTgxQzQuNzY0IDExLjM3OCAyLjg5NiAxMC42ODkgMi44OTYgNy42MTJDMi44OTYgNi43MzUgMy4yMDggNi4wMTggMy43MiA1LjQ1NkMzLjYzNyA1LjI1MyAzLjM2MyA0LjQzNiAzLjc5OCAzLjMzMUMzLjc5OCAzLjMzMSA0LjQ3IDMuMTE1IDUuOTk4IDQuMTU0QzYuNjUwNzUgMy45NzU2MSA3LjMyNDMyIDMuODg0ODIgOC4wMDEwMSAzLjg4NEM4LjY3NzcyIDMuODg1MzQgOS4zNTEyNiAzLjk3NjQ3IDEwLjAwNCA0LjE1NUMxMS41MzEgMy4xMTYgMTIuMjAyIDMuMzMyIDEyLjIwMiAzLjMzMkMxMi42MzggNC40MzggMTIuMzY0IDUuMjU0IDEyLjI4MiA1LjQ1N0MxMi43OTUgNi4wMTkgMTMuMTA0IDYuNzM2IDEzLjEwNCA3LjYxM0MxMy4xMDQgMTAuNjk4IDExLjIzNCAxMS4zNzcgOS40NTIgMTEuNTc2QzkuNzM5IDExLjgyNCA5Ljk5NSAxMi4zMTQgOS45OTUgMTMuMDYzQzkuOTk1IDE0LjEzNyA5Ljk4NSAxNS4wMDMgOS45ODUgMTUuMjY2QzkuOTg1IDE1LjQ4MSAxMC4xMjkgMTUuNzMxIDEwLjUzNSAxNS42NTJDMTIuMTI5MiAxNS4xMTQzIDEzLjUxNDQgMTQuMDg5NSAxNC40OTQ5IDEyLjcyMjNDMTUuNDc1NSAxMS4zNTUxIDE2LjAwMTkgOS43MTQ0OCAxNiA4LjAzMkMxNiAzLjU5NiAxMi40MTggMCA3Ljk5OSAwWiIgZmlsbD0iIzhCOEI4QiIvPgo8L2c+CjxkZWZzPgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzEwXzIiPgo8cmVjdCB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9IndoaXRlIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg=="; +export const appleIconUri = + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDM4IiBoZWlnaHQ9IjI1MDAiIHZpZXdCb3g9IjAgMCA0OTYuMjU1IDYwOC43MjgiIGlkPSJhcHBsZSI+PHBhdGggZmlsbD0iIzk5OSIgZD0iTTI3My44MSA1Mi45NzNDMzEzLjgwNi4yNTcgMzY5LjQxIDAgMzY5LjQxIDBzOC4yNzEgNDkuNTYyLTMxLjQ2MyA5Ny4zMDZjLTQyLjQyNiA1MC45OC05MC42NDkgNDIuNjM4LTkwLjY0OSA0Mi42MzhzLTkuMDU1LTQwLjA5NCAyNi41MTItODYuOTcxek0yNTIuMzg1IDE3NC42NjJjMjAuNTc2IDAgNTguNzY0LTI4LjI4NCAxMDguNDcxLTI4LjI4NCA4NS41NjIgMCAxMTkuMjIyIDYwLjg4MyAxMTkuMjIyIDYwLjg4M3MtNjUuODMzIDMzLjY1OS02NS44MzMgMTE1LjMzMWMwIDkyLjEzMyA4Mi4wMSAxMjMuODg1IDgyLjAxIDEyMy44ODVzLTU3LjMyOCAxNjEuMzU3LTEzNC43NjIgMTYxLjM1N2MtMzUuNTY1IDAtNjMuMjE1LTIzLjk2Ny0xMDAuNjg4LTIzLjk2Ny0zOC4xODggMC03Ni4wODQgMjQuODYxLTEwMC43NjYgMjQuODYxQzg5LjMzIDYwOC43MyAwIDQ1NS42NjYgMCAzMzIuNjI4YzAtMTIxLjA1MiA3NS42MTItMTg0LjU1NCAxNDYuNTMzLTE4NC41NTQgNDYuMTA1IDAgODEuODgzIDI2LjU4OCAxMDUuODUyIDI2LjU4OHoiPjwvcGF0aD48L3N2Zz4="; +export const linkedinIconUri = + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NCIgaGVpZ2h0PSI0MCIgaWQ9ImxpbmtlZGluIj48cGF0aCBmaWxsPSIjMDA3RUJCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00NCA0MGgtOS43MjVWMjUuOTM4YzAtMy42OC0xLjUyLTYuMTkzLTQuODY2LTYuMTkzLTIuNTU4IDAtMy45ODEgMS42OTYtNC42NDMgMy4zMy0uMjQ5LjU4Ni0uMjEgMS40MDMtLjIxIDIuMjJWNDBoLTkuNjM0cy4xMjQtMjQuOTA5IDAtMjcuMTczaDkuNjM0djQuMjY1Yy41Ny0xLjg2NSAzLjY0OC00LjUyNiA4LjU2LTQuNTI2QzM5LjIxMSAxMi41NjYgNDQgMTYuNDc0IDQ0IDI0Ljg5MVY0MHpNNS4xOCA5LjQyOGgtLjA2M0MyLjAxMyA5LjQyOCAwIDcuMzUxIDAgNC43MTggMCAyLjAzNCAyLjA3MiAwIDUuMjM5IDBjMy4xNjQgMCA1LjExIDIuMDI5IDUuMTcxIDQuNzEgMCAyLjYzMy0yLjAwNyA0LjcxOC01LjIzIDQuNzE4em0tNC4wNyAzLjM5OWg4LjU3NlY0MEgxLjExVjEyLjgyN3oiPjwvcGF0aD48L3N2Zz4="; +export const bitbucketIconUri = + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgaWQ9ImJpdGJ1Y2tldCI+PHBhdGggZmlsbD0iIzI2ODBGOCIgZD0iTTQuMjk3IDIzaDE1LjY1OWEuNzc2Ljc3NiAwIDAgMCAuNzY5LS42NTdMMjMuOTkgMS45MTZhLjc4Ljc4IDAgMCAwLS42MzUtLjg5NyAxLjEzIDEuMTMgMCAwIDAtLjEzNC0uMDA5TC43NzkgMUEuNzc1Ljc3NSAwIDAgMCAwIDEuNzc1YzAgLjA0NC4wMDUuMDkzLjAwOS4xMzdsMy4yNjUgMjAuMTk2Yy4wODIuNTA5LjUxNS44ODcgMS4wMjMuODkyek0xNS43MzYgOC4zOTFsLTEuMjExIDcuMjA1aC01TDguMTczIDguMzkxaDcuNTYzeiI+PC9wYXRoPjwvc3ZnPg=="; +export const gitlabIconUri = + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTAwIiBoZWlnaHQ9IjIzMDUiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaW5ZTWluIG1lZXQiIHZpZXdCb3g9IjAgMCAyNTYgMjM2IiBpZD0iZ2l0bGFiIj48cGF0aCBmaWxsPSIjRTI0MzI5IiBkPSJNMTI4LjA3NSAyMzYuMDc1bDQ3LjEwNC0xNDQuOTdIODAuOTdsNDcuMTA0IDE0NC45N3oiPjwvcGF0aD48cGF0aCBmaWxsPSIjRkM2RDI2IiBkPSJNMTI4LjA3NSAyMzYuMDc0TDgwLjk3IDkxLjEwNEgxNC45NTZsMTEzLjExOSAxNDQuOTd6Ij48L3BhdGg+PHBhdGggZmlsbD0iI0ZDQTMyNiIgZD0iTTE0Ljk1NiA5MS4xMDRMLjY0MiAxMzUuMTZhOS43NTIgOS43NTIgMCAwIDAgMy41NDIgMTAuOTAzbDEyMy44OTEgOTAuMDEyLTExMy4xMi0xNDQuOTd6Ij48L3BhdGg+PHBhdGggZmlsbD0iI0UyNDMyOSIgZD0iTTE0Ljk1NiA5MS4xMDVIODAuOTdMNTIuNjAxIDMuNzljLTEuNDYtNC40OTMtNy44MTYtNC40OTItOS4yNzUgMGwtMjguMzcgODcuMzE1eiI+PC9wYXRoPjxwYXRoIGZpbGw9IiNGQzZEMjYiIGQ9Ik0xMjguMDc1IDIzNi4wNzRsNDcuMTA0LTE0NC45N2g2Ni4wMTVsLTExMy4xMiAxNDQuOTd6Ij48L3BhdGg+PHBhdGggZmlsbD0iI0ZDQTMyNiIgZD0iTTI0MS4xOTQgOTEuMTA0bDE0LjMxNCA0NC4wNTZhOS43NTIgOS43NTIgMCAwIDEtMy41NDMgMTAuOTAzbC0xMjMuODkgOTAuMDEyIDExMy4xMTktMTQ0Ljk3eiI+PC9wYXRoPjxwYXRoIGZpbGw9IiNFMjQzMjkiIGQ9Ik0yNDEuMTk0IDkxLjEwNWgtNjYuMDE1bDI4LjM3LTg3LjMxNWMxLjQ2LTQuNDkzIDcuODE2LTQuNDkyIDkuMjc1IDBsMjguMzcgODcuMzE1eiI+PC9wYXRoPjwvc3ZnPg=="; +export const twitchIconUri = + "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgdmlld0JveD0iMCAwIDExMS43ODY2NyAxMjcuMzg2NjciCiAgIGhlaWdodD0iMTI3LjM4NjY3IgogICB3aWR0aD0iMTExLjc4NjY3IgogICB4bWw6c3BhY2U9InByZXNlcnZlIgogICB2ZXJzaW9uPSIxLjEiCiAgIGlkPSJzdmczMzU1IgogICBzb2RpcG9kaTpkb2NuYW1lPSJUd2l0Y2hfbG9nby5zdmciCiAgIGlua3NjYXBlOnZlcnNpb249IjEuMS4xICgzYmY1YWUwZDI1LCAyMDIxLTA5LTIwKSIKICAgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiCiAgIHhtbG5zOnNvZGlwb2RpPSJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZCIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcwogICBpZD0iZGVmczI5Ij4KICAgIAogICAgCiAgPC9kZWZzPjxzb2RpcG9kaTpuYW1lZHZpZXcKICAgaWQ9Im5hbWVkdmlldzI3IgogICBwYWdlY29sb3I9IiNmZmZmZmYiCiAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICBib3JkZXJvcGFjaXR5PSIxLjAiCiAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiCiAgIGlua3NjYXBlOnBhZ2VjaGVja2VyYm9hcmQ9IjAiCiAgIHNob3dncmlkPSJmYWxzZSIKICAgaW5rc2NhcGU6em9vbT0iNC4xOTkyMjg0IgogICBpbmtzY2FwZTpjeD0iLTUwLjYwNDUzNSIKICAgaW5rc2NhcGU6Y3k9IjE0MC4zODI5MyIKICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIyNTYwIgogICBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSIxMzg3IgogICBpbmtzY2FwZTp3aW5kb3cteD0iMTkxMiIKICAgaW5rc2NhcGU6d2luZG93LXk9Ii04IgogICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIgogICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmczMzU1IiAvPgogIDxnCiAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMzMzMzMzMywwLDAsLTEuMzMzMzMzMywxMDEuMzkzMzMsNjcuNTg5MzMyKSIKICAgaWQ9ImczMzY1Ij4KICAgICAgPHBhdGgKICAgaWQ9InBhdGgzMzY3IgogICBzdHlsZT0iZmlsbDojNjQ0MWE1O2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpldmVub2RkO3N0cm9rZTpub25lIgogICBkPSJtIDAsMCAtMTMuNjUyLC0xMy42NTEgaCAtMjEuNDQ1IGwgLTExLjY5OSwtMTEuNjk3IHYgMTEuNjk3IEggLTY0LjM0NCBWIDQyLjg5MyBIIDAgWiBtIC03Mi4xNDYsNTAuNjkyIC0zLjg5OSwtMTUuNTk5IHYgLTcwLjE5IGggMTcuNTUgdiAtOS43NTEgaCA5Ljc0NiBsIDkuNzUyLDkuNzUxIGggMTUuNTk2IEwgNy43OTUsLTMuOTA1IHYgNTQuNTk3IHoiIC8+CiAgICA8L2c+PHBhdGgKICAgaWQ9InBhdGgzMzY5IgogICBzdHlsZT0iZmlsbDojNjQ0MWE1O2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpldmVub2RkO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxLjMzMzMzIgogICBkPSJtIDQ0LjE5NzMzMSw2Mi4zOTQyNjYgaCAxMC4zOTg2NyBWIDMxLjE5MjkzMyBoIC0xMC4zOTg2NyB6IG0gMjguNTk0NjcsMCBoIDEwLjM5ODY2IFYgMzEuMTkyOTMzIGggLTEwLjM5ODY2IHoiIC8+Cjwvc3ZnPgo="; +export const discordIconUri = + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDEwMCAxMDAiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBpZD0iZGlzY29yZCI+PHBhdGggZmlsbD0iIzY2NjVkMiIgZD0iTTg1LjIyLDI0Ljk1OGMtMTEuNDU5LTguNTc1LTIyLjQzOC04LjMzNC0yMi40MzgtOC4zMzRsLTEuMTIyLDEuMjgyCgkJCQljMTMuNjIzLDQuMDg3LDE5Ljk1NCwxMC4wOTcsMTkuOTU0LDEwLjA5N2MtMTkuNDkxLTEwLjczMS00NC4zMTctMTAuNjU0LTY0LjU5LDBjMCwwLDYuNTcxLTYuMzMxLDIwLjk5Ni0xMC40MThsLTAuODAxLTAuOTYyCgkJCQljMCwwLTEwLjg5OS0wLjI0LTIyLjQzOCw4LjMzNGMwLDAtMTEuNTQsMjAuNzU1LTExLjU0LDQ2LjMxOWMwLDAsNi43MzIsMTEuNTQsMjQuNDQyLDEyLjEwMWMwLDAsMi45NjUtMy41MjYsNS4zNjktNi41NzEKCQkJCWMtMTAuMTc3LTMuMDQ1LTE0LjAyNC05LjM3Ni0xNC4wMjQtOS4zNzZjNi4zOTQsNC4wMDEsMTIuODU5LDYuNTA1LDIwLjkxNiw4LjA5NGMxMy4xMDgsMi42OTgsMjkuNDEzLTAuMDc2LDQxLjU5MS04LjA5NAoJCQkJYzAsMC00LjAwNyw2LjQ5MS0xNC41MDUsOS40NTZjMi40MDQsMi45NjUsNS4yODksNi40MTEsNS4yODksNi40MTFjMTcuNzEtMC41NjEsMjQuNDQxLTEyLjEwMSwyNC40NDEtMTIuMDIKCQkJCUM5Ni43NTksNDUuNzEzLDg1LjIyLDI0Ljk1OCw4NS4yMiwyNC45NTh6IE0zNS4wNTUsNjMuODI0Yy00LjQ4OCwwLTguMTc0LTMuOTI3LTguMTc0LTguODE1CgkJCQljMC4zMjgtMTEuNzA3LDE2LjEwMi0xMS42NzEsMTYuMzQ4LDBDNDMuMjI5LDU5Ljg5NywzOS42MjIsNjMuODI0LDM1LjA1NSw2My44MjR6IE02NC4zMDQsNjMuODI0CgkJCQljLTQuNDg4LDAtOC4xNzQtMy45MjctOC4xNzQtOC44MTVjMC4zNi0xMS42ODQsMTUuOTM3LTExLjY4OSwxNi4zNDgsMEM3Mi40NzgsNTkuODk3LDY4Ljg3Miw2My44MjQsNjQuMzA0LDYzLjgyNHoiPjwvcGF0aD48L3N2Zz4="; +export const microsoftIconUri = + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciICB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxwYXRoIGZpbGw9IiNmZjU3MjIiIGQ9Ik02IDZIMjJWMjJINnoiIHRyYW5zZm9ybT0icm90YXRlKC0xODAgMTQgMTQpIi8+PHBhdGggZmlsbD0iIzRjYWY1MCIgZD0iTTI2IDZINDJWMjJIMjZ6IiB0cmFuc2Zvcm09InJvdGF0ZSgtMTgwIDM0IDE0KSIvPjxwYXRoIGZpbGw9IiNmZmMxMDciIGQ9Ik0yNiAyNkg0MlY0MkgyNnoiIHRyYW5zZm9ybT0icm90YXRlKC0xODAgMzQgMzQpIi8+PHBhdGggZmlsbD0iIzAzYTlmNCIgZD0iTTYgMjZIMjJWNDJINnoiIHRyYW5zZm9ybT0icm90YXRlKC0xODAgMTQgMzQpIi8+PC9zdmc+"; + export const emailIcon = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEzLjMzMzUgMi42NjY1SDIuNjY2ODNDMS45MzA0NSAyLjY2NjUgMS4zMzM1IDMuMjYzNDYgMS4zMzM1IDMuOTk5ODRWMTEuOTk5OEMxLjMzMzUgMTIuNzM2MiAxLjkzMDQ1IDEzLjMzMzIgMi42NjY4MyAxMy4zMzMySDEzLjMzMzVDMTQuMDY5OSAxMy4zMzMyIDE0LjY2NjggMTIuNzM2MiAxNC42NjY4IDExLjk5OThWMy45OTk4NEMxNC42NjY4IDMuMjYzNDYgMTQuMDY5OSAyLjY2NjUgMTMuMzMzNSAyLjY2NjVaIiBzdHJva2U9IiMzMzg1RkYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMTQuNjY2OCA0LjY2NjVMOC42ODY4MyA4LjQ2NjVDOC40ODEwMSA4LjU5NTQ1IDguMjQzMDQgOC42NjM4NCA4LjAwMDE2IDguNjYzODRDNy43NTcyOCA4LjY2Mzg0IDcuNTE5MzEgOC41OTU0NSA3LjMxMzUgOC40NjY1TDEuMzMzNSA0LjY2NjUiIHN0cm9rZT0iIzMzODVGRiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo="; @@ -18,3 +42,9 @@ export const genericWalletIcon = export const passkeyIcon = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzU2MzlfMzIpIj4KPHBhdGggZD0iTTcuOTk5NTkgNi42NjY1QzcuNjQ1OTYgNi42NjY1IDcuMzA2ODMgNi44MDY5OCA3LjA1Njc4IDcuMDU3MDNDNi44MDY3MyA3LjMwNzA4IDYuNjY2MjUgNy42NDYyMiA2LjY2NjI1IDcuOTk5ODRDNi42NjYyNSA4LjY3OTg0IDYuNTk5NTkgOS42NzMxNyA2LjQ5MjkyIDEwLjY2NjUiIHN0cm9rZT0iIzMzODVGRiIgc3Ryb2tlLXdpZHRoPSIxLjI1NDkiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNOS4zMzI5MyA4Ljc0NjU4QzkuMzMyOTMgMTAuMzMzMiA5LjMzMjkzIDEyLjk5OTkgOC42NjYyNiAxNC42NjY2IiBzdHJva2U9IiMzMzg1RkYiIHN0cm9rZS13aWR0aD0iMS4yNTQ5IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTExLjUyNzMgMTQuMDEzM0MxMS42MDczIDEzLjYxMzMgMTEuODE0IDEyLjQ4IDExLjg2MDcgMTIiIHN0cm9rZT0iIzMzODVGRiIgc3Ryb2tlLXdpZHRoPSIxLjI1NDkiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMS4zMzM5OCA4LjAwMDE2QzEuMzMzOTggNi42MDA5NSAxLjc3NDIzIDUuMjM3MiAyLjU5MjM3IDQuMTAyMDlDMy40MTA1MSAyLjk2Njk5IDQuNTY1MDUgMi4xMTgwOCA1Ljg5MjQ3IDEuNjc1NjFDNy4yMTk4OCAxLjIzMzE0IDguNjUyODYgMS4yMTk1NCA5Ljk4ODQ0IDEuNjM2NzRDMTEuMzI0IDIuMDUzOTQgMTIuNDk0NSAyLjg4MDc5IDEzLjMzNCA0LjAwMDE2IiBzdHJva2U9IiMzMzg1RkYiIHN0cm9rZS13aWR0aD0iMS4yNTQ5IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTEuMzMzOTggMTAuNjY2NUgxLjMzOTE0IiBzdHJva2U9IiMzMzg1RkYiIHN0cm9rZS13aWR0aD0iMS4yNTQ5IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTE0LjUzMjcgMTAuNjY2NUMxNC42NjYgOS4zMzMxNyAxNC42MiA3LjA5NzE3IDE0LjUzMjcgNi42NjY1IiBzdHJva2U9IiMzMzg1RkYiIHN0cm9rZS13aWR0aD0iMS4yNTQ5IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTMuMzMzOTggMTIuOTk5OEMzLjY2NzMyIDExLjk5OTggNC4wMDA2NSA5Ljk5OTg0IDQuMDAwNjUgNy45OTk4NEMzLjk5OTk4IDcuNTQ1NzUgNC4wNzY2MyA3LjA5NDg2IDQuMjI3MzIgNi42NjY1IiBzdHJva2U9IiMzMzg1RkYiIHN0cm9rZS13aWR0aD0iMS4yNTQ5IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTUuNzY3MDkgMTQuNjY2OEM1LjkwNzA5IDE0LjIyNjggNi4wNjcwOSAxMy43ODY4IDYuMTQ3MDkgMTMuMzMzNSIgc3Ryb2tlPSIjMzM4NUZGIiBzdHJva2Utd2lkdGg9IjEuMjU0OSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik02IDQuNTMzNDZDNi42MDgyNyA0LjE4MjI4IDcuMjk4MjggMy45OTc0NSA4LjAwMDY0IDMuOTk3NTZDOC43MDMwMSAzLjk5NzY3IDkuMzkyOTYgNC4xODI3MiAxMC4wMDExIDQuNTM0MUMxMC42MDkzIDQuODg1NDggMTEuMTE0MiA1LjM5MDc5IDExLjQ2NTEgNS45OTkyM0MxMS44MTYgNi42MDc2NiAxMi4wMDA1IDcuMjk3NzYgMTIgOC4wMDAxMlY5LjMzMzQ2IiBzdHJva2U9IiMzMzg1RkYiIHN0cm9rZS13aWR0aD0iMS4yNTQ5IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF81NjM5XzMyIj4KPHJlY3Qgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2IiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="; + +export const socialIcons = { + google: googleIconUri, + apple: appleIconUri, + facebook: facebookIconUri, +}; diff --git a/packages/thirdweb/src/react/core/utils/wallet.ts b/packages/thirdweb/src/react/core/utils/wallet.ts index 016216caf46..b0a4e48d8e1 100644 --- a/packages/thirdweb/src/react/core/utils/wallet.ts +++ b/packages/thirdweb/src/react/core/utils/wallet.ts @@ -11,6 +11,9 @@ import type { WalletId } from "../../../wallets/wallet-types.js"; import { useWalletBalance } from "../hooks/others/useWalletBalance.js"; import { shortenString } from "./addresses.js"; +/** + * @internal + */ export function useConnectedWalletDetails( client: ThirdwebClient, walletChain: Chain | undefined, diff --git a/packages/thirdweb/src/react/native/hooks/wallets/useAutoConnect.ts b/packages/thirdweb/src/react/native/hooks/wallets/useAutoConnect.ts index 68beffab23e..4e631ad03b0 100644 --- a/packages/thirdweb/src/react/native/hooks/wallets/useAutoConnect.ts +++ b/packages/thirdweb/src/react/native/hooks/wallets/useAutoConnect.ts @@ -2,6 +2,7 @@ import { nativeLocalStorage } from "../../../../utils/storage/nativeStorage.js"; import type { AutoConnectProps } from "../../../core/hooks/connection/types.js"; import { useAutoConnectCore } from "../../../core/hooks/wallets/useAutoConnect.js"; import { connectionManager } from "../../index.js"; +import { getDefaultWallets } from "../../wallets/defaultWallets.js"; /** * Autoconnect the last previously connected wallet. @@ -23,5 +24,8 @@ import { connectionManager } from "../../index.js"; * @returns whether the auto connect was successful. */ export function useAutoConnect(props: AutoConnectProps) { - return useAutoConnectCore(connectionManager, nativeLocalStorage, props); + return useAutoConnectCore(connectionManager, nativeLocalStorage, { + ...props, + wallets: props.wallets || getDefaultWallets(props), + }); } diff --git a/packages/thirdweb/src/react/native/hooks/wallets/useSendToken.ts b/packages/thirdweb/src/react/native/hooks/wallets/useSendToken.ts new file mode 100644 index 00000000000..7c9d1728952 --- /dev/null +++ b/packages/thirdweb/src/react/native/hooks/wallets/useSendToken.ts @@ -0,0 +1,29 @@ +import type { ThirdwebClient } from "../../../../client/client.js"; +import { useSendTokenCore } from "../../../core/hooks/wallets/useSendToken.js"; +import { useActiveWallet } from "./useActiveWallet.js"; + +/** + * Send Native or ERC20 tokens from active wallet to given address. + * @example + * ```tsx + * const { mutate: sendToken } = useSendToken(client); + * + * // send native currency + * sendToken({ + * receiverAddress: "0x...", + * amount: "0.1", + * }); + * + * // send ERC20 + * sendToken({ + * tokenAddress, + * receiverAddress: "0x...", + * amount: "0.5", + * }); + * ``` + * @wallet + */ +export function useSendToken(client: ThirdwebClient) { + const wallet = useActiveWallet(); + return useSendTokenCore(client, wallet); +} diff --git a/packages/thirdweb/src/react/native/ui/components/Address.tsx b/packages/thirdweb/src/react/native/ui/components/Address.tsx new file mode 100644 index 00000000000..8aff84b3164 --- /dev/null +++ b/packages/thirdweb/src/react/native/ui/components/Address.tsx @@ -0,0 +1,55 @@ +import Clipboard from "@react-native-clipboard/clipboard"; +import { useEffect, useState } from "react"; +import { StyleSheet, TouchableOpacity } from "react-native"; +import type { Account } from "../../../../wallets/interfaces/wallet.js"; +import type { Theme } from "../../../core/design-system/index.js"; +import { spacing } from "../../design-system/index.js"; +import { CHECK, COPY_ICON } from "../icons/svgs.js"; +import { RNImage } from "./RNImage.js"; +import { ThemedText } from "./text.js"; + +export type AddressProps = { + account: Account; + theme: Theme; + addressOrENS: string; +}; + +export const Address = ({ account, theme, addressOrENS }: AddressProps) => { + const [copySuccess, setCopySuccess] = useState(false); + useEffect(() => { + if (copySuccess) { + setTimeout(() => { + setCopySuccess(false); + }, 2500); + } + }, [copySuccess]); + return ( + { + // @ts-ignore - missing native types + Clipboard.setString(account.address); + setCopySuccess(true); + }} + > + + {addressOrENS} + + + + ); +}; + +const styles = StyleSheet.create({ + addressContainer: { + flexDirection: "row", + gap: spacing.sm, + alignItems: "center", + }, +}); diff --git a/packages/thirdweb/src/react/native/ui/components/ChainIcon.tsx b/packages/thirdweb/src/react/native/ui/components/ChainIcon.tsx new file mode 100644 index 00000000000..9e4a7d4ef5d --- /dev/null +++ b/packages/thirdweb/src/react/native/ui/components/ChainIcon.tsx @@ -0,0 +1,41 @@ +import { useMemo } from "react"; +import type { Chain } from "../../../../chains/types.js"; +import type { ThirdwebClient } from "../../../../client/client.js"; +import { resolveScheme } from "../../../../utils/ipfs.js"; +import type { Theme } from "../../../core/design-system/index.js"; +import { useChainQuery } from "../../../core/hooks/others/useChainQuery.js"; +import { CHAIN_ICON } from "../icons/svgs.js"; +import { RNImage } from "./RNImage.js"; + +export type ChainIconProps = { + theme: Theme; + size: number; + client: ThirdwebClient; + chain?: Chain; +}; + +export const ChainIcon = (props: ChainIconProps) => { + const chainQuery = useChainQuery(props.chain); + const data = useMemo(() => { + const url = chainQuery?.data?.icon?.url; + if (!url) { + return CHAIN_ICON; + } + try { + return resolveScheme({ + uri: url, + client: props.client, + }); + } catch { + return CHAIN_ICON; + } + }, [props, chainQuery?.data?.icon?.url]); + return ( + + ); +}; diff --git a/packages/thirdweb/src/react/native/ui/components/Header.tsx b/packages/thirdweb/src/react/native/ui/components/Header.tsx new file mode 100644 index 00000000000..10f632963f8 --- /dev/null +++ b/packages/thirdweb/src/react/native/ui/components/Header.tsx @@ -0,0 +1,81 @@ +import { StyleSheet, TouchableOpacity, View } from "react-native"; +import type { Theme } from "../../../core/design-system/index.js"; +import { spacing } from "../../design-system/index.js"; +import { BACK_ICON, CLOSE_ICON } from "../icons/svgs.js"; +import { RNImage } from "./RNImage.js"; +import { ThemedText } from "./text.js"; + +export type ContainerType = "modal" | "embed"; + +export function Header({ + theme, + title, + onClose, + onBack, + containerType, +}: { + theme: Theme; + title?: string; + onClose?: () => void; + onBack?: () => void; + containerType: ContainerType; +}) { + if (containerType === "embed") { + return onBack ? ( + + + + Back + + + ) : null; + } + + return ( + + {onBack && ( + + + + )} + + {title ? title : "Sign in"} + + {onClose && ( + + + + )} + + ); +} + +const styles = StyleSheet.create({ + headerModal: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + paddingHorizontal: spacing.lg, + paddingTop: spacing.lg, + }, +}); diff --git a/packages/thirdweb/src/react/native/ui/components/RNImage.tsx b/packages/thirdweb/src/react/native/ui/components/RNImage.tsx new file mode 100644 index 00000000000..ddf20807a2c --- /dev/null +++ b/packages/thirdweb/src/react/native/ui/components/RNImage.tsx @@ -0,0 +1,61 @@ +import { useMemo } from "react"; +import { Image } from "react-native"; +import { SvgXml } from "react-native-svg"; +import { radius } from "../../design-system/index.js"; + +export type ImageInfo = { + size: number; + data?: string | null; + placeholder?: string; + color?: string; +}; + +function getImage(data: string): { + image: string; + type: "xml" | "image" | "url"; +} { + if (data.startsWith("data:image/svg+xml;base64,")) { + const image = globalThis.atob( + data.replace("data:image/svg+xml;base64,", ""), + ); + return { image, type: "xml" }; + } + if (data.startsWith("data:image/")) { + return { image: data, type: "image" }; + } + if (data.startsWith(" { + const { data, size, color, placeholder } = props; + if (!data) { + return null; + } + const { image, type } = useMemo(() => getImage(data), [data]); + switch (type) { + case "url": + return ( + + ); + case "image": + return ( + + ); + case "xml": + return ; + default: + return null; + } +}; diff --git a/packages/thirdweb/src/react/native/ui/components/TokenIcon.tsx b/packages/thirdweb/src/react/native/ui/components/TokenIcon.tsx new file mode 100644 index 00000000000..7dae8792a3e --- /dev/null +++ b/packages/thirdweb/src/react/native/ui/components/TokenIcon.tsx @@ -0,0 +1,27 @@ +"use client"; +import type { Chain } from "../../../../chains/types.js"; +import type { ThirdwebClient } from "../../../../client/client.js"; +import type { Theme } from "../../../core/design-system/index.js"; +import type { TokenInfo } from "../../../core/utils/defaultTokens.js"; +import { genericTokenIcon } from "../../../core/utils/socialIcons.js"; +import { ChainIcon } from "./ChainIcon.js"; +import { RNImage } from "./RNImage.js"; + +// Note: Must not use useConnectUI here + +/** + * @internal + */ +export function TokenIcon(props: { + theme: Theme; + size: number; + token?: TokenInfo; + chain?: Chain; + client: ThirdwebClient; +}) { + return props.token ? ( + + ) : ( + + ); +} diff --git a/packages/thirdweb/src/react/native/ui/components/WalletImage.tsx b/packages/thirdweb/src/react/native/ui/components/WalletImage.tsx new file mode 100644 index 00000000000..a16be667b01 --- /dev/null +++ b/packages/thirdweb/src/react/native/ui/components/WalletImage.tsx @@ -0,0 +1,82 @@ +import { useQuery } from "@tanstack/react-query"; +import { nativeLocalStorage } from "../../../../utils/storage/nativeStorage.js"; +import { getWalletInfo } from "../../../../wallets/__generated__/getWalletInfo.js"; +import type { Wallet } from "../../../../wallets/interfaces/wallet.js"; +import { getStoredActiveWalletId } from "../../../../wallets/manager/index.js"; +import { getLastAuthProvider } from "../../../core/utils/storage.js"; +import { + APPLE_ICON, + EMAIL_ICON, + FACEBOOK_ICON, + GOOGLE_ICON, + PHONE_ICON, + WALLET_ICON, +} from "../icons/svgs.js"; +import { RNImage } from "./RNImage.js"; + +export const WalletImage = (props: { + wallet: Wallet; + size: number; + ensAvatar?: string | null; +}) => { + const { wallet, ensAvatar, size } = props; + const { data: imageData } = useQuery({ + queryKey: [ + "wallet-image-or-ens", + wallet.id, + wallet.getAccount()?.address, + ensAvatar, + ], + queryFn: async (): Promise => { + if (ensAvatar) { + return ensAvatar; + } + const storage = nativeLocalStorage; + let activeEOAId = wallet.id; + if (wallet.id === "smart") { + const storedId = await getStoredActiveWalletId(storage); + if (storedId) { + activeEOAId = storedId; + } + } + let imageData: string; + if ( + activeEOAId === "inApp" && + (wallet.id === "inApp" || wallet.id === "smart") + ) { + const lastAuthProvider = await getLastAuthProvider(nativeLocalStorage); + switch (lastAuthProvider) { + case "phone": + imageData = PHONE_ICON; + break; + case "email": + imageData = EMAIL_ICON; + break; + case "google": + imageData = GOOGLE_ICON; + break; + case "apple": + imageData = APPLE_ICON; + break; + case "facebook": + imageData = FACEBOOK_ICON; + break; + default: + imageData = WALLET_ICON; + break; + } + return imageData; + } + try { + const externalWalletImage = await getWalletInfo(activeEOAId, true); + if (externalWalletImage) { + return externalWalletImage; + } + } catch {} + + return WALLET_ICON; + }, + }); + + return ; +}; diff --git a/packages/thirdweb/src/react/native/ui/components/button.tsx b/packages/thirdweb/src/react/native/ui/components/button.tsx index 830a9170505..b33c50cfbd9 100644 --- a/packages/thirdweb/src/react/native/ui/components/button.tsx +++ b/packages/thirdweb/src/react/native/ui/components/button.tsx @@ -4,9 +4,9 @@ import { type TouchableOpacityProps, View, } from "react-native"; -import { SvgXml } from "react-native-svg"; import type { Theme } from "../../../core/design-system/index.js"; import { radius, spacing } from "../../design-system/index.js"; +import { RNImage } from "./RNImage.js"; import { ThemedText } from "./text.js"; export type ThemedButtonProps = TouchableOpacityProps & { @@ -60,7 +60,7 @@ export function ThemedButtonWithIcon( width: "100%", }} > - + {title} diff --git a/packages/thirdweb/src/react/native/ui/components/input.tsx b/packages/thirdweb/src/react/native/ui/components/input.tsx index 69140e71268..94420dd74bf 100644 --- a/packages/thirdweb/src/react/native/ui/components/input.tsx +++ b/packages/thirdweb/src/react/native/ui/components/input.tsx @@ -14,17 +14,36 @@ import { ThemedSpinner } from "./spinner.js"; export type ThemedInputProps = { theme: Theme; + rightView?: React.ReactNode; } & TextInputProps; export function ThemedInput(props: ThemedInputProps) { - const { theme } = props; + const { theme, rightView } = props; + const [isFocused, setIsFocused] = useState(false); return ( - + setIsFocused(true)} + onBlur={() => setIsFocused(false)} {...props} /> + {rightView && ( + <> + + {rightView} + + )} ); } @@ -36,9 +55,19 @@ export function ThemedInputWithSubmit( }, ) { const { theme, onSubmit } = props; + const [isFocused, setIsFocused] = useState(false); const [val, setVal] = useState(""); return ( - + setIsFocused(true)} + onBlur={() => setIsFocused(false)} {...props} /> {onSubmit && ( diff --git a/packages/thirdweb/src/react/native/ui/components/text.tsx b/packages/thirdweb/src/react/native/ui/components/text.tsx index 7955a5349fe..6422618415d 100644 --- a/packages/thirdweb/src/react/native/ui/components/text.tsx +++ b/packages/thirdweb/src/react/native/ui/components/text.tsx @@ -40,11 +40,9 @@ export function ThemedText({ const styles = StyleSheet.create({ default: { fontSize: 16, - lineHeight: 24, }, defaultSemiBold: { fontSize: 16, - lineHeight: 24, fontWeight: "600", }, subtext: { @@ -60,7 +58,6 @@ const styles = StyleSheet.create({ fontWeight: "600", }, link: { - lineHeight: 30, fontSize: 16, }, }); diff --git a/packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx b/packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx index 9cdc71e068b..86e78031c9f 100644 --- a/packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx +++ b/packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx @@ -9,27 +9,41 @@ import { StyleSheet, View, } from "react-native"; -import type { MultiStepAuthProviderType } from "../../../../wallets/in-app/core/authentication/type.js"; -import type { Wallet } from "../../../../wallets/interfaces/wallet.js"; import { parseTheme } from "../../../core/design-system/CustomThemeProvider.js"; import type { ConnectButtonProps } from "../../../core/hooks/connection/ConnectButtonProps.js"; import { useActiveAccount } from "../../hooks/wallets/useActiveAccount.js"; import { useActiveWallet } from "../../hooks/wallets/useActiveWallet.js"; +import { useActiveWalletConnectionStatus } from "../../hooks/wallets/useActiveWalletConnectionStatus.js"; +import { useAutoConnect } from "../../hooks/wallets/useAutoConnect.js"; import { ThemedButton } from "../components/button.js"; +import { ThemedSpinner } from "../components/spinner.js"; import { ThemedText } from "../components/text.js"; import { ConnectModal } from "./ConnectModal.js"; import { ConnectedButton } from "./ConnectedButton.js"; +import { ConnectedModal } from "./ConnectedModal.js"; -export type ModalState = - | { screen: "base" } - | { screen: "otp"; auth: MultiStepAuthProviderType; wallet: Wallet<"inApp"> } - | { screen: "external_wallets" }; - +/** + * A component that allows the user to connect their wallet. + * It renders a button which when clicked opens a modal to allow users to connect to wallets specified in `wallets` prop. + * @example + * ```tsx + * + * ``` + * @param props + * Props for the `ConnectButton` component + * + * Refer to [ConnectButtonProps](https://portal.thirdweb.com/references/typescript/v5/ConnectButtonProps) to see the available props. + * @component + */ export function ConnectButton(props: ConnectButtonProps) { const theme = parseTheme(props.theme); const [visible, setVisible] = useState(false); const wallet = useActiveWallet(); const account = useActiveAccount(); + const status = useActiveWalletConnectionStatus(); + useAutoConnect(props); const fadeAnim = useRef(new Animated.Value(0)); // For background opacity const slideAnim = useRef(new Animated.Value(screenHeight)); // For bottom sheet position @@ -71,24 +85,33 @@ export function ConnectButton(props: ConnectButtonProps) { }); }, []); - return wallet && account ? ( - - ) : ( + return ( - openModal()}> - - Connect Wallet - - + {wallet && account ? ( + openModal()} + onClose={closeModal} + wallet={wallet} + account={account} + {...props} + /> + ) : ( + openModal()}> + {status === "connecting" ? ( + <> + + + ) : ( + + Connect Wallet + + )} + + )} - + {wallet && account ? ( + + ) : ( + + )} diff --git a/packages/thirdweb/src/react/native/ui/connect/ConnectModal.tsx b/packages/thirdweb/src/react/native/ui/connect/ConnectModal.tsx index 651827d7a2d..14c752b90fb 100644 --- a/packages/thirdweb/src/react/native/ui/connect/ConnectModal.tsx +++ b/packages/thirdweb/src/react/native/ui/connect/ConnectModal.tsx @@ -1,24 +1,49 @@ import { useState } from "react"; -import { Platform, StyleSheet, TouchableOpacity, View } from "react-native"; +import { Platform, StyleSheet, View } from "react-native"; import { SvgXml } from "react-native-svg"; +import type { MultiStepAuthProviderType } from "../../../../wallets/in-app/core/authentication/type.js"; import type { Wallet } from "../../../../wallets/interfaces/wallet.js"; import { parseTheme } from "../../../core/design-system/CustomThemeProvider.js"; import type { Theme } from "../../../core/design-system/index.js"; import type { ConnectButtonProps } from "../../../core/hooks/connection/ConnectButtonProps.js"; import type { ConnectEmbedProps } from "../../../core/hooks/connection/ConnectEmbedProps.js"; +import { genericWalletIcon } from "../../../core/utils/socialIcons.js"; import { radius, spacing } from "../../design-system/index.js"; import { useActiveWallet } from "../../hooks/wallets/useActiveWallet.js"; import { useConnect } from "../../hooks/wallets/useConnect.js"; import { getDefaultWallets } from "../../wallets/defaultWallets.js"; +import { type ContainerType, Header } from "../components/Header.js"; import { ThemedButtonWithIcon } from "../components/button.js"; import { Spacer } from "../components/spacer.js"; import { ThemedText } from "../components/text.js"; import { ThemedView } from "../components/view.js"; -import { BACK_ICON, CLOSE_ICON, TW_ICON, WALLET_ICON } from "../icons/svgs.js"; -import type { ModalState } from "./ConnectButton.js"; +import { TW_ICON } from "../icons/svgs.js"; import { ExternalWalletsList } from "./ExternalWalletsList.js"; import { InAppWalletUI, OtpLogin } from "./InAppWalletUI.js"; +export type ModalState = + | { screen: "base" } + | { screen: "otp"; auth: MultiStepAuthProviderType; wallet: Wallet<"inApp"> } + | { screen: "external_wallets" }; + +/** + * A component that allows the user to connect their wallet. + * + * it renders the same UI as the [`ConnectButton`](https://portal.thirdweb.com/react/v4/components/ConnectButton) component's modal - but directly on the page instead of being in a modal. + * + * It only renders UI if wallet is not connected + * @example + * ```tsx + * + * ``` + * @param props - + * The props for the `ConnectEmbed` component. + * + * Refer to the [`ConnectEmbedProps`](https://portal.thirdweb.com/references/typescript/v5/ConnectEmbedProps) type for more details + * @component + */ export function ConnectEmbed(props: ConnectEmbedProps) { const theme = parseTheme(props.theme); const wallet = useActiveWallet(); @@ -35,7 +60,7 @@ export function ConnectModal( props: ConnectButtonProps & { theme: Theme; onClose?: () => void; - containerType: "modal" | "embed"; + containerType: ContainerType; }, ) { const { theme, client, containerType, accountAbstraction, onConnect } = props; @@ -52,98 +77,134 @@ export function ConnectModal( const externalWallets = wallets.filter((wallet) => wallet.id !== "inApp"); const showBranding = props.connectModal?.showThirdwebBranding !== false; let content: JSX.Element; - if (modalState.screen === "otp") { - content = ( - <> -
setModalState({ screen: "base" })} - /> - - - +
setModalState({ screen: "base" })} /> - - {containerType === "modal" ? ( - - ) : ( - - )} - - ); - } else if (modalState.screen === "external_wallets") { - content = ( - <> -
setModalState({ screen: "base" })} - /> - - - - ); - } else { - content = ( - <> -
- - - {inAppWallet && ( - + + + + {containerType === "modal" ? ( + + ) : ( + )} - - + ); + break; + } + case "external_wallets": { + content = ( + <> +
setModalState({ screen: "external_wallets" })} + onClose={props.onClose} + containerType={containerType} + onBack={() => setModalState({ screen: "base" })} /> - - {containerType === "modal" ? ( - - ) : ( - )} - - ); + + + ); + break; + } + default: { + content = ( + <> +
+ {inAppWallet ? ( + <> + {containerType === "modal" ? ( + + ) : ( + + )} + + + {externalWallets.length > 0 ? ( + <> + + + setModalState({ screen: "external_wallets" }) + } + /> + + ) : null} + + {containerType === "modal" ? ( + + ) : ( + + )} + + ) : externalWallets.length > 0 ? ( + <> + + + + + + ) : null} + + ); + } } return ( @@ -161,70 +222,6 @@ export function ConnectModal( ); } -function Header({ - theme, - onClose, - onBack, - containerType, -}: { - theme: Theme; - onClose?: () => void; - onBack?: () => void; - containerType: "modal" | "embed"; -}) { - if (containerType === "embed") { - return onBack ? ( - - - - Back - - - ) : null; - } - - return ( - - {onBack && ( - - - - )} - - Sign in - - {onClose && ( - - - - )} - - ); -} - function OrDivider({ theme }: { theme: Theme }) { return ( void; onClose: () => void; wallet: Wallet; account: Account; @@ -31,7 +19,6 @@ export function ConnectedButton( ) { const theme = parseTheme(props.theme); const { account, wallet } = props; - const { disconnect } = useDisconnect(); const walletChain = useActiveWalletChain(); const { ensAvatarQuery, addressOrENS, balanceQuery } = useConnectedWalletDetails( @@ -41,135 +28,51 @@ export function ConnectedButton( props.detailsButton?.displayBalanceToken, ); return ( - wallet && - account && ( - { - props.onClose(); - disconnect(wallet); - }} - style={{ - paddingHorizontal: spacing.md, - paddingVertical: spacing.smd, - }} - > - - - - - {addressOrENS} - - - {balanceQuery.data - ? Number(balanceQuery.data.displayValue).toFixed(3) - : "-"}{" "} - {balanceQuery.data?.symbol}{" "} - - + { + props.openModal(); + }} + style={{ + paddingHorizontal: spacing.md, + paddingVertical: spacing.smd, + }} + > + + + + + {addressOrENS} + + + {balanceQuery.data + ? Number(balanceQuery.data.displayValue).toFixed(3) + : "---"}{" "} + {balanceQuery.data?.symbol}{" "} + - {/* - Disconnect - */} - - ) + + ); } -const WalletImageOrEns = (props: { - wallet: Wallet; - account: Account; - ensAvatar?: string | null; -}) => { - const { wallet, account, ensAvatar } = props; - const { data: imageData } = useQuery({ - queryKey: ["wallet-image-or-ens", wallet.id, account.address], - queryFn: async () => { - let imageData: string; - let imageType: "xml" | "image" | "url"; - if (ensAvatar) { - return { - data: ensAvatar, - type: "url", - }; - } - if (wallet.id === "inApp") { - const lastAuthProvider = await getLastAuthProvider(nativeLocalStorage); - imageType = "xml"; - switch (lastAuthProvider) { - case "phone": - imageData = PHONE_ICON; - break; - case "email": - imageData = EMAIL_ICON; - break; - case "google": - imageData = GOOGLE_ICON; - break; - case "apple": - imageData = APPLE_ICON; - break; - case "facebook": - imageData = FACEBOOK_ICON; - break; - default: - imageData = WALLET_ICON; - break; - } - return { - data: imageData, - type: imageType, - }; - } - const externalWalletImage = await getWalletInfo(wallet.id, true); - return { - data: externalWalletImage, - type: "image", - }; - }, - }); - - if (imageData) { - switch (imageData.type) { - case "url": - return ( - - ); - case "image": - return ( - - ); - case "xml": - return ; - } - } - return null; -}; - const styles = StyleSheet.create({ row: { flexDirection: "row", diff --git a/packages/thirdweb/src/react/native/ui/connect/ConnectedModal.tsx b/packages/thirdweb/src/react/native/ui/connect/ConnectedModal.tsx new file mode 100644 index 00000000000..45be5ace63c --- /dev/null +++ b/packages/thirdweb/src/react/native/ui/connect/ConnectedModal.tsx @@ -0,0 +1,420 @@ +import { useEffect, useState } from "react"; +import { Linking, StyleSheet, TouchableOpacity, View } from "react-native"; +import type { ThirdwebClient } from "../../../../client/client.js"; +import { getContract } from "../../../../contract/contract.js"; +import { isContractDeployed } from "../../../../utils/bytecode/is-contract-deployed.js"; +import type { Account, Wallet } from "../../../../wallets/interfaces/wallet.js"; +import type { Theme } from "../../../core/design-system/index.js"; +import type { ConnectButtonProps } from "../../../core/hooks/connection/ConnectButtonProps.js"; +import { useChainQuery } from "../../../core/hooks/others/useChainQuery.js"; +import { hasSmartAccount } from "../../../core/utils/isSmartWallet.js"; +import { useConnectedWalletDetails } from "../../../core/utils/wallet.js"; +import { fontSize, radius, spacing } from "../../design-system/index.js"; +import { useActiveAccount } from "../../hooks/wallets/useActiveAccount.js"; +import { useActiveWallet } from "../../hooks/wallets/useActiveWallet.js"; +import { useActiveWalletChain } from "../../hooks/wallets/useActiveWalletChain.js"; +import { useDisconnect } from "../../hooks/wallets/useDisconnect.js"; +import { Address } from "../components/Address.js"; +import { ChainIcon } from "../components/ChainIcon.js"; +import { type ContainerType, Header } from "../components/Header.js"; +import { RNImage } from "../components/RNImage.js"; +import { WalletImage } from "../components/WalletImage.js"; +import { ThemedButton } from "../components/button.js"; +import { Spacer } from "../components/spacer.js"; +import { ThemedText } from "../components/text.js"; +import { ThemedView } from "../components/view.js"; +import { + CLOSE_ICON, + COINS_ICON, + EXIT_ICON, + RECEIVE_ICON, + SEND_ICON, + SMART_WALLET_ICON, +} from "../icons/svgs.js"; +import { ReceiveScreen } from "./ReceiveScreen.js"; +import { SendScreen } from "./SendScreen.js"; +import { TokenListScreen } from "./TokenListScreen.js"; + +type ConnectedModalState = + | { + screen: "account"; + } + | { screen: "send" } + | { screen: "receive" } + | { screen: "view_funds" }; + +type ConnectedModalProps = ConnectButtonProps & { + theme: Theme; + wallet: Wallet; + account: Account; + onClose?: () => void; + containerType: ContainerType; +}; + +type ConnectedModalPropsInner = ConnectedModalProps & { + setModalState: (state: ConnectedModalState) => void; +}; + +export function ConnectedModal(props: ConnectedModalProps) { + const { theme, containerType, client } = props; + const [modalState, setModalState] = useState({ + screen: "account", + }); + + let content: JSX.Element; + + switch (modalState.screen) { + case "send": { + content = ( + <> + setModalState({ screen: "account" })} + containerType={containerType} + supportedTokens={props.supportedTokens} + /> + + ); + break; + } + case "receive": { + content = ( + <> + setModalState({ screen: "account" })} + onClose={props.onClose} + /> + + ); + break; + } + case "view_funds": { + content = ( + <> +
setModalState({ screen: "account" })} + containerType={containerType} + title="View Funds" + /> + + + + ); + break; + } + default: { + content = ( + <> + {props.onClose && ( + + + + )} + + + + + + + + ); + } + } + + return ( + + {content} + + ); +} + +const AccountHeader = (props: ConnectedModalProps) => { + const { account, wallet, theme } = props; + const walletChain = useActiveWalletChain(); + const { ensAvatarQuery, addressOrENS, balanceQuery } = + useConnectedWalletDetails( + props.client, + walletChain, + account, + props.detailsButton?.displayBalanceToken, + ); + return ( + + + + +
+ + + {balanceQuery.data + ? Number(balanceQuery.data.displayValue).toFixed(3) + : "---"}{" "} + {balanceQuery.data?.symbol}{" "} + + + ); +}; + +const WalletActionsRow = (props: ConnectedModalPropsInner) => { + const { theme, setModalState } = props; + return ( + + setModalState({ screen: "send" })} + > + + + Send + + + setModalState({ screen: "receive" })} + > + + + Receive + + + {/** TODO (rn) Buy button here */} + + ); +}; + +const WalletMenu = (props: ConnectedModalPropsInner) => { + return ( + + + + + + ); +}; + +const ChainSwitcher = (props: ConnectedModalPropsInner) => { + const { client, wallet, theme } = props; + const chain = wallet.getChain(); + const chainQuery = useChainQuery(chain); + return ( + + + + {chainQuery.data?.name || "---"} + + + ); +}; + +const ViewFunds = (props: ConnectedModalPropsInner) => { + const { theme, setModalState } = props; + return ( + setModalState({ screen: "view_funds" })} + > + + + View Funds + + + ); +}; + +const DisconnectWallet = (props: ConnectedModalProps) => { + const { wallet, theme, onClose } = props; + const { disconnect } = useDisconnect(); + return ( + { + onClose?.(); + disconnect(wallet); + }} + > + + + Disconnect Wallet + + + ); +}; + +function SmartAccountBadge(props: { + theme: Theme; + client: ThirdwebClient; +}) { + const activeAccount = useActiveAccount(); + const activeWallet = useActiveWallet(); + const isSmartWallet = hasSmartAccount(activeWallet); + const chain = useActiveWalletChain(); + const { client, theme } = props; + + const [isSmartWalletDeployed, setIsSmartWalletDeployed] = useState(false); + + useEffect(() => { + if (activeAccount && isSmartWallet && activeAccount.address && chain) { + const contract = getContract({ + address: activeAccount.address, + chain, + client, + }); + + isContractDeployed(contract).then((isDeployed) => { + setIsSmartWalletDeployed(isDeployed); + }); + } else { + setIsSmartWalletDeployed(false); + } + }, [activeAccount, chain, client, isSmartWallet]); + + const content = ( + + + + Smart Account + + + ); + + if (chain && activeAccount && isSmartWallet) { + return ( + <> + + {isSmartWalletDeployed ? ( + + Linking.openURL( + `https://thirdweb.com/${chain.id}/${activeAccount.address}/account`, + ) + } + > + {content} + + ) : ( + {content} + )} + + ); + } + + return null; +} + +const styles = StyleSheet.create({ + modalContainer: { + flex: 1, + width: "100%", + flexDirection: "column", + borderTopLeftRadius: radius.lg, + borderTopRightRadius: radius.lg, + }, + embedContainer: { + flex: 1, + width: "100%", + flexDirection: "column", + backgroundColor: "transparent", + }, + accountHeaderContainer: { + flexDirection: "column", + justifyContent: "center", + alignItems: "center", + paddingHorizontal: spacing.lg, + }, + walletActionRowContainer: { + flexDirection: "row", + justifyContent: "space-evenly", + alignItems: "center", + gap: spacing.md, + paddingHorizontal: spacing.lg, + }, + walletActionButton: { flex: 1, padding: spacing.smd, gap: spacing.smd }, + walletMenuContainer: { + flexDirection: "column", + gap: spacing.lg, + paddingHorizontal: spacing.lg, + }, + walletMenuRow: { + flexDirection: "row", + justifyContent: "flex-start", + alignItems: "center", + gap: spacing.md, + }, +}); diff --git a/packages/thirdweb/src/react/native/ui/connect/ErrorView.tsx b/packages/thirdweb/src/react/native/ui/connect/ErrorView.tsx new file mode 100644 index 00000000000..2f994226f02 --- /dev/null +++ b/packages/thirdweb/src/react/native/ui/connect/ErrorView.tsx @@ -0,0 +1,39 @@ +import { StyleSheet, View } from "react-native"; +import type { Theme } from "../../../core/design-system/index.js"; +import { spacing } from "../../design-system/index.js"; +import { RNImage } from "../components/RNImage.js"; +import { ThemedText } from "../components/text.js"; +import { CLOSE_CIRCLE } from "../icons/svgs.js"; + +export type ErrorViewProps = { + theme: Theme; + title: string; +}; + +export const ErrorView = (props: ErrorViewProps) => { + const { theme, title } = props; + + return ( + + + + {title} + + + ); +}; + +const styles = StyleSheet.create({ + container: { + paddingHorizontal: spacing.lg, + paddingVertical: spacing.xxl, + flexDirection: "column", + justifyContent: "center", + alignItems: "center", + gap: spacing.lg, + }, +}); diff --git a/packages/thirdweb/src/react/native/ui/connect/ExternalWalletsList.tsx b/packages/thirdweb/src/react/native/ui/connect/ExternalWalletsList.tsx index 2d42a025574..dd9fd1dd208 100644 --- a/packages/thirdweb/src/react/native/ui/connect/ExternalWalletsList.tsx +++ b/packages/thirdweb/src/react/native/ui/connect/ExternalWalletsList.tsx @@ -12,13 +12,14 @@ import type { Theme } from "../../../core/design-system/index.js"; import { useWalletImage, useWalletInfo } from "../../../core/utils/wallet.js"; import { spacing } from "../../design-system/index.js"; import type { useConnect } from "../../hooks/wallets/useConnect.js"; +import type { ContainerType } from "../components/Header.js"; import { ThemedText } from "../components/text.js"; export type ExternalWalletsUiProps = { theme: Theme; client: ThirdwebClient; connectMutation: ReturnType; - containerType: "modal" | "embed"; + containerType: ContainerType; }; export function ExternalWalletsList( @@ -30,6 +31,7 @@ export function ExternalWalletsList( style={{ flex: 1, paddingHorizontal: props.containerType === "modal" ? spacing.lg : 0, + paddingBottom: spacing.md, }} > @@ -38,7 +40,7 @@ export function ExternalWalletsList( ))} - + ); } @@ -73,7 +75,10 @@ function ExternalWalletRow(props: ExternalWalletsUiProps & { wallet: Wallet }) { ); } -function NewToWallets({ theme }: { theme: Theme }) { +function NewToWallets({ + theme, + containerType, +}: { theme: Theme; containerType: ContainerType }) { return ( @@ -108,7 +113,6 @@ const styles = StyleSheet.create({ container: { flex: 1, flexDirection: "column", - gap: spacing.md, }, row: { flexDirection: "row", diff --git a/packages/thirdweb/src/react/native/ui/connect/InAppWalletUI.tsx b/packages/thirdweb/src/react/native/ui/connect/InAppWalletUI.tsx index beba82bbaee..8fa7569bef3 100644 --- a/packages/thirdweb/src/react/native/ui/connect/InAppWalletUI.tsx +++ b/packages/thirdweb/src/react/native/ui/connect/InAppWalletUI.tsx @@ -1,7 +1,6 @@ import { useMutation } from "@tanstack/react-query"; import { useCallback, useState } from "react"; import { Alert, StyleSheet, TouchableOpacity, View } from "react-native"; -import { SvgXml } from "react-native-svg"; import type { ThirdwebClient } from "../../../../client/client.js"; import { nativeLocalStorage } from "../../../../utils/storage/nativeStorage.js"; import type { @@ -18,6 +17,7 @@ import type { Theme } from "../../../core/design-system/index.js"; import { setLastAuthProvider } from "../../../core/utils/storage.js"; import { radius, spacing } from "../../design-system/index.js"; import type { useConnect } from "../../hooks/wallets/useConnect.js"; +import { RNImage } from "../components/RNImage.js"; import { ThemedButton, ThemedButtonWithIcon } from "../components/button.js"; import { ThemedInput, ThemedInputWithSubmit } from "../components/input.js"; import { Spacer } from "../components/spacer.js"; @@ -30,7 +30,7 @@ import { GOOGLE_ICON, PHONE_ICON, } from "../icons/svgs.js"; -import type { ModalState } from "./ConnectButton.js"; +import type { ModalState } from "./ConnectModal.js"; const defaultAuthOptions: InAppWalletAuth[] = [ "email", @@ -40,10 +40,10 @@ const defaultAuthOptions: InAppWalletAuth[] = [ "apple", ]; -export const authOptionIcons = { +const socialIcons = { google: GOOGLE_ICON, - apple: APPLE_ICON, facebook: FACEBOOK_ICON, + apple: APPLE_ICON, }; type InAppWalletFormUIProps = { @@ -129,7 +129,7 @@ function SocialLogin( onPress={connectInAppWallet} disabled={connectMutation.isConnecting} > - + )} diff --git a/packages/thirdweb/src/react/native/ui/connect/ReceiveScreen.tsx b/packages/thirdweb/src/react/native/ui/connect/ReceiveScreen.tsx new file mode 100644 index 00000000000..12b376a68b1 --- /dev/null +++ b/packages/thirdweb/src/react/native/ui/connect/ReceiveScreen.tsx @@ -0,0 +1,81 @@ +import { StyleSheet, View } from "react-native"; +import { shortenAddress } from "../../../../utils/address.js"; +import type { Account, Wallet } from "../../../../wallets/interfaces/wallet.js"; +import type { Theme } from "../../../core/design-system/index.js"; +import { spacing } from "../../design-system/index.js"; +import { Address } from "../components/Address.js"; +import { type ContainerType, Header } from "../components/Header.js"; +import { WalletImage } from "../components/WalletImage.js"; +import { Spacer } from "../components/spacer.js"; +import { ThemedText } from "../components/text.js"; + +export type ReceiveScreenProps = { + theme: Theme; + wallet: Wallet; + account: Account; + onClose?: () => void; + onBack?: () => void; + containerType: ContainerType; +}; + +export const ReceiveScreen = (props: ReceiveScreenProps) => { + const { wallet, account, theme, onClose, onBack, containerType } = props; + + return ( + <> +
+ + {/* TODO (rn) QR code scanning */} + + + +
+ + + Copy your address to send funds to this wallet + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + paddingHorizontal: spacing.lg, + paddingVertical: spacing.xxl, + flexDirection: "column", + gap: spacing.md, + alignItems: "center", + justifyContent: "center", + flex: 1, + }, + addressContainer: { + width: "100%", + flexDirection: "row", + gap: spacing.sm, + alignItems: "center", + justifyContent: "center", + borderWidth: 1, + padding: spacing.md, + borderRadius: spacing.lg, + }, +}); diff --git a/packages/thirdweb/src/react/native/ui/connect/SendScreen.tsx b/packages/thirdweb/src/react/native/ui/connect/SendScreen.tsx new file mode 100644 index 00000000000..41b33370ea1 --- /dev/null +++ b/packages/thirdweb/src/react/native/ui/connect/SendScreen.tsx @@ -0,0 +1,238 @@ +import { useState } from "react"; +import { StyleSheet, View } from "react-native"; +import type { ThirdwebClient } from "../../../../client/client.js"; +import type { Theme } from "../../../core/design-system/index.js"; +import { useChainQuery } from "../../../core/hooks/others/useChainQuery.js"; +import type { + SupportedTokens, + TokenInfo, +} from "../../../core/utils/defaultTokens.js"; +import { radius, spacing } from "../../design-system/index.js"; +import { useActiveAccount } from "../../hooks/wallets/useActiveAccount.js"; +import { useActiveWalletChain } from "../../hooks/wallets/useActiveWalletChain.js"; +import { useSendToken } from "../../hooks/wallets/useSendToken.js"; +import { type ContainerType, Header } from "../components/Header.js"; +import { ThemedButton } from "../components/button.js"; +import { ThemedInput } from "../components/input.js"; +import { Spacer } from "../components/spacer.js"; +import { ThemedSpinner } from "../components/spinner.js"; +import { ThemedText } from "../components/text.js"; +import { ErrorView } from "./ErrorView.js"; +import { SuccessView } from "./SuccessView.js"; +import { TokenListScreen, TokenRow } from "./TokenListScreen.js"; + +export type SendScreenProps = { + theme: Theme; + client: ThirdwebClient; + onClose?: () => void; + onBack?: () => void; + containerType: ContainerType; + supportedTokens?: SupportedTokens; +}; + +export const SendScreen = (props: SendScreenProps) => { + const { theme, client, onClose, onBack, containerType, supportedTokens } = + props; + const [receiverAddress, setReceiverAddress] = useState(""); + const [amount, setAmount] = useState("0"); + const [selectedToken, setSelectedToken] = useState(); + const account = useActiveAccount(); + const chain = useActiveWalletChain(); + const chainIfo = useChainQuery(chain); + const sendMutation = useSendToken(client); + const [screen, setScreen] = useState< + "base" | "tokenList" | "success" | "error" + >("base"); + + const handleTokenClicked = () => { + setScreen("tokenList"); + }; + + const handleSend = async () => { + sendMutation.mutate( + { + amount, + receiverAddress, + tokenAddress: selectedToken?.address, + }, + { + onSuccess() { + setScreen("success"); + }, + onError() { + setScreen("error"); + }, + }, + ); + }; + + if (screen === "success") { + return ( + <> +
setScreen("base")} + containerType={containerType} + title="Funds Sent" + /> + + + + + + ); + } + + if (screen === "error") { + return ( + <> +
setScreen("base")} + containerType={containerType} + title="Error Sending Funds" + /> + + + + + + ); + } + + if (screen === "tokenList") { + return ( + <> +
setScreen("base")} + containerType={containerType} + title="Token to Send" + /> + + + { + setSelectedToken(t); + setScreen("base"); + }} + /> + + + ); + } + + return ( + <> +
+ + + + Token + + + + + + + + Send to + + + + + + Amount + + + {selectedToken?.symbol || chainIfo.data?.nativeCurrency?.symbol} + + } + /> + + + + {sendMutation.isPending ? ( + + ) : ( + + Send + + )} + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + paddingHorizontal: spacing.lg, + paddingVertical: spacing.lg, + flexDirection: "column", + gap: spacing.md, + }, + inputContainer: { + gap: spacing.sm, + }, +}); diff --git a/packages/thirdweb/src/react/native/ui/connect/SuccessView.tsx b/packages/thirdweb/src/react/native/ui/connect/SuccessView.tsx new file mode 100644 index 00000000000..c855b64e908 --- /dev/null +++ b/packages/thirdweb/src/react/native/ui/connect/SuccessView.tsx @@ -0,0 +1,39 @@ +import { StyleSheet, View } from "react-native"; +import type { Theme } from "../../../core/design-system/index.js"; +import { spacing } from "../../design-system/index.js"; +import { RNImage } from "../components/RNImage.js"; +import { ThemedText } from "../components/text.js"; +import { CHECK_CIRCLE } from "../icons/svgs.js"; + +export type SuccessViewProps = { + theme: Theme; + title: string; +}; + +export const SuccessView = (props: SuccessViewProps) => { + const { theme, title } = props; + + return ( + + + + {title} + + + ); +}; + +const styles = StyleSheet.create({ + container: { + paddingHorizontal: spacing.lg, + paddingVertical: spacing.xxl, + flexDirection: "column", + justifyContent: "center", + alignItems: "center", + gap: spacing.lg, + }, +}); diff --git a/packages/thirdweb/src/react/native/ui/connect/TokenListScreen.tsx b/packages/thirdweb/src/react/native/ui/connect/TokenListScreen.tsx new file mode 100644 index 00000000000..cf46940cf6d --- /dev/null +++ b/packages/thirdweb/src/react/native/ui/connect/TokenListScreen.tsx @@ -0,0 +1,142 @@ +import { ScrollView, StyleSheet, TouchableOpacity, View } from "react-native"; +import type { Chain } from "../../../../chains/types.js"; +import type { ThirdwebClient } from "../../../../client/client.js"; +import type { Theme } from "../../../core/design-system/index.js"; +import { useWalletBalance } from "../../../core/hooks/others/useWalletBalance.js"; +import { + type SupportedTokens, + type TokenInfo, + defaultTokens, +} from "../../../core/utils/defaultTokens.js"; +import { spacing } from "../../design-system/index.js"; +import { useActiveAccount } from "../../hooks/wallets/useActiveAccount.js"; +import { useActiveWalletChain } from "../../hooks/wallets/useActiveWalletChain.js"; +import { RNImage } from "../components/RNImage.js"; +import { TokenIcon } from "../components/TokenIcon.js"; +import { ThemedText } from "../components/text.js"; +import { RIGHT_CHEVRON } from "../icons/svgs.js"; + +export type TokenListScreenProps = { + theme: Theme; + client: ThirdwebClient; + supportedTokens?: SupportedTokens; + onTokenSelected?: (token?: TokenInfo) => void; +}; + +export const TokenListScreen = (props: TokenListScreenProps) => { + const supportedTokens = props.supportedTokens || defaultTokens; + const chain = useActiveWalletChain(); + const account = useActiveAccount(); + const tokens = chain ? supportedTokens[chain.id] || [] : []; + + return ( + <> + + + + {tokens.map((t) => { + return ( + + ); + })} + + + + ); +}; + +export const TokenRow = (props: { + token?: TokenInfo; + theme: Theme; + client: ThirdwebClient; + chain?: Chain; + address?: string; + onTokenSelected?: (token?: TokenInfo) => void; +}) => { + const { token, theme, address, chain, client, onTokenSelected } = props; + const balanceQuery = useWalletBalance({ + address, + chain, + client, + tokenAddress: token?.address, + }); + const tokenName = props.token ? props.token.name : balanceQuery.data?.name; + const inner = ( + <> + + + + {tokenName} + + {address && ( + + {balanceQuery.data + ? `${Number(balanceQuery.data.displayValue).toFixed(3)} ${balanceQuery.data.symbol}` + : "---"} + + )} + + {props.onTokenSelected && ( + <> + + + + )} + + ); + return onTokenSelected ? ( + onTokenSelected(token)} + > + {inner} + + ) : ( + {inner} + ); +}; + +const styles = StyleSheet.create({ + listContainer: { + flexDirection: "column", + flex: 1, + paddingHorizontal: spacing.lg, + gap: spacing.md, + }, + tokenRowContainer: { + flexDirection: "row", + gap: spacing.md, + alignItems: "center", + }, + emptyContainer: { + flexDirection: "column", + flex: 1, + justifyContent: "center", + alignItems: "center", + padding: spacing.lg, + }, +}); diff --git a/packages/thirdweb/src/react/native/ui/icons/svgs.ts b/packages/thirdweb/src/react/native/ui/icons/svgs.ts index dfaba59825f..437f1334410 100644 --- a/packages/thirdweb/src/react/native/ui/icons/svgs.ts +++ b/packages/thirdweb/src/react/native/ui/icons/svgs.ts @@ -80,3 +80,173 @@ export const CLOSE_ICON = ` `; + +export const EXIT_ICON = ` + + +`; + +export const SEND_ICON = ` + + +`; + +export const RECEIVE_ICON = ` + + + +`; + +export const CHAIN_ICON = ``; + +export const COINS_ICON = ` + + + + + `; + +export const RIGHT_CHEVRON = ` + + +`; + +export const SMART_WALLET_ICON = ` + + + + + + + + + + `; + +export const CHECK_CIRCLE = ` + + +`; + +export const CHECK = ` + +`; + +export const CLOSE_CIRCLE = ` + + +`; + +export const COPY_ICON = ` + + + `; diff --git a/packages/thirdweb/src/react/web/hooks/transaction/useSendTransaction.tsx b/packages/thirdweb/src/react/web/hooks/transaction/useSendTransaction.tsx index 2db5a7625a2..ee9d5cc7f64 100644 --- a/packages/thirdweb/src/react/web/hooks/transaction/useSendTransaction.tsx +++ b/packages/thirdweb/src/react/web/hooks/transaction/useSendTransaction.tsx @@ -11,7 +11,7 @@ import { useSendTransactionCore, } from "../../../core/hooks/transaction/useSendTransaction.js"; import { SetRootElementContext } from "../../../core/providers/RootElementContext.js"; -import type { SupportedTokens } from "../../ui/ConnectWallet/defaultTokens.js"; +import type { SupportedTokens } from "../../../core/utils/defaultTokens.js"; import { AccentFailIcon } from "../../ui/ConnectWallet/icons/AccentFailIcon.js"; import { useConnectLocale } from "../../ui/ConnectWallet/locale/getConnectLocale.js"; import { LazyBuyScreen } from "../../ui/ConnectWallet/screens/Buy/LazyBuyScreen.js"; diff --git a/packages/thirdweb/src/react/web/hooks/wallets/useAutoConnect.ts b/packages/thirdweb/src/react/web/hooks/wallets/useAutoConnect.ts index 8b700d8a733..b91ca647223 100644 --- a/packages/thirdweb/src/react/web/hooks/wallets/useAutoConnect.ts +++ b/packages/thirdweb/src/react/web/hooks/wallets/useAutoConnect.ts @@ -4,6 +4,7 @@ import { getInstalledWalletProviders } from "../../../../wallets/injected/mipdSt import type { AutoConnectProps } from "../../../core/hooks/connection/types.js"; import { useAutoConnectCore } from "../../../core/hooks/wallets/useAutoConnect.js"; import { connectionManager } from "../../index.js"; +import { getDefaultWallets } from "../../wallets/defaultWallets.js"; /** * Autoconnect the last previously connected wallet. @@ -25,14 +26,23 @@ import { connectionManager } from "../../index.js"; * @returns whether the auto connect was successful. */ export function useAutoConnect(props: AutoConnectProps) { - return useAutoConnectCore(connectionManager, webLocalStorage, props, () => { - const specifiedWalletIds = new Set(props.wallets.map((x) => x.id)); + const wallets = props.wallets || getDefaultWallets(props); + return useAutoConnectCore( + connectionManager, + webLocalStorage, + { + ...props, + wallets, + }, + () => { + const specifiedWalletIds = new Set(wallets.map((x) => x.id)); - // pass the wallets that are not already specified but are installed by the user - const installedWallets = getInstalledWalletProviders() - .filter((x) => !specifiedWalletIds.has(x.info.rdns)) - .map((x) => createWallet(x.info.rdns)); + // pass the wallets that are not already specified but are installed by the user + const installedWallets = getInstalledWalletProviders() + .filter((x) => !specifiedWalletIds.has(x.info.rdns)) + .map((x) => createWallet(x.info.rdns)); - return installedWallets; - }); + return installedWallets; + }, + ); } diff --git a/packages/thirdweb/src/react/web/hooks/wallets/useSendToken.ts b/packages/thirdweb/src/react/web/hooks/wallets/useSendToken.ts new file mode 100644 index 00000000000..7c9d1728952 --- /dev/null +++ b/packages/thirdweb/src/react/web/hooks/wallets/useSendToken.ts @@ -0,0 +1,29 @@ +import type { ThirdwebClient } from "../../../../client/client.js"; +import { useSendTokenCore } from "../../../core/hooks/wallets/useSendToken.js"; +import { useActiveWallet } from "./useActiveWallet.js"; + +/** + * Send Native or ERC20 tokens from active wallet to given address. + * @example + * ```tsx + * const { mutate: sendToken } = useSendToken(client); + * + * // send native currency + * sendToken({ + * receiverAddress: "0x...", + * amount: "0.1", + * }); + * + * // send ERC20 + * sendToken({ + * tokenAddress, + * receiverAddress: "0x...", + * amount: "0.5", + * }); + * ``` + * @wallet + */ +export function useSendToken(client: ThirdwebClient) { + const wallet = useActiveWallet(); + return useSendTokenCore(client, wallet); +} diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx index 9a4d4ae4dd3..fdb5a20af42 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx @@ -5,6 +5,7 @@ import { useEffect, useMemo, useState } from "react"; import { iconSize } from "../../../core/design-system/index.js"; import { useSiweAuth } from "../../../core/hooks/auth/useSiweAuth.js"; import type { ConnectButtonProps } from "../../../core/hooks/connection/ConnectButtonProps.js"; +import { defaultTokens } from "../../../core/utils/defaultTokens.js"; import { useActiveAccount } from "../../hooks/wallets/useActiveAccount.js"; import { useActiveWallet } from "../../hooks/wallets/useActiveWallet.js"; import { useActiveWalletConnectionStatus } from "../../hooks/wallets/useActiveWalletConnectionStatus.js"; @@ -23,7 +24,6 @@ import { Button } from "../components/buttons.js"; import { fadeInAnimation } from "../design-system/animations.js"; import { ConnectedWalletDetails } from "./Details.js"; import ConnectModal from "./Modal/ConnectModal.js"; -import { defaultTokens } from "./defaultTokens.js"; import { LockIcon } from "./icons/LockIcon.js"; import { useConnectLocale } from "./locale/getConnectLocale.js"; import type { ConnectLocale } from "./locale/types.js"; diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx index 5372ec69965..30c23c76373 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx @@ -38,13 +38,14 @@ import { useChainsQuery, } from "../../../core/hooks/others/useChainQuery.js"; import { SetRootElementContext } from "../../../core/providers/RootElementContext.js"; +import type { SupportedTokens } from "../../../core/utils/defaultTokens.js"; +import { hasSmartAccount } from "../../../core/utils/isSmartWallet.js"; import { useConnectedWalletDetails } from "../../../core/utils/wallet.js"; import { useActiveAccount } from "../../hooks/wallets/useActiveAccount.js"; import { useActiveWallet } from "../../hooks/wallets/useActiveWallet.js"; import { useActiveWalletChain } from "../../hooks/wallets/useActiveWalletChain.js"; import { useDisconnect } from "../../hooks/wallets/useDisconnect.js"; import { useSwitchActiveWalletChain } from "../../hooks/wallets/useSwitchActiveWalletChain.js"; -import { hasSmartAccount } from "../../utils/isSmartWallet.js"; import { ChainIcon } from "../components/ChainIcon.js"; import { CopyIcon } from "../components/CopyIcon.js"; import { Img } from "../components/Img.js"; @@ -65,7 +66,6 @@ import { type NetworkSelectorProps, } from "./NetworkSelector.js"; import { onModalUnmount } from "./constants.js"; -import type { SupportedTokens } from "./defaultTokens.js"; import { CoinsIcon } from "./icons/CoinsIcon.js"; import { FundsIcon } from "./icons/FundsIcon.js"; import { GenericWalletIcon } from "./icons/GenericWalletIcon.js"; diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx index f3f9160129d..1052511eb8b 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx @@ -47,10 +47,6 @@ import { useSetupScreen } from "./screen.js"; * ```tsx * * ``` * @param props - diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx index 743dc8694c6..fc7bdcff6c0 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx @@ -16,6 +16,7 @@ import { radius, spacing, } from "../../../core/design-system/index.js"; +import { genericWalletIcon } from "../../../core/utils/socialIcons.js"; import { sortWallets } from "../../utils/sortWallets.js"; import { LoadingScreen } from "../../wallets/shared/LoadingScreen.js"; import { Img } from "../components/Img.js"; @@ -40,7 +41,6 @@ import { PoweredByThirdweb } from "./PoweredByTW.js"; import { WalletButton, WalletEntryButton } from "./WalletEntryButton.js"; import { WalletTypeRowButton } from "./WalletTypeRowButton.js"; import { compactModalMaxHeight } from "./constants.js"; -import { genericWalletIcon } from "./icons/dataUris.js"; import type { ConnectLocale } from "./locale/types.js"; const InAppWalletSelectionUI = /* @__PURE__ */ lazy( diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/icons/socialLogins.ts b/packages/thirdweb/src/react/web/ui/ConnectWallet/icons/socialLogins.ts deleted file mode 100644 index 56aeb5302e3..00000000000 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/icons/socialLogins.ts +++ /dev/null @@ -1,22 +0,0 @@ -export const googleIconUri = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDUuNiIgaGVpZ2h0PSI3MjAiIHZpZXdCb3g9IjAgMCAxODYuNjkgMTkwLjUiIHhtbG5zOnY9Imh0dHBzOi8vdmVjdGEuaW8vbmFubyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTE4NC41ODMgNzY1LjE3MSkiPjxwYXRoIGNsaXAtcGF0aD0ibm9uZSIgbWFzaz0ibm9uZSIgZD0iTS0xMDg5LjMzMy02ODcuMjM5djM2Ljg4OGg1MS4yNjJjLTIuMjUxIDExLjg2My05LjAwNiAyMS45MDgtMTkuMTM3IDI4LjY2MmwzMC45MTMgMjMuOTg2YzE4LjAxMS0xNi42MjUgMjguNDAyLTQxLjA0NCAyOC40MDItNzAuMDUyIDAtNi43NTQtLjYwNi0xMy4yNDktMS43MzItMTkuNDgzeiIgZmlsbD0iIzQyODVmNCIvPjxwYXRoIGNsaXAtcGF0aD0ibm9uZSIgbWFzaz0ibm9uZSIgZD0iTS0xMTQyLjcxNC02NTEuNzkxbC02Ljk3MiA1LjMzNy0yNC42NzkgMTkuMjIzaDBjMTUuNjczIDMxLjA4NiA0Ny43OTYgNTIuNTYxIDg1LjAzIDUyLjU2MSAyNS43MTcgMCA0Ny4yNzgtOC40ODYgNjMuMDM4LTIzLjAzM2wtMzAuOTEzLTIzLjk4NmMtOC40ODYgNS43MTUtMTkuMzEgOS4xNzktMzIuMTI1IDkuMTc5LTI0Ljc2NSAwLTQ1LjgwNi0xNi43MTItNTMuMzQtMzkuMjI2eiIgZmlsbD0iIzM0YTg1MyIvPjxwYXRoIGNsaXAtcGF0aD0ibm9uZSIgbWFzaz0ibm9uZSIgZD0iTS0xMTc0LjM2NS03MTIuNjFjLTYuNDk0IDEyLjgxNS0xMC4yMTcgMjcuMjc2LTEwLjIxNyA0Mi42ODlzMy43MjMgMjkuODc0IDEwLjIxNyA0Mi42ODljMCAuMDg2IDMxLjY5My0yNC41OTIgMzEuNjkzLTI0LjU5Mi0xLjkwNS01LjcxNS0zLjAzMS0xMS43NzYtMy4wMzEtMTguMDk4czEuMTI2LTEyLjM4MyAzLjAzMS0xOC4wOTh6IiBmaWxsPSIjZmJiYzA1Ii8+PHBhdGggZD0iTS0xMDg5LjMzMy03MjcuMjQ0YzE0LjAyOCAwIDI2LjQ5NyA0Ljg0OSAzNi40NTUgMTQuMjAxbDI3LjI3Ni0yNy4yNzZjLTE2LjUzOS0xNS40MTMtMzguMDEzLTI0Ljg1Mi02My43MzEtMjQuODUyLTM3LjIzNCAwLTY5LjM1OSAyMS4zODgtODUuMDMyIDUyLjU2MWwzMS42OTIgMjQuNTkyYzcuNTMzLTIyLjUxNCAyOC41NzUtMzkuMjI2IDUzLjM0LTM5LjIyNnoiIGZpbGw9IiNlYTQzMzUiIGNsaXAtcGF0aD0ibm9uZSIgbWFzaz0ibm9uZSIvPjwvZz48L3N2Zz4="; -export const facebookIconUri = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGRhdGEtbmFtZT0iRWJlbmUgMSIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgaWQ9ImZhY2Vib29rLWxvZ28tMjAxOSI+PHBhdGggZmlsbD0iIzE4NzdmMiIgZD0iTTEwMjQsNTEyQzEwMjQsMjI5LjIzMDE2LDc5NC43Njk3OCwwLDUxMiwwUzAsMjI5LjIzMDE2LDAsNTEyYzAsMjU1LjU1NCwxODcuMjMxLDQ2Ny4zNzAxMiw0MzIsNTA1Ljc3Nzc3VjY2MEgzMDJWNTEySDQzMlYzOTkuMkM0MzIsMjcwLjg3OTgyLDUwOC40Mzg1NCwyMDAsNjI1LjM4OTIyLDIwMCw2ODEuNDA3NjUsMjAwLDc0MCwyMTAsNzQwLDIxMFYzMzZINjc1LjQzNzEzQzYxMS44MzUwOCwzMzYsNTkyLDM3NS40NjY2Nyw1OTIsNDE1Ljk1NzI4VjUxMkg3MzRMNzExLjMsNjYwSDU5MnYzNTcuNzc3NzdDODM2Ljc2OSw5NzkuMzcwMTIsMTAyNCw3NjcuNTU0LDEwMjQsNTEyWiI+PC9wYXRoPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik03MTEuMyw2NjAsNzM0LDUxMkg1OTJWNDE1Ljk1NzI4QzU5MiwzNzUuNDY2NjcsNjExLjgzNTA4LDMzNiw2NzUuNDM3MTMsMzM2SDc0MFYyMTBzLTU4LjU5MjM1LTEwLTExNC42MTA3OC0xMEM1MDguNDM4NTQsMjAwLDQzMiwyNzAuODc5ODIsNDMyLDM5OS4yVjUxMkgzMDJWNjYwSDQzMnYzNTcuNzc3NzdhNTE3LjM5NjE5LDUxNy4zOTYxOSwwLDAsMCwxNjAsMFY2NjBaIj48L3BhdGg+PC9zdmc+"; -export const twitterIconUri = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiIgaWQ9InR3aXR0ZXIiPjxwYXRoIGZpbGw9IiMwM0E5RjQiIGQ9Ik0xNiAzLjUzOWE2LjgzOSA2LjgzOSAwIDAgMS0xLjg5LjUxOCAzLjI2MiAzLjI2MiAwIDAgMCAxLjQ0My0xLjgxMyA2LjU1NSA2LjU1NSAwIDAgMS0yLjA4Ljc5NCAzLjI4IDMuMjggMCAwIDAtNS42NzQgMi4yNDNjMCAuMjYuMDIyLjUxLjA3Ni43NDhhOS4yODQgOS4yODQgMCAwIDEtNi43NjEtMy40MzEgMy4yODUgMy4yODUgMCAwIDAgMS4wMDggNC4zODRBMy4yNCAzLjI0IDAgMCAxIC42NCA2LjU3OHYuMDM2YTMuMjk1IDMuMjk1IDAgMCAwIDIuNjI4IDMuMjIzIDMuMjc0IDMuMjc0IDAgMCAxLS44Ni4xMDggMi45IDIuOSAwIDAgMS0uNjIxLS4wNTYgMy4zMTEgMy4zMTEgMCAwIDAgMy4wNjUgMi4yODUgNi41OSA2LjU5IDAgMCAxLTQuMDY3IDEuMzk5Yy0uMjY5IDAtLjUyNy0uMDEyLS43ODUtLjA0NUE5LjIzNCA5LjIzNCAwIDAgMCA1LjAzMiAxNWM2LjAzNiAwIDkuMzM2LTUgOS4zMzYtOS4zMzQgMC0uMTQ1LS4wMDUtLjI4NS0uMDEyLS40MjRBNi41NDQgNi41NDQgMCAwIDAgMTYgMy41Mzl6Ij48L3BhdGg+PC9zdmc+"; -export const githubIconUri = - "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzEwXzIpIj4KPHBhdGggZD0iTTcuOTk5IDBDMy41ODIwMSAwIDQuNjE2NDhlLTA2IDMuNTk2IDQuNjE2NDhlLTA2IDguMDMyQy0wLjAwMTggOS43MTU1NSAwLjUyNTUxOSAxMS4zNTcxIDEuNTA3NDQgMTIuNzI0NkMyLjQ4OTM1IDE0LjA5MjIgMy44NzYyMSAxNS4xMTY2IDUuNDcyIDE1LjY1M0M1Ljg3MiAxNS43MjcgNi4wMTggMTUuNDc5IDYuMDE4IDE1LjI2NkM2LjAxOCAxNS4wNzUgNi4wMTEgMTQuNTcgNi4wMDcgMTMuOUMzLjc4MiAxNC4zODUgMy4zMTIgMTIuODIzIDMuMzEyIDEyLjgyM0MyLjk0OSAxMS44OTUgMi40MjQgMTEuNjQ4IDIuNDI0IDExLjY0OEMxLjY5NyAxMS4xNSAyLjQ3OCAxMS4xNiAyLjQ3OCAxMS4xNkMzLjI4MSAxMS4yMTcgMy43MDMgMTEuOTg4IDMuNzAzIDExLjk4OEM0LjQxNyAxMy4yMTUgNS41NzYgMTIuODYxIDYuMDMyIDEyLjY1NUM2LjEwNCAxMi4xMzYgNi4zMTEgMTEuNzgyIDYuNTQgMTEuNTgxQzQuNzY0IDExLjM3OCAyLjg5NiAxMC42ODkgMi44OTYgNy42MTJDMi44OTYgNi43MzUgMy4yMDggNi4wMTggMy43MiA1LjQ1NkMzLjYzNyA1LjI1MyAzLjM2MyA0LjQzNiAzLjc5OCAzLjMzMUMzLjc5OCAzLjMzMSA0LjQ3IDMuMTE1IDUuOTk4IDQuMTU0QzYuNjUwNzUgMy45NzU2MSA3LjMyNDMyIDMuODg0ODIgOC4wMDEwMSAzLjg4NEM4LjY3NzcyIDMuODg1MzQgOS4zNTEyNiAzLjk3NjQ3IDEwLjAwNCA0LjE1NUMxMS41MzEgMy4xMTYgMTIuMjAyIDMuMzMyIDEyLjIwMiAzLjMzMkMxMi42MzggNC40MzggMTIuMzY0IDUuMjU0IDEyLjI4MiA1LjQ1N0MxMi43OTUgNi4wMTkgMTMuMTA0IDYuNzM2IDEzLjEwNCA3LjYxM0MxMy4xMDQgMTAuNjk4IDExLjIzNCAxMS4zNzcgOS40NTIgMTEuNTc2QzkuNzM5IDExLjgyNCA5Ljk5NSAxMi4zMTQgOS45OTUgMTMuMDYzQzkuOTk1IDE0LjEzNyA5Ljk4NSAxNS4wMDMgOS45ODUgMTUuMjY2QzkuOTg1IDE1LjQ4MSAxMC4xMjkgMTUuNzMxIDEwLjUzNSAxNS42NTJDMTIuMTI5MiAxNS4xMTQzIDEzLjUxNDQgMTQuMDg5NSAxNC40OTQ5IDEyLjcyMjNDMTUuNDc1NSAxMS4zNTUxIDE2LjAwMTkgOS43MTQ0OCAxNiA4LjAzMkMxNiAzLjU5NiAxMi40MTggMCA3Ljk5OSAwWiIgZmlsbD0iIzhCOEI4QiIvPgo8L2c+CjxkZWZzPgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzEwXzIiPgo8cmVjdCB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9IndoaXRlIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg=="; -export const appleIconUri = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDM4IiBoZWlnaHQ9IjI1MDAiIHZpZXdCb3g9IjAgMCA0OTYuMjU1IDYwOC43MjgiIGlkPSJhcHBsZSI+PHBhdGggZmlsbD0iIzk5OSIgZD0iTTI3My44MSA1Mi45NzNDMzEzLjgwNi4yNTcgMzY5LjQxIDAgMzY5LjQxIDBzOC4yNzEgNDkuNTYyLTMxLjQ2MyA5Ny4zMDZjLTQyLjQyNiA1MC45OC05MC42NDkgNDIuNjM4LTkwLjY0OSA0Mi42MzhzLTkuMDU1LTQwLjA5NCAyNi41MTItODYuOTcxek0yNTIuMzg1IDE3NC42NjJjMjAuNTc2IDAgNTguNzY0LTI4LjI4NCAxMDguNDcxLTI4LjI4NCA4NS41NjIgMCAxMTkuMjIyIDYwLjg4MyAxMTkuMjIyIDYwLjg4M3MtNjUuODMzIDMzLjY1OS02NS44MzMgMTE1LjMzMWMwIDkyLjEzMyA4Mi4wMSAxMjMuODg1IDgyLjAxIDEyMy44ODVzLTU3LjMyOCAxNjEuMzU3LTEzNC43NjIgMTYxLjM1N2MtMzUuNTY1IDAtNjMuMjE1LTIzLjk2Ny0xMDAuNjg4LTIzLjk2Ny0zOC4xODggMC03Ni4wODQgMjQuODYxLTEwMC43NjYgMjQuODYxQzg5LjMzIDYwOC43MyAwIDQ1NS42NjYgMCAzMzIuNjI4YzAtMTIxLjA1MiA3NS42MTItMTg0LjU1NCAxNDYuNTMzLTE4NC41NTQgNDYuMTA1IDAgODEuODgzIDI2LjU4OCAxMDUuODUyIDI2LjU4OHoiPjwvcGF0aD48L3N2Zz4="; -export const linkedinIconUri = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NCIgaGVpZ2h0PSI0MCIgaWQ9ImxpbmtlZGluIj48cGF0aCBmaWxsPSIjMDA3RUJCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00NCA0MGgtOS43MjVWMjUuOTM4YzAtMy42OC0xLjUyLTYuMTkzLTQuODY2LTYuMTkzLTIuNTU4IDAtMy45ODEgMS42OTYtNC42NDMgMy4zMy0uMjQ5LjU4Ni0uMjEgMS40MDMtLjIxIDIuMjJWNDBoLTkuNjM0cy4xMjQtMjQuOTA5IDAtMjcuMTczaDkuNjM0djQuMjY1Yy41Ny0xLjg2NSAzLjY0OC00LjUyNiA4LjU2LTQuNTI2QzM5LjIxMSAxMi41NjYgNDQgMTYuNDc0IDQ0IDI0Ljg5MVY0MHpNNS4xOCA5LjQyOGgtLjA2M0MyLjAxMyA5LjQyOCAwIDcuMzUxIDAgNC43MTggMCAyLjAzNCAyLjA3MiAwIDUuMjM5IDBjMy4xNjQgMCA1LjExIDIuMDI5IDUuMTcxIDQuNzEgMCAyLjYzMy0yLjAwNyA0LjcxOC01LjIzIDQuNzE4em0tNC4wNyAzLjM5OWg4LjU3NlY0MEgxLjExVjEyLjgyN3oiPjwvcGF0aD48L3N2Zz4="; -export const bitbucketIconUri = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgaWQ9ImJpdGJ1Y2tldCI+PHBhdGggZmlsbD0iIzI2ODBGOCIgZD0iTTQuMjk3IDIzaDE1LjY1OWEuNzc2Ljc3NiAwIDAgMCAuNzY5LS42NTdMMjMuOTkgMS45MTZhLjc4Ljc4IDAgMCAwLS42MzUtLjg5NyAxLjEzIDEuMTMgMCAwIDAtLjEzNC0uMDA5TC43NzkgMUEuNzc1Ljc3NSAwIDAgMCAwIDEuNzc1YzAgLjA0NC4wMDUuMDkzLjAwOS4xMzdsMy4yNjUgMjAuMTk2Yy4wODIuNTA5LjUxNS44ODcgMS4wMjMuODkyek0xNS43MzYgOC4zOTFsLTEuMjExIDcuMjA1aC01TDguMTczIDguMzkxaDcuNTYzeiI+PC9wYXRoPjwvc3ZnPg=="; -export const gitlabIconUri = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTAwIiBoZWlnaHQ9IjIzMDUiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaW5ZTWluIG1lZXQiIHZpZXdCb3g9IjAgMCAyNTYgMjM2IiBpZD0iZ2l0bGFiIj48cGF0aCBmaWxsPSIjRTI0MzI5IiBkPSJNMTI4LjA3NSAyMzYuMDc1bDQ3LjEwNC0xNDQuOTdIODAuOTdsNDcuMTA0IDE0NC45N3oiPjwvcGF0aD48cGF0aCBmaWxsPSIjRkM2RDI2IiBkPSJNMTI4LjA3NSAyMzYuMDc0TDgwLjk3IDkxLjEwNEgxNC45NTZsMTEzLjExOSAxNDQuOTd6Ij48L3BhdGg+PHBhdGggZmlsbD0iI0ZDQTMyNiIgZD0iTTE0Ljk1NiA5MS4xMDRMLjY0MiAxMzUuMTZhOS43NTIgOS43NTIgMCAwIDAgMy41NDIgMTAuOTAzbDEyMy44OTEgOTAuMDEyLTExMy4xMi0xNDQuOTd6Ij48L3BhdGg+PHBhdGggZmlsbD0iI0UyNDMyOSIgZD0iTTE0Ljk1NiA5MS4xMDVIODAuOTdMNTIuNjAxIDMuNzljLTEuNDYtNC40OTMtNy44MTYtNC40OTItOS4yNzUgMGwtMjguMzcgODcuMzE1eiI+PC9wYXRoPjxwYXRoIGZpbGw9IiNGQzZEMjYiIGQ9Ik0xMjguMDc1IDIzNi4wNzRsNDcuMTA0LTE0NC45N2g2Ni4wMTVsLTExMy4xMiAxNDQuOTd6Ij48L3BhdGg+PHBhdGggZmlsbD0iI0ZDQTMyNiIgZD0iTTI0MS4xOTQgOTEuMTA0bDE0LjMxNCA0NC4wNTZhOS43NTIgOS43NTIgMCAwIDEtMy41NDMgMTAuOTAzbC0xMjMuODkgOTAuMDEyIDExMy4xMTktMTQ0Ljk3eiI+PC9wYXRoPjxwYXRoIGZpbGw9IiNFMjQzMjkiIGQ9Ik0yNDEuMTk0IDkxLjEwNWgtNjYuMDE1bDI4LjM3LTg3LjMxNWMxLjQ2LTQuNDkzIDcuODE2LTQuNDkyIDkuMjc1IDBsMjguMzcgODcuMzE1eiI+PC9wYXRoPjwvc3ZnPg=="; -export const twitchIconUri = - "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgdmlld0JveD0iMCAwIDExMS43ODY2NyAxMjcuMzg2NjciCiAgIGhlaWdodD0iMTI3LjM4NjY3IgogICB3aWR0aD0iMTExLjc4NjY3IgogICB4bWw6c3BhY2U9InByZXNlcnZlIgogICB2ZXJzaW9uPSIxLjEiCiAgIGlkPSJzdmczMzU1IgogICBzb2RpcG9kaTpkb2NuYW1lPSJUd2l0Y2hfbG9nby5zdmciCiAgIGlua3NjYXBlOnZlcnNpb249IjEuMS4xICgzYmY1YWUwZDI1LCAyMDIxLTA5LTIwKSIKICAgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiCiAgIHhtbG5zOnNvZGlwb2RpPSJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZCIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcwogICBpZD0iZGVmczI5Ij4KICAgIAogICAgCiAgPC9kZWZzPjxzb2RpcG9kaTpuYW1lZHZpZXcKICAgaWQ9Im5hbWVkdmlldzI3IgogICBwYWdlY29sb3I9IiNmZmZmZmYiCiAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICBib3JkZXJvcGFjaXR5PSIxLjAiCiAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiCiAgIGlua3NjYXBlOnBhZ2VjaGVja2VyYm9hcmQ9IjAiCiAgIHNob3dncmlkPSJmYWxzZSIKICAgaW5rc2NhcGU6em9vbT0iNC4xOTkyMjg0IgogICBpbmtzY2FwZTpjeD0iLTUwLjYwNDUzNSIKICAgaW5rc2NhcGU6Y3k9IjE0MC4zODI5MyIKICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIyNTYwIgogICBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSIxMzg3IgogICBpbmtzY2FwZTp3aW5kb3cteD0iMTkxMiIKICAgaW5rc2NhcGU6d2luZG93LXk9Ii04IgogICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIgogICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmczMzU1IiAvPgogIDxnCiAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMzMzMzMzMywwLDAsLTEuMzMzMzMzMywxMDEuMzkzMzMsNjcuNTg5MzMyKSIKICAgaWQ9ImczMzY1Ij4KICAgICAgPHBhdGgKICAgaWQ9InBhdGgzMzY3IgogICBzdHlsZT0iZmlsbDojNjQ0MWE1O2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpldmVub2RkO3N0cm9rZTpub25lIgogICBkPSJtIDAsMCAtMTMuNjUyLC0xMy42NTEgaCAtMjEuNDQ1IGwgLTExLjY5OSwtMTEuNjk3IHYgMTEuNjk3IEggLTY0LjM0NCBWIDQyLjg5MyBIIDAgWiBtIC03Mi4xNDYsNTAuNjkyIC0zLjg5OSwtMTUuNTk5IHYgLTcwLjE5IGggMTcuNTUgdiAtOS43NTEgaCA5Ljc0NiBsIDkuNzUyLDkuNzUxIGggMTUuNTk2IEwgNy43OTUsLTMuOTA1IHYgNTQuNTk3IHoiIC8+CiAgICA8L2c+PHBhdGgKICAgaWQ9InBhdGgzMzY5IgogICBzdHlsZT0iZmlsbDojNjQ0MWE1O2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpldmVub2RkO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxLjMzMzMzIgogICBkPSJtIDQ0LjE5NzMzMSw2Mi4zOTQyNjYgaCAxMC4zOTg2NyBWIDMxLjE5MjkzMyBoIC0xMC4zOTg2NyB6IG0gMjguNTk0NjcsMCBoIDEwLjM5ODY2IFYgMzEuMTkyOTMzIGggLTEwLjM5ODY2IHoiIC8+Cjwvc3ZnPgo="; -export const discordIconUri = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDEwMCAxMDAiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBpZD0iZGlzY29yZCI+PHBhdGggZmlsbD0iIzY2NjVkMiIgZD0iTTg1LjIyLDI0Ljk1OGMtMTEuNDU5LTguNTc1LTIyLjQzOC04LjMzNC0yMi40MzgtOC4zMzRsLTEuMTIyLDEuMjgyCgkJCQljMTMuNjIzLDQuMDg3LDE5Ljk1NCwxMC4wOTcsMTkuOTU0LDEwLjA5N2MtMTkuNDkxLTEwLjczMS00NC4zMTctMTAuNjU0LTY0LjU5LDBjMCwwLDYuNTcxLTYuMzMxLDIwLjk5Ni0xMC40MThsLTAuODAxLTAuOTYyCgkJCQljMCwwLTEwLjg5OS0wLjI0LTIyLjQzOCw4LjMzNGMwLDAtMTEuNTQsMjAuNzU1LTExLjU0LDQ2LjMxOWMwLDAsNi43MzIsMTEuNTQsMjQuNDQyLDEyLjEwMWMwLDAsMi45NjUtMy41MjYsNS4zNjktNi41NzEKCQkJCWMtMTAuMTc3LTMuMDQ1LTE0LjAyNC05LjM3Ni0xNC4wMjQtOS4zNzZjNi4zOTQsNC4wMDEsMTIuODU5LDYuNTA1LDIwLjkxNiw4LjA5NGMxMy4xMDgsMi42OTgsMjkuNDEzLTAuMDc2LDQxLjU5MS04LjA5NAoJCQkJYzAsMC00LjAwNyw2LjQ5MS0xNC41MDUsOS40NTZjMi40MDQsMi45NjUsNS4yODksNi40MTEsNS4yODksNi40MTFjMTcuNzEtMC41NjEsMjQuNDQxLTEyLjEwMSwyNC40NDEtMTIuMDIKCQkJCUM5Ni43NTksNDUuNzEzLDg1LjIyLDI0Ljk1OCw4NS4yMiwyNC45NTh6IE0zNS4wNTUsNjMuODI0Yy00LjQ4OCwwLTguMTc0LTMuOTI3LTguMTc0LTguODE1CgkJCQljMC4zMjgtMTEuNzA3LDE2LjEwMi0xMS42NzEsMTYuMzQ4LDBDNDMuMjI5LDU5Ljg5NywzOS42MjIsNjMuODI0LDM1LjA1NSw2My44MjR6IE02NC4zMDQsNjMuODI0CgkJCQljLTQuNDg4LDAtOC4xNzQtMy45MjctOC4xNzQtOC44MTVjMC4zNi0xMS42ODQsMTUuOTM3LTExLjY4OSwxNi4zNDgsMEM3Mi40NzgsNTkuODk3LDY4Ljg3Miw2My44MjQsNjQuMzA0LDYzLjgyNHoiPjwvcGF0aD48L3N2Zz4="; -export const microsoftIconUri = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciICB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxwYXRoIGZpbGw9IiNmZjU3MjIiIGQ9Ik02IDZIMjJWMjJINnoiIHRyYW5zZm9ybT0icm90YXRlKC0xODAgMTQgMTQpIi8+PHBhdGggZmlsbD0iIzRjYWY1MCIgZD0iTTI2IDZINDJWMjJIMjZ6IiB0cmFuc2Zvcm09InJvdGF0ZSgtMTgwIDM0IDE0KSIvPjxwYXRoIGZpbGw9IiNmZmMxMDciIGQ9Ik0yNiAyNkg0MlY0MkgyNnoiIHRyYW5zZm9ybT0icm90YXRlKC0xODAgMzQgMzQpIi8+PHBhdGggZmlsbD0iIzAzYTlmNCIgZD0iTTYgMjZIMjJWNDJINnoiIHRyYW5zZm9ybT0icm90YXRlKC0xODAgMTQgMzQpIi8+PC9zdmc+"; diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx index e1d166bae6c..c61f7b3b50c 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx @@ -22,6 +22,7 @@ import { import { useWalletBalance } from "../../../../../core/hooks/others/useWalletBalance.js"; import { useBuyWithCryptoQuote } from "../../../../../core/hooks/pay/useBuyWithCryptoQuote.js"; import { useBuyWithFiatQuote } from "../../../../../core/hooks/pay/useBuyWithFiatQuote.js"; +import type { SupportedTokens } from "../../../../../core/utils/defaultTokens.js"; import { useActiveAccount } from "../../../../hooks/wallets/useActiveAccount.js"; import { useActiveWalletChain } from "../../../../hooks/wallets/useActiveWalletChain.js"; import { LoadingScreen } from "../../../../wallets/shared/LoadingScreen.js"; @@ -42,7 +43,6 @@ import { Button } from "../../../components/buttons.js"; import { Text } from "../../../components/text.js"; import { TokenSymbol } from "../../../components/token/TokenSymbol.js"; import { ChainButton, NetworkSelectorContent } from "../../NetworkSelector.js"; -import type { SupportedTokens } from "../../defaultTokens.js"; import { CoinsIcon } from "../../icons/CoinsIcon.js"; import type { ConnectLocale } from "../../locale/types.js"; import { TokenSelector } from "../TokenSelector.js"; diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.tsx index 5d92da86bc5..19541a3f649 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.tsx @@ -18,13 +18,13 @@ import { spacing, } from "../../../../../../core/design-system/index.js"; import { useChainQuery } from "../../../../../../core/hooks/others/useChainQuery.js"; +import type { TokenInfo } from "../../../../../../core/utils/defaultTokens.js"; import { Spacer } from "../../../../components/Spacer.js"; import { Spinner } from "../../../../components/Spinner.js"; import { Container, Line, ModalHeader } from "../../../../components/basic.js"; import { Button, ButtonLink } from "../../../../components/buttons.js"; import { Text } from "../../../../components/text.js"; import { TokenSymbol } from "../../../../components/token/TokenSymbol.js"; -import type { TokenInfo } from "../../../defaultTokens.js"; import { type ERC20OrNativeToken, NATIVE_TOKEN } from "../../nativeToken.js"; import { PayTokenIcon } from "../PayTokenIcon.js"; import { StepIcon } from "../Stepper.js"; diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.tsx index f4599d6ba99..bad65f36be4 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.tsx @@ -10,13 +10,13 @@ import { } from "../../../../../../core/design-system/index.js"; import { useChainQuery } from "../../../../../../core/hooks/others/useChainQuery.js"; import { useWalletBalance } from "../../../../../../core/hooks/others/useWalletBalance.js"; +import type { TokenInfo } from "../../../../../../core/utils/defaultTokens.js"; import { useActiveAccount } from "../../../../../hooks/wallets/useActiveAccount.js"; import { Skeleton } from "../../../../components/Skeleton.js"; import { Container } from "../../../../components/basic.js"; import { Button } from "../../../../components/buttons.js"; import { Text } from "../../../../components/text.js"; import { TokenSymbol } from "../../../../components/token/TokenSymbol.js"; -import type { TokenInfo } from "../../../defaultTokens.js"; import { GenericWalletIcon } from "../../../icons/GenericWalletIcon.js"; import { formatTokenBalance } from "../../formatTokenBalance.js"; import { type NativeToken, isNativeToken } from "../../nativeToken.js"; diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapFlow.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapFlow.tsx index 447d9f15bc4..e39b718b207 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapFlow.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapFlow.tsx @@ -4,7 +4,7 @@ import type { ThirdwebClient } from "../../../../../../../client/client.js"; import { NATIVE_TOKEN_ADDRESS } from "../../../../../../../constants/addresses.js"; import type { BuyWithCryptoQuote } from "../../../../../../../pay/buyWithCrypto/getQuote.js"; import type { Account } from "../../../../../../../wallets/interfaces/wallet.js"; -import type { TokenInfo } from "../../../defaultTokens.js"; +import type { TokenInfo } from "../../../../../../core/utils/defaultTokens.js"; import { type ERC20OrNativeToken, NATIVE_TOKEN } from "../../nativeToken.js"; import { SwapConfirmationScreen } from "./ConfirmationScreen.js"; import { SwapStatusScreen } from "./SwapStatusScreen.js"; diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/SendFunds.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/SendFunds.tsx index e8b1e640fca..3adf0fb446f 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/SendFunds.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/SendFunds.tsx @@ -1,15 +1,19 @@ import { CheckCircledIcon, CrossCircledIcon } from "@radix-ui/react-icons"; -import { useMemo, useState } from "react"; +import { useState } from "react"; import type { ThirdwebClient } from "../../../../../client/client.js"; -import { isAddress } from "../../../../../utils/address.js"; import { fontSize, iconSize, spacing, } from "../../../../core/design-system/index.js"; import { useWalletBalance } from "../../../../core/hooks/others/useWalletBalance.js"; +import { + type SupportedTokens, + defaultTokens, +} from "../../../../core/utils/defaultTokens.js"; import { useActiveAccount } from "../../../hooks/wallets/useActiveAccount.js"; import { useActiveWalletChain } from "../../../hooks/wallets/useActiveWalletChain.js"; +import { useSendToken } from "../../../hooks/wallets/useSendToken.js"; import { Skeleton } from "../../components/Skeleton.js"; import { Spacer } from "../../components/Spacer.js"; import { Spinner } from "../../components/Spinner.js"; @@ -19,8 +23,6 @@ import { Button } from "../../components/buttons.js"; import { Input, Label } from "../../components/formElements.js"; import { Text } from "../../components/text.js"; import { StyledDiv } from "../../design-system/elements.js"; -import { useSendToken } from "../../hooks/useSendToken.js"; -import { type SupportedTokens, defaultTokens } from "../defaultTokens.js"; import type { ConnectLocale } from "../locale/types.js"; import { TokenSelector } from "./TokenSelector.js"; import { formatTokenBalance } from "./formatTokenBalance.js"; @@ -134,22 +136,7 @@ function SendFundsForm(props: { }); const { receiverAddress, setReceiverAddress, amount, setAmount } = props; - - // Ethereum or Rinkeby or Goerli - // TODO support ens - const isENSSupported = false; - - const isValidReceiverAddress = useMemo(() => { - const isENS = receiverAddress.endsWith(".eth"); - - if (!isENSSupported && isENS) { - return false; - } - - return isENS || isAddress(receiverAddress); - }, [receiverAddress]); - - const showInvalidAddressError = receiverAddress && !isValidReceiverAddress; + const showInvalidAddressError = receiverAddress; const sendTokenMutation = useSendToken(props.client); @@ -297,7 +284,7 @@ function SendFundsForm(props: { data-error={showInvalidAddressError} required id="receiver" - placeholder={isENSSupported ? "0x... / ENS name" : "0x..."} + placeholder={"0x... or ENS name"} variant="outline" value={receiverAddress} onChange={(e) => { diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/TokenSelector.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/TokenSelector.tsx index b3f7bbea4c8..04942d8254a 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/TokenSelector.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/TokenSelector.tsx @@ -14,6 +14,7 @@ import { } from "../../../../core/design-system/index.js"; import { useChainQuery } from "../../../../core/hooks/others/useChainQuery.js"; import { useTokenInfo } from "../../../../core/hooks/others/useTokenInfo.js"; +import type { TokenInfo } from "../../../../core/utils/defaultTokens.js"; import { useActiveAccount } from "../../../hooks/wallets/useActiveAccount.js"; import { ChainIcon } from "../../components/ChainIcon.js"; import { Skeleton } from "../../components/Skeleton.js"; @@ -25,7 +26,6 @@ import { Button } from "../../components/buttons.js"; import { Input } from "../../components/formElements.js"; import { Text } from "../../components/text.js"; import { ChainButton, NetworkSelectorContent } from "../NetworkSelector.js"; -import type { TokenInfo } from "../defaultTokens.js"; import type { ConnectLocale } from "../locale/types.js"; import { formatTokenBalance } from "./formatTokenBalance.js"; import { diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/ViewFunds.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/ViewFunds.tsx index 8bdae7cf9d3..90e1f93a0fc 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/ViewFunds.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/ViewFunds.tsx @@ -2,6 +2,10 @@ import type { Chain } from "../../../../../chains/types.js"; import type { ThirdwebClient } from "../../../../../client/client.js"; import { fontSize } from "../../../../core/design-system/index.js"; import { useWalletBalance } from "../../../../core/hooks/others/useWalletBalance.js"; +import { + type SupportedTokens, + defaultTokens, +} from "../../../../core/utils/defaultTokens.js"; import { useActiveAccount } from "../../../hooks/wallets/useActiveAccount.js"; import { useActiveWalletChain } from "../../../hooks/wallets/useActiveWalletChain.js"; import { Skeleton } from "../../components/Skeleton.js"; @@ -9,7 +13,6 @@ import { Spacer } from "../../components/Spacer.js"; import { TokenIcon } from "../../components/TokenIcon.js"; import { Container, Line, ModalHeader } from "../../components/basic.js"; import { Text } from "../../components/text.js"; -import { type SupportedTokens, defaultTokens } from "../defaultTokens.js"; import { formatTokenBalance } from "./formatTokenBalance.js"; import { type ERC20OrNativeToken, diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/nativeToken.ts b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/nativeToken.ts index 0b9d9a2486a..f060b1a665b 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/nativeToken.ts +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/nativeToken.ts @@ -1,4 +1,4 @@ -import type { TokenInfo } from "../defaultTokens.js"; +import type { TokenInfo } from "../../../../core/utils/defaultTokens.js"; export type NativeToken = { nativeToken: true }; diff --git a/packages/thirdweb/src/react/web/ui/PayEmbed.tsx b/packages/thirdweb/src/react/web/ui/PayEmbed.tsx index 971acfac158..582bc21ec27 100644 --- a/packages/thirdweb/src/react/web/ui/PayEmbed.tsx +++ b/packages/thirdweb/src/react/web/ui/PayEmbed.tsx @@ -13,8 +13,8 @@ import type { ConnectButton_connectModalOptions, PayUIOptions, } from "../../core/hooks/connection/ConnectButtonProps.js"; +import type { SupportedTokens } from "../../core/utils/defaultTokens.js"; import { ConnectButton } from "./ConnectWallet/ConnectButton.js"; -import type { SupportedTokens } from "./ConnectWallet/defaultTokens.js"; import { useConnectLocale } from "./ConnectWallet/locale/getConnectLocale.js"; import BuyScreen from "./ConnectWallet/screens/Buy/BuyScreen.js"; import { BuyTxHistory } from "./ConnectWallet/screens/Buy/tx-history/BuyTxHistory.js"; diff --git a/packages/thirdweb/src/react/web/ui/components/ChainIcon.tsx b/packages/thirdweb/src/react/web/ui/components/ChainIcon.tsx index ebd6ff32f1a..868b49661e4 100644 --- a/packages/thirdweb/src/react/web/ui/components/ChainIcon.tsx +++ b/packages/thirdweb/src/react/web/ui/components/ChainIcon.tsx @@ -5,7 +5,6 @@ import { StyledDiv } from "../design-system/elements.js"; import { Img } from "./Img.js"; // Note: Must not use useConnectUI here - export const fallbackChainIcon = "data:image/svg+xml;charset=UTF-8,%3csvg width='15' height='14' viewBox='0 0 15 14' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M7 8.04238e-07C5.1435 8.04238e-07 3.36301 0.737501 2.05025 2.05025C0.7375 3.36301 0 5.1435 0 7C0 7.225 -1.52737e-07 7.445 0.0349998 7.665C0.16385 9.0151 0.68213 10.2988 1.52686 11.3598C2.37158 12.4209 3.50637 13.2137 4.79326 13.642C6.0801 14.0702 7.4637 14.1153 8.7758 13.7719C10.0879 13.4285 11.2719 12.7113 12.184 11.7075C13.0961 10.7038 13.6969 9.4567 13.9135 8.1178C14.1301 6.7789 13.9531 5.406 13.4039 4.16587C12.8548 2.92574 11.9573 1.87184 10.8204 1.13228C9.6835 0.392721 8.3563 -0.000649196 7 8.04238e-07ZM7 1C8.581 1.00137 10.0975 1.62668 11.22 2.74V3.24C9.2438 2.55991 7.0956 2.56872 5.125 3.265C4.96758 3.1116 4.76997 3.00586 4.555 2.96H4.43C4.37 2.75 4.315 2.54 4.27 2.325C4.225 2.11 4.2 1.92 4.175 1.715C5.043 1.24658 6.0137 1.00091 7 1ZM5.5 3.935C7.3158 3.32693 9.2838 3.34984 11.085 4C10.8414 5.2703 10.3094 6.4677 9.53 7.5C9.312 7.4077 9.0707 7.3855 8.8395 7.4366C8.6083 7.4877 8.3988 7.6094 8.24 7.785C8.065 7.685 7.89 7.585 7.74 7.47C6.7307 6.7966 5.8877 5.9023 5.275 4.855C5.374 4.73221 5.4461 4.58996 5.4866 4.43749C5.5271 4.28502 5.5351 4.12575 5.51 3.97L5.5 3.935ZM3.5 2.135C3.5 2.24 3.53 2.35 3.55 2.455C3.595 2.675 3.655 2.89 3.715 3.105C3.52353 3.21838 3.36943 3.38531 3.2717 3.58522C3.17397 3.78513 3.13688 4.00927 3.165 4.23C2.37575 4.7454 1.67078 5.3795 1.075 6.11C1.19455 5.3189 1.47112 4.55966 1.88843 3.87701C2.30575 3.19437 2.85539 2.60208 3.505 2.135H3.5ZM3.5 9.99C3.30481 10.0555 3.13037 10.1714 2.9943 10.3259C2.85822 10.4804 2.76533 10.6681 2.725 10.87H2.405C1.59754 9.9069 1.1146 8.7136 1.025 7.46L1.08 7.365C1.70611 6.3942 2.52463 5.562 3.485 4.92C3.62899 5.0704 3.81094 5.179 4.01162 5.2345C4.2123 5.2899 4.42423 5.2901 4.625 5.235C5.2938 6.3652 6.208 7.3306 7.3 8.06C7.505 8.195 7.715 8.32 7.925 8.44C7.9082 8.6312 7.9391 8.8237 8.015 9C7.1 9.7266 6.0445 10.256 4.915 10.555C4.78401 10.3103 4.57028 10.1201 4.31199 10.0184C4.05369 9.9167 3.76766 9.9102 3.505 10L3.5 9.99ZM7 12.99C5.9831 12.9903 4.98307 12.7304 4.095 12.235L4.235 12.205C4.43397 12.1397 4.61176 12.0222 4.74984 11.8648C4.88792 11.7074 4.98122 11.5158 5.02 11.31C6.2985 10.984 7.4921 10.3872 8.52 9.56C8.7642 9.7027 9.0525 9.75 9.3295 9.6927C9.6064 9.6355 9.8524 9.4778 10.02 9.25C10.7254 9.4334 11.4511 9.5275 12.18 9.53H12.445C11.9626 10.5673 11.1938 11.4451 10.2291 12.0599C9.2643 12.6747 8.144 13.0009 7 13V12.99ZM10.255 8.54C10.2545 8.3304 10.1975 8.1249 10.09 7.945C10.9221 6.8581 11.5012 5.5991 11.785 4.26C12.035 4.37667 12.2817 4.50667 12.525 4.65C13.0749 5.9495 13.1493 7.4012 12.735 8.75C11.9049 8.8142 11.0698 8.7484 10.26 8.555L10.255 8.54Z' fill='%23646D7A'/%3e%3c/svg%3e"; diff --git a/packages/thirdweb/src/react/web/ui/components/TokenIcon.tsx b/packages/thirdweb/src/react/web/ui/components/TokenIcon.tsx index 994d2e43739..8654c8ee18e 100644 --- a/packages/thirdweb/src/react/web/ui/components/TokenIcon.tsx +++ b/packages/thirdweb/src/react/web/ui/components/TokenIcon.tsx @@ -5,7 +5,7 @@ import type { ThirdwebClient } from "../../../../client/client.js"; import { NATIVE_TOKEN_ADDRESS } from "../../../../constants/addresses.js"; import { iconSize } from "../../../core/design-system/index.js"; import { useChainQuery } from "../../../core/hooks/others/useChainQuery.js"; -import { genericTokenIcon } from "../ConnectWallet/icons/dataUris.js"; +import { genericTokenIcon } from "../../../core/utils/socialIcons.js"; import { type NativeToken, isNativeToken, diff --git a/packages/thirdweb/src/react/web/ui/components/WalletImage.tsx b/packages/thirdweb/src/react/web/ui/components/WalletImage.tsx index 82702897250..30400296c24 100644 --- a/packages/thirdweb/src/react/web/ui/components/WalletImage.tsx +++ b/packages/thirdweb/src/react/web/ui/components/WalletImage.tsx @@ -7,20 +7,18 @@ import { getInstalledWalletProviders } from "../../../../wallets/injected/mipdSt import { getStoredActiveWalletId } from "../../../../wallets/manager/index.js"; import type { WalletId } from "../../../../wallets/wallet-types.js"; import { radius } from "../../../core/design-system/index.js"; -import { getLastAuthProvider } from "../../../core/utils/storage.js"; -import { useWalletImage } from "../../../core/utils/wallet.js"; -import { useActiveWallet } from "../../hooks/wallets/useActiveWallet.js"; import { + appleIconUri, emailIcon, + facebookIconUri, genericWalletIcon, + googleIconUri, passkeyIcon, phoneIcon, -} from "../ConnectWallet/icons/dataUris.js"; -import { - appleIconUri, - facebookIconUri, - googleIconUri, -} from "../ConnectWallet/icons/socialLogins.js"; +} from "../../../core/utils/socialIcons.js"; +import { getLastAuthProvider } from "../../../core/utils/storage.js"; +import { useWalletImage } from "../../../core/utils/wallet.js"; +import { useActiveWallet } from "../../hooks/wallets/useActiveWallet.js"; import { Img } from "./Img.js"; // Note: Must not use useConnectUI here diff --git a/packages/thirdweb/src/react/web/ui/hooks/useSendToken.ts b/packages/thirdweb/src/react/web/ui/hooks/useSendToken.ts deleted file mode 100644 index b44358c069f..00000000000 --- a/packages/thirdweb/src/react/web/ui/hooks/useSendToken.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { useMutation } from "@tanstack/react-query"; -import type { ThirdwebClient } from "../../../../client/client.js"; -import { getContract } from "../../../../contract/contract.js"; -import { transfer } from "../../../../extensions/erc20/write/transfer.js"; -import { waitForReceipt } from "../../../../transaction/actions/wait-for-tx-receipt.js"; -import { prepareTransaction } from "../../../../transaction/prepare-transaction.js"; -import { toWei } from "../../../../utils/units.js"; -import { useSendTransaction } from "../../hooks/transaction/useSendTransaction.js"; -import { useActiveWalletChain } from "../../hooks/wallets/useActiveWalletChain.js"; - -// Q: Should we expose this hook? - -/** - * Send Native or ERC20 tokens from active wallet to given address. - * @internal - */ -export function useSendToken(client: ThirdwebClient) { - const sendTransaction = useSendTransaction({ - payModal: false, - }); - const activeChain = useActiveWalletChain(); - - return useMutation({ - async mutationFn(option: { - tokenAddress?: string; - receiverAddress: string; - amount: string; - }) { - const { tokenAddress, receiverAddress, amount } = option; - if (!activeChain) { - throw new Error("No active chain"); - } - - // native token transfer - if (!tokenAddress) { - const sendNativeTokenTx = prepareTransaction({ - chain: activeChain, - client, - to: receiverAddress, - value: toWei(amount), - }); - - const txHash = await sendTransaction.mutateAsync(sendNativeTokenTx); - await waitForReceipt(txHash); - } - - // erc20 token transfer - else { - const contract = getContract({ - address: tokenAddress, - client, - chain: activeChain, - }); - - const tx = transfer({ - amount, - contract, - to: receiverAddress, - }); - - const txHash = await sendTransaction.mutateAsync(tx); - await waitForReceipt(txHash); - } - }, - }); -} diff --git a/packages/thirdweb/src/react/web/wallets/in-app/socialIcons.ts b/packages/thirdweb/src/react/web/wallets/in-app/socialIcons.ts deleted file mode 100644 index e8e40232c52..00000000000 --- a/packages/thirdweb/src/react/web/wallets/in-app/socialIcons.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { - appleIconUri, - facebookIconUri, - googleIconUri, -} from "../../ui/ConnectWallet/icons/socialLogins.js"; - -export const socialIcons = { - google: googleIconUri, - apple: appleIconUri, - facebook: facebookIconUri, -}; diff --git a/packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx b/packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx index d52d5aaecf7..551ecc99d8e 100644 --- a/packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx +++ b/packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx @@ -19,20 +19,20 @@ import { iconSize, spacing, } from "../../../core/design-system/index.js"; -import { setLastAuthProvider } from "../../../core/utils/storage.js"; -import { useSetSelectionData } from "../../providers/wallet-ui-states-provider.js"; -import { WalletTypeRowButton } from "../../ui/ConnectWallet/WalletTypeRowButton.js"; import { emailIcon, passkeyIcon, phoneIcon, -} from "../../ui/ConnectWallet/icons/dataUris.js"; + socialIcons, +} from "../../../core/utils/socialIcons.js"; +import { setLastAuthProvider } from "../../../core/utils/storage.js"; +import { useSetSelectionData } from "../../providers/wallet-ui-states-provider.js"; +import { WalletTypeRowButton } from "../../ui/ConnectWallet/WalletTypeRowButton.js"; import { Img } from "../../ui/components/Img.js"; import { TextDivider } from "../../ui/components/TextDivider.js"; import { Container } from "../../ui/components/basic.js"; import { Button } from "../../ui/components/buttons.js"; import { InputSelectionUI } from "../in-app/InputSelectionUI.js"; -import { socialIcons } from "../in-app/socialIcons.js"; import { validateEmail } from "../in-app/validateEmail.js"; import { LoadingScreen } from "./LoadingScreen.js"; import type { InAppWalletLocale } from "./locale/types.js"; diff --git a/packages/thirdweb/src/wallets/manager/index.ts b/packages/thirdweb/src/wallets/manager/index.ts index 6c6c4ec8c25..3800f54e047 100644 --- a/packages/thirdweb/src/wallets/manager/index.ts +++ b/packages/thirdweb/src/wallets/manager/index.ts @@ -1,6 +1,6 @@ import type { Chain } from "../../chains/types.js"; import type { ThirdwebClient } from "../../client/client.js"; -import { hasSmartAccount } from "../../react/web/utils/isSmartWallet.js"; +import { hasSmartAccount } from "../../react/core/utils/isSmartWallet.js"; import { computedStore } from "../../reactive/computedStore.js"; import { effect } from "../../reactive/effect.js"; import { createStore } from "../../reactive/store.js"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b5a84479978..a5c280f679c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1964,6 +1964,9 @@ importers: '@react-native-async-storage/async-storage': specifier: ^1 version: 1.23.1(react-native@0.74.1) + '@react-native-clipboard/clipboard': + specifier: ^1 + version: 1.14.1(react-native-macos@0.73.32)(react-native-windows@0.73.15)(react-native@0.74.1)(react@18.2.0) '@react-native-community/netinfo': specifier: ^11 version: 11.3.2(react-native@0.74.1) @@ -2125,6 +2128,9 @@ importers: '@react-native-async-storage/async-storage': specifier: ^1.23.1 version: 1.23.1(react-native@0.74.2) + '@react-native-clipboard/clipboard': + specifier: 1.14.1 + version: 1.14.1(react-native-macos@0.73.32)(react-native-windows@0.73.15)(react-native@0.74.2)(react@18.3.1) '@testing-library/jest-dom': specifier: ^6.4.6 version: 6.4.6(@types/bun@1.0.12)(vitest@1.6.0) @@ -5114,6 +5120,75 @@ packages: '@aws-sdk/types': 3.6.1 tslib: 1.14.1 + /@azure/abort-controller@1.1.0: + resolution: {integrity: sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==} + engines: {node: '>=12.0.0'} + dependencies: + tslib: 2.6.2 + + /@azure/abort-controller@2.1.2: + resolution: {integrity: sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==} + engines: {node: '>=18.0.0'} + dependencies: + tslib: 2.6.2 + + /@azure/core-auth@1.7.2: + resolution: {integrity: sha512-Igm/S3fDYmnMq1uKS38Ae1/m37B3zigdlZw+kocwEhh5GjyKjPrXKO2J6rzpC1wAxrNil/jX9BJRqBshyjnF3g==} + engines: {node: '>=18.0.0'} + dependencies: + '@azure/abort-controller': 2.1.2 + '@azure/core-util': 1.2.0 + tslib: 2.6.2 + + /@azure/core-rest-pipeline@1.10.1: + resolution: {integrity: sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA==} + engines: {node: '>=14.0.0'} + dependencies: + '@azure/abort-controller': 1.1.0 + '@azure/core-auth': 1.7.2 + '@azure/core-tracing': 1.1.2 + '@azure/core-util': 1.2.0 + '@azure/logger': 1.1.2 + form-data: 4.0.0 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + tslib: 2.6.2 + uuid: 8.3.2 + transitivePeerDependencies: + - supports-color + + /@azure/core-tracing@1.1.2: + resolution: {integrity: sha512-dawW9ifvWAWmUm9/h+/UQ2jrdvjCJ7VJEuCJ6XVNudzcOwm53BFZH4Q845vjfgoUAM8ZxokvVNxNxAITc502YA==} + engines: {node: '>=18.0.0'} + dependencies: + tslib: 2.6.2 + + /@azure/core-util@1.2.0: + resolution: {integrity: sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng==} + engines: {node: '>=14.0.0'} + dependencies: + '@azure/abort-controller': 1.1.0 + tslib: 2.6.2 + + /@azure/logger@1.1.2: + resolution: {integrity: sha512-l170uE7bsKpIU6B/giRc9i4NI0Mj+tANMMMxf7Zi/5cKzEqPayP7+X1WPrG7e+91JgY8N+7K7nF2WOi7iVhXvg==} + engines: {node: '>=18.0.0'} + dependencies: + tslib: 2.6.2 + + /@azure/opentelemetry-instrumentation-azure-sdk@1.0.0-beta.5: + resolution: {integrity: sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA==} + engines: {node: '>=14.0.0'} + dependencies: + '@azure/core-tracing': 1.1.2 + '@azure/logger': 1.1.2 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.41.2(@opentelemetry/api@1.9.0) + tslib: 2.6.2 + transitivePeerDependencies: + - supports-color + /@babel/code-frame@7.10.4: resolution: {integrity: sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==} dependencies: @@ -10933,6 +11008,9 @@ packages: - '@types/node' dev: true + /@microsoft/applicationinsights-web-snippet@1.2.0: + resolution: {integrity: sha512-KpJzrC+VYOKSNVOlk0vIxsQ6ZmZOswdNXvkv+nVBsz6tzRI86fKW2qKTCzKcd80f3xOa6dxg6OfEljQPcelQ7g==} + /@microsoft/tsdoc-config@0.17.0: resolution: {integrity: sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg==} dependencies: @@ -11666,7 +11744,6 @@ packages: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.25.1 - dev: false /@opentelemetry/instrumentation-connect@0.37.0(@opentelemetry/api@1.9.0): resolution: {integrity: sha512-SeQktDIH5rNzjiEiazWiJAIXkmnLOnNV7wwHpahrqE0Ph+Z3heqMfxRtoMtbdJSIYLfcNZYO51AjxZ00IXufdw==} @@ -11881,6 +11958,21 @@ packages: - supports-color dev: false + /@opentelemetry/instrumentation@0.41.2(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.9.0 + '@types/shimmer': 1.0.5 + import-in-the-middle: 1.4.2 + require-in-the-middle: 7.3.0 + semver: 7.6.2 + shimmer: 1.2.1 + transitivePeerDependencies: + - supports-color + /@opentelemetry/instrumentation@0.43.0(@opentelemetry/api@1.9.0): resolution: {integrity: sha512-S1uHE+sxaepgp+t8lvIDuRgyjJWisAb733198kwQTUc9ZtYQ2V2gmyCtR1x21ePGVLoMiX/NWY7WA290hwkjJQ==} engines: {node: '>=14'} @@ -11964,7 +12056,6 @@ packages: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.25.1 - dev: false /@opentelemetry/sdk-metrics@1.25.1(@opentelemetry/api@1.9.0): resolution: {integrity: sha512-9Mb7q5ioFL4E4dDrc4wC/A3NTHDat44v4I3p2pLPSxRvqUbDIQyMVr9uK+EU69+HWhlET1VaSrRzwdckWqY15Q==} @@ -11988,7 +12079,6 @@ packages: '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.25.1 - dev: false /@opentelemetry/semantic-conventions@1.25.0: resolution: {integrity: sha512-M+kkXKRAIAiAP6qYyesfrC5TOmDpDVtsxuGfPcqd9B/iBrac+E14jYwrgm0yZBUIbIP2OnqC3j+UgkXLm1vxUQ==} @@ -11998,7 +12088,6 @@ packages: /@opentelemetry/semantic-conventions@1.25.1: resolution: {integrity: sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==} engines: {node: '>=14'} - dev: false /@opentelemetry/sql-common@0.40.1(@opentelemetry/api@1.9.0): resolution: {integrity: sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==} @@ -13346,6 +13435,43 @@ packages: merge-options: 3.0.4 react-native: 0.74.2(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(@types/react@18.3.3)(react@18.3.1) + /@react-native-clipboard/clipboard@1.14.1(react-native-macos@0.73.32)(react-native-windows@0.73.15)(react-native@0.74.1)(react@18.2.0): + resolution: {integrity: sha512-SM3el0A28SwoeJljVNhF217o0nI4E7RfalLmuRQcT1/7tGcxUjgFa3jyrEndYUct8/uxxK5EUNGUu1YEDqzxqw==} + peerDependencies: + react: 16.9.0 || 16.11.0 || 16.13.1 || 17.0.1 || 17.0.2 || 18.0.0 || 18.1.0 || 18.2.0 + react-native: ^0.61.5 || ^0.62.3 || ^0.63.2 || ^0.64.2 || ^0.65.0 || ^0.66.0 || ^0.67.0 || ^0.68.0 || ^0.69.0 || ^0.70.0 || ^0.71.0 || ^0.72.0 || ^0.73.0 + react-native-macos: ^0.61.0 || ^0.62.0 || ^0.63.0 || ^0.64.0 || ^0.65.0 || ^0.66.0 || ^0.67.0 || ^0.68.0 || ^0.69.0 || ^0.70.0 || ^0.71.0 || ^0.72.0 || ^0.73.0 + react-native-windows: ^0.61.0 || ^0.62.0 || ^0.63.0 || ^0.64.0 || ^0.65.0 || ^0.66.0 || ^0.67.0 || ^0.68.0 || ^0.69.0 || ^0.70.0 || ^0.71.0 || ^0.72.0 || ^0.73.0 + dependencies: + react: 18.2.0 + react-native: 0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(@types/react@18.3.3)(react@18.2.0) + react-native-macos: 0.73.32(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(react-native@0.74.1)(react@18.2.0) + react-native-windows: 0.73.15(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(react-native@0.74.1)(react@18.2.0) + dev: false + + /@react-native-clipboard/clipboard@1.14.1(react-native-macos@0.73.32)(react-native-windows@0.73.15)(react-native@0.74.2)(react@18.3.1): + resolution: {integrity: sha512-SM3el0A28SwoeJljVNhF217o0nI4E7RfalLmuRQcT1/7tGcxUjgFa3jyrEndYUct8/uxxK5EUNGUu1YEDqzxqw==} + peerDependencies: + react: 16.9.0 || 16.11.0 || 16.13.1 || 17.0.1 || 17.0.2 || 18.0.0 || 18.1.0 || 18.2.0 + react-native: ^0.61.5 || ^0.62.3 || ^0.63.2 || ^0.64.2 || ^0.65.0 || ^0.66.0 || ^0.67.0 || ^0.68.0 || ^0.69.0 || ^0.70.0 || ^0.71.0 || ^0.72.0 || ^0.73.0 + react-native-macos: ^0.61.0 || ^0.62.0 || ^0.63.0 || ^0.64.0 || ^0.65.0 || ^0.66.0 || ^0.67.0 || ^0.68.0 || ^0.69.0 || ^0.70.0 || ^0.71.0 || ^0.72.0 || ^0.73.0 + react-native-windows: ^0.61.0 || ^0.62.0 || ^0.63.0 || ^0.64.0 || ^0.65.0 || ^0.66.0 || ^0.67.0 || ^0.68.0 || ^0.69.0 || ^0.70.0 || ^0.71.0 || ^0.72.0 || ^0.73.0 + dependencies: + react: 18.3.1 + react-native: 0.74.2(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(@types/react@18.3.3)(react@18.3.1) + react-native-macos: 0.73.32(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(react-native@0.74.2)(react@18.3.1) + react-native-windows: 0.73.15(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(react-native@0.74.2)(react@18.3.1) + dev: true + + /@react-native-community/cli-clean@12.3.6: + resolution: {integrity: sha512-gUU29ep8xM0BbnZjwz9MyID74KKwutq9x5iv4BCr2im6nly4UMf1B1D+V225wR7VcDGzbgWjaezsJShLLhC5ig==} + dependencies: + '@react-native-community/cli-tools': 12.3.6 + chalk: 4.1.2 + execa: 5.1.1 + transitivePeerDependencies: + - encoding + /@react-native-community/cli-clean@13.6.6: resolution: {integrity: sha512-cBwJTwl0NyeA4nyMxbhkWZhxtILYkbU3TW3k8AXLg+iGphe0zikYMGB3T+haTvTc6alTyEFwPbimk9bGIqkjAQ==} dependencies: @@ -13367,6 +13493,18 @@ packages: transitivePeerDependencies: - encoding + /@react-native-community/cli-config@12.3.6: + resolution: {integrity: sha512-JGWSYQ9EAK6m2v0abXwFLEfsqJ1zkhzZ4CV261QZF9MoUNB6h57a274h1MLQR9mG6Tsh38wBUuNfEPUvS1vYew==} + dependencies: + '@react-native-community/cli-tools': 12.3.6 + chalk: 4.1.2 + cosmiconfig: 5.2.1 + deepmerge: 4.3.1 + glob: 7.2.3 + joi: 17.13.1 + transitivePeerDependencies: + - encoding + /@react-native-community/cli-config@13.6.6: resolution: {integrity: sha512-mbG425zCKr8JZhv/j11382arezwS/70juWMsn8j2lmrGTrP1cUdW0MF15CCIFtJsqyK3Qs+FTmqttRpq81QfSg==} dependencies: @@ -13392,6 +13530,13 @@ packages: transitivePeerDependencies: - encoding + /@react-native-community/cli-debugger-ui@12.3.6: + resolution: {integrity: sha512-SjUKKsx5FmcK9G6Pb6UBFT0s9JexVStK5WInmANw75Hm7YokVvHEgtprQDz2Uvy5znX5g2ujzrkIU//T15KQzA==} + dependencies: + serve-static: 1.15.0 + transitivePeerDependencies: + - supports-color + /@react-native-community/cli-debugger-ui@13.6.6: resolution: {integrity: sha512-Vv9u6eS4vKSDAvdhA0OiQHoA7y39fiPIgJ6biT32tN4avHDtxlc6TWZGiqv7g98SBvDWvoVAmdPLcRf3kU+c8g==} dependencies: @@ -13407,6 +13552,28 @@ packages: transitivePeerDependencies: - supports-color + /@react-native-community/cli-doctor@12.3.6: + resolution: {integrity: sha512-fvBDv2lTthfw4WOQKkdTop2PlE9GtfrlNnpjB818MhcdEnPjfQw5YaTUcnNEGsvGomdCs1MVRMgYXXwPSN6OvQ==} + dependencies: + '@react-native-community/cli-config': 12.3.6 + '@react-native-community/cli-platform-android': 12.3.6 + '@react-native-community/cli-platform-ios': 12.3.6 + '@react-native-community/cli-tools': 12.3.6 + chalk: 4.1.2 + command-exists: 1.2.9 + deepmerge: 4.3.1 + envinfo: 7.13.0 + execa: 5.1.1 + hermes-profile-transformer: 0.0.6 + node-stream-zip: 1.15.0 + ora: 5.4.1 + semver: 7.6.2 + strip-ansi: 5.2.0 + wcwidth: 1.0.1 + yaml: 2.4.5 + transitivePeerDependencies: + - encoding + /@react-native-community/cli-doctor@13.6.6: resolution: {integrity: sha512-TWZb5g6EmQe2Ua2TEWNmyaEayvlWH4GmdD9ZC+p8EpKFpB1NpDGMK6sXbpb42TDvwZg5s4TDRplK0PBEA/SVDg==} dependencies: @@ -13454,6 +13621,16 @@ packages: transitivePeerDependencies: - encoding + /@react-native-community/cli-hermes@12.3.6: + resolution: {integrity: sha512-sNGwfOCl8OAIjWCkwuLpP8NZbuO0dhDI/2W7NeOGDzIBsf4/c4MptTrULWtGIH9okVPLSPX0NnRyGQ+mSwWyuQ==} + dependencies: + '@react-native-community/cli-platform-android': 12.3.6 + '@react-native-community/cli-tools': 12.3.6 + chalk: 4.1.2 + hermes-profile-transformer: 0.0.6 + transitivePeerDependencies: + - encoding + /@react-native-community/cli-hermes@13.6.6: resolution: {integrity: sha512-La5Ie+NGaRl3klei6WxKoOxmCUSGGxpOk6vU5pEGf0/O7ky+Ay0io+zXYUZqlNMi/cGpO7ZUijakBYOB/uyuFg==} dependencies: @@ -13475,6 +13652,18 @@ packages: transitivePeerDependencies: - encoding + /@react-native-community/cli-platform-android@12.3.6: + resolution: {integrity: sha512-DeDDAB8lHpuGIAPXeeD9Qu2+/wDTFPo99c8uSW49L0hkmZJixzvvvffbGQAYk32H0TmaI7rzvzH+qzu7z3891g==} + dependencies: + '@react-native-community/cli-tools': 12.3.6 + chalk: 4.1.2 + execa: 5.1.1 + fast-xml-parser: 4.3.6 + glob: 7.2.3 + logkitty: 0.7.1 + transitivePeerDependencies: + - encoding + /@react-native-community/cli-platform-android@13.6.6: resolution: {integrity: sha512-/tMwkBeNxh84syiSwNlYtmUz/Ppc+HfKtdopL/5RB+fd3SV1/5/NPNjMlyLNgFKnpxvKCInQ7dnl6jGHJjeHjg==} dependencies: @@ -13525,6 +13714,18 @@ packages: transitivePeerDependencies: - encoding + /@react-native-community/cli-platform-ios@12.3.6: + resolution: {integrity: sha512-3eZ0jMCkKUO58wzPWlvAPRqezVKm9EPZyaPyHbRPWU8qw7JqkvnRlWIaYDGpjCJgVW4k2hKsEursLtYKb188tg==} + dependencies: + '@react-native-community/cli-tools': 12.3.6 + chalk: 4.1.2 + execa: 5.1.1 + fast-xml-parser: 4.3.6 + glob: 7.2.3 + ora: 5.4.1 + transitivePeerDependencies: + - encoding + /@react-native-community/cli-platform-ios@13.6.6: resolution: {integrity: sha512-vjDnRwhlSN5ryqKTas6/DPkxuouuyFBAqAROH4FR1cspTbn6v78JTZKDmtQy9JMMo7N5vZj1kASU5vbFep9IOQ==} dependencies: @@ -13540,6 +13741,27 @@ packages: transitivePeerDependencies: - encoding + /@react-native-community/cli-plugin-metro@12.3.6: + resolution: {integrity: sha512-3jxSBQt4fkS+KtHCPSyB5auIT+KKIrPCv9Dk14FbvOaEh9erUWEm/5PZWmtboW1z7CYeNbFMeXm9fM2xwtVOpg==} + + /@react-native-community/cli-server-api@12.3.6: + resolution: {integrity: sha512-80NIMzo8b2W+PL0Jd7NjiJW9mgaT8Y8wsIT/lh6mAvYH7mK0ecDJUYUTAAv79Tbo1iCGPAr3T295DlVtS8s4yQ==} + dependencies: + '@react-native-community/cli-debugger-ui': 12.3.6 + '@react-native-community/cli-tools': 12.3.6 + compression: 1.7.4 + connect: 3.7.0 + errorhandler: 1.5.1 + nocache: 3.0.4 + pretty-format: 26.6.2 + serve-static: 1.15.0 + ws: 7.5.10 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + /@react-native-community/cli-server-api@13.6.6: resolution: {integrity: sha512-ZtCXxoFlM7oDv3iZ3wsrT3SamhtUJuIkX2WePLPlN5bcbq7zimbPm2lHyicNJtpcGQ5ymsgpUWPCNZsWQhXBqQ==} dependencies: @@ -13577,6 +13799,22 @@ packages: - supports-color - utf-8-validate + /@react-native-community/cli-tools@12.3.6: + resolution: {integrity: sha512-FPEvZn19UTMMXUp/piwKZSh8cMEfO8G3KDtOwo53O347GTcwNrKjgZGtLSPELBX2gr+YlzEft3CoRv2Qmo83fQ==} + dependencies: + appdirsjs: 1.2.7 + chalk: 4.1.2 + find-up: 5.0.0 + mime: 2.6.0 + node-fetch: 2.7.0 + open: 6.4.0 + ora: 5.4.1 + semver: 7.6.2 + shell-quote: 1.8.1 + sudo-prompt: 9.2.1 + transitivePeerDependencies: + - encoding + /@react-native-community/cli-tools@13.6.6: resolution: {integrity: sha512-ptOnn4AJczY5njvbdK91k4hcYazDnGtEPrqIwEI+k/CTBHNdb27Rsm2OZ7ye6f7otLBqF8gj/hK6QzJs8CEMgw==} dependencies: @@ -13612,6 +13850,11 @@ packages: transitivePeerDependencies: - encoding + /@react-native-community/cli-types@12.3.6: + resolution: {integrity: sha512-xPqTgcUtZowQ8WKOkI9TLGBwH2bGggOC4d2FFaIRST3gTcjrEeGRNeR5aXCzJFIgItIft8sd7p2oKEdy90+01Q==} + dependencies: + joi: 17.13.1 + /@react-native-community/cli-types@13.6.6: resolution: {integrity: sha512-733iaYzlmvNK7XYbnWlMjdE+2k0hlTBJW071af/xb6Bs+hbJqBP9c03FZuYH2hFFwDDntwj05bkri/P7VgSxug==} dependencies: @@ -13623,6 +13866,35 @@ packages: dependencies: joi: 17.13.1 + /@react-native-community/cli@12.3.6: + resolution: {integrity: sha512-647OSi6xBb8FbwFqX9zsJxOzu685AWtrOUWHfOkbKD+5LOpGORw+GQo0F9rWZnB68rLQyfKUZWJeaD00pGv5fw==} + engines: {node: '>=18'} + hasBin: true + dependencies: + '@react-native-community/cli-clean': 12.3.6 + '@react-native-community/cli-config': 12.3.6 + '@react-native-community/cli-debugger-ui': 12.3.6 + '@react-native-community/cli-doctor': 12.3.6 + '@react-native-community/cli-hermes': 12.3.6 + '@react-native-community/cli-plugin-metro': 12.3.6 + '@react-native-community/cli-server-api': 12.3.6 + '@react-native-community/cli-tools': 12.3.6 + '@react-native-community/cli-types': 12.3.6 + chalk: 4.1.2 + commander: 9.5.0 + deepmerge: 4.3.1 + execa: 5.1.1 + find-up: 4.1.0 + fs-extra: 8.1.0 + graceful-fs: 4.2.11 + prompts: 2.4.2 + semver: 7.6.2 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + /@react-native-community/cli@13.6.6: resolution: {integrity: sha512-IqclB7VQ84ye8Fcs89HOpOscY4284VZg2pojHNl8H0Lzd4DadXJWQoxC7zWm8v2f8eyeX2kdhxp2ETD5tceIgA==} engines: {node: '>=18'} @@ -13688,6 +13960,168 @@ packages: react-native: 0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(@types/react@18.3.3)(react@18.2.0) dev: false + /@react-native-mac/virtualized-lists@0.73.3(react-native@0.74.1): + resolution: {integrity: sha512-7UcvjGYLIU0s2FzVLUPxHYo68tqtZV6x0AH8B0Hf9mkkpENGdRIKD7wDv0kjb/GkVn+qk94u3u0kQyMNRY9UkQ==} + engines: {node: '>=18'} + peerDependencies: + react-native: '*' + dependencies: + invariant: 2.2.4 + nullthrows: 1.1.1 + react-native: 0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(@types/react@18.3.3)(react@18.2.0) + dev: false + + /@react-native-mac/virtualized-lists@0.73.3(react-native@0.74.2): + resolution: {integrity: sha512-7UcvjGYLIU0s2FzVLUPxHYo68tqtZV6x0AH8B0Hf9mkkpENGdRIKD7wDv0kjb/GkVn+qk94u3u0kQyMNRY9UkQ==} + engines: {node: '>=18'} + peerDependencies: + react-native: '*' + dependencies: + invariant: 2.2.4 + nullthrows: 1.1.1 + react-native: 0.74.2(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(@types/react@18.3.3)(react@18.3.1) + dev: true + + /@react-native-windows/cli@0.73.4(react-native@0.74.1): + resolution: {integrity: sha512-WVKcRbQSLV/gKA+jnhuC+8k+e0IM4Cla2WeEReBgkSI5uvrU9pEErV1hTdRQAmtUAtgA7QAuOFhZ5EEKKZSE8A==} + engines: {node: '>= 18'} + peerDependencies: + react-native: '*' + dependencies: + '@react-native-windows/codegen': 0.73.1(react-native@0.74.1) + '@react-native-windows/fs': 0.73.1 + '@react-native-windows/package-utils': 0.73.1 + '@react-native-windows/telemetry': 0.73.2 + '@xmldom/xmldom': 0.7.13 + chalk: 4.1.2 + cli-spinners: 2.9.2 + envinfo: 7.13.0 + find-up: 4.1.0 + glob: 7.2.3 + lodash: 4.17.21 + mustache: 4.2.0 + ora: 3.4.0 + prompts: 2.4.2 + react-native: 0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(@types/react@18.3.3)(react@18.2.0) + semver: 7.6.2 + shelljs: 0.8.5 + username: 5.1.0 + uuid: 3.4.0 + xml-formatter: 2.6.1 + xml-parser: 1.2.1 + xpath: 0.0.27 + transitivePeerDependencies: + - applicationinsights-native-metrics + - supports-color + dev: false + + /@react-native-windows/cli@0.73.4(react-native@0.74.2): + resolution: {integrity: sha512-WVKcRbQSLV/gKA+jnhuC+8k+e0IM4Cla2WeEReBgkSI5uvrU9pEErV1hTdRQAmtUAtgA7QAuOFhZ5EEKKZSE8A==} + engines: {node: '>= 18'} + peerDependencies: + react-native: '*' + dependencies: + '@react-native-windows/codegen': 0.73.1(react-native@0.74.2) + '@react-native-windows/fs': 0.73.1 + '@react-native-windows/package-utils': 0.73.1 + '@react-native-windows/telemetry': 0.73.2 + '@xmldom/xmldom': 0.7.13 + chalk: 4.1.2 + cli-spinners: 2.9.2 + envinfo: 7.13.0 + find-up: 4.1.0 + glob: 7.2.3 + lodash: 4.17.21 + mustache: 4.2.0 + ora: 3.4.0 + prompts: 2.4.2 + react-native: 0.74.2(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(@types/react@18.3.3)(react@18.3.1) + semver: 7.6.2 + shelljs: 0.8.5 + username: 5.1.0 + uuid: 3.4.0 + xml-formatter: 2.6.1 + xml-parser: 1.2.1 + xpath: 0.0.27 + transitivePeerDependencies: + - applicationinsights-native-metrics + - supports-color + dev: true + + /@react-native-windows/codegen@0.73.1(react-native@0.74.1): + resolution: {integrity: sha512-rwOYHwG9CJu9YPvjZH4rlCDWjNoJUokcfh8belumKD8eZh6G855RiJ3SmcGoozV3r4m7fYWGs71mjQmnyPScXw==} + engines: {node: '>= 18'} + hasBin: true + peerDependencies: + react-native: '*' + dependencies: + '@react-native-windows/fs': 0.73.1 + chalk: 4.1.2 + globby: 11.1.0 + mustache: 4.2.0 + react-native: 0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(@types/react@18.3.3)(react@18.2.0) + source-map-support: 0.5.21 + yargs: 16.2.0 + dev: false + + /@react-native-windows/codegen@0.73.1(react-native@0.74.2): + resolution: {integrity: sha512-rwOYHwG9CJu9YPvjZH4rlCDWjNoJUokcfh8belumKD8eZh6G855RiJ3SmcGoozV3r4m7fYWGs71mjQmnyPScXw==} + engines: {node: '>= 18'} + hasBin: true + peerDependencies: + react-native: '*' + dependencies: + '@react-native-windows/fs': 0.73.1 + chalk: 4.1.2 + globby: 11.1.0 + mustache: 4.2.0 + react-native: 0.74.2(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(@types/react@18.3.3)(react@18.3.1) + source-map-support: 0.5.21 + yargs: 16.2.0 + dev: true + + /@react-native-windows/find-repo-root@0.73.1: + resolution: {integrity: sha512-CsYidJxvJYIUmbqgrzZEWbVnZjvY4CpfVXlNKhi1BpYj0F26eCAHNHYS38QS+9FIoy+YOyE+jEoTsGVhXkXmOA==} + engines: {node: '>= 18'} + dependencies: + '@react-native-windows/fs': 0.73.1 + find-up: 4.1.0 + + /@react-native-windows/fs@0.73.1: + resolution: {integrity: sha512-FVJeyc1uRJguEdwWsucrOnRWQOB3JlRapPqL3EKUO/i1TX0Fbd8b8MCb9pjCOihoHnN0+aCY9Y8aSar2M33kAw==} + engines: {node: '>= 18'} + dependencies: + graceful-fs: 4.2.11 + + /@react-native-windows/package-utils@0.73.1: + resolution: {integrity: sha512-psr0ESygZWJoyCXreRzOOJa7cIWuZ5btrpeMYvoFej1p/CaJA65pLHuFiFaFi580KkHFvHJYG8mY3K4PDzqctA==} + engines: {node: '>= 18'} + dependencies: + '@react-native-windows/find-repo-root': 0.73.1 + '@react-native-windows/fs': 0.73.1 + get-monorepo-packages: 1.2.0 + lodash: 4.17.21 + + /@react-native-windows/telemetry@0.73.2: + resolution: {integrity: sha512-QOo5t6aiO+BlPdJgQGYY/9IWtOkI4h/YoAYbpuFsMsLfBuyzM+5yovoeamIf5Cd9zFYM0YUswZ0VJx4Q7zP4zQ==} + engines: {node: '>= 18'} + dependencies: + '@react-native-windows/fs': 0.73.1 + '@xmldom/xmldom': 0.7.13 + applicationinsights: 2.7.3 + ci-info: 3.9.0 + envinfo: 7.13.0 + lodash: 4.17.21 + os-locale: 5.0.0 + xpath: 0.0.27 + transitivePeerDependencies: + - applicationinsights-native-metrics + - supports-color + + /@react-native/assets-registry@0.73.1: + resolution: {integrity: sha512-2FgAbU7uKM5SbbW9QptPPZx8N9Ke2L7bsHb+EhAanZjFZunA9PaYtyjUQ1s7HD+zDVqOQIvjkpXSv7Kejd2tqg==} + engines: {node: '>=18'} + /@react-native/assets-registry@0.74.83: resolution: {integrity: sha512-2vkLMVnp+YTZYTNSDIBZojSsjz8sl5PscP3j4GcV6idD8V978SZfwFlk8K0ti0BzRs11mzL0Pj17km597S/eTQ==} engines: {node: '>=18'} @@ -13697,6 +14131,15 @@ packages: resolution: {integrity: sha512-dzUhwyaX04QosWZ8zyaaNB/WYZIdeDN1lcpfQbqiOhZJShRH+FLTDVONE/dqlMQrP+EO7lDqF0RrlIt9lnOCQQ==} engines: {node: '>=18'} + /@react-native/babel-plugin-codegen@0.73.4(@babel/preset-env@7.24.7): + resolution: {integrity: sha512-XzRd8MJGo4Zc5KsphDHBYJzS1ryOHg8I2gOZDAUCGcwLFhdyGu1zBNDJYH2GFyDrInn9TzAbRIf3d4O+eltXQQ==} + engines: {node: '>=18'} + dependencies: + '@react-native/codegen': 0.73.3(@babel/preset-env@7.24.7) + transitivePeerDependencies: + - '@babel/preset-env' + - supports-color + /@react-native/babel-plugin-codegen@0.74.83(@babel/preset-env@7.24.7): resolution: {integrity: sha512-+S0st3t4Ro00bi9gjT1jnK8qTFOU+CwmziA7U9odKyWrCoRJrgmrvogq/Dr1YXlpFxexiGIupGut1VHxr+fxJA==} engines: {node: '>=18'} @@ -13716,6 +14159,58 @@ packages: - '@babel/preset-env' - supports-color + /@react-native/babel-preset@0.73.21(@babel/core@7.24.5)(@babel/preset-env@7.24.7): + resolution: {integrity: sha512-WlFttNnySKQMeujN09fRmrdWqh46QyJluM5jdtDNrkl/2Hx6N4XeDUGhABvConeK95OidVO7sFFf7sNebVXogA==} + engines: {node: '>=18'} + peerDependencies: + '@babel/core': '*' + dependencies: + '@babel/core': 7.24.5 + '@babel/plugin-proposal-async-generator-functions': 7.20.7(@babel/core@7.24.5) + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.24.5) + '@babel/plugin-proposal-export-default-from': 7.24.1(@babel/core@7.24.5) + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.24.5) + '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.24.5) + '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.24.5) + '@babel/plugin-proposal-optional-catch-binding': 7.18.6(@babel/core@7.24.5) + '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.24.5) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.5) + '@babel/plugin-syntax-export-default-from': 7.24.1(@babel/core@7.24.5) + '@babel/plugin-syntax-flow': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.5) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.5) + '@babel/plugin-transform-arrow-functions': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-async-to-generator': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-block-scoping': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-classes': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-computed-properties': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-destructuring': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-flow-strip-types': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-function-name': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-literals': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-modules-commonjs': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-named-capturing-groups-regex': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-private-methods': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-private-property-in-object': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-react-display-name': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-react-jsx': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-react-jsx-self': 7.24.5(@babel/core@7.24.5) + '@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/core@7.24.5) + '@babel/plugin-transform-runtime': 7.24.3(@babel/core@7.24.5) + '@babel/plugin-transform-shorthand-properties': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-spread': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-sticky-regex': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-typescript': 7.24.7(@babel/core@7.24.5) + '@babel/plugin-transform-unicode-regex': 7.24.7(@babel/core@7.24.5) + '@babel/template': 7.24.7 + '@react-native/babel-plugin-codegen': 0.73.4(@babel/preset-env@7.24.7) + babel-plugin-transform-flow-enums: 0.0.2(@babel/core@7.24.5) + react-refresh: 0.14.2 + transitivePeerDependencies: + - '@babel/preset-env' + - supports-color + /@react-native/babel-preset@0.74.83(@babel/core@7.24.5)(@babel/preset-env@7.24.7): resolution: {integrity: sha512-KJuu3XyVh3qgyUer+rEqh9a/JoUxsDOzkJNfRpDyXiAyjDRoVch60X/Xa/NcEQ93iCVHAWs0yQ+XGNGIBCYE6g==} engines: {node: '>=18'} @@ -13823,6 +14318,23 @@ packages: - '@babel/preset-env' - supports-color + /@react-native/codegen@0.73.3(@babel/preset-env@7.24.7): + resolution: {integrity: sha512-sxslCAAb8kM06vGy9Jyh4TtvjhcP36k/rvj2QE2Jdhdm61KvfafCATSIsOfc0QvnduWFcpXUPvAVyYwuv7PYDg==} + engines: {node: '>=18'} + peerDependencies: + '@babel/preset-env': ^7.1.6 + dependencies: + '@babel/parser': 7.24.7 + '@babel/preset-env': 7.24.7(@babel/core@7.24.5) + flow-parser: 0.206.0 + glob: 7.2.3 + invariant: 2.2.4 + jscodeshift: 0.14.0(@babel/preset-env@7.24.7) + mkdirp: 0.5.6 + nullthrows: 1.1.1 + transitivePeerDependencies: + - supports-color + /@react-native/codegen@0.74.83(@babel/preset-env@7.24.7): resolution: {integrity: sha512-GgvgHS3Aa2J8/mp1uC/zU8HuTh8ZT5jz7a4mVMWPw7+rGyv70Ba8uOVBq6UH2Q08o617IATYc+0HfyzAfm4n0w==} engines: {node: '>=18'} @@ -13858,6 +14370,29 @@ packages: transitivePeerDependencies: - supports-color + /@react-native/community-cli-plugin@0.73.17(@babel/core@7.24.5)(@babel/preset-env@7.24.7): + resolution: {integrity: sha512-F3PXZkcHg+1ARIr6FRQCQiB7ZAA+MQXGmq051metRscoLvgYJwj7dgC8pvgy0kexzUkHu5BNKrZeySzUft3xuQ==} + engines: {node: '>=18'} + dependencies: + '@react-native-community/cli-server-api': 12.3.6 + '@react-native-community/cli-tools': 12.3.6 + '@react-native/dev-middleware': 0.73.8 + '@react-native/metro-babel-transformer': 0.73.15(@babel/core@7.24.5)(@babel/preset-env@7.24.7) + chalk: 4.1.2 + execa: 5.1.1 + metro: 0.80.9 + metro-config: 0.80.9 + metro-core: 0.80.9 + node-fetch: 2.7.0 + readline: 1.3.0 + transitivePeerDependencies: + - '@babel/core' + - '@babel/preset-env' + - bufferutil + - encoding + - supports-color + - utf-8-validate + /@react-native/community-cli-plugin@0.74.83(@babel/core@7.24.5)(@babel/preset-env@7.24.7): resolution: {integrity: sha512-7GAFjFOg1mFSj8bnFNQS4u8u7+QtrEeflUIDVZGEfBZQ3wMNI5ycBzbBGycsZYiq00Xvoc6eKFC7kvIaqeJpUQ==} engines: {node: '>=18'} @@ -13907,6 +14442,10 @@ packages: - supports-color - utf-8-validate + /@react-native/debugger-frontend@0.73.3: + resolution: {integrity: sha512-RgEKnWuoo54dh7gQhV7kvzKhXZEhpF9LlMdZolyhGxHsBqZ2gXdibfDlfcARFFifPIiaZ3lXuOVVa4ei+uPgTw==} + engines: {node: '>=18'} + /@react-native/debugger-frontend@0.74.83: resolution: {integrity: sha512-RGQlVUegBRxAUF9c1ss1ssaHZh6CO+7awgtI9sDeU0PzDZY/40ImoPD5m0o0SI6nXoVzbPtcMGzU+VO590pRfA==} engines: {node: '>=18'} @@ -13916,6 +14455,27 @@ packages: resolution: {integrity: sha512-YUEA03UNFbiYzHpYxlcS2D9+3eNT5YLGkl5yRg3nOSN6KbCc/OttGnNZme+tuSOJwjMN/vcvtDKYkTqjJw8U0A==} engines: {node: '>=18'} + /@react-native/dev-middleware@0.73.8: + resolution: {integrity: sha512-oph4NamCIxkMfUL/fYtSsE+JbGOnrlawfQ0kKtDQ5xbOjPKotKoXqrs1eGwozNKv7FfQ393stk1by9a6DyASSg==} + engines: {node: '>=18'} + dependencies: + '@isaacs/ttlcache': 1.4.1 + '@react-native/debugger-frontend': 0.73.3 + chrome-launcher: 0.15.2 + chromium-edge-launcher: 1.0.0 + connect: 3.7.0 + debug: 2.6.9 + node-fetch: 2.7.0 + open: 7.4.2 + serve-static: 1.15.0 + temp-dir: 2.0.0 + ws: 6.2.3 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + /@react-native/dev-middleware@0.74.83: resolution: {integrity: sha512-UH8iriqnf7N4Hpi20D7M2FdvSANwTVStwFCSD7VMU9agJX88Yk0D1T6Meh2RMhUu4kY2bv8sTkNRm7LmxvZqgA==} engines: {node: '>=18'} @@ -13963,6 +14523,10 @@ packages: - supports-color - utf-8-validate + /@react-native/gradle-plugin@0.73.4: + resolution: {integrity: sha512-PMDnbsZa+tD55Ug+W8CfqXiGoGneSSyrBZCMb5JfiB3AFST3Uj5e6lw8SgI/B6SKZF7lG0BhZ6YHZsRZ5MlXmg==} + engines: {node: '>=18'} + /@react-native/gradle-plugin@0.74.83: resolution: {integrity: sha512-Pw2BWVyOHoBuJVKxGVYF6/GSZRf6+v1Ygc+ULGz5t20N8qzRWPa2fRZWqoxsN7TkNLPsECYY8gooOl7okOcPAQ==} engines: {node: '>=18'} @@ -13972,6 +14536,10 @@ packages: resolution: {integrity: sha512-wYWC5WWXqzCCe4PDogz9pNc4xH5ZamahW5XGSbrrYJ5V3walZ+7z43V6iEBJkZbLjj9YBcSttkXYGr1Xh4veAg==} engines: {node: '>=18'} + /@react-native/js-polyfills@0.73.1: + resolution: {integrity: sha512-ewMwGcumrilnF87H4jjrnvGZEaPFCAC4ebraEK+CurDDmwST/bIicI4hrOAv+0Z0F7DEK4O4H7r8q9vH7IbN4g==} + engines: {node: '>=18'} + /@react-native/js-polyfills@0.74.83: resolution: {integrity: sha512-/t74n8r6wFhw4JEoOj3bN71N1NDLqaawB75uKAsSjeCwIR9AfCxlzZG0etsXtOexkY9KMeZIQ7YwRPqUdNXuqw==} engines: {node: '>=18'} @@ -13981,6 +14549,20 @@ packages: resolution: {integrity: sha512-+PgxuUjBw9JVlz6m4ECsIJMLbDopnr4rpLmsG32hQaJrg0wMuvHtsgAY/J/aVCSG2GNUXexfjrnhc+O9yGOZXQ==} engines: {node: '>=18'} + /@react-native/metro-babel-transformer@0.73.15(@babel/core@7.24.5)(@babel/preset-env@7.24.7): + resolution: {integrity: sha512-LlkSGaXCz+xdxc9819plmpsl4P4gZndoFtpjN3GMBIu6f7TBV0GVbyJAU4GE8fuAWPVSVL5ArOcdkWKSbI1klw==} + engines: {node: '>=18'} + peerDependencies: + '@babel/core': '*' + dependencies: + '@babel/core': 7.24.5 + '@react-native/babel-preset': 0.73.21(@babel/core@7.24.5)(@babel/preset-env@7.24.7) + hermes-parser: 0.15.0 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@babel/preset-env' + - supports-color + /@react-native/metro-babel-transformer@0.74.83(@babel/core@7.24.5)(@babel/preset-env@7.24.7): resolution: {integrity: sha512-hGdx5N8diu8y+GW/ED39vTZa9Jx1di2ZZ0aapbhH4egN1agIAusj5jXTccfNBwwWF93aJ5oVbRzfteZgjbutKg==} engines: {node: '>=18'} @@ -14010,6 +14592,9 @@ packages: - '@babel/preset-env' - supports-color + /@react-native/normalize-colors@0.73.2: + resolution: {integrity: sha512-bRBcb2T+I88aG74LMVHaKms2p/T8aQd8+BZ7LuuzXlRfog1bMWWn/C5i0HVuvW4RPtXQYgIlGiXVDy9Ir1So/w==} + /@react-native/normalize-colors@0.74.83: resolution: {integrity: sha512-jhCY95gRDE44qYawWVvhTjTplW1g+JtKTKM3f8xYT1dJtJ8QWv+gqEtKcfmOHfDkSDaMKG0AGBaDTSK8GXLH8Q==} dev: false @@ -14017,6 +14602,28 @@ packages: /@react-native/normalize-colors@0.74.84: resolution: {integrity: sha512-Y5W6x8cC5RuakUcTVUFNAIhUZ/tYpuqHZlRBoAuakrTwVuoNHXfQki8lj1KsYU7rW6e3VWgdEx33AfOQpdNp6A==} + /@react-native/virtualized-lists@0.73.4(react-native@0.74.1): + resolution: {integrity: sha512-HpmLg1FrEiDtrtAbXiwCgXFYyloK/dOIPIuWW3fsqukwJEWAiTzm1nXGJ7xPU5XTHiWZ4sKup5Ebaj8z7iyWog==} + engines: {node: '>=18'} + peerDependencies: + react-native: '*' + dependencies: + invariant: 2.2.4 + nullthrows: 1.1.1 + react-native: 0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(@types/react@18.3.3)(react@18.2.0) + dev: false + + /@react-native/virtualized-lists@0.73.4(react-native@0.74.2): + resolution: {integrity: sha512-HpmLg1FrEiDtrtAbXiwCgXFYyloK/dOIPIuWW3fsqukwJEWAiTzm1nXGJ7xPU5XTHiWZ4sKup5Ebaj8z7iyWog==} + engines: {node: '>=18'} + peerDependencies: + react-native: '*' + dependencies: + invariant: 2.2.4 + nullthrows: 1.1.1 + react-native: 0.74.2(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(@types/react@18.3.3)(react@18.3.1) + dev: true + /@react-native/virtualized-lists@0.74.83(@types/react@18.3.3)(react-native@0.74.1)(react@18.2.0): resolution: {integrity: sha512-rmaLeE34rj7py4FxTod7iMTC7BAsm+HrGA8WxYmEJeyTV7WSaxAkosKoYBz8038mOiwnG9VwA/7FrB6bEQvn1A==} engines: {node: '>=18'} @@ -16329,7 +16936,6 @@ packages: /@tootallnate/once@2.0.0: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} - dev: false /@tootallnate/quickjs-emscripten@0.23.0: resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} @@ -16972,7 +17578,6 @@ packages: /@types/shimmer@1.0.5: resolution: {integrity: sha512-9Hp0ObzwwO57DpLFF0InUjUm/II8GmKAvzbefxQTihCb7KI6yc9yzf0nLc4mVdby5N4DRCgQM2wCup9KTieeww==} - dev: false /@types/spdx-correct@3.1.3: resolution: {integrity: sha512-fdQ0oyqcKpAH+FwNEerZl1oTslsrhFYhdbb21IO1FKXK/+TFYM2IO1c/Nvsh7MCPVp8TYEAPXIOlXUJRkWoUWQ==} @@ -18379,8 +18984,6 @@ packages: acorn: ^8 dependencies: acorn: 8.11.3 - dev: false - optional: true /acorn-import-attributes@1.9.5(acorn@8.11.3): resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} @@ -18638,6 +19241,31 @@ packages: /application-config-path@0.1.1: resolution: {integrity: sha512-zy9cHePtMP0YhwG+CfHm0bgwdnga2X3gZexpdCwEj//dpb+TKajtiC8REEUJUSq6Ab4f9cgNy2l8ObXzCXFkEw==} + /applicationinsights@2.7.3: + resolution: {integrity: sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw==} + engines: {node: '>=8.0.0'} + peerDependencies: + applicationinsights-native-metrics: '*' + peerDependenciesMeta: + applicationinsights-native-metrics: + optional: true + dependencies: + '@azure/core-auth': 1.7.2 + '@azure/core-rest-pipeline': 1.10.1 + '@azure/core-util': 1.2.0 + '@azure/opentelemetry-instrumentation-azure-sdk': 1.0.0-beta.5 + '@microsoft/applicationinsights-web-snippet': 1.2.0 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + cls-hooked: 4.2.2 + continuation-local-storage: 3.2.1 + diagnostic-channel: 1.1.1 + diagnostic-channel-publishers: 1.0.7(diagnostic-channel@1.1.1) + transitivePeerDependencies: + - supports-color + /arch@2.2.0: resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} dev: true @@ -18715,10 +19343,20 @@ packages: is-number: 4.0.0 dev: true + /array-union@1.0.2: + resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} + engines: {node: '>=0.10.0'} + dependencies: + array-uniq: 1.0.3 + /array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} + /array-uniq@1.0.3: + resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} + engines: {node: '>=0.10.0'} + /array.prototype.findlast@1.2.5: resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} engines: {node: '>= 0.4'} @@ -18879,9 +19517,22 @@ packages: engines: {node: '>=8'} dev: true + /async-hook-jl@1.7.6: + resolution: {integrity: sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==} + engines: {node: ^4.7 || >=6.9 || >=7.3} + dependencies: + stack-chain: 1.3.7 + /async-limiter@1.0.1: resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} + /async-listener@0.6.10: + resolution: {integrity: sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==} + engines: {node: <=0.11.8 || >0.11.10} + dependencies: + semver: 7.6.2 + shimmer: 1.2.1 + /async-mqtt@2.6.3: resolution: {integrity: sha512-mFGTtlEpOugOoLOf9H5AJyJaZUNtOVXLGGOnPaPZDPQex6W6iIOgtV+fAgam0GQbgnLfgX+Wn/QzS6d+PYfFAQ==} dependencies: @@ -19989,6 +20640,18 @@ packages: zod: 3.22.4 dev: true + /chromium-edge-launcher@1.0.0: + resolution: {integrity: sha512-pgtgjNKZ7i5U++1g1PWv75umkHvhVTDOQIZ+sjeUX9483S7Y6MUvO0lrd7ShGlQlFHMN4SwKTCq/X8hWrbv2KA==} + dependencies: + '@types/node': 20.14.9 + escape-string-regexp: 4.0.0 + is-wsl: 2.2.0 + lighthouse-logger: 1.4.2 + mkdirp: 1.0.4 + rimraf: 3.0.2 + transitivePeerDependencies: + - supports-color + /ci-info@2.0.0: resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} @@ -20039,7 +20702,6 @@ packages: /cjs-module-lexer@1.3.1: resolution: {integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==} - dev: false /class-variance-authority@0.7.0: resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==} @@ -20192,6 +20854,14 @@ packages: resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} engines: {node: '>=0.8'} + /cls-hooked@4.2.2: + resolution: {integrity: sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==} + engines: {node: ^4.7 || >=6.9 || >=7.3 || >=8.2.1} + dependencies: + async-hook-jl: 1.7.6 + emitter-listener: 1.1.2 + semver: 7.6.2 + /clsx@1.2.1: resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} engines: {node: '>=6'} @@ -20451,6 +21121,12 @@ packages: engines: {node: '>= 0.6'} dev: true + /continuation-local-storage@3.2.1: + resolution: {integrity: sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==} + dependencies: + async-listener: 0.6.10 + emitter-listener: 1.1.2 + /convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} @@ -21078,6 +21754,14 @@ packages: - supports-color dev: true + /deprecated-react-native-prop-types@5.0.0: + resolution: {integrity: sha512-cIK8KYiiGVOFsKdPMmm1L3tA/Gl+JopXL6F5+C7x39MyPsQYnP57Im/D6bNUzcborD7fcMwiwZqcBdBXXZucYQ==} + engines: {node: '>=18'} + dependencies: + '@react-native/normalize-colors': 0.73.2 + invariant: 2.2.4 + prop-types: 15.8.1 + /dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -21228,6 +21912,18 @@ packages: resolution: {integrity: sha512-YJe4CT5SA8on3Spa+UDtNhEqtuV6Epwz3OZ4HQVLhlRccpZ9/PAYk0/cy/oKxFKRrZPBUPyxympQci4yWNWZ9g==} dev: true + /diagnostic-channel-publishers@1.0.7(diagnostic-channel@1.1.1): + resolution: {integrity: sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg==} + peerDependencies: + diagnostic-channel: '*' + dependencies: + diagnostic-channel: 1.1.1 + + /diagnostic-channel@1.1.1: + resolution: {integrity: sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw==} + dependencies: + semver: 7.6.2 + /didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} @@ -21257,6 +21953,12 @@ packages: resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} dev: false + /dir-glob@2.2.2: + resolution: {integrity: sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==} + engines: {node: '>=4'} + dependencies: + path-type: 3.0.0 + /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -21454,6 +22156,11 @@ packages: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 + /emitter-listener@1.1.2: + resolution: {integrity: sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==} + dependencies: + shimmer: 1.2.1 + /emoji-regex@10.3.0: resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} @@ -22628,6 +23335,20 @@ packages: signal-exit: 3.0.7 strip-eof: 1.0.0 + /execa@4.1.0: + resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 5.2.0 + human-signals: 1.1.1 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + /execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -23326,6 +24047,10 @@ packages: /flow-enums-runtime@0.0.6: resolution: {integrity: sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==} + /flow-parser@0.206.0: + resolution: {integrity: sha512-HVzoK3r6Vsg+lKvlIZzaWNBVai+FXTX1wdYhz/wVlH13tb/gOdLXmlTqy6odmTBhT5UoWUbq0k8263Qhr9d88w==} + engines: {node: '>=0.4.0'} + /flow-parser@0.236.0: resolution: {integrity: sha512-0OEk9Gr+Yj7wjDW2KgaNYUypKau71jAfFyeLQF5iVtxqc6uJHag/MT7pmaEApf4qM7u86DkBcd4ualddYMfbLw==} engines: {node: '>=0.4.0'} @@ -23624,6 +24349,12 @@ packages: has-symbols: 1.0.3 hasown: 2.0.2 + /get-monorepo-packages@1.2.0: + resolution: {integrity: sha512-aDP6tH+eM3EuVSp3YyCutOcFS4Y9AhRRH9FAd+cjtR/g63Hx+DCXdKoP1ViRPUJz5wm+BOEXB4FhoffGHxJ7jQ==} + dependencies: + globby: 7.1.1 + load-json-file: 4.0.0 + /get-nonce@1.0.1: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} @@ -23917,6 +24648,17 @@ packages: unicorn-magic: 0.1.0 dev: true + /globby@7.1.1: + resolution: {integrity: sha512-yANWAN2DUcBtuus5Cpd+SKROzXHs2iVXFZt/Ykrfz6SAXqacLX25NZpltE+39ceMexYF4TtEadjuSTw8+3wX4g==} + engines: {node: '>=4'} + dependencies: + array-union: 1.0.2 + dir-glob: 2.2.2 + glob: 7.2.3 + ignore: 3.3.10 + pify: 3.0.0 + slash: 1.0.0 + /gonzales-pe@4.3.0: resolution: {integrity: sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==} engines: {node: '>=0.6.0'} @@ -24284,12 +25026,20 @@ packages: readable-stream: 3.6.2 dev: true + /hermes-estree@0.15.0: + resolution: {integrity: sha512-lLYvAd+6BnOqWdnNbP/Q8xfl8LOGw4wVjfrNd9Gt8eoFzhNBRVD95n4l2ksfMVOoxuVyegs85g83KS9QOsxbVQ==} + /hermes-estree@0.19.1: resolution: {integrity: sha512-daLGV3Q2MKk8w4evNMKwS8zBE/rcpA800nu1Q5kM08IKijoSnPe9Uo1iIxzPKRkn95IxxsgBMPeYHt3VG4ej2g==} /hermes-estree@0.20.1: resolution: {integrity: sha512-SQpZK4BzR48kuOg0v4pb3EAGNclzIlqMj3Opu/mu7bbAoFw6oig6cEt/RAi0zTFW/iW6Iz9X9ggGuZTAZ/yZHg==} + /hermes-parser@0.15.0: + resolution: {integrity: sha512-Q1uks5rjZlE9RjMMjSUCkGrEIPI5pKJILeCtK1VmTj7U4pf3wVPoo+cxfu+s4cBAPy2JzikIIdCZgBoR6x7U1Q==} + dependencies: + hermes-estree: 0.15.0 + /hermes-parser@0.19.1: resolution: {integrity: sha512-Vp+bXzxYJWrpEuJ/vXxUsLnt0+y4q9zyi4zUlkLqD8FKv4LjIfOvP69R/9Lty3dCyKh0E2BU7Eypqr63/rKT/A==} dependencies: @@ -24390,7 +25140,6 @@ packages: debug: 4.3.5(supports-color@8.1.1) transitivePeerDependencies: - supports-color - dev: false /http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} @@ -24457,6 +25206,10 @@ packages: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} dev: true + /human-signals@1.1.1: + resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} + engines: {node: '>=8.12.0'} + /human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -24509,6 +25262,9 @@ packages: minimatch: 3.1.2 dev: true + /ignore@3.3.10: + resolution: {integrity: sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==} + /ignore@5.3.1: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} @@ -24558,8 +25314,6 @@ packages: acorn-import-assertions: 1.9.0(acorn@8.11.3) cjs-module-lexer: 1.3.1 module-details-from-path: 1.0.3 - dev: false - optional: true /import-in-the-middle@1.7.4: resolution: {integrity: sha512-Lk+qzWmiQuRPPulGQeK5qq0v32k2bHnWrRPFgqyvhw7Kkov5L6MOLOIU3pcWeujc9W4q54Cp3Q2WV16eQkc7Bg==} @@ -24693,7 +25447,6 @@ packages: /interpret@1.4.0: resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} engines: {node: '>= 0.10'} - dev: true /interpret@3.1.1: resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==} @@ -24704,6 +25457,10 @@ packages: dependencies: loose-envify: 1.4.0 + /invert-kv@3.0.1: + resolution: {integrity: sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==} + engines: {node: '>=8'} + /io-ts@1.10.4: resolution: {integrity: sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==} dependencies: @@ -25790,6 +26547,12 @@ packages: package-json: 8.1.1 dev: false + /lcid@3.1.1: + resolution: {integrity: sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg==} + engines: {node: '>=8'} + dependencies: + invert-kv: 3.0.1 + /leven@2.1.0: resolution: {integrity: sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==} engines: {node: '>=0.10.0'} @@ -25972,6 +26735,15 @@ packages: lit-html: 2.8.0 dev: false + /load-json-file@4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} + dependencies: + graceful-fs: 4.2.11 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 + /load-tsconfig@0.2.5: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -26344,6 +27116,12 @@ packages: dependencies: tmpl: 1.0.5 + /map-age-cleaner@0.1.3: + resolution: {integrity: sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==} + engines: {node: '>=6'} + dependencies: + p-defer: 1.0.0 + /map-obj@1.0.1: resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} engines: {node: '>=0.10.0'} @@ -26593,6 +27371,22 @@ packages: engines: {node: '>= 0.6'} dev: true + /mem@4.3.0: + resolution: {integrity: sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==} + engines: {node: '>=6'} + dependencies: + map-age-cleaner: 0.1.3 + mimic-fn: 2.1.0 + p-is-promise: 2.1.0 + + /mem@5.1.1: + resolution: {integrity: sha512-qvwipnozMohxLXG1pOqoLiZKNkC4r4qqRucSoDwXowsNGDSULiqFTRUF05vcZWnwJSG22qTsynQhxbaMtnX9gw==} + engines: {node: '>=8'} + dependencies: + map-age-cleaner: 0.1.3 + mimic-fn: 2.1.0 + p-is-promise: 2.1.0 + /memoize-one@5.2.1: resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} @@ -27415,7 +28209,6 @@ packages: /module-details-from-path@1.0.3: resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==} - dev: false /module-lookup-amd@7.0.1: resolution: {integrity: sha512-w9mCNlj0S8qviuHzpakaLVc+/7q50jl9a/kmJ/n8bmXQZgDPkQHnPBb8MUOYh3WpAYkXuNc2c+khsozhIp/amQ==} @@ -27527,6 +28320,10 @@ packages: varint: 5.0.2 dev: false + /mustache@4.2.0: + resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} + hasBin: true + /mute-stream@0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} dev: false @@ -28450,6 +29247,14 @@ packages: resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} engines: {node: '>=0.10.0'} + /os-locale@5.0.0: + resolution: {integrity: sha512-tqZcNEDAIZKBEPnHPlVDvKrp7NzgLi7jRmhKiUoa2NUmhl13FtkAGLUVR+ZsYvApBQdBfYm43A4tXXQ4IrYLBA==} + engines: {node: '>=10'} + dependencies: + execa: 4.1.0 + lcid: 3.1.1 + mem: 5.1.1 + /os-paths@7.4.0: resolution: {integrity: sha512-Ux1J4NUqC6tZayBqLN1kUlDAEvLiQlli/53sSddU4IN+h+3xxnv2HmRSMpVSvr1hvJzotfMs3ERvETGK+f4OwA==} engines: {node: '>= 4.0'} @@ -28480,6 +29285,10 @@ packages: resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} engines: {node: '>=12.20'} + /p-defer@1.0.0: + resolution: {integrity: sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==} + engines: {node: '>=4'} + /p-filter@2.1.0: resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} engines: {node: '>=8'} @@ -28491,6 +29300,10 @@ packages: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} + /p-is-promise@2.1.0: + resolution: {integrity: sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==} + engines: {node: '>=6'} + /p-limit@1.3.0: resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} engines: {node: '>=4'} @@ -28820,6 +29633,12 @@ packages: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} dev: true + /path-type@3.0.0: + resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} + engines: {node: '>=4'} + dependencies: + pify: 3.0.0 + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -28902,7 +29721,6 @@ packages: /pify@3.0.0: resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} engines: {node: '>=4'} - dev: false /pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} @@ -29736,6 +30554,15 @@ packages: react: 18.3.1 dev: false + /react-devtools-core@4.28.5: + resolution: {integrity: sha512-cq/o30z9W2Wb4rzBefjv5fBalHU0rJGZCHAkf/RHSBWSSYwh8PlQTqqOJmgIIbBtpj27T6FIPXeomIjZtCNVqA==} + dependencies: + shell-quote: 1.8.1 + ws: 7.5.10 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + /react-devtools-core@5.2.0: resolution: {integrity: sha512-vZK+/gvxxsieAoAyYaiRIVFxlajb7KXhgBDV7OsoMzaAE+IqGpoxusBjIgq5ibqA2IloKu0p9n7tE68z1xs18A==} dependencies: @@ -29924,6 +30751,118 @@ packages: react-native: 0.74.2(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(@types/react@18.3.3)(react@18.3.1) dev: true + /react-native-macos@0.73.32(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(react-native@0.74.1)(react@18.2.0): + resolution: {integrity: sha512-NNQEUAHYs8Vr1tNRiU5cgWj3Z+ktNPEjJa8EYiGjAFRPohhfkMqHvkhhGHninxyI3GR+mXkAy+bDvqPIWXlxOA==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + react: 18.2.0 + dependencies: + '@jest/create-cache-key-function': 29.7.0 + '@react-native-community/cli': 12.3.6 + '@react-native-community/cli-platform-android': 12.3.6 + '@react-native-community/cli-platform-ios': 12.3.6 + '@react-native-mac/virtualized-lists': 0.73.3(react-native@0.74.1) + '@react-native/assets-registry': 0.73.1 + '@react-native/codegen': 0.73.3(@babel/preset-env@7.24.7) + '@react-native/community-cli-plugin': 0.73.17(@babel/core@7.24.5)(@babel/preset-env@7.24.7) + '@react-native/gradle-plugin': 0.73.4 + '@react-native/js-polyfills': 0.73.1 + '@react-native/normalize-colors': 0.73.2 + abort-controller: 3.0.0 + anser: 1.4.10 + ansi-regex: 5.0.1 + base64-js: 1.5.1 + chalk: 4.1.2 + deprecated-react-native-prop-types: 5.0.0 + event-target-shim: 5.0.1 + flow-enums-runtime: 0.0.6 + invariant: 2.2.4 + jest-environment-node: 29.7.0 + jsc-android: 250231.0.0 + memoize-one: 5.2.1 + metro-runtime: 0.80.9 + metro-source-map: 0.80.9 + mkdirp: 0.5.6 + nullthrows: 1.1.1 + pretty-format: 26.6.2 + promise: 8.3.0 + react: 18.2.0 + react-devtools-core: 4.28.5 + react-refresh: 0.14.2 + react-shallow-renderer: 16.15.0(react@18.2.0) + regenerator-runtime: 0.13.11 + scheduler: 0.24.0-canary-efb381bbf-20230505 + stacktrace-parser: 0.1.10 + whatwg-fetch: 3.6.20 + ws: 6.2.3 + yargs: 17.7.2 + transitivePeerDependencies: + - '@babel/core' + - '@babel/preset-env' + - bufferutil + - encoding + - react-native + - supports-color + - utf-8-validate + dev: false + + /react-native-macos@0.73.32(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(react-native@0.74.2)(react@18.3.1): + resolution: {integrity: sha512-NNQEUAHYs8Vr1tNRiU5cgWj3Z+ktNPEjJa8EYiGjAFRPohhfkMqHvkhhGHninxyI3GR+mXkAy+bDvqPIWXlxOA==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + react: 18.2.0 + dependencies: + '@jest/create-cache-key-function': 29.7.0 + '@react-native-community/cli': 12.3.6 + '@react-native-community/cli-platform-android': 12.3.6 + '@react-native-community/cli-platform-ios': 12.3.6 + '@react-native-mac/virtualized-lists': 0.73.3(react-native@0.74.2) + '@react-native/assets-registry': 0.73.1 + '@react-native/codegen': 0.73.3(@babel/preset-env@7.24.7) + '@react-native/community-cli-plugin': 0.73.17(@babel/core@7.24.5)(@babel/preset-env@7.24.7) + '@react-native/gradle-plugin': 0.73.4 + '@react-native/js-polyfills': 0.73.1 + '@react-native/normalize-colors': 0.73.2 + abort-controller: 3.0.0 + anser: 1.4.10 + ansi-regex: 5.0.1 + base64-js: 1.5.1 + chalk: 4.1.2 + deprecated-react-native-prop-types: 5.0.0 + event-target-shim: 5.0.1 + flow-enums-runtime: 0.0.6 + invariant: 2.2.4 + jest-environment-node: 29.7.0 + jsc-android: 250231.0.0 + memoize-one: 5.2.1 + metro-runtime: 0.80.9 + metro-source-map: 0.80.9 + mkdirp: 0.5.6 + nullthrows: 1.1.1 + pretty-format: 26.6.2 + promise: 8.3.0 + react: 18.3.1 + react-devtools-core: 4.28.5 + react-refresh: 0.14.2 + react-shallow-renderer: 16.15.0(react@18.3.1) + regenerator-runtime: 0.13.11 + scheduler: 0.24.0-canary-efb381bbf-20230505 + stacktrace-parser: 0.1.10 + whatwg-fetch: 3.6.20 + ws: 6.2.3 + yargs: 17.7.2 + transitivePeerDependencies: + - '@babel/core' + - '@babel/preset-env' + - bufferutil + - encoding + - react-native + - supports-color + - utf-8-validate + dev: true + /react-native-mmkv@2.11.0(react-native@0.74.1)(react@18.2.0): resolution: {integrity: sha512-28PdUHjZJmAw3q+8zJDAAdohnZMpDC7WgRUJxACOMkcmJeqS3u5cKS/lSq2bhf1CvaeIiHYHUWiyatUjMRCDQQ==} peerDependencies: @@ -30043,6 +30982,126 @@ packages: whatwg-url-without-unicode: 8.0.0-3 dev: false + /react-native-windows@0.73.15(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(react-native@0.74.1)(react@18.2.0): + resolution: {integrity: sha512-kKBkjro9MN2ZcDEUG1lLL+2X99SzJ5qk78gJpqyWLHY505GnSjoldwdYh3l1LZsaLEvzNdndya0wYin//Nmj8g==} + engines: {node: '>= 18'} + peerDependencies: + react: 18.2.0 + react-native: ^0.73.0 + dependencies: + '@babel/runtime': 7.24.5 + '@jest/create-cache-key-function': 29.7.0 + '@react-native-community/cli': 12.3.6 + '@react-native-community/cli-platform-android': 12.3.6 + '@react-native-community/cli-platform-ios': 12.3.6 + '@react-native-windows/cli': 0.73.4(react-native@0.74.1) + '@react-native/assets-registry': 0.73.1 + '@react-native/codegen': 0.73.3(@babel/preset-env@7.24.7) + '@react-native/community-cli-plugin': 0.73.17(@babel/core@7.24.5)(@babel/preset-env@7.24.7) + '@react-native/gradle-plugin': 0.73.4 + '@react-native/js-polyfills': 0.73.1 + '@react-native/normalize-colors': 0.73.2 + '@react-native/virtualized-lists': 0.73.4(react-native@0.74.1) + abort-controller: 3.0.0 + anser: 1.4.10 + ansi-regex: 5.0.1 + base64-js: 1.5.1 + chalk: 4.1.2 + deprecated-react-native-prop-types: 5.0.0 + event-target-shim: 5.0.1 + flow-enums-runtime: 0.0.6 + invariant: 2.2.4 + jest-environment-node: 29.7.0 + jsc-android: 250231.0.0 + memoize-one: 5.2.1 + metro-runtime: 0.80.9 + metro-source-map: 0.80.9 + mkdirp: 0.5.6 + nullthrows: 1.1.1 + pretty-format: 26.6.2 + promise: 8.3.0 + react: 18.2.0 + react-devtools-core: 4.28.5 + react-native: 0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(@types/react@18.3.3)(react@18.2.0) + react-refresh: 0.14.2 + react-shallow-renderer: 16.15.0(react@18.2.0) + regenerator-runtime: 0.13.11 + scheduler: 0.24.0-canary-efb381bbf-20230505 + source-map-support: 0.5.21 + stacktrace-parser: 0.1.10 + whatwg-fetch: 3.6.20 + ws: 6.2.3 + yargs: 17.7.2 + transitivePeerDependencies: + - '@babel/core' + - '@babel/preset-env' + - applicationinsights-native-metrics + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: false + + /react-native-windows@0.73.15(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(react-native@0.74.2)(react@18.3.1): + resolution: {integrity: sha512-kKBkjro9MN2ZcDEUG1lLL+2X99SzJ5qk78gJpqyWLHY505GnSjoldwdYh3l1LZsaLEvzNdndya0wYin//Nmj8g==} + engines: {node: '>= 18'} + peerDependencies: + react: 18.2.0 + react-native: ^0.73.0 + dependencies: + '@babel/runtime': 7.24.5 + '@jest/create-cache-key-function': 29.7.0 + '@react-native-community/cli': 12.3.6 + '@react-native-community/cli-platform-android': 12.3.6 + '@react-native-community/cli-platform-ios': 12.3.6 + '@react-native-windows/cli': 0.73.4(react-native@0.74.2) + '@react-native/assets-registry': 0.73.1 + '@react-native/codegen': 0.73.3(@babel/preset-env@7.24.7) + '@react-native/community-cli-plugin': 0.73.17(@babel/core@7.24.5)(@babel/preset-env@7.24.7) + '@react-native/gradle-plugin': 0.73.4 + '@react-native/js-polyfills': 0.73.1 + '@react-native/normalize-colors': 0.73.2 + '@react-native/virtualized-lists': 0.73.4(react-native@0.74.2) + abort-controller: 3.0.0 + anser: 1.4.10 + ansi-regex: 5.0.1 + base64-js: 1.5.1 + chalk: 4.1.2 + deprecated-react-native-prop-types: 5.0.0 + event-target-shim: 5.0.1 + flow-enums-runtime: 0.0.6 + invariant: 2.2.4 + jest-environment-node: 29.7.0 + jsc-android: 250231.0.0 + memoize-one: 5.2.1 + metro-runtime: 0.80.9 + metro-source-map: 0.80.9 + mkdirp: 0.5.6 + nullthrows: 1.1.1 + pretty-format: 26.6.2 + promise: 8.3.0 + react: 18.3.1 + react-devtools-core: 4.28.5 + react-native: 0.74.2(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(@types/react@18.3.3)(react@18.3.1) + react-refresh: 0.14.2 + react-shallow-renderer: 16.15.0(react@18.3.1) + regenerator-runtime: 0.13.11 + scheduler: 0.24.0-canary-efb381bbf-20230505 + source-map-support: 0.5.21 + stacktrace-parser: 0.1.10 + whatwg-fetch: 3.6.20 + ws: 6.2.3 + yargs: 17.7.2 + transitivePeerDependencies: + - '@babel/core' + - '@babel/preset-env' + - applicationinsights-native-metrics + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: true + /react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.24.7)(@types/react@18.3.3)(react@18.2.0): resolution: {integrity: sha512-0H2XpmghwOtfPpM2LKqHIN7gxy+7G/r1hwJHKLV6uoyXGC/gCojRtoo5NqyKrWpFC8cqyT6wTYCLuG7CxEKilg==} engines: {node: '>=18'} @@ -30511,7 +31570,6 @@ packages: engines: {node: '>= 0.10'} dependencies: resolve: 1.22.8 - dev: true /rechoir@0.8.0: resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} @@ -30715,7 +31773,6 @@ packages: resolve: 1.22.8 transitivePeerDependencies: - supports-color - dev: false /require-main-filename@2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} @@ -31327,7 +32384,6 @@ packages: glob: 7.2.3 interpret: 1.4.0 rechoir: 0.6.2 - dev: true /shiki@0.14.7: resolution: {integrity: sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==} @@ -31346,7 +32402,6 @@ packages: /shimmer@1.2.1: resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==} - dev: false /short-unique-id@5.2.0: resolution: {integrity: sha512-cMGfwNyfDZ/nzJ2k2M+ClthBIh//GlZl1JEf47Uoa9XR11bz8Pa2T2wQO4bVrRdH48LrIDWJahQziKo3MjhsWg==} @@ -31433,6 +32488,10 @@ packages: picocolors: 1.0.1 dev: true + /slash@1.0.0: + resolution: {integrity: sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==} + engines: {node: '>=0.10.0'} + /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -31682,6 +32741,9 @@ packages: dependencies: minipass: 3.3.6 + /stack-chain@1.3.7: + resolution: {integrity: sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug==} + /stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} @@ -33568,6 +34630,13 @@ packages: react: 18.3.1 dev: false + /username@5.1.0: + resolution: {integrity: sha512-PCKbdWw85JsYMvmCv5GH3kXmM66rCd9m1hBEDutPNv94b/pqCMT4NtcKyeWYvLFiE8b+ha1Jdl8XAaUdPn5QTg==} + engines: {node: '>=8'} + dependencies: + execa: 1.0.0 + mem: 4.3.0 + /utf-8-validate@5.0.10: resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} engines: {node: '>=6.14.2'} @@ -34608,6 +35677,23 @@ packages: repeat-string: 1.6.1 dev: false + /xml-formatter@2.6.1: + resolution: {integrity: sha512-dOiGwoqm8y22QdTNI7A+N03tyVfBlQ0/oehAzxIZtwnFAHGeSlrfjF73YQvzSsa/Kt6+YZasKsrdu6OIpuBggw==} + engines: {node: '>= 10'} + dependencies: + xml-parser-xo: 3.2.0 + + /xml-parser-xo@3.2.0: + resolution: {integrity: sha512-8LRU6cq+d7mVsoDaMhnkkt3CTtAs4153p49fRo+HIB3I1FD1o5CeXRjRH29sQevIfVJIcPjKSsPU/+Ujhq09Rg==} + engines: {node: '>= 10'} + + /xml-parser@1.2.1: + resolution: {integrity: sha512-lPUzzmS0zdwcNtyNndCl2IwH172ozkUDqmfmH3FcuDzHVl552Kr6oNfsvteHabqTWhsrMgpijqZ/yT7Wo1/Pzw==} + dependencies: + debug: 2.6.9 + transitivePeerDependencies: + - supports-color + /xml2js@0.6.0: resolution: {integrity: sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w==} engines: {node: '>=4.0.0'} @@ -34639,6 +35725,10 @@ packages: resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} engines: {node: '>=8.0'} + /xpath@0.0.27: + resolution: {integrity: sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==} + engines: {node: '>=0.6.0'} + /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'}