From 2bdc9b5e474f4b6c456e266d0f5449c46f0ce4f5 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 7 Dec 2023 10:24:46 +0100 Subject: [PATCH 001/170] Create `StakingParameters` struct Store staking-related parameters in struct such as minimum amount for a single deposit operation and maximum total amount og tBTC token held by Acre. In the future, we should add other staking-related parametrs here. --- core/contracts/Acre.sol | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 0e1cf640f..abd91c163 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -17,6 +17,15 @@ import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; contract Acre is ERC4626 { event StakeReferral(bytes32 indexed referral, uint256 assets); + struct StakingParameters { + // Minimum amount for a single deposit operation. + uint256 minimumDepositAmount; + // Maximum total amount of tBTC token held by Acre. + uint256 maximumTotalAssets; + } + + StakingParameters public stakingParameters; + constructor( IERC20 tbtc ) ERC4626(tbtc) ERC20("Acre Staked Bitcoin", "stBTC") {} From 5679d876e54336bc2a00d14d2abfcd8b4bfd6aff Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 7 Dec 2023 10:28:56 +0100 Subject: [PATCH 002/170] Set default staking parameters in constructor --- core/contracts/Acre.sol | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index abd91c163..6a117568c 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -15,8 +15,6 @@ import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; /// burning of shares (stBTC), which are represented as standard ERC20 /// tokens, providing a seamless exchange with tBTC tokens. contract Acre is ERC4626 { - event StakeReferral(bytes32 indexed referral, uint256 assets); - struct StakingParameters { // Minimum amount for a single deposit operation. uint256 minimumDepositAmount; @@ -26,9 +24,16 @@ contract Acre is ERC4626 { StakingParameters public stakingParameters; + event StakeReferral(bytes32 indexed referral, uint256 assets); + constructor( IERC20 tbtc - ) ERC4626(tbtc) ERC20("Acre Staked Bitcoin", "stBTC") {} + ) ERC4626(tbtc) ERC20("Acre Staked Bitcoin", "stBTC") { + stakingParameters = StakingParameters({ + minimumDepositAmount: 10000000000000000, // 0.01 tBTC + maximumTotalAssets: 25000000000000000000 // 25 tBTC + }); + } /// @notice Stakes a given amount of tBTC token and mints shares to a /// receiver. From ae7b3fb0b3e6096c9ddeaae8acbdea71540ef418 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 7 Dec 2023 15:26:24 +0100 Subject: [PATCH 003/170] Implement min amount limit for a single deposit Only deposits where the amount is greater than or equal to the minimum amount for a single deposit should be possible. --- core/contracts/Acre.sol | 14 +++++++++++ core/test/Acre.test.ts | 51 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 6a117568c..091c4f578 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -35,6 +35,20 @@ contract Acre is ERC4626 { }); } + function deposit( + uint256 assets, + address receiver + ) public override returns (uint256) { + require( + assets >= stakingParameters.minimumDepositAmount, + "Amount is less than minimum" + ); + + uint256 shares = super.deposit(assets, receiver); + + return shares; + } + /// @notice Stakes a given amount of tBTC token and mints shares to a /// receiver. /// @dev This function calls `deposit` function from `ERC4626` contract. The diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 74e764ca0..91ffdab0b 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -161,12 +161,59 @@ describe("Acre", () => { .approve(await acre.getAddress(), amountToStake) }) - it("should not revert", async () => { + it("should revert", async () => { + await expect( + acre + .connect(staker1) + .stake(amountToStake, staker1.address, referral), + ).to.revertedWith("Amount is less than minimum") + }) + }) + + context("when amount to stake is less than minimum", () => { + let amountToStake: bigint + + beforeEach(async () => { + const { minimumDepositAmount } = await acre.stakingParameters() + amountToStake = minimumDepositAmount - 1n + + await tbtc + .connect(staker1) + .approve(await acre.getAddress(), amountToStake) + }) + + it("should revert", async () => { await expect( acre .connect(staker1) .stake(amountToStake, staker1.address, referral), - ).to.not.be.reverted + ).to.revertedWith("Amount is less than minimum") + }) + }) + + context("when amount to stake is equal to the minimum amount", () => { + let amountToStake: bigint + let tx: ContractTransactionResponse + + beforeEach(async () => { + const { minimumDepositAmount } = await acre.stakingParameters() + amountToStake = minimumDepositAmount + + await tbtc + .connect(staker1) + .approve(await acre.getAddress(), amountToStake) + + tx = await acre + .connect(staker1) + .stake(amountToStake, staker1.address, referral) + }) + + it("should receive shares equal to the staked amount", async () => { + await expect(tx).to.changeTokenBalances( + acre, + [staker1.address], + [amountToStake], + ) }) }) From 1765b6d382e7465f9f8ca96f7ffe64bfbfcc84e7 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 7 Dec 2023 16:29:49 +0100 Subject: [PATCH 004/170] Fix typo `apporval` -> `approval` --- core/test/Acre.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 91ffdab0b..e51dedc44 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -234,7 +234,7 @@ describe("Acre", () => { }) context( - "when a staker approved and staked tokens and wants to stake more but w/o another apporval", + "when a staker approved and staked tokens and wants to stake more but w/o another approval", () => { const amountToStake = to1e18(10) From 5494c4461916f1ec10d7e968bfc165f82e1a38ed Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 7 Dec 2023 16:31:20 +0100 Subject: [PATCH 005/170] Simplify test --- core/test/Acre.test.ts | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index e51dedc44..5d0952b58 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -286,34 +286,30 @@ describe("Acre", () => { }) context("when staker A stakes tokens", () => { - it("should stake tokens correctly", async () => { - await expect( - acre - .connect(staker1) - .stake(staker1AmountToStake, staker1.address, referral), - ).to.be.not.reverted - }) - it("should receive shares equal to a staked amount", async () => { - const shares = await acre.balanceOf(staker1.address) + const tx = await acre + .connect(staker1) + .stake(staker1AmountToStake, staker1.address, referral) - expect(shares).to.eq(staker1AmountToStake) + await expect(tx).to.changeTokenBalances( + acre, + [staker1.address], + [staker1AmountToStake], + ) }) }) context("when staker B stakes tokens", () => { - it("should stake tokens correctly", async () => { - await expect( - acre - .connect(staker2) - .stake(staker2AmountToStake, staker2.address, referral), - ).to.be.not.reverted - }) - it("should receive shares equal to a staked amount", async () => { - const shares = await acre.balanceOf(staker2.address) - - expect(shares).to.eq(staker2AmountToStake) + const tx = await acre + .connect(staker2) + .stake(staker2AmountToStake, staker2.address, referral) + + await expect(tx).to.changeTokenBalances( + acre, + [staker2.address], + [staker2AmountToStake], + ) }) }) }, From 15ff38d1111a21ae17b9c7e6d1a21f14e51ac471 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 7 Dec 2023 16:32:26 +0100 Subject: [PATCH 006/170] Override `maxDeposit` fn We want to control how many tBTC tokens the Acre contract can hold. Here we override the `maxDeposit` function that takes into account the staking param, maximum total assets, which determines the total amount of tBTC token held by Acre. --- core/contracts/Acre.sol | 10 +++ core/test/Acre.test.ts | 141 +++++++++++++++++++++++++--------------- 2 files changed, 98 insertions(+), 53 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 091c4f578..6b5838b8e 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -71,4 +71,14 @@ contract Acre is ERC4626 { return shares; } + + /// @notice Returns the maximum amount of the tBTC token that can be + /// deposited into the vault for the receiver, through a deposit + /// call. It takes into account the staking parameter, maximum total + /// assets, which determines the total amount of tBTC token held by + /// Acre. + /// @return The maximum amount of the tBTC token. + function maxDeposit(address) public view override returns (uint256) { + return stakingParameters.maximumTotalAssets - totalAssets(); + } } diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 5d0952b58..c7cb3bec0 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -50,7 +50,7 @@ describe("Acre", () => { }) context("with a referral", () => { - const amountToStake = to1e18(1000) + const amountToStake = to1e18(1) // In this test case there is only one staker and // the token vault has not earned anythig yet so received shares are @@ -259,9 +259,9 @@ describe("Acre", () => { ) }) - context("when there are two stakers, A and B ", () => { - const staker1AmountToStake = to1e18(75) - const staker2AmountToStake = to1e18(25) + context("when there are two stakers", () => { + const staker1AmountToStake = to1e18(7) + const staker2AmountToStake = to1e18(3) let afterStakesSnapshot: SnapshotRestorer let afterSimulatingYieldSnapshot: SnapshotRestorer @@ -334,14 +334,14 @@ describe("Acre", () => { before(async () => { // Current state: - // Staker A shares = 75 - // Staker B shares = 25 - // Total assets = 75(staker A) + 25(staker B) + 50(yield) + // Staker A shares = 7 + // Staker B shares = 3 + // Total assets = 7(staker A) + 3(staker B) + 5(yield) await afterStakesSnapshot.restore() staker1SharesBefore = await acre.balanceOf(staker1.address) staker2SharesBefore = await acre.balanceOf(staker2.address) - vaultYield = to1e18(50) + vaultYield = to1e18(5) // Simulating yield returned from strategies. The vault now contains // more tokens than deposited which causes the exchange rate to @@ -372,10 +372,10 @@ describe("Acre", () => { const shares = await acre.balanceOf(staker1.address) const availableAssetsToRedeem = await acre.previewRedeem(shares) - // Expected amount w/o rounding: 75 * 150 / 100 = 112.5 - // Expected amount w/ support for rounding: 112499999999999999999 in + // Expected amount w/o rounding: 7 * 15 / 10 = 10.5 + // Expected amount w/ support for rounding: 10499999999999999999 in // tBTC token precision. - const expectedAssetsToRedeem = 112499999999999999999n + const expectedAssetsToRedeem = 10499999999999999999n expect(availableAssetsToRedeem).to.be.eq(expectedAssetsToRedeem) }) @@ -384,65 +384,100 @@ describe("Acre", () => { const shares = await acre.balanceOf(staker2.address) const availableAssetsToRedeem = await acre.previewRedeem(shares) - // Expected amount w/o rounding: 25 * 150 / 100 = 37.5 - // Expected amount w/ support for rounding: 37499999999999999999 in + // Expected amount w/o rounding: 3 * 15 / 10 = 4.5 + // Expected amount w/ support for rounding: 4499999999999999999 in // tBTC token precision. - const expectedAssetsToRedeem = 37499999999999999999n + const expectedAssetsToRedeem = 4499999999999999999n expect(availableAssetsToRedeem).to.be.eq(expectedAssetsToRedeem) }) }) context("when staker A stakes more tokens", () => { - const newAmountToStake = to1e18(20) - // Current state: - // Total assets = 75(staker A) + 25(staker B) + 50(yield) - // Total shares = 75 + 25 = 100 - // 20 * 100 / 150 = 13.(3) -> 13333333333333333333 in stBTC token - /// precision - const expectedSharesToMint = 13333333333333333333n - let sharesBefore: bigint - let availableToRedeemBefore: bigint + context( + "when total tBTC amount after staking would not exceed max amount", + () => { + const newAmountToStake = to1e18(2) + // Current state: + // Total assets = 7(staker A) + 3(staker B) + 5(yield) + // Total shares = 7 + 3 = 10 + // Shares to mint = 2 * 10 / 15 = 1.(3) -> 1333333333333333333 in stBTC + // token precision + const expectedSharesToMint = 1333333333333333333n + let sharesBefore: bigint + let availableToRedeemBefore: bigint + + before(async () => { + await afterSimulatingYieldSnapshot.restore() + + sharesBefore = await acre.balanceOf(staker1.address) + availableToRedeemBefore = await acre.previewRedeem(sharesBefore) + + tbtc.mint(staker1.address, newAmountToStake) + + await tbtc + .connect(staker1) + .approve(await acre.getAddress(), newAmountToStake) - before(async () => { - await afterSimulatingYieldSnapshot.restore() + // State after stake: + // Total assets = 7(staker A) + 3(staker B) + 5(yield) + 2(staker + // A) = 17 + // Total shares = 7 + 3 + 1.(3) = 11.(3) + await acre.stake(newAmountToStake, staker1.address, referral) + }) - sharesBefore = await acre.balanceOf(staker1.address) - availableToRedeemBefore = await acre.previewRedeem(sharesBefore) + it("should receive more shares", async () => { + const shares = await acre.balanceOf(staker1.address) - tbtc.mint(staker1.address, newAmountToStake) + expect(shares).to.be.eq(sharesBefore + expectedSharesToMint) + }) - await tbtc - .connect(staker1) - .approve(await acre.getAddress(), newAmountToStake) + it("should be able to redeem more tokens than before", async () => { + const shares = await acre.balanceOf(staker1.address) + const availableToRedeem = await acre.previewRedeem(shares) - // State after stake: - // Total assets = 75(staker A) + 25(staker B) + 50(yield) + 20(staker - // A) = 170 - // Total shares = 75 + 25 + 13.(3) = 113.(3) - await acre.stake(newAmountToStake, staker1.address, referral) - }) + // Expected amount w/o rounding: 8.(3) * 17 / 11.(3) = 12.5 + // Expected amount w/ support for rounding: 12499999999999999999 in + // tBTC token precision. + const expectedTotalAssetsAvailableToRedeem = 12499999999999999999n - it("should receive more shares", async () => { - const shares = await acre.balanceOf(staker1.address) + expect(availableToRedeem).to.be.greaterThan( + availableToRedeemBefore, + ) + expect(availableToRedeem).to.be.eq( + expectedTotalAssetsAvailableToRedeem, + ) + }) + }, + ) - expect(shares).to.be.eq(sharesBefore + expectedSharesToMint) - }) + context( + "when total tBTC amount after staking would exceed max amount", + () => { + let possibleMaxAmountToStake: bigint + let amountToStake: bigint - it("should be able to redeem more tokens than before", async () => { - const shares = await acre.balanceOf(staker1.address) - const availableToRedeem = await acre.previewRedeem(shares) + before(async () => { + await afterSimulatingYieldSnapshot.restore() - // Expected amount w/o rounding: 88.(3) * 170 / 113.(3) = 132.5 - // Expected amount w/ support for rounding: 132499999999999999999 in - // tBTC token precision. - const expectedTotalAssetsAvailableToRedeem = 132499999999999999999n + // In the current implementation of the `maxDeposit` the + // `address` param is not taken into account - it means it will + // return the same value for any address. + possibleMaxAmountToStake = await acre.maxDeposit(staker1.address) + amountToStake = possibleMaxAmountToStake + 1n - expect(availableToRedeem).to.be.greaterThan(availableToRedeemBefore) - expect(availableToRedeem).to.be.eq( - expectedTotalAssetsAvailableToRedeem, - ) - }) + await tbtc + .connect(staker1) + .approve(await acre.getAddress(), amountToStake) + }) + + it("should revert", async () => { + await expect( + acre.stake(amountToStake, staker1.address, referral), + ).to.be.revertedWithCustomError(acre, "ERC4626ExceededMaxDeposit") + }) + }, + ) }) }) }) From 0efc202a3c3e20cfe087fedc73854e7f703d9df7 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 7 Dec 2023 17:57:47 +0100 Subject: [PATCH 007/170] Implement staking limits in `mint` fn In ERC4626 standard users can deposit using 2 functions `mint` and `deposit` so we need to take into account staking limits in `mint` function to not allow deposits that break staking limts rules. --- core/contracts/Acre.sol | 23 +++++++++++++++++++++++ core/test/Acre.test.ts | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 6b5838b8e..5bf418dfa 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -49,6 +49,20 @@ contract Acre is ERC4626 { return shares; } + function mint( + uint256 shares, + address receiver + ) public override returns (uint256) { + uint256 assets = super.mint(shares, receiver); + + require( + assets >= stakingParameters.minimumDepositAmount, + "Amount is less than minimum" + ); + + return assets; + } + /// @notice Stakes a given amount of tBTC token and mints shares to a /// receiver. /// @dev This function calls `deposit` function from `ERC4626` contract. The @@ -81,4 +95,13 @@ contract Acre is ERC4626 { function maxDeposit(address) public view override returns (uint256) { return stakingParameters.maximumTotalAssets - totalAssets(); } + + /// @notice Returns the maximum amount of the vault shares that can be + /// minted for the receiver, through a mint call. + /// @dev Since the Acre contract limits the maximum total tBTC tokens this + /// function converts the maximum deposit amount to shares. + /// @return The maximum amount of the vault shares. + function maxMint(address receiver) public view override returns (uint256) { + return previewDeposit(maxDeposit(receiver)); + } } diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index c7cb3bec0..7d67e7923 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -481,4 +481,42 @@ describe("Acre", () => { }) }) }) + + describe("mint", () => { + context("when staker wants to mint more shares than allowed", () => { + let sharesToMint: bigint + + beforeEach(async () => { + const maxMint = await acre.maxMint(staker1.address) + + sharesToMint = maxMint + 1n + }) + + it("should take into account the max total assets parameter and revert", async () => { + await expect( + acre.mint(sharesToMint, staker1.address), + ).to.be.revertedWithCustomError(acre, "ERC4626ExceededMaxMint") + }) + }) + + context( + "when staker wants to mint less shares than is equal to the min deposit amount", + () => { + let sharesToMint: bigint + + beforeEach(async () => { + const { minimumDepositAmount } = await acre.stakingParameters() + const previewDeposit = await acre.previewDeposit(minimumDepositAmount) + + sharesToMint = previewDeposit - 1n + }) + + it("should take into account the min deposit amount parameter and revert", async () => { + await expect( + acre.mint(sharesToMint, staker1.address), + ).to.be.revertedWith("Amount is less than minimum") + }) + }, + ) + }) }) From 2fda404cf0e6b33872fcaf3b5db1e89cca4dd222 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Fri, 8 Dec 2023 14:30:38 +0100 Subject: [PATCH 008/170] Add fn that allows owner to update staking params Add function that updates parameters of staking. Only owner can update these parameters so here we also use the `Ownable` contract from `OZ` library to use the `onlyOwner` modifier. Requirements: - Minimum deposit amount must be greater than zero, - Minimum deposit amount must be greater than or equal to the minimum deposit amount in the tBTC system, - Maximum total assets must be greater than zero. --- core/contracts/Acre.sol | 66 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 5bf418dfa..a74151581 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.21; import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; /// @title Acre /// @notice This contract implements the ERC-4626 tokenized vault standard. By @@ -14,7 +15,7 @@ import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; /// of yield-bearing vaults. This contract facilitates the minting and /// burning of shares (stBTC), which are represented as standard ERC20 /// tokens, providing a seamless exchange with tBTC tokens. -contract Acre is ERC4626 { +contract Acre is ERC4626, Ownable { struct StakingParameters { // Minimum amount for a single deposit operation. uint256 minimumDepositAmount; @@ -25,16 +26,62 @@ contract Acre is ERC4626 { StakingParameters public stakingParameters; event StakeReferral(bytes32 indexed referral, uint256 assets); + event StakingParametersUpdated( + uint256 minimumDepositAmount, + uint256 maximumTotalAssets + ); constructor( - IERC20 tbtc - ) ERC4626(tbtc) ERC20("Acre Staked Bitcoin", "stBTC") { + IERC20 tbtc, + address initialOwner + ) + ERC4626(tbtc) + ERC20("Acre Staked Bitcoin", "stBTC") + Ownable(initialOwner) + { stakingParameters = StakingParameters({ minimumDepositAmount: 10000000000000000, // 0.01 tBTC maximumTotalAssets: 25000000000000000000 // 25 tBTC }); } + /// @notice Updates parameters of staking. + /// @dev Requirements: + /// - Minimum deposit amount must be greater than zero, + /// - Minimum deposit amount must be greater than or equal to the + /// minimum deposit amount in the tBTC system, + /// - Maximum total assets must be greater than zero. + /// @param minimumDepositAmount New value of the minimum deposit amount. It + /// is the minimum amount for a single deposit operation. + /// @param maximumTotalAssets New value of the maximum total assets amount. + /// It is the maximum amount of the tBTC token that the Acre can + /// hold. + function updateStakingParameters( + uint256 minimumDepositAmount, + uint256 maximumTotalAssets + ) external onlyOwner { + require( + minimumDepositAmount > 0, + "Minimum deposit amount must be greater than zero" + ); + + // TODO: Do we need this requirement? + require( + minimumDepositAmount >= _getTBTCSystemMinDepositAmount(), + "Minimum deposit amount must be greater than or to the equal minimum deposit amount in tBTC system" + ); + + require( + maximumTotalAssets > 0, + "Maximum total assets amount must be greater than zero" + ); + + stakingParameters.minimumDepositAmount = minimumDepositAmount; + stakingParameters.maximumTotalAssets = maximumTotalAssets; + + emit StakingParametersUpdated(minimumDepositAmount, maximumTotalAssets); + } + function deposit( uint256 assets, address receiver @@ -104,4 +151,17 @@ contract Acre is ERC4626 { function maxMint(address receiver) public view override returns (uint256) { return previewDeposit(maxDeposit(receiver)); } + + function _getTBTCSystemMinDepositAmount() private pure returns (uint256) { + // TODO: Implement if we want to make sure the minimum deposit amount is + // greater than or equal the minimum dposit amount in the tBTC system. + + // (uint64 depositDustThreshold, , , ) = tbtcBridge.depositParameters(); + + // // The `depositDustThreshold` is in satoshi so we need to cast to tBTC + // // decimals. + // return 10 ** (ERC20(asset()).decimals() - 8) * depositDustThreshold; + + return 10000000000000000; // 0.01 tBTC + } } From 7ae23cbaab3d638f0e6b801face4ef7c5463812e Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Fri, 8 Dec 2023 15:14:30 +0100 Subject: [PATCH 009/170] Add unit test for `updateStakingParameters` fn --- core/test/Acre.test.ts | 133 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 129 insertions(+), 4 deletions(-) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 7d67e7923..ac5d92938 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -11,29 +11,30 @@ import type { TestERC20, Acre } from "../typechain" import { to1e18 } from "./utils" async function acreFixture() { - const [staker1, staker2] = await ethers.getSigners() + const [owner, staker1, staker2] = await ethers.getSigners() const TestERC20 = await ethers.getContractFactory("TestERC20") const tbtc = await TestERC20.deploy() const Acre = await ethers.getContractFactory("Acre") - const acre = await Acre.deploy(await tbtc.getAddress()) + const acre = await Acre.deploy(await tbtc.getAddress(), owner) const amountToMint = to1e18(100000) tbtc.mint(staker1, amountToMint) tbtc.mint(staker2, amountToMint) - return { acre, tbtc, staker1, staker2 } + return { acre, tbtc, owner, staker1, staker2 } } describe("Acre", () => { let acre: Acre let tbtc: TestERC20 + let owner: HardhatEthersSigner let staker1: HardhatEthersSigner let staker2: HardhatEthersSigner before(async () => { - ;({ acre, tbtc, staker1, staker2 } = await loadFixture(acreFixture)) + ;({ acre, tbtc, owner, staker1, staker2 } = await loadFixture(acreFixture)) }) describe("stake", () => { @@ -483,6 +484,16 @@ describe("Acre", () => { }) describe("mint", () => { + let snapshot: SnapshotRestorer + + beforeEach(async () => { + snapshot = await takeSnapshot() + }) + + afterEach(async () => { + await snapshot.restore() + }) + context("when staker wants to mint more shares than allowed", () => { let sharesToMint: bigint @@ -519,4 +530,118 @@ describe("Acre", () => { }, ) }) + + describe("updateStakingParameters", () => { + const validMinimumDepositAmount = to1e18(1) + const validMaximumTotalAssetsAmount = to1e18(30) + + context("when is called by owner", () => { + context("when all parameters are valid", () => { + let tx: ContractTransactionResponse + + beforeEach(async () => { + tx = await acre + .connect(owner) + .updateStakingParameters( + validMinimumDepositAmount, + validMaximumTotalAssetsAmount, + ) + }) + + it("should emit StakingParametersUpdated event", async () => { + await expect(tx) + .to.emit(acre, "StakingParametersUpdated") + .withArgs(validMinimumDepositAmount, validMaximumTotalAssetsAmount) + }) + + it("should update parameters correctly", async () => { + const stakingParameters = await acre.stakingParameters() + + expect(stakingParameters.minimumDepositAmount).to.be.eq( + validMinimumDepositAmount, + ) + expect(stakingParameters.maximumTotalAssets).to.be.eq( + validMaximumTotalAssetsAmount, + ) + }) + }) + + context("when minimum deposit amount is invalid", () => { + context("when it is equal to 0", () => { + const minimumDepositAmount = 0 + + it("should revert", async () => { + await expect( + acre + .connect(owner) + .updateStakingParameters( + minimumDepositAmount, + validMaximumTotalAssetsAmount, + ), + ).to.be.revertedWith( + "Minimum deposit amount must be greater than zero", + ) + }) + }) + + context( + "when it is less than the minimum deposit amount in tBTC system", + () => { + // TODO: In the current implementation the minimum deposit amount + // from tBTC system is hardcoded to 0.01 tBTC. We should get this + // value from mocked tBTC Bridge contract. + const minimumDepositAmountInTBTCSystem = 10000000000000000n + + const newMinimumDepositAmount = + minimumDepositAmountInTBTCSystem - 1n + + it("should revert", async () => { + await expect( + acre + .connect(owner) + .updateStakingParameters( + newMinimumDepositAmount, + validMaximumTotalAssetsAmount, + ), + ).to.be.revertedWith( + "Minimum deposit amount must be greater than or to the equal minimum deposit amount in tBTC system", + ) + }) + }, + ) + }) + + context("when the maximum total assets amount is invalid", () => { + const maximumTotalAssets = 0 + + context("when it is equal to 0", () => { + it("should revert", async () => { + await expect( + acre + .connect(owner) + .updateStakingParameters( + validMinimumDepositAmount, + maximumTotalAssets, + ), + ).to.be.revertedWith( + "Maximum total assets amount must be greater than zero", + ) + }) + }) + }) + }) + + context("when it is called by non-owner", () => { + it("should revert", async () => { + await expect( + acre + .connect(staker1) + .updateStakingParameters( + validMinimumDepositAmount, + validMaximumTotalAssetsAmount, + ), + ).to.be.revertedWithCustomError(acre, "OwnableUnauthorizedAccount") + }) + }) + }) }) From a5d022cf6c5fbc1506d2b036dc1cf8b0580bbe8d Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Fri, 8 Dec 2023 15:50:54 +0100 Subject: [PATCH 010/170] Fix unit tests We added a new role `owner` to the test fixture and we need to make sure we call functions with correct staker account. --- core/test/Acre.test.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index ac5d92938..282b045f2 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -424,7 +424,9 @@ describe("Acre", () => { // Total assets = 7(staker A) + 3(staker B) + 5(yield) + 2(staker // A) = 17 // Total shares = 7 + 3 + 1.(3) = 11.(3) - await acre.stake(newAmountToStake, staker1.address, referral) + await acre + .connect(staker1) + .stake(newAmountToStake, staker1.address, referral) }) it("should receive more shares", async () => { @@ -505,7 +507,7 @@ describe("Acre", () => { it("should take into account the max total assets parameter and revert", async () => { await expect( - acre.mint(sharesToMint, staker1.address), + acre.connect(staker1).mint(sharesToMint, staker1.address), ).to.be.revertedWithCustomError(acre, "ERC4626ExceededMaxMint") }) }) @@ -520,11 +522,14 @@ describe("Acre", () => { const previewDeposit = await acre.previewDeposit(minimumDepositAmount) sharesToMint = previewDeposit - 1n + await tbtc + .connect(staker1) + .approve(await acre.getAddress(), minimumDepositAmount) }) it("should take into account the min deposit amount parameter and revert", async () => { await expect( - acre.mint(sharesToMint, staker1.address), + acre.connect(staker1).mint(sharesToMint, staker1.address), ).to.be.revertedWith("Amount is less than minimum") }) }, From 4a1de543457244f20dac7f5169f093d5965ef78b Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Fri, 8 Dec 2023 15:58:33 +0100 Subject: [PATCH 011/170] Fix slither errors Fix too many digits error by using `ether` suffix as recomended in slither docs. --- core/contracts/Acre.sol | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index a74151581..c438bcf3c 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -39,10 +39,8 @@ contract Acre is ERC4626, Ownable { ERC20("Acre Staked Bitcoin", "stBTC") Ownable(initialOwner) { - stakingParameters = StakingParameters({ - minimumDepositAmount: 10000000000000000, // 0.01 tBTC - maximumTotalAssets: 25000000000000000000 // 25 tBTC - }); + stakingParameters.minimumDepositAmount = 0.01 ether; // 0.01 tBTC + stakingParameters.maximumTotalAssets = 25 ether; // 25 tBTC } /// @notice Updates parameters of staking. @@ -162,6 +160,6 @@ contract Acre is ERC4626, Ownable { // // decimals. // return 10 ** (ERC20(asset()).decimals() - 8) * depositDustThreshold; - return 10000000000000000; // 0.01 tBTC + return 0.01 ether; // 0.01 tBTC } } From afc232335f5a9072f3fdca00ec1efda5fd7700b6 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Fri, 8 Dec 2023 16:01:07 +0100 Subject: [PATCH 012/170] Fix deployment scripts Since the `Acre` contract inherits from `Ownable` contract from OZ lib we need to pass `initialOwner` to the Acre contract constructor. --- core/deploy/01_deploy_acre.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/deploy/01_deploy_acre.ts b/core/deploy/01_deploy_acre.ts index 531fc6c12..ffcfaf660 100644 --- a/core/deploy/01_deploy_acre.ts +++ b/core/deploy/01_deploy_acre.ts @@ -9,7 +9,7 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { await deployments.deploy("Acre", { from: deployer, - args: [tbtc.address], + args: [tbtc.address, deployer], log: true, waitConfirmations: 1, }) From 7b907fe0e889a8a2440c239f13efaf416ab00eb2 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Fri, 8 Dec 2023 16:40:37 +0100 Subject: [PATCH 013/170] Simplify overridden `deposit` fn There is no need to assign value from `super.deposit` to the new variable. We can return directly. --- core/contracts/Acre.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index c438bcf3c..3ee03a7aa 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -89,9 +89,7 @@ contract Acre is ERC4626, Ownable { "Amount is less than minimum" ); - uint256 shares = super.deposit(assets, receiver); - - return shares; + return super.deposit(assets, receiver); } function mint( From 2ecd47fc4435e05d61bb3f4837334bf6d7111fab Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Tue, 12 Dec 2023 10:43:17 +0100 Subject: [PATCH 014/170] Simplify the Acre constructor We can pass `msg.sender` to the `Ownable` constructor and later in the deployment scripts transfer the ownership at the end of the deployment scenario. --- core/contracts/Acre.sol | 9 ++------- core/deploy/01_deploy_acre.ts | 2 +- core/deploy/21_transfer_ownership_acre.ts | 2 -- core/test/Acre.test.ts | 2 +- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 3ee03a7aa..c77cb4016 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -32,13 +32,8 @@ contract Acre is ERC4626, Ownable { ); constructor( - IERC20 tbtc, - address initialOwner - ) - ERC4626(tbtc) - ERC20("Acre Staked Bitcoin", "stBTC") - Ownable(initialOwner) - { + IERC20 tbtc + ) ERC4626(tbtc) ERC20("Acre Staked Bitcoin", "stBTC") Ownable(msg.sender) { stakingParameters.minimumDepositAmount = 0.01 ether; // 0.01 tBTC stakingParameters.maximumTotalAssets = 25 ether; // 25 tBTC } diff --git a/core/deploy/01_deploy_acre.ts b/core/deploy/01_deploy_acre.ts index ffcfaf660..531fc6c12 100644 --- a/core/deploy/01_deploy_acre.ts +++ b/core/deploy/01_deploy_acre.ts @@ -9,7 +9,7 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { await deployments.deploy("Acre", { from: deployer, - args: [tbtc.address, deployer], + args: [tbtc.address], log: true, waitConfirmations: 1, }) diff --git a/core/deploy/21_transfer_ownership_acre.ts b/core/deploy/21_transfer_ownership_acre.ts index c62708641..09a875a1d 100644 --- a/core/deploy/21_transfer_ownership_acre.ts +++ b/core/deploy/21_transfer_ownership_acre.ts @@ -19,5 +19,3 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { export default func func.tags = ["TransferOwnershipAcre"] -// TODO: Enable once Acre extends Ownable -func.skip = async () => true diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 282b045f2..9d4ae800a 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -17,7 +17,7 @@ async function acreFixture() { const tbtc = await TestERC20.deploy() const Acre = await ethers.getContractFactory("Acre") - const acre = await Acre.deploy(await tbtc.getAddress(), owner) + const acre = await Acre.deploy(await tbtc.getAddress()) const amountToMint = to1e18(100000) tbtc.mint(staker1, amountToMint) From 425a06f0c0f650aa70ccf7f68920c4e8389d4e60 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Tue, 12 Dec 2023 11:31:19 +0100 Subject: [PATCH 015/170] Update `maxDeposit` fn Cover a case where `totalAssets()` value is greater than `stakingParameters.maxiumumTotalAssets`. This can happen when vaults generated yield or `maximumTotalAssets` has been updated to a lower value. --- core/contracts/Acre.sol | 6 +++- core/test/Acre.test.ts | 72 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index c77cb4016..0205cffc8 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -131,7 +131,11 @@ contract Acre is ERC4626, Ownable { /// Acre. /// @return The maximum amount of the tBTC token. function maxDeposit(address) public view override returns (uint256) { - return stakingParameters.maximumTotalAssets - totalAssets(); + uint256 _totalAssets = totalAssets(); + + if (_totalAssets >= stakingParameters.maximumTotalAssets) return 0; + + return stakingParameters.maximumTotalAssets - _totalAssets; } /// @notice Returns the maximum amount of the vault shares that can be diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 9d4ae800a..1c2457abe 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -279,6 +279,10 @@ describe("Acre", () => { await tbtc.connect(staker2).mint(staker2.address, staker2AmountToStake) }) + after(async () => { + await snapshot.restore() + }) + context( "when the vault is empty and has not yet earned yield from strategies", () => { @@ -539,6 +543,15 @@ describe("Acre", () => { describe("updateStakingParameters", () => { const validMinimumDepositAmount = to1e18(1) const validMaximumTotalAssetsAmount = to1e18(30) + let snapshot: SnapshotRestorer + + beforeEach(async () => { + snapshot = await takeSnapshot() + }) + + afterEach(async () => { + await snapshot.restore() + }) context("when is called by owner", () => { context("when all parameters are valid", () => { @@ -649,4 +662,63 @@ describe("Acre", () => { }) }) }) + + describe("maxDeposit", () => { + let maximumTotalAssets: bigint + let snapshot: SnapshotRestorer + + beforeEach(async () => { + snapshot = await takeSnapshot() + ;({ maximumTotalAssets } = await acre.stakingParameters()) + }) + + afterEach(async () => { + await snapshot.restore() + }) + + context( + "when total assets is greater than maximum total assets amount", + () => { + beforeEach(async () => { + const toMint = maximumTotalAssets + 1n + + await tbtc.mint(await acre.getAddress(), toMint) + }) + + it("should return 0", async () => { + expect(await acre.maxDeposit(staker1.address)).to.be.eq(0) + }) + }, + ) + + context("when the vault is empty", () => { + it("should return maximum total assets amount", async () => { + expect(await acre.maxDeposit(staker1.address)).to.be.eq( + maximumTotalAssets, + ) + }) + }) + + context("when the maximum total amount has not yet been reached", () => { + let expectedValue: bigint + + beforeEach(async () => { + const toMint = to1e18(2) + const newMaximumTotalAssets = to1e18(30) + const minimumDepositAmount = to1e18(1) + + expectedValue = newMaximumTotalAssets - toMint + + await acre.updateStakingParameters( + minimumDepositAmount, + newMaximumTotalAssets, + ) + await tbtc.mint(await acre.getAddress(), toMint) + }) + + it("should return correct value", async () => { + expect(await acre.maxDeposit(staker1.address)).to.be.eq(expectedValue) + }) + }) + }) }) From 8535cfed0e0b29dad9e453917b58a9898711b28b Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Tue, 12 Dec 2023 11:34:56 +0100 Subject: [PATCH 016/170] Move the require check before `super.mint` --- core/contracts/Acre.sol | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 0205cffc8..c1119abe0 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -91,14 +91,12 @@ contract Acre is ERC4626, Ownable { uint256 shares, address receiver ) public override returns (uint256) { - uint256 assets = super.mint(shares, receiver); - require( - assets >= stakingParameters.minimumDepositAmount, + previewMint(shares) >= stakingParameters.minimumDepositAmount, "Amount is less than minimum" ); - return assets; + return super.mint(shares, receiver); } /// @notice Stakes a given amount of tBTC token and mints shares to a From ec6f06e35333032fa337d636ba791ff34826a794 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Tue, 12 Dec 2023 11:48:12 +0100 Subject: [PATCH 017/170] Update `updateStakingParameters` fn Remove unnecessary requirement. `0.01` BTC is tBTC minting process limitation which is expected to be invoked before `Acre.stake` function. --- core/contracts/Acre.sol | 21 --------------------- core/test/Acre.test.ts | 26 -------------------------- 2 files changed, 47 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index c1119abe0..b8b2dbc05 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -41,8 +41,6 @@ contract Acre is ERC4626, Ownable { /// @notice Updates parameters of staking. /// @dev Requirements: /// - Minimum deposit amount must be greater than zero, - /// - Minimum deposit amount must be greater than or equal to the - /// minimum deposit amount in the tBTC system, /// - Maximum total assets must be greater than zero. /// @param minimumDepositAmount New value of the minimum deposit amount. It /// is the minimum amount for a single deposit operation. @@ -58,12 +56,6 @@ contract Acre is ERC4626, Ownable { "Minimum deposit amount must be greater than zero" ); - // TODO: Do we need this requirement? - require( - minimumDepositAmount >= _getTBTCSystemMinDepositAmount(), - "Minimum deposit amount must be greater than or to the equal minimum deposit amount in tBTC system" - ); - require( maximumTotalAssets > 0, "Maximum total assets amount must be greater than zero" @@ -144,17 +136,4 @@ contract Acre is ERC4626, Ownable { function maxMint(address receiver) public view override returns (uint256) { return previewDeposit(maxDeposit(receiver)); } - - function _getTBTCSystemMinDepositAmount() private pure returns (uint256) { - // TODO: Implement if we want to make sure the minimum deposit amount is - // greater than or equal the minimum dposit amount in the tBTC system. - - // (uint64 depositDustThreshold, , , ) = tbtcBridge.depositParameters(); - - // // The `depositDustThreshold` is in satoshi so we need to cast to tBTC - // // decimals. - // return 10 ** (ERC20(asset()).decimals() - 8) * depositDustThreshold; - - return 0.01 ether; // 0.01 tBTC - } } diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 1c2457abe..fe2d37110 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -601,32 +601,6 @@ describe("Acre", () => { ) }) }) - - context( - "when it is less than the minimum deposit amount in tBTC system", - () => { - // TODO: In the current implementation the minimum deposit amount - // from tBTC system is hardcoded to 0.01 tBTC. We should get this - // value from mocked tBTC Bridge contract. - const minimumDepositAmountInTBTCSystem = 10000000000000000n - - const newMinimumDepositAmount = - minimumDepositAmountInTBTCSystem - 1n - - it("should revert", async () => { - await expect( - acre - .connect(owner) - .updateStakingParameters( - newMinimumDepositAmount, - validMaximumTotalAssetsAmount, - ), - ).to.be.revertedWith( - "Minimum deposit amount must be greater than or to the equal minimum deposit amount in tBTC system", - ) - }) - }, - ) }) context("when the maximum total assets amount is invalid", () => { From 7516de4a7ed10ba3d00e4ba4b695c633947c00ed Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Tue, 12 Dec 2023 11:51:59 +0100 Subject: [PATCH 018/170] Leave TODO in `updateStakingParameters` Leave a TODO to remember about introducing a governable parameters update process. --- core/contracts/Acre.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index b8b2dbc05..63e30e8c8 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -51,6 +51,7 @@ contract Acre is ERC4626, Ownable { uint256 minimumDepositAmount, uint256 maximumTotalAssets ) external onlyOwner { + // TODO: Introduce a parameters update process. require( minimumDepositAmount > 0, "Minimum deposit amount must be greater than zero" From 331c1d30f5620e8a5a586d60d16d4516d375cb0a Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Tue, 12 Dec 2023 12:29:16 +0100 Subject: [PATCH 019/170] Define custom errors for the checks The ERC4626 already uses custom errors, so it would be nice to have them here for consistency. --- core/contracts/Acre.sol | 37 ++++++++++++++++++++----------------- core/test/Acre.test.ts | 14 +++++--------- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 63e30e8c8..be4d78a82 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -31,6 +31,9 @@ contract Acre is ERC4626, Ownable { uint256 maximumTotalAssets ); + error StakingAmountLessThanMin(uint256 amount, uint256 min); + error InvalidStakingParameter(); + constructor( IERC20 tbtc ) ERC4626(tbtc) ERC20("Acre Staked Bitcoin", "stBTC") Ownable(msg.sender) { @@ -52,15 +55,9 @@ contract Acre is ERC4626, Ownable { uint256 maximumTotalAssets ) external onlyOwner { // TODO: Introduce a parameters update process. - require( - minimumDepositAmount > 0, - "Minimum deposit amount must be greater than zero" - ); - - require( - maximumTotalAssets > 0, - "Maximum total assets amount must be greater than zero" - ); + if (minimumDepositAmount <= 0 || maximumTotalAssets <= 0) { + revert InvalidStakingParameter(); + } stakingParameters.minimumDepositAmount = minimumDepositAmount; stakingParameters.maximumTotalAssets = maximumTotalAssets; @@ -72,10 +69,12 @@ contract Acre is ERC4626, Ownable { uint256 assets, address receiver ) public override returns (uint256) { - require( - assets >= stakingParameters.minimumDepositAmount, - "Amount is less than minimum" - ); + if (assets < stakingParameters.minimumDepositAmount) { + revert StakingAmountLessThanMin( + assets, + stakingParameters.minimumDepositAmount + ); + } return super.deposit(assets, receiver); } @@ -84,10 +83,14 @@ contract Acre is ERC4626, Ownable { uint256 shares, address receiver ) public override returns (uint256) { - require( - previewMint(shares) >= stakingParameters.minimumDepositAmount, - "Amount is less than minimum" - ); + uint256 assets = previewMint(shares); + + if (assets < stakingParameters.minimumDepositAmount) { + revert StakingAmountLessThanMin( + assets, + stakingParameters.minimumDepositAmount + ); + } return super.mint(shares, receiver); } diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index fe2d37110..94a5d451e 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -167,7 +167,7 @@ describe("Acre", () => { acre .connect(staker1) .stake(amountToStake, staker1.address, referral), - ).to.revertedWith("Amount is less than minimum") + ).to.revertedWithCustomError(acre, "StakingAmountLessThanMin") }) }) @@ -188,7 +188,7 @@ describe("Acre", () => { acre .connect(staker1) .stake(amountToStake, staker1.address, referral), - ).to.revertedWith("Amount is less than minimum") + ).to.revertedWithCustomError(acre, "StakingAmountLessThanMin") }) }) @@ -534,7 +534,7 @@ describe("Acre", () => { it("should take into account the min deposit amount parameter and revert", async () => { await expect( acre.connect(staker1).mint(sharesToMint, staker1.address), - ).to.be.revertedWith("Amount is less than minimum") + ).to.be.revertedWithCustomError(acre, "StakingAmountLessThanMin") }) }, ) @@ -596,9 +596,7 @@ describe("Acre", () => { minimumDepositAmount, validMaximumTotalAssetsAmount, ), - ).to.be.revertedWith( - "Minimum deposit amount must be greater than zero", - ) + ).to.be.revertedWithCustomError(acre, "InvalidStakingParameter") }) }) }) @@ -615,9 +613,7 @@ describe("Acre", () => { validMinimumDepositAmount, maximumTotalAssets, ), - ).to.be.revertedWith( - "Maximum total assets amount must be greater than zero", - ) + ).to.be.revertedWithCustomError(acre, "InvalidStakingParameter") }) }) }) From dfec9bfe90610af1efcaf4ea4f1deeb1163ce88b Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 8 Dec 2023 17:37:02 +0100 Subject: [PATCH 020/170] Adding deposit and redeem functionality Renamed AcreRouter to Dispatcher and introduced an abstract contract called Router that will handle moving funds between Acre and Vaults. In order to deposit / redeem assets, Acre contract should approve assets for Dispatcher to spend and call depositToVault or redeemFromVault functions. These Acre's functions can be also called by a bot for rebalancing purposes. --- core/contracts/Dispatcher.sol | 26 ++++++++++++++++ core/contracts/Router.sol | 57 +++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 core/contracts/Router.sol diff --git a/core/contracts/Dispatcher.sol b/core/contracts/Dispatcher.sol index 309da2ae8..6a17bcf91 100644 --- a/core/contracts/Dispatcher.sol +++ b/core/contracts/Dispatcher.sol @@ -2,6 +2,8 @@ pragma solidity ^0.8.21; import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/interfaces/IERC4626.sol"; +import "./Router.sol"; /// @title Dispatcher /// @notice Dispatcher is a contract that routes TBTC from stBTC (Acre) to @@ -66,4 +68,28 @@ contract Dispatcher is Ownable { function getVaults() external view returns (address[] memory) { return vaults; } + + // TODO: add documentation + function depositToVault( + address vault, + uint256 amount, + uint256 minSharesOut + ) public { + require(msg.sender == address(stBTC), "stBTC only"); + require(vaultsInfo[vault].authorized, "Vault is not approved"); + + deposit(IERC4626(vault), address(stBTC), amount, minSharesOut); + } + + // TODO: add documentation + function redeemFromVault( + address vault, + uint256 shares, + uint256 minAssetsOut + ) public { + require(msg.sender == address(stBTC), "stBTC only"); + require(vaultsInfo[vault].authorized, "Vault is not approved"); + + redeem(IERC4626(vault), address(stBTC), shares, minAssetsOut); + } } diff --git a/core/contracts/Router.sol b/core/contracts/Router.sol new file mode 100644 index 000000000..7a965d264 --- /dev/null +++ b/core/contracts/Router.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-3.0-only +pragma solidity ^0.8.21; + +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts/interfaces/IERC20.sol"; +import "@openzeppelin/contracts/interfaces/IERC4626.sol"; + +/// TODO: Add documentation +abstract contract Router { + using SafeERC20 for IERC20; + + /// @notice Routes funds from stBTC (Acre) to a vault. The amount of tBTC to + /// Shares of deposited tBTC are minted to the stBTC contract. + /// @param vault Address of the vault to route the funds to. + /// @param to Address of the receiver of the shares. + /// @param amount Amount of tBTC to deposit. + /// @param minSharesOut Minimum amount of shares to receive. + function deposit( + IERC4626 vault, + address to, + uint256 amount, + uint256 minSharesOut + ) public returns (uint256 sharesOut) { + IERC20(vault.asset()).safeTransferFrom( + msg.sender, + address(this), + amount + ); + IERC20(vault.asset()).safeIncreaseAllowance(address(vault), amount); + if ((sharesOut = vault.deposit(amount, to)) < minSharesOut) { + revert("Not enough shares received"); + } + } + + /// @notice Redeem tBTC from a vault and approve tokens to be transferred + /// by stBTC (Acre) + /// @param vault Address of the vault to collect the assets from. + /// @param to Address of the receiver of the assets. + /// @param shares Amount of shares to collect. Shares are the internal representation + /// of the underlying asset in the vault. Concrete amount of the + /// underlying asset is calculated by calling `convertToAssets` on + /// the vault and the shares are burned. + /// @param minAssetsOut Minimum amount of TBTC to receive. + function redeem( + IERC4626 vault, + address to, + uint256 shares, + uint256 minAssetsOut + ) public returns (uint256 assetsOut) { + if ( + (assetsOut = vault.redeem(shares, address(this), to)) < minAssetsOut + ) { + revert("Not enough assets received"); + } + IERC20(vault.asset()).safeIncreaseAllowance(to, assetsOut); + } +} From 54a1562425878c8bc72c7ad614a586feed53576e Mon Sep 17 00:00:00 2001 From: Dmitry Date: Tue, 12 Dec 2023 15:48:38 +0100 Subject: [PATCH 021/170] Resolved conflicts with the base branched --- core/contracts/Dispatcher.sol | 23 ++++++++++++++++++----- core/deploy/02_deploy_acre_router.ts | 5 ++++- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/core/contracts/Dispatcher.sol b/core/contracts/Dispatcher.sol index 6a17bcf91..7ad021713 100644 --- a/core/contracts/Dispatcher.sol +++ b/core/contracts/Dispatcher.sol @@ -2,14 +2,17 @@ pragma solidity ^0.8.21; import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/interfaces/IERC4626.sol"; import "./Router.sol"; /// @title Dispatcher -/// @notice Dispatcher is a contract that routes TBTC from stBTC (Acre) to +/// @notice Dispatcher is a contract that routes tBTC from stBTC (Acre) to /// a given vault and back. Vaults supply yield strategies with TBTC that /// generate yield for Bitcoin holders. -contract Dispatcher is Ownable { +contract Dispatcher is Router, Ownable { + using SafeERC20 for IERC20; + error VaultAlreadyAuthorized(); error VaultUnauthorized(); @@ -17,6 +20,9 @@ contract Dispatcher is Ownable { bool authorized; } + IERC20 public immutable stBTC; // Acre contract + IERC20 public immutable tBTC; + /// @notice Authorized Yield Vaults that implement ERC4626 standard. These /// vaults deposit assets to yield strategies, e.g. Uniswap V3 /// WBTC/TBTC pool. Vault can be a part of Acre ecosystem or can be @@ -29,7 +35,10 @@ contract Dispatcher is Ownable { event VaultAuthorized(address indexed vault); event VaultDeauthorized(address indexed vault); - constructor() Ownable(msg.sender) {} + constructor(IERC20 _stBTC, IERC20 _tBTC) Ownable(msg.sender) { + stBTC = _stBTC; + tBTC = _tBTC; + } /// @notice Adds a vault to the list of authorized vaults. /// @param vault Address of the vault to add. @@ -76,7 +85,9 @@ contract Dispatcher is Ownable { uint256 minSharesOut ) public { require(msg.sender == address(stBTC), "stBTC only"); - require(vaultsInfo[vault].authorized, "Vault is not approved"); + if (!vaultsInfo[vault].authorized) { + revert VaultUnauthorized(); + } deposit(IERC4626(vault), address(stBTC), amount, minSharesOut); } @@ -88,7 +99,9 @@ contract Dispatcher is Ownable { uint256 minAssetsOut ) public { require(msg.sender == address(stBTC), "stBTC only"); - require(vaultsInfo[vault].authorized, "Vault is not approved"); + if (!vaultsInfo[vault].authorized) { + revert VaultUnauthorized(); + } redeem(IERC4626(vault), address(stBTC), shares, minAssetsOut); } diff --git a/core/deploy/02_deploy_acre_router.ts b/core/deploy/02_deploy_acre_router.ts index bf99d4d73..d2441ec52 100644 --- a/core/deploy/02_deploy_acre_router.ts +++ b/core/deploy/02_deploy_acre_router.ts @@ -5,9 +5,12 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { const { getNamedAccounts, deployments } = hre const { deployer } = await getNamedAccounts() + const tTBC = await deployments.get("TBTC") + const stBTC = await deployments.get("Acre") + await deployments.deploy("Dispatcher", { from: deployer, - args: [], + args: [stBTC.address, tTBC.address], log: true, waitConfirmations: 1, }) From 1166e5ec74bc4e500c61c4acc9d1e892317ecbf9 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Tue, 12 Dec 2023 22:45:58 +0100 Subject: [PATCH 022/170] Drafting integration flows for assets --- core/contracts/Acre.sol | 39 ++++++++ core/contracts/Dispatcher.sol | 19 +++- core/contracts/test/TestERC4626.sol | 12 +++ core/deploy/00_resolve_testing_erc4626.ts | 27 ++++++ ...acre_router.ts => 02_deploy_dispatcher.ts} | 9 ++ core/test/helpers/context.ts | 5 +- core/test/integration/AssetFlows.test.ts | 91 +++++++++++++++++++ 7 files changed, 196 insertions(+), 6 deletions(-) create mode 100644 core/contracts/test/TestERC4626.sol create mode 100644 core/deploy/00_resolve_testing_erc4626.ts rename core/deploy/{02_deploy_acre_router.ts => 02_deploy_dispatcher.ts} (73%) create mode 100644 core/test/integration/AssetFlows.test.ts diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 0e1cf640f..76003fe74 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -2,6 +2,8 @@ pragma solidity ^0.8.21; import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "./Dispatcher.sol"; /// @title Acre /// @notice This contract implements the ERC-4626 tokenized vault standard. By @@ -15,6 +17,12 @@ import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; /// burning of shares (stBTC), which are represented as standard ERC20 /// tokens, providing a seamless exchange with tBTC tokens. contract Acre is ERC4626 { + using SafeERC20 for IERC20; + + Dispatcher public dispatcher; + + error ZeroAddress(); + event StakeReferral(bytes32 indexed referral, uint256 assets); constructor( @@ -43,4 +51,35 @@ contract Acre is ERC4626 { return shares; } + + // TODO: add onlyOwner + function updateDispatcher(Dispatcher _dispatcher) external { + if (address(_dispatcher) == address(0)) { + revert ZeroAddress(); + } + dispatcher = _dispatcher; + } + + // TODO: Add maintainerOnly or maintainerOrOwner? + // We should decide if this function should be called by a bot (maintainer) + // only. Leaving as is for now for testing purposes. + function depositToVault( + address vault, + uint256 amount, + uint256 minSharesOut + ) external { + IERC20(asset()).safeIncreaseAllowance(address(dispatcher), amount); + // TODO: check if the dispatcher is set + dispatcher.depositToVault(vault, amount, minSharesOut); + } + + // TODO: same question as for depositToVault + function redeemFromVault( + address vault, + uint256 shares, + uint256 minAssetsOut + ) external { + // TODO: implement + dispatcher.redeemFromVault(vault, shares, minAssetsOut); + } } diff --git a/core/contracts/Dispatcher.sol b/core/contracts/Dispatcher.sol index 7ad021713..b3393f8a9 100644 --- a/core/contracts/Dispatcher.sol +++ b/core/contracts/Dispatcher.sol @@ -15,6 +15,7 @@ contract Dispatcher is Router, Ownable { error VaultAlreadyAuthorized(); error VaultUnauthorized(); + error CallerUnauthorized(string reason); struct VaultInfo { bool authorized; @@ -78,13 +79,18 @@ contract Dispatcher is Router, Ownable { return vaults; } - // TODO: add documentation + /// @notice Routes tBTC from stBTC (Acre) to a vault. + /// @param vault Address of the vault to route the assets to. + /// @param amount Amount of tBTC to deposit. + /// @param minSharesOut Minimum amount of shares to receive by Acre. function depositToVault( address vault, uint256 amount, uint256 minSharesOut ) public { - require(msg.sender == address(stBTC), "stBTC only"); + if (msg.sender != address(stBTC)) { + revert CallerUnauthorized("Acre only"); + } if (!vaultsInfo[vault].authorized) { revert VaultUnauthorized(); } @@ -92,13 +98,18 @@ contract Dispatcher is Router, Ownable { deposit(IERC4626(vault), address(stBTC), amount, minSharesOut); } - // TODO: add documentation + /// @notice Routes tBTC from a vault to stBTC (Acre). + /// @param vault Address of the vault to collect the assets from. + /// @param shares Amount of shares to collect. + /// @param minAssetsOut Minimum amount of TBTC to receive. function redeemFromVault( address vault, uint256 shares, uint256 minAssetsOut ) public { - require(msg.sender == address(stBTC), "stBTC only"); + if (msg.sender != address(stBTC)) { + revert CallerUnauthorized("Acre only"); + } if (!vaultsInfo[vault].authorized) { revert VaultUnauthorized(); } diff --git a/core/contracts/test/TestERC4626.sol b/core/contracts/test/TestERC4626.sol new file mode 100644 index 000000000..acf09928e --- /dev/null +++ b/core/contracts/test/TestERC4626.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-3.0-only +pragma solidity ^0.8.21; + +import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; + +contract TestERC4626 is ERC4626 { + constructor( + IERC20 asset, + string memory tokenName, + string memory tokenSymbol + ) ERC4626(asset) ERC20(tokenName, tokenSymbol) {} +} diff --git a/core/deploy/00_resolve_testing_erc4626.ts b/core/deploy/00_resolve_testing_erc4626.ts new file mode 100644 index 000000000..3ceccaa15 --- /dev/null +++ b/core/deploy/00_resolve_testing_erc4626.ts @@ -0,0 +1,27 @@ +import type { HardhatRuntimeEnvironment } from "hardhat/types" +import type { DeployFunction } from "hardhat-deploy/types" + +const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { getNamedAccounts, deployments } = hre + const { log } = deployments + const { deployer } = await getNamedAccounts() + + const tBTC = await deployments.get("TBTC") + + if (hre.network.tags.allowStubs) { + log("deploying Mock ERC4626 Vault") + + await deployments.deploy("Vault", { + contract: "TestERC4626", + from: deployer, + args: [tBTC.address, "MockVault", "MV"], + log: true, + waitConfirmations: 1, + }) + } +} + +export default func + +func.tags = ["TestERC4626"] +func.dependencies = ["TBTC"] diff --git a/core/deploy/02_deploy_acre_router.ts b/core/deploy/02_deploy_dispatcher.ts similarity index 73% rename from core/deploy/02_deploy_acre_router.ts rename to core/deploy/02_deploy_dispatcher.ts index d2441ec52..831bfacc3 100644 --- a/core/deploy/02_deploy_acre_router.ts +++ b/core/deploy/02_deploy_dispatcher.ts @@ -14,6 +14,15 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { log: true, waitConfirmations: 1, }) + const dispatcher = await deployments.get("Dispatcher") + + // TODO: move to a separate script + await deployments.execute( + "Acre", + { from: deployer, log: true, waitConfirmations: 1 }, + "updateDispatcher", + dispatcher.address, + ) // TODO: Add Etherscan verification // TODO: Add Tenderly verification diff --git a/core/test/helpers/context.ts b/core/test/helpers/context.ts index 34875e43d..239242a39 100644 --- a/core/test/helpers/context.ts +++ b/core/test/helpers/context.ts @@ -2,7 +2,7 @@ import { deployments } from "hardhat" import { getDeployedContract } from "./contract" -import type { Acre, Dispatcher, TestERC20 } from "../../typechain" +import type { Acre, Dispatcher, TestERC20, TestERC4626 } from "../../typechain" // eslint-disable-next-line import/prefer-default-export export async function deployment() { @@ -11,6 +11,7 @@ export async function deployment() { const tbtc: TestERC20 = await getDeployedContract("TBTC") const acre: Acre = await getDeployedContract("Acre") const dispatcher: Dispatcher = await getDeployedContract("Dispatcher") + const vault: TestERC4626 = await getDeployedContract("Vault") - return { tbtc, acre, dispatcher } + return { tbtc, acre, dispatcher, vault } } diff --git a/core/test/integration/AssetFlows.test.ts b/core/test/integration/AssetFlows.test.ts new file mode 100644 index 000000000..169d91856 --- /dev/null +++ b/core/test/integration/AssetFlows.test.ts @@ -0,0 +1,91 @@ +import { ethers } from "hardhat" +import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers" +import { expect } from "chai" +import { + SnapshotRestorer, + takeSnapshot, + loadFixture, +} from "@nomicfoundation/hardhat-toolbox/network-helpers" +import type { Acre, Dispatcher, TestERC4626, TestERC20 } from "../../typechain" +import { deployment } from "../helpers/context" +import { getNamedSigner, getUnnamedSigner } from "../helpers/signer" +import { to1e18 } from "../utils" + +async function fixture() { + const { tbtc, acre, dispatcher, vault } = await deployment() + const { governance } = await getNamedSigner() + const [thirdParty] = await getUnnamedSigner() + + return { acre, dispatcher, governance, thirdParty, vault, tbtc } +} + +describe("Integration Test - Asset Flows", () => { + let snapshot: SnapshotRestorer + + let dispatcher: Dispatcher + let acre: Acre + let vault: TestERC4626 + let tbtc: TestERC20 + let governance: HardhatEthersSigner + let thirdParty: HardhatEthersSigner + + before(async () => { + ;({ acre, dispatcher, governance, thirdParty, vault, tbtc } = + await loadFixture(fixture)) + + await dispatcher.connect(governance).authorizeVault(vault.getAddress()) + await tbtc.mint(acre.getAddress(), to1e18(100000)) + }) + + beforeEach(async () => { + snapshot = await takeSnapshot() + }) + + afterEach(async () => { + await snapshot.restore() + }) + + describe("depositToVault", () => { + const tbtcToDeposit = to1e18(100) + const shares = to1e18(100) + + context("when caller is not Acre (stBTC)", () => { + it("should revert when depositing to a vault", async () => { + await expect( + dispatcher + .connect(thirdParty) + .depositToVault(vault.getAddress(), tbtcToDeposit, shares), + ) + .to.be.revertedWithCustomError(dispatcher, "CallerUnauthorized") + .withArgs("Acre only") + }) + }) + + context("when caller is Acre (stBTC)", () => { + it("should revert when vault is unauthorized", async () => { + const randomAddress = await ethers.Wallet.createRandom().getAddress() + await expect( + acre.depositToVault(randomAddress, tbtcToDeposit, shares), + ).to.be.revertedWithCustomError(dispatcher, "VaultUnauthorized") + }) + + it("should be able to deposit to an authorized vault", async () => { + await acre.depositToVault(vault.getAddress(), tbtcToDeposit, shares) + + expect(await tbtc.balanceOf(vault.getAddress())).to.equal(tbtcToDeposit) + }) + + it("should be able to receive vault's shares", async () => { + await acre.depositToVault(vault.getAddress(), tbtcToDeposit, shares) + + expect(await vault.balanceOf(acre.getAddress())).to.equal(shares) + }) + + // TODO: add more tests + }) + }) + + describe("redeemFromVault", () => { + // TODO: add tests + }) +}) From a26798bc1c5d4d2a93e43410af531149454a57bf Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Mon, 18 Dec 2023 16:12:20 +0100 Subject: [PATCH 023/170] Create a basic `TokenBalanceInput` component --- dapp/package.json | 3 +- .../shared/CurrencyBalance/index.tsx | 9 +- .../shared/NumberFormatInput/index.tsx | 47 +++++ .../shared/TokenBalanceInput/index.tsx | 170 ++++++++++++++++++ dapp/src/constants/currency.ts | 2 +- dapp/src/static/icons/Alert.tsx | 24 +++ dapp/src/static/icons/index.ts | 1 + dapp/src/theme/Input.ts | 40 +++++ dapp/src/theme/TokenBalanceInput.ts | 99 ++++++++++ dapp/src/theme/index.ts | 4 + dapp/src/theme/utils/colors.ts | 3 + dapp/src/utils/numbers.ts | 39 ++++ pnpm-lock.yaml | 14 ++ 13 files changed, 449 insertions(+), 6 deletions(-) create mode 100644 dapp/src/components/shared/NumberFormatInput/index.tsx create mode 100644 dapp/src/components/shared/TokenBalanceInput/index.tsx create mode 100644 dapp/src/static/icons/Alert.tsx create mode 100644 dapp/src/theme/Input.ts create mode 100644 dapp/src/theme/TokenBalanceInput.ts diff --git a/dapp/package.json b/dapp/package.json index a3dfaea79..383bc7456 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -22,7 +22,8 @@ "@ledgerhq/wallet-api-client-react": "^1.1.2", "framer-motion": "^10.16.5", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-number-format": "^5.3.1" }, "devDependencies": { "@thesis-co/eslint-config": "^0.6.1", diff --git a/dapp/src/components/shared/CurrencyBalance/index.tsx b/dapp/src/components/shared/CurrencyBalance/index.tsx index 11301c7a7..889419dad 100644 --- a/dapp/src/components/shared/CurrencyBalance/index.tsx +++ b/dapp/src/components/shared/CurrencyBalance/index.tsx @@ -1,5 +1,5 @@ import React, { useMemo } from "react" -import { Box, useMultiStyleConfig } from "@chakra-ui/react" +import { Box, useMultiStyleConfig, TextProps } from "@chakra-ui/react" import { formatTokenAmount, toLocaleString } from "../../../utils" import { CurrencyType } from "../../../types" import { CURRENCIES_BY_TYPE } from "../../../constants" @@ -11,7 +11,7 @@ export type CurrencyBalanceProps = { desiredDecimals?: number size?: string variant?: "greater-balance" -} +} & TextProps export function CurrencyBalance({ currencyType, @@ -20,6 +20,7 @@ export function CurrencyBalance({ desiredDecimals = 2, size, variant, + ...textProps }: CurrencyBalanceProps) { const styles = useMultiStyleConfig("CurrencyBalance", { size, variant }) @@ -38,10 +39,10 @@ export function CurrencyBalance({ return ( - + {balance} - + {currency.symbol} diff --git a/dapp/src/components/shared/NumberFormatInput/index.tsx b/dapp/src/components/shared/NumberFormatInput/index.tsx new file mode 100644 index 000000000..a7792f156 --- /dev/null +++ b/dapp/src/components/shared/NumberFormatInput/index.tsx @@ -0,0 +1,47 @@ +import React from "react" +import { NumericFormat } from "react-number-format" +import { InputProps, chakra, useMultiStyleConfig } from "@chakra-ui/react" + +const ChakraWrapper = chakra(NumericFormat) + +export type NumberFormatInputValues = { + formattedValue: string + value: string + floatValue: number +} + +type NumberFormatInputProps = { + onValueChange: (values: NumberFormatInputValues) => void + decimalScale?: number +} & InputProps + +/** + * Component is from the Threshold Network React Components repository. + * It has been used because it supports the thousandth separator + * and can be easily integrated with Chakra UI. + * + * More info: + * https://github.com/threshold-network/components/blob/main/src/components/NumberFormatInput/index.tsx + */ +const NumberFormatInput = React.forwardRef< + HTMLInputElement, + NumberFormatInputProps +>((props, ref) => { + const { field: css } = useMultiStyleConfig("Input", props) + + const { decimalScale, isDisabled, ...restProps } = props + + return ( + + ) +}) + +export default NumberFormatInput diff --git a/dapp/src/components/shared/TokenBalanceInput/index.tsx b/dapp/src/components/shared/TokenBalanceInput/index.tsx new file mode 100644 index 000000000..907f533d0 --- /dev/null +++ b/dapp/src/components/shared/TokenBalanceInput/index.tsx @@ -0,0 +1,170 @@ +import React, { useMemo } from "react" +import { + Box, + Button, + HStack, + Icon, + InputGroup, + InputProps, + InputRightElement, + TypographyProps, + createStylesContext, + useMultiStyleConfig, +} from "@chakra-ui/react" +import { fixedPointNumberToString } from "../../../utils" +import { CurrencyType } from "../../../types" +import { CURRENCIES_BY_TYPE } from "../../../constants" +import NumberFormatInput, { + NumberFormatInputValues, +} from "../NumberFormatInput" +import { CurrencyBalance } from "../CurrencyBalance" +import { Alert } from "../../../static/icons" + +const VARIANT = "balance" +const [StylesProvider, useStyles] = createStylesContext("TokenBalanceInput") + +type HelperErrorTextProps = { + errorMsgText?: string | JSX.Element + hasError?: boolean + helperText?: string | JSX.Element +} + +function HelperErrorText({ + helperText, + errorMsgText, + hasError, +}: HelperErrorTextProps) { + const styles = useStyles() + + if (hasError) { + return ( + + {errorMsgText || "Please enter a valid value"} + + ) + } + + if (helperText) { + return ( + + + {helperText} + + ) + } + + return null +} + +type FiatCurrencyBalanceProps = { + fiatAmount?: string + fiatCurrencyType?: CurrencyType +} + +function FiatCurrencyBalance({ + fiatAmount, + fiatCurrencyType, +}: FiatCurrencyBalanceProps) { + const { helperText } = useStyles() + const textProps = helperText as TypographyProps + + if (fiatAmount && fiatCurrencyType) { + return ( + + ) + } + + return null +} + +type TokenBalanceInputProps = { + amount?: string + currencyType: CurrencyType + tokenBalance: string | number + placeholder?: string + size?: "lg" | "md" + setAmount: (value: string) => void +} & InputProps & + HelperErrorTextProps & + FiatCurrencyBalanceProps + +export default function TokenBalanceInput({ + amount, + currencyType, + tokenBalance, + placeholder, + size = "lg", + setAmount, + errorMsgText, + helperText, + hasError = false, + fiatAmount, + fiatCurrencyType, + ...inputProps +}: TokenBalanceInputProps) { + const styles = useMultiStyleConfig("TokenBalanceInput", { size }) + + const tokenBalanceAmount = useMemo( + () => + fixedPointNumberToString( + BigInt(tokenBalance || 0), + CURRENCIES_BY_TYPE[currencyType].decimals, + ), + [currencyType, tokenBalance], + ) + + return ( + + + + Amount + + + + Balance + + + + + + + setAmount(values.value) + } + {...inputProps} + /> + + + + + + + {!hasError && !helperText && ( + + )} + + + ) +} diff --git a/dapp/src/constants/currency.ts b/dapp/src/constants/currency.ts index c35c7c9c6..420adb8b6 100644 --- a/dapp/src/constants/currency.ts +++ b/dapp/src/constants/currency.ts @@ -27,5 +27,5 @@ export const CURRENCY_ID_ETHEREUM = export const CURRENCIES_BY_TYPE: Record = { bitcoin: BITCOIN, ethereum: ETHEREUM, - usd: ETHEREUM, + usd: USD, } diff --git a/dapp/src/static/icons/Alert.tsx b/dapp/src/static/icons/Alert.tsx new file mode 100644 index 000000000..e76365d89 --- /dev/null +++ b/dapp/src/static/icons/Alert.tsx @@ -0,0 +1,24 @@ +import React from "react" +import { createIcon } from "@chakra-ui/react" + +export const Alert = createIcon({ + displayName: "Alert", + viewBox: "0 0 16 16", + path: [ + + + , + + + + + , + ], +}) diff --git a/dapp/src/static/icons/index.ts b/dapp/src/static/icons/index.ts index 0752c5839..ea843affd 100644 --- a/dapp/src/static/icons/index.ts +++ b/dapp/src/static/icons/index.ts @@ -3,3 +3,4 @@ export * from "./Bitcoin" export * from "./Ethereum" export * from "./ArrowUpRight" export * from "./AcreLogo" +export * from "./Alert" diff --git a/dapp/src/theme/Input.ts b/dapp/src/theme/Input.ts new file mode 100644 index 000000000..3bc2aeb25 --- /dev/null +++ b/dapp/src/theme/Input.ts @@ -0,0 +1,40 @@ +import { inputAnatomy as parts } from "@chakra-ui/anatomy" +import { createMultiStyleConfigHelpers, defineStyle } from "@chakra-ui/react" + +const { definePartsStyle, defineMultiStyleConfig } = + createMultiStyleConfigHelpers(parts.keys) + +const variantBalanceField = defineStyle({ + border: "1px solid", + borderColor: "gold.300", + color: "grey.700", + fontWeight: "bold", + bg: "opacity.white.5", + paddingRight: 20, + // TODO: Set the color correctly without using the chakra variable. + caretColor: "var(--chakra-colors-brand-400)", + + _placeholder: { + color: "grey.300", + fontWeight: "medium", + }, +}) + +const variantBalanceElement = defineStyle({ + h: "100%", + width: 14, + mr: 2, +}) + +const variantBalance = definePartsStyle({ + field: variantBalanceField, + element: variantBalanceElement, +}) + +const variants = { + balance: variantBalance, +} + +const Input = defineMultiStyleConfig({ variants }) + +export default Input diff --git a/dapp/src/theme/TokenBalanceInput.ts b/dapp/src/theme/TokenBalanceInput.ts new file mode 100644 index 000000000..36b16066e --- /dev/null +++ b/dapp/src/theme/TokenBalanceInput.ts @@ -0,0 +1,99 @@ +import { createMultiStyleConfigHelpers, defineStyle } from "@chakra-ui/react" + +const PARTS = [ + "container", + "labelContainer", + "label", + "balance", + "helperText", + "errorMsgText", +] + +const { defineMultiStyleConfig, definePartsStyle } = + createMultiStyleConfigHelpers(PARTS) + +const baseStyleContainer = defineStyle({ + display: "flex", + flexDirection: "column", + gap: 1, +}) + +const baseStyleLabelContainer = defineStyle({ + display: "flex", + justifyContent: "space-between", +}) + +const baseStyleLabel = defineStyle({ + fontWeight: "semibold", +}) + +const baseStyleBalance = defineStyle({ + fontWeight: "medium", + color: "grey.500", +}) + +const baseStyleHelperText = defineStyle({ + fontWeight: "medium", + color: "grey.500", +}) + +const baseStyleErrorMsgText = defineStyle({ + fontWeight: "medium", + color: "red.400", +}) + +const baseStyle = definePartsStyle({ + container: baseStyleContainer, + labelContainer: baseStyleLabelContainer, + label: baseStyleLabel, + balance: baseStyleBalance, + helperText: baseStyleHelperText, + errorMsgText: baseStyleErrorMsgText, +}) + +const sizeMd = definePartsStyle({ + label: { + fontSize: "sm", + lineHeight: "sm", + }, + balance: { + fontSize: "sm", + lineHeight: "sm", + }, + helperText: { + fontSize: "sm", + lineHeight: "sm", + }, + errorMsgText: { + fontSize: "sm", + lineHeight: "sm", + }, +}) + +const sizeLg = definePartsStyle({ + label: { + fontSize: "md", + lineHeight: "md", + }, + balance: { + fontSize: "md", + lineHeight: "md", + }, + helperText: { + fontSize: "sm", + lineHeight: "sm", + }, + errorMsgText: { + fontSize: "sm", + lineHeight: "sm", + }, +}) + +const sizes = { + md: sizeMd, + lg: sizeLg, +} + +const TokenBalanceInput = defineMultiStyleConfig({ baseStyle, sizes }) + +export default TokenBalanceInput diff --git a/dapp/src/theme/index.ts b/dapp/src/theme/index.ts index 024a55b1f..68afde1dd 100644 --- a/dapp/src/theme/index.ts +++ b/dapp/src/theme/index.ts @@ -7,6 +7,8 @@ import Tooltip from "./Tooltip" import { colors, fonts, lineHeights } from "./utils" import Heading from "./Heading" import CurrencyBalance from "./CurrencyBalance" +import TokenBalanceInput from "./TokenBalanceInput" +import Input from "./Input" const defaultTheme = { colors, @@ -28,6 +30,8 @@ const defaultTheme = { CurrencyBalance, Card, Tooltip, + Input, + TokenBalanceInput, }, } diff --git a/dapp/src/theme/utils/colors.ts b/dapp/src/theme/utils/colors.ts index f9a53d8f0..2ab5f3a12 100644 --- a/dapp/src/theme/utils/colors.ts +++ b/dapp/src/theme/utils/colors.ts @@ -54,6 +54,9 @@ export const colors = { 700: "#231F20", // Acre Dirt }, opacity: { + white: { + 5: "rgba(255, 255, 255, 0.50)", + }, grey: { 700: { 5: "rgba(35, 31, 32, 0.05)", diff --git a/dapp/src/utils/numbers.ts b/dapp/src/utils/numbers.ts index d2de47cca..e3c9077c4 100644 --- a/dapp/src/utils/numbers.ts +++ b/dapp/src/utils/numbers.ts @@ -65,3 +65,42 @@ export const formatSatoshiAmount = ( amount: number | string, desiredDecimals = 2, ) => formatTokenAmount(amount, 8, desiredDecimals) + +/** + * Converts a fixed point number with a bigint amount and a decimals field + * indicating the orders of magnitude in `amount` behind the decimal point into + * a string in US decimal format (no thousands separators, . for the decimal + * separator). + * + * Used in cases where precision is critical. + * + * This function is based on the solution used by the Taho extension. + * More info: https://github.com/tahowallet/extension/blob/main/background/lib/fixed-point.ts#L172-L214 + */ +export function fixedPointNumberToString( + amount: bigint, + decimals: number, + trimTrailingZeros = true, +): string { + const undecimaledAmount = amount.toString() + const preDecimalLength = undecimaledAmount.length - decimals + + const preDecimalCharacters = + preDecimalLength > 0 + ? undecimaledAmount.substring(0, preDecimalLength) + : "0" + const postDecimalCharacters = + "0".repeat(Math.max(-preDecimalLength, 0)) + + undecimaledAmount.substring(preDecimalLength) + + const trimmedPostDecimalCharacters = trimTrailingZeros + ? postDecimalCharacters.replace(/0*$/, "") + : postDecimalCharacters + + const decimalString = + trimmedPostDecimalCharacters.length > 0 + ? `.${trimmedPostDecimalCharacters}` + : "" + + return `${preDecimalCharacters}${decimalString}` +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2ef71f0cc..042be719e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -135,6 +135,9 @@ importers: react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) + react-number-format: + specifier: ^5.3.1 + version: 5.3.1(react-dom@18.2.0)(react@18.2.0) devDependencies: '@thesis-co/eslint-config': specifier: ^0.6.1 @@ -13099,6 +13102,17 @@ packages: /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + /react-number-format@5.3.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-qpYcQLauIeEhCZUZY9jXZnnroOtdy3jYaS1zQ3M1Sr6r/KMOBEIGNIb7eKT19g2N1wbYgFgvDzs19hw5TrB8XQ==} + peerDependencies: + react: ^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + dependencies: + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /react-refresh@0.14.0: resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} engines: {node: '>=0.10.0'} From bacd2ce53544e8c5f9992f8a79301f93d13f897c Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 19 Dec 2023 09:25:41 +0100 Subject: [PATCH 024/170] Add styles when input is invalid --- dapp/src/components/shared/NumberFormatInput/index.tsx | 3 ++- dapp/src/components/shared/TokenBalanceInput/index.tsx | 1 + dapp/src/theme/Input.ts | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/dapp/src/components/shared/NumberFormatInput/index.tsx b/dapp/src/components/shared/NumberFormatInput/index.tsx index a7792f156..4f657f711 100644 --- a/dapp/src/components/shared/NumberFormatInput/index.tsx +++ b/dapp/src/components/shared/NumberFormatInput/index.tsx @@ -29,7 +29,7 @@ const NumberFormatInput = React.forwardRef< >((props, ref) => { const { field: css } = useMultiStyleConfig("Input", props) - const { decimalScale, isDisabled, ...restProps } = props + const { decimalScale, isDisabled, isInvalid, ...restProps } = props return ( diff --git a/dapp/src/components/shared/TokenBalanceInput/index.tsx b/dapp/src/components/shared/TokenBalanceInput/index.tsx index 907f533d0..94c5ccd81 100644 --- a/dapp/src/components/shared/TokenBalanceInput/index.tsx +++ b/dapp/src/components/shared/TokenBalanceInput/index.tsx @@ -140,6 +140,7 @@ export default function TokenBalanceInput({ size={size} value={amount} variant={VARIANT} + isInvalid={hasError} placeholder={placeholder} onValueChange={(values: NumberFormatInputValues) => setAmount(values.value) diff --git a/dapp/src/theme/Input.ts b/dapp/src/theme/Input.ts index 3bc2aeb25..cccff7c7c 100644 --- a/dapp/src/theme/Input.ts +++ b/dapp/src/theme/Input.ts @@ -18,6 +18,10 @@ const variantBalanceField = defineStyle({ color: "grey.300", fontWeight: "medium", }, + + _invalid: { + color: "red.400", + }, }) const variantBalanceElement = defineStyle({ From bff966536a08c6cddcf466b2026ba33ce49d71f4 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Tue, 19 Dec 2023 15:04:23 +0100 Subject: [PATCH 025/170] Update `mint` function Check the `super.mint` result inline to optimize the gas usage. In this way we should save ~2k gas if we do not duplicate the `previewMint` call. --- core/contracts/Acre.sol | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index be4d78a82..8fd1ef3d4 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -82,17 +82,16 @@ contract Acre is ERC4626, Ownable { function mint( uint256 shares, address receiver - ) public override returns (uint256) { - uint256 assets = previewMint(shares); - - if (assets < stakingParameters.minimumDepositAmount) { + ) public override returns (uint256 assets) { + if ( + (assets = super.mint(shares, receiver)) < + stakingParameters.minimumDepositAmount + ) { revert StakingAmountLessThanMin( assets, stakingParameters.minimumDepositAmount ); } - - return super.mint(shares, receiver); } /// @notice Stakes a given amount of tBTC token and mints shares to a From 9ed875d8bb83ca3a08124e9191a637330280e168 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Tue, 19 Dec 2023 15:35:37 +0100 Subject: [PATCH 026/170] Update `updateStakingParameters` function We should leave the possibility to set `minimumDepositAmount` to zero. --- core/contracts/Acre.sol | 2 +- core/test/Acre.test.ts | 30 +++++++++++++++++------------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 8fd1ef3d4..2fab07dd0 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -55,7 +55,7 @@ contract Acre is ERC4626, Ownable { uint256 maximumTotalAssets ) external onlyOwner { // TODO: Introduce a parameters update process. - if (minimumDepositAmount <= 0 || maximumTotalAssets <= 0) { + if (minimumDepositAmount < 0 || maximumTotalAssets <= 0) { revert InvalidStakingParameter(); } diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 8bf29c942..a912d4637 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -589,20 +589,24 @@ describe("Acre", () => { }) }) - context("when minimum deposit amount is invalid", () => { - context("when it is equal to 0", () => { - const minimumDepositAmount = 0 + context("when minimum deposit amount is 0", () => { + const newMinimumDepositAmount = 0 - it("should revert", async () => { - await expect( - acre - .connect(owner) - .updateStakingParameters( - minimumDepositAmount, - validMaximumTotalAssetsAmount, - ), - ).to.be.revertedWithCustomError(acre, "InvalidStakingParameter") - }) + beforeEach(async () => { + await acre + .connect(owner) + .updateStakingParameters( + newMinimumDepositAmount, + validMaximumTotalAssetsAmount, + ) + }) + + it("should update the minimum deposit amount correctly", async () => { + const stakingParameters = await acre.stakingParameters() + + expect(stakingParameters.minimumDepositAmount).to.be.eq( + newMinimumDepositAmount, + ) }) }) From f9f230aff688839084791336b0e46281cf3ce999 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Tue, 19 Dec 2023 15:42:05 +0100 Subject: [PATCH 027/170] Rename error `StakingAmountLessThanMin` -> `DepositAmountLessThanMin` --- core/contracts/Acre.sol | 6 +++--- core/test/Acre.test.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 2fab07dd0..9aa17b18b 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -31,7 +31,7 @@ contract Acre is ERC4626, Ownable { uint256 maximumTotalAssets ); - error StakingAmountLessThanMin(uint256 amount, uint256 min); + error DepositAmountLessThanMin(uint256 amount, uint256 min); error InvalidStakingParameter(); constructor( @@ -70,7 +70,7 @@ contract Acre is ERC4626, Ownable { address receiver ) public override returns (uint256) { if (assets < stakingParameters.minimumDepositAmount) { - revert StakingAmountLessThanMin( + revert DepositAmountLessThanMin( assets, stakingParameters.minimumDepositAmount ); @@ -87,7 +87,7 @@ contract Acre is ERC4626, Ownable { (assets = super.mint(shares, receiver)) < stakingParameters.minimumDepositAmount ) { - revert StakingAmountLessThanMin( + revert DepositAmountLessThanMin( assets, stakingParameters.minimumDepositAmount ); diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index a912d4637..3ea71677d 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -172,7 +172,7 @@ describe("Acre", () => { acre .connect(staker1) .stake(amountToStake, staker1.address, referral), - ).to.revertedWithCustomError(acre, "StakingAmountLessThanMin") + ).to.revertedWithCustomError(acre, "DepositAmountLessThanMin") }) }) @@ -193,7 +193,7 @@ describe("Acre", () => { acre .connect(staker1) .stake(amountToStake, staker1.address, referral), - ).to.revertedWithCustomError(acre, "StakingAmountLessThanMin") + ).to.revertedWithCustomError(acre, "DepositAmountLessThanMin") }) }) @@ -539,7 +539,7 @@ describe("Acre", () => { it("should take into account the min deposit amount parameter and revert", async () => { await expect( acre.connect(staker1).mint(sharesToMint, staker1.address), - ).to.be.revertedWithCustomError(acre, "StakingAmountLessThanMin") + ).to.be.revertedWithCustomError(acre, "DepositAmountLessThanMin") }) }, ) From b2c4a800e5d1c92e714480d21e6a671c9e46df6f Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Tue, 19 Dec 2023 17:01:06 +0100 Subject: [PATCH 028/170] Simplify `maxDeposit` function Use ternary operator instead of `if` statement. --- core/contracts/Acre.sol | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 9aa17b18b..5d9da7418 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -126,9 +126,10 @@ contract Acre is ERC4626, Ownable { function maxDeposit(address) public view override returns (uint256) { uint256 _totalAssets = totalAssets(); - if (_totalAssets >= stakingParameters.maximumTotalAssets) return 0; - - return stakingParameters.maximumTotalAssets - _totalAssets; + return + _totalAssets >= stakingParameters.maximumTotalAssets + ? 0 + : stakingParameters.maximumTotalAssets - _totalAssets; } /// @notice Returns the maximum amount of the vault shares that can be From ea67712dc49c33127052f1588fcec0aa32c4d1f2 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Tue, 19 Dec 2023 17:22:03 +0100 Subject: [PATCH 029/170] Add unit test for `mint` function Add a simple test case to check that `mint` function works if the transaction is within the limits. --- core/test/Acre.test.ts | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 3ea71677d..24c0514a6 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -505,6 +505,51 @@ describe("Acre", () => { await snapshot.restore() }) + context("when minting as first staker", () => { + const amountToStake = to1e18(1) + let tx: ContractTransactionResponse + let sharesToMint: bigint + + beforeEach(async () => { + sharesToMint = await acre.previewDeposit(amountToStake) + + await tbtc + .connect(staker1) + .approve(await acre.getAddress(), amountToStake) + + tx = await acre.connect(staker1).mint(sharesToMint, staker1.address) + }) + + it("should emit Deposit event", () => { + expect(tx).to.emit(acre, "Deposit").withArgs( + // Caller. + staker1.address, + // Receiver. + staker1.address, + // Staked tokens. + amountToStake, + // Received shares. + sharesToMint, + ) + }) + + it("should mint stBTC tokens", async () => { + await expect(tx).to.changeTokenBalances( + acre, + [staker1.address], + [sharesToMint], + ) + }) + + it("should transfer tBTC tokens", async () => { + await expect(tx).to.changeTokenBalances( + tbtc, + [staker1.address, acre], + [-amountToStake, amountToStake], + ) + }) + }) + context("when staker wants to mint more shares than allowed", () => { let sharesToMint: bigint From 43f583db56171b0812b1a27dad802924b8278592 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 20 Dec 2023 11:34:40 +0100 Subject: [PATCH 030/170] Fix typo `anythig` -> `anything` and rewrap comment. --- core/test/Acre.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 24c0514a6..159fa46a5 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -58,9 +58,9 @@ describe("Acre", () => { context("with a referral", () => { const amountToStake = to1e18(1) - // In this test case there is only one staker and - // the token vault has not earned anythig yet so received shares are - // equal to staked tokens amount. + // In this test case, there is only one staker and the token vault has + // not earned anything yet so received shares are equal to staked tokens + // amount. const expectedReceivedShares = amountToStake let tx: ContractTransactionResponse From becb46e9a116306f3130bfebacf076ef88dff20a Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 20 Dec 2023 11:36:27 +0100 Subject: [PATCH 031/170] Add unit tests for `maxMint` function --- core/test/Acre.test.ts | 74 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 159fa46a5..aa30d2046 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -744,4 +744,78 @@ describe("Acre", () => { }) }) }) + + describe("maxMint", () => { + let maximumTotalAssets: bigint + let snapshot: SnapshotRestorer + + beforeEach(async () => { + snapshot = await takeSnapshot() + ;({ maximumTotalAssets } = await acre.stakingParameters()) + }) + + afterEach(async () => { + await snapshot.restore() + }) + + context( + "when total assets is greater than maximum total assets amount", + () => { + beforeEach(async () => { + const toMint = maximumTotalAssets + 1n + + await tbtc.mint(await acre.getAddress(), toMint) + }) + + it("should return 0", async () => { + expect(await acre.maxMint(staker1.address)).to.be.eq(0) + }) + }, + ) + + context("when the vault is empty", () => { + it("should return maximum total assets amount in shares", async () => { + // When the vault is empty the max shares amount is equal to the maximum + // total assets amount. + expect(await acre.maxMint(staker1.address)).to.be.eq(maximumTotalAssets) + }) + }) + + context("when the maximum total amount has not yet been reached", () => { + let expectedValue: bigint + + beforeEach(async () => { + const toMint = to1e18(2) + const amountToStake = to1e18(3) + const newMaximumTotalAssets = to1e18(30) + const minimumDepositAmount = to1e18(1) + + await acre + .connect(owner) + .updateStakingParameters(minimumDepositAmount, newMaximumTotalAssets) + + // Staker stakes 3 tBTC. + await tbtc + .connect(staker1) + .approve(await acre.getAddress(), amountToStake) + await acre.connect(staker1).deposit(amountToStake, staker1.address) + + // Vault earns 2 tBTC. + await tbtc.mint(await acre.getAddress(), toMint) + + // The current state is: + // Total assets: 5 + // Total supply: 3 + // Maximum total assets: 30 + // Current max deposit: 30 - 2 - 3 = 25 + // Max shares: 25 * 3 / 5 = 15 -> 15000000000000000001 in stBTC + // precision and rounding support. + expectedValue = 15000000000000000001n + }) + + it("should return correct value", async () => { + expect(await acre.maxMint(staker1.address)).to.be.eq(expectedValue) + }) + }) + }) }) From 1c42a377aede695f0ed22c705dd2f067cea4c370 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 20 Dec 2023 11:44:30 +0100 Subject: [PATCH 032/170] Update validation of staking parameters The `minimumDepositAmount` is `uint256` type so `minimumDepositAmount < 0` will alwyas be true. We can remove this check and in previous commit we left a possibility to update the `minimumDepositAmount` to `0` so we do not have to validate this value, at least for now. Also `maximumTotalAssets` is `uint256` type so we can't assign negative values - here we only check if `maximumTotalAssets` is not zero. --- core/contracts/Acre.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 5d9da7418..cfc6246d5 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -43,7 +43,6 @@ contract Acre is ERC4626, Ownable { /// @notice Updates parameters of staking. /// @dev Requirements: - /// - Minimum deposit amount must be greater than zero, /// - Maximum total assets must be greater than zero. /// @param minimumDepositAmount New value of the minimum deposit amount. It /// is the minimum amount for a single deposit operation. @@ -55,7 +54,7 @@ contract Acre is ERC4626, Ownable { uint256 maximumTotalAssets ) external onlyOwner { // TODO: Introduce a parameters update process. - if (minimumDepositAmount < 0 || maximumTotalAssets <= 0) { + if (maximumTotalAssets == 0) { revert InvalidStakingParameter(); } From a5903e3b5fccab73ce8e75d47a6e6cd9e066902a Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 20 Dec 2023 12:01:28 +0100 Subject: [PATCH 033/170] Update `maxMint` function According to the EIP-4626 `previewDeposit` and `convertToShares` slightly differ, especially in terms of taking fees into account. We plan to add fees for deposits and withdrawals that will be included in the previewDeposit function. This will cause `previewDeposit` and `convertToShares` return different values. Here for the `maxMint` calculation, we want to have pure assets to shares conversion, exclusive of the fees. --- core/contracts/Acre.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index cfc6246d5..4f2c0e604 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -137,6 +137,6 @@ contract Acre is ERC4626, Ownable { /// function converts the maximum deposit amount to shares. /// @return The maximum amount of the vault shares. function maxMint(address receiver) public view override returns (uint256) { - return previewDeposit(maxDeposit(receiver)); + return convertToShares(maxDeposit(receiver)); } } From a13b09f8afbc78414dd2040a57239b65a7babd9c Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 20 Dec 2023 15:52:39 +0100 Subject: [PATCH 034/170] Get rid of `StakingParameter` struct To reduce complexity, especially for contract upgrades and dealing with storage changes in upgradable contracts, which is very tricky. Here we also expose `depositParameters` function that returns all deposit-related parameters in a single call. --- core/contracts/Acre.sol | 69 +++++++++++++++++++---------------------- core/test/Acre.test.ts | 47 +++++++++++++--------------- 2 files changed, 53 insertions(+), 63 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 4f2c0e604..38125a417 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -16,63 +16,59 @@ import "@openzeppelin/contracts/access/Ownable.sol"; /// burning of shares (stBTC), which are represented as standard ERC20 /// tokens, providing a seamless exchange with tBTC tokens. contract Acre is ERC4626, Ownable { - struct StakingParameters { - // Minimum amount for a single deposit operation. - uint256 minimumDepositAmount; - // Maximum total amount of tBTC token held by Acre. - uint256 maximumTotalAssets; - } - - StakingParameters public stakingParameters; + // Minimum amount for a single deposit operation. + uint256 public minimumDepositAmount; + // Maximum total amount of tBTC token held by Acre. + uint256 public maximumTotalAssets; event StakeReferral(bytes32 indexed referral, uint256 assets); - event StakingParametersUpdated( + event DepositParametersUpdated( uint256 minimumDepositAmount, uint256 maximumTotalAssets ); error DepositAmountLessThanMin(uint256 amount, uint256 min); - error InvalidStakingParameter(); + error InvalidDepositParameter(); constructor( IERC20 tbtc ) ERC4626(tbtc) ERC20("Acre Staked Bitcoin", "stBTC") Ownable(msg.sender) { - stakingParameters.minimumDepositAmount = 0.01 ether; // 0.01 tBTC - stakingParameters.maximumTotalAssets = 25 ether; // 25 tBTC + minimumDepositAmount = 0.01 ether; // 0.01 tBTC + maximumTotalAssets = 25 ether; // 25 tBTC } /// @notice Updates parameters of staking. /// @dev Requirements: /// - Maximum total assets must be greater than zero. - /// @param minimumDepositAmount New value of the minimum deposit amount. It + /// @param _minimumDepositAmount New value of the minimum deposit amount. It /// is the minimum amount for a single deposit operation. - /// @param maximumTotalAssets New value of the maximum total assets amount. + /// @param _maximumTotalAssets New value of the maximum total assets amount. /// It is the maximum amount of the tBTC token that the Acre can /// hold. - function updateStakingParameters( - uint256 minimumDepositAmount, - uint256 maximumTotalAssets + function updateDepositParameters( + uint256 _minimumDepositAmount, + uint256 _maximumTotalAssets ) external onlyOwner { // TODO: Introduce a parameters update process. - if (maximumTotalAssets == 0) { - revert InvalidStakingParameter(); + if (_maximumTotalAssets == 0) { + revert InvalidDepositParameter(); } - stakingParameters.minimumDepositAmount = minimumDepositAmount; - stakingParameters.maximumTotalAssets = maximumTotalAssets; + minimumDepositAmount = _minimumDepositAmount; + maximumTotalAssets = _maximumTotalAssets; - emit StakingParametersUpdated(minimumDepositAmount, maximumTotalAssets); + emit DepositParametersUpdated( + _minimumDepositAmount, + _maximumTotalAssets + ); } function deposit( uint256 assets, address receiver ) public override returns (uint256) { - if (assets < stakingParameters.minimumDepositAmount) { - revert DepositAmountLessThanMin( - assets, - stakingParameters.minimumDepositAmount - ); + if (assets < minimumDepositAmount) { + revert DepositAmountLessThanMin(assets, minimumDepositAmount); } return super.deposit(assets, receiver); @@ -82,14 +78,8 @@ contract Acre is ERC4626, Ownable { uint256 shares, address receiver ) public override returns (uint256 assets) { - if ( - (assets = super.mint(shares, receiver)) < - stakingParameters.minimumDepositAmount - ) { - revert DepositAmountLessThanMin( - assets, - stakingParameters.minimumDepositAmount - ); + if ((assets = super.mint(shares, receiver)) < minimumDepositAmount) { + revert DepositAmountLessThanMin(assets, minimumDepositAmount); } } @@ -126,9 +116,9 @@ contract Acre is ERC4626, Ownable { uint256 _totalAssets = totalAssets(); return - _totalAssets >= stakingParameters.maximumTotalAssets + _totalAssets >= maximumTotalAssets ? 0 - : stakingParameters.maximumTotalAssets - _totalAssets; + : maximumTotalAssets - _totalAssets; } /// @notice Returns the maximum amount of the vault shares that can be @@ -139,4 +129,9 @@ contract Acre is ERC4626, Ownable { function maxMint(address receiver) public view override returns (uint256) { return convertToShares(maxDeposit(receiver)); } + + /// @return Returns deposit parametrs + function depositParameters() public view returns (uint256, uint256) { + return (minimumDepositAmount, maximumTotalAssets); + } } diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index aa30d2046..57f9ce9e9 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -180,7 +180,7 @@ describe("Acre", () => { let amountToStake: bigint beforeEach(async () => { - const { minimumDepositAmount } = await acre.stakingParameters() + const [minimumDepositAmount] = await acre.depositParameters() amountToStake = minimumDepositAmount - 1n await tbtc @@ -202,7 +202,7 @@ describe("Acre", () => { let tx: ContractTransactionResponse beforeEach(async () => { - const { minimumDepositAmount } = await acre.stakingParameters() + const [minimumDepositAmount] = await acre.depositParameters() amountToStake = minimumDepositAmount await tbtc @@ -572,7 +572,7 @@ describe("Acre", () => { let sharesToMint: bigint beforeEach(async () => { - const { minimumDepositAmount } = await acre.stakingParameters() + const [minimumDepositAmount] = await acre.depositParameters() const previewDeposit = await acre.previewDeposit(minimumDepositAmount) sharesToMint = previewDeposit - 1n @@ -590,7 +590,7 @@ describe("Acre", () => { ) }) - describe("updateStakingParameters", () => { + describe("updateDepositParameters", () => { const validMinimumDepositAmount = to1e18(1) const validMaximumTotalAssetsAmount = to1e18(30) let snapshot: SnapshotRestorer @@ -610,27 +610,24 @@ describe("Acre", () => { beforeEach(async () => { tx = await acre .connect(owner) - .updateStakingParameters( + .updateDepositParameters( validMinimumDepositAmount, validMaximumTotalAssetsAmount, ) }) - it("should emit StakingParametersUpdated event", async () => { + it("should emit DepositParametersUpdated event", async () => { await expect(tx) - .to.emit(acre, "StakingParametersUpdated") + .to.emit(acre, "DepositParametersUpdated") .withArgs(validMinimumDepositAmount, validMaximumTotalAssetsAmount) }) it("should update parameters correctly", async () => { - const stakingParameters = await acre.stakingParameters() + const [minimumDepositAmount, maximumTotalAssets] = + await acre.depositParameters() - expect(stakingParameters.minimumDepositAmount).to.be.eq( - validMinimumDepositAmount, - ) - expect(stakingParameters.maximumTotalAssets).to.be.eq( - validMaximumTotalAssetsAmount, - ) + expect(minimumDepositAmount).to.be.eq(validMinimumDepositAmount) + expect(maximumTotalAssets).to.be.eq(validMaximumTotalAssetsAmount) }) }) @@ -640,18 +637,16 @@ describe("Acre", () => { beforeEach(async () => { await acre .connect(owner) - .updateStakingParameters( + .updateDepositParameters( newMinimumDepositAmount, validMaximumTotalAssetsAmount, ) }) it("should update the minimum deposit amount correctly", async () => { - const stakingParameters = await acre.stakingParameters() + const [minimumDepositAmount] = await acre.depositParameters() - expect(stakingParameters.minimumDepositAmount).to.be.eq( - newMinimumDepositAmount, - ) + expect(minimumDepositAmount).to.be.eq(newMinimumDepositAmount) }) }) @@ -663,11 +658,11 @@ describe("Acre", () => { await expect( acre .connect(owner) - .updateStakingParameters( + .updateDepositParameters( validMinimumDepositAmount, maximumTotalAssets, ), - ).to.be.revertedWithCustomError(acre, "InvalidStakingParameter") + ).to.be.revertedWithCustomError(acre, "InvalidDepositParameter") }) }) }) @@ -678,7 +673,7 @@ describe("Acre", () => { await expect( acre .connect(staker1) - .updateStakingParameters( + .updateDepositParameters( validMinimumDepositAmount, validMaximumTotalAssetsAmount, ), @@ -693,7 +688,7 @@ describe("Acre", () => { beforeEach(async () => { snapshot = await takeSnapshot() - ;({ maximumTotalAssets } = await acre.stakingParameters()) + maximumTotalAssets = await acre.maximumTotalAssets() }) afterEach(async () => { @@ -735,7 +730,7 @@ describe("Acre", () => { await acre .connect(owner) - .updateStakingParameters(minimumDepositAmount, newMaximumTotalAssets) + .updateDepositParameters(minimumDepositAmount, newMaximumTotalAssets) await tbtc.mint(await acre.getAddress(), toMint) }) @@ -751,7 +746,7 @@ describe("Acre", () => { beforeEach(async () => { snapshot = await takeSnapshot() - ;({ maximumTotalAssets } = await acre.stakingParameters()) + maximumTotalAssets = await acre.maximumTotalAssets() }) afterEach(async () => { @@ -792,7 +787,7 @@ describe("Acre", () => { await acre .connect(owner) - .updateStakingParameters(minimumDepositAmount, newMaximumTotalAssets) + .updateDepositParameters(minimumDepositAmount, newMaximumTotalAssets) // Staker stakes 3 tBTC. await tbtc From 31f74f2c69ed76b787c0c82c5c3409c33163dfdc Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 21 Dec 2023 07:46:32 +0100 Subject: [PATCH 035/170] Update `Acre` constructor Using `ether` as the unit will be confusing here, let's explicitly use decimals. Here we also leave a TODO - we need to revisit the exact values closer to the launch. --- core/contracts/Acre.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 38125a417..0612a502d 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -33,8 +33,9 @@ contract Acre is ERC4626, Ownable { constructor( IERC20 tbtc ) ERC4626(tbtc) ERC20("Acre Staked Bitcoin", "stBTC") Ownable(msg.sender) { - minimumDepositAmount = 0.01 ether; // 0.01 tBTC - maximumTotalAssets = 25 ether; // 25 tBTC + // TODO: Revisit the exact values closer to the launch. + minimumDepositAmount = 0.01 * 1e18; // 0.01 tBTC + maximumTotalAssets = 25 * 1e18; // 25 tBTC } /// @notice Updates parameters of staking. From 5ec1b805f63fc338de823da96df069b3eb44fbf4 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 21 Dec 2023 07:56:14 +0100 Subject: [PATCH 036/170] Rename error `InvalidDepositParameter` -> `InvalidMaximumTotalAssetsParameter`. The previous one was too general - now we exactly know what's wrong with which parameter. --- core/contracts/Acre.sol | 4 ++-- core/test/Acre.test.ts | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 0612a502d..edf4cebfa 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -28,7 +28,7 @@ contract Acre is ERC4626, Ownable { ); error DepositAmountLessThanMin(uint256 amount, uint256 min); - error InvalidDepositParameter(); + error InvalidMaximumTotalAssetsParameter(uint256 maximumTotalAssets); constructor( IERC20 tbtc @@ -52,7 +52,7 @@ contract Acre is ERC4626, Ownable { ) external onlyOwner { // TODO: Introduce a parameters update process. if (_maximumTotalAssets == 0) { - revert InvalidDepositParameter(); + revert InvalidMaximumTotalAssetsParameter(_maximumTotalAssets); } minimumDepositAmount = _minimumDepositAmount; diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 57f9ce9e9..acc57a02c 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -662,7 +662,10 @@ describe("Acre", () => { validMinimumDepositAmount, maximumTotalAssets, ), - ).to.be.revertedWithCustomError(acre, "InvalidDepositParameter") + ).to.be.revertedWithCustomError( + acre, + "InvalidMaximumTotalAssetsParameter", + ) }) }) }) From 1f14cde7e114aff3fb2080f80ec9082f3de97978 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 21 Dec 2023 08:16:11 +0100 Subject: [PATCH 037/170] Update Acre docs Add documentation to `deposit` and `mint` functions and fix typos. --- core/contracts/Acre.sol | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index edf4cebfa..aea6a5ff7 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -38,7 +38,7 @@ contract Acre is ERC4626, Ownable { maximumTotalAssets = 25 * 1e18; // 25 tBTC } - /// @notice Updates parameters of staking. + /// @notice Updates deposit parameters. /// @dev Requirements: /// - Maximum total assets must be greater than zero. /// @param _minimumDepositAmount New value of the minimum deposit amount. It @@ -64,6 +64,15 @@ contract Acre is ERC4626, Ownable { ); } + /// @notice Mints shares to receiver by depositing exactly amount of + /// tBTC tokens. + /// @dev Takes into account a deposit parameter, minimum deposit amount, + /// which determines the minimum amount for a single deposit operation. + /// The amount of the assets has to be pre-approved in the tBTC + /// contract. + /// @param assets Approved amount of tBTC tokens to deposit. + /// @param receiver The address to which the shares will be minted. + /// @return Minted shares. function deposit( uint256 assets, address receiver @@ -75,6 +84,14 @@ contract Acre is ERC4626, Ownable { return super.deposit(assets, receiver); } + /// @notice Mints shares to receiver by depositing tBTC tokens. + /// @dev Takes into account a deposit parameter, minimum deposit amount, + /// which determines the minimum amount for a single deposit operation. + /// The amount of the assets has to be pre-approved in the tBTC + /// contract. + /// @param shares Amount of shares to mint. To get the amount of share use + /// `previewMint`. + /// @param receiver The address to which the shares will be minted. function mint( uint256 shares, address receiver @@ -109,7 +126,7 @@ contract Acre is ERC4626, Ownable { /// @notice Returns the maximum amount of the tBTC token that can be /// deposited into the vault for the receiver, through a deposit - /// call. It takes into account the staking parameter, maximum total + /// call. It takes into account the deposit parameter, maximum total /// assets, which determines the total amount of tBTC token held by /// Acre. /// @return The maximum amount of the tBTC token. From e8f7aa11c2e5835bac584e48325ab74ecf4c9e84 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 21 Dec 2023 08:21:38 +0100 Subject: [PATCH 038/170] Remove unnecessary test We can remove `when amount to stake is 1` test, as we have it covered by `when amount to stake is less than minimum`. --- core/test/Acre.test.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index acc57a02c..ac37db303 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -158,24 +158,6 @@ describe("Acre", () => { }, ) - context("when amount to stake is 1", () => { - const amountToStake = 1 - - beforeEach(async () => { - await tbtc - .connect(staker1) - .approve(await acre.getAddress(), amountToStake) - }) - - it("should revert", async () => { - await expect( - acre - .connect(staker1) - .stake(amountToStake, staker1.address, referral), - ).to.revertedWithCustomError(acre, "DepositAmountLessThanMin") - }) - }) - context("when amount to stake is less than minimum", () => { let amountToStake: bigint From ab8d89cb277fe238df54a1cc3e7386afb7442c3c Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 21 Dec 2023 08:30:41 +0100 Subject: [PATCH 039/170] Add `.withArgs` for all errors that have args --- core/test/Acre.test.ts | 65 ++++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index ac37db303..1e3b85018 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -153,16 +153,19 @@ describe("Acre", () => { acre .connect(staker1) .stake(amountToStake, staker1.address, referral), - ).to.be.revertedWithCustomError(tbtc, "ERC20InsufficientAllowance") + ) + .to.be.revertedWithCustomError(tbtc, "ERC20InsufficientAllowance") + .withArgs(await acre.getAddress(), approvedAmount, amountToStake) }) }, ) context("when amount to stake is less than minimum", () => { let amountToStake: bigint + let minimumDepositAmount: bigint beforeEach(async () => { - const [minimumDepositAmount] = await acre.depositParameters() + ;[minimumDepositAmount] = await acre.depositParameters() amountToStake = minimumDepositAmount - 1n await tbtc @@ -175,7 +178,9 @@ describe("Acre", () => { acre .connect(staker1) .stake(amountToStake, staker1.address, referral), - ).to.revertedWithCustomError(acre, "DepositAmountLessThanMin") + ) + .to.revertedWithCustomError(acre, "DepositAmountLessThanMin") + .withArgs(amountToStake, minimumDepositAmount) }) }) @@ -217,7 +222,9 @@ describe("Acre", () => { it("should revert", async () => { await expect( acre.connect(staker1).stake(amountToStake, ZeroAddress, referral), - ).to.be.revertedWithCustomError(acre, "ERC20InvalidReceiver") + ) + .to.be.revertedWithCustomError(acre, "ERC20InvalidReceiver") + .withArgs(ZeroAddress) }) }) @@ -241,7 +248,9 @@ describe("Acre", () => { acre .connect(staker1) .stake(amountToStake, staker1.address, referral), - ).to.be.revertedWithCustomError(acre, "ERC20InsufficientAllowance") + ) + .to.be.revertedWithCustomError(acre, "ERC20InsufficientAllowance") + .withArgs(await acre.getAddress(), 0, amountToStake) }) }, ) @@ -466,9 +475,16 @@ describe("Acre", () => { }) it("should revert", async () => { - await expect( - acre.stake(amountToStake, staker1.address, referral), - ).to.be.revertedWithCustomError(acre, "ERC4626ExceededMaxDeposit") + await expect(acre.stake(amountToStake, staker1.address, referral)) + .to.be.revertedWithCustomError( + acre, + "ERC4626ExceededMaxDeposit", + ) + .withArgs( + staker1.address, + amountToStake, + possibleMaxAmountToStake, + ) }) }, ) @@ -534,17 +550,18 @@ describe("Acre", () => { context("when staker wants to mint more shares than allowed", () => { let sharesToMint: bigint + let maxMint: bigint beforeEach(async () => { - const maxMint = await acre.maxMint(staker1.address) + maxMint = await acre.maxMint(staker1.address) sharesToMint = maxMint + 1n }) it("should take into account the max total assets parameter and revert", async () => { - await expect( - acre.connect(staker1).mint(sharesToMint, staker1.address), - ).to.be.revertedWithCustomError(acre, "ERC4626ExceededMaxMint") + await expect(acre.connect(staker1).mint(sharesToMint, staker1.address)) + .to.be.revertedWithCustomError(acre, "ERC4626ExceededMaxMint") + .withArgs(staker1.address, sharesToMint, maxMint) }) }) @@ -552,9 +569,10 @@ describe("Acre", () => { "when staker wants to mint less shares than is equal to the min deposit amount", () => { let sharesToMint: bigint + let minimumDepositAmount: bigint beforeEach(async () => { - const [minimumDepositAmount] = await acre.depositParameters() + ;[minimumDepositAmount] = await acre.depositParameters() const previewDeposit = await acre.previewDeposit(minimumDepositAmount) sharesToMint = previewDeposit - 1n @@ -564,9 +582,16 @@ describe("Acre", () => { }) it("should take into account the min deposit amount parameter and revert", async () => { + // In this test case, there is only one staker and the token vault has + // not earned anything yet so received shares are equal to staked + // tokens amount. + const depositAmount = sharesToMint + await expect( acre.connect(staker1).mint(sharesToMint, staker1.address), - ).to.be.revertedWithCustomError(acre, "DepositAmountLessThanMin") + ) + .to.be.revertedWithCustomError(acre, "DepositAmountLessThanMin") + .withArgs(depositAmount, minimumDepositAmount) }) }, ) @@ -644,10 +669,12 @@ describe("Acre", () => { validMinimumDepositAmount, maximumTotalAssets, ), - ).to.be.revertedWithCustomError( - acre, - "InvalidMaximumTotalAssetsParameter", ) + .to.be.revertedWithCustomError( + acre, + "InvalidMaximumTotalAssetsParameter", + ) + .withArgs(maximumTotalAssets) }) }) }) @@ -662,7 +689,9 @@ describe("Acre", () => { validMinimumDepositAmount, validMaximumTotalAssetsAmount, ), - ).to.be.revertedWithCustomError(acre, "OwnableUnauthorizedAccount") + ) + .to.be.revertedWithCustomError(acre, "OwnableUnauthorizedAccount") + .withArgs(staker1.address) }) }) }) From 0e33e4bb62d56b4151fc0586e0ffc80aae70aed2 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 21 Dec 2023 08:35:20 +0100 Subject: [PATCH 040/170] Celean up Acre unit tests - improve test descriptions, - use `minimumDepositAmount` instead of `depositParameters` in some cases where we only need the minimum deposit amount, - get rid of unnecessary `updateDepositParameters` call in `beforeEach` hook. We can test with default values. --- core/test/Acre.test.ts | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 1e3b85018..a97c72d8d 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -165,7 +165,7 @@ describe("Acre", () => { let minimumDepositAmount: bigint beforeEach(async () => { - ;[minimumDepositAmount] = await acre.depositParameters() + minimumDepositAmount = await acre.minimumDepositAmount() amountToStake = minimumDepositAmount - 1n await tbtc @@ -189,7 +189,7 @@ describe("Acre", () => { let tx: ContractTransactionResponse beforeEach(async () => { - const [minimumDepositAmount] = await acre.depositParameters() + const minimumDepositAmount = await acre.minimumDepositAmount() amountToStake = minimumDepositAmount await tbtc @@ -548,7 +548,7 @@ describe("Acre", () => { }) }) - context("when staker wants to mint more shares than allowed", () => { + context("when staker wants to mint more shares than max mint limit", () => { let sharesToMint: bigint let maxMint: bigint @@ -566,13 +566,13 @@ describe("Acre", () => { }) context( - "when staker wants to mint less shares than is equal to the min deposit amount", + "when staker wants to mint less shares than the min deposit amount", () => { let sharesToMint: bigint let minimumDepositAmount: bigint beforeEach(async () => { - ;[minimumDepositAmount] = await acre.depositParameters() + minimumDepositAmount = await acre.minimumDepositAmount() const previewDeposit = await acre.previewDeposit(minimumDepositAmount) sharesToMint = previewDeposit - 1n @@ -651,7 +651,7 @@ describe("Acre", () => { }) it("should update the minimum deposit amount correctly", async () => { - const [minimumDepositAmount] = await acre.depositParameters() + const minimumDepositAmount = await acre.minimumDepositAmount() expect(minimumDepositAmount).to.be.eq(newMinimumDepositAmount) }) @@ -737,14 +737,8 @@ describe("Acre", () => { beforeEach(async () => { const toMint = to1e18(2) - const newMaximumTotalAssets = to1e18(30) - const minimumDepositAmount = to1e18(1) + expectedValue = maximumTotalAssets - toMint - expectedValue = newMaximumTotalAssets - toMint - - await acre - .connect(owner) - .updateDepositParameters(minimumDepositAmount, newMaximumTotalAssets) await tbtc.mint(await acre.getAddress(), toMint) }) @@ -796,12 +790,6 @@ describe("Acre", () => { beforeEach(async () => { const toMint = to1e18(2) const amountToStake = to1e18(3) - const newMaximumTotalAssets = to1e18(30) - const minimumDepositAmount = to1e18(1) - - await acre - .connect(owner) - .updateDepositParameters(minimumDepositAmount, newMaximumTotalAssets) // Staker stakes 3 tBTC. await tbtc @@ -816,10 +804,10 @@ describe("Acre", () => { // Total assets: 5 // Total supply: 3 // Maximum total assets: 30 - // Current max deposit: 30 - 2 - 3 = 25 - // Max shares: 25 * 3 / 5 = 15 -> 15000000000000000001 in stBTC + // Current max deposit: 25 - 2 - 3 = 20 + // Max shares: 20 * 3 / 5 = 15 -> 12000000000000000001 in stBTC // precision and rounding support. - expectedValue = 15000000000000000001n + expectedValue = 12000000000000000001n }) it("should return correct value", async () => { From fdd62ed54bfee7a0a74b860106407da97f366a55 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 22 Dec 2023 14:09:26 +0100 Subject: [PATCH 041/170] Use Form Control for `TokenBalanceInput` --- .../shared/TokenBalanceInput/index.tsx | 75 +++++++++-------- dapp/src/theme/Form.ts | 21 +++++ dapp/src/theme/FormError.ts | 19 +++++ dapp/src/theme/FormLabel.ts | 25 ++++++ dapp/src/theme/TokenBalanceInput.ts | 80 ++----------------- dapp/src/theme/index.ts | 6 ++ 6 files changed, 114 insertions(+), 112 deletions(-) create mode 100644 dapp/src/theme/Form.ts create mode 100644 dapp/src/theme/FormError.ts create mode 100644 dapp/src/theme/FormLabel.ts diff --git a/dapp/src/components/shared/TokenBalanceInput/index.tsx b/dapp/src/components/shared/TokenBalanceInput/index.tsx index c8feb6d8d..ff6f1da40 100644 --- a/dapp/src/components/shared/TokenBalanceInput/index.tsx +++ b/dapp/src/components/shared/TokenBalanceInput/index.tsx @@ -2,13 +2,14 @@ import React, { useMemo } from "react" import { Box, Button, - HStack, + FormControl, + FormErrorMessage, + FormHelperText, + FormLabel, Icon, InputGroup, InputProps, InputRightElement, - TypographyProps, - createStylesContext, useMultiStyleConfig, } from "@chakra-ui/react" import { fixedPointNumberToString } from "../../../utils" @@ -21,7 +22,6 @@ import { CurrencyBalance } from "../CurrencyBalance" import { AlertInfo } from "../../../static/icons" const VARIANT = "balance" -const [StylesProvider, useStyles] = createStylesContext("TokenBalanceInput") type HelperErrorTextProps = { errorMsgText?: string | JSX.Element @@ -34,22 +34,20 @@ function HelperErrorText({ errorMsgText, hasError, }: HelperErrorTextProps) { - const styles = useStyles() - if (hasError) { return ( - + {errorMsgText || "Please enter a valid value"} - + ) } if (helperText) { return ( - + - {helperText} - + {helperText} + ) } @@ -65,8 +63,8 @@ function FiatCurrencyBalance({ fiatAmount, fiatCurrencyType, }: FiatCurrencyBalanceProps) { - const { helperText } = useStyles() - const textProps = helperText as TypographyProps + const styles = useMultiStyleConfig("Form") + const { fontWeight } = styles.helperText if (fiatAmount && fiatCurrencyType) { return ( @@ -74,7 +72,8 @@ function FiatCurrencyBalance({ currencyType={fiatCurrencyType} amount={fiatAmount} shouldBeFormatted={false} - {...textProps} + fontWeight={fontWeight as string} + size="sm" /> ) } @@ -119,22 +118,22 @@ export default function TokenBalanceInput({ ) return ( - - - + + + Amount - - - - Balance + + + Balance + + - - - + + - - - {!hasError && !helperText && ( + + {!hasError && !helperText && ( + - )} - - + + )} + ) } diff --git a/dapp/src/theme/Form.ts b/dapp/src/theme/Form.ts new file mode 100644 index 000000000..42a4a7165 --- /dev/null +++ b/dapp/src/theme/Form.ts @@ -0,0 +1,21 @@ +import { formAnatomy as parts } from "@chakra-ui/anatomy" +import { createMultiStyleConfigHelpers, defineStyle } from "@chakra-ui/react" + +const { defineMultiStyleConfig, definePartsStyle } = + createMultiStyleConfigHelpers(parts.keys) + +const baseStyleHelperText = defineStyle({ + display: "flex", + alignItems: "center", + gap: 1, + fontWeight: "medium", + color: "grey.500", +}) + +const baseStyle = definePartsStyle({ + helperText: baseStyleHelperText, +}) + +const Form = defineMultiStyleConfig({ baseStyle }) + +export default Form diff --git a/dapp/src/theme/FormError.ts b/dapp/src/theme/FormError.ts new file mode 100644 index 000000000..f9b8dd9b3 --- /dev/null +++ b/dapp/src/theme/FormError.ts @@ -0,0 +1,19 @@ +import { defineStyle, createMultiStyleConfigHelpers } from "@chakra-ui/react" + +import { formErrorAnatomy as parts } from "@chakra-ui/anatomy" + +const { defineMultiStyleConfig, definePartsStyle } = + createMultiStyleConfigHelpers(parts.keys) + +const baseStyleText = defineStyle({ + fontWeight: "medium", + color: "red.400", +}) + +const baseStyle = definePartsStyle({ + text: baseStyleText, +}) + +const FormError = defineMultiStyleConfig({ baseStyle }) + +export default FormError diff --git a/dapp/src/theme/FormLabel.ts b/dapp/src/theme/FormLabel.ts new file mode 100644 index 000000000..08e211903 --- /dev/null +++ b/dapp/src/theme/FormLabel.ts @@ -0,0 +1,25 @@ +import { defineStyle, defineStyleConfig } from "@chakra-ui/react" + +const baseStyle = defineStyle({ + fontWeight: "semibold", + color: "grey.700", +}) + +const sizeMd = defineStyle({ + fontSize: "sm", + lineHeight: "sm", +}) + +const sizeLg = defineStyle({ + fontSize: "md", + lineHeight: "md", +}) + +const sizes = { + md: sizeMd, + lg: sizeLg, +} + +const FormLabel = defineStyleConfig({ baseStyle, sizes }) + +export default FormLabel diff --git a/dapp/src/theme/TokenBalanceInput.ts b/dapp/src/theme/TokenBalanceInput.ts index 36b16066e..8c662a769 100644 --- a/dapp/src/theme/TokenBalanceInput.ts +++ b/dapp/src/theme/TokenBalanceInput.ts @@ -1,30 +1,18 @@ import { createMultiStyleConfigHelpers, defineStyle } from "@chakra-ui/react" -const PARTS = [ - "container", - "labelContainer", - "label", - "balance", - "helperText", - "errorMsgText", -] +const PARTS = ["labelContainer", "balanceContainer", "balance"] const { defineMultiStyleConfig, definePartsStyle } = createMultiStyleConfigHelpers(PARTS) -const baseStyleContainer = defineStyle({ - display: "flex", - flexDirection: "column", - gap: 1, -}) - const baseStyleLabelContainer = defineStyle({ display: "flex", justifyContent: "space-between", }) -const baseStyleLabel = defineStyle({ - fontWeight: "semibold", +const baseStyleBalanceContainer = defineStyle({ + display: "flex", + gap: 1, }) const baseStyleBalance = defineStyle({ @@ -32,68 +20,12 @@ const baseStyleBalance = defineStyle({ color: "grey.500", }) -const baseStyleHelperText = defineStyle({ - fontWeight: "medium", - color: "grey.500", -}) - -const baseStyleErrorMsgText = defineStyle({ - fontWeight: "medium", - color: "red.400", -}) - const baseStyle = definePartsStyle({ - container: baseStyleContainer, labelContainer: baseStyleLabelContainer, - label: baseStyleLabel, + balanceContainer: baseStyleBalanceContainer, balance: baseStyleBalance, - helperText: baseStyleHelperText, - errorMsgText: baseStyleErrorMsgText, }) -const sizeMd = definePartsStyle({ - label: { - fontSize: "sm", - lineHeight: "sm", - }, - balance: { - fontSize: "sm", - lineHeight: "sm", - }, - helperText: { - fontSize: "sm", - lineHeight: "sm", - }, - errorMsgText: { - fontSize: "sm", - lineHeight: "sm", - }, -}) - -const sizeLg = definePartsStyle({ - label: { - fontSize: "md", - lineHeight: "md", - }, - balance: { - fontSize: "md", - lineHeight: "md", - }, - helperText: { - fontSize: "sm", - lineHeight: "sm", - }, - errorMsgText: { - fontSize: "sm", - lineHeight: "sm", - }, -}) - -const sizes = { - md: sizeMd, - lg: sizeLg, -} - -const TokenBalanceInput = defineMultiStyleConfig({ baseStyle, sizes }) +const TokenBalanceInput = defineMultiStyleConfig({ baseStyle }) export default TokenBalanceInput diff --git a/dapp/src/theme/index.ts b/dapp/src/theme/index.ts index c1e05c2bc..6e7babc46 100644 --- a/dapp/src/theme/index.ts +++ b/dapp/src/theme/index.ts @@ -14,6 +14,9 @@ import TokenBalanceInput from "./TokenBalanceInput" import Input from "./Input" import Stepper from "./Stepper" import Alert from "./Alert" +import Form from "./Form" +import FormLabel from "./FormLabel" +import FormError from "./FormError" const defaultTheme = { colors, @@ -44,6 +47,9 @@ const defaultTheme = { TokenBalanceInput, Stepper, Alert, + Form, + FormLabel, + FormError, }, } From 7269487f75fd9cf0e5aa32c7b74481cf6543e45f Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 27 Dec 2023 11:11:26 +0100 Subject: [PATCH 042/170] Form initialization for stake/unstake action --- dapp/package.json | 1 + .../components/Modals/ActionForm/index.tsx | 45 ++++++++ .../components/Modals/Staking/StakeForm.tsx | 31 ++++-- dapp/src/components/Modals/Staking/index.tsx | 6 +- dapp/src/components/shared/Form/Form.tsx | 4 + .../shared/Form/FormTokenBalanceInput.tsx | 24 +++++ dapp/src/components/shared/Form/index.tsx | 2 + .../shared/FormBase/TransactionDetails.tsx | 100 ++++++++++++++++++ dapp/src/components/shared/FormBase/index.tsx | 49 +++++++++ .../shared/TokenBalanceInput/index.tsx | 20 ++-- dapp/src/theme/Tabs.ts | 51 +++++++++ dapp/src/theme/index.ts | 2 + dapp/src/types/index.ts | 1 + dapp/src/types/staking.ts | 1 + pnpm-lock.yaml | 43 ++++++++ 15 files changed, 362 insertions(+), 18 deletions(-) create mode 100644 dapp/src/components/Modals/ActionForm/index.tsx create mode 100644 dapp/src/components/shared/Form/Form.tsx create mode 100644 dapp/src/components/shared/Form/FormTokenBalanceInput.tsx create mode 100644 dapp/src/components/shared/Form/index.tsx create mode 100644 dapp/src/components/shared/FormBase/TransactionDetails.tsx create mode 100644 dapp/src/components/shared/FormBase/index.tsx create mode 100644 dapp/src/theme/Tabs.ts create mode 100644 dapp/src/types/staking.ts diff --git a/dapp/package.json b/dapp/package.json index 383bc7456..39fdc283b 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -20,6 +20,7 @@ "@emotion/styled": "^11.11.0", "@ledgerhq/wallet-api-client": "^1.2.1", "@ledgerhq/wallet-api-client-react": "^1.1.2", + "formik": "^2.4.5", "framer-motion": "^10.16.5", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/dapp/src/components/Modals/ActionForm/index.tsx b/dapp/src/components/Modals/ActionForm/index.tsx new file mode 100644 index 000000000..bacb4de49 --- /dev/null +++ b/dapp/src/components/Modals/ActionForm/index.tsx @@ -0,0 +1,45 @@ +import React from "react" +import { + ModalBody, + Tabs, + TabList, + Tab, + TabPanels, + TabPanel, +} from "@chakra-ui/react" +import { ModalStep } from "../../../contexts" +import StakeForm from "../Staking/StakeForm" + +const TABS = ["stake", "unstake"] as const + +type FormType = (typeof TABS)[number] + +type ActionFormProps = { defaultForm: FormType } & ModalStep + +function ActionForm({ defaultForm, goNext }: ActionFormProps) { + return ( + + + + {TABS.map((tab) => ( + + {tab} + + ))} + + + + + + {/* TODO: Add form for unstake */} + + + + ) +} + +export default ActionForm diff --git a/dapp/src/components/Modals/Staking/StakeForm.tsx b/dapp/src/components/Modals/Staking/StakeForm.tsx index 8d308ecff..fa76d849d 100644 --- a/dapp/src/components/Modals/Staking/StakeForm.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm.tsx @@ -1,15 +1,28 @@ import React from "react" -import { Button, ModalBody } from "@chakra-ui/react" +import { withFormik } from "formik" import { ModalStep } from "../../../contexts" -import { TextMd } from "../../shared/Typography" +import FormBase, { FormBaseProps, FormValues } from "../../shared/FormBase" +import { useWalletContext } from "../../../hooks" + +// TODO: Add a validate function +const StakeFormik = withFormik({ + handleSubmit: (values, { props }) => { + // TODO: Handle the correct form action + props.goNext() + }, +})(FormBase) + +function StakeForm({ goNext }: ModalStep) { + const { btcAccount } = useWalletContext() -export default function StakeModal({ goNext }: ModalStep) { return ( - - Stake modal - - + ) } + +export default StakeForm diff --git a/dapp/src/components/Modals/Staking/index.tsx b/dapp/src/components/Modals/Staking/index.tsx index d5b117df3..eb0b09387 100644 --- a/dapp/src/components/Modals/Staking/index.tsx +++ b/dapp/src/components/Modals/Staking/index.tsx @@ -1,17 +1,17 @@ import React from "react" import { useModalFlowContext } from "../../../hooks" -import StakeForm from "./StakeForm" import Overview from "./Overview" import ModalBase from "../../shared/ModalBase" +import ActionForm from "../ActionForm" function StakingSteps() { const { activeStep, goNext } = useModalFlowContext() switch (activeStep) { case 1: - return + return case 2: - return + return default: return null } diff --git a/dapp/src/components/shared/Form/Form.tsx b/dapp/src/components/shared/Form/Form.tsx new file mode 100644 index 000000000..8b3cbc2b1 --- /dev/null +++ b/dapp/src/components/shared/Form/Form.tsx @@ -0,0 +1,4 @@ +import { chakra } from "@chakra-ui/react" +import { Form as FormikForm } from "formik" + +export const Form = chakra(FormikForm) diff --git a/dapp/src/components/shared/Form/FormTokenBalanceInput.tsx b/dapp/src/components/shared/Form/FormTokenBalanceInput.tsx new file mode 100644 index 000000000..5f88f8bec --- /dev/null +++ b/dapp/src/components/shared/Form/FormTokenBalanceInput.tsx @@ -0,0 +1,24 @@ +import React from "react" +import { useField } from "formik" +import TokenBalanceInput, { TokenBalanceInputProps } from "../TokenBalanceInput" + +export type FormTokenBalanceInputProps = { + name: string +} & Omit +export function FormTokenBalanceInput({ + name, + ...restProps +}: FormTokenBalanceInputProps) { + const [field, meta, helpers] = useField(name) + + return ( + + ) +} diff --git a/dapp/src/components/shared/Form/index.tsx b/dapp/src/components/shared/Form/index.tsx new file mode 100644 index 000000000..57268f72b --- /dev/null +++ b/dapp/src/components/shared/Form/index.tsx @@ -0,0 +1,2 @@ +export * from "./Form" +export * from "./FormTokenBalanceInput" diff --git a/dapp/src/components/shared/FormBase/TransactionDetails.tsx b/dapp/src/components/shared/FormBase/TransactionDetails.tsx new file mode 100644 index 000000000..fe53538a7 --- /dev/null +++ b/dapp/src/components/shared/FormBase/TransactionDetails.tsx @@ -0,0 +1,100 @@ +import React from "react" +import { Box, Flex, VStack } from "@chakra-ui/react" +import { useField } from "formik" +import { CurrencyBalanceWithConversion } from "../CurrencyBalanceWithConversion" +import { TextMd } from "../Typography" +import { TransactionType } from "../../../types" + +const DETAILS: Record< + TransactionType, + { + btcAmountText: string + protocolFeeText: string + estimatedAmountText: string + } +> = { + stake: { + btcAmountText: "Amount to be staked", + protocolFeeText: "Protocol fee (0.01%)", + estimatedAmountText: "Approximately staked tokens", + }, + unstake: { + btcAmountText: "Amount to be unstaked from the pool", + protocolFeeText: "Protocol fee (0.01%)", + estimatedAmountText: "Approximately unstaked tokens", + }, +} + +function TransactionDetailsItem({ + text, + btcAmount, + usdAmount, +}: { + text: string + btcAmount: string | number + usdAmount: string +}) { + return ( + + + {text} + + + + + + ) +} + +function TransactionDetails({ + fieldName, + type, +}: { + fieldName: string + type: TransactionType +}) { + const [, { value }] = useField(fieldName) + + const { btcAmountText, protocolFeeText, estimatedAmountText } = DETAILS[type] + + // TODO: Let's simplify it and secure edge cases + const btcAmount = parseFloat(value) || 0 + const protocolFee = btcAmount * 0.01 + const stakedAmount = btcAmount - protocolFee + + return ( + + + + + + ) +} + +export default TransactionDetails diff --git a/dapp/src/components/shared/FormBase/index.tsx b/dapp/src/components/shared/FormBase/index.tsx new file mode 100644 index 000000000..b7cb33740 --- /dev/null +++ b/dapp/src/components/shared/FormBase/index.tsx @@ -0,0 +1,49 @@ +import React from "react" +import { Button } from "@chakra-ui/react" +import { FormikProps } from "formik" +import { Form, FormTokenBalanceInput } from "../Form" +import { CurrencyType, TransactionType } from "../../../types" +import TransactionDetails from "./TransactionDetails" + +export type FormValues = { + amount: string +} + +export type FormBaseProps = { + transactionType: TransactionType + btnText: string + tokenBalance: string + tokenBalanceInputPlaceholder?: string + currencyType?: CurrencyType + fieldName?: string + children?: React.ReactNode +} + +function FormBase({ + transactionType, + btnText, + tokenBalance, + tokenBalanceInputPlaceholder = "BTC", + currencyType = "bitcoin", + fieldName = "amount", + children, + ...formikProps +}: FormBaseProps & FormikProps) { + return ( +
+ + + {children} + + + ) +} + +export default FormBase diff --git a/dapp/src/components/shared/TokenBalanceInput/index.tsx b/dapp/src/components/shared/TokenBalanceInput/index.tsx index ff6f1da40..d5ec6244c 100644 --- a/dapp/src/components/shared/TokenBalanceInput/index.tsx +++ b/dapp/src/components/shared/TokenBalanceInput/index.tsx @@ -1,4 +1,4 @@ -import React, { useMemo } from "react" +import React, { useMemo, useRef } from "react" import { Box, Button, @@ -81,13 +81,13 @@ function FiatCurrencyBalance({ return null } -type TokenBalanceInputProps = { +export type TokenBalanceInputProps = { amount?: string currencyType: CurrencyType tokenBalance: string | number placeholder?: string size?: "lg" | "md" - setAmount: (value: string) => void + setAmount: (value?: string) => void } & InputProps & HelperErrorTextProps & FiatCurrencyBalanceProps @@ -106,6 +106,7 @@ export default function TokenBalanceInput({ fiatCurrencyType, ...inputProps }: TokenBalanceInputProps) { + const valueRef = useRef(amount) const styles = useMultiStyleConfig("TokenBalanceInput", { size }) const tokenBalanceAmount = useMemo( @@ -117,6 +118,10 @@ export default function TokenBalanceInput({ [currencyType, tokenBalance], ) + const handleValueChange = (value: string) => { + valueRef.current = value + } + return ( @@ -137,14 +142,17 @@ export default function TokenBalanceInput({ - setAmount(values.value) + handleValueChange(values.value) } - {...inputProps} + onChange={() => { + setAmount(valueRef?.current) + }} /> diff --git a/dapp/src/constants/index.ts b/dapp/src/constants/index.ts index 68cb50031..a5cb59713 100644 --- a/dapp/src/constants/index.ts +++ b/dapp/src/constants/index.ts @@ -1 +1,2 @@ export * from "./currency" +export * from "./staking" diff --git a/dapp/src/constants/staking.ts b/dapp/src/constants/staking.ts new file mode 100644 index 000000000..19cd34be0 --- /dev/null +++ b/dapp/src/constants/staking.ts @@ -0,0 +1,8 @@ +export const BITCOIN_MIN_AMOUNT = "1000000" // 0.01 BTC + +export const ERRORS = { + REQUIRED: "Required.", + EXCEEDED_VALUE: "The amount exceeds your current balance.", + INSUFFICIENT_VALUE: (minValue: string) => + `The minimum amount must be at least ${minValue} BTC.`, +} From 4c67f66a5ad63025b4e20883ede0384059181883 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Thu, 28 Dec 2023 19:28:31 +0100 Subject: [PATCH 058/170] Handling the submission of the stake form --- .../components/Modals/Staking/StakeForm.tsx | 23 +++++++++---- .../src/components/shared/ModalBase/index.tsx | 26 ++++++++------ dapp/src/contexts/TransactionContext.tsx | 34 +++++++++++++++++++ dapp/src/contexts/index.tsx | 1 + dapp/src/hooks/index.ts | 1 + dapp/src/hooks/useTransactionContext.ts | 14 ++++++++ 6 files changed, 83 insertions(+), 16 deletions(-) create mode 100644 dapp/src/contexts/TransactionContext.tsx create mode 100644 dapp/src/hooks/useTransactionContext.ts diff --git a/dapp/src/components/Modals/Staking/StakeForm.tsx b/dapp/src/components/Modals/Staking/StakeForm.tsx index d88628685..3af0c6712 100644 --- a/dapp/src/components/Modals/Staking/StakeForm.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm.tsx @@ -1,12 +1,15 @@ -import React from "react" +import React, { useCallback } from "react" import { FormikErrors, withFormik } from "formik" import { ModalStep } from "../../../contexts" import FormBase, { FormBaseProps, FormValues } from "../../shared/FormBase" -import { useWalletContext } from "../../../hooks" +import { useTransactionContext, useWalletContext } from "../../../hooks" import { formatSatoshiAmount } from "../../../utils" import { BITCOIN_MIN_AMOUNT, ERRORS } from "../../../constants" -const StakeFormik = withFormik({ +const StakeFormik = withFormik< + { onSubmitForm: (values: FormValues) => void } & FormBaseProps, + FormValues +>({ validate: ({ amount: value }, { tokenBalance }) => { const errors: FormikErrors = {} @@ -29,20 +32,28 @@ const StakeFormik = withFormik({ return errors }, handleSubmit: (values, { props }) => { - // TODO: Handle the correct form action - props.goNext() + props.onSubmitForm(values) }, })(FormBase) function StakeForm({ goNext }: ModalStep) { const { btcAccount } = useWalletContext() + const { setAmount } = useTransactionContext() + + const handleSubmitForm = useCallback( + (values: FormValues) => { + setAmount(values.amount) + goNext() + }, + [goNext, setAmount], + ) return ( ) } diff --git a/dapp/src/components/shared/ModalBase/index.tsx b/dapp/src/components/shared/ModalBase/index.tsx index 423f29e1c..cfeb34472 100644 --- a/dapp/src/components/shared/ModalBase/index.tsx +++ b/dapp/src/components/shared/ModalBase/index.tsx @@ -5,7 +5,11 @@ import { ModalContent, ModalOverlay, } from "@chakra-ui/react" -import { ModalFlowContext, ModalFlowContextValue } from "../../../contexts" +import { + ModalFlowContext, + ModalFlowContextValue, + TransactionContextProvider, +} from "../../../contexts" import { useSidebar } from "../../../hooks" import SupportWrapper from "../../Modals/Support" @@ -66,14 +70,16 @@ export default function ModalBase({ ) return ( - - - - - - {children} - - - + + + + + + + {children} + + + + ) } diff --git a/dapp/src/contexts/TransactionContext.tsx b/dapp/src/contexts/TransactionContext.tsx new file mode 100644 index 000000000..c61c84a7d --- /dev/null +++ b/dapp/src/contexts/TransactionContext.tsx @@ -0,0 +1,34 @@ +import React, { createContext, useMemo, useState } from "react" + +type TransactionContextValue = { + amount?: string + setAmount: React.Dispatch> +} + +export const TransactionContext = createContext({ + amount: undefined, + setAmount: () => {}, +}) + +export function TransactionContextProvider({ + children, +}: { + children: React.ReactNode +}): React.ReactElement { + const [amount, setAmount] = useState(undefined) + + const contextValue: TransactionContextValue = + useMemo( + () => ({ + amount, + setAmount, + }), + [amount], + ) + + return ( + + {children} + + ) +} diff --git a/dapp/src/contexts/index.tsx b/dapp/src/contexts/index.tsx index 6787e1cc6..a849afb3f 100644 --- a/dapp/src/contexts/index.tsx +++ b/dapp/src/contexts/index.tsx @@ -3,3 +3,4 @@ export * from "./LedgerWalletAPIProvider" export * from "./DocsDrawerContext" export * from "./SidebarContext" export * from "./ModalFlowContext" +export * from "./TransactionContext" diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts index 076da9a53..4f2b42d57 100644 --- a/dapp/src/hooks/index.ts +++ b/dapp/src/hooks/index.ts @@ -5,3 +5,4 @@ export * from "./useWalletContext" export * from "./useSidebar" export * from "./useDocsDrawer" export * from "./useModalFlowContext" +export * from "./useTransactionContext" diff --git a/dapp/src/hooks/useTransactionContext.ts b/dapp/src/hooks/useTransactionContext.ts new file mode 100644 index 000000000..d28c8bf1b --- /dev/null +++ b/dapp/src/hooks/useTransactionContext.ts @@ -0,0 +1,14 @@ +import { useContext } from "react" +import { TransactionContext } from "../contexts" + +export function useTransactionContext() { + const context = useContext(TransactionContext) + + if (!context) { + throw new Error( + "TransactionContext used outside of TransactionContext component", + ) + } + + return context +} From 5866ec515e1fe3d5ad64732972c826ac22a6ad9b Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Thu, 28 Dec 2023 21:47:43 +0100 Subject: [PATCH 059/170] Import ethers from hardhat When using ethers we should import it from hardhat. --- core/test/Acre.test.ts | 1 + core/test/helpers/contract.ts | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 4a5960e3e..b4f176830 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -3,6 +3,7 @@ import { loadFixture, } from "@nomicfoundation/hardhat-toolbox/network-helpers" import { expect } from "chai" +import { ethers } from "hardhat" import { ContractTransactionResponse, ZeroAddress } from "ethers" import type { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers" diff --git a/core/test/helpers/contract.ts b/core/test/helpers/contract.ts index 88a83812a..6ba7b36ae 100644 --- a/core/test/helpers/contract.ts +++ b/core/test/helpers/contract.ts @@ -1,5 +1,4 @@ -import { ethers } from "ethers" -import { deployments } from "hardhat" +import { deployments, ethers } from "hardhat" import type { BaseContract } from "ethers" import { getUnnamedSigner } from "./signer" From 58576bd62a8ca07304f460582a96104448712a6f Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Thu, 28 Dec 2023 21:48:44 +0100 Subject: [PATCH 060/170] Update @thesis-co/eslint-config to the latest version This version enables `@typescript-eslint/recommended-type-checked` rules. The commit hash refers to the merge commit of https://github.com/thesis/eslint-config/pull/12. --- core/package.json | 2 +- pnpm-lock.yaml | 44 ++++++++++++++++++++++++++++++++++++++------ sdk/package.json | 2 +- website/package.json | 2 +- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/core/package.json b/core/package.json index ff7aa5197..ca5b4e175 100644 --- a/core/package.json +++ b/core/package.json @@ -35,7 +35,7 @@ "@nomicfoundation/hardhat-verify": "^2.0.1", "@nomiclabs/hardhat-etherscan": "^3.1.7", "@openzeppelin/hardhat-upgrades": "^2.4.1", - "@thesis-co/eslint-config": "^0.6.1", + "@thesis-co/eslint-config": "github:thesis/eslint-config#7b9bc8c", "@typechain/ethers-v6": "^0.5.1", "@typechain/hardhat": "^9.1.0", "@types/chai": "^4.3.11", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5c71a8afa..ccfe3ea52 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -46,8 +46,8 @@ importers: specifier: ^2.4.1 version: 2.4.1(@nomicfoundation/hardhat-ethers@3.0.5)(@nomicfoundation/hardhat-verify@2.0.1)(ethers@6.8.1)(hardhat@2.19.1) '@thesis-co/eslint-config': - specifier: ^0.6.1 - version: 0.6.1(eslint@8.54.0)(prettier@3.1.0)(typescript@5.3.2) + specifier: github:thesis/eslint-config#7b9bc8c + version: github.com/thesis/eslint-config/7b9bc8c(eslint@8.54.0)(prettier@3.1.0)(typescript@5.3.2) '@typechain/ethers-v6': specifier: ^0.5.1 version: 0.5.1(ethers@6.8.1)(typechain@8.3.2)(typescript@5.3.2) @@ -173,8 +173,8 @@ importers: sdk: devDependencies: '@thesis-co/eslint-config': - specifier: ^0.6.1 - version: 0.6.1(eslint@8.54.0)(prettier@3.1.0)(typescript@5.3.2) + specifier: github:thesis/eslint-config#7b9bc8c + version: github.com/thesis/eslint-config/7b9bc8c(eslint@8.54.0)(prettier@3.1.0)(typescript@5.3.2) '@types/chai': specifier: ^4.3.11 version: 4.3.11 @@ -225,8 +225,8 @@ importers: version: 6.1.0(react@18.2.0) devDependencies: '@thesis-co/eslint-config': - specifier: ^0.6.1 - version: 0.6.1(eslint@8.54.0)(prettier@3.1.0)(typescript@5.3.2) + specifier: github:thesis/eslint-config#7b9bc8c + version: github.com/thesis/eslint-config/7b9bc8c(eslint@8.54.0)(prettier@3.1.0)(typescript@5.3.2) '@types/node': specifier: ^20.9.4 version: 20.9.4 @@ -15476,6 +15476,38 @@ packages: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} dev: false + github.com/thesis/eslint-config/7b9bc8c(eslint@8.54.0)(prettier@3.1.0)(typescript@5.3.2): + resolution: {tarball: https://codeload.github.com/thesis/eslint-config/tar.gz/7b9bc8c} + id: github.com/thesis/eslint-config/7b9bc8c + name: '@thesis-co/eslint-config' + version: 0.8.0-pre + engines: {node: '>=14.0.0'} + peerDependencies: + eslint: '>=6.8.0' + dependencies: + '@thesis-co/prettier-config': github.com/thesis/prettier-config/daeaac564056a7885e4366ce12bfde6fd823fc90(prettier@3.1.0) + '@typescript-eslint/eslint-plugin': 6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.3.2) + eslint: 8.54.0 + eslint-config-airbnb: 19.0.4(eslint-plugin-import@2.29.0)(eslint-plugin-jsx-a11y@6.8.0)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.33.2)(eslint@8.54.0) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.0)(eslint@8.54.0) + eslint-config-airbnb-typescript: 17.1.0(@typescript-eslint/eslint-plugin@6.12.0)(@typescript-eslint/parser@6.12.0)(eslint-plugin-import@2.29.0)(eslint@8.54.0) + eslint-config-prettier: 9.0.0(eslint@8.54.0) + eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0) + eslint-plugin-jsx-a11y: 6.8.0(eslint@8.54.0) + eslint-plugin-no-only-tests: 3.1.0 + eslint-plugin-prettier: 5.0.1(eslint-config-prettier@9.0.0)(eslint@8.54.0)(prettier@3.1.0) + eslint-plugin-react: 7.33.2(eslint@8.54.0) + eslint-plugin-react-hooks: 4.6.0(eslint@8.54.0) + transitivePeerDependencies: + - '@types/eslint' + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - prettier + - supports-color + - typescript + dev: true + github.com/thesis/prettier-config/daeaac564056a7885e4366ce12bfde6fd823fc90(prettier@3.1.0): resolution: {tarball: https://codeload.github.com/thesis/prettier-config/tar.gz/daeaac564056a7885e4366ce12bfde6fd823fc90} id: github.com/thesis/prettier-config/daeaac564056a7885e4366ce12bfde6fd823fc90 diff --git a/sdk/package.json b/sdk/package.json index 49d9e8580..2c95625aa 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -14,7 +14,7 @@ "test": "mocha --exit --recursive 'test/**/*.test.ts'" }, "devDependencies": { - "@thesis-co/eslint-config": "^0.6.1", + "@thesis-co/eslint-config": "github:thesis/eslint-config#7b9bc8c", "@types/chai": "^4.3.11", "@types/mocha": "^10.0.6", "@types/node": "^20.9.4", diff --git a/website/package.json b/website/package.json index 23f6fdb53..3d0dcc6fd 100644 --- a/website/package.json +++ b/website/package.json @@ -28,7 +28,7 @@ "react-helmet": "^6.1.0" }, "devDependencies": { - "@thesis-co/eslint-config": "^0.6.1", + "@thesis-co/eslint-config": "github:thesis/eslint-config#7b9bc8c", "@types/node": "^20.9.4", "@types/react": "^18.2.38", "@types/react-dom": "^18.2.17", From 57272f0f3c52082ec8aa4b609e9aabf8166e7f1b Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Thu, 28 Dec 2023 22:07:37 +0100 Subject: [PATCH 061/170] Fix problems reported by eslint The problems were reported after the latest upgrade of eslint-config. --- core/deploy/00_resolve_tbtc.ts | 1 + core/deploy/21_transfer_ownership_acre.ts | 2 ++ core/deploy/22_transfer_ownership_acre_router.ts | 1 + core/test/Acre.test.ts | 16 ++++++++-------- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/core/deploy/00_resolve_tbtc.ts b/core/deploy/00_resolve_tbtc.ts index dc1bfeff5..bf9f27d46 100644 --- a/core/deploy/00_resolve_tbtc.ts +++ b/core/deploy/00_resolve_tbtc.ts @@ -4,6 +4,7 @@ import { isNonZeroAddress } from "../helpers/address" const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { const { getNamedAccounts, deployments } = hre + // eslint-disable-next-line @typescript-eslint/unbound-method const { log } = deployments const { deployer } = await getNamedAccounts() diff --git a/core/deploy/21_transfer_ownership_acre.ts b/core/deploy/21_transfer_ownership_acre.ts index c62708641..709a219b0 100644 --- a/core/deploy/21_transfer_ownership_acre.ts +++ b/core/deploy/21_transfer_ownership_acre.ts @@ -4,6 +4,7 @@ import type { DeployFunction } from "hardhat-deploy/types" const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { const { getNamedAccounts, deployments } = hre const { deployer, governance } = await getNamedAccounts() + // eslint-disable-next-line @typescript-eslint/unbound-method const { log } = deployments log(`transferring ownership of Acre contract to ${governance}`) @@ -20,4 +21,5 @@ export default func func.tags = ["TransferOwnershipAcre"] // TODO: Enable once Acre extends Ownable +// eslint-disable-next-line @typescript-eslint/require-await func.skip = async () => true diff --git a/core/deploy/22_transfer_ownership_acre_router.ts b/core/deploy/22_transfer_ownership_acre_router.ts index 686d378c4..2c7322898 100644 --- a/core/deploy/22_transfer_ownership_acre_router.ts +++ b/core/deploy/22_transfer_ownership_acre_router.ts @@ -4,6 +4,7 @@ import type { DeployFunction } from "hardhat-deploy/types" const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { const { getNamedAccounts, deployments } = hre const { deployer, governance } = await getNamedAccounts() + // eslint-disable-next-line @typescript-eslint/unbound-method const { log } = deployments log(`transferring ownership of Dispatcher contract to ${governance}`) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index b4f176830..a292dffa4 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -21,8 +21,8 @@ async function fixture() { const [staker1, staker2] = await getUnnamedSigner() const amountToMint = to1e18(100000) - tbtc.mint(staker1, amountToMint) - tbtc.mint(staker2, amountToMint) + await tbtc.mint(staker1, amountToMint) + await tbtc.mint(staker2, amountToMint) return { acre, tbtc, staker1, staker2 } } @@ -38,7 +38,7 @@ describe("Acre", () => { }) describe("stake", () => { - const referral = ethers.encodeBytes32String("referral") + const referral: string = ethers.encodeBytes32String("referral") let snapshot: SnapshotRestorer context("when staking as first staker", () => { @@ -75,8 +75,8 @@ describe("Acre", () => { .stake(amountToStake, receiver.address, referral) }) - it("should emit Deposit event", () => { - expect(tx).to.emit(acre, "Deposit").withArgs( + it("should emit Deposit event", async () => { + await expect(tx).to.emit(acre, "Deposit").withArgs( // Caller. tbtcHolder.address, // Receiver. @@ -88,8 +88,8 @@ describe("Acre", () => { ) }) - it("should emit StakeReferral event", () => { - expect(tx) + it("should emit StakeReferral event", async () => { + await expect(tx) .to.emit(acre, "StakeReferral") .withArgs(referral, amountToStake) }) @@ -368,7 +368,7 @@ describe("Acre", () => { sharesBefore = await acre.balanceOf(staker1.address) availableToRedeemBefore = await acre.previewRedeem(sharesBefore) - tbtc.mint(staker1.address, newAmountToStake) + await tbtc.mint(staker1.address, newAmountToStake) await tbtc .connect(staker1) From f04bca6732d47935ee15aa68060d1192276e68ce Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Thu, 28 Dec 2023 22:13:32 +0100 Subject: [PATCH 062/170] Run format after build in CI workflow Since the eslint rules we enabled for typescript with the latest eslint-config upgrade check typings, we need to ensure that `typechain/` directory is generated before we run eslint. For this reason we first run build and later format. --- .github/workflows/core.yaml | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/.github/workflows/core.yaml b/.github/workflows/core.yaml index a0501e05b..6b431ba4e 100644 --- a/.github/workflows/core.yaml +++ b/.github/workflows/core.yaml @@ -13,7 +13,7 @@ defaults: working-directory: ./core jobs: - core-format: + core-build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -30,10 +30,20 @@ jobs: - name: Install Dependencies run: pnpm install --prefer-offline --frozen-lockfile - - name: Format - run: pnpm run format + - name: Build + run: pnpm run build - core-build: + - name: Upload Build Artifacts + uses: actions/upload-artifact@v3 + with: + name: core-build + path: | + core/build/ + core/typechain/ + if-no-files-found: error + + core-format: + needs: [core-build] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -50,17 +60,14 @@ jobs: - name: Install Dependencies run: pnpm install --prefer-offline --frozen-lockfile - - name: Build - run: pnpm run build - - - name: Upload Build Artifacts - uses: actions/upload-artifact@v3 + - name: Download Build Artifacts + uses: actions/download-artifact@v3 with: name: core-build - path: | - core/build/ - core/typechain/ - if-no-files-found: error + path: core/ + + - name: Format + run: pnpm run format core-slither: needs: [core-build] From 1b1b9ab6324d7ea371cd028cd2333af5360ddf5a Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 29 Dec 2023 09:07:32 +0100 Subject: [PATCH 063/170] Improvements for forms --- .../components/Modals/Staking/StakeForm.tsx | 26 ++++---------- dapp/src/constants/staking.ts | 7 ---- dapp/src/utils/forms.ts | 35 +++++++++++++++++++ dapp/src/utils/index.ts | 1 + 4 files changed, 43 insertions(+), 26 deletions(-) create mode 100644 dapp/src/utils/forms.ts diff --git a/dapp/src/components/Modals/Staking/StakeForm.tsx b/dapp/src/components/Modals/Staking/StakeForm.tsx index 3af0c6712..c201dbc60 100644 --- a/dapp/src/components/Modals/Staking/StakeForm.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm.tsx @@ -3,33 +3,21 @@ import { FormikErrors, withFormik } from "formik" import { ModalStep } from "../../../contexts" import FormBase, { FormBaseProps, FormValues } from "../../shared/FormBase" import { useTransactionContext, useWalletContext } from "../../../hooks" -import { formatSatoshiAmount } from "../../../utils" -import { BITCOIN_MIN_AMOUNT, ERRORS } from "../../../constants" +import { getErrorsObj, validateTokenAmount } from "../../../utils" const StakeFormik = withFormik< { onSubmitForm: (values: FormValues) => void } & FormBaseProps, FormValues >({ - validate: ({ amount: value }, { tokenBalance }) => { + mapPropsToValues: () => ({ + amount: "", + }), + validate: async ({ amount }, { tokenBalance }) => { const errors: FormikErrors = {} - if (!value) errors.amount = ERRORS.REQUIRED - else { - const valueInBI = BigInt(value) - const maxValueInBI = BigInt(tokenBalance) - const minValueInBI = BigInt(BITCOIN_MIN_AMOUNT) + errors.amount = validateTokenAmount(amount, tokenBalance) - const isMaximumValueExceeded = valueInBI > maxValueInBI - const isMinimumValueFulfilled = valueInBI > minValueInBI - - if (isMaximumValueExceeded) errors.amount = ERRORS.EXCEEDED_VALUE - else if (!isMinimumValueFulfilled) - errors.amount = ERRORS.INSUFFICIENT_VALUE( - formatSatoshiAmount(BITCOIN_MIN_AMOUNT), - ) - } - - return errors + return getErrorsObj(errors) }, handleSubmit: (values, { props }) => { props.onSubmitForm(values) diff --git a/dapp/src/constants/staking.ts b/dapp/src/constants/staking.ts index 19cd34be0..421c57bb5 100644 --- a/dapp/src/constants/staking.ts +++ b/dapp/src/constants/staking.ts @@ -1,8 +1 @@ export const BITCOIN_MIN_AMOUNT = "1000000" // 0.01 BTC - -export const ERRORS = { - REQUIRED: "Required.", - EXCEEDED_VALUE: "The amount exceeds your current balance.", - INSUFFICIENT_VALUE: (minValue: string) => - `The minimum amount must be at least ${minValue} BTC.`, -} diff --git a/dapp/src/utils/forms.ts b/dapp/src/utils/forms.ts new file mode 100644 index 000000000..70249a13d --- /dev/null +++ b/dapp/src/utils/forms.ts @@ -0,0 +1,35 @@ +import { BITCOIN_MIN_AMOUNT } from "../constants" +import { formatSatoshiAmount } from "./numbers" + +const ERRORS = { + REQUIRED: "Required.", + EXCEEDED_VALUE: "The amount exceeds your current balance.", + INSUFFICIENT_VALUE: (minValue: string) => + `The minimum amount must be at least ${minValue} BTC.`, +} + +export function getErrorsObj(errors: { [key in keyof T]: string }) { + return (Object.keys(errors) as Array).every((name) => !errors[name]) + ? {} + : errors +} + +export function validateTokenAmount( + value: string, + tokenBalance: string, +): string | undefined { + if (!value) return ERRORS.REQUIRED + + const valueInBI = BigInt(value) + const maxValueInBI = BigInt(tokenBalance) + const minValueInBI = BigInt(BITCOIN_MIN_AMOUNT) + + const isMaximumValueExceeded = valueInBI > maxValueInBI + const isMinimumValueFulfilled = valueInBI >= minValueInBI + + if (isMaximumValueExceeded) return ERRORS.EXCEEDED_VALUE + if (!isMinimumValueFulfilled) + return ERRORS.INSUFFICIENT_VALUE(formatSatoshiAmount(BITCOIN_MIN_AMOUNT)) + + return undefined +} diff --git a/dapp/src/utils/index.ts b/dapp/src/utils/index.ts index 613e0f071..563f2e6d1 100644 --- a/dapp/src/utils/index.ts +++ b/dapp/src/utils/index.ts @@ -1,2 +1,3 @@ export * from "./numbers" export * from "./address" +export * from "./forms" From 4b845b96507701f4e3f3d0b32dd12e1d9e99c36b Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 29 Dec 2023 09:59:25 +0100 Subject: [PATCH 064/170] Define custom data from the form level --- .../components/Modals/Staking/StakeForm.tsx | 9 ++++-- .../shared/FormBase/TransactionDetails.tsx | 30 ++++--------------- dapp/src/components/shared/FormBase/index.tsx | 20 ++++++++----- dapp/src/types/index.ts | 1 - dapp/src/types/staking.ts | 1 - 5 files changed, 26 insertions(+), 35 deletions(-) delete mode 100644 dapp/src/types/staking.ts diff --git a/dapp/src/components/Modals/Staking/StakeForm.tsx b/dapp/src/components/Modals/Staking/StakeForm.tsx index c201dbc60..9ab138f24 100644 --- a/dapp/src/components/Modals/Staking/StakeForm.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm.tsx @@ -5,6 +5,12 @@ import FormBase, { FormBaseProps, FormValues } from "../../shared/FormBase" import { useTransactionContext, useWalletContext } from "../../../hooks" import { getErrorsObj, validateTokenAmount } from "../../../utils" +const CUSTOM_DATA = { + buttonText: "Stake", + btcAmountText: "Amount to be staked", + estimatedAmountText: "Approximately staked tokens", +} + const StakeFormik = withFormik< { onSubmitForm: (values: FormValues) => void } & FormBaseProps, FormValues @@ -38,8 +44,7 @@ function StakeForm({ goNext }: ModalStep) { return ( diff --git a/dapp/src/components/shared/FormBase/TransactionDetails.tsx b/dapp/src/components/shared/FormBase/TransactionDetails.tsx index bd8270919..4e9857d1e 100644 --- a/dapp/src/components/shared/FormBase/TransactionDetails.tsx +++ b/dapp/src/components/shared/FormBase/TransactionDetails.tsx @@ -3,27 +3,7 @@ import { Box, Flex, VStack } from "@chakra-ui/react" import { useField } from "formik" import { CurrencyBalanceWithConversion } from "../CurrencyBalanceWithConversion" import { TextMd } from "../Typography" -import { TransactionType } from "../../../types" -const DETAILS: Record< - TransactionType, - { - btcAmountText: string - protocolFeeText: string - estimatedAmountText: string - } -> = { - stake: { - btcAmountText: "Amount to be staked", - protocolFeeText: "Protocol fee (0.01%)", - estimatedAmountText: "Approximately staked tokens", - }, - unstake: { - btcAmountText: "Amount to be unstaked from the pool", - protocolFeeText: "Protocol fee (0.01%)", - estimatedAmountText: "Approximately unstaked tokens", - }, -} // TODO: Use data from the SDK function getTransactionDetails(value: string): | { @@ -83,14 +63,15 @@ function TransactionDetailsItem({ function TransactionDetails({ fieldName, - type, + btcAmountText, + estimatedAmountText, }: { fieldName: string - type: TransactionType + btcAmountText: string + estimatedAmountText: string }) { const [, { value }] = useField(fieldName) - const { btcAmountText, protocolFeeText, estimatedAmountText } = DETAILS[type] const details = getTransactionDetails(value) return ( @@ -101,7 +82,8 @@ function TransactionDetails({ usdAmount="45.725,91" /> diff --git a/dapp/src/components/shared/FormBase/index.tsx b/dapp/src/components/shared/FormBase/index.tsx index b7cb33740..371278b2a 100644 --- a/dapp/src/components/shared/FormBase/index.tsx +++ b/dapp/src/components/shared/FormBase/index.tsx @@ -2,7 +2,7 @@ import React from "react" import { Button } from "@chakra-ui/react" import { FormikProps } from "formik" import { Form, FormTokenBalanceInput } from "../Form" -import { CurrencyType, TransactionType } from "../../../types" +import { CurrencyType } from "../../../types" import TransactionDetails from "./TransactionDetails" export type FormValues = { @@ -10,8 +10,11 @@ export type FormValues = { } export type FormBaseProps = { - transactionType: TransactionType - btnText: string + customData: { + buttonText: string + btcAmountText: string + estimatedAmountText: string + } tokenBalance: string tokenBalanceInputPlaceholder?: string currencyType?: CurrencyType @@ -20,8 +23,7 @@ export type FormBaseProps = { } function FormBase({ - transactionType, - btnText, + customData, tokenBalance, tokenBalanceInputPlaceholder = "BTC", currencyType = "bitcoin", @@ -37,10 +39,14 @@ function FormBase({ placeholder={tokenBalanceInputPlaceholder} currencyType={currencyType} /> - + {children} ) diff --git a/dapp/src/types/index.ts b/dapp/src/types/index.ts index 32b259c7f..1e77e81e7 100644 --- a/dapp/src/types/index.ts +++ b/dapp/src/types/index.ts @@ -1,3 +1,2 @@ export * from "./ledger-live-app" export * from "./currency" -export * from "./staking" diff --git a/dapp/src/types/staking.ts b/dapp/src/types/staking.ts deleted file mode 100644 index 69e565c51..000000000 --- a/dapp/src/types/staking.ts +++ /dev/null @@ -1 +0,0 @@ -export type TransactionType = "stake" | "unstake" From fcac79279e6557968ed0794448675e3c34eb4321 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 29 Dec 2023 11:00:58 +0100 Subject: [PATCH 065/170] Resetting approval for the old dispatcher When a new dispatcher is set, the tBTC allowance for the old one should be set to zero. Added tests. --- core/contracts/Acre.sol | 5 ++++ core/test/Acre.test.ts | 64 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 5eb1e45f9..720f3e65c 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -62,6 +62,11 @@ contract Acre is ERC4626, Ownable { if (address(_dispatcher) == address(0)) { revert ZeroAddress(); } + + if (address(dispatcher) != address(0)) { + IERC20(asset()).approve(address(dispatcher), 0); + } + dispatcher = _dispatcher; bool success = IERC20(asset()).approve( diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 4a5960e3e..497ac08ed 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -3,19 +3,20 @@ import { loadFixture, } from "@nomicfoundation/hardhat-toolbox/network-helpers" import { expect } from "chai" -import { ContractTransactionResponse, ZeroAddress } from "ethers" +import { ContractTransactionResponse, ZeroAddress, MaxUint256 } from "ethers" import type { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers" import type { SnapshotRestorer } from "@nomicfoundation/hardhat-toolbox/network-helpers" import { deployment } from "./helpers/context" -import { getUnnamedSigner } from "./helpers/signer" +import { getUnnamedSigner, getNamedSigner } from "./helpers/signer" import { to1e18 } from "./utils" -import type { Acre, TestERC20 } from "../typechain" +import type { Acre, TestERC20, Dispatcher } from "../typechain" async function fixture() { - const { tbtc, acre } = await deployment() + const { tbtc, acre, dispatcher } = await deployment() + const { governance } = await getNamedSigner() const [staker1, staker2] = await getUnnamedSigner() @@ -23,7 +24,7 @@ async function fixture() { tbtc.mint(staker1, amountToMint) tbtc.mint(staker2, amountToMint) - return { acre, tbtc, staker1, staker2 } + return { acre, tbtc, staker1, staker2, dispatcher, governance } } describe("Acre", () => { @@ -31,9 +32,12 @@ describe("Acre", () => { let tbtc: TestERC20 let staker1: HardhatEthersSigner let staker2: HardhatEthersSigner + let dispatcher: Dispatcher + let governance: HardhatEthersSigner before(async () => { - ;({ acre, tbtc, staker1, staker2 } = await loadFixture(fixture)) + ;({ acre, tbtc, staker1, staker2, dispatcher, governance } = + await loadFixture(fixture)) }) describe("stake", () => { @@ -403,4 +407,52 @@ describe("Acre", () => { }) }) }) + + describe("updateDispatcher", () => { + context("when caller is not an owner", () => { + it("should revert", async () => { + await expect( + acre.connect(staker1).updateDispatcher(ZeroAddress), + ).to.be.revertedWithCustomError(acre, "OwnableUnauthorizedAccount") + }) + }) + + context("when caller is an owner", () => { + let newDispatcher: string + let acreAddress: string + let dispatcherAddress: string + + before(async () => { + dispatcherAddress = await dispatcher.getAddress() + newDispatcher = await ethers.Wallet.createRandom().getAddress() + acreAddress = await acre.getAddress() + }) + + it("should approve max amount for the dispatcher", async () => { + const allowance = await tbtc.allowance(acreAddress, dispatcherAddress) + expect(allowance).to.be.equal(MaxUint256) + }) + + it("should be able to update the dispatcher", async () => { + await acre.connect(governance).updateDispatcher(newDispatcher) + expect(await acre.dispatcher()).to.be.equal(newDispatcher) + }) + + it("should reset approval amount for the old dispatcher", async () => { + const allowance = await tbtc.allowance(acreAddress, dispatcherAddress) + expect(allowance).to.be.equal(0) + }) + + it("should approve max amount for the new dispatcher", async () => { + const allowance = await tbtc.allowance(acreAddress, newDispatcher) + expect(allowance).to.be.equal(MaxUint256) + }) + + it("should not be able to update the dispatcher to the zero address", async () => { + await expect( + acre.connect(governance).updateDispatcher(ZeroAddress), + ).to.be.revertedWithCustomError(acre, "ZeroAddress") + }) + }) + }) }) From 5313aa61455891ef304249b82ee95ced02d582a4 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 29 Dec 2023 11:19:57 +0100 Subject: [PATCH 066/170] Skipping deployment of TestERC4626 Vault for Mainnet --- core/deploy/00_resolve_testing_erc4626.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/deploy/00_resolve_testing_erc4626.ts b/core/deploy/00_resolve_testing_erc4626.ts index 3ceccaa15..ecf80f52e 100644 --- a/core/deploy/00_resolve_testing_erc4626.ts +++ b/core/deploy/00_resolve_testing_erc4626.ts @@ -25,3 +25,7 @@ export default func func.tags = ["TestERC4626"] func.dependencies = ["TBTC"] + +if (hre.network.name === "mainnet") { + func.skip = async () => true +} From e7f48cbe76858f731166aacf0f505f714b467a84 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 29 Dec 2023 11:20:29 +0100 Subject: [PATCH 067/170] Renames and smaller refactorings --- core/contracts/Dispatcher.sol | 15 +++++---------- core/contracts/Router.sol | 6 +++--- core/deploy/02_deploy_dispatcher.ts | 6 +++--- ...dispatcher.ts => 11_acre_update_dispatcher.ts} | 4 ++-- ...iner.ts => 12_dispatcher_update_maintainer.ts} | 2 +- core/hardhat.config.ts | 8 ++++---- core/test/integration/AssetFlows.test.ts | 10 +++++----- 7 files changed, 23 insertions(+), 28 deletions(-) rename core/deploy/{11_update_dispatcher.ts => 11_acre_update_dispatcher.ts} (86%) rename core/deploy/{12_update_maintainer.ts => 12_dispatcher_update_maintainer.ts} (92%) diff --git a/core/contracts/Dispatcher.sol b/core/contracts/Dispatcher.sol index c85187c43..1b29bdef3 100644 --- a/core/contracts/Dispatcher.sol +++ b/core/contracts/Dispatcher.sol @@ -92,12 +92,14 @@ contract Dispatcher is Router, Ownable { emit VaultDeauthorized(vault); } + /// TODO: make this function internal once the allocation distribution is + /// implemented /// @notice Routes tBTC from Acre to a vault. Can be called by the maintainer /// only. /// @param vault Address of the vault to route the assets to. /// @param amount Amount of tBTC to deposit. /// @param minSharesOut Minimum amount of shares to receive by Acre. - function allocate( + function depositToVault( address vault, uint256 amount, uint256 minSharesOut @@ -108,15 +110,8 @@ contract Dispatcher is Router, Ownable { emit DepositAllocated(vault, amount, minSharesOut); // slither-disable-next-line arbitrary-send-erc20 - IERC20(IERC4626(vault).asset()).safeTransferFrom( - address(acre), - address(this), - amount - ); - IERC20(IERC4626(vault).asset()).safeIncreaseAllowance( - address(vault), - amount - ); + tBTC.safeTransferFrom(address(acre), address(this), amount); + tBTC.safeIncreaseAllowance(address(vault), amount); deposit(IERC4626(vault), address(acre), amount, minSharesOut); } diff --git a/core/contracts/Router.sol b/core/contracts/Router.sol index 1131fe7e5..b1359b1a4 100644 --- a/core/contracts/Router.sol +++ b/core/contracts/Router.sol @@ -18,16 +18,16 @@ abstract contract Router { /// @notice Routes funds from stBTC (Acre) to a vault. The amount of tBTC to /// Shares of deposited tBTC are minted to the stBTC contract. /// @param vault Address of the vault to route the funds to. - /// @param to Address of the receiver of the shares. + /// @param receiver Address of the receiver of the shares. /// @param amount Amount of tBTC to deposit. /// @param minSharesOut Minimum amount of shares to receive. function deposit( IERC4626 vault, - address to, + address receiver, uint256 amount, uint256 minSharesOut ) internal returns (uint256 sharesOut) { - if ((sharesOut = vault.deposit(amount, to)) < minSharesOut) { + if ((sharesOut = vault.deposit(amount, receiver)) < minSharesOut) { revert MinSharesError(); } } diff --git a/core/deploy/02_deploy_dispatcher.ts b/core/deploy/02_deploy_dispatcher.ts index d2441ec52..3c7a84e5c 100644 --- a/core/deploy/02_deploy_dispatcher.ts +++ b/core/deploy/02_deploy_dispatcher.ts @@ -5,12 +5,12 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { const { getNamedAccounts, deployments } = hre const { deployer } = await getNamedAccounts() - const tTBC = await deployments.get("TBTC") - const stBTC = await deployments.get("Acre") + const tbtc = await deployments.get("TBTC") + const acre = await deployments.get("Acre") await deployments.deploy("Dispatcher", { from: deployer, - args: [stBTC.address, tTBC.address], + args: [acre.address, tbtc.address], log: true, waitConfirmations: 1, }) diff --git a/core/deploy/11_update_dispatcher.ts b/core/deploy/11_acre_update_dispatcher.ts similarity index 86% rename from core/deploy/11_update_dispatcher.ts rename to core/deploy/11_acre_update_dispatcher.ts index 4ce40956f..2f645027c 100644 --- a/core/deploy/11_update_dispatcher.ts +++ b/core/deploy/11_acre_update_dispatcher.ts @@ -17,5 +17,5 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { export default func -func.tags = ["UpdateDispatcher"] -func.dependencies = ["Dispatcher"] +func.tags = ["AcreUpdateDispatcher"] +func.dependencies = ["Acre", "Dispatcher"] diff --git a/core/deploy/12_update_maintainer.ts b/core/deploy/12_dispatcher_update_maintainer.ts similarity index 92% rename from core/deploy/12_update_maintainer.ts rename to core/deploy/12_dispatcher_update_maintainer.ts index ae13da6d7..8f616fac0 100644 --- a/core/deploy/12_update_maintainer.ts +++ b/core/deploy/12_dispatcher_update_maintainer.ts @@ -15,5 +15,5 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { export default func -func.tags = ["UpdateMaintainer"] +func.tags = ["DispatcherUpdateMaintainer"] func.dependencies = ["Dispatcher"] diff --git a/core/hardhat.config.ts b/core/hardhat.config.ts index 478e07b49..3ca6f77bf 100644 --- a/core/hardhat.config.ts +++ b/core/hardhat.config.ts @@ -67,13 +67,13 @@ const config: HardhatUserConfig = { }, governance: { default: 2, - sepolia: 0, - mainnet: "", + sepolia: 0, // TODO: updated to the actual address once available + mainnet: "", // TODO: updated to the actual address once available }, maintainer: { default: 3, - sepolia: 0, - mainnet: "", + sepolia: 0, // TODO: updated to the actual address once available + mainnet: "", // TODO: updated to the actual address once available }, }, diff --git a/core/test/integration/AssetFlows.test.ts b/core/test/integration/AssetFlows.test.ts index 9b87195d3..74bfce3f5 100644 --- a/core/test/integration/AssetFlows.test.ts +++ b/core/test/integration/AssetFlows.test.ts @@ -49,7 +49,7 @@ describe("Integration Tests - Asset Flows", () => { await snapshot.restore() }) - describe("allocate", () => { + describe("depositToVault", () => { const assetsToAllocate = to1e18(100) const minSharesOut = to1e18(100) @@ -58,7 +58,7 @@ describe("Integration Tests - Asset Flows", () => { await expect( dispatcher .connect(thirdParty) - .allocate(vault.getAddress(), assetsToAllocate, minSharesOut), + .depositToVault(vault.getAddress(), assetsToAllocate, minSharesOut), ) .to.be.revertedWithCustomError(dispatcher, "CallerUnauthorized") .withArgs("Maintainer only") @@ -72,7 +72,7 @@ describe("Integration Tests - Asset Flows", () => { await expect( dispatcher .connect(maintainer) - .allocate(randomAddress, assetsToAllocate, minSharesOut), + .depositToVault(randomAddress, assetsToAllocate, minSharesOut), ).to.be.revertedWithCustomError(dispatcher, "VaultUnauthorized") }) }) @@ -88,7 +88,7 @@ describe("Integration Tests - Asset Flows", () => { before(async () => { tx = await dispatcher .connect(maintainer) - .allocate(vaultAddress, assetsToAllocate, minSharesOut) + .depositToVault(vaultAddress, assetsToAllocate, minSharesOut) }) it("should be able to deposit to an authorized Vault", async () => { @@ -117,7 +117,7 @@ describe("Integration Tests - Asset Flows", () => { await expect( dispatcher .connect(maintainer) - .allocate(vaultAddress, assetsToAllocate, minShares), + .depositToVault(vaultAddress, assetsToAllocate, minShares), ).to.be.revertedWithCustomError(dispatcher, "MinSharesError") }) }) From 10b080609ee11b8be65499765b3d78a3412cda40 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 29 Dec 2023 11:33:04 +0100 Subject: [PATCH 068/170] Slithering Making Slither happy to avoid reentrancy warning. --- core/contracts/Acre.sol | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 720f3e65c..f664a8b40 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -63,17 +63,23 @@ contract Acre is ERC4626, Ownable { revert ZeroAddress(); } - if (address(dispatcher) != address(0)) { - IERC20(asset()).approve(address(dispatcher), 0); - } - + address oldDispatcher = address(dispatcher); dispatcher = _dispatcher; - bool success = IERC20(asset()).approve( + if (oldDispatcher != address(0)) { + // Setting allowance to zero for the old dispatcher + bool approvedToZero = IERC20(asset()).approve(oldDispatcher, 0); + if (!approvedToZero) { + revert ApproveFailed(); + } + } + + // Setting allowance to max for the new dispatcher + bool approvedToMax = IERC20(asset()).approve( address(dispatcher), type(uint256).max ); - if (!success) { + if (!approvedToMax) { revert ApproveFailed(); } } From 771553b1a7002f44de02c4d1c6a07858a61fc1ed Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Fri, 29 Dec 2023 09:22:49 +0100 Subject: [PATCH 069/170] Fix slither error --- core/contracts/Acre.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 2d968e4a3..a7109a997 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -146,6 +146,7 @@ contract Acre is ERC4626, Ownable { function maxMint(address receiver) public view override returns (uint256) { uint256 _maxDeposit = maxDeposit(receiver); + // slither-disable-next-line incorrect-equality return _maxDeposit == type(uint256).max ? type(uint256).max From cc05de6bca66acc806208fbef04340af606a8241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Czajkowski?= <57687279+r-czajkowski@users.noreply.github.com> Date: Fri, 29 Dec 2023 12:14:02 +0100 Subject: [PATCH 070/170] Fix typo `parametrs` -> `parameters` Co-authored-by: Jakub Nowakowski --- core/contracts/Acre.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index a7109a997..83e10b835 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -153,7 +153,7 @@ contract Acre is ERC4626, Ownable { : convertToShares(_maxDeposit); } - /// @return Returns deposit parametrs + /// @return Returns deposit parameters. function depositParameters() public view returns (uint256, uint256) { return (minimumDepositAmount, maximumTotalAssets); } From 68f3d9206044fab0b4e01c69dbdd43a9493153f1 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 29 Dec 2023 12:18:01 +0100 Subject: [PATCH 071/170] Add a staking steps overview --- .../components/Modals/Staking/Overview.tsx | 57 +++++++++++++++++-- dapp/src/components/Modals/Staking/index.tsx | 4 +- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/dapp/src/components/Modals/Staking/Overview.tsx b/dapp/src/components/Modals/Staking/Overview.tsx index 2ad8a1e94..dd95a152f 100644 --- a/dapp/src/components/Modals/Staking/Overview.tsx +++ b/dapp/src/components/Modals/Staking/Overview.tsx @@ -1,17 +1,62 @@ import React from "react" -import { Button, ModalBody, ModalFooter } from "@chakra-ui/react" +import { + Button, + ModalBody, + ModalFooter, + ModalHeader, + StepNumber, +} from "@chakra-ui/react" import { ModalStep } from "../../../contexts" -import { TextMd } from "../../shared/Typography" +import StepperBase from "../../shared/StepperBase" +import { TextLg, TextMd } from "../../shared/Typography" + +function Title({ children }: { children: React.ReactNode }) { + return {children} +} + +function Description({ children }: { children: React.ReactNode }) { + return {children} +} + +const STEPS = [ + { + id: "sign-message", + title: Sign message, + description: ( + + You will sign a gas-free Ethereum message to indicate the address where + you'd like to get your stBTC liquid staking token. + + ), + }, + { + id: "deposit-btc", + title: Deposit BTC, + description: ( + + You will make a Bitcoin transaction to deposit and stake your BTC. + + ), + }, +] export default function Overview({ goNext }: ModalStep) { return ( <> - - Staking overview + Staking steps overview + + } + steps={STEPS} + /> - diff --git a/dapp/src/components/Modals/Staking/index.tsx b/dapp/src/components/Modals/Staking/index.tsx index d5b117df3..140f5d7ef 100644 --- a/dapp/src/components/Modals/Staking/index.tsx +++ b/dapp/src/components/Modals/Staking/index.tsx @@ -9,9 +9,9 @@ function StakingSteps() { switch (activeStep) { case 1: - return - case 2: return + case 2: + return default: return null } From ea667eddedbfd78374cf911e44f11e9517049045 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 29 Dec 2023 12:26:36 +0100 Subject: [PATCH 072/170] Adding TODO to revoke share tokens approval from the old dispatcher to a new one --- core/contracts/Acre.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index f664a8b40..d69c54601 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -66,6 +66,10 @@ contract Acre is ERC4626, Ownable { address oldDispatcher = address(dispatcher); dispatcher = _dispatcher; + // TODO: Once withdrawal/rebalancing is implemented, we need to revoke the + // approval of the vaults share tokens from the old dispatcher and approve + // a new dispatcher to manage the share tokens. + if (oldDispatcher != address(0)) { // Setting allowance to zero for the old dispatcher bool approvedToZero = IERC20(asset()).approve(oldDispatcher, 0); From d2fcf4a4ca5220585465e21187f8d3cac10084bb Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Fri, 29 Dec 2023 12:28:50 +0100 Subject: [PATCH 073/170] Add new test case for staking Add a case where total tBTC amount after staking would be equal the max amount, to confirm the transaction will succeed. --- core/test/Acre.test.ts | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 6e39f88be..776dea47a 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -489,6 +489,41 @@ describe("Acre", () => { }) }, ) + + context( + "when total tBTC amount after staking would be equal to the max amount", + () => { + let amountToStake: bigint + let tx: ContractTransactionResponse + + before(async () => { + amountToStake = await acre.maxDeposit(staker1.address) + + await tbtc + .connect(staker1) + .approve(await acre.getAddress(), amountToStake) + + tx = await acre.stake(amountToStake, staker1, referral) + }) + + it("should stake tokens correctly", async () => { + await expect(tx).to.emit(acre, "Deposit") + }) + + it("the max deposit amount should be equal 0", async () => { + expect(await acre.maxDeposit(staker1)).to.eq(0) + }) + + it("should not be able to stake more tokens", async () => { + await expect(acre.stake(amountToStake, staker1, referral)) + .to.be.revertedWithCustomError( + acre, + "ERC4626ExceededMaxDeposit", + ) + .withArgs(staker1.address, amountToStake, 0) + }) + }, + ) }) }) }) From 56c21fad60df7c26ccf353661c48ebc590760653 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Fri, 29 Dec 2023 14:18:44 +0100 Subject: [PATCH 074/170] Add missing snapshot restorer to `deposit` tests According to the existing pattern. --- core/test/Acre.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 776dea47a..4a5b97620 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -924,11 +924,17 @@ describe("Acre", () => { describe("deposit", () => { let amountToDeposit: bigint let minimumDepositAmount: bigint + let snapshot: SnapshotRestorer beforeEach(async () => { + snapshot = await takeSnapshot() minimumDepositAmount = await acre.minimumDepositAmount() }) + afterEach(async () => { + await snapshot.restore() + }) + context("when the deposit amount is less than minimum", () => { beforeEach(() => { amountToDeposit = minimumDepositAmount - 1n From 12b9d5ff4b0b33bf28e397069c0396e41ff28ae2 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 29 Dec 2023 14:58:26 +0100 Subject: [PATCH 075/170] Simplifying tBTC token approvals by using OZ forceApprove --- core/contracts/Acre.sol | 13 ++----------- core/contracts/Dispatcher.sol | 2 +- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index d69c54601..ea4840ee6 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -72,19 +72,10 @@ contract Acre is ERC4626, Ownable { if (oldDispatcher != address(0)) { // Setting allowance to zero for the old dispatcher - bool approvedToZero = IERC20(asset()).approve(oldDispatcher, 0); - if (!approvedToZero) { - revert ApproveFailed(); - } + IERC20(asset()).forceApprove(oldDispatcher, 0); } // Setting allowance to max for the new dispatcher - bool approvedToMax = IERC20(asset()).approve( - address(dispatcher), - type(uint256).max - ); - if (!approvedToMax) { - revert ApproveFailed(); - } + IERC20(asset()).forceApprove(address(dispatcher), type(uint256).max); } } diff --git a/core/contracts/Dispatcher.sol b/core/contracts/Dispatcher.sol index 1b29bdef3..49f180e80 100644 --- a/core/contracts/Dispatcher.sol +++ b/core/contracts/Dispatcher.sol @@ -111,7 +111,7 @@ contract Dispatcher is Router, Ownable { // slither-disable-next-line arbitrary-send-erc20 tBTC.safeTransferFrom(address(acre), address(this), amount); - tBTC.safeIncreaseAllowance(address(vault), amount); + tBTC.forceApprove(address(vault), amount); deposit(IERC4626(vault), address(acre), amount, minSharesOut); } From e1e058b189181747e3751060a02971bc761d591b Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 29 Dec 2023 14:59:22 +0100 Subject: [PATCH 076/170] Update @ledgerhq/* to the latest version --- dapp/package.json | 4 +- pnpm-lock.yaml | 118 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 85 insertions(+), 37 deletions(-) diff --git a/dapp/package.json b/dapp/package.json index 383bc7456..2d160d0a4 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -18,8 +18,8 @@ "@chakra-ui/react": "^2.8.2", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@ledgerhq/wallet-api-client": "^1.2.1", - "@ledgerhq/wallet-api-client-react": "^1.1.2", + "@ledgerhq/wallet-api-client": "^1.5.0", + "@ledgerhq/wallet-api-client-react": "^1.3.0", "framer-motion": "^10.16.5", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5c71a8afa..1c334a15e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -121,11 +121,11 @@ importers: specifier: ^11.11.0 version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.38)(react@18.2.0) '@ledgerhq/wallet-api-client': - specifier: ^1.2.1 - version: 1.2.1 + specifier: ^1.5.0 + version: 1.5.0 '@ledgerhq/wallet-api-client-react': - specifier: ^1.1.2 - version: 1.1.2(react@18.2.0) + specifier: ^1.3.0 + version: 1.3.0(react@18.2.0) framer-motion: specifier: ^10.16.5 version: 10.16.5(react-dom@18.2.0)(react@18.2.0) @@ -345,6 +345,13 @@ packages: '@babel/highlight': 7.23.4 chalk: 2.4.2 + /@babel/code-frame@7.23.5: + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.23.4 + chalk: 2.4.2 + /@babel/compat-data@7.23.3: resolution: {integrity: sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==} engines: {node: '>=6.9.0'} @@ -393,6 +400,15 @@ packages: '@jridgewell/trace-mapping': 0.3.20 jsesc: 2.5.2 + /@babel/generator@7.23.6: + resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.20 + jsesc: 2.5.2 + /@babel/helper-annotate-as-pure@7.22.5: resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} engines: {node: '>=6.9.0'} @@ -594,6 +610,13 @@ packages: dependencies: '@babel/types': 7.23.4 + /@babel/parser@7.23.6: + resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.6 + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.23.3): resolution: {integrity: sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==} engines: {node: '>=6.9.0'} @@ -1613,6 +1636,23 @@ packages: transitivePeerDependencies: - supports-color + /@babel/traverse@7.23.6: + resolution: {integrity: sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.6 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + debug: 4.3.4(supports-color@8.1.1) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + /@babel/types@7.23.4: resolution: {integrity: sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==} engines: {node: '>=6.9.0'} @@ -1621,6 +1661,14 @@ packages: '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 + /@babel/types@7.23.6: + resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.23.4 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + /@builder.io/partytown@0.7.6: resolution: {integrity: sha512-snXIGNiZpqjno3XYQN2lbBB+05hsQR/LSttbtIW1c0gmZ7Kh/DIo0YrxlDxCDulAMFPFM8J+4voLwvYepSj3sw==} hasBin: true @@ -3829,53 +3877,53 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /@ledgerhq/devices@8.0.8: - resolution: {integrity: sha512-0j7E8DY2jeSSATc8IJk+tXDZ9u+Z7tXxB8I4TzXrfV/8A5exMh/K1IwX6Jt1zlw1wre4CT9MV4mzUs3M/TE7lg==} + /@ledgerhq/devices@8.2.0: + resolution: {integrity: sha512-XROTW2gTmmuy+YPPDjdtKKTQ3mfxrPtKtV+a9QFbj8f5MnjVMV0Zpy1BIB4CyIMsVVi4z6+nI67auT7IlsM3SQ==} dependencies: - '@ledgerhq/errors': 6.15.0 - '@ledgerhq/logs': 6.11.0 + '@ledgerhq/errors': 6.16.1 + '@ledgerhq/logs': 6.12.0 rxjs: 7.8.1 semver: 7.5.4 dev: false - /@ledgerhq/errors@6.15.0: - resolution: {integrity: sha512-6xaw5/mgoht62TnL3rXsaQYEFwpnXyNDk1AOSJksIjFHx9bHUnkyVmrnGQDj0JLzi+E7bHEgTrpCs8wpeDh9jA==} + /@ledgerhq/errors@6.16.1: + resolution: {integrity: sha512-4D4wKecGzQpIu7sx03Sg4uE1e8g1oZUndWgw9gw776H8h9ov9c5TxPaldTn2j6orPECAERViLf7LTO4L5pE2Cw==} dev: false - /@ledgerhq/hw-transport@6.29.0: - resolution: {integrity: sha512-WQfzxt3EnnbOmzZVYiCgSmNsqafBOFQn40awvUPY2IZviJRs23/1ANPHAo76bzPV88+Qk0+1wZlcnIanGN6fFA==} + /@ledgerhq/hw-transport@6.30.1: + resolution: {integrity: sha512-Xeeo4nt33g5Fsp3CdsPvcc2Uk7dwYeKRSlSFLWcYAAKprf/PmxgNekhke1eaNU/wLoeLOWhY2Cki8F8w9nLMdQ==} dependencies: - '@ledgerhq/devices': 8.0.8 - '@ledgerhq/errors': 6.15.0 - '@ledgerhq/logs': 6.11.0 + '@ledgerhq/devices': 8.2.0 + '@ledgerhq/errors': 6.16.1 + '@ledgerhq/logs': 6.12.0 events: 3.3.0 dev: false - /@ledgerhq/logs@6.11.0: - resolution: {integrity: sha512-HHK9y4GGe4X7CXbRUCh7z8Mp+WggpJn1dmUjmuk1rNugESF6o8nAOnXA+BxwtRRNV3CgNJR3Wxdos4J9qV0Zsg==} + /@ledgerhq/logs@6.12.0: + resolution: {integrity: sha512-ExDoj1QV5eC6TEbMdLUMMk9cfvNKhhv5gXol4SmULRVCx/3iyCPhJ74nsb3S0Vb+/f+XujBEj3vQn5+cwS0fNA==} dev: false - /@ledgerhq/wallet-api-client-react@1.1.2(react@18.2.0): - resolution: {integrity: sha512-ZBnp8HBHwtuDE/jqYuJmqx20Dx9dqqcZaOW4YuaY32GRwqEJJslTtcypCCgq2kArl0Y0q0irOYEd/0I7ULxdLQ==} + /@ledgerhq/wallet-api-client-react@1.3.0(react@18.2.0): + resolution: {integrity: sha512-UYNKQ1Yp/ZieqY4SGKgkoxKXJ3t0Zj/PPnZDoOrG/YbAFd4r3bL4XvTMa5T+bIdjbqITTo7VRiA9mhk5ootLrA==} peerDependencies: react: ^16.8.0 || ^17 || ^18 dependencies: - '@ledgerhq/wallet-api-client': 1.2.1 + '@ledgerhq/wallet-api-client': 1.5.0 react: 18.2.0 dev: false - /@ledgerhq/wallet-api-client@1.2.1: - resolution: {integrity: sha512-uTBTZCpbLTM5y5Cd7ioQB0lcq0b3cbrU2bGzCiKuY1IEd0NUyFhr2dKliRrcLoMPDRtQRmRnSxeX0BFKinoo8Q==} + /@ledgerhq/wallet-api-client@1.5.0: + resolution: {integrity: sha512-I07RlTmHw0uia5xhHa8Z3I7yVlYkxUWPfKWruh0vM6o0hDzPddGp+oDJZlriJIIrj2eHfaUCO1bEgycewPe0jA==} dependencies: - '@ledgerhq/hw-transport': 6.29.0 - '@ledgerhq/wallet-api-core': 1.3.1 + '@ledgerhq/hw-transport': 6.30.1 + '@ledgerhq/wallet-api-core': 1.6.0 bignumber.js: 9.1.2 dev: false - /@ledgerhq/wallet-api-core@1.3.1: - resolution: {integrity: sha512-yOeb1tfdwF6NdxVEIVr8SVz5iOyh6asWa0bbuCyMpiLrfuVS/Wkr6OeDMBYSxWxXxRFmQDJ9XQxdtSS+MGNk1Q==} + /@ledgerhq/wallet-api-core@1.6.0: + resolution: {integrity: sha512-nVPN3yu5+5pbhfFYh0iKmij5U7KVKZfpDkusXbj4yKvueKY8ZXU1wgvw1rDhgxlqu+s7JTA50MX56doyhm46Qg==} dependencies: - '@ledgerhq/errors': 6.15.0 + '@ledgerhq/errors': 6.16.1 bignumber.js: 9.1.2 uuid: 9.0.1 zod: 3.22.4 @@ -6544,10 +6592,10 @@ packages: peerDependencies: eslint: '>= 4.12.1' dependencies: - '@babel/code-frame': 7.23.4 - '@babel/parser': 7.23.4 - '@babel/traverse': 7.23.4 - '@babel/types': 7.23.4 + '@babel/code-frame': 7.23.5 + '@babel/parser': 7.23.6 + '@babel/traverse': 7.23.6 + '@babel/types': 7.23.6 eslint: 8.54.0 eslint-visitor-keys: 1.3.0 resolve: 1.22.8 @@ -9770,7 +9818,7 @@ packages: fs-extra: 11.1.1 gatsby: 5.12.11(babel-eslint@10.1.0)(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.2) gatsby-core-utils: 4.12.1 - gatsby-sharp: 1.12.1 + gatsby-sharp: 1.13.0 graphql: 16.8.1 graphql-compose: 9.0.10(graphql@16.8.1) import-from: 4.0.0 @@ -9803,8 +9851,8 @@ packages: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - /gatsby-sharp@1.12.1: - resolution: {integrity: sha512-e7lqA74UZau7MOktc9V+sNh86a8oNZPFIsY5Atk+C0sGlzHx0IcivsJjwLHJ6OF11SIC38a9z2wE8Nl6YiG/Ig==} + /gatsby-sharp@1.13.0: + resolution: {integrity: sha512-DviUtgm7tatSd1Hm54o/orHimOcyXBO9OJkSfzEchPFClvOza+2Qe/lqZShio0gFDxmG0Jgn0XCLzG7uH5VyJQ==} engines: {node: '>=18.0.0'} dependencies: sharp: 0.32.6 @@ -10018,7 +10066,7 @@ packages: xstate: 4.38.3 yaml-loader: 0.8.0 optionalDependencies: - gatsby-sharp: 1.12.1 + gatsby-sharp: 1.13.0 transitivePeerDependencies: - '@swc/core' - '@types/webpack' From e8faf951c00d6bf75ec7e0c2ef02bdd78c081494 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 29 Dec 2023 15:43:10 +0100 Subject: [PATCH 077/170] Initial implementation of stake steps --- dapp/manifest-ledger-live-app.json | 2 +- dapp/package.json | 3 +- .../components/Modals/Staking/DepositBTC.tsx | 32 ++ .../components/Modals/Staking/Overview.tsx | 6 +- .../components/Modals/Staking/SignMessage.tsx | 45 +++ .../components/Modals/Staking/StakeForm.tsx | 6 +- .../components/Modals/Staking/StakeSteps.tsx | 80 ++++ dapp/src/components/Modals/Staking/index.tsx | 14 +- dapp/src/components/shared/Spinner/index.tsx | 17 + .../components/shared/StepperBase/index.tsx | 11 +- dapp/vite.config.ts | 3 +- pnpm-lock.yaml | 362 ++++++++++++++++++ 12 files changed, 567 insertions(+), 14 deletions(-) create mode 100644 dapp/src/components/Modals/Staking/DepositBTC.tsx create mode 100644 dapp/src/components/Modals/Staking/SignMessage.tsx create mode 100644 dapp/src/components/Modals/Staking/StakeSteps.tsx create mode 100644 dapp/src/components/shared/Spinner/index.tsx diff --git a/dapp/manifest-ledger-live-app.json b/dapp/manifest-ledger-live-app.json index 29f63c113..265928a59 100644 --- a/dapp/manifest-ledger-live-app.json +++ b/dapp/manifest-ledger-live-app.json @@ -18,6 +18,6 @@ "en": "Bitcoin Liquid Staking" } }, - "permissions": ["account.request"], + "permissions": ["account.request", "message.sign"], "domains": ["http://*"] } diff --git a/dapp/package.json b/dapp/package.json index 2d160d0a4..8345eb7e2 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -35,6 +35,7 @@ "eslint": "^8.54.0", "prettier": "^3.1.0", "typescript": "^5.3.2", - "vite": "^5.0.2" + "vite": "^5.0.2", + "vite-plugin-node-polyfills": "^0.19.0" } } diff --git a/dapp/src/components/Modals/Staking/DepositBTC.tsx b/dapp/src/components/Modals/Staking/DepositBTC.tsx new file mode 100644 index 000000000..91e7c8789 --- /dev/null +++ b/dapp/src/components/Modals/Staking/DepositBTC.tsx @@ -0,0 +1,32 @@ +import React from "react" +import Alert from "../../shared/Alert" +import { useModalFlowContext, useWalletContext } from "../../../hooks" +import StakeSteps from "./StakeSteps" +import { TextMd } from "../../shared/Typography" + +export default function DepositBTC() { + const { goNext } = useModalFlowContext() + const { btcAccount } = useWalletContext() + + const handleSendBTC = async () => { + if (!btcAccount?.id) return + + // TODO: Send the correct transaction + goNext() + } + + return ( + + + + Make a Bitcoin transaction to deposit and stake your BTC. + + + + ) +} diff --git a/dapp/src/components/Modals/Staking/Overview.tsx b/dapp/src/components/Modals/Staking/Overview.tsx index 2ad8a1e94..61023146d 100644 --- a/dapp/src/components/Modals/Staking/Overview.tsx +++ b/dapp/src/components/Modals/Staking/Overview.tsx @@ -1,9 +1,11 @@ import React from "react" import { Button, ModalBody, ModalFooter } from "@chakra-ui/react" -import { ModalStep } from "../../../contexts" import { TextMd } from "../../shared/Typography" +import { useModalFlowContext } from "../../../hooks" + +export default function Overview() { + const { goNext } = useModalFlowContext() -export default function Overview({ goNext }: ModalStep) { return ( <> diff --git a/dapp/src/components/Modals/Staking/SignMessage.tsx b/dapp/src/components/Modals/Staking/SignMessage.tsx new file mode 100644 index 000000000..9965966b8 --- /dev/null +++ b/dapp/src/components/Modals/Staking/SignMessage.tsx @@ -0,0 +1,45 @@ +import React, { useEffect } from "react" +import { Highlight } from "@chakra-ui/react" +import { useSignMessage } from "@ledgerhq/wallet-api-client-react" +import Alert from "../../shared/Alert" +import { useModalFlowContext, useWalletContext } from "../../../hooks" +import StakeSteps from "./StakeSteps" +import { TextMd } from "../../shared/Typography" + +const SIGN_MESSAGE = "Test message" + +export default function SignMessage() { + const { goNext } = useModalFlowContext() + const { ethAccount } = useWalletContext() + const { signMessage, signature } = useSignMessage() + + const handleSignMessage = async () => { + if (!ethAccount?.id) return + + await signMessage(ethAccount.id, Buffer.from(SIGN_MESSAGE, "utf-8")) + } + + useEffect(() => { + if (signature) { + goNext() + } + }, [goNext, signature]) + + return ( + + + + + You will receive stBTC liquid staking token at this Ethereum address + once the staking transaction is completed. + + + + + ) +} diff --git a/dapp/src/components/Modals/Staking/StakeForm.tsx b/dapp/src/components/Modals/Staking/StakeForm.tsx index 8d308ecff..a887dd052 100644 --- a/dapp/src/components/Modals/Staking/StakeForm.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm.tsx @@ -1,9 +1,11 @@ import React from "react" import { Button, ModalBody } from "@chakra-ui/react" -import { ModalStep } from "../../../contexts" import { TextMd } from "../../shared/Typography" +import { useModalFlowContext } from "../../../hooks" + +export default function StakeModal() { + const { goNext } = useModalFlowContext() -export default function StakeModal({ goNext }: ModalStep) { return ( Stake modal diff --git a/dapp/src/components/Modals/Staking/StakeSteps.tsx b/dapp/src/components/Modals/Staking/StakeSteps.tsx new file mode 100644 index 000000000..00318ad3e --- /dev/null +++ b/dapp/src/components/Modals/Staking/StakeSteps.tsx @@ -0,0 +1,80 @@ +import React from "react" +import { + Button, + HStack, + ModalBody, + ModalFooter, + ModalHeader, + StepNumber, +} from "@chakra-ui/react" +import StepperBase, { StepBase } from "../../shared/StepperBase" +import { TextLg, TextMd } from "../../shared/Typography" +import Spinner from "../../shared/Spinner" + +function Title({ children }: { children: React.ReactNode }) { + return {children} +} +function Description({ children }: { children: React.ReactNode }) { + return {children} +} + +const STEPS: StepBase[] = [ + { + id: "sign-message", + title: Sign message, + description: ( + + + Sign the message in your ETH wallet. + + ), + }, + { + id: "deposit-btc", + title: Deposit BTC, + description: ( + + + Waiting for your deposit... + + ), + }, +] + +export default function StakeSteps({ + header, + buttonText, + activeStep, + onClick, + children, +}: { + header: string + buttonText: string + activeStep: number + onClick: () => void + children: React.ReactNode +}) { + return ( + <> + {header} + + } + steps={STEPS} + hideDescriptionWhenInactive + /> + {children} + + + + + + ) +} diff --git a/dapp/src/components/Modals/Staking/index.tsx b/dapp/src/components/Modals/Staking/index.tsx index d5b117df3..2f65f91ca 100644 --- a/dapp/src/components/Modals/Staking/index.tsx +++ b/dapp/src/components/Modals/Staking/index.tsx @@ -3,15 +3,21 @@ import { useModalFlowContext } from "../../../hooks" import StakeForm from "./StakeForm" import Overview from "./Overview" import ModalBase from "../../shared/ModalBase" +import SignMessage from "./SignMessage" +import DepositBTC from "./DepositBTC" function StakingSteps() { - const { activeStep, goNext } = useModalFlowContext() + const { activeStep } = useModalFlowContext() switch (activeStep) { case 1: - return + return case 2: - return + return + case 3: + return + case 4: + return default: return null } @@ -25,7 +31,7 @@ export default function StakingModal({ onClose: () => void }) { return ( - + ) diff --git a/dapp/src/components/shared/Spinner/index.tsx b/dapp/src/components/shared/Spinner/index.tsx new file mode 100644 index 000000000..1e5c6a29d --- /dev/null +++ b/dapp/src/components/shared/Spinner/index.tsx @@ -0,0 +1,17 @@ +import React from "react" +import { + Spinner as ChakraSpinner, + SpinnerProps as ChakraSpinnerProps, +} from "@chakra-ui/react" + +export default function Spinner({ ...spinnerProps }: ChakraSpinnerProps) { + return ( + + ) +} diff --git a/dapp/src/components/shared/StepperBase/index.tsx b/dapp/src/components/shared/StepperBase/index.tsx index a58551d67..7121ddc40 100644 --- a/dapp/src/components/shared/StepperBase/index.tsx +++ b/dapp/src/components/shared/StepperBase/index.tsx @@ -24,6 +24,7 @@ type StepperBaseProps = { complete?: JSX.Element incomplete?: JSX.Element active?: JSX.Element + hideDescriptionWhenInactive?: boolean } & Omit export default function StepperBase({ @@ -31,11 +32,13 @@ export default function StepperBase({ complete, incomplete, active, + index: activeStep, + hideDescriptionWhenInactive, ...stepperProps }: StepperBaseProps) { return ( - - {steps.map((step) => ( + + {steps.map((step, index) => ( {step.title} - {step.description} + {(!hideDescriptionWhenInactive || activeStep === index) && ( + {step.description} + )} diff --git a/dapp/vite.config.ts b/dapp/vite.config.ts index ea1889ae7..cef82d65c 100644 --- a/dapp/vite.config.ts +++ b/dapp/vite.config.ts @@ -1,6 +1,7 @@ import { defineConfig } from "vite" import react from "@vitejs/plugin-react" +import { nodePolyfills } from "vite-plugin-node-polyfills" export default defineConfig({ - plugins: [react()], + plugins: [nodePolyfills(), react()], }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1c334a15e..521f0059e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -169,6 +169,9 @@ importers: vite: specifier: ^5.0.2 version: 5.0.2 + vite-plugin-node-polyfills: + specifier: ^0.19.0 + version: 0.19.0(vite@5.0.2) sdk: devDependencies: @@ -5113,6 +5116,34 @@ packages: resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} dev: false + /@rollup/plugin-inject@5.0.5: + resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.1.0 + estree-walker: 2.0.2 + magic-string: 0.30.5 + dev: true + + /@rollup/pluginutils@5.1.0: + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + dev: true + /@rollup/rollup-android-arm-eabi@4.5.1: resolution: {integrity: sha512-YaN43wTyEBaMqLDYeze+gQ4ZrW5RbTEGtT5o1GVDkhpdNcsLTnLRcLccvwy3E9wiDKWg9RIhuoy3JQKDRBfaZA==} cpu: [arm] @@ -6496,6 +6527,25 @@ packages: /asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + /asn1.js@5.4.1: + resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==} + dependencies: + bn.js: 4.12.0 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + safer-buffer: 2.1.2 + dev: true + + /assert@2.1.0: + resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} + dependencies: + call-bind: 1.0.5 + is-nan: 1.3.2 + object-is: 1.1.5 + object.assign: 4.1.4 + util: 0.12.5 + dev: true + /assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: true @@ -6903,6 +6953,12 @@ packages: run-parallel-limit: 1.1.0 dev: true + /browser-resolve@2.0.0: + resolution: {integrity: sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==} + dependencies: + resolve: 1.22.8 + dev: true + /browser-stdout@1.3.1: resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} dev: true @@ -6918,6 +6974,51 @@ packages: safe-buffer: 5.2.1 dev: true + /browserify-cipher@1.0.1: + resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==} + dependencies: + browserify-aes: 1.2.0 + browserify-des: 1.0.2 + evp_bytestokey: 1.0.3 + dev: true + + /browserify-des@1.0.2: + resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} + dependencies: + cipher-base: 1.0.4 + des.js: 1.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: true + + /browserify-rsa@4.1.0: + resolution: {integrity: sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==} + dependencies: + bn.js: 5.2.1 + randombytes: 2.1.0 + dev: true + + /browserify-sign@4.2.2: + resolution: {integrity: sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==} + engines: {node: '>= 4'} + dependencies: + bn.js: 5.2.1 + browserify-rsa: 4.1.0 + create-hash: 1.2.0 + create-hmac: 1.1.7 + elliptic: 6.5.4 + inherits: 2.0.4 + parse-asn1: 5.1.6 + readable-stream: 3.6.2 + safe-buffer: 5.2.1 + dev: true + + /browserify-zlib@0.2.0: + resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} + dependencies: + pako: 1.0.11 + dev: true + /browserslist@4.22.1: resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -6976,6 +7077,10 @@ packages: ieee754: 1.2.1 dev: true + /builtin-status-codes@3.0.0: + resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} + dev: true + /builtins@5.0.1: resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} dependencies: @@ -7506,6 +7611,10 @@ packages: /confusing-browser-globals@1.0.11: resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} + /console-browserify@1.2.0: + resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} + dev: true + /constant-case@3.0.4: resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} dependencies: @@ -7513,6 +7622,10 @@ packages: tslib: 2.6.2 upper-case: 2.0.2 + /constants-browserify@1.0.0: + resolution: {integrity: sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==} + dev: true + /content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -7615,6 +7728,13 @@ packages: hasBin: true dev: true + /create-ecdh@4.0.4: + resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} + dependencies: + bn.js: 4.12.0 + elliptic: 6.5.4 + dev: true + /create-gatsby@3.12.3: resolution: {integrity: sha512-N0K/Z/MD5LMRJcBy669WpSgrn+31zBV72Lv0RHolX0fXa77Yx58HsEiLWz83j/dtciGMQfEOEHFRetUqZhOggA==} hasBin: true @@ -7675,6 +7795,22 @@ packages: resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} dev: true + /crypto-browserify@3.12.0: + resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==} + dependencies: + browserify-cipher: 1.0.1 + browserify-sign: 4.2.2 + create-ecdh: 4.0.4 + create-hash: 1.2.0 + create-hmac: 1.1.7 + diffie-hellman: 5.0.3 + inherits: 2.0.4 + pbkdf2: 3.1.2 + public-encrypt: 4.0.3 + randombytes: 2.1.0 + randomfill: 1.0.4 + dev: true + /crypto-random-string@2.0.0: resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} engines: {node: '>=8'} @@ -7983,6 +8119,13 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} + /des.js@1.1.0: + resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + dev: true + /destroy@1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -8059,6 +8202,14 @@ packages: engines: {node: '>=0.3.1'} dev: true + /diffie-hellman@5.0.3: + resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} + dependencies: + bn.js: 4.12.0 + miller-rabin: 4.0.1 + randombytes: 2.1.0 + dev: true + /difflib@0.2.4: resolution: {integrity: sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==} dependencies: @@ -8095,6 +8246,11 @@ packages: domhandler: 4.3.1 entities: 2.2.0 + /domain-browser@4.23.0: + resolution: {integrity: sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==} + engines: {node: '>=10'} + dev: true + /domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} @@ -8888,6 +9044,10 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -10676,6 +10836,10 @@ packages: quick-lru: 5.1.1 resolve-alpn: 1.2.1 + /https-browserify@1.0.0: + resolution: {integrity: sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==} + dev: true + /https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -10828,6 +10992,14 @@ packages: is-relative: 1.0.0 is-windows: 1.0.2 + /is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + has-tostringtag: 1.0.0 + dev: true + /is-array-buffer@3.0.2: resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} dependencies: @@ -10975,6 +11147,14 @@ packages: /is-map@2.0.2: resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} + /is-nan@1.3.2: + resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + dev: true + /is-negative-zero@2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} @@ -11145,6 +11325,11 @@ packages: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} + /isomorphic-timers-promises@1.0.1: + resolution: {integrity: sha512-u4sej9B1LPSxTGKB/HiuzvEQnXH0ECYkSVQU39koSwmFAxhlEAFl9RdTvLv4TOTQUgBS5O3O5fwUxk6byBZ+IQ==} + engines: {node: '>=10'} + dev: true + /isomorphic-unfetch@3.1.0: resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} dependencies: @@ -11587,6 +11772,13 @@ packages: resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} dev: true + /magic-string@0.30.5: + resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + /make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -11702,6 +11894,14 @@ packages: braces: 3.0.2 picomatch: 2.3.1 + /miller-rabin@4.0.1: + resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} + hasBin: true + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + dev: true + /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} @@ -12021,6 +12221,39 @@ packages: /node-releases@2.0.13: resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + /node-stdlib-browser@1.2.0: + resolution: {integrity: sha512-VSjFxUhRhkyed8AtLwSCkMrJRfQ3e2lGtG3sP6FEgaLKBBbxM/dLfjRe1+iLhjvyLFW3tBQ8+c0pcOtXGbAZJg==} + engines: {node: '>=10'} + dependencies: + assert: 2.1.0 + browser-resolve: 2.0.0 + browserify-zlib: 0.2.0 + buffer: 5.7.1 + console-browserify: 1.2.0 + constants-browserify: 1.0.0 + create-require: 1.1.1 + crypto-browserify: 3.12.0 + domain-browser: 4.23.0 + events: 3.3.0 + https-browserify: 1.0.0 + isomorphic-timers-promises: 1.0.1 + os-browserify: 0.3.0 + path-browserify: 1.0.1 + pkg-dir: 5.0.0 + process: 0.11.10 + punycode: 1.4.1 + querystring-es3: 0.2.1 + readable-stream: 3.6.2 + stream-browserify: 3.0.0 + stream-http: 3.2.0 + string_decoder: 1.3.0 + timers-browserify: 2.0.12 + tty-browserify: 0.0.1 + url: 0.11.3 + util: 0.12.5 + vm-browserify: 1.1.2 + dev: true + /nofilter@3.1.0: resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} engines: {node: '>=12.19'} @@ -12117,6 +12350,14 @@ packages: /object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + /object-is@1.1.5: + resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + dev: true + /object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} @@ -12274,6 +12515,10 @@ packages: resolution: {integrity: sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==} dev: true + /os-browserify@0.3.0: + resolution: {integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==} + dev: true + /os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -12367,6 +12612,10 @@ packages: registry-url: 6.0.1 semver: 7.5.4 + /pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + dev: true + /param-case@3.0.4: resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} dependencies: @@ -12379,6 +12628,16 @@ packages: dependencies: callsites: 3.1.0 + /parse-asn1@5.1.6: + resolution: {integrity: sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==} + dependencies: + asn1.js: 5.4.1 + browserify-aes: 1.2.0 + evp_bytestokey: 1.0.3 + pbkdf2: 3.1.2 + safe-buffer: 5.2.1 + dev: true + /parse-cache-control@1.0.1: resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} dev: true @@ -12426,6 +12685,10 @@ packages: ansi-escapes: 4.3.2 cross-spawn: 7.0.3 + /path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + dev: true + /path-case@3.0.4: resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==} dependencies: @@ -12517,6 +12780,13 @@ packages: dependencies: find-up: 4.1.0 + /pkg-dir@5.0.0: + resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} + engines: {node: '>=10'} + dependencies: + find-up: 5.0.0 + dev: true + /pkg-up@3.1.0: resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} engines: {node: '>=8'} @@ -12934,6 +13204,11 @@ packages: /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + /process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + dev: true + /progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} @@ -12990,12 +13265,27 @@ packages: /pseudomap@1.0.2: resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + /public-encrypt@4.0.3: + resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} + dependencies: + bn.js: 4.12.0 + browserify-rsa: 4.1.0 + create-hash: 1.2.0 + parse-asn1: 5.1.6 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + dev: true + /pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} dependencies: end-of-stream: 1.4.4 once: 1.4.0 + /punycode@1.4.1: + resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} + dev: true + /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -13026,6 +13316,11 @@ packages: split-on-first: 1.1.0 strict-uri-encode: 2.0.0 + /querystring-es3@0.2.1: + resolution: {integrity: sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==} + engines: {node: '>=0.4.x'} + dev: true + /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -13042,6 +13337,13 @@ packages: dependencies: safe-buffer: 5.2.1 + /randomfill@1.0.4: + resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} + dependencies: + randombytes: 2.1.0 + safe-buffer: 5.2.1 + dev: true + /range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -14145,6 +14447,22 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + /stream-browserify@3.0.0: + resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /stream-http@3.2.0: + resolution: {integrity: sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==} + dependencies: + builtin-status-codes: 3.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + xtend: 4.0.2 + dev: true + /streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} @@ -14559,6 +14877,13 @@ packages: engines: {node: '>=14'} dev: true + /timers-browserify@2.0.12: + resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==} + engines: {node: '>=0.6.0'} + dependencies: + setimmediate: 1.0.5 + dev: true + /timers-ext@0.1.7: resolution: {integrity: sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==} dependencies: @@ -14716,6 +15041,10 @@ packages: tslib: 1.14.1 typescript: 5.3.2 + /tty-browserify@0.0.1: + resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==} + dev: true + /tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} requiresBuild: true @@ -14986,6 +15315,13 @@ packages: schema-utils: 3.3.0 webpack: 5.89.0 + /url@0.11.3: + resolution: {integrity: sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==} + dependencies: + punycode: 1.4.1 + qs: 6.11.2 + dev: true + /use-callback-ref@1.3.0(@types/react@18.2.38)(react@18.2.0): resolution: {integrity: sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==} engines: {node: '>=10'} @@ -15024,6 +15360,16 @@ packages: /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + /util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + dependencies: + inherits: 2.0.4 + is-arguments: 1.1.1 + is-generator-function: 1.0.10 + is-typed-array: 1.1.12 + which-typed-array: 1.1.13 + dev: true + /utila@0.4.0: resolution: {integrity: sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==} @@ -15066,6 +15412,18 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + /vite-plugin-node-polyfills@0.19.0(vite@5.0.2): + resolution: {integrity: sha512-AhdVxAmVnd1doUlIRGUGV6ZRPfB9BvIwDF10oCOmL742IsvsFIAV4tSMxSfu5e0Px0QeJLgWVOSbtHIvblzqMw==} + peerDependencies: + vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 + dependencies: + '@rollup/plugin-inject': 5.0.5 + node-stdlib-browser: 1.2.0 + vite: 5.0.2 + transitivePeerDependencies: + - rollup + dev: true + /vite@5.0.2: resolution: {integrity: sha512-6CCq1CAJCNM1ya2ZZA7+jS2KgnhbzvxakmlIjN24cF/PXhRMzpM/z8QgsVJA/Dm5fWUWnVEsmtBoMhmerPxT0g==} engines: {node: ^18.0.0 || >=20.0.0} @@ -15101,6 +15459,10 @@ packages: fsevents: 2.3.3 dev: true + /vm-browserify@1.1.2: + resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} + dev: true + /watchpack@2.4.0: resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} engines: {node: '>=10.13.0'} From 6d0d57439626bd3aba9934f7b6c95436068bcabc Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 29 Dec 2023 15:43:37 +0100 Subject: [PATCH 078/170] Refactoring skip flag for Mainnet --- core/deploy/00_resolve_testing_erc4626.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/deploy/00_resolve_testing_erc4626.ts b/core/deploy/00_resolve_testing_erc4626.ts index ecf80f52e..8fb6b0fce 100644 --- a/core/deploy/00_resolve_testing_erc4626.ts +++ b/core/deploy/00_resolve_testing_erc4626.ts @@ -26,6 +26,5 @@ export default func func.tags = ["TestERC4626"] func.dependencies = ["TBTC"] -if (hre.network.name === "mainnet") { - func.skip = async () => true -} +func.skip = async (hre: HardhatRuntimeEnvironment): Promise => + hre.network.name === "mainnet" From c0d9147c7e05766c5ea4d4b4bb174d3fb8680684 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 29 Dec 2023 15:49:12 +0100 Subject: [PATCH 079/170] Adding event when updating Dispatcher plus smaller comments --- core/contracts/Acre.sol | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 26c020661..ece9892f9 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -20,6 +20,7 @@ import "./Dispatcher.sol"; contract Acre is ERC4626, Ownable { using SafeERC20 for IERC20; + // Dispatcher contract that routes tBTC from Acre to a given vault and back. Dispatcher public dispatcher; // Minimum amount for a single deposit operation. uint256 public minimumDepositAmount; @@ -31,12 +32,10 @@ contract Acre is ERC4626, Ownable { uint256 minimumDepositAmount, uint256 maximumTotalAssets ); + event DispatcherUpdated(address oldDispatcher, address newDispatcher); error DepositAmountLessThanMin(uint256 amount, uint256 min); - error ZeroAddress(); - error DispatcherNotSet(); - error ApproveFailed(); constructor( IERC20 tbtc @@ -128,16 +127,20 @@ contract Acre is ERC4626, Ownable { return shares; } + // TODO: Implement a governed upgrade process that initiates an update and + // then finalizes it after a delay. /// @notice Updates the dispatcher contract and gives it an unlimited /// allowance to transfer staked tBTC. - /// @param _dispatcher Address of the new dispatcher contract. - function updateDispatcher(Dispatcher _dispatcher) external onlyOwner { - if (address(_dispatcher) == address(0)) { + /// @param newDispatcher Address of the new dispatcher contract. + function updateDispatcher(Dispatcher newDispatcher) external onlyOwner { + if (address(newDispatcher) == address(0)) { revert ZeroAddress(); } address oldDispatcher = address(dispatcher); - dispatcher = _dispatcher; + + emit DispatcherUpdated(oldDispatcher, address(newDispatcher)); + dispatcher = newDispatcher; // TODO: Once withdrawal/rebalancing is implemented, we need to revoke the // approval of the vaults share tokens from the old dispatcher and approve From dc288d9f294421d73af9f146a5e53d5e646e69c1 Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Fri, 29 Dec 2023 16:27:11 +0100 Subject: [PATCH 080/170] Define helpers wrapper for snapshots We take snapshots with before/after and beforeEach/afterEach blocks. Here we define common helper functions to simplify the code. --- core/test/Acre.test.ts | 66 ++++++++++-------------------------- core/test/Dispatcher.test.ts | 18 ++-------- core/test/helpers/context.ts | 38 +++++++++++++++++++-- 3 files changed, 56 insertions(+), 66 deletions(-) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 4a5b97620..683c4da4f 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -12,7 +12,11 @@ import { import type { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers" import type { SnapshotRestorer } from "@nomicfoundation/hardhat-toolbox/network-helpers" -import { deployment } from "./helpers/context" +import { + beforeAfterEachSnapshotWrapper, + beforeAfterSnapshotWrapper, + deployment, +} from "./helpers/context" import { getNamedSigner, getUnnamedSigner } from "./helpers/signer" import { to1e18 } from "./utils" @@ -45,16 +49,9 @@ describe("Acre", () => { describe("stake", () => { const referral = encodeBytes32String("referral") - let snapshot: SnapshotRestorer context("when staking as first staker", () => { - beforeEach(async () => { - snapshot = await takeSnapshot() - }) - - afterEach(async () => { - await snapshot.restore() - }) + beforeAfterEachSnapshotWrapper() context("with a referral", () => { const amountToStake = to1e18(1) @@ -258,6 +255,8 @@ describe("Acre", () => { }) context("when there are two stakers", () => { + beforeAfterSnapshotWrapper() + const staker1AmountToStake = to1e18(7) const staker2AmountToStake = to1e18(3) let afterStakesSnapshot: SnapshotRestorer @@ -276,10 +275,6 @@ describe("Acre", () => { await tbtc.connect(staker2).mint(staker2.address, staker2AmountToStake) }) - after(async () => { - await snapshot.restore() - }) - context( "when the vault is empty and has not yet earned yield from strategies", () => { @@ -529,15 +524,7 @@ describe("Acre", () => { }) describe("mint", () => { - let snapshot: SnapshotRestorer - - beforeEach(async () => { - snapshot = await takeSnapshot() - }) - - afterEach(async () => { - await snapshot.restore() - }) + beforeAfterEachSnapshotWrapper() context("when minting as first staker", () => { const amountToStake = to1e18(1) @@ -634,17 +621,10 @@ describe("Acre", () => { }) describe("updateDepositParameters", () => { + beforeAfterEachSnapshotWrapper() + const validMinimumDepositAmount = to1e18(1) const validMaximumTotalAssetsAmount = to1e18(30) - let snapshot: SnapshotRestorer - - beforeEach(async () => { - snapshot = await takeSnapshot() - }) - - afterEach(async () => { - await snapshot.restore() - }) context("when is called by owner", () => { context("when all parameters are valid", () => { @@ -728,20 +708,16 @@ describe("Acre", () => { }) describe("maxDeposit", () => { + beforeAfterEachSnapshotWrapper() + let maximumTotalAssets: bigint let minimumDepositAmount: bigint - let snapshot: SnapshotRestorer beforeEach(async () => { - snapshot = await takeSnapshot() ;[minimumDepositAmount, maximumTotalAssets] = await acre.depositParameters() }) - afterEach(async () => { - await snapshot.restore() - }) - context( "when total assets is greater than maximum total assets amount", () => { @@ -817,20 +793,16 @@ describe("Acre", () => { }) describe("maxMint", () => { + beforeAfterEachSnapshotWrapper() + let maximumTotalAssets: bigint let minimumDepositAmount: bigint - let snapshot: SnapshotRestorer beforeEach(async () => { - snapshot = await takeSnapshot() ;[minimumDepositAmount, maximumTotalAssets] = await acre.depositParameters() }) - afterEach(async () => { - await snapshot.restore() - }) - context( "when total assets is greater than maximum total assets amount", () => { @@ -922,19 +894,15 @@ describe("Acre", () => { }) describe("deposit", () => { + beforeAfterEachSnapshotWrapper() + let amountToDeposit: bigint let minimumDepositAmount: bigint - let snapshot: SnapshotRestorer beforeEach(async () => { - snapshot = await takeSnapshot() minimumDepositAmount = await acre.minimumDepositAmount() }) - afterEach(async () => { - await snapshot.restore() - }) - context("when the deposit amount is less than minimum", () => { beforeEach(() => { amountToDeposit = minimumDepositAmount - 1n diff --git a/core/test/Dispatcher.test.ts b/core/test/Dispatcher.test.ts index 1fdecc5d9..3b986674e 100644 --- a/core/test/Dispatcher.test.ts +++ b/core/test/Dispatcher.test.ts @@ -1,13 +1,9 @@ import { ethers } from "hardhat" import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers" import { expect } from "chai" -import { - SnapshotRestorer, - takeSnapshot, - loadFixture, -} from "@nomicfoundation/hardhat-toolbox/network-helpers" +import { loadFixture } from "@nomicfoundation/hardhat-toolbox/network-helpers" import type { Dispatcher } from "../typechain" -import { deployment } from "./helpers/context" +import { beforeAfterEachSnapshotWrapper, deployment } from "./helpers/context" import { getNamedSigner, getUnnamedSigner } from "./helpers/signer" async function fixture() { @@ -19,8 +15,6 @@ async function fixture() { } describe("Dispatcher", () => { - let snapshot: SnapshotRestorer - let dispatcher: Dispatcher let governance: HardhatEthersSigner let thirdParty: HardhatEthersSigner @@ -38,13 +32,7 @@ describe("Dispatcher", () => { vaultAddress4 = await ethers.Wallet.createRandom().getAddress() }) - beforeEach(async () => { - snapshot = await takeSnapshot() - }) - - afterEach(async () => { - await snapshot.restore() - }) + beforeAfterEachSnapshotWrapper() describe("authorizeVault", () => { context("when caller is not a governance account", () => { diff --git a/core/test/helpers/context.ts b/core/test/helpers/context.ts index 34875e43d..8bbc206f1 100644 --- a/core/test/helpers/context.ts +++ b/core/test/helpers/context.ts @@ -1,10 +1,44 @@ import { deployments } from "hardhat" - +import { + SnapshotRestorer, + takeSnapshot, +} from "@nomicfoundation/hardhat-toolbox/network-helpers" import { getDeployedContract } from "./contract" import type { Acre, Dispatcher, TestERC20 } from "../../typechain" -// eslint-disable-next-line import/prefer-default-export +/** + * Adds a before/after hook pair to snapshot the EVM state before and after tests + * in a test suite. + */ +export function beforeAfterSnapshotWrapper(): void { + let snapshot: SnapshotRestorer + + before(async () => { + snapshot = await takeSnapshot() + }) + + after(async () => { + await snapshot.restore() + }) +} + +/** + * Adds a beforeEach/afterEach hook pair to snapshot the EVM state before and + * after each of tests in a test suite. + */ +export function beforeAfterEachSnapshotWrapper(): void { + let snapshot: SnapshotRestorer + + beforeEach(async () => { + snapshot = await takeSnapshot() + }) + + afterEach(async () => { + await snapshot.restore() + }) +} + export async function deployment() { await deployments.fixture() From c73202ee74d5e1883a46aaef3bffc1c0fb744d73 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 29 Dec 2023 16:30:16 +0100 Subject: [PATCH 081/170] Updating dispatcher in 'before' instead of 'it' --- core/test/Acre.test.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 5231b445d..7cd059f2e 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -838,15 +838,11 @@ describe("Acre", () => { dispatcherAddress = await dispatcher.getAddress() newDispatcher = await ethers.Wallet.createRandom().getAddress() acreAddress = await acre.getAddress() - }) - it("should approve max amount for the dispatcher", async () => { - const allowance = await tbtc.allowance(acreAddress, dispatcherAddress) - expect(allowance).to.be.equal(MaxUint256) + await acre.connect(governance).updateDispatcher(newDispatcher) }) it("should be able to update the dispatcher", async () => { - await acre.connect(governance).updateDispatcher(newDispatcher) expect(await acre.dispatcher()).to.be.equal(newDispatcher) }) From 11becd098cb13b8af098e57c7433ba96a4cc1960 Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Fri, 29 Dec 2023 16:33:52 +0100 Subject: [PATCH 082/170] Update order of actions in before block --- core/test/Acre.test.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 683c4da4f..85e86c4ec 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -263,16 +263,17 @@ describe("Acre", () => { let afterSimulatingYieldSnapshot: SnapshotRestorer before(async () => { + // Mint tBTC. + await tbtc.mint(staker1.address, staker1AmountToStake) + await tbtc.mint(staker2.address, staker2AmountToStake) + + // Approve tBTC. await tbtc .connect(staker1) .approve(await acre.getAddress(), staker1AmountToStake) await tbtc .connect(staker2) .approve(await acre.getAddress(), staker2AmountToStake) - - // Mint tokens. - await tbtc.connect(staker1).mint(staker1.address, staker1AmountToStake) - await tbtc.connect(staker2).mint(staker2.address, staker2AmountToStake) }) context( From 39ff3d79ddaaccfc17da63919b897d2ae566bde6 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 29 Dec 2023 17:05:48 +0100 Subject: [PATCH 083/170] Refactorings in Dispatcher - Renamings - Extracted isVaultAuthorized - error change CallerUnauthorized > NotMaintainer --- core/contracts/Dispatcher.sol | 54 +++++++++++++++--------- core/test/integration/AssetFlows.test.ts | 4 +- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/core/contracts/Dispatcher.sol b/core/contracts/Dispatcher.sol index 49f180e80..f3937fa2e 100644 --- a/core/contracts/Dispatcher.sol +++ b/core/contracts/Dispatcher.sol @@ -18,9 +18,11 @@ contract Dispatcher is Router, Ownable { bool authorized; } - Acre public immutable acre; // Depositing tBTC into Acre returns stBTC. - IERC20 public immutable tBTC; - + // Depositing tBTC into Acre returns stBTC. + Acre public immutable acre; + // tBTC token contract. + IERC20 public immutable tbtc; + // Address of the maintainer bot. address public maintainer; /// @notice Authorized Yield Vaults that implement ERC4626 standard. These @@ -37,31 +39,31 @@ contract Dispatcher is Router, Ownable { event DepositAllocated( address indexed vault, uint256 amount, - uint256 minSharesOut + uint256 sharesOut ); event MaintainerUpdated(address indexed maintainer); error VaultAlreadyAuthorized(); error VaultUnauthorized(); - error CallerUnauthorized(string reason); + error NotMaintainer(); error ZeroAddress(); modifier onlyMaintainer() { if (msg.sender != maintainer) { - revert CallerUnauthorized("Maintainer only"); + revert NotMaintainer(); } _; } - constructor(Acre _acre, IERC20 _tBTC) Ownable(msg.sender) { + constructor(Acre _acre, IERC20 _tbtc) Ownable(msg.sender) { acre = _acre; - tBTC = _tBTC; + tbtc = _tbtc; } /// @notice Adds a vault to the list of authorized vaults. /// @param vault Address of the vault to add. function authorizeVault(address vault) external onlyOwner { - if (vaultsInfo[vault].authorized) { + if (isVaultAuthorized(vault)) { revert VaultAlreadyAuthorized(); } @@ -74,7 +76,7 @@ contract Dispatcher is Router, Ownable { /// @notice Removes a vault from the list of authorized vaults. /// @param vault Address of the vault to remove. function deauthorizeVault(address vault) external onlyOwner { - if (!vaultsInfo[vault].authorized) { + if (!isVaultAuthorized(vault)) { revert VaultUnauthorized(); } @@ -104,26 +106,32 @@ contract Dispatcher is Router, Ownable { uint256 amount, uint256 minSharesOut ) public onlyMaintainer { - if (!vaultsInfo[vault].authorized) { + if (!isVaultAuthorized(vault)) { revert VaultUnauthorized(); } - emit DepositAllocated(vault, amount, minSharesOut); // slither-disable-next-line arbitrary-send-erc20 - tBTC.safeTransferFrom(address(acre), address(this), amount); - tBTC.forceApprove(address(vault), amount); - - deposit(IERC4626(vault), address(acre), amount, minSharesOut); + tbtc.safeTransferFrom(address(acre), address(this), amount); + tbtc.forceApprove(address(vault), amount); + + uint256 sharesOut = deposit( + IERC4626(vault), + address(acre), + amount, + minSharesOut + ); + // slither-disable-next-line reentrancy-events + emit DepositAllocated(vault, amount, sharesOut); } /// @notice Updates the maintainer address. - /// @param _maintainer Address of the new maintainer. - function updateMaintainer(address _maintainer) external onlyOwner { - if (_maintainer == address(0)) { + /// @param newMaintainer Address of the new maintainer. + function updateMaintainer(address newMaintainer) external onlyOwner { + if (newMaintainer == address(0)) { revert ZeroAddress(); } - maintainer = _maintainer; + maintainer = newMaintainer; emit MaintainerUpdated(maintainer); } @@ -133,5 +141,11 @@ contract Dispatcher is Router, Ownable { return vaults; } + /// @notice Returns true if the vault is authorized. + /// @param vault Address of the vault to check. + function isVaultAuthorized(address vault) internal view returns (bool) { + return vaultsInfo[vault].authorized; + } + /// TODO: implement redeem() / withdraw() functions } diff --git a/core/test/integration/AssetFlows.test.ts b/core/test/integration/AssetFlows.test.ts index 74bfce3f5..e8d69bbc0 100644 --- a/core/test/integration/AssetFlows.test.ts +++ b/core/test/integration/AssetFlows.test.ts @@ -59,9 +59,7 @@ describe("Integration Tests - Asset Flows", () => { dispatcher .connect(thirdParty) .depositToVault(vault.getAddress(), assetsToAllocate, minSharesOut), - ) - .to.be.revertedWithCustomError(dispatcher, "CallerUnauthorized") - .withArgs("Maintainer only") + ).to.be.revertedWithCustomError(dispatcher, "NotMaintainer") }) }) From 659556b87e3f57e773bbf5959b1172a775dcbb3c Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 29 Dec 2023 17:18:49 +0100 Subject: [PATCH 084/170] Extracting function calls under tests to before clause --- core/test/Acre.test.ts | 52 +++++++++++++++++++----------------- core/test/Dispatcher.test.ts | 39 ++++++++++++++++----------- 2 files changed, 52 insertions(+), 39 deletions(-) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 7cd059f2e..29f9b2292 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -830,36 +830,40 @@ describe("Acre", () => { }) context("when caller is an owner", () => { - let newDispatcher: string - let acreAddress: string - let dispatcherAddress: string + context("when a new dispatcher is zero address", () => { + it("should revert", async () => { + await expect( + acre.connect(governance).updateDispatcher(ZeroAddress), + ).to.be.revertedWithCustomError(acre, "ZeroAddress") + }) + }) - before(async () => { - dispatcherAddress = await dispatcher.getAddress() - newDispatcher = await ethers.Wallet.createRandom().getAddress() - acreAddress = await acre.getAddress() + context("when a new dispatcher is non-zero address", () => { + let newDispatcher: string + let acreAddress: string + let dispatcherAddress: string - await acre.connect(governance).updateDispatcher(newDispatcher) - }) + before(async () => { + dispatcherAddress = await dispatcher.getAddress() + newDispatcher = await ethers.Wallet.createRandom().getAddress() + acreAddress = await acre.getAddress() - it("should be able to update the dispatcher", async () => { - expect(await acre.dispatcher()).to.be.equal(newDispatcher) - }) + await acre.connect(governance).updateDispatcher(newDispatcher) + }) - it("should reset approval amount for the old dispatcher", async () => { - const allowance = await tbtc.allowance(acreAddress, dispatcherAddress) - expect(allowance).to.be.equal(0) - }) + it("should be able to update the dispatcher", async () => { + expect(await acre.dispatcher()).to.be.equal(newDispatcher) + }) - it("should approve max amount for the new dispatcher", async () => { - const allowance = await tbtc.allowance(acreAddress, newDispatcher) - expect(allowance).to.be.equal(MaxUint256) - }) + it("should reset approval amount for the old dispatcher", async () => { + const allowance = await tbtc.allowance(acreAddress, dispatcherAddress) + expect(allowance).to.be.equal(0) + }) - it("should not be able to update the dispatcher to the zero address", async () => { - await expect( - acre.connect(governance).updateDispatcher(ZeroAddress), - ).to.be.revertedWithCustomError(acre, "ZeroAddress") + it("should approve max amount for the new dispatcher", async () => { + const allowance = await tbtc.allowance(acreAddress, newDispatcher) + expect(allowance).to.be.equal(MaxUint256) + }) }) }) }) diff --git a/core/test/Dispatcher.test.ts b/core/test/Dispatcher.test.ts index e04ab802b..d7a458d43 100644 --- a/core/test/Dispatcher.test.ts +++ b/core/test/Dispatcher.test.ts @@ -159,7 +159,7 @@ describe("Dispatcher", () => { describe("updateMaintainer", () => { context("when caller is not an owner", () => { - it("should revert when updating the maintainer", async () => { + it("should revert", async () => { await expect( dispatcher.connect(thirdParty).updateMaintainer(newMaintainer), ).to.be.revertedWithCustomError( @@ -170,23 +170,32 @@ describe("Dispatcher", () => { }) context("when caller is an owner", () => { - it("should revert when updating the maintainer to the zero address", async () => { - await expect( - dispatcher.connect(governance).updateMaintainer(ZeroAddress), - ).to.be.revertedWithCustomError(dispatcher, "ZeroAddress") + context("when maintainer is a zero address", () => { + it("should revert", async () => { + await expect( + dispatcher.connect(governance).updateMaintainer(ZeroAddress), + ).to.be.revertedWithCustomError(dispatcher, "ZeroAddress") + }) }) - it("should be able to update the maintainer", async () => { - await dispatcher.connect(governance).updateMaintainer(newMaintainer) - expect(await dispatcher.maintainer()).to.be.equal(newMaintainer) - }) + context("when maintainer is not a zero address", () => { + let tx: ContractTransactionResponse - it("should emit an event when updating the maintainer", async () => { - await expect( - dispatcher.connect(governance).updateMaintainer(newMaintainer), - ) - .to.emit(dispatcher, "MaintainerUpdated") - .withArgs(newMaintainer) + before(async () => { + tx = await dispatcher + .connect(governance) + .updateMaintainer(newMaintainer) + }) + + it("should be able to update the maintainer", async () => { + expect(await dispatcher.maintainer()).to.be.equal(newMaintainer) + }) + + it("should emit an event when updating the maintainer", async () => { + await expect(tx) + .to.emit(dispatcher, "MaintainerUpdated") + .withArgs(newMaintainer) + }) }) }) }) From 03b4e377337cc3a770e9f8af4c052671b6b2465f Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Fri, 29 Dec 2023 17:06:55 +0100 Subject: [PATCH 085/170] Improve stake tests Minor improvements to stake tests to restructure the tests and clean up a little bit. --- core/test/Acre.test.ts | 432 ++++++++++++++++++++--------------------- 1 file changed, 215 insertions(+), 217 deletions(-) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 85e86c4ec..94af3f3aa 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -37,6 +37,8 @@ async function fixture() { } describe("Acre", () => { + const referral = encodeBytes32String("referral") + let acre: Acre let tbtc: TestERC20 let owner: HardhatEthersSigner @@ -48,8 +50,6 @@ describe("Acre", () => { }) describe("stake", () => { - const referral = encodeBytes32String("referral") - context("when staking as first staker", () => { beforeAfterEachSnapshotWrapper() @@ -254,11 +254,13 @@ describe("Acre", () => { ) }) - context("when there are two stakers", () => { + describe("when staking by multiple stakers", () => { beforeAfterSnapshotWrapper() const staker1AmountToStake = to1e18(7) const staker2AmountToStake = to1e18(3) + const earnedYield = to1e18(5) + let afterStakesSnapshot: SnapshotRestorer let afterSimulatingYieldSnapshot: SnapshotRestorer @@ -276,250 +278,248 @@ describe("Acre", () => { .approve(await acre.getAddress(), staker2AmountToStake) }) - context( - "when the vault is empty and has not yet earned yield from strategies", - () => { - after(async () => { + context("when the vault is in initial state", () => { + describe("when two stakers stake", () => { + let stakeTx1: ContractTransactionResponse + let stakeTx2: ContractTransactionResponse + + before(async () => { + stakeTx1 = await acre + .connect(staker1) + .stake(staker1AmountToStake, staker1.address, referral) + + stakeTx2 = await acre + .connect(staker2) + .stake(staker2AmountToStake, staker2.address, referral) + afterStakesSnapshot = await takeSnapshot() }) - context("when staker A stakes tokens", () => { - it("should receive shares equal to a staked amount", async () => { - const tx = await acre - .connect(staker1) - .stake(staker1AmountToStake, staker1.address, referral) - - await expect(tx).to.changeTokenBalances( - acre, - [staker1.address], - [staker1AmountToStake], - ) - }) + it("staker A should receive shares equal to a staked amount", async () => { + await expect(stakeTx1).to.changeTokenBalances( + acre, + [staker1.address], + [staker1AmountToStake], + ) }) - context("when staker B stakes tokens", () => { - it("should receive shares equal to a staked amount", async () => { - const tx = await acre - .connect(staker2) - .stake(staker2AmountToStake, staker2.address, referral) - - await expect(tx).to.changeTokenBalances( - acre, - [staker2.address], - [staker2AmountToStake], - ) - }) + it("staker B should receive shares equal to a staked amount", async () => { + await expect(stakeTx2).to.changeTokenBalances( + acre, + [staker2.address], + [staker2AmountToStake], + ) }) - }, - ) - - context("when the vault has stakes", () => { - before(async () => { - await afterStakesSnapshot.restore() - }) - - it("the total assets amount should be equal to all staked tokens", async () => { - const totalAssets = await acre.totalAssets() - expect(totalAssets).to.eq(staker1AmountToStake + staker2AmountToStake) + it("the total assets amount should be equal to all staked tokens", async () => { + expect(await acre.totalAssets()).to.eq( + staker1AmountToStake + staker2AmountToStake, + ) + }) }) }) - context("when vault earns yield", () => { - let staker1SharesBefore: bigint - let staker2SharesBefore: bigint - let vaultYield: bigint + context("when vault has two stakers", () => { + context("when vault earns yield", () => { + let staker1SharesBefore: bigint + let staker2SharesBefore: bigint - before(async () => { - // Current state: - // Staker A shares = 7 - // Staker B shares = 3 - // Total assets = 7(staker A) + 3(staker B) + 5(yield) - await afterStakesSnapshot.restore() + before(async () => { + // Current state: + // Staker A shares = 7 + // Staker B shares = 3 + // Total assets = 7(staker A) + 3(staker B) + 5(yield) + await afterStakesSnapshot.restore() - staker1SharesBefore = await acre.balanceOf(staker1.address) - staker2SharesBefore = await acre.balanceOf(staker2.address) - vaultYield = to1e18(5) + staker1SharesBefore = await acre.balanceOf(staker1.address) + staker2SharesBefore = await acre.balanceOf(staker2.address) - // Simulating yield returned from strategies. The vault now contains - // more tokens than deposited which causes the exchange rate to - // change. - await tbtc.mint(await acre.getAddress(), vaultYield) - }) + // Simulating yield returned from strategies. The vault now contains + // more tokens than deposited which causes the exchange rate to + // change. + await tbtc.mint(await acre.getAddress(), earnedYield) + }) - after(async () => { - afterSimulatingYieldSnapshot = await takeSnapshot() - }) + after(async () => { + afterSimulatingYieldSnapshot = await takeSnapshot() + }) - it("the vault should hold more assets", async () => { - expect(await acre.totalAssets()).to.be.eq( - staker1AmountToStake + staker2AmountToStake + vaultYield, - ) - }) + it("the vault should hold more assets", async () => { + expect(await acre.totalAssets()).to.be.eq( + staker1AmountToStake + staker2AmountToStake + earnedYield, + ) + }) - it("the staker's shares should be the same", async () => { - expect(await acre.balanceOf(staker1.address)).to.be.eq( - staker1SharesBefore, - ) - expect(await acre.balanceOf(staker2.address)).to.be.eq( - staker2SharesBefore, - ) - }) + it("the stakers shares should be the same", async () => { + expect(await acre.balanceOf(staker1.address)).to.be.eq( + staker1SharesBefore, + ) + expect(await acre.balanceOf(staker2.address)).to.be.eq( + staker2SharesBefore, + ) + }) - it("the staker A should be able to redeem more tokens than before", async () => { - const shares = await acre.balanceOf(staker1.address) - const availableAssetsToRedeem = await acre.previewRedeem(shares) + it("the staker A should be able to redeem more tokens than before", async () => { + const shares = await acre.balanceOf(staker1.address) + const availableAssetsToRedeem = await acre.previewRedeem(shares) - // Expected amount w/o rounding: 7 * 15 / 10 = 10.5 - // Expected amount w/ support for rounding: 10499999999999999999 in - // tBTC token precision. - const expectedAssetsToRedeem = 10499999999999999999n + // Expected amount w/o rounding: 7 * 15 / 10 = 10.5 + // Expected amount w/ support for rounding: 10499999999999999999 in + // tBTC token precision. + const expectedAssetsToRedeem = 10499999999999999999n - expect(availableAssetsToRedeem).to.be.eq(expectedAssetsToRedeem) - }) + expect(availableAssetsToRedeem).to.be.eq(expectedAssetsToRedeem) + }) - it("the staker B should be able to redeem more tokens than before", async () => { - const shares = await acre.balanceOf(staker2.address) - const availableAssetsToRedeem = await acre.previewRedeem(shares) + it("the staker B should be able to redeem more tokens than before", async () => { + const shares = await acre.balanceOf(staker2.address) + const availableAssetsToRedeem = await acre.previewRedeem(shares) - // Expected amount w/o rounding: 3 * 15 / 10 = 4.5 - // Expected amount w/ support for rounding: 4499999999999999999 in - // tBTC token precision. - const expectedAssetsToRedeem = 4499999999999999999n + // Expected amount w/o rounding: 3 * 15 / 10 = 4.5 + // Expected amount w/ support for rounding: 4499999999999999999 in + // tBTC token precision. + const expectedAssetsToRedeem = 4499999999999999999n - expect(availableAssetsToRedeem).to.be.eq(expectedAssetsToRedeem) + expect(availableAssetsToRedeem).to.be.eq(expectedAssetsToRedeem) + }) }) - }) - - context("when staker A stakes more tokens", () => { - context( - "when total tBTC amount after staking would not exceed max amount", - () => { - const newAmountToStake = to1e18(2) - // Current state: - // Total assets = 7(staker A) + 3(staker B) + 5(yield) - // Total shares = 7 + 3 = 10 - // Shares to mint = 2 * 10 / 15 = 1.(3) -> 1333333333333333333 in stBTC - // token precision - const expectedSharesToMint = 1333333333333333333n - let sharesBefore: bigint - let availableToRedeemBefore: bigint - - before(async () => { - await afterSimulatingYieldSnapshot.restore() - - sharesBefore = await acre.balanceOf(staker1.address) - availableToRedeemBefore = await acre.previewRedeem(sharesBefore) - - await tbtc.mint(staker1.address, newAmountToStake) - - await tbtc - .connect(staker1) - .approve(await acre.getAddress(), newAmountToStake) - - // State after stake: - // Total assets = 7(staker A) + 3(staker B) + 5(yield) + 2(staker - // A) = 17 - // Total shares = 7 + 3 + 1.(3) = 11.(3) - await acre - .connect(staker1) - .stake(newAmountToStake, staker1.address, referral) - }) - - it("should receive more shares", async () => { - const shares = await acre.balanceOf(staker1.address) - - expect(shares).to.be.eq(sharesBefore + expectedSharesToMint) - }) - - it("should be able to redeem more tokens than before", async () => { - const shares = await acre.balanceOf(staker1.address) - const availableToRedeem = await acre.previewRedeem(shares) - - // Expected amount w/o rounding: 8.(3) * 17 / 11.(3) = 12.5 - // Expected amount w/ support for rounding: 12499999999999999999 in - // tBTC token precision. - const expectedTotalAssetsAvailableToRedeem = 12499999999999999999n - - expect(availableToRedeem).to.be.greaterThan( - availableToRedeemBefore, - ) - expect(availableToRedeem).to.be.eq( - expectedTotalAssetsAvailableToRedeem, - ) - }) - }, - ) - context( - "when total tBTC amount after staking would exceed max amount", - () => { - let possibleMaxAmountToStake: bigint - let amountToStake: bigint - - before(async () => { - await afterSimulatingYieldSnapshot.restore() - - // In the current implementation of the `maxDeposit` the - // `address` param is not taken into account - it means it will - // return the same value for any address. - possibleMaxAmountToStake = await acre.maxDeposit(staker1.address) - amountToStake = possibleMaxAmountToStake + 1n - - await tbtc - .connect(staker1) - .approve(await acre.getAddress(), amountToStake) - }) - - it("should revert", async () => { - await expect(acre.stake(amountToStake, staker1.address, referral)) - .to.be.revertedWithCustomError( - acre, - "ERC4626ExceededMaxDeposit", + context("when staker A stakes more tokens", () => { + context( + "when total tBTC amount after staking would not exceed max amount", + () => { + const newAmountToStake = to1e18(2) + // Current state: + // Total assets = 7(staker A) + 3(staker B) + 5(yield) + // Total shares = 7 + 3 = 10 + // New stake amount = 2 + // Shares to mint = 2 * 10 / 15 = 1.(3) -> 1333333333333333333 in stBTC + // token precision + const expectedSharesToMint = 1333333333333333333n + let sharesBefore: bigint + let availableToRedeemBefore: bigint + + before(async () => { + await afterSimulatingYieldSnapshot.restore() + + sharesBefore = await acre.balanceOf(staker1.address) + availableToRedeemBefore = await acre.previewRedeem(sharesBefore) + + await tbtc.mint(staker1.address, newAmountToStake) + + await tbtc + .connect(staker1) + .approve(await acre.getAddress(), newAmountToStake) + + // State after stake: + // Total assets = 7(staker A) + 3(staker B) + 5(yield) + 2(staker + // A) = 17 + // Total shares = 7 + 3 + 1.(3) = 11.(3) + await acre + .connect(staker1) + .stake(newAmountToStake, staker1.address, referral) + }) + + it("should receive more shares", async () => { + const shares = await acre.balanceOf(staker1.address) + + expect(shares).to.be.eq(sharesBefore + expectedSharesToMint) + }) + + it("should be able to redeem more tokens than before", async () => { + const shares = await acre.balanceOf(staker1.address) + const availableToRedeem = await acre.previewRedeem(shares) + + // Expected amount w/o rounding: 8.(3) * 17 / 11.(3) = 12.5 + // Expected amount w/ support for rounding: 12499999999999999999 in + // tBTC token precision. + const expectedTotalAssetsAvailableToRedeem = + 12499999999999999999n + + expect(availableToRedeem).to.be.greaterThan( + availableToRedeemBefore, ) - .withArgs( - staker1.address, - amountToStake, - possibleMaxAmountToStake, + expect(availableToRedeem).to.be.eq( + expectedTotalAssetsAvailableToRedeem, ) - }) - }, - ) - - context( - "when total tBTC amount after staking would be equal to the max amount", - () => { - let amountToStake: bigint - let tx: ContractTransactionResponse + }) + }, + ) - before(async () => { - amountToStake = await acre.maxDeposit(staker1.address) + context( + "when total tBTC amount after staking would exceed max amount", + () => { + let possibleMaxAmountToStake: bigint + let amountToStake: bigint - await tbtc - .connect(staker1) - .approve(await acre.getAddress(), amountToStake) + before(async () => { + await afterSimulatingYieldSnapshot.restore() - tx = await acre.stake(amountToStake, staker1, referral) - }) - - it("should stake tokens correctly", async () => { - await expect(tx).to.emit(acre, "Deposit") - }) + // In the current implementation of the `maxDeposit` the + // `address` param is not taken into account - it means it will + // return the same value for any address. + possibleMaxAmountToStake = await acre.maxDeposit( + staker1.address, + ) + amountToStake = possibleMaxAmountToStake + 1n - it("the max deposit amount should be equal 0", async () => { - expect(await acre.maxDeposit(staker1)).to.eq(0) - }) + await tbtc + .connect(staker1) + .approve(await acre.getAddress(), amountToStake) + }) - it("should not be able to stake more tokens", async () => { - await expect(acre.stake(amountToStake, staker1, referral)) - .to.be.revertedWithCustomError( - acre, - "ERC4626ExceededMaxDeposit", + it("should revert", async () => { + await expect( + acre.stake(amountToStake, staker1.address, referral), ) - .withArgs(staker1.address, amountToStake, 0) - }) - }, - ) + .to.be.revertedWithCustomError( + acre, + "ERC4626ExceededMaxDeposit", + ) + .withArgs( + staker1.address, + amountToStake, + possibleMaxAmountToStake, + ) + }) + }, + ) + + context( + "when total tBTC amount after staking would be equal to the max amount", + () => { + let amountToStake: bigint + let tx: ContractTransactionResponse + + before(async () => { + amountToStake = await acre.maxDeposit(staker1.address) + + await tbtc + .connect(staker1) + .approve(await acre.getAddress(), amountToStake) + + tx = await acre.stake(amountToStake, staker1, referral) + }) + + it("should stake tokens correctly", async () => { + await expect(tx).to.emit(acre, "Deposit") + }) + + it("the max deposit amount should be equal 0", async () => { + expect(await acre.maxDeposit(staker1)).to.eq(0) + }) + + it("should not be able to stake more tokens", async () => { + await expect(acre.stake(amountToStake, staker1, referral)) + .to.be.revertedWithCustomError( + acre, + "ERC4626ExceededMaxDeposit", + ) + .withArgs(staker1.address, amountToStake, 0) + }) + }, + ) + }) }) }) }) @@ -774,7 +774,6 @@ describe("Acre", () => { context("when the vault is not empty", () => { const amountToStake = to1e18(1) - const referral = encodeBytes32String("referral") beforeEach(async () => { await tbtc @@ -875,7 +874,6 @@ describe("Acre", () => { context("when the vault is not empty", () => { const amountToStake = to1e18(1) - const referral = encodeBytes32String("referral") beforeEach(async () => { await tbtc From 90c3669862bae6a205a6dab2ddf9f86003231ec4 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 2 Jan 2024 09:35:10 +0100 Subject: [PATCH 086/170] Update outdated link to ledger doc --- dapp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dapp/README.md b/dapp/README.md index f6033bf13..3d3772d00 100644 --- a/dapp/README.md +++ b/dapp/README.md @@ -23,4 +23,4 @@ Once the build is running, you can import the manifest on desktop: Click on Browse next to **Add a local app** and select the manifest file. The app is now visible in the menu. -If you have any problems, take a look [here](https://developers.ledger.com/docs/non-dapp/tutorial/3-import/#desktop). +If you have any problems, take a look [here](https://developers.ledger.com/docs/discover/developer-mode). From 303f3b20a0c17e3198f96e05e95d2d3d5344bdc7 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 2 Jan 2024 10:38:16 +0100 Subject: [PATCH 087/170] Make a `validate` function more general --- dapp/src/components/Modals/Staking/StakeForm.tsx | 10 ++++++++-- dapp/src/utils/forms.ts | 16 ++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/dapp/src/components/Modals/Staking/StakeForm.tsx b/dapp/src/components/Modals/Staking/StakeForm.tsx index 9ab138f24..59916670a 100644 --- a/dapp/src/components/Modals/Staking/StakeForm.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm.tsx @@ -4,6 +4,7 @@ import { ModalStep } from "../../../contexts" import FormBase, { FormBaseProps, FormValues } from "../../shared/FormBase" import { useTransactionContext, useWalletContext } from "../../../hooks" import { getErrorsObj, validateTokenAmount } from "../../../utils" +import { BITCOIN_MIN_AMOUNT } from "../../../constants" const CUSTOM_DATA = { buttonText: "Stake", @@ -18,10 +19,15 @@ const StakeFormik = withFormik< mapPropsToValues: () => ({ amount: "", }), - validate: async ({ amount }, { tokenBalance }) => { + validate: async ({ amount }, { tokenBalance, currencyType }) => { const errors: FormikErrors = {} - errors.amount = validateTokenAmount(amount, tokenBalance) + errors.amount = validateTokenAmount( + amount, + tokenBalance, + BITCOIN_MIN_AMOUNT, + currencyType ?? "bitcoin", + ) return getErrorsObj(errors) }, diff --git a/dapp/src/utils/forms.ts b/dapp/src/utils/forms.ts index 70249a13d..299322cb5 100644 --- a/dapp/src/utils/forms.ts +++ b/dapp/src/utils/forms.ts @@ -1,5 +1,6 @@ -import { BITCOIN_MIN_AMOUNT } from "../constants" -import { formatSatoshiAmount } from "./numbers" +import { CURRENCIES_BY_TYPE } from "../constants" +import { CurrencyType } from "../types" +import { formatTokenAmount } from "./numbers" const ERRORS = { REQUIRED: "Required.", @@ -16,20 +17,23 @@ export function getErrorsObj(errors: { [key in keyof T]: string }) { export function validateTokenAmount( value: string, - tokenBalance: string, + maxValue: string, + minValue: string, + currencyType: CurrencyType, ): string | undefined { if (!value) return ERRORS.REQUIRED + const { decimals } = CURRENCIES_BY_TYPE[currencyType] const valueInBI = BigInt(value) - const maxValueInBI = BigInt(tokenBalance) - const minValueInBI = BigInt(BITCOIN_MIN_AMOUNT) + const maxValueInBI = BigInt(maxValue) + const minValueInBI = BigInt(minValue) const isMaximumValueExceeded = valueInBI > maxValueInBI const isMinimumValueFulfilled = valueInBI >= minValueInBI if (isMaximumValueExceeded) return ERRORS.EXCEEDED_VALUE if (!isMinimumValueFulfilled) - return ERRORS.INSUFFICIENT_VALUE(formatSatoshiAmount(BITCOIN_MIN_AMOUNT)) + return ERRORS.INSUFFICIENT_VALUE(formatTokenAmount(minValue, decimals)) return undefined } From 147f9cc92791c410a2f13b0ba5e491452df010a6 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Tue, 2 Jan 2024 11:47:34 +0100 Subject: [PATCH 088/170] Adding tests for deployment scripts around dispatcher and maintainer --- core/test/Deployment.test.ts | 51 ++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 core/test/Deployment.test.ts diff --git a/core/test/Deployment.test.ts b/core/test/Deployment.test.ts new file mode 100644 index 000000000..5b7a311ab --- /dev/null +++ b/core/test/Deployment.test.ts @@ -0,0 +1,51 @@ +import { loadFixture } from "@nomicfoundation/hardhat-toolbox/network-helpers" +import { expect } from "chai" +import { MaxUint256 } from "ethers" + +import type { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers" +import { deployment } from "./helpers/context" +import { getNamedSigner } from "./helpers/signer" + +import type { Acre, Dispatcher, TestERC20 } from "../typechain" + +async function fixture() { + const { tbtc, acre, dispatcher } = await deployment() + const { governance, maintainer } = await getNamedSigner() + + return { acre, dispatcher, tbtc, governance, maintainer } +} + +describe("Deployment", () => { + let acre: Acre + let dispatcher: Dispatcher + let tbtc: TestERC20 + let maintainer: HardhatEthersSigner + + before(async () => { + ;({ acre, dispatcher, tbtc, maintainer } = await loadFixture(fixture)) + }) + + describe("updateDispatcher", () => { + context("when a dispatcher has been set", () => { + it("should approve max amount for the dispatcher", async () => { + const actualDispatcher = await acre.dispatcher() + const allowance = await tbtc.allowance( + await acre.getAddress(), + actualDispatcher, + ) + + expect(allowance).to.be.equal(MaxUint256) + }) + }) + }) + + describe("updateMaintainer", () => { + context("when a new maintainer has been set", () => { + it("should be set to a new maintainer address", async () => { + const actualMaintainer = await dispatcher.maintainer() + + expect(actualMaintainer).to.be.equal(await maintainer.getAddress()) + }) + }) + }) +}) From 241a50405ba8d3a2efd3856c5a404de4c6775678 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Tue, 2 Jan 2024 14:24:12 +0100 Subject: [PATCH 089/170] Extracting common code to before clause --- core/test/Dispatcher.test.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/core/test/Dispatcher.test.ts b/core/test/Dispatcher.test.ts index d7a458d43..f99664dad 100644 --- a/core/test/Dispatcher.test.ts +++ b/core/test/Dispatcher.test.ts @@ -62,11 +62,15 @@ describe("Dispatcher", () => { }) context("when caller is a governance account", () => { - it("should be able to authorize vaults", async () => { - await dispatcher.connect(governance).authorizeVault(vaultAddress1) + let tx1: ContractTransactionResponse + + beforeEach(async () => { + tx1 = await dispatcher.connect(governance).authorizeVault(vaultAddress1) await dispatcher.connect(governance).authorizeVault(vaultAddress2) await dispatcher.connect(governance).authorizeVault(vaultAddress3) + }) + it("should be able to authorize vaults", async () => { expect(await dispatcher.vaults(0)).to.equal(vaultAddress1) expect(await dispatcher.vaultsInfo(vaultAddress1)).to.be.equal(true) @@ -78,16 +82,13 @@ describe("Dispatcher", () => { }) it("should not be able to authorize the same vault twice", async () => { - await dispatcher.connect(governance).authorizeVault(vaultAddress1) await expect( dispatcher.connect(governance).authorizeVault(vaultAddress1), ).to.be.revertedWithCustomError(dispatcher, "VaultAlreadyAuthorized") }) it("should emit an event when adding a vault", async () => { - await expect( - dispatcher.connect(governance).authorizeVault(vaultAddress1), - ) + await expect(tx1) .to.emit(dispatcher, "VaultAuthorized") .withArgs(vaultAddress1) }) @@ -113,7 +114,7 @@ describe("Dispatcher", () => { }) context("when caller is a governance account", () => { - it("should be able to authorize vaults", async () => { + it("should be able to deauthorize vaults", async () => { await dispatcher.connect(governance).deauthorizeVault(vaultAddress1) // Last vault replaced the first vault in the 'vaults' array From 591447a099d98a353d057c4e3ca2c6b15be48ba8 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Tue, 2 Jan 2024 14:50:16 +0100 Subject: [PATCH 090/170] Moving depositToVault tests under Dipatcher.test.ts + smaller cleanups --- core/test/Dispatcher.test.ts | 107 +++++++++++++++++-- core/test/integration/AssetFlows.test.ts | 125 ----------------------- 2 files changed, 100 insertions(+), 132 deletions(-) delete mode 100644 core/test/integration/AssetFlows.test.ts diff --git a/core/test/Dispatcher.test.ts b/core/test/Dispatcher.test.ts index f99664dad..f4dde05a7 100644 --- a/core/test/Dispatcher.test.ts +++ b/core/test/Dispatcher.test.ts @@ -7,16 +7,17 @@ import { loadFixture, } from "@nomicfoundation/hardhat-toolbox/network-helpers" import { ZeroAddress } from "ethers" -import type { Dispatcher } from "../typechain" +import type { Dispatcher, TestERC4626, Acre, TestERC20 } from "../typechain" import { deployment } from "./helpers/context" import { getNamedSigner, getUnnamedSigner } from "./helpers/signer" +import { to1e18 } from "./utils" async function fixture() { - const { dispatcher } = await deployment() - const { governance } = await getNamedSigner() + const { tbtc, acre, dispatcher, vault } = await deployment() + const { governance, maintainer } = await getNamedSigner() const [thirdParty] = await getUnnamedSigner() - return { dispatcher, governance, thirdParty } + return { dispatcher, governance, thirdParty, maintainer, vault, tbtc, acre } } describe("Dispatcher", () => { @@ -25,20 +26,23 @@ describe("Dispatcher", () => { let dispatcher: Dispatcher let governance: HardhatEthersSigner let thirdParty: HardhatEthersSigner + let maintainer: HardhatEthersSigner + let vault: TestERC4626 + let acre: Acre + let tbtc: TestERC20 let vaultAddress1: string let vaultAddress2: string let vaultAddress3: string let vaultAddress4: string - let newMaintainer: string before(async () => { - ;({ dispatcher, governance, thirdParty } = await loadFixture(fixture)) + ;({ dispatcher, governance, thirdParty, maintainer, vault, tbtc, acre } = + await loadFixture(fixture)) vaultAddress1 = await ethers.Wallet.createRandom().getAddress() vaultAddress2 = await ethers.Wallet.createRandom().getAddress() vaultAddress3 = await ethers.Wallet.createRandom().getAddress() vaultAddress4 = await ethers.Wallet.createRandom().getAddress() - newMaintainer = await ethers.Wallet.createRandom().getAddress() }) beforeEach(async () => { @@ -158,7 +162,96 @@ describe("Dispatcher", () => { }) }) + describe("depositToVault", () => { + const assetsToAllocate = to1e18(100) + const minSharesOut = to1e18(100) + + before(async () => { + await dispatcher.connect(governance).authorizeVault(vault.getAddress()) + await tbtc.mint(await acre.getAddress(), to1e18(100000)) + }) + + context("when caller is not maintainer", () => { + it("should revert when depositing to a vault", async () => { + await expect( + dispatcher + .connect(thirdParty) + .depositToVault( + await vault.getAddress(), + assetsToAllocate, + minSharesOut, + ), + ).to.be.revertedWithCustomError(dispatcher, "NotMaintainer") + }) + }) + + context("when caller is maintainer", () => { + context("when vault is not authorized", () => { + it("should revert", async () => { + const randomAddress = await ethers.Wallet.createRandom().getAddress() + await expect( + dispatcher + .connect(maintainer) + .depositToVault(randomAddress, assetsToAllocate, minSharesOut), + ).to.be.revertedWithCustomError(dispatcher, "VaultUnauthorized") + }) + }) + + context("when the vault is authorized", () => { + let vaultAddress: string + before(async () => { + vaultAddress = await vault.getAddress() + }) + + context("when allocation is successful", () => { + let tx: ContractTransactionResponse + before(async () => { + tx = await dispatcher + .connect(maintainer) + .depositToVault(vaultAddress, assetsToAllocate, minSharesOut) + }) + + it("should be able to deposit to an authorized Vault", async () => { + expect(await tbtc.balanceOf(vault.getAddress())).to.equal( + assetsToAllocate, + ) + }) + + it("should be able to receive Vault's shares", async () => { + expect(await vault.balanceOf(acre.getAddress())).to.equal( + minSharesOut, + ) + }) + + it("should emit a DepositAllocated event", async () => { + await expect(tx) + .to.emit(dispatcher, "DepositAllocated") + .withArgs(vaultAddress, assetsToAllocate, minSharesOut) + }) + }) + + context("when allocation is not successful", () => { + const minShares = to1e18(101) + + it("should emit a MinSharesError event", async () => { + await expect( + dispatcher + .connect(maintainer) + .depositToVault(vaultAddress, assetsToAllocate, minShares), + ).to.be.revertedWithCustomError(dispatcher, "MinSharesError") + }) + }) + }) + }) + }) + describe("updateMaintainer", () => { + let newMaintainer: string + + before(async () => { + newMaintainer = await ethers.Wallet.createRandom().getAddress() + }) + context("when caller is not an owner", () => { it("should revert", async () => { await expect( diff --git a/core/test/integration/AssetFlows.test.ts b/core/test/integration/AssetFlows.test.ts deleted file mode 100644 index e8d69bbc0..000000000 --- a/core/test/integration/AssetFlows.test.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { ethers } from "hardhat" -import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers" -import { expect } from "chai" -import { - SnapshotRestorer, - takeSnapshot, - loadFixture, -} from "@nomicfoundation/hardhat-toolbox/network-helpers" -import { ContractTransactionResponse } from "ethers" -import type { Acre, Dispatcher, TestERC4626, TestERC20 } from "../../typechain" -import { deployment } from "../helpers/context" -import { getNamedSigner, getUnnamedSigner } from "../helpers/signer" -import { to1e18 } from "../utils" - -async function fixture() { - const { tbtc, acre, dispatcher, vault } = await deployment() - const { governance, maintainer } = await getNamedSigner() - const [thirdParty] = await getUnnamedSigner() - - return { acre, dispatcher, governance, thirdParty, vault, tbtc, maintainer } -} - -describe("Integration Tests - Asset Flows", () => { - let snapshot: SnapshotRestorer - - let dispatcher: Dispatcher - let acre: Acre - let vault: TestERC4626 - let tbtc: TestERC20 - let governance: HardhatEthersSigner - let thirdParty: HardhatEthersSigner - let maintainer: HardhatEthersSigner - - const tbtcToMintForAcre = to1e18(100000) - - before(async () => { - ;({ acre, dispatcher, governance, thirdParty, vault, tbtc, maintainer } = - await loadFixture(fixture)) - - await dispatcher.connect(governance).authorizeVault(vault.getAddress()) - await tbtc.mint(acre.getAddress(), tbtcToMintForAcre) - }) - - beforeEach(async () => { - snapshot = await takeSnapshot() - }) - - afterEach(async () => { - await snapshot.restore() - }) - - describe("depositToVault", () => { - const assetsToAllocate = to1e18(100) - const minSharesOut = to1e18(100) - - context("when caller is not Maintainer", () => { - it("should revert when depositing to a vault", async () => { - await expect( - dispatcher - .connect(thirdParty) - .depositToVault(vault.getAddress(), assetsToAllocate, minSharesOut), - ).to.be.revertedWithCustomError(dispatcher, "NotMaintainer") - }) - }) - - context("when caller is Maintainer", () => { - context("when vault is not authorized", () => { - it("should revert", async () => { - const randomAddress = await ethers.Wallet.createRandom().getAddress() - await expect( - dispatcher - .connect(maintainer) - .depositToVault(randomAddress, assetsToAllocate, minSharesOut), - ).to.be.revertedWithCustomError(dispatcher, "VaultUnauthorized") - }) - }) - - context("when the vault is authorized", () => { - let vaultAddress: string - before(async () => { - vaultAddress = await vault.getAddress() - }) - - context("when allocation is successfull", () => { - let tx: ContractTransactionResponse - before(async () => { - tx = await dispatcher - .connect(maintainer) - .depositToVault(vaultAddress, assetsToAllocate, minSharesOut) - }) - - it("should be able to deposit to an authorized Vault", async () => { - expect(await tbtc.balanceOf(vault.getAddress())).to.equal( - assetsToAllocate, - ) - }) - - it("should be able to receive Vault's shares", async () => { - expect(await vault.balanceOf(acre.getAddress())).to.equal( - minSharesOut, - ) - }) - - it("should emit a DepositAllocated event", async () => { - await expect(tx) - .to.emit(dispatcher, "DepositAllocated") - .withArgs(vaultAddress, assetsToAllocate, minSharesOut) - }) - }) - - context("when allocation is not successfull", () => { - const minShares = to1e18(101) - - it("should emit a MinSharesError event", async () => { - await expect( - dispatcher - .connect(maintainer) - .depositToVault(vaultAddress, assetsToAllocate, minShares), - ).to.be.revertedWithCustomError(dispatcher, "MinSharesError") - }) - }) - }) - }) - }) -}) From c697ec8448ac7bc223194befbcb4db65b2411478 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 2 Jan 2024 14:54:25 +0100 Subject: [PATCH 091/170] Create a utils function to find for currency by type --- dapp/src/components/Modals/Support/MissingAccount.tsx | 4 ++-- dapp/src/components/shared/CurrencyBalance/index.tsx | 9 ++++++--- dapp/src/components/shared/TokenBalanceInput/index.tsx | 9 ++++++--- dapp/src/utils/currency.ts | 5 +++++ dapp/src/utils/forms.ts | 4 ++-- dapp/src/utils/index.ts | 1 + 6 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 dapp/src/utils/currency.ts diff --git a/dapp/src/components/Modals/Support/MissingAccount.tsx b/dapp/src/components/Modals/Support/MissingAccount.tsx index 7b6216276..710388917 100644 --- a/dapp/src/components/Modals/Support/MissingAccount.tsx +++ b/dapp/src/components/Modals/Support/MissingAccount.tsx @@ -10,7 +10,7 @@ import { import { CurrencyType, RequestAccountParams } from "../../../types" import { TextMd } from "../../shared/Typography" import AlertWrapper from "../../shared/Alert" -import { CURRENCIES_BY_TYPE } from "../../../constants" +import { getCurrencyByType } from "../../../utils" type MissingAccountProps = { currencyType: CurrencyType @@ -23,7 +23,7 @@ export default function MissingAccount({ icon, requestAccount, }: MissingAccountProps) { - const currency = CURRENCIES_BY_TYPE[currencyType] + const currency = getCurrencyByType(currencyType) return ( <> diff --git a/dapp/src/components/shared/CurrencyBalance/index.tsx b/dapp/src/components/shared/CurrencyBalance/index.tsx index 1f307d853..d6e72f64e 100644 --- a/dapp/src/components/shared/CurrencyBalance/index.tsx +++ b/dapp/src/components/shared/CurrencyBalance/index.tsx @@ -1,8 +1,11 @@ import React, { useMemo } from "react" import { Box, useMultiStyleConfig, TextProps } from "@chakra-ui/react" -import { formatTokenAmount, numberToLocaleString } from "../../../utils" +import { + formatTokenAmount, + getCurrencyByType, + numberToLocaleString, +} from "../../../utils" import { CurrencyType } from "../../../types" -import { CURRENCIES_BY_TYPE } from "../../../constants" export type CurrencyBalanceProps = { currencyType: CurrencyType @@ -24,7 +27,7 @@ export function CurrencyBalance({ }: CurrencyBalanceProps) { const styles = useMultiStyleConfig("CurrencyBalance", { size, variant }) - const currency = CURRENCIES_BY_TYPE[currencyType] + const currency = getCurrencyByType(currencyType) const balance = useMemo(() => { const value = amount ?? 0 diff --git a/dapp/src/components/shared/TokenBalanceInput/index.tsx b/dapp/src/components/shared/TokenBalanceInput/index.tsx index 8a6536e9a..418a90fb9 100644 --- a/dapp/src/components/shared/TokenBalanceInput/index.tsx +++ b/dapp/src/components/shared/TokenBalanceInput/index.tsx @@ -12,9 +12,12 @@ import { InputRightElement, useMultiStyleConfig, } from "@chakra-ui/react" -import { fixedPointNumberToString, userAmountToBigInt } from "../../../utils" +import { + fixedPointNumberToString, + getCurrencyByType, + userAmountToBigInt, +} from "../../../utils" import { CurrencyType } from "../../../types" -import { CURRENCIES_BY_TYPE } from "../../../constants" import NumberFormatInput, { NumberFormatInputValues, } from "../NumberFormatInput" @@ -109,7 +112,7 @@ export default function TokenBalanceInput({ const valueRef = useRef(amount) const styles = useMultiStyleConfig("TokenBalanceInput", { size }) - const currency = CURRENCIES_BY_TYPE[currencyType] + const currency = getCurrencyByType(currencyType) const handleValueChange = (value: string) => { valueRef.current = value diff --git a/dapp/src/utils/currency.ts b/dapp/src/utils/currency.ts new file mode 100644 index 000000000..dd745e373 --- /dev/null +++ b/dapp/src/utils/currency.ts @@ -0,0 +1,5 @@ +import { CURRENCIES_BY_TYPE } from "../constants" +import { Currency, CurrencyType } from "../types" + +export const getCurrencyByType = (type: CurrencyType): Currency => + CURRENCIES_BY_TYPE[type] diff --git a/dapp/src/utils/forms.ts b/dapp/src/utils/forms.ts index 299322cb5..844fa5bf0 100644 --- a/dapp/src/utils/forms.ts +++ b/dapp/src/utils/forms.ts @@ -1,5 +1,5 @@ -import { CURRENCIES_BY_TYPE } from "../constants" import { CurrencyType } from "../types" +import { getCurrencyByType } from "./currency" import { formatTokenAmount } from "./numbers" const ERRORS = { @@ -23,7 +23,7 @@ export function validateTokenAmount( ): string | undefined { if (!value) return ERRORS.REQUIRED - const { decimals } = CURRENCIES_BY_TYPE[currencyType] + const { decimals } = getCurrencyByType(currencyType) const valueInBI = BigInt(value) const maxValueInBI = BigInt(maxValue) const minValueInBI = BigInt(minValue) diff --git a/dapp/src/utils/index.ts b/dapp/src/utils/index.ts index 563f2e6d1..02eaa61b8 100644 --- a/dapp/src/utils/index.ts +++ b/dapp/src/utils/index.ts @@ -1,3 +1,4 @@ export * from "./numbers" export * from "./address" export * from "./forms" +export * from "./currency" From c18d23bdbc6724a90ed460982ae66f745e3cb49c Mon Sep 17 00:00:00 2001 From: Dmitry Date: Tue, 2 Jan 2024 14:54:41 +0100 Subject: [PATCH 092/170] Reorder of the functions in Dispatcher.sol --- core/contracts/Dispatcher.sol | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/core/contracts/Dispatcher.sol b/core/contracts/Dispatcher.sol index f3937fa2e..9e2c47a64 100644 --- a/core/contracts/Dispatcher.sol +++ b/core/contracts/Dispatcher.sol @@ -94,6 +94,18 @@ contract Dispatcher is Router, Ownable { emit VaultDeauthorized(vault); } + /// @notice Updates the maintainer address. + /// @param newMaintainer Address of the new maintainer. + function updateMaintainer(address newMaintainer) external onlyOwner { + if (newMaintainer == address(0)) { + revert ZeroAddress(); + } + + maintainer = newMaintainer; + + emit MaintainerUpdated(maintainer); + } + /// TODO: make this function internal once the allocation distribution is /// implemented /// @notice Routes tBTC from Acre to a vault. Can be called by the maintainer @@ -124,18 +136,6 @@ contract Dispatcher is Router, Ownable { emit DepositAllocated(vault, amount, sharesOut); } - /// @notice Updates the maintainer address. - /// @param newMaintainer Address of the new maintainer. - function updateMaintainer(address newMaintainer) external onlyOwner { - if (newMaintainer == address(0)) { - revert ZeroAddress(); - } - - maintainer = newMaintainer; - - emit MaintainerUpdated(maintainer); - } - /// @notice Returns the list of authorized vaults. function getVaults() external view returns (address[] memory) { return vaults; From 9e6c63009d1413d72c77fd7c7b8c7011fa73e488 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Tue, 2 Jan 2024 15:10:07 +0100 Subject: [PATCH 093/170] Adding withArgs checks for CustomErrors validations --- core/test/Acre.test.ts | 6 +++--- core/test/Dispatcher.test.ts | 24 +++++++++++++++--------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 29f9b2292..3e9d8a0c7 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -823,9 +823,9 @@ describe("Acre", () => { describe("updateDispatcher", () => { context("when caller is not an owner", () => { it("should revert", async () => { - await expect( - acre.connect(staker1).updateDispatcher(ZeroAddress), - ).to.be.revertedWithCustomError(acre, "OwnableUnauthorizedAccount") + await expect(acre.connect(staker1).updateDispatcher(ZeroAddress)) + .to.be.revertedWithCustomError(acre, "OwnableUnauthorizedAccount") + .withArgs(staker1.address) }) }) diff --git a/core/test/Dispatcher.test.ts b/core/test/Dispatcher.test.ts index f4dde05a7..99d3247cb 100644 --- a/core/test/Dispatcher.test.ts +++ b/core/test/Dispatcher.test.ts @@ -58,10 +58,12 @@ describe("Dispatcher", () => { it("should revert when adding a vault", async () => { await expect( dispatcher.connect(thirdParty).authorizeVault(vaultAddress1), - ).to.be.revertedWithCustomError( - dispatcher, - "OwnableUnauthorizedAccount", ) + .to.be.revertedWithCustomError( + dispatcher, + "OwnableUnauthorizedAccount", + ) + .withArgs(thirdParty.address) }) }) @@ -110,10 +112,12 @@ describe("Dispatcher", () => { it("should revert when adding a vault", async () => { await expect( dispatcher.connect(thirdParty).deauthorizeVault(vaultAddress1), - ).to.be.revertedWithCustomError( - dispatcher, - "OwnableUnauthorizedAccount", ) + .to.be.revertedWithCustomError( + dispatcher, + "OwnableUnauthorizedAccount", + ) + .withArgs(thirdParty.address) }) }) @@ -256,10 +260,12 @@ describe("Dispatcher", () => { it("should revert", async () => { await expect( dispatcher.connect(thirdParty).updateMaintainer(newMaintainer), - ).to.be.revertedWithCustomError( - dispatcher, - "OwnableUnauthorizedAccount", ) + .to.be.revertedWithCustomError( + dispatcher, + "OwnableUnauthorizedAccount", + ) + .withArgs(thirdParty.address) }) }) From 998407678780832f722d33abaf0b1709472dda63 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 2 Jan 2024 17:14:03 +0100 Subject: [PATCH 094/170] Make the token amount form component clearer --- .../components/Modals/Staking/StakeForm.tsx | 35 +++------------ .../TransactionDetails.tsx | 0 .../{FormBase => TokenAmountForm}/index.tsx | 45 ++++++++++++++++--- 3 files changed, 44 insertions(+), 36 deletions(-) rename dapp/src/components/shared/{FormBase => TokenAmountForm}/TransactionDetails.tsx (100%) rename dapp/src/components/shared/{FormBase => TokenAmountForm}/index.tsx (52%) diff --git a/dapp/src/components/Modals/Staking/StakeForm.tsx b/dapp/src/components/Modals/Staking/StakeForm.tsx index 59916670a..40e05ea2f 100644 --- a/dapp/src/components/Modals/Staking/StakeForm.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm.tsx @@ -1,9 +1,9 @@ import React, { useCallback } from "react" -import { FormikErrors, withFormik } from "formik" import { ModalStep } from "../../../contexts" -import FormBase, { FormBaseProps, FormValues } from "../../shared/FormBase" +import TokenAmountForm, { + TokenAmountFormValues, +} from "../../shared/TokenAmountForm" import { useTransactionContext, useWalletContext } from "../../../hooks" -import { getErrorsObj, validateTokenAmount } from "../../../utils" import { BITCOIN_MIN_AMOUNT } from "../../../constants" const CUSTOM_DATA = { @@ -12,36 +12,12 @@ const CUSTOM_DATA = { estimatedAmountText: "Approximately staked tokens", } -const StakeFormik = withFormik< - { onSubmitForm: (values: FormValues) => void } & FormBaseProps, - FormValues ->({ - mapPropsToValues: () => ({ - amount: "", - }), - validate: async ({ amount }, { tokenBalance, currencyType }) => { - const errors: FormikErrors = {} - - errors.amount = validateTokenAmount( - amount, - tokenBalance, - BITCOIN_MIN_AMOUNT, - currencyType ?? "bitcoin", - ) - - return getErrorsObj(errors) - }, - handleSubmit: (values, { props }) => { - props.onSubmitForm(values) - }, -})(FormBase) - function StakeForm({ goNext }: ModalStep) { const { btcAccount } = useWalletContext() const { setAmount } = useTransactionContext() const handleSubmitForm = useCallback( - (values: FormValues) => { + (values: TokenAmountFormValues) => { setAmount(values.amount) goNext() }, @@ -49,9 +25,10 @@ function StakeForm({ goNext }: ModalStep) { ) return ( - ) diff --git a/dapp/src/components/shared/FormBase/TransactionDetails.tsx b/dapp/src/components/shared/TokenAmountForm/TransactionDetails.tsx similarity index 100% rename from dapp/src/components/shared/FormBase/TransactionDetails.tsx rename to dapp/src/components/shared/TokenAmountForm/TransactionDetails.tsx diff --git a/dapp/src/components/shared/FormBase/index.tsx b/dapp/src/components/shared/TokenAmountForm/index.tsx similarity index 52% rename from dapp/src/components/shared/FormBase/index.tsx rename to dapp/src/components/shared/TokenAmountForm/index.tsx index 371278b2a..7cede79dd 100644 --- a/dapp/src/components/shared/FormBase/index.tsx +++ b/dapp/src/components/shared/TokenAmountForm/index.tsx @@ -1,15 +1,15 @@ import React from "react" import { Button } from "@chakra-ui/react" -import { FormikProps } from "formik" +import { FormikProps, FormikErrors, withFormik } from "formik" import { Form, FormTokenBalanceInput } from "../Form" import { CurrencyType } from "../../../types" import TransactionDetails from "./TransactionDetails" +import { getErrorsObj, validateTokenAmount } from "../../../utils" -export type FormValues = { +export type TokenAmountFormValues = { amount: string } - -export type FormBaseProps = { +type TokenAmountFormBaseProps = { customData: { buttonText: string btcAmountText: string @@ -22,7 +22,7 @@ export type FormBaseProps = { children?: React.ReactNode } -function FormBase({ +function TokenAmountFormBase({ customData, tokenBalance, tokenBalanceInputPlaceholder = "BTC", @@ -30,7 +30,7 @@ function FormBase({ fieldName = "amount", children, ...formikProps -}: FormBaseProps & FormikProps) { +}: TokenAmountFormBaseProps & FormikProps) { return (
void + minTokenAmount: string +} & TokenAmountFormBaseProps + +const TokenAmountForm = withFormik( + { + mapPropsToValues: () => ({ + amount: "", + }), + validate: async ( + { amount }, + { tokenBalance, currencyType, minTokenAmount }, + ) => { + const errors: FormikErrors = {} + + errors.amount = validateTokenAmount( + amount, + tokenBalance, + minTokenAmount, + currencyType ?? "bitcoin", + ) + + return getErrorsObj(errors) + }, + handleSubmit: (values, { props }) => { + props.onSubmitForm(values) + }, + }, +)(TokenAmountFormBase) + +export default TokenAmountForm From 4399b2c2f89d3f4dec420ab5d7eeba033887c101 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 3 Jan 2024 08:47:06 +0100 Subject: [PATCH 095/170] Simplify the ActionForm component --- dapp/src/components/Modals/ActionForm/index.tsx | 12 ++++-------- dapp/src/components/Modals/Staking/index.tsx | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/dapp/src/components/Modals/ActionForm/index.tsx b/dapp/src/components/Modals/ActionForm/index.tsx index bacb4de49..c108da36e 100644 --- a/dapp/src/components/Modals/ActionForm/index.tsx +++ b/dapp/src/components/Modals/ActionForm/index.tsx @@ -12,18 +12,14 @@ import StakeForm from "../Staking/StakeForm" const TABS = ["stake", "unstake"] as const -type FormType = (typeof TABS)[number] +type Action = (typeof TABS)[number] -type ActionFormProps = { defaultForm: FormType } & ModalStep +type ActionFormProps = { action: Action } & ModalStep -function ActionForm({ defaultForm, goNext }: ActionFormProps) { +function ActionForm({ action, goNext }: ActionFormProps) { return ( - + {TABS.map((tab) => ( diff --git a/dapp/src/components/Modals/Staking/index.tsx b/dapp/src/components/Modals/Staking/index.tsx index eb0b09387..24b51bb12 100644 --- a/dapp/src/components/Modals/Staking/index.tsx +++ b/dapp/src/components/Modals/Staking/index.tsx @@ -9,7 +9,7 @@ function StakingSteps() { switch (activeStep) { case 1: - return + return case 2: return default: From 8c8d2a18155a4b4a12ebfeb829d1762ececab5ba Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 3 Jan 2024 11:00:04 +0100 Subject: [PATCH 096/170] Store the amount as bigint for the token amount form --- .../components/Modals/Staking/StakeForm.tsx | 13 +++++++++---- .../shared/TokenAmountForm/index.tsx | 10 +++++----- .../shared/TokenBalanceInput/index.tsx | 10 +++++----- dapp/src/contexts/TransactionContext.tsx | 19 +++++++++++-------- dapp/src/types/index.ts | 1 + dapp/src/types/staking.ts | 6 ++++++ dapp/src/utils/forms.ts | 9 ++++----- 7 files changed, 41 insertions(+), 27 deletions(-) create mode 100644 dapp/src/types/staking.ts diff --git a/dapp/src/components/Modals/Staking/StakeForm.tsx b/dapp/src/components/Modals/Staking/StakeForm.tsx index 40e05ea2f..4055fedb5 100644 --- a/dapp/src/components/Modals/Staking/StakeForm.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm.tsx @@ -5,7 +5,9 @@ import TokenAmountForm, { } from "../../shared/TokenAmountForm" import { useTransactionContext, useWalletContext } from "../../../hooks" import { BITCOIN_MIN_AMOUNT } from "../../../constants" +import { CurrencyType } from "../../../types" +const CURRENCY_TYPE: CurrencyType = "bitcoin" const CUSTOM_DATA = { buttonText: "Stake", btcAmountText: "Amount to be staked", @@ -14,18 +16,21 @@ const CUSTOM_DATA = { function StakeForm({ goNext }: ModalStep) { const { btcAccount } = useWalletContext() - const { setAmount } = useTransactionContext() + const { seTokenAmount } = useTransactionContext() const handleSubmitForm = useCallback( (values: TokenAmountFormValues) => { - setAmount(values.amount) - goNext() + if (values.amount) { + seTokenAmount({ amount: values.amount, currencyType: CURRENCY_TYPE }) + goNext() + } }, - [goNext, setAmount], + [goNext, seTokenAmount], ) return ( ( { mapPropsToValues: () => ({ - amount: "", + amount: undefined, }), validate: async ( { amount }, @@ -72,7 +72,7 @@ const TokenAmountForm = withFormik( amount, tokenBalance, minTokenAmount, - currencyType ?? "bitcoin", + currencyType, ) return getErrorsObj(errors) diff --git a/dapp/src/components/shared/TokenBalanceInput/index.tsx b/dapp/src/components/shared/TokenBalanceInput/index.tsx index 418a90fb9..23b66f35c 100644 --- a/dapp/src/components/shared/TokenBalanceInput/index.tsx +++ b/dapp/src/components/shared/TokenBalanceInput/index.tsx @@ -85,12 +85,12 @@ function FiatCurrencyBalance({ } export type TokenBalanceInputProps = { - amount?: string + amount?: bigint currencyType: CurrencyType tokenBalance: string | number placeholder?: string size?: "lg" | "md" - setAmount: (value?: string) => void + setAmount: (value?: bigint) => void } & InputProps & HelperErrorTextProps & FiatCurrencyBalanceProps @@ -109,14 +109,14 @@ export default function TokenBalanceInput({ fiatCurrencyType, ...inputProps }: TokenBalanceInputProps) { - const valueRef = useRef(amount) + const valueRef = useRef(amount) const styles = useMultiStyleConfig("TokenBalanceInput", { size }) const currency = getCurrencyByType(currencyType) const handleValueChange = (value: string) => { valueRef.current = value - ? userAmountToBigInt(value, currency.decimals)?.toString() + ? userAmountToBigInt(value, currency.decimals) : undefined } @@ -157,7 +157,7 @@ export default function TokenBalanceInput({ }} /> - diff --git a/dapp/src/contexts/TransactionContext.tsx b/dapp/src/contexts/TransactionContext.tsx index c61c84a7d..b0f92ac6c 100644 --- a/dapp/src/contexts/TransactionContext.tsx +++ b/dapp/src/contexts/TransactionContext.tsx @@ -1,13 +1,14 @@ import React, { createContext, useMemo, useState } from "react" +import { TokenAmount } from "../types" type TransactionContextValue = { - amount?: string - setAmount: React.Dispatch> + tokenAmount?: TokenAmount + seTokenAmount: React.Dispatch> } export const TransactionContext = createContext({ - amount: undefined, - setAmount: () => {}, + tokenAmount: undefined, + seTokenAmount: () => {}, }) export function TransactionContextProvider({ @@ -15,15 +16,17 @@ export function TransactionContextProvider({ }: { children: React.ReactNode }): React.ReactElement { - const [amount, setAmount] = useState(undefined) + const [tokenAmount, seTokenAmount] = useState( + undefined, + ) const contextValue: TransactionContextValue = useMemo( () => ({ - amount, - setAmount, + tokenAmount, + seTokenAmount, }), - [amount], + [tokenAmount], ) return ( diff --git a/dapp/src/types/index.ts b/dapp/src/types/index.ts index 1e77e81e7..32b259c7f 100644 --- a/dapp/src/types/index.ts +++ b/dapp/src/types/index.ts @@ -1,2 +1,3 @@ export * from "./ledger-live-app" export * from "./currency" +export * from "./staking" diff --git a/dapp/src/types/staking.ts b/dapp/src/types/staking.ts new file mode 100644 index 000000000..f3d2d902b --- /dev/null +++ b/dapp/src/types/staking.ts @@ -0,0 +1,6 @@ +import { CurrencyType } from "./currency" + +export type TokenAmount = { + amount: bigint + currencyType: CurrencyType +} diff --git a/dapp/src/utils/forms.ts b/dapp/src/utils/forms.ts index 844fa5bf0..eb5d947da 100644 --- a/dapp/src/utils/forms.ts +++ b/dapp/src/utils/forms.ts @@ -16,20 +16,19 @@ export function getErrorsObj(errors: { [key in keyof T]: string }) { } export function validateTokenAmount( - value: string, + value: bigint | undefined, maxValue: string, minValue: string, currencyType: CurrencyType, ): string | undefined { - if (!value) return ERRORS.REQUIRED + if (value === undefined) return ERRORS.REQUIRED const { decimals } = getCurrencyByType(currencyType) - const valueInBI = BigInt(value) const maxValueInBI = BigInt(maxValue) const minValueInBI = BigInt(minValue) - const isMaximumValueExceeded = valueInBI > maxValueInBI - const isMinimumValueFulfilled = valueInBI >= minValueInBI + const isMaximumValueExceeded = value > maxValueInBI + const isMinimumValueFulfilled = value >= minValueInBI if (isMaximumValueExceeded) return ERRORS.EXCEEDED_VALUE if (!isMinimumValueFulfilled) From 6f42e4cfd19d64ef77db45bcc22e28ab90c8896b Mon Sep 17 00:00:00 2001 From: ioay Date: Tue, 2 Jan 2024 18:11:56 +0100 Subject: [PATCH 097/170] DApp: updated doc url in readme.md --- dapp/README.md | 2 +- dapp/yarn.lock | 4045 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 4046 insertions(+), 1 deletion(-) create mode 100644 dapp/yarn.lock diff --git a/dapp/README.md b/dapp/README.md index 3d3772d00..7fb03a1ef 100644 --- a/dapp/README.md +++ b/dapp/README.md @@ -23,4 +23,4 @@ Once the build is running, you can import the manifest on desktop: Click on Browse next to **Add a local app** and select the manifest file. The app is now visible in the menu. -If you have any problems, take a look [here](https://developers.ledger.com/docs/discover/developer-mode). +If you have any problems, take a look [here](https://developers.ledger.com/APIs/wallet-api/examples/use-live-app/import). diff --git a/dapp/yarn.lock b/dapp/yarn.lock new file mode 100644 index 000000000..816c6cc09 --- /dev/null +++ b/dapp/yarn.lock @@ -0,0 +1,4045 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" + integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== + dependencies: + "@babel/highlight" "^7.23.4" + chalk "^2.4.2" + +"@babel/compat-data@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" + integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== + +"@babel/core@^7.23.5": + version "7.23.7" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.7.tgz#4d8016e06a14b5f92530a13ed0561730b5c6483f" + integrity sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.23.7" + "@babel/parser" "^7.23.6" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.7" + "@babel/types" "^7.23.6" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e" + integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== + dependencies: + "@babel/types" "^7.23.6" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" + integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== + dependencies: + "@babel/compat-data" "^7.23.5" + "@babel/helper-validator-option" "^7.23.5" + browserslist "^4.22.2" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + +"@babel/helper-module-transforms@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" + integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + +"@babel/helper-plugin-utils@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" + integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/helper-validator-option@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" + integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== + +"@babel/helpers@^7.23.7": + version "7.23.7" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.7.tgz#eb543c36f81da2873e47b76ee032343ac83bba60" + integrity sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ== + dependencies: + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.7" + "@babel/types" "^7.23.6" + +"@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.6.tgz#ba1c9e512bda72a47e285ae42aff9d2a635a9e3b" + integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ== + +"@babel/plugin-transform-react-jsx-self@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz#ed3e7dadde046cce761a8e3cf003a13d1a7972d9" + integrity sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-react-jsx-source@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz#03527006bdc8775247a78643c51d4e715fe39a3e" + integrity sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.23.2": + version "7.23.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.7.tgz#dd7c88deeb218a0f8bd34d5db1aa242e0f203193" + integrity sha512-w06OXVOFso7LcbzMiDGt+3X7Rh7Ho8MmgPoWU3rarH+8upf+wSU/grlGbWzQyr3DkdN6ZeuMFjpdwW0Q+HxobA== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/template@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + +"@babel/traverse@^7.23.7": + version "7.23.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.7.tgz#9a7bf285c928cb99b5ead19c3b1ce5b310c9c305" + integrity sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.6" + "@babel/types" "^7.23.6" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.6.tgz#be33fdb151e1f5a56877d704492c240fc71c7ccd" + integrity sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + +"@chakra-ui/accordion@2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/accordion/-/accordion-2.3.1.tgz#a326509e286a5c4e8478de9bc2b4b05017039e6b" + integrity sha512-FSXRm8iClFyU+gVaXisOSEw0/4Q+qZbFRiuhIAkVU6Boj0FxAMrlo9a8AV5TuF77rgaHytCdHk0Ng+cyUijrag== + dependencies: + "@chakra-ui/descendant" "3.1.0" + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-use-controllable-state" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/transition" "2.1.0" + +"@chakra-ui/alert@2.2.2": + version "2.2.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/alert/-/alert-2.2.2.tgz#aeba951d120c7c6e69d5f515a695ad6e4db43ffe" + integrity sha512-jHg4LYMRNOJH830ViLuicjb3F+v6iriE/2G5T+Sd0Hna04nukNJ1MxUmBPE+vI22me2dIflfelu2v9wdB6Pojw== + dependencies: + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/spinner" "2.1.0" + +"@chakra-ui/anatomy@2.2.2": + version "2.2.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/anatomy/-/anatomy-2.2.2.tgz#2d0e14cba2534d92077ca28abf8c183b6e27897b" + integrity sha512-MV6D4VLRIHr4PkW4zMyqfrNS1mPlCTiCXwvYGtDFQYr+xHFfonhAuf9WjsSc0nyp2m0OdkSLnzmVKkZFLo25Tg== + +"@chakra-ui/avatar@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/avatar/-/avatar-2.3.0.tgz#f018a2714d1e3ba5970bcf66558887925fdfccf4" + integrity sha512-8gKSyLfygnaotbJbDMHDiJoF38OHXUYVme4gGxZ1fLnQEdPVEaIWfH+NndIjOM0z8S+YEFnT9KyGMUtvPrBk3g== + dependencies: + "@chakra-ui/image" "2.1.0" + "@chakra-ui/react-children-utils" "2.0.6" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/breadcrumb@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/breadcrumb/-/breadcrumb-2.2.0.tgz#751bc48498f3c403f97b5d9aae528ebfd405ef48" + integrity sha512-4cWCG24flYBxjruRi4RJREWTGF74L/KzI2CognAW/d/zWR0CjiScuJhf37Am3LFbCySP6WSoyBOtTIoTA4yLEA== + dependencies: + "@chakra-ui/react-children-utils" "2.0.6" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/breakpoint-utils@2.0.8": + version "2.0.8" + resolved "https://registry.yarnpkg.com/@chakra-ui/breakpoint-utils/-/breakpoint-utils-2.0.8.tgz#750d3712668b69f6e8917b45915cee0e08688eed" + integrity sha512-Pq32MlEX9fwb5j5xx8s18zJMARNHlQZH2VH1RZgfgRDpp7DcEgtRW5AInfN5CfqdHLO1dGxA7I3MqEuL5JnIsA== + dependencies: + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/button@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/button/-/button-2.1.0.tgz#623ed32cc92fc8e52492923e9924791fc6f25447" + integrity sha512-95CplwlRKmmUXkdEp/21VkEWgnwcx2TOBG6NfYlsuLBDHSLlo5FKIiE2oSi4zXc4TLcopGcWPNcm/NDaSC5pvA== + dependencies: + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/spinner" "2.1.0" + +"@chakra-ui/card@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/card/-/card-2.2.0.tgz#b5e59dc51c171fced76ea76bf26088803b8bc184" + integrity sha512-xUB/k5MURj4CtPAhdSoXZidUbm8j3hci9vnc+eZJVDqhDOShNlD6QeniQNRPRys4lWAQLCbFcrwL29C8naDi6g== + dependencies: + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/checkbox@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/checkbox/-/checkbox-2.3.2.tgz#4ecb14a2f57b7470d1a58542ca4691c3b105bfa1" + integrity sha512-85g38JIXMEv6M+AcyIGLh7igNtfpAN6KGQFYxY9tBj0eWvWk4NKQxvqqyVta0bSAyIl1rixNIIezNpNWk2iO4g== + dependencies: + "@chakra-ui/form-control" "2.2.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-callback-ref" "2.1.0" + "@chakra-ui/react-use-controllable-state" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + "@chakra-ui/react-use-update-effect" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/visually-hidden" "2.2.0" + "@zag-js/focus-visible" "0.16.0" + +"@chakra-ui/clickable@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/clickable/-/clickable-2.1.0.tgz#800fa8d10cf45a41fc50a3df32c679a3ce1921c3" + integrity sha512-flRA/ClPUGPYabu+/GLREZVZr9j2uyyazCAUHAdrTUEdDYCr31SVGhgh7dgKdtq23bOvAQJpIJjw/0Bs0WvbXw== + dependencies: + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/close-button@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/close-button/-/close-button-2.1.1.tgz#995b245c56eb41465a71d8667840c238618a7b66" + integrity sha512-gnpENKOanKexswSVpVz7ojZEALl2x5qjLYNqSQGbxz+aP9sOXPfUS56ebyBrre7T7exuWGiFeRwnM0oVeGPaiw== + dependencies: + "@chakra-ui/icon" "3.2.0" + +"@chakra-ui/color-mode@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/color-mode/-/color-mode-2.2.0.tgz#828d47234c74ba2fb4c5dd63a63331aead20b9f6" + integrity sha512-niTEA8PALtMWRI9wJ4LL0CSBDo8NBfLNp4GD6/0hstcm3IlbBHTVKxN6HwSaoNYfphDQLxCjT4yG+0BJA5tFpg== + dependencies: + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + +"@chakra-ui/control-box@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/control-box/-/control-box-2.1.0.tgz#0f4586797b3154c02463bc5c106782e70c88f04f" + integrity sha512-gVrRDyXFdMd8E7rulL0SKeoljkLQiPITFnsyMO8EFHNZ+AHt5wK4LIguYVEq88APqAGZGfHFWXr79RYrNiE3Mg== + +"@chakra-ui/counter@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/counter/-/counter-2.1.0.tgz#e413a2f1093a18f847bb7aa240117fde788a59e6" + integrity sha512-s6hZAEcWT5zzjNz2JIWUBzRubo9la/oof1W7EKZVVfPYHERnl5e16FmBC79Yfq8p09LQ+aqFKm/etYoJMMgghw== + dependencies: + "@chakra-ui/number-utils" "2.0.7" + "@chakra-ui/react-use-callback-ref" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/css-reset@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/css-reset/-/css-reset-2.3.0.tgz#83e3160a9c2a12431cad0ee27ebfbf3aedc5c9c7" + integrity sha512-cQwwBy5O0jzvl0K7PLTLgp8ijqLPKyuEMiDXwYzl95seD3AoeuoCLyzZcJtVqaUZ573PiBdAbY/IlZcwDOItWg== + +"@chakra-ui/descendant@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/descendant/-/descendant-3.1.0.tgz#f3b80ed13ffc4bf1d615b3ed5541bd0905375cca" + integrity sha512-VxCIAir08g5w27klLyi7PVo8BxhW4tgU/lxQyujkmi4zx7hT9ZdrcQLAted/dAa+aSIZ14S1oV0Q9lGjsAdxUQ== + dependencies: + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + +"@chakra-ui/dom-utils@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/dom-utils/-/dom-utils-2.1.0.tgz#d15df89e458ef19756db04c7cfd084eb552454f0" + integrity sha512-ZmF2qRa1QZ0CMLU8M1zCfmw29DmPNtfjR9iTo74U5FPr3i1aoAh7fbJ4qAlZ197Xw9eAW28tvzQuoVWeL5C7fQ== + +"@chakra-ui/editable@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/editable/-/editable-3.1.0.tgz#065783c2e3389c3bb9ab0582cb50d38e1dc00fa1" + integrity sha512-j2JLrUL9wgg4YA6jLlbU88370eCRyor7DZQD9lzpY95tSOXpTljeg3uF9eOmDnCs6fxp3zDWIfkgMm/ExhcGTg== + dependencies: + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-callback-ref" "2.1.0" + "@chakra-ui/react-use-controllable-state" "2.1.0" + "@chakra-ui/react-use-focus-on-pointer-down" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + "@chakra-ui/react-use-update-effect" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/event-utils@2.0.8": + version "2.0.8" + resolved "https://registry.yarnpkg.com/@chakra-ui/event-utils/-/event-utils-2.0.8.tgz#e6439ba200825a2f15d8f1973d267d1c00a6d1b4" + integrity sha512-IGM/yGUHS+8TOQrZGpAKOJl/xGBrmRYJrmbHfUE7zrG3PpQyXvbLDP1M+RggkCFVgHlJi2wpYIf0QtQlU0XZfw== + +"@chakra-ui/focus-lock@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/focus-lock/-/focus-lock-2.1.0.tgz#580e5450fe85356987b9a246abaff8333369c667" + integrity sha512-EmGx4PhWGjm4dpjRqM4Aa+rCWBxP+Rq8Uc/nAVnD4YVqkEhBkrPTpui2lnjsuxqNaZ24fIAZ10cF1hlpemte/w== + dependencies: + "@chakra-ui/dom-utils" "2.1.0" + react-focus-lock "^2.9.4" + +"@chakra-ui/form-control@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/form-control/-/form-control-2.2.0.tgz#69c771d6406ddac8ab357ae88446cc11827656a4" + integrity sha512-wehLC1t4fafCVJ2RvJQT2jyqsAwX7KymmiGqBu7nQoQz8ApTkGABWpo/QwDh3F/dBLrouHDoOvGmYTqft3Mirw== + dependencies: + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/hooks@2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/hooks/-/hooks-2.2.1.tgz#b86ce5eeaaab877ddcb11a50842d1227306ace28" + integrity sha512-RQbTnzl6b1tBjbDPf9zGRo9rf/pQMholsOudTxjy4i9GfTfz6kgp5ValGjQm2z7ng6Z31N1cnjZ1AlSzQ//ZfQ== + dependencies: + "@chakra-ui/react-utils" "2.0.12" + "@chakra-ui/utils" "2.0.15" + compute-scroll-into-view "3.0.3" + copy-to-clipboard "3.3.3" + +"@chakra-ui/icon@3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/icon/-/icon-3.2.0.tgz#92b9454aa0d561b4994bcd6a1b3bb1fdd5c67bef" + integrity sha512-xxjGLvlX2Ys4H0iHrI16t74rG9EBcpFvJ3Y3B7KMQTrnW34Kf7Da/UC8J67Gtx85mTHW020ml85SVPKORWNNKQ== + dependencies: + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/image@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/image/-/image-2.1.0.tgz#6c205f1ca148e3bf58345b0b5d4eb3d959eb9f87" + integrity sha512-bskumBYKLiLMySIWDGcz0+D9Th0jPvmX6xnRMs4o92tT3Od/bW26lahmV2a2Op2ItXeCmRMY+XxJH5Gy1i46VA== + dependencies: + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/input@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/input/-/input-2.1.2.tgz#0cad49ec372f8f21f2f4f1db365f34b9a708ff9d" + integrity sha512-GiBbb3EqAA8Ph43yGa6Mc+kUPjh4Spmxp1Pkelr8qtudpc3p2PJOOebLpd90mcqw8UePPa+l6YhhPtp6o0irhw== + dependencies: + "@chakra-ui/form-control" "2.2.0" + "@chakra-ui/object-utils" "2.1.0" + "@chakra-ui/react-children-utils" "2.0.6" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/layout@2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/layout/-/layout-2.3.1.tgz#0601c5eb91555d24a7015a7c9d4e01fed2698557" + integrity sha512-nXuZ6WRbq0WdgnRgLw+QuxWAHuhDtVX8ElWqcTK+cSMFg/52eVP47czYBE5F35YhnoW2XBwfNoNgZ7+e8Z01Rg== + dependencies: + "@chakra-ui/breakpoint-utils" "2.0.8" + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/object-utils" "2.1.0" + "@chakra-ui/react-children-utils" "2.0.6" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/lazy-utils@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@chakra-ui/lazy-utils/-/lazy-utils-2.0.5.tgz#363c3fa1d421362790b416ffa595acb835e1ae5b" + integrity sha512-UULqw7FBvcckQk2n3iPO56TMJvDsNv0FKZI6PlUNJVaGsPbsYxK/8IQ60vZgaTVPtVcjY6BE+y6zg8u9HOqpyg== + +"@chakra-ui/live-region@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/live-region/-/live-region-2.1.0.tgz#02b4b1d997075f19a7a9a87187e08c72e82ef0dd" + integrity sha512-ZOxFXwtaLIsXjqnszYYrVuswBhnIHHP+XIgK1vC6DePKtyK590Wg+0J0slDwThUAd4MSSIUa/nNX84x1GMphWw== + +"@chakra-ui/media-query@3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/media-query/-/media-query-3.3.0.tgz#40f9151dedb6a7af9df3be0474b59a799c92c619" + integrity sha512-IsTGgFLoICVoPRp9ykOgqmdMotJG0CnPsKvGQeSFOB/dZfIujdVb14TYxDU4+MURXry1MhJ7LzZhv+Ml7cr8/g== + dependencies: + "@chakra-ui/breakpoint-utils" "2.0.8" + "@chakra-ui/react-env" "3.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/menu@2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/menu/-/menu-2.2.1.tgz#7d9810d435f6b40fa72ed867a33b88a1ef75073f" + integrity sha512-lJS7XEObzJxsOwWQh7yfG4H8FzFPRP5hVPN/CL+JzytEINCSBvsCDHrYPQGp7jzpCi8vnTqQQGQe0f8dwnXd2g== + dependencies: + "@chakra-ui/clickable" "2.1.0" + "@chakra-ui/descendant" "3.1.0" + "@chakra-ui/lazy-utils" "2.0.5" + "@chakra-ui/popper" "3.1.0" + "@chakra-ui/react-children-utils" "2.0.6" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-use-animation-state" "2.1.0" + "@chakra-ui/react-use-controllable-state" "2.1.0" + "@chakra-ui/react-use-disclosure" "2.1.0" + "@chakra-ui/react-use-focus-effect" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/react-use-outside-click" "2.2.0" + "@chakra-ui/react-use-update-effect" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/transition" "2.1.0" + +"@chakra-ui/modal@2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/modal/-/modal-2.3.1.tgz#524dc32b6b4f545b54ae531dbf6c74e1052ee794" + integrity sha512-TQv1ZaiJMZN+rR9DK0snx/OPwmtaGH1HbZtlYt4W4s6CzyK541fxLRTjIXfEzIGpvNW+b6VFuFjbcR78p4DEoQ== + dependencies: + "@chakra-ui/close-button" "2.1.1" + "@chakra-ui/focus-lock" "2.1.0" + "@chakra-ui/portal" "2.1.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/transition" "2.1.0" + aria-hidden "^1.2.3" + react-remove-scroll "^2.5.6" + +"@chakra-ui/number-input@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/number-input/-/number-input-2.1.2.tgz#dda9095fba6a4b89212332db02831b94120da163" + integrity sha512-pfOdX02sqUN0qC2ysuvgVDiws7xZ20XDIlcNhva55Jgm095xjm8eVdIBfNm3SFbSUNxyXvLTW/YQanX74tKmuA== + dependencies: + "@chakra-ui/counter" "2.1.0" + "@chakra-ui/form-control" "2.2.0" + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-callback-ref" "2.1.0" + "@chakra-ui/react-use-event-listener" "2.1.0" + "@chakra-ui/react-use-interval" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + "@chakra-ui/react-use-update-effect" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/number-utils@2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@chakra-ui/number-utils/-/number-utils-2.0.7.tgz#aaee979ca2fb1923a0373a91619473811315db11" + integrity sha512-yOGxBjXNvLTBvQyhMDqGU0Oj26s91mbAlqKHiuw737AXHt0aPllOthVUqQMeaYLwLCjGMg0jtI7JReRzyi94Dg== + +"@chakra-ui/object-utils@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/object-utils/-/object-utils-2.1.0.tgz#a4ecf9cea92f1de09f5531f53ffdc41e0b19b6c3" + integrity sha512-tgIZOgLHaoti5PYGPTwK3t/cqtcycW0owaiOXoZOcpwwX/vlVb+H1jFsQyWiiwQVPt9RkoSLtxzXamx+aHH+bQ== + +"@chakra-ui/pin-input@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/pin-input/-/pin-input-2.1.0.tgz#61e6bbf909ec510634307b2861c4f1891a9f8d81" + integrity sha512-x4vBqLStDxJFMt+jdAHHS8jbh294O53CPQJoL4g228P513rHylV/uPscYUHrVJXRxsHfRztQO9k45jjTYaPRMw== + dependencies: + "@chakra-ui/descendant" "3.1.0" + "@chakra-ui/react-children-utils" "2.0.6" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-use-controllable-state" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/popover@2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/popover/-/popover-2.2.1.tgz#89cfd29817abcd204da570073c0f2b4d8072c3a3" + integrity sha512-K+2ai2dD0ljvJnlrzesCDT9mNzLifE3noGKZ3QwLqd/K34Ym1W/0aL1ERSynrcG78NKoXS54SdEzkhCZ4Gn/Zg== + dependencies: + "@chakra-ui/close-button" "2.1.1" + "@chakra-ui/lazy-utils" "2.0.5" + "@chakra-ui/popper" "3.1.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-animation-state" "2.1.0" + "@chakra-ui/react-use-disclosure" "2.1.0" + "@chakra-ui/react-use-focus-effect" "2.1.0" + "@chakra-ui/react-use-focus-on-pointer-down" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/popper@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/popper/-/popper-3.1.0.tgz#92a9180c6894763af3b22a6003f9a9d958fe2659" + integrity sha512-ciDdpdYbeFG7og6/6J8lkTFxsSvwTdMLFkpVylAF6VNC22jssiWfquj2eyD4rJnzkRFPvIWJq8hvbfhsm+AjSg== + dependencies: + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@popperjs/core" "^2.9.3" + +"@chakra-ui/portal@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/portal/-/portal-2.1.0.tgz#9e7f57424d7041738b6563cac80134561080bd27" + integrity sha512-9q9KWf6SArEcIq1gGofNcFPSWEyl+MfJjEUg/un1SMlQjaROOh3zYr+6JAwvcORiX7tyHosnmWC3d3wI2aPSQg== + dependencies: + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + +"@chakra-ui/progress@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/progress/-/progress-2.2.0.tgz#67444ea9779631d7c8395b2c9c78e5634f994999" + integrity sha512-qUXuKbuhN60EzDD9mHR7B67D7p/ZqNS2Aze4Pbl1qGGZfulPW0PY8Rof32qDtttDQBkzQIzFGE8d9QpAemToIQ== + dependencies: + "@chakra-ui/react-context" "2.1.0" + +"@chakra-ui/provider@2.4.2": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/provider/-/provider-2.4.2.tgz#92cb10b6a7df0720e3fa62716dc7cd872ae3ea3d" + integrity sha512-w0Tef5ZCJK1mlJorcSjItCSbyvVuqpvyWdxZiVQmE6fvSJR83wZof42ux0+sfWD+I7rHSfj+f9nzhNaEWClysw== + dependencies: + "@chakra-ui/css-reset" "2.3.0" + "@chakra-ui/portal" "2.1.0" + "@chakra-ui/react-env" "3.1.0" + "@chakra-ui/system" "2.6.2" + "@chakra-ui/utils" "2.0.15" + +"@chakra-ui/radio@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/radio/-/radio-2.1.2.tgz#66db19c61a2e628aaf5e727027f7c3b4006ea898" + integrity sha512-n10M46wJrMGbonaghvSRnZ9ToTv/q76Szz284gv4QUWvyljQACcGrXIONUnQ3BIwbOfkRqSk7Xl/JgZtVfll+w== + dependencies: + "@chakra-ui/form-control" "2.2.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + "@zag-js/focus-visible" "0.16.0" + +"@chakra-ui/react-children-utils@2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-children-utils/-/react-children-utils-2.0.6.tgz#6c480c6a60678fcb75cb7d57107c7a79e5179b92" + integrity sha512-QVR2RC7QsOsbWwEnq9YduhpqSFnZGvjjGREV8ygKi8ADhXh93C8azLECCUVgRJF2Wc+So1fgxmjLcbZfY2VmBA== + +"@chakra-ui/react-context@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-context/-/react-context-2.1.0.tgz#4858be1d5ff1c8ac0a0ec088d93a3b7f1cbbff99" + integrity sha512-iahyStvzQ4AOwKwdPReLGfDesGG+vWJfEsn0X/NoGph/SkN+HXtv2sCfYFFR9k7bb+Kvc6YfpLlSuLvKMHi2+w== + +"@chakra-ui/react-env@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-env/-/react-env-3.1.0.tgz#7d3c1c05a501bb369524d9f3d38c9325eb16ab50" + integrity sha512-Vr96GV2LNBth3+IKzr/rq1IcnkXv+MLmwjQH6C8BRtn3sNskgDFD5vLkVXcEhagzZMCh8FR3V/bzZPojBOyNhw== + dependencies: + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + +"@chakra-ui/react-types@2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-types/-/react-types-2.0.7.tgz#799c166a44882b23059c8f510eac9bd5d0869ac4" + integrity sha512-12zv2qIZ8EHwiytggtGvo4iLT0APris7T0qaAWqzpUGS0cdUtR8W+V1BJ5Ocq+7tA6dzQ/7+w5hmXih61TuhWQ== + +"@chakra-ui/react-use-animation-state@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-animation-state/-/react-use-animation-state-2.1.0.tgz#eab661fbafd96804fe867b0df0c27e78feefe6e2" + integrity sha512-CFZkQU3gmDBwhqy0vC1ryf90BVHxVN8cTLpSyCpdmExUEtSEInSCGMydj2fvn7QXsz/za8JNdO2xxgJwxpLMtg== + dependencies: + "@chakra-ui/dom-utils" "2.1.0" + "@chakra-ui/react-use-event-listener" "2.1.0" + +"@chakra-ui/react-use-callback-ref@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-callback-ref/-/react-use-callback-ref-2.1.0.tgz#a508085f4d9e7d84d4ceffdf5f41745c9ac451d7" + integrity sha512-efnJrBtGDa4YaxDzDE90EnKD3Vkh5a1t3w7PhnRQmsphLy3g2UieasoKTlT2Hn118TwDjIv5ZjHJW6HbzXA9wQ== + +"@chakra-ui/react-use-controllable-state@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-controllable-state/-/react-use-controllable-state-2.1.0.tgz#8fb6fa2f45d0c04173582ae8297e604ffdb9c7d9" + integrity sha512-QR/8fKNokxZUs4PfxjXuwl0fj/d71WPrmLJvEpCTkHjnzu7LnYvzoe2wB867IdooQJL0G1zBxl0Dq+6W1P3jpg== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.1.0" + +"@chakra-ui/react-use-disclosure@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-disclosure/-/react-use-disclosure-2.1.0.tgz#90093eaf45db1bea7a6851dd0ce5cdb3eb66f90a" + integrity sha512-Ax4pmxA9LBGMyEZJhhUZobg9C0t3qFE4jVF1tGBsrLDcdBeLR9fwOogIPY9Hf0/wqSlAryAimICbr5hkpa5GSw== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.1.0" + +"@chakra-ui/react-use-event-listener@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-event-listener/-/react-use-event-listener-2.1.0.tgz#afea2645bd9b38f754fc2b8eb858f9bb22385ded" + integrity sha512-U5greryDLS8ISP69DKDsYcsXRtAdnTQT+jjIlRYZ49K/XhUR/AqVZCK5BkR1spTDmO9H8SPhgeNKI70ODuDU/Q== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.1.0" + +"@chakra-ui/react-use-focus-effect@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-focus-effect/-/react-use-focus-effect-2.1.0.tgz#963fb790370dfadd51d12666ff2da60706f53a2a" + integrity sha512-xzVboNy7J64xveLcxTIJ3jv+lUJKDwRM7Szwn9tNzUIPD94O3qwjV7DDCUzN2490nSYDF4OBMt/wuDBtaR3kUQ== + dependencies: + "@chakra-ui/dom-utils" "2.1.0" + "@chakra-ui/react-use-event-listener" "2.1.0" + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + "@chakra-ui/react-use-update-effect" "2.1.0" + +"@chakra-ui/react-use-focus-on-pointer-down@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-focus-on-pointer-down/-/react-use-focus-on-pointer-down-2.1.0.tgz#2fbcf6bc7d06d97606747e231a908d5c387ca0cc" + integrity sha512-2jzrUZ+aiCG/cfanrolsnSMDykCAbv9EK/4iUyZno6BYb3vziucmvgKuoXbMPAzWNtwUwtuMhkby8rc61Ue+Lg== + dependencies: + "@chakra-ui/react-use-event-listener" "2.1.0" + +"@chakra-ui/react-use-interval@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-interval/-/react-use-interval-2.1.0.tgz#2602c097b3ab74b6644812e4f5efaad621218d98" + integrity sha512-8iWj+I/+A0J08pgEXP1J1flcvhLBHkk0ln7ZvGIyXiEyM6XagOTJpwNhiu+Bmk59t3HoV/VyvyJTa+44sEApuw== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.1.0" + +"@chakra-ui/react-use-latest-ref@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-latest-ref/-/react-use-latest-ref-2.1.0.tgz#d1e926130102566ece1d39f8a48ed125e0c8441a" + integrity sha512-m0kxuIYqoYB0va9Z2aW4xP/5b7BzlDeWwyXCH6QpT2PpW3/281L3hLCm1G0eOUcdVlayqrQqOeD6Mglq+5/xoQ== + +"@chakra-ui/react-use-merge-refs@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-merge-refs/-/react-use-merge-refs-2.1.0.tgz#c0c233527abdbea9a1348269c192012205762314" + integrity sha512-lERa6AWF1cjEtWSGjxWTaSMvneccnAVH4V4ozh8SYiN9fSPZLlSG3kNxfNzdFvMEhM7dnP60vynF7WjGdTgQbQ== + +"@chakra-ui/react-use-outside-click@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-outside-click/-/react-use-outside-click-2.2.0.tgz#5570b772a255f6f02b69e967127397c1b5fa3d3c" + integrity sha512-PNX+s/JEaMneijbgAM4iFL+f3m1ga9+6QK0E5Yh4s8KZJQ/bLwZzdhMz8J/+mL+XEXQ5J0N8ivZN28B82N1kNw== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.1.0" + +"@chakra-ui/react-use-pan-event@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-pan-event/-/react-use-pan-event-2.1.0.tgz#51c21bc3c0e9e73d1faef5ea4f7e3c3d071a2758" + integrity sha512-xmL2qOHiXqfcj0q7ZK5s9UjTh4Gz0/gL9jcWPA6GVf+A0Od5imEDa/Vz+533yQKWiNSm1QGrIj0eJAokc7O4fg== + dependencies: + "@chakra-ui/event-utils" "2.0.8" + "@chakra-ui/react-use-latest-ref" "2.1.0" + framesync "6.1.2" + +"@chakra-ui/react-use-previous@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-previous/-/react-use-previous-2.1.0.tgz#f6046e6f7398b1e8d7e66ff7ebb8d61c92a2d3d0" + integrity sha512-pjxGwue1hX8AFcmjZ2XfrQtIJgqbTF3Qs1Dy3d1krC77dEsiCUbQ9GzOBfDc8pfd60DrB5N2tg5JyHbypqh0Sg== + +"@chakra-ui/react-use-safe-layout-effect@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-safe-layout-effect/-/react-use-safe-layout-effect-2.1.0.tgz#3a95f0ba6fd5d2d0aa14919160f2c825f13e686f" + integrity sha512-Knbrrx/bcPwVS1TorFdzrK/zWA8yuU/eaXDkNj24IrKoRlQrSBFarcgAEzlCHtzuhufP3OULPkELTzz91b0tCw== + +"@chakra-ui/react-use-size@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-size/-/react-use-size-2.1.0.tgz#fcf3070eaade8b4a84af8ce5341c4d5ca0a42bec" + integrity sha512-tbLqrQhbnqOjzTaMlYytp7wY8BW1JpL78iG7Ru1DlV4EWGiAmXFGvtnEt9HftU0NJ0aJyjgymkxfVGI55/1Z4A== + dependencies: + "@zag-js/element-size" "0.10.5" + +"@chakra-ui/react-use-timeout@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-timeout/-/react-use-timeout-2.1.0.tgz#24415f54267d7241a3c1d36a5cae4d472834cef7" + integrity sha512-cFN0sobKMM9hXUhyCofx3/Mjlzah6ADaEl/AXl5Y+GawB5rgedgAcu2ErAgarEkwvsKdP6c68CKjQ9dmTQlJxQ== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.1.0" + +"@chakra-ui/react-use-update-effect@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-update-effect/-/react-use-update-effect-2.1.0.tgz#5c57cd1f50c2a6a8119e0f57f69510723d69884b" + integrity sha512-ND4Q23tETaR2Qd3zwCKYOOS1dfssojPLJMLvUtUbW5M9uW1ejYWgGUobeAiOVfSplownG8QYMmHTP86p/v0lbA== + +"@chakra-ui/react-utils@2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-utils/-/react-utils-2.0.12.tgz#d6b773b9a5b2e51dce61f51ac8a0e9a0f534f479" + integrity sha512-GbSfVb283+YA3kA8w8xWmzbjNWk14uhNpntnipHCftBibl0lxtQ9YqMFQLwuFOO0U2gYVocszqqDWX+XNKq9hw== + dependencies: + "@chakra-ui/utils" "2.0.15" + +"@chakra-ui/react@^2.8.2": + version "2.8.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/react/-/react-2.8.2.tgz#94d692fb35e4447748c5bfd73d8d38a746193c7d" + integrity sha512-Hn0moyxxyCDKuR9ywYpqgX8dvjqwu9ArwpIb9wHNYjnODETjLwazgNIliCVBRcJvysGRiV51U2/JtJVrpeCjUQ== + dependencies: + "@chakra-ui/accordion" "2.3.1" + "@chakra-ui/alert" "2.2.2" + "@chakra-ui/avatar" "2.3.0" + "@chakra-ui/breadcrumb" "2.2.0" + "@chakra-ui/button" "2.1.0" + "@chakra-ui/card" "2.2.0" + "@chakra-ui/checkbox" "2.3.2" + "@chakra-ui/close-button" "2.1.1" + "@chakra-ui/control-box" "2.1.0" + "@chakra-ui/counter" "2.1.0" + "@chakra-ui/css-reset" "2.3.0" + "@chakra-ui/editable" "3.1.0" + "@chakra-ui/focus-lock" "2.1.0" + "@chakra-ui/form-control" "2.2.0" + "@chakra-ui/hooks" "2.2.1" + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/image" "2.1.0" + "@chakra-ui/input" "2.1.2" + "@chakra-ui/layout" "2.3.1" + "@chakra-ui/live-region" "2.1.0" + "@chakra-ui/media-query" "3.3.0" + "@chakra-ui/menu" "2.2.1" + "@chakra-ui/modal" "2.3.1" + "@chakra-ui/number-input" "2.1.2" + "@chakra-ui/pin-input" "2.1.0" + "@chakra-ui/popover" "2.2.1" + "@chakra-ui/popper" "3.1.0" + "@chakra-ui/portal" "2.1.0" + "@chakra-ui/progress" "2.2.0" + "@chakra-ui/provider" "2.4.2" + "@chakra-ui/radio" "2.1.2" + "@chakra-ui/react-env" "3.1.0" + "@chakra-ui/select" "2.1.2" + "@chakra-ui/skeleton" "2.1.0" + "@chakra-ui/skip-nav" "2.1.0" + "@chakra-ui/slider" "2.1.0" + "@chakra-ui/spinner" "2.1.0" + "@chakra-ui/stat" "2.1.1" + "@chakra-ui/stepper" "2.3.1" + "@chakra-ui/styled-system" "2.9.2" + "@chakra-ui/switch" "2.1.2" + "@chakra-ui/system" "2.6.2" + "@chakra-ui/table" "2.1.0" + "@chakra-ui/tabs" "3.0.0" + "@chakra-ui/tag" "3.1.1" + "@chakra-ui/textarea" "2.1.2" + "@chakra-ui/theme" "3.3.1" + "@chakra-ui/theme-utils" "2.0.21" + "@chakra-ui/toast" "7.0.2" + "@chakra-ui/tooltip" "2.3.1" + "@chakra-ui/transition" "2.1.0" + "@chakra-ui/utils" "2.0.15" + "@chakra-ui/visually-hidden" "2.2.0" + +"@chakra-ui/select@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/select/-/select-2.1.2.tgz#f57d6cec0559373c32094fd4a5abd32855829264" + integrity sha512-ZwCb7LqKCVLJhru3DXvKXpZ7Pbu1TDZ7N0PdQ0Zj1oyVLJyrpef1u9HR5u0amOpqcH++Ugt0f5JSmirjNlctjA== + dependencies: + "@chakra-ui/form-control" "2.2.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/shared-utils@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@chakra-ui/shared-utils/-/shared-utils-2.0.5.tgz#cb2b49705e113853647f1822142619570feba081" + integrity sha512-4/Wur0FqDov7Y0nCXl7HbHzCg4aq86h+SXdoUeuCMD3dSj7dpsVnStLYhng1vxvlbUnLpdF4oz5Myt3i/a7N3Q== + +"@chakra-ui/skeleton@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/skeleton/-/skeleton-2.1.0.tgz#e3b25dd3afa330029d6d63be0f7cb8d44ad25531" + integrity sha512-JNRuMPpdZGd6zFVKjVQ0iusu3tXAdI29n4ZENYwAJEMf/fN0l12sVeirOxkJ7oEL0yOx2AgEYFSKdbcAgfUsAQ== + dependencies: + "@chakra-ui/media-query" "3.3.0" + "@chakra-ui/react-use-previous" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/skip-nav@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/skip-nav/-/skip-nav-2.1.0.tgz#cac27eecc6eded1e83c8f0cf7445d727739cb325" + integrity sha512-Hk+FG+vadBSH0/7hwp9LJnLjkO0RPGnx7gBJWI4/SpoJf3e4tZlWYtwGj0toYY4aGKl93jVghuwGbDBEMoHDug== + +"@chakra-ui/slider@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/slider/-/slider-2.1.0.tgz#1caeed18761ba2a390777418cc9389ba25e39bce" + integrity sha512-lUOBcLMCnFZiA/s2NONXhELJh6sY5WtbRykPtclGfynqqOo47lwWJx+VP7xaeuhDOPcWSSecWc9Y1BfPOCz9cQ== + dependencies: + "@chakra-ui/number-utils" "2.0.7" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-callback-ref" "2.1.0" + "@chakra-ui/react-use-controllable-state" "2.1.0" + "@chakra-ui/react-use-latest-ref" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/react-use-pan-event" "2.1.0" + "@chakra-ui/react-use-size" "2.1.0" + "@chakra-ui/react-use-update-effect" "2.1.0" + +"@chakra-ui/spinner@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/spinner/-/spinner-2.1.0.tgz#aa24a3d692c6ac90714e0f0f82c76c12c78c8e60" + integrity sha512-hczbnoXt+MMv/d3gE+hjQhmkzLiKuoTo42YhUG7Bs9OSv2lg1fZHW1fGNRFP3wTi6OIbD044U1P9HK+AOgFH3g== + dependencies: + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/stat@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/stat/-/stat-2.1.1.tgz#a204ba915795345996a16c79794d84826d7dcc2d" + integrity sha512-LDn0d/LXQNbAn2KaR3F1zivsZCewY4Jsy1qShmfBMKwn6rI8yVlbvu6SiA3OpHS0FhxbsZxQI6HefEoIgtqY6Q== + dependencies: + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/stepper@2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/stepper/-/stepper-2.3.1.tgz#a0a0b73e147f202ab4e51cae55dad45489cc89fd" + integrity sha512-ky77lZbW60zYkSXhYz7kbItUpAQfEdycT0Q4bkHLxfqbuiGMf8OmgZOQkOB9uM4v0zPwy2HXhe0vq4Dd0xa55Q== + dependencies: + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/styled-system@2.9.2": + version "2.9.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/styled-system/-/styled-system-2.9.2.tgz#898ab63da560a4a014f7b05fa7767e8c76da6d2f" + integrity sha512-To/Z92oHpIE+4nk11uVMWqo2GGRS86coeMmjxtpnErmWRdLcp1WVCVRAvn+ZwpLiNR+reWFr2FFqJRsREuZdAg== + dependencies: + "@chakra-ui/shared-utils" "2.0.5" + csstype "^3.1.2" + lodash.mergewith "4.6.2" + +"@chakra-ui/switch@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/switch/-/switch-2.1.2.tgz#f7c6878d8126bfac8fa3b939079f1017c21b7479" + integrity sha512-pgmi/CC+E1v31FcnQhsSGjJnOE2OcND4cKPyTE+0F+bmGm48Q/b5UmKD9Y+CmZsrt/7V3h8KNczowupfuBfIHA== + dependencies: + "@chakra-ui/checkbox" "2.3.2" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/system@2.6.2": + version "2.6.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/system/-/system-2.6.2.tgz#528ec955bd6a7f74da46470ee8225b1e2c80a78b" + integrity sha512-EGtpoEjLrUu4W1fHD+a62XR+hzC5YfsWm+6lO0Kybcga3yYEij9beegO0jZgug27V+Rf7vns95VPVP6mFd/DEQ== + dependencies: + "@chakra-ui/color-mode" "2.2.0" + "@chakra-ui/object-utils" "2.1.0" + "@chakra-ui/react-utils" "2.0.12" + "@chakra-ui/styled-system" "2.9.2" + "@chakra-ui/theme-utils" "2.0.21" + "@chakra-ui/utils" "2.0.15" + react-fast-compare "3.2.2" + +"@chakra-ui/table@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/table/-/table-2.1.0.tgz#20dce14c5e4d70dc7c6c0e87cce9b05907ff8c50" + integrity sha512-o5OrjoHCh5uCLdiUb0Oc0vq9rIAeHSIRScc2ExTC9Qg/uVZl2ygLrjToCaKfaaKl1oQexIeAcZDKvPG8tVkHyQ== + dependencies: + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/tabs@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/tabs/-/tabs-3.0.0.tgz#854c06880af26158d7c72881c4b5e0453f6c485d" + integrity sha512-6Mlclp8L9lqXmsGWF5q5gmemZXOiOYuh0SGT/7PgJVNPz3LXREXlXg2an4MBUD8W5oTkduCX+3KTMCwRrVrDYw== + dependencies: + "@chakra-ui/clickable" "2.1.0" + "@chakra-ui/descendant" "3.1.0" + "@chakra-ui/lazy-utils" "2.0.5" + "@chakra-ui/react-children-utils" "2.0.6" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-use-controllable-state" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/tag@3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/tag/-/tag-3.1.1.tgz#d05284b6549a84d3a08e57eec57df3ad0eebd882" + integrity sha512-Bdel79Dv86Hnge2PKOU+t8H28nm/7Y3cKd4Kfk9k3lOpUh4+nkSGe58dhRzht59lEqa4N9waCgQiBdkydjvBXQ== + dependencies: + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/react-context" "2.1.0" + +"@chakra-ui/textarea@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/textarea/-/textarea-2.1.2.tgz#30f8af0e233cec2dee79d527450c6586e7122eff" + integrity sha512-ip7tvklVCZUb2fOHDb23qPy/Fr2mzDOGdkrpbNi50hDCiV4hFX02jdQJdi3ydHZUyVgZVBKPOJ+lT9i7sKA2wA== + dependencies: + "@chakra-ui/form-control" "2.2.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/theme-tools@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/theme-tools/-/theme-tools-2.1.2.tgz#913be05879cd816c546993ccb9ff7615f85ff69f" + integrity sha512-Qdj8ajF9kxY4gLrq7gA+Azp8CtFHGO9tWMN2wfF9aQNgG9AuMhPrUzMq9AMQ0MXiYcgNq/FD3eegB43nHVmXVA== + dependencies: + "@chakra-ui/anatomy" "2.2.2" + "@chakra-ui/shared-utils" "2.0.5" + color2k "^2.0.2" + +"@chakra-ui/theme-utils@2.0.21": + version "2.0.21" + resolved "https://registry.yarnpkg.com/@chakra-ui/theme-utils/-/theme-utils-2.0.21.tgz#da7ed541a5241a8ed0384eb14f37fa9b998382cf" + integrity sha512-FjH5LJbT794r0+VSCXB3lT4aubI24bLLRWB+CuRKHijRvsOg717bRdUN/N1fEmEpFnRVrbewttWh/OQs0EWpWw== + dependencies: + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/styled-system" "2.9.2" + "@chakra-ui/theme" "3.3.1" + lodash.mergewith "4.6.2" + +"@chakra-ui/theme@3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/theme/-/theme-3.3.1.tgz#75c6cd0b5c70c0aa955068274ee4780f299bd8a4" + integrity sha512-Hft/VaT8GYnItGCBbgWd75ICrIrIFrR7lVOhV/dQnqtfGqsVDlrztbSErvMkoPKt0UgAkd9/o44jmZ6X4U2nZQ== + dependencies: + "@chakra-ui/anatomy" "2.2.2" + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/theme-tools" "2.1.2" + +"@chakra-ui/toast@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/toast/-/toast-7.0.2.tgz#d1c396bbfced12e22b010899731fd8cc294d53ec" + integrity sha512-yvRP8jFKRs/YnkuE41BVTq9nB2v/KDRmje9u6dgDmE5+1bFt3bwjdf9gVbif4u5Ve7F7BGk5E093ARRVtvLvXA== + dependencies: + "@chakra-ui/alert" "2.2.2" + "@chakra-ui/close-button" "2.1.1" + "@chakra-ui/portal" "2.1.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-use-timeout" "2.1.0" + "@chakra-ui/react-use-update-effect" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/styled-system" "2.9.2" + "@chakra-ui/theme" "3.3.1" + +"@chakra-ui/tooltip@2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/tooltip/-/tooltip-2.3.1.tgz#29fb8508a37bb6b20ab8dbb32bca6cd59b098796" + integrity sha512-Rh39GBn/bL4kZpuEMPPRwYNnccRCL+w9OqamWHIB3Qboxs6h8cOyXfIdGxjo72lvhu1QI/a4KFqkM3St+WfC0A== + dependencies: + "@chakra-ui/dom-utils" "2.1.0" + "@chakra-ui/popper" "3.1.0" + "@chakra-ui/portal" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-disclosure" "2.1.0" + "@chakra-ui/react-use-event-listener" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/transition@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/transition/-/transition-2.1.0.tgz#c8e95564f7ab356e78119780037bae5ad150c7b3" + integrity sha512-orkT6T/Dt+/+kVwJNy7zwJ+U2xAZ3EU7M3XCs45RBvUnZDr/u9vdmaM/3D/rOpmQJWgQBwKPJleUXrYWUagEDQ== + dependencies: + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/utils@2.0.15": + version "2.0.15" + resolved "https://registry.yarnpkg.com/@chakra-ui/utils/-/utils-2.0.15.tgz#bd800b1cff30eb5a5e8c36fa039f49984b4c5e4a" + integrity sha512-El4+jL0WSaYYs+rJbuYFDbjmfCcfGDmRY95GO4xwzit6YAPZBLcR65rOEwLps+XWluZTy1xdMrusg/hW0c1aAA== + dependencies: + "@types/lodash.mergewith" "4.6.7" + css-box-model "1.2.1" + framesync "6.1.2" + lodash.mergewith "4.6.2" + +"@chakra-ui/visually-hidden@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/visually-hidden/-/visually-hidden-2.2.0.tgz#9b0ecef8f01263ab808ba3bda7b36a0d91b4d5c1" + integrity sha512-KmKDg01SrQ7VbTD3+cPWf/UfpF5MSwm3v7MWi0n5t8HnnadT13MF0MJCDSXbBWnzLv1ZKJ6zlyAOeARWX+DpjQ== + +"@emotion/babel-plugin@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c" + integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/runtime" "^7.18.3" + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/serialize" "^1.1.2" + babel-plugin-macros "^3.1.0" + convert-source-map "^1.5.0" + escape-string-regexp "^4.0.0" + find-root "^1.1.0" + source-map "^0.5.7" + stylis "4.2.0" + +"@emotion/cache@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff" + integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ== + dependencies: + "@emotion/memoize" "^0.8.1" + "@emotion/sheet" "^1.2.2" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + stylis "4.2.0" + +"@emotion/hash@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" + integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== + +"@emotion/is-prop-valid@^0.8.2": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" + integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== + dependencies: + "@emotion/memoize" "0.7.4" + +"@emotion/is-prop-valid@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" + integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw== + dependencies: + "@emotion/memoize" "^0.8.1" + +"@emotion/memoize@0.7.4": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" + integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== + +"@emotion/memoize@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" + integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== + +"@emotion/react@^11.11.1": + version "11.11.3" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.3.tgz#96b855dc40a2a55f52a72f518a41db4f69c31a25" + integrity sha512-Cnn0kuq4DoONOMcnoVsTOR8E+AdnKFf//6kUWc4LCdnxj31pZWn7rIULd6Y7/Js1PiPHzn7SKCM9vB/jBni8eA== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/cache" "^11.11.0" + "@emotion/serialize" "^1.1.3" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + hoist-non-react-statics "^3.3.1" + +"@emotion/serialize@^1.1.2", "@emotion/serialize@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.3.tgz#84b77bfcfe3b7bb47d326602f640ccfcacd5ffb0" + integrity sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA== + dependencies: + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/unitless" "^0.8.1" + "@emotion/utils" "^1.2.1" + csstype "^3.0.2" + +"@emotion/sheet@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec" + integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== + +"@emotion/styled@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.0.tgz#26b75e1b5a1b7a629d7c0a8b708fbf5a9cdce346" + integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/is-prop-valid" "^1.2.1" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + +"@emotion/unitless@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" + integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== + +"@emotion/use-insertion-effect-with-fallbacks@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963" + integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw== + +"@emotion/utils@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4" + integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg== + +"@emotion/weak-memoize@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6" + integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== + +"@esbuild/aix-ppc64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz#2acd20be6d4f0458bc8c784103495ff24f13b1d3" + integrity sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g== + +"@esbuild/android-arm64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz#b45d000017385c9051a4f03e17078abb935be220" + integrity sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q== + +"@esbuild/android-arm@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.11.tgz#f46f55414e1c3614ac682b29977792131238164c" + integrity sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw== + +"@esbuild/android-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.11.tgz#bfc01e91740b82011ef503c48f548950824922b2" + integrity sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg== + +"@esbuild/darwin-arm64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz#533fb7f5a08c37121d82c66198263dcc1bed29bf" + integrity sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ== + +"@esbuild/darwin-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz#62f3819eff7e4ddc656b7c6815a31cf9a1e7d98e" + integrity sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g== + +"@esbuild/freebsd-arm64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz#d478b4195aa3ca44160272dab85ef8baf4175b4a" + integrity sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA== + +"@esbuild/freebsd-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz#7bdcc1917409178257ca6a1a27fe06e797ec18a2" + integrity sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw== + +"@esbuild/linux-arm64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz#58ad4ff11685fcc735d7ff4ca759ab18fcfe4545" + integrity sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg== + +"@esbuild/linux-arm@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz#ce82246d873b5534d34de1e5c1b33026f35e60e3" + integrity sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q== + +"@esbuild/linux-ia32@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz#cbae1f313209affc74b80f4390c4c35c6ab83fa4" + integrity sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA== + +"@esbuild/linux-loong64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz#5f32aead1c3ec8f4cccdb7ed08b166224d4e9121" + integrity sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg== + +"@esbuild/linux-mips64el@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz#38eecf1cbb8c36a616261de858b3c10d03419af9" + integrity sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg== + +"@esbuild/linux-ppc64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz#9c5725a94e6ec15b93195e5a6afb821628afd912" + integrity sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA== + +"@esbuild/linux-riscv64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz#2dc4486d474a2a62bbe5870522a9a600e2acb916" + integrity sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ== + +"@esbuild/linux-s390x@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz#4ad8567df48f7dd4c71ec5b1753b6f37561a65a8" + integrity sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q== + +"@esbuild/linux-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz#b7390c4d5184f203ebe7ddaedf073df82a658766" + integrity sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA== + +"@esbuild/netbsd-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz#d633c09492a1721377f3bccedb2d821b911e813d" + integrity sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ== + +"@esbuild/openbsd-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz#17388c76e2f01125bf831a68c03a7ffccb65d1a2" + integrity sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw== + +"@esbuild/sunos-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz#e320636f00bb9f4fdf3a80e548cb743370d41767" + integrity sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ== + +"@esbuild/win32-arm64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz#c778b45a496e90b6fc373e2a2bb072f1441fe0ee" + integrity sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ== + +"@esbuild/win32-ia32@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz#481a65fee2e5cce74ec44823e6b09ecedcc5194c" + integrity sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg== + +"@esbuild/win32-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz#a5d300008960bb39677c46bf16f53ec70d8dee04" + integrity sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw== + +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" + integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== + +"@eslint/eslintrc@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" + integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@8.56.0": + version "8.56.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b" + integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== + +"@humanwhocodes/config-array@^0.11.13": + version "0.11.13" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" + integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ== + dependencies: + "@humanwhocodes/object-schema" "^2.0.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" + integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.20" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" + integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@ledgerhq/devices@^8.2.0": + version "8.2.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-8.2.0.tgz#ef67bf49628252d1779acaa151b1a941acba790e" + integrity sha512-XROTW2gTmmuy+YPPDjdtKKTQ3mfxrPtKtV+a9QFbj8f5MnjVMV0Zpy1BIB4CyIMsVVi4z6+nI67auT7IlsM3SQ== + dependencies: + "@ledgerhq/errors" "^6.16.1" + "@ledgerhq/logs" "^6.12.0" + rxjs "^7.8.1" + semver "^7.3.5" + +"@ledgerhq/errors@^6.14.0", "@ledgerhq/errors@^6.16.1": + version "6.16.1" + resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-6.16.1.tgz#df650a9ba105397dee2e8c0ceddf6931c5b25ede" + integrity sha512-4D4wKecGzQpIu7sx03Sg4uE1e8g1oZUndWgw9gw776H8h9ov9c5TxPaldTn2j6orPECAERViLf7LTO4L5pE2Cw== + +"@ledgerhq/hw-transport@^6.28.8": + version "6.30.1" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-6.30.1.tgz#fd3c825f41197aeaf705e3c066f82843eaf48cae" + integrity sha512-Xeeo4nt33g5Fsp3CdsPvcc2Uk7dwYeKRSlSFLWcYAAKprf/PmxgNekhke1eaNU/wLoeLOWhY2Cki8F8w9nLMdQ== + dependencies: + "@ledgerhq/devices" "^8.2.0" + "@ledgerhq/errors" "^6.16.1" + "@ledgerhq/logs" "^6.12.0" + events "^3.3.0" + +"@ledgerhq/logs@^6.12.0": + version "6.12.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/logs/-/logs-6.12.0.tgz#ad903528bf3687a44da435d7b2479d724d374f5d" + integrity sha512-ExDoj1QV5eC6TEbMdLUMMk9cfvNKhhv5gXol4SmULRVCx/3iyCPhJ74nsb3S0Vb+/f+XujBEj3vQn5+cwS0fNA== + +"@ledgerhq/wallet-api-client-react@^1.1.2": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/wallet-api-client-react/-/wallet-api-client-react-1.3.0.tgz#955bf9d163d683dfe7feb87d06ee852adf8453ef" + integrity sha512-UYNKQ1Yp/ZieqY4SGKgkoxKXJ3t0Zj/PPnZDoOrG/YbAFd4r3bL4XvTMa5T+bIdjbqITTo7VRiA9mhk5ootLrA== + dependencies: + "@ledgerhq/wallet-api-client" "1.5.0" + +"@ledgerhq/wallet-api-client@1.5.0", "@ledgerhq/wallet-api-client@^1.2.1": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/wallet-api-client/-/wallet-api-client-1.5.0.tgz#2c9cbe87c3f5c19a7e95d67d1d1c72dd1200cb12" + integrity sha512-I07RlTmHw0uia5xhHa8Z3I7yVlYkxUWPfKWruh0vM6o0hDzPddGp+oDJZlriJIIrj2eHfaUCO1bEgycewPe0jA== + dependencies: + "@ledgerhq/hw-transport" "^6.28.8" + "@ledgerhq/wallet-api-core" "1.6.0" + bignumber.js "^9.1.2" + +"@ledgerhq/wallet-api-core@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/wallet-api-core/-/wallet-api-core-1.6.0.tgz#41492a9393d432e71e25606305ec61d141ebe6b3" + integrity sha512-nVPN3yu5+5pbhfFYh0iKmij5U7KVKZfpDkusXbj4yKvueKY8ZXU1wgvw1rDhgxlqu+s7JTA50MX56doyhm46Qg== + dependencies: + "@ledgerhq/errors" "^6.14.0" + bignumber.js "^9.1.2" + uuid "^9.0.0" + zod "^3.22.2" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@pkgr/core@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.0.tgz#7d8dacb7fdef0e4387caf7396cbd77f179867d06" + integrity sha512-Zwq5OCzuwJC2jwqmpEQt7Ds1DTi6BWSwoGkbb1n9pO3hzb35BoJELx7c0T23iDkBGkh2e7tvOtjF3tr3OaQHDQ== + +"@popperjs/core@^2.9.3": + version "2.11.8" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" + integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== + +"@rollup/rollup-android-arm-eabi@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.2.tgz#ccb02257556bacbc1e756ab9b0b973cea2c7a664" + integrity sha512-RKzxFxBHq9ysZ83fn8Iduv3A283K7zPPYuhL/z9CQuyFrjwpErJx0h4aeb/bnJ+q29GRLgJpY66ceQ/Wcsn3wA== + +"@rollup/rollup-android-arm64@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.2.tgz#21bd0fbafdf442c6a17645b840f6a94556b0e9bb" + integrity sha512-yZ+MUbnwf3SHNWQKJyWh88ii2HbuHCFQnAYTeeO1Nb8SyEiWASEi5dQUygt3ClHWtA9My9RQAYkjvrsZ0WK8Xg== + +"@rollup/rollup-darwin-arm64@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.2.tgz#9f2e5d5637677f9839dbe1622130d0592179136a" + integrity sha512-vqJ/pAUh95FLc/G/3+xPqlSBgilPnauVf2EXOQCZzhZJCXDXt/5A8mH/OzU6iWhb3CNk5hPJrh8pqJUPldN5zw== + +"@rollup/rollup-darwin-x64@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.2.tgz#1b06291ff1c41af94d2786cd167188c5bf7caec9" + integrity sha512-otPHsN5LlvedOprd3SdfrRNhOahhVBwJpepVKUN58L0RnC29vOAej1vMEaVU6DadnpjivVsNTM5eNt0CcwTahw== + +"@rollup/rollup-linux-arm-gnueabihf@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.2.tgz#147069948bba00f435122f411210624e72638ebf" + integrity sha512-ewG5yJSp+zYKBYQLbd1CUA7b1lSfIdo9zJShNTyc2ZP1rcPrqyZcNlsHgs7v1zhgfdS+kW0p5frc0aVqhZCiYQ== + +"@rollup/rollup-linux-arm64-gnu@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.2.tgz#3a50f0e7ae6e444d11c61fce12783196454a4efb" + integrity sha512-pL6QtV26W52aCWTG1IuFV3FMPL1m4wbsRG+qijIvgFO/VBsiXJjDPE/uiMdHBAO6YcpV4KvpKtd0v3WFbaxBtg== + +"@rollup/rollup-linux-arm64-musl@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.2.tgz#82b5e75484d91c25d4e649d018d9523e72d6dac2" + integrity sha512-On+cc5EpOaTwPSNetHXBuqylDW+765G/oqB9xGmWU3npEhCh8xu0xqHGUA+4xwZLqBbIZNcBlKSIYfkBm6ko7g== + +"@rollup/rollup-linux-riscv64-gnu@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.2.tgz#ca96f2d43a553d73aec736e991c07010561bc7a9" + integrity sha512-Wnx/IVMSZ31D/cO9HSsU46FjrPWHqtdF8+0eyZ1zIB5a6hXaZXghUKpRrC4D5DcRTZOjml2oBhXoqfGYyXKipw== + +"@rollup/rollup-linux-x64-gnu@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.2.tgz#db1cece244ea46706c0e1a522ec19ca0173abc55" + integrity sha512-ym5x1cj4mUAMBummxxRkI4pG5Vht1QMsJexwGP8547TZ0sox9fCLDHw9KCH9c1FO5d9GopvkaJsBIOkTKxksdw== + +"@rollup/rollup-linux-x64-musl@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.2.tgz#c15b26b86827f75977bf59ebd41ce5d788713936" + integrity sha512-m0hYELHGXdYx64D6IDDg/1vOJEaiV8f1G/iO+tejvRCJNSwK4jJ15e38JQy5Q6dGkn1M/9KcyEOwqmlZ2kqaZg== + +"@rollup/rollup-win32-arm64-msvc@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.2.tgz#60152948f9fb08e8c50c1555e334ca9f9f1f53aa" + integrity sha512-x1CWburlbN5JjG+juenuNa4KdedBdXLjZMp56nHFSHTOsb/MI2DYiGzLtRGHNMyydPGffGId+VgjOMrcltOksA== + +"@rollup/rollup-win32-ia32-msvc@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.2.tgz#657288cff10311f997d8dbd648590441760ae6d9" + integrity sha512-VVzCB5yXR1QlfsH1Xw1zdzQ4Pxuzv+CPr5qpElpKhVxlxD3CRdfubAG9mJROl6/dmj5gVYDDWk8sC+j9BI9/kQ== + +"@rollup/rollup-win32-x64-msvc@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.2.tgz#830f3a3fba67f6216a5884368431918029045afe" + integrity sha512-SYRedJi+mweatroB+6TTnJYLts0L0bosg531xnQWtklOI6dezEagx4Q0qDyvRdK+qgdA3YZpjjGuPFtxBmddBA== + +"@thesis-co/eslint-config@^0.6.1": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@thesis-co/eslint-config/-/eslint-config-0.6.1.tgz#70e419cd02b271ae447eebdefaa5359dca301285" + integrity sha512-0vJCCI4UwUdniDCQeTFlMBT+bSp5pGkrtHrZrG2vmyLZwSVdJNtInjkBc/Jd0sGfMtPo3pqQRwA40Zo80lPi+Q== + dependencies: + "@thesis-co/prettier-config" "github:thesis/prettier-config" + "@typescript-eslint/eslint-plugin" ">=6.4.1" + "@typescript-eslint/parser" ">=6.4.1" + eslint-config-airbnb "^19.0.4" + eslint-config-airbnb-base "^15.0.0" + eslint-config-airbnb-typescript "^17.1.0" + eslint-config-prettier "^9.0.0" + eslint-plugin-import "^2.28.1" + eslint-plugin-jsx-a11y "^6.7.1" + eslint-plugin-no-only-tests "^3.1.0" + eslint-plugin-prettier "^5.0.0" + eslint-plugin-react "^7.33.2" + eslint-plugin-react-hooks "^4.6.0" + +"@thesis-co/prettier-config@github:thesis/prettier-config": + version "0.0.2" + resolved "https://codeload.github.com/thesis/prettier-config/tar.gz/daeaac564056a7885e4366ce12bfde6fd823fc90" + +"@types/babel__core@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.8" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.5.tgz#7b7502be0aa80cc4ef22978846b983edaafcd4dd" + integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== + dependencies: + "@babel/types" "^7.20.7" + +"@types/json-schema@^7.0.12": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + +"@types/lodash.mergewith@4.6.7": + version "4.6.7" + resolved "https://registry.yarnpkg.com/@types/lodash.mergewith/-/lodash.mergewith-4.6.7.tgz#eaa65aa5872abdd282f271eae447b115b2757212" + integrity sha512-3m+lkO5CLRRYU0fhGRp7zbsGi6+BZj0uTVSwvcKU+nSlhjA9/QRNfuSGnD2mX6hQA7ZbmcCkzk5h4ZYGOtk14A== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*": + version "4.14.202" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8" + integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ== + +"@types/parse-json@^4.0.0": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== + +"@types/prop-types@*": + version "15.7.11" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563" + integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== + +"@types/react-dom@^18.2.17": + version "18.2.18" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.18.tgz#16946e6cd43971256d874bc3d0a72074bb8571dd" + integrity sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw== + dependencies: + "@types/react" "*" + +"@types/react@*", "@types/react@^18.2.38": + version "18.2.46" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.46.tgz#f04d6c528f8f136ea66333bc66abcae46e2680df" + integrity sha512-nNCvVBcZlvX4NU1nRRNV/mFl1nNRuTuslAJglQsq+8ldXe5Xv0Wd2f7WTE3jOxhLH2BFfiZGC6GCp+kHQbgG+w== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/scheduler@*": + version "0.16.8" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" + integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== + +"@types/semver@^7.5.0": + version "7.5.6" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" + integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== + +"@typescript-eslint/eslint-plugin@>=6.4.1", "@typescript-eslint/eslint-plugin@^6.12.0": + version "6.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.17.0.tgz#dfc38f790704ba8a54a1277c51efdb489f6ecf9f" + integrity sha512-Vih/4xLXmY7V490dGwBQJTpIZxH4ZFH6eCVmQ4RFkB+wmaCTDAx4dtgoWwMNGKLkqRY1L6rPqzEbjorRnDo4rQ== + dependencies: + "@eslint-community/regexpp" "^4.5.1" + "@typescript-eslint/scope-manager" "6.17.0" + "@typescript-eslint/type-utils" "6.17.0" + "@typescript-eslint/utils" "6.17.0" + "@typescript-eslint/visitor-keys" "6.17.0" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/parser@>=6.4.1", "@typescript-eslint/parser@^6.12.0": + version "6.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.17.0.tgz#8cd7a0599888ca6056082225b2fdf9a635bf32a1" + integrity sha512-C4bBaX2orvhK+LlwrY8oWGmSl4WolCfYm513gEccdWZj0CwGadbIADb0FtVEcI+WzUyjyoBj2JRP8g25E6IB8A== + dependencies: + "@typescript-eslint/scope-manager" "6.17.0" + "@typescript-eslint/types" "6.17.0" + "@typescript-eslint/typescript-estree" "6.17.0" + "@typescript-eslint/visitor-keys" "6.17.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@6.17.0": + version "6.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.17.0.tgz#70e6c1334d0d76562dfa61aed9009c140a7601b4" + integrity sha512-RX7a8lwgOi7am0k17NUO0+ZmMOX4PpjLtLRgLmT1d3lBYdWH4ssBUbwdmc5pdRX8rXon8v9x8vaoOSpkHfcXGA== + dependencies: + "@typescript-eslint/types" "6.17.0" + "@typescript-eslint/visitor-keys" "6.17.0" + +"@typescript-eslint/type-utils@6.17.0": + version "6.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.17.0.tgz#5febad3f523e393006614cbda28b826925b728d5" + integrity sha512-hDXcWmnbtn4P2B37ka3nil3yi3VCQO2QEB9gBiHJmQp5wmyQWqnjA85+ZcE8c4FqnaB6lBwMrPkgd4aBYz3iNg== + dependencies: + "@typescript-eslint/typescript-estree" "6.17.0" + "@typescript-eslint/utils" "6.17.0" + debug "^4.3.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/types@6.17.0": + version "6.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.17.0.tgz#844a92eb7c527110bf9a7d177e3f22bd5a2f40cb" + integrity sha512-qRKs9tvc3a4RBcL/9PXtKSehI/q8wuU9xYJxe97WFxnzH8NWWtcW3ffNS+EWg8uPvIerhjsEZ+rHtDqOCiH57A== + +"@typescript-eslint/typescript-estree@6.17.0": + version "6.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.17.0.tgz#b913d19886c52d8dc3db856903a36c6c64fd62aa" + integrity sha512-gVQe+SLdNPfjlJn5VNGhlOhrXz4cajwFd5kAgWtZ9dCZf4XJf8xmgCTLIqec7aha3JwgLI2CK6GY1043FRxZwg== + dependencies: + "@typescript-eslint/types" "6.17.0" + "@typescript-eslint/visitor-keys" "6.17.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "9.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/utils@6.17.0": + version "6.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.17.0.tgz#f2b16d4c9984474656c420438cdede7eccd4079e" + integrity sha512-LofsSPjN/ITNkzV47hxas2JCsNCEnGhVvocfyOcLzT9c/tSZE7SfhS/iWtzP1lKNOEfLhRTZz6xqI8N2RzweSQ== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.17.0" + "@typescript-eslint/types" "6.17.0" + "@typescript-eslint/typescript-estree" "6.17.0" + semver "^7.5.4" + +"@typescript-eslint/visitor-keys@6.17.0": + version "6.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.17.0.tgz#3ed043709c39b43ec1e58694f329e0b0430c26b6" + integrity sha512-H6VwB/k3IuIeQOyYczyyKN8wH6ed8EwliaYHLxOIhyF0dYEIsN8+Bk3GE19qafeMKyZJJHP8+O1HiFhFLUNKSg== + dependencies: + "@typescript-eslint/types" "6.17.0" + eslint-visitor-keys "^3.4.1" + +"@ungap/structured-clone@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + +"@vitejs/plugin-react@^4.2.0": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.2.1.tgz#744d8e4fcb120fc3dbaa471dadd3483f5a304bb9" + integrity sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ== + dependencies: + "@babel/core" "^7.23.5" + "@babel/plugin-transform-react-jsx-self" "^7.23.3" + "@babel/plugin-transform-react-jsx-source" "^7.23.3" + "@types/babel__core" "^7.20.5" + react-refresh "^0.14.0" + +"@zag-js/dom-query@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@zag-js/dom-query/-/dom-query-0.16.0.tgz#bca46bcd78f78c900064478646d95f9781ed098e" + integrity sha512-Oqhd6+biWyKnhKwFFuZrrf6lxBz2tX2pRQe6grUnYwO6HJ8BcbqZomy2lpOdr+3itlaUqx+Ywj5E5ZZDr/LBfQ== + +"@zag-js/element-size@0.10.5": + version "0.10.5" + resolved "https://registry.yarnpkg.com/@zag-js/element-size/-/element-size-0.10.5.tgz#a24bad2eeb7e2c8709e32be5336e158e1a1a174f" + integrity sha512-uQre5IidULANvVkNOBQ1tfgwTQcGl4hliPSe69Fct1VfYb2Fd0jdAcGzqQgPhfrXFpR62MxLPB7erxJ/ngtL8w== + +"@zag-js/focus-visible@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@zag-js/focus-visible/-/focus-visible-0.16.0.tgz#c9e53e3dbab0f2649d04a489bb379f5800f4f069" + integrity sha512-a7U/HSopvQbrDU4GLerpqiMcHKEkQkNPeDZJWz38cw/6Upunh41GjHetq5TB84hxyCaDzJ6q2nEdNoBQfC0FKA== + dependencies: + "@zag-js/dom-query" "0.16.0" + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn@^8.9.0: + version "8.11.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== + +ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +aria-hidden@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.3.tgz#14aeb7fb692bbb72d69bebfa47279c1fd725e954" + integrity sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ== + dependencies: + tslib "^2.0.0" + +aria-query@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" + integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== + dependencies: + dequal "^2.0.3" + +array-buffer-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" + integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== + dependencies: + call-bind "^1.0.2" + is-array-buffer "^3.0.1" + +array-includes@^3.1.6, array-includes@^3.1.7: + version "3.1.7" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" + integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + is-string "^1.0.7" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array.prototype.findlastindex@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207" + integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.2.1" + +array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" + integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +array.prototype.flatmap@^1.3.1, array.prototype.flatmap@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" + integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +array.prototype.tosorted@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz#620eff7442503d66c799d95503f82b475745cefd" + integrity sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.2.1" + +arraybuffer.prototype.slice@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" + integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + +ast-types-flow@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6" + integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== + +asynciterator.prototype@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz#8c5df0514936cdd133604dfcc9d3fb93f09b2b62" + integrity sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg== + dependencies: + has-symbols "^1.0.3" + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +axe-core@=4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" + integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== + +axobject-query@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" + integrity sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg== + dependencies: + dequal "^2.0.3" + +babel-plugin-macros@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" + integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== + dependencies: + "@babel/runtime" "^7.12.5" + cosmiconfig "^7.0.0" + resolve "^1.19.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +bignumber.js@^9.1.2: + version "9.1.2" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" + integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.22.2: + version "4.22.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.2.tgz#704c4943072bd81ea18997f3bd2180e89c77874b" + integrity sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A== + dependencies: + caniuse-lite "^1.0.30001565" + electron-to-chromium "^1.4.601" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" + +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== + dependencies: + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +caniuse-lite@^1.0.30001565: + version "1.0.30001572" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001572.tgz#1ccf7dc92d2ee2f92ed3a54e11b7b4a3041acfa0" + integrity sha512-1Pbh5FLmn5y4+QhNyJE9j3/7dK44dGB83/ZMjv/qJk86TvDbjk0LosiZo0i0WB0Vx607qMX9jYrn1VLHCkN4rw== + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color2k@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/color2k/-/color2k-2.0.3.tgz#a771244f6b6285541c82aa65ff0a0c624046e533" + integrity sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog== + +compute-scroll-into-view@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-3.0.3.tgz#c418900a5c56e2b04b885b54995df164535962b1" + integrity sha512-nadqwNxghAGTamwIqQSG433W6OADZx2vCo3UXHNrzTRHK/htu+7+L0zhjEoaeaQVNAi3YgqWDv8+tzf0hRfR+A== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +confusing-browser-globals@^1.0.10: + version "1.0.11" + resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" + integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== + +convert-source-map@^1.5.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +copy-to-clipboard@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0" + integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== + dependencies: + toggle-selection "^1.0.6" + +cosmiconfig@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-box-model@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/css-box-model/-/css-box-model-1.2.1.tgz#59951d3b81fd6b2074a62d49444415b0d2b4d7c1" + integrity sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw== + dependencies: + tiny-invariant "^1.0.6" + +csstype@^3.0.2, csstype@^3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + +damerau-levenshtein@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" + integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +define-data-property@^1.0.1, define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== + dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +dequal@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + +detect-node-es@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493" + integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +electron-to-chromium@^1.4.601: + version "1.4.616" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz#4bddbc2c76e1e9dbf449ecd5da3d8119826ea4fb" + integrity sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.22.1: + version "1.22.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" + integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== + dependencies: + array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.2" + available-typed-arrays "^1.0.5" + call-bind "^1.0.5" + es-set-tostringtag "^2.0.1" + es-to-primitive "^1.2.1" + function.prototype.name "^1.1.6" + get-intrinsic "^1.2.2" + get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + internal-slot "^1.0.5" + is-array-buffer "^3.0.2" + is-callable "^1.2.7" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-typed-array "^1.1.12" + is-weakref "^1.0.2" + object-inspect "^1.13.1" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.1" + safe-array-concat "^1.0.1" + safe-regex-test "^1.0.0" + string.prototype.trim "^1.2.8" + string.prototype.trimend "^1.0.7" + string.prototype.trimstart "^1.0.7" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" + typed-array-byte-offset "^1.0.0" + typed-array-length "^1.0.4" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.13" + +es-iterator-helpers@^1.0.12, es-iterator-helpers@^1.0.15: + version "1.0.15" + resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz#bd81d275ac766431d19305923707c3efd9f1ae40" + integrity sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g== + dependencies: + asynciterator.prototype "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.1" + es-abstract "^1.22.1" + es-set-tostringtag "^2.0.1" + function-bind "^1.1.1" + get-intrinsic "^1.2.1" + globalthis "^1.0.3" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + internal-slot "^1.0.5" + iterator.prototype "^1.1.2" + safe-array-concat "^1.0.1" + +es-set-tostringtag@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" + integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== + dependencies: + get-intrinsic "^1.2.2" + has-tostringtag "^1.0.0" + hasown "^2.0.0" + +es-shim-unscopables@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" + integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== + dependencies: + hasown "^2.0.0" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +esbuild@^0.19.3: + version "0.19.11" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.11.tgz#4a02dca031e768b5556606e1b468fe72e3325d96" + integrity sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA== + optionalDependencies: + "@esbuild/aix-ppc64" "0.19.11" + "@esbuild/android-arm" "0.19.11" + "@esbuild/android-arm64" "0.19.11" + "@esbuild/android-x64" "0.19.11" + "@esbuild/darwin-arm64" "0.19.11" + "@esbuild/darwin-x64" "0.19.11" + "@esbuild/freebsd-arm64" "0.19.11" + "@esbuild/freebsd-x64" "0.19.11" + "@esbuild/linux-arm" "0.19.11" + "@esbuild/linux-arm64" "0.19.11" + "@esbuild/linux-ia32" "0.19.11" + "@esbuild/linux-loong64" "0.19.11" + "@esbuild/linux-mips64el" "0.19.11" + "@esbuild/linux-ppc64" "0.19.11" + "@esbuild/linux-riscv64" "0.19.11" + "@esbuild/linux-s390x" "0.19.11" + "@esbuild/linux-x64" "0.19.11" + "@esbuild/netbsd-x64" "0.19.11" + "@esbuild/openbsd-x64" "0.19.11" + "@esbuild/sunos-x64" "0.19.11" + "@esbuild/win32-arm64" "0.19.11" + "@esbuild/win32-ia32" "0.19.11" + "@esbuild/win32-x64" "0.19.11" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-airbnb-base@^15.0.0: + version "15.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz#6b09add90ac79c2f8d723a2580e07f3925afd236" + integrity sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig== + dependencies: + confusing-browser-globals "^1.0.10" + object.assign "^4.1.2" + object.entries "^1.1.5" + semver "^6.3.0" + +eslint-config-airbnb-typescript@^17.1.0: + version "17.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-17.1.0.tgz#fda960eee4a510f092a9a1c139035ac588937ddc" + integrity sha512-GPxI5URre6dDpJ0CtcthSZVBAfI+Uw7un5OYNVxP2EYi3H81Jw701yFP7AU+/vCE7xBtFmjge7kfhhk4+RAiig== + dependencies: + eslint-config-airbnb-base "^15.0.0" + +eslint-config-airbnb@^19.0.4: + version "19.0.4" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz#84d4c3490ad70a0ffa571138ebcdea6ab085fdc3" + integrity sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew== + dependencies: + eslint-config-airbnb-base "^15.0.0" + object.assign "^4.1.2" + object.entries "^1.1.5" + +eslint-config-prettier@^9.0.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f" + integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== + +eslint-import-resolver-node@^0.3.9: + version "0.3.9" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" + integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== + dependencies: + debug "^3.2.7" + is-core-module "^2.13.0" + resolve "^1.22.4" + +eslint-module-utils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" + integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== + dependencies: + debug "^3.2.7" + +eslint-plugin-import@^2.28.1: + version "2.29.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" + integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== + dependencies: + array-includes "^3.1.7" + array.prototype.findlastindex "^1.2.3" + array.prototype.flat "^1.3.2" + array.prototype.flatmap "^1.3.2" + debug "^3.2.7" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.9" + eslint-module-utils "^2.8.0" + hasown "^2.0.0" + is-core-module "^2.13.1" + is-glob "^4.0.3" + minimatch "^3.1.2" + object.fromentries "^2.0.7" + object.groupby "^1.0.1" + object.values "^1.1.7" + semver "^6.3.1" + tsconfig-paths "^3.15.0" + +eslint-plugin-jsx-a11y@^6.7.1: + version "6.8.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz#2fa9c701d44fcd722b7c771ec322432857fcbad2" + integrity sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA== + dependencies: + "@babel/runtime" "^7.23.2" + aria-query "^5.3.0" + array-includes "^3.1.7" + array.prototype.flatmap "^1.3.2" + ast-types-flow "^0.0.8" + axe-core "=4.7.0" + axobject-query "^3.2.1" + damerau-levenshtein "^1.0.8" + emoji-regex "^9.2.2" + es-iterator-helpers "^1.0.15" + hasown "^2.0.0" + jsx-ast-utils "^3.3.5" + language-tags "^1.0.9" + minimatch "^3.1.2" + object.entries "^1.1.7" + object.fromentries "^2.0.7" + +eslint-plugin-no-only-tests@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.1.0.tgz#f38e4935c6c6c4842bf158b64aaa20c366fe171b" + integrity sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw== + +eslint-plugin-prettier@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.2.tgz#584c94d4bf31329b2d4cbeb10fd600d17d6de742" + integrity sha512-dhlpWc9vOwohcWmClFcA+HjlvUpuyynYs0Rf+L/P6/0iQE6vlHW9l5bkfzN62/Stm9fbq8ku46qzde76T1xlSg== + dependencies: + prettier-linter-helpers "^1.0.0" + synckit "^0.8.6" + +eslint-plugin-react-hooks@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" + integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== + +eslint-plugin-react@^7.33.2: + version "7.33.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz#69ee09443ffc583927eafe86ffebb470ee737608" + integrity sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw== + dependencies: + array-includes "^3.1.6" + array.prototype.flatmap "^1.3.1" + array.prototype.tosorted "^1.1.1" + doctrine "^2.1.0" + es-iterator-helpers "^1.0.12" + estraverse "^5.3.0" + jsx-ast-utils "^2.4.1 || ^3.0.0" + minimatch "^3.1.2" + object.entries "^1.1.6" + object.fromentries "^2.0.6" + object.hasown "^1.1.2" + object.values "^1.1.6" + prop-types "^15.8.1" + resolve "^2.0.0-next.4" + semver "^6.3.1" + string.prototype.matchall "^4.0.8" + +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint@^8.54.0: + version "8.56.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.56.0.tgz#4957ce8da409dc0809f99ab07a1b94832ab74b15" + integrity sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.4" + "@eslint/js" "8.56.0" + "@humanwhocodes/config-array" "^0.11.13" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + "@ungap/structured-clone" "^1.2.0" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== + dependencies: + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +events@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + +fast-glob@^3.2.9: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastq@^1.6.0: + version "1.16.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.16.0.tgz#83b9a9375692db77a822df081edb6a9cf6839320" + integrity sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA== + dependencies: + reusify "^1.0.4" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== + dependencies: + flatted "^3.2.9" + keyv "^4.5.3" + rimraf "^3.0.2" + +flatted@^3.2.9: + version "3.2.9" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" + integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== + +focus-lock@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-1.0.0.tgz#2c50d8ce59d3d6608cda2672be9e65812459206c" + integrity sha512-a8Ge6cdKh9za/GZR/qtigTAk7SrGore56EFcoMshClsh7FLk1zwszc/ltuMfKhx56qeuyL/jWQ4J4axou0iJ9w== + dependencies: + tslib "^2.0.3" + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +framer-motion@^10.16.5: + version "10.16.16" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-10.16.16.tgz#a10a03e1190a717109163cfff212a84c8ad11b0c" + integrity sha512-je6j91rd7NmUX7L1XHouwJ4v3R+SO4umso2LUcgOct3rHZ0PajZ80ETYZTajzEXEl9DlKyzjyt4AvGQ+lrebOw== + dependencies: + tslib "^2.4.0" + optionalDependencies: + "@emotion/is-prop-valid" "^0.8.2" + +framesync@6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/framesync/-/framesync-6.1.2.tgz#755eff2fb5b8f3b4d2b266dd18121b300aefea27" + integrity sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g== + dependencies: + tslib "2.4.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.1, function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +function.prototype.name@^1.1.5, function.prototype.name@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" + integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + functions-have-names "^1.2.3" + +functions-have-names@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== + dependencies: + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-nonce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" + integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^13.19.0: + version "13.24.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" + integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== + dependencies: + type-fest "^0.20.2" + +globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== + dependencies: + get-intrinsic "^1.2.2" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + +hoist-non-react-statics@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + +ignore@^5.2.0, ignore@^5.2.4: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" + integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +internal-slot@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" + integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== + dependencies: + get-intrinsic "^1.2.2" + hasown "^2.0.0" + side-channel "^1.0.4" + +invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + is-typed-array "^1.1.10" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-async-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.0.0.tgz#8e4418efd3e5d3a6ebb0164c05ef5afb69aa9646" + integrity sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA== + dependencies: + has-tostringtag "^1.0.0" + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-core-module@^2.13.0, is-core-module@^2.13.1: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.0.0" + +is-date-object@^1.0.1, is-date-object@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-finalizationregistry@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz#c8749b65f17c133313e661b1289b95ad3dbd62e6" + integrity sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw== + dependencies: + call-bind "^1.0.2" + +is-generator-function@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-map@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + +is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-set@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: + version "1.1.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== + dependencies: + which-typed-array "^1.1.11" + +is-weakmap@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" + integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== + +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + +is-weakset@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" + integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +iterator.prototype@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.2.tgz#5e29c8924f01916cb9335f1ff80619dcff22b0c0" + integrity sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w== + dependencies: + define-properties "^1.2.1" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + reflect.getprototypeof "^1.0.4" + set-function-name "^2.0.1" + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json5@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== + dependencies: + minimist "^1.2.0" + +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: + version "3.3.5" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" + integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== + dependencies: + array-includes "^3.1.6" + array.prototype.flat "^1.3.1" + object.assign "^4.1.4" + object.values "^1.1.6" + +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + +language-subtag-registry@^0.3.20: + version "0.3.22" + resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" + integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== + +language-tags@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.9.tgz#1ffdcd0ec0fafb4b1be7f8b11f306ad0f9c08777" + integrity sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA== + dependencies: + language-subtag-registry "^0.3.20" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.mergewith@4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" + integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +minimatch@9.0.3: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.13.1, object-inspect@^1.9.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.2, object.assign@^4.1.4: + version "4.1.5" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" + integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== + dependencies: + call-bind "^1.0.5" + define-properties "^1.2.1" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.entries@^1.1.5, object.entries@^1.1.6, object.entries@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.7.tgz#2b47760e2a2e3a752f39dd874655c61a7f03c131" + integrity sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +object.fromentries@^2.0.6, object.fromentries@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" + integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +object.groupby@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" + integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + +object.hasown@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.3.tgz#6a5f2897bb4d3668b8e79364f98ccf971bda55ae" + integrity sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA== + dependencies: + define-properties "^1.2.0" + es-abstract "^1.22.1" + +object.values@^1.1.6, object.values@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" + integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +postcss@^8.4.32: + version "8.4.32" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.32.tgz#1dac6ac51ab19adb21b8b34fd2d93a86440ef6c9" + integrity sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.1.1.tgz#6ba9f23165d690b6cbdaa88cb0807278f7019848" + integrity sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw== + +prop-types@^15.6.2, prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +react-clientside-effect@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz#29f9b14e944a376b03fb650eed2a754dd128ea3a" + integrity sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg== + dependencies: + "@babel/runtime" "^7.12.13" + +react-dom@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.0" + +react-fast-compare@3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" + integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== + +react-focus-lock@^2.9.4: + version "2.9.6" + resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.9.6.tgz#cad168a150fdd72d5ab2419ba8e62780788011b1" + integrity sha512-B7gYnCjHNrNYwY2juS71dHbf0+UpXXojt02svxybj8N5bxceAkzPChKEncHuratjUHkIFNCn06k2qj1DRlzTug== + dependencies: + "@babel/runtime" "^7.0.0" + focus-lock "^1.0.0" + prop-types "^15.6.2" + react-clientside-effect "^1.2.6" + use-callback-ref "^1.3.0" + use-sidecar "^1.1.2" + +react-is@^16.13.1, react-is@^16.7.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-refresh@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" + integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ== + +react-remove-scroll-bar@^2.3.4: + version "2.3.4" + resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz#53e272d7a5cb8242990c7f144c44d8bd8ab5afd9" + integrity sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A== + dependencies: + react-style-singleton "^2.2.1" + tslib "^2.0.0" + +react-remove-scroll@^2.5.6: + version "2.5.7" + resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz#15a1fd038e8497f65a695bf26a4a57970cac1ccb" + integrity sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA== + dependencies: + react-remove-scroll-bar "^2.3.4" + react-style-singleton "^2.2.1" + tslib "^2.1.0" + use-callback-ref "^1.3.0" + use-sidecar "^1.1.2" + +react-style-singleton@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4" + integrity sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g== + dependencies: + get-nonce "^1.0.0" + invariant "^2.2.4" + tslib "^2.0.0" + +react@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== + dependencies: + loose-envify "^1.1.0" + +reflect.getprototypeof@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3" + integrity sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + globalthis "^1.0.3" + which-builtin-type "^1.1.3" + +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + +regexp.prototype.flags@^1.5.0, regexp.prototype.flags@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" + integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + set-function-name "^2.0.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve@^1.19.0, resolve@^1.22.4: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve@^2.0.0-next.4: + version "2.0.0-next.5" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" + integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rollup@^4.2.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.9.2.tgz#19d730219b7ec5f51372c6cf15cfb841990489fe" + integrity sha512-66RB8OtFKUTozmVEh3qyNfH+b+z2RXBVloqO2KCC/pjFaGaHtxP9fVfOQKPSGXg2mElmjmxjW/fZ7iKrEpMH5Q== + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.9.2" + "@rollup/rollup-android-arm64" "4.9.2" + "@rollup/rollup-darwin-arm64" "4.9.2" + "@rollup/rollup-darwin-x64" "4.9.2" + "@rollup/rollup-linux-arm-gnueabihf" "4.9.2" + "@rollup/rollup-linux-arm64-gnu" "4.9.2" + "@rollup/rollup-linux-arm64-musl" "4.9.2" + "@rollup/rollup-linux-riscv64-gnu" "4.9.2" + "@rollup/rollup-linux-x64-gnu" "4.9.2" + "@rollup/rollup-linux-x64-musl" "4.9.2" + "@rollup/rollup-win32-arm64-msvc" "4.9.2" + "@rollup/rollup-win32-ia32-msvc" "4.9.2" + "@rollup/rollup-win32-x64-msvc" "4.9.2" + fsevents "~2.3.2" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +rxjs@^7.8.1: + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + +safe-array-concat@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" + integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + isarray "^2.0.5" + +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== + dependencies: + loose-envify "^1.1.0" + +semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.3.5, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + dependencies: + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +set-function-name@^2.0.0, set-function-name@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" + integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== + dependencies: + define-data-property "^1.0.1" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + +string.prototype.matchall@^4.0.8: + version "4.0.10" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz#a1553eb532221d4180c51581d6072cd65d1ee100" + integrity sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + internal-slot "^1.0.5" + regexp.prototype.flags "^1.5.0" + set-function-name "^2.0.0" + side-channel "^1.0.4" + +string.prototype.trim@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" + integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +string.prototype.trimend@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" + integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +string.prototype.trimstart@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" + integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +stylis@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" + integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +synckit@^0.8.6: + version "0.8.8" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.8.tgz#fe7fe446518e3d3d49f5e429f443cf08b6edfcd7" + integrity sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ== + dependencies: + "@pkgr/core" "^0.1.0" + tslib "^2.6.2" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +tiny-invariant@^1.0.6: + version "1.3.1" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" + integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toggle-selection@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" + integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== + +ts-api-utils@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" + integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== + +tsconfig-paths@^3.15.0: + version "3.15.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" + integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + +tslib@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + +tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" + +typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" + integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" + +typescript@^5.3.2: + version "5.3.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" + integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== + +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + +update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +use-callback-ref@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.1.tgz#9be64c3902cbd72b07fe55e56408ae3a26036fd0" + integrity sha512-Lg4Vx1XZQauB42Hw3kK7JM6yjVjgFmFC5/Ab797s79aARomD2nEErc4mCgM8EZrARLmmbWpi5DGCadmK50DcAQ== + dependencies: + tslib "^2.0.0" + +use-sidecar@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2" + integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw== + dependencies: + detect-node-es "^1.1.0" + tslib "^2.0.0" + +uuid@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + +vite@^5.0.2: + version "5.0.10" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.0.10.tgz#1e13ef5c3cf5aa4eed81f5df6d107b3c3f1f6356" + integrity sha512-2P8J7WWgmc355HUMlFrwofacvr98DAjoE52BfdbwQtyLH06XKwaL/FMnmKM2crF0iX4MpmMKoDlNCB1ok7zHCw== + dependencies: + esbuild "^0.19.3" + postcss "^8.4.32" + rollup "^4.2.0" + optionalDependencies: + fsevents "~2.3.3" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-builtin-type@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.1.3.tgz#b1b8443707cc58b6e9bf98d32110ff0c2cbd029b" + integrity sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw== + dependencies: + function.prototype.name "^1.1.5" + has-tostringtag "^1.0.0" + is-async-function "^2.0.0" + is-date-object "^1.0.5" + is-finalizationregistry "^1.0.2" + is-generator-function "^1.0.10" + is-regex "^1.1.4" + is-weakref "^1.0.2" + isarray "^2.0.5" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.9" + +which-collection@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" + integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== + dependencies: + is-map "^2.0.1" + is-set "^2.0.1" + is-weakmap "^2.0.1" + is-weakset "^2.0.1" + +which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.9: + version "1.1.13" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" + integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.4" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zod@^3.22.2: + version "3.22.4" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff" + integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg== From 2db89f9fa86472dc966f18f042e80b3f00348277 Mon Sep 17 00:00:00 2001 From: ioay Date: Wed, 3 Jan 2024 08:39:45 +0100 Subject: [PATCH 098/170] yarn.lock removed --- dapp/yarn.lock | 4045 ------------------------------------------------ 1 file changed, 4045 deletions(-) delete mode 100644 dapp/yarn.lock diff --git a/dapp/yarn.lock b/dapp/yarn.lock deleted file mode 100644 index 816c6cc09..000000000 --- a/dapp/yarn.lock +++ /dev/null @@ -1,4045 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== - -"@ampproject/remapping@^2.2.0": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" - integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" - integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== - dependencies: - "@babel/highlight" "^7.23.4" - chalk "^2.4.2" - -"@babel/compat-data@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" - integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== - -"@babel/core@^7.23.5": - version "7.23.7" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.7.tgz#4d8016e06a14b5f92530a13ed0561730b5c6483f" - integrity sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.23.5" - "@babel/generator" "^7.23.6" - "@babel/helper-compilation-targets" "^7.23.6" - "@babel/helper-module-transforms" "^7.23.3" - "@babel/helpers" "^7.23.7" - "@babel/parser" "^7.23.6" - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.7" - "@babel/types" "^7.23.6" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - -"@babel/generator@^7.23.6": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e" - integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== - dependencies: - "@babel/types" "^7.23.6" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - -"@babel/helper-compilation-targets@^7.23.6": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" - integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== - dependencies: - "@babel/compat-data" "^7.23.5" - "@babel/helper-validator-option" "^7.23.5" - browserslist "^4.22.2" - lru-cache "^5.1.1" - semver "^6.3.1" - -"@babel/helper-environment-visitor@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" - integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== - -"@babel/helper-function-name@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" - integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== - dependencies: - "@babel/template" "^7.22.15" - "@babel/types" "^7.23.0" - -"@babel/helper-hoist-variables@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" - integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" - integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== - dependencies: - "@babel/types" "^7.22.15" - -"@babel/helper-module-transforms@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" - integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== - dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-simple-access" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/helper-validator-identifier" "^7.22.20" - -"@babel/helper-plugin-utils@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" - integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== - -"@babel/helper-simple-access@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" - integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-split-export-declaration@^7.22.6": - version "7.22.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" - integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-string-parser@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" - integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== - -"@babel/helper-validator-identifier@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" - integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== - -"@babel/helper-validator-option@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" - integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== - -"@babel/helpers@^7.23.7": - version "7.23.7" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.7.tgz#eb543c36f81da2873e47b76ee032343ac83bba60" - integrity sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ== - dependencies: - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.7" - "@babel/types" "^7.23.6" - -"@babel/highlight@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" - integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== - dependencies: - "@babel/helper-validator-identifier" "^7.22.20" - chalk "^2.4.2" - js-tokens "^4.0.0" - -"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.6": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.6.tgz#ba1c9e512bda72a47e285ae42aff9d2a635a9e3b" - integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ== - -"@babel/plugin-transform-react-jsx-self@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz#ed3e7dadde046cce761a8e3cf003a13d1a7972d9" - integrity sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-react-jsx-source@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz#03527006bdc8775247a78643c51d4e715fe39a3e" - integrity sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.23.2": - version "7.23.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.7.tgz#dd7c88deeb218a0f8bd34d5db1aa242e0f203193" - integrity sha512-w06OXVOFso7LcbzMiDGt+3X7Rh7Ho8MmgPoWU3rarH+8upf+wSU/grlGbWzQyr3DkdN6ZeuMFjpdwW0Q+HxobA== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/template@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" - integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== - dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/parser" "^7.22.15" - "@babel/types" "^7.22.15" - -"@babel/traverse@^7.23.7": - version "7.23.7" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.7.tgz#9a7bf285c928cb99b5ead19c3b1ce5b310c9c305" - integrity sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg== - dependencies: - "@babel/code-frame" "^7.23.5" - "@babel/generator" "^7.23.6" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.23.6" - "@babel/types" "^7.23.6" - debug "^4.3.1" - globals "^11.1.0" - -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.6.tgz#be33fdb151e1f5a56877d704492c240fc71c7ccd" - integrity sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg== - dependencies: - "@babel/helper-string-parser" "^7.23.4" - "@babel/helper-validator-identifier" "^7.22.20" - to-fast-properties "^2.0.0" - -"@chakra-ui/accordion@2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/accordion/-/accordion-2.3.1.tgz#a326509e286a5c4e8478de9bc2b4b05017039e6b" - integrity sha512-FSXRm8iClFyU+gVaXisOSEw0/4Q+qZbFRiuhIAkVU6Boj0FxAMrlo9a8AV5TuF77rgaHytCdHk0Ng+cyUijrag== - dependencies: - "@chakra-ui/descendant" "3.1.0" - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-use-controllable-state" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/transition" "2.1.0" - -"@chakra-ui/alert@2.2.2": - version "2.2.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/alert/-/alert-2.2.2.tgz#aeba951d120c7c6e69d5f515a695ad6e4db43ffe" - integrity sha512-jHg4LYMRNOJH830ViLuicjb3F+v6iriE/2G5T+Sd0Hna04nukNJ1MxUmBPE+vI22me2dIflfelu2v9wdB6Pojw== - dependencies: - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/spinner" "2.1.0" - -"@chakra-ui/anatomy@2.2.2": - version "2.2.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/anatomy/-/anatomy-2.2.2.tgz#2d0e14cba2534d92077ca28abf8c183b6e27897b" - integrity sha512-MV6D4VLRIHr4PkW4zMyqfrNS1mPlCTiCXwvYGtDFQYr+xHFfonhAuf9WjsSc0nyp2m0OdkSLnzmVKkZFLo25Tg== - -"@chakra-ui/avatar@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/avatar/-/avatar-2.3.0.tgz#f018a2714d1e3ba5970bcf66558887925fdfccf4" - integrity sha512-8gKSyLfygnaotbJbDMHDiJoF38OHXUYVme4gGxZ1fLnQEdPVEaIWfH+NndIjOM0z8S+YEFnT9KyGMUtvPrBk3g== - dependencies: - "@chakra-ui/image" "2.1.0" - "@chakra-ui/react-children-utils" "2.0.6" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/breadcrumb@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/breadcrumb/-/breadcrumb-2.2.0.tgz#751bc48498f3c403f97b5d9aae528ebfd405ef48" - integrity sha512-4cWCG24flYBxjruRi4RJREWTGF74L/KzI2CognAW/d/zWR0CjiScuJhf37Am3LFbCySP6WSoyBOtTIoTA4yLEA== - dependencies: - "@chakra-ui/react-children-utils" "2.0.6" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/breakpoint-utils@2.0.8": - version "2.0.8" - resolved "https://registry.yarnpkg.com/@chakra-ui/breakpoint-utils/-/breakpoint-utils-2.0.8.tgz#750d3712668b69f6e8917b45915cee0e08688eed" - integrity sha512-Pq32MlEX9fwb5j5xx8s18zJMARNHlQZH2VH1RZgfgRDpp7DcEgtRW5AInfN5CfqdHLO1dGxA7I3MqEuL5JnIsA== - dependencies: - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/button@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/button/-/button-2.1.0.tgz#623ed32cc92fc8e52492923e9924791fc6f25447" - integrity sha512-95CplwlRKmmUXkdEp/21VkEWgnwcx2TOBG6NfYlsuLBDHSLlo5FKIiE2oSi4zXc4TLcopGcWPNcm/NDaSC5pvA== - dependencies: - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/spinner" "2.1.0" - -"@chakra-ui/card@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/card/-/card-2.2.0.tgz#b5e59dc51c171fced76ea76bf26088803b8bc184" - integrity sha512-xUB/k5MURj4CtPAhdSoXZidUbm8j3hci9vnc+eZJVDqhDOShNlD6QeniQNRPRys4lWAQLCbFcrwL29C8naDi6g== - dependencies: - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/checkbox@2.3.2": - version "2.3.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/checkbox/-/checkbox-2.3.2.tgz#4ecb14a2f57b7470d1a58542ca4691c3b105bfa1" - integrity sha512-85g38JIXMEv6M+AcyIGLh7igNtfpAN6KGQFYxY9tBj0eWvWk4NKQxvqqyVta0bSAyIl1rixNIIezNpNWk2iO4g== - dependencies: - "@chakra-ui/form-control" "2.2.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-callback-ref" "2.1.0" - "@chakra-ui/react-use-controllable-state" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - "@chakra-ui/react-use-update-effect" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/visually-hidden" "2.2.0" - "@zag-js/focus-visible" "0.16.0" - -"@chakra-ui/clickable@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/clickable/-/clickable-2.1.0.tgz#800fa8d10cf45a41fc50a3df32c679a3ce1921c3" - integrity sha512-flRA/ClPUGPYabu+/GLREZVZr9j2uyyazCAUHAdrTUEdDYCr31SVGhgh7dgKdtq23bOvAQJpIJjw/0Bs0WvbXw== - dependencies: - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/close-button@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/close-button/-/close-button-2.1.1.tgz#995b245c56eb41465a71d8667840c238618a7b66" - integrity sha512-gnpENKOanKexswSVpVz7ojZEALl2x5qjLYNqSQGbxz+aP9sOXPfUS56ebyBrre7T7exuWGiFeRwnM0oVeGPaiw== - dependencies: - "@chakra-ui/icon" "3.2.0" - -"@chakra-ui/color-mode@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/color-mode/-/color-mode-2.2.0.tgz#828d47234c74ba2fb4c5dd63a63331aead20b9f6" - integrity sha512-niTEA8PALtMWRI9wJ4LL0CSBDo8NBfLNp4GD6/0hstcm3IlbBHTVKxN6HwSaoNYfphDQLxCjT4yG+0BJA5tFpg== - dependencies: - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - -"@chakra-ui/control-box@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/control-box/-/control-box-2.1.0.tgz#0f4586797b3154c02463bc5c106782e70c88f04f" - integrity sha512-gVrRDyXFdMd8E7rulL0SKeoljkLQiPITFnsyMO8EFHNZ+AHt5wK4LIguYVEq88APqAGZGfHFWXr79RYrNiE3Mg== - -"@chakra-ui/counter@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/counter/-/counter-2.1.0.tgz#e413a2f1093a18f847bb7aa240117fde788a59e6" - integrity sha512-s6hZAEcWT5zzjNz2JIWUBzRubo9la/oof1W7EKZVVfPYHERnl5e16FmBC79Yfq8p09LQ+aqFKm/etYoJMMgghw== - dependencies: - "@chakra-ui/number-utils" "2.0.7" - "@chakra-ui/react-use-callback-ref" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/css-reset@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/css-reset/-/css-reset-2.3.0.tgz#83e3160a9c2a12431cad0ee27ebfbf3aedc5c9c7" - integrity sha512-cQwwBy5O0jzvl0K7PLTLgp8ijqLPKyuEMiDXwYzl95seD3AoeuoCLyzZcJtVqaUZ573PiBdAbY/IlZcwDOItWg== - -"@chakra-ui/descendant@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/descendant/-/descendant-3.1.0.tgz#f3b80ed13ffc4bf1d615b3ed5541bd0905375cca" - integrity sha512-VxCIAir08g5w27klLyi7PVo8BxhW4tgU/lxQyujkmi4zx7hT9ZdrcQLAted/dAa+aSIZ14S1oV0Q9lGjsAdxUQ== - dependencies: - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - -"@chakra-ui/dom-utils@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/dom-utils/-/dom-utils-2.1.0.tgz#d15df89e458ef19756db04c7cfd084eb552454f0" - integrity sha512-ZmF2qRa1QZ0CMLU8M1zCfmw29DmPNtfjR9iTo74U5FPr3i1aoAh7fbJ4qAlZ197Xw9eAW28tvzQuoVWeL5C7fQ== - -"@chakra-ui/editable@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/editable/-/editable-3.1.0.tgz#065783c2e3389c3bb9ab0582cb50d38e1dc00fa1" - integrity sha512-j2JLrUL9wgg4YA6jLlbU88370eCRyor7DZQD9lzpY95tSOXpTljeg3uF9eOmDnCs6fxp3zDWIfkgMm/ExhcGTg== - dependencies: - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-callback-ref" "2.1.0" - "@chakra-ui/react-use-controllable-state" "2.1.0" - "@chakra-ui/react-use-focus-on-pointer-down" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - "@chakra-ui/react-use-update-effect" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/event-utils@2.0.8": - version "2.0.8" - resolved "https://registry.yarnpkg.com/@chakra-ui/event-utils/-/event-utils-2.0.8.tgz#e6439ba200825a2f15d8f1973d267d1c00a6d1b4" - integrity sha512-IGM/yGUHS+8TOQrZGpAKOJl/xGBrmRYJrmbHfUE7zrG3PpQyXvbLDP1M+RggkCFVgHlJi2wpYIf0QtQlU0XZfw== - -"@chakra-ui/focus-lock@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/focus-lock/-/focus-lock-2.1.0.tgz#580e5450fe85356987b9a246abaff8333369c667" - integrity sha512-EmGx4PhWGjm4dpjRqM4Aa+rCWBxP+Rq8Uc/nAVnD4YVqkEhBkrPTpui2lnjsuxqNaZ24fIAZ10cF1hlpemte/w== - dependencies: - "@chakra-ui/dom-utils" "2.1.0" - react-focus-lock "^2.9.4" - -"@chakra-ui/form-control@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/form-control/-/form-control-2.2.0.tgz#69c771d6406ddac8ab357ae88446cc11827656a4" - integrity sha512-wehLC1t4fafCVJ2RvJQT2jyqsAwX7KymmiGqBu7nQoQz8ApTkGABWpo/QwDh3F/dBLrouHDoOvGmYTqft3Mirw== - dependencies: - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/hooks@2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/hooks/-/hooks-2.2.1.tgz#b86ce5eeaaab877ddcb11a50842d1227306ace28" - integrity sha512-RQbTnzl6b1tBjbDPf9zGRo9rf/pQMholsOudTxjy4i9GfTfz6kgp5ValGjQm2z7ng6Z31N1cnjZ1AlSzQ//ZfQ== - dependencies: - "@chakra-ui/react-utils" "2.0.12" - "@chakra-ui/utils" "2.0.15" - compute-scroll-into-view "3.0.3" - copy-to-clipboard "3.3.3" - -"@chakra-ui/icon@3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/icon/-/icon-3.2.0.tgz#92b9454aa0d561b4994bcd6a1b3bb1fdd5c67bef" - integrity sha512-xxjGLvlX2Ys4H0iHrI16t74rG9EBcpFvJ3Y3B7KMQTrnW34Kf7Da/UC8J67Gtx85mTHW020ml85SVPKORWNNKQ== - dependencies: - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/image@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/image/-/image-2.1.0.tgz#6c205f1ca148e3bf58345b0b5d4eb3d959eb9f87" - integrity sha512-bskumBYKLiLMySIWDGcz0+D9Th0jPvmX6xnRMs4o92tT3Od/bW26lahmV2a2Op2ItXeCmRMY+XxJH5Gy1i46VA== - dependencies: - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/input@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/input/-/input-2.1.2.tgz#0cad49ec372f8f21f2f4f1db365f34b9a708ff9d" - integrity sha512-GiBbb3EqAA8Ph43yGa6Mc+kUPjh4Spmxp1Pkelr8qtudpc3p2PJOOebLpd90mcqw8UePPa+l6YhhPtp6o0irhw== - dependencies: - "@chakra-ui/form-control" "2.2.0" - "@chakra-ui/object-utils" "2.1.0" - "@chakra-ui/react-children-utils" "2.0.6" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/layout@2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/layout/-/layout-2.3.1.tgz#0601c5eb91555d24a7015a7c9d4e01fed2698557" - integrity sha512-nXuZ6WRbq0WdgnRgLw+QuxWAHuhDtVX8ElWqcTK+cSMFg/52eVP47czYBE5F35YhnoW2XBwfNoNgZ7+e8Z01Rg== - dependencies: - "@chakra-ui/breakpoint-utils" "2.0.8" - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/object-utils" "2.1.0" - "@chakra-ui/react-children-utils" "2.0.6" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/lazy-utils@2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@chakra-ui/lazy-utils/-/lazy-utils-2.0.5.tgz#363c3fa1d421362790b416ffa595acb835e1ae5b" - integrity sha512-UULqw7FBvcckQk2n3iPO56TMJvDsNv0FKZI6PlUNJVaGsPbsYxK/8IQ60vZgaTVPtVcjY6BE+y6zg8u9HOqpyg== - -"@chakra-ui/live-region@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/live-region/-/live-region-2.1.0.tgz#02b4b1d997075f19a7a9a87187e08c72e82ef0dd" - integrity sha512-ZOxFXwtaLIsXjqnszYYrVuswBhnIHHP+XIgK1vC6DePKtyK590Wg+0J0slDwThUAd4MSSIUa/nNX84x1GMphWw== - -"@chakra-ui/media-query@3.3.0": - version "3.3.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/media-query/-/media-query-3.3.0.tgz#40f9151dedb6a7af9df3be0474b59a799c92c619" - integrity sha512-IsTGgFLoICVoPRp9ykOgqmdMotJG0CnPsKvGQeSFOB/dZfIujdVb14TYxDU4+MURXry1MhJ7LzZhv+Ml7cr8/g== - dependencies: - "@chakra-ui/breakpoint-utils" "2.0.8" - "@chakra-ui/react-env" "3.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/menu@2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/menu/-/menu-2.2.1.tgz#7d9810d435f6b40fa72ed867a33b88a1ef75073f" - integrity sha512-lJS7XEObzJxsOwWQh7yfG4H8FzFPRP5hVPN/CL+JzytEINCSBvsCDHrYPQGp7jzpCi8vnTqQQGQe0f8dwnXd2g== - dependencies: - "@chakra-ui/clickable" "2.1.0" - "@chakra-ui/descendant" "3.1.0" - "@chakra-ui/lazy-utils" "2.0.5" - "@chakra-ui/popper" "3.1.0" - "@chakra-ui/react-children-utils" "2.0.6" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-use-animation-state" "2.1.0" - "@chakra-ui/react-use-controllable-state" "2.1.0" - "@chakra-ui/react-use-disclosure" "2.1.0" - "@chakra-ui/react-use-focus-effect" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/react-use-outside-click" "2.2.0" - "@chakra-ui/react-use-update-effect" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/transition" "2.1.0" - -"@chakra-ui/modal@2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/modal/-/modal-2.3.1.tgz#524dc32b6b4f545b54ae531dbf6c74e1052ee794" - integrity sha512-TQv1ZaiJMZN+rR9DK0snx/OPwmtaGH1HbZtlYt4W4s6CzyK541fxLRTjIXfEzIGpvNW+b6VFuFjbcR78p4DEoQ== - dependencies: - "@chakra-ui/close-button" "2.1.1" - "@chakra-ui/focus-lock" "2.1.0" - "@chakra-ui/portal" "2.1.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/transition" "2.1.0" - aria-hidden "^1.2.3" - react-remove-scroll "^2.5.6" - -"@chakra-ui/number-input@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/number-input/-/number-input-2.1.2.tgz#dda9095fba6a4b89212332db02831b94120da163" - integrity sha512-pfOdX02sqUN0qC2ysuvgVDiws7xZ20XDIlcNhva55Jgm095xjm8eVdIBfNm3SFbSUNxyXvLTW/YQanX74tKmuA== - dependencies: - "@chakra-ui/counter" "2.1.0" - "@chakra-ui/form-control" "2.2.0" - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-callback-ref" "2.1.0" - "@chakra-ui/react-use-event-listener" "2.1.0" - "@chakra-ui/react-use-interval" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - "@chakra-ui/react-use-update-effect" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/number-utils@2.0.7": - version "2.0.7" - resolved "https://registry.yarnpkg.com/@chakra-ui/number-utils/-/number-utils-2.0.7.tgz#aaee979ca2fb1923a0373a91619473811315db11" - integrity sha512-yOGxBjXNvLTBvQyhMDqGU0Oj26s91mbAlqKHiuw737AXHt0aPllOthVUqQMeaYLwLCjGMg0jtI7JReRzyi94Dg== - -"@chakra-ui/object-utils@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/object-utils/-/object-utils-2.1.0.tgz#a4ecf9cea92f1de09f5531f53ffdc41e0b19b6c3" - integrity sha512-tgIZOgLHaoti5PYGPTwK3t/cqtcycW0owaiOXoZOcpwwX/vlVb+H1jFsQyWiiwQVPt9RkoSLtxzXamx+aHH+bQ== - -"@chakra-ui/pin-input@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/pin-input/-/pin-input-2.1.0.tgz#61e6bbf909ec510634307b2861c4f1891a9f8d81" - integrity sha512-x4vBqLStDxJFMt+jdAHHS8jbh294O53CPQJoL4g228P513rHylV/uPscYUHrVJXRxsHfRztQO9k45jjTYaPRMw== - dependencies: - "@chakra-ui/descendant" "3.1.0" - "@chakra-ui/react-children-utils" "2.0.6" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-use-controllable-state" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/popover@2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/popover/-/popover-2.2.1.tgz#89cfd29817abcd204da570073c0f2b4d8072c3a3" - integrity sha512-K+2ai2dD0ljvJnlrzesCDT9mNzLifE3noGKZ3QwLqd/K34Ym1W/0aL1ERSynrcG78NKoXS54SdEzkhCZ4Gn/Zg== - dependencies: - "@chakra-ui/close-button" "2.1.1" - "@chakra-ui/lazy-utils" "2.0.5" - "@chakra-ui/popper" "3.1.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-animation-state" "2.1.0" - "@chakra-ui/react-use-disclosure" "2.1.0" - "@chakra-ui/react-use-focus-effect" "2.1.0" - "@chakra-ui/react-use-focus-on-pointer-down" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/popper@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/popper/-/popper-3.1.0.tgz#92a9180c6894763af3b22a6003f9a9d958fe2659" - integrity sha512-ciDdpdYbeFG7og6/6J8lkTFxsSvwTdMLFkpVylAF6VNC22jssiWfquj2eyD4rJnzkRFPvIWJq8hvbfhsm+AjSg== - dependencies: - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@popperjs/core" "^2.9.3" - -"@chakra-ui/portal@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/portal/-/portal-2.1.0.tgz#9e7f57424d7041738b6563cac80134561080bd27" - integrity sha512-9q9KWf6SArEcIq1gGofNcFPSWEyl+MfJjEUg/un1SMlQjaROOh3zYr+6JAwvcORiX7tyHosnmWC3d3wI2aPSQg== - dependencies: - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - -"@chakra-ui/progress@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/progress/-/progress-2.2.0.tgz#67444ea9779631d7c8395b2c9c78e5634f994999" - integrity sha512-qUXuKbuhN60EzDD9mHR7B67D7p/ZqNS2Aze4Pbl1qGGZfulPW0PY8Rof32qDtttDQBkzQIzFGE8d9QpAemToIQ== - dependencies: - "@chakra-ui/react-context" "2.1.0" - -"@chakra-ui/provider@2.4.2": - version "2.4.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/provider/-/provider-2.4.2.tgz#92cb10b6a7df0720e3fa62716dc7cd872ae3ea3d" - integrity sha512-w0Tef5ZCJK1mlJorcSjItCSbyvVuqpvyWdxZiVQmE6fvSJR83wZof42ux0+sfWD+I7rHSfj+f9nzhNaEWClysw== - dependencies: - "@chakra-ui/css-reset" "2.3.0" - "@chakra-ui/portal" "2.1.0" - "@chakra-ui/react-env" "3.1.0" - "@chakra-ui/system" "2.6.2" - "@chakra-ui/utils" "2.0.15" - -"@chakra-ui/radio@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/radio/-/radio-2.1.2.tgz#66db19c61a2e628aaf5e727027f7c3b4006ea898" - integrity sha512-n10M46wJrMGbonaghvSRnZ9ToTv/q76Szz284gv4QUWvyljQACcGrXIONUnQ3BIwbOfkRqSk7Xl/JgZtVfll+w== - dependencies: - "@chakra-ui/form-control" "2.2.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - "@zag-js/focus-visible" "0.16.0" - -"@chakra-ui/react-children-utils@2.0.6": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-children-utils/-/react-children-utils-2.0.6.tgz#6c480c6a60678fcb75cb7d57107c7a79e5179b92" - integrity sha512-QVR2RC7QsOsbWwEnq9YduhpqSFnZGvjjGREV8ygKi8ADhXh93C8azLECCUVgRJF2Wc+So1fgxmjLcbZfY2VmBA== - -"@chakra-ui/react-context@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-context/-/react-context-2.1.0.tgz#4858be1d5ff1c8ac0a0ec088d93a3b7f1cbbff99" - integrity sha512-iahyStvzQ4AOwKwdPReLGfDesGG+vWJfEsn0X/NoGph/SkN+HXtv2sCfYFFR9k7bb+Kvc6YfpLlSuLvKMHi2+w== - -"@chakra-ui/react-env@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-env/-/react-env-3.1.0.tgz#7d3c1c05a501bb369524d9f3d38c9325eb16ab50" - integrity sha512-Vr96GV2LNBth3+IKzr/rq1IcnkXv+MLmwjQH6C8BRtn3sNskgDFD5vLkVXcEhagzZMCh8FR3V/bzZPojBOyNhw== - dependencies: - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - -"@chakra-ui/react-types@2.0.7": - version "2.0.7" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-types/-/react-types-2.0.7.tgz#799c166a44882b23059c8f510eac9bd5d0869ac4" - integrity sha512-12zv2qIZ8EHwiytggtGvo4iLT0APris7T0qaAWqzpUGS0cdUtR8W+V1BJ5Ocq+7tA6dzQ/7+w5hmXih61TuhWQ== - -"@chakra-ui/react-use-animation-state@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-animation-state/-/react-use-animation-state-2.1.0.tgz#eab661fbafd96804fe867b0df0c27e78feefe6e2" - integrity sha512-CFZkQU3gmDBwhqy0vC1ryf90BVHxVN8cTLpSyCpdmExUEtSEInSCGMydj2fvn7QXsz/za8JNdO2xxgJwxpLMtg== - dependencies: - "@chakra-ui/dom-utils" "2.1.0" - "@chakra-ui/react-use-event-listener" "2.1.0" - -"@chakra-ui/react-use-callback-ref@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-callback-ref/-/react-use-callback-ref-2.1.0.tgz#a508085f4d9e7d84d4ceffdf5f41745c9ac451d7" - integrity sha512-efnJrBtGDa4YaxDzDE90EnKD3Vkh5a1t3w7PhnRQmsphLy3g2UieasoKTlT2Hn118TwDjIv5ZjHJW6HbzXA9wQ== - -"@chakra-ui/react-use-controllable-state@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-controllable-state/-/react-use-controllable-state-2.1.0.tgz#8fb6fa2f45d0c04173582ae8297e604ffdb9c7d9" - integrity sha512-QR/8fKNokxZUs4PfxjXuwl0fj/d71WPrmLJvEpCTkHjnzu7LnYvzoe2wB867IdooQJL0G1zBxl0Dq+6W1P3jpg== - dependencies: - "@chakra-ui/react-use-callback-ref" "2.1.0" - -"@chakra-ui/react-use-disclosure@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-disclosure/-/react-use-disclosure-2.1.0.tgz#90093eaf45db1bea7a6851dd0ce5cdb3eb66f90a" - integrity sha512-Ax4pmxA9LBGMyEZJhhUZobg9C0t3qFE4jVF1tGBsrLDcdBeLR9fwOogIPY9Hf0/wqSlAryAimICbr5hkpa5GSw== - dependencies: - "@chakra-ui/react-use-callback-ref" "2.1.0" - -"@chakra-ui/react-use-event-listener@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-event-listener/-/react-use-event-listener-2.1.0.tgz#afea2645bd9b38f754fc2b8eb858f9bb22385ded" - integrity sha512-U5greryDLS8ISP69DKDsYcsXRtAdnTQT+jjIlRYZ49K/XhUR/AqVZCK5BkR1spTDmO9H8SPhgeNKI70ODuDU/Q== - dependencies: - "@chakra-ui/react-use-callback-ref" "2.1.0" - -"@chakra-ui/react-use-focus-effect@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-focus-effect/-/react-use-focus-effect-2.1.0.tgz#963fb790370dfadd51d12666ff2da60706f53a2a" - integrity sha512-xzVboNy7J64xveLcxTIJ3jv+lUJKDwRM7Szwn9tNzUIPD94O3qwjV7DDCUzN2490nSYDF4OBMt/wuDBtaR3kUQ== - dependencies: - "@chakra-ui/dom-utils" "2.1.0" - "@chakra-ui/react-use-event-listener" "2.1.0" - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - "@chakra-ui/react-use-update-effect" "2.1.0" - -"@chakra-ui/react-use-focus-on-pointer-down@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-focus-on-pointer-down/-/react-use-focus-on-pointer-down-2.1.0.tgz#2fbcf6bc7d06d97606747e231a908d5c387ca0cc" - integrity sha512-2jzrUZ+aiCG/cfanrolsnSMDykCAbv9EK/4iUyZno6BYb3vziucmvgKuoXbMPAzWNtwUwtuMhkby8rc61Ue+Lg== - dependencies: - "@chakra-ui/react-use-event-listener" "2.1.0" - -"@chakra-ui/react-use-interval@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-interval/-/react-use-interval-2.1.0.tgz#2602c097b3ab74b6644812e4f5efaad621218d98" - integrity sha512-8iWj+I/+A0J08pgEXP1J1flcvhLBHkk0ln7ZvGIyXiEyM6XagOTJpwNhiu+Bmk59t3HoV/VyvyJTa+44sEApuw== - dependencies: - "@chakra-ui/react-use-callback-ref" "2.1.0" - -"@chakra-ui/react-use-latest-ref@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-latest-ref/-/react-use-latest-ref-2.1.0.tgz#d1e926130102566ece1d39f8a48ed125e0c8441a" - integrity sha512-m0kxuIYqoYB0va9Z2aW4xP/5b7BzlDeWwyXCH6QpT2PpW3/281L3hLCm1G0eOUcdVlayqrQqOeD6Mglq+5/xoQ== - -"@chakra-ui/react-use-merge-refs@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-merge-refs/-/react-use-merge-refs-2.1.0.tgz#c0c233527abdbea9a1348269c192012205762314" - integrity sha512-lERa6AWF1cjEtWSGjxWTaSMvneccnAVH4V4ozh8SYiN9fSPZLlSG3kNxfNzdFvMEhM7dnP60vynF7WjGdTgQbQ== - -"@chakra-ui/react-use-outside-click@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-outside-click/-/react-use-outside-click-2.2.0.tgz#5570b772a255f6f02b69e967127397c1b5fa3d3c" - integrity sha512-PNX+s/JEaMneijbgAM4iFL+f3m1ga9+6QK0E5Yh4s8KZJQ/bLwZzdhMz8J/+mL+XEXQ5J0N8ivZN28B82N1kNw== - dependencies: - "@chakra-ui/react-use-callback-ref" "2.1.0" - -"@chakra-ui/react-use-pan-event@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-pan-event/-/react-use-pan-event-2.1.0.tgz#51c21bc3c0e9e73d1faef5ea4f7e3c3d071a2758" - integrity sha512-xmL2qOHiXqfcj0q7ZK5s9UjTh4Gz0/gL9jcWPA6GVf+A0Od5imEDa/Vz+533yQKWiNSm1QGrIj0eJAokc7O4fg== - dependencies: - "@chakra-ui/event-utils" "2.0.8" - "@chakra-ui/react-use-latest-ref" "2.1.0" - framesync "6.1.2" - -"@chakra-ui/react-use-previous@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-previous/-/react-use-previous-2.1.0.tgz#f6046e6f7398b1e8d7e66ff7ebb8d61c92a2d3d0" - integrity sha512-pjxGwue1hX8AFcmjZ2XfrQtIJgqbTF3Qs1Dy3d1krC77dEsiCUbQ9GzOBfDc8pfd60DrB5N2tg5JyHbypqh0Sg== - -"@chakra-ui/react-use-safe-layout-effect@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-safe-layout-effect/-/react-use-safe-layout-effect-2.1.0.tgz#3a95f0ba6fd5d2d0aa14919160f2c825f13e686f" - integrity sha512-Knbrrx/bcPwVS1TorFdzrK/zWA8yuU/eaXDkNj24IrKoRlQrSBFarcgAEzlCHtzuhufP3OULPkELTzz91b0tCw== - -"@chakra-ui/react-use-size@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-size/-/react-use-size-2.1.0.tgz#fcf3070eaade8b4a84af8ce5341c4d5ca0a42bec" - integrity sha512-tbLqrQhbnqOjzTaMlYytp7wY8BW1JpL78iG7Ru1DlV4EWGiAmXFGvtnEt9HftU0NJ0aJyjgymkxfVGI55/1Z4A== - dependencies: - "@zag-js/element-size" "0.10.5" - -"@chakra-ui/react-use-timeout@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-timeout/-/react-use-timeout-2.1.0.tgz#24415f54267d7241a3c1d36a5cae4d472834cef7" - integrity sha512-cFN0sobKMM9hXUhyCofx3/Mjlzah6ADaEl/AXl5Y+GawB5rgedgAcu2ErAgarEkwvsKdP6c68CKjQ9dmTQlJxQ== - dependencies: - "@chakra-ui/react-use-callback-ref" "2.1.0" - -"@chakra-ui/react-use-update-effect@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-update-effect/-/react-use-update-effect-2.1.0.tgz#5c57cd1f50c2a6a8119e0f57f69510723d69884b" - integrity sha512-ND4Q23tETaR2Qd3zwCKYOOS1dfssojPLJMLvUtUbW5M9uW1ejYWgGUobeAiOVfSplownG8QYMmHTP86p/v0lbA== - -"@chakra-ui/react-utils@2.0.12": - version "2.0.12" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-utils/-/react-utils-2.0.12.tgz#d6b773b9a5b2e51dce61f51ac8a0e9a0f534f479" - integrity sha512-GbSfVb283+YA3kA8w8xWmzbjNWk14uhNpntnipHCftBibl0lxtQ9YqMFQLwuFOO0U2gYVocszqqDWX+XNKq9hw== - dependencies: - "@chakra-ui/utils" "2.0.15" - -"@chakra-ui/react@^2.8.2": - version "2.8.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/react/-/react-2.8.2.tgz#94d692fb35e4447748c5bfd73d8d38a746193c7d" - integrity sha512-Hn0moyxxyCDKuR9ywYpqgX8dvjqwu9ArwpIb9wHNYjnODETjLwazgNIliCVBRcJvysGRiV51U2/JtJVrpeCjUQ== - dependencies: - "@chakra-ui/accordion" "2.3.1" - "@chakra-ui/alert" "2.2.2" - "@chakra-ui/avatar" "2.3.0" - "@chakra-ui/breadcrumb" "2.2.0" - "@chakra-ui/button" "2.1.0" - "@chakra-ui/card" "2.2.0" - "@chakra-ui/checkbox" "2.3.2" - "@chakra-ui/close-button" "2.1.1" - "@chakra-ui/control-box" "2.1.0" - "@chakra-ui/counter" "2.1.0" - "@chakra-ui/css-reset" "2.3.0" - "@chakra-ui/editable" "3.1.0" - "@chakra-ui/focus-lock" "2.1.0" - "@chakra-ui/form-control" "2.2.0" - "@chakra-ui/hooks" "2.2.1" - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/image" "2.1.0" - "@chakra-ui/input" "2.1.2" - "@chakra-ui/layout" "2.3.1" - "@chakra-ui/live-region" "2.1.0" - "@chakra-ui/media-query" "3.3.0" - "@chakra-ui/menu" "2.2.1" - "@chakra-ui/modal" "2.3.1" - "@chakra-ui/number-input" "2.1.2" - "@chakra-ui/pin-input" "2.1.0" - "@chakra-ui/popover" "2.2.1" - "@chakra-ui/popper" "3.1.0" - "@chakra-ui/portal" "2.1.0" - "@chakra-ui/progress" "2.2.0" - "@chakra-ui/provider" "2.4.2" - "@chakra-ui/radio" "2.1.2" - "@chakra-ui/react-env" "3.1.0" - "@chakra-ui/select" "2.1.2" - "@chakra-ui/skeleton" "2.1.0" - "@chakra-ui/skip-nav" "2.1.0" - "@chakra-ui/slider" "2.1.0" - "@chakra-ui/spinner" "2.1.0" - "@chakra-ui/stat" "2.1.1" - "@chakra-ui/stepper" "2.3.1" - "@chakra-ui/styled-system" "2.9.2" - "@chakra-ui/switch" "2.1.2" - "@chakra-ui/system" "2.6.2" - "@chakra-ui/table" "2.1.0" - "@chakra-ui/tabs" "3.0.0" - "@chakra-ui/tag" "3.1.1" - "@chakra-ui/textarea" "2.1.2" - "@chakra-ui/theme" "3.3.1" - "@chakra-ui/theme-utils" "2.0.21" - "@chakra-ui/toast" "7.0.2" - "@chakra-ui/tooltip" "2.3.1" - "@chakra-ui/transition" "2.1.0" - "@chakra-ui/utils" "2.0.15" - "@chakra-ui/visually-hidden" "2.2.0" - -"@chakra-ui/select@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/select/-/select-2.1.2.tgz#f57d6cec0559373c32094fd4a5abd32855829264" - integrity sha512-ZwCb7LqKCVLJhru3DXvKXpZ7Pbu1TDZ7N0PdQ0Zj1oyVLJyrpef1u9HR5u0amOpqcH++Ugt0f5JSmirjNlctjA== - dependencies: - "@chakra-ui/form-control" "2.2.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/shared-utils@2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@chakra-ui/shared-utils/-/shared-utils-2.0.5.tgz#cb2b49705e113853647f1822142619570feba081" - integrity sha512-4/Wur0FqDov7Y0nCXl7HbHzCg4aq86h+SXdoUeuCMD3dSj7dpsVnStLYhng1vxvlbUnLpdF4oz5Myt3i/a7N3Q== - -"@chakra-ui/skeleton@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/skeleton/-/skeleton-2.1.0.tgz#e3b25dd3afa330029d6d63be0f7cb8d44ad25531" - integrity sha512-JNRuMPpdZGd6zFVKjVQ0iusu3tXAdI29n4ZENYwAJEMf/fN0l12sVeirOxkJ7oEL0yOx2AgEYFSKdbcAgfUsAQ== - dependencies: - "@chakra-ui/media-query" "3.3.0" - "@chakra-ui/react-use-previous" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/skip-nav@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/skip-nav/-/skip-nav-2.1.0.tgz#cac27eecc6eded1e83c8f0cf7445d727739cb325" - integrity sha512-Hk+FG+vadBSH0/7hwp9LJnLjkO0RPGnx7gBJWI4/SpoJf3e4tZlWYtwGj0toYY4aGKl93jVghuwGbDBEMoHDug== - -"@chakra-ui/slider@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/slider/-/slider-2.1.0.tgz#1caeed18761ba2a390777418cc9389ba25e39bce" - integrity sha512-lUOBcLMCnFZiA/s2NONXhELJh6sY5WtbRykPtclGfynqqOo47lwWJx+VP7xaeuhDOPcWSSecWc9Y1BfPOCz9cQ== - dependencies: - "@chakra-ui/number-utils" "2.0.7" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-callback-ref" "2.1.0" - "@chakra-ui/react-use-controllable-state" "2.1.0" - "@chakra-ui/react-use-latest-ref" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/react-use-pan-event" "2.1.0" - "@chakra-ui/react-use-size" "2.1.0" - "@chakra-ui/react-use-update-effect" "2.1.0" - -"@chakra-ui/spinner@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/spinner/-/spinner-2.1.0.tgz#aa24a3d692c6ac90714e0f0f82c76c12c78c8e60" - integrity sha512-hczbnoXt+MMv/d3gE+hjQhmkzLiKuoTo42YhUG7Bs9OSv2lg1fZHW1fGNRFP3wTi6OIbD044U1P9HK+AOgFH3g== - dependencies: - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/stat@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/stat/-/stat-2.1.1.tgz#a204ba915795345996a16c79794d84826d7dcc2d" - integrity sha512-LDn0d/LXQNbAn2KaR3F1zivsZCewY4Jsy1qShmfBMKwn6rI8yVlbvu6SiA3OpHS0FhxbsZxQI6HefEoIgtqY6Q== - dependencies: - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/stepper@2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/stepper/-/stepper-2.3.1.tgz#a0a0b73e147f202ab4e51cae55dad45489cc89fd" - integrity sha512-ky77lZbW60zYkSXhYz7kbItUpAQfEdycT0Q4bkHLxfqbuiGMf8OmgZOQkOB9uM4v0zPwy2HXhe0vq4Dd0xa55Q== - dependencies: - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/styled-system@2.9.2": - version "2.9.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/styled-system/-/styled-system-2.9.2.tgz#898ab63da560a4a014f7b05fa7767e8c76da6d2f" - integrity sha512-To/Z92oHpIE+4nk11uVMWqo2GGRS86coeMmjxtpnErmWRdLcp1WVCVRAvn+ZwpLiNR+reWFr2FFqJRsREuZdAg== - dependencies: - "@chakra-ui/shared-utils" "2.0.5" - csstype "^3.1.2" - lodash.mergewith "4.6.2" - -"@chakra-ui/switch@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/switch/-/switch-2.1.2.tgz#f7c6878d8126bfac8fa3b939079f1017c21b7479" - integrity sha512-pgmi/CC+E1v31FcnQhsSGjJnOE2OcND4cKPyTE+0F+bmGm48Q/b5UmKD9Y+CmZsrt/7V3h8KNczowupfuBfIHA== - dependencies: - "@chakra-ui/checkbox" "2.3.2" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/system@2.6.2": - version "2.6.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/system/-/system-2.6.2.tgz#528ec955bd6a7f74da46470ee8225b1e2c80a78b" - integrity sha512-EGtpoEjLrUu4W1fHD+a62XR+hzC5YfsWm+6lO0Kybcga3yYEij9beegO0jZgug27V+Rf7vns95VPVP6mFd/DEQ== - dependencies: - "@chakra-ui/color-mode" "2.2.0" - "@chakra-ui/object-utils" "2.1.0" - "@chakra-ui/react-utils" "2.0.12" - "@chakra-ui/styled-system" "2.9.2" - "@chakra-ui/theme-utils" "2.0.21" - "@chakra-ui/utils" "2.0.15" - react-fast-compare "3.2.2" - -"@chakra-ui/table@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/table/-/table-2.1.0.tgz#20dce14c5e4d70dc7c6c0e87cce9b05907ff8c50" - integrity sha512-o5OrjoHCh5uCLdiUb0Oc0vq9rIAeHSIRScc2ExTC9Qg/uVZl2ygLrjToCaKfaaKl1oQexIeAcZDKvPG8tVkHyQ== - dependencies: - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/tabs@3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/tabs/-/tabs-3.0.0.tgz#854c06880af26158d7c72881c4b5e0453f6c485d" - integrity sha512-6Mlclp8L9lqXmsGWF5q5gmemZXOiOYuh0SGT/7PgJVNPz3LXREXlXg2an4MBUD8W5oTkduCX+3KTMCwRrVrDYw== - dependencies: - "@chakra-ui/clickable" "2.1.0" - "@chakra-ui/descendant" "3.1.0" - "@chakra-ui/lazy-utils" "2.0.5" - "@chakra-ui/react-children-utils" "2.0.6" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-use-controllable-state" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/tag@3.1.1": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/tag/-/tag-3.1.1.tgz#d05284b6549a84d3a08e57eec57df3ad0eebd882" - integrity sha512-Bdel79Dv86Hnge2PKOU+t8H28nm/7Y3cKd4Kfk9k3lOpUh4+nkSGe58dhRzht59lEqa4N9waCgQiBdkydjvBXQ== - dependencies: - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/react-context" "2.1.0" - -"@chakra-ui/textarea@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/textarea/-/textarea-2.1.2.tgz#30f8af0e233cec2dee79d527450c6586e7122eff" - integrity sha512-ip7tvklVCZUb2fOHDb23qPy/Fr2mzDOGdkrpbNi50hDCiV4hFX02jdQJdi3ydHZUyVgZVBKPOJ+lT9i7sKA2wA== - dependencies: - "@chakra-ui/form-control" "2.2.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/theme-tools@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/theme-tools/-/theme-tools-2.1.2.tgz#913be05879cd816c546993ccb9ff7615f85ff69f" - integrity sha512-Qdj8ajF9kxY4gLrq7gA+Azp8CtFHGO9tWMN2wfF9aQNgG9AuMhPrUzMq9AMQ0MXiYcgNq/FD3eegB43nHVmXVA== - dependencies: - "@chakra-ui/anatomy" "2.2.2" - "@chakra-ui/shared-utils" "2.0.5" - color2k "^2.0.2" - -"@chakra-ui/theme-utils@2.0.21": - version "2.0.21" - resolved "https://registry.yarnpkg.com/@chakra-ui/theme-utils/-/theme-utils-2.0.21.tgz#da7ed541a5241a8ed0384eb14f37fa9b998382cf" - integrity sha512-FjH5LJbT794r0+VSCXB3lT4aubI24bLLRWB+CuRKHijRvsOg717bRdUN/N1fEmEpFnRVrbewttWh/OQs0EWpWw== - dependencies: - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/styled-system" "2.9.2" - "@chakra-ui/theme" "3.3.1" - lodash.mergewith "4.6.2" - -"@chakra-ui/theme@3.3.1": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/theme/-/theme-3.3.1.tgz#75c6cd0b5c70c0aa955068274ee4780f299bd8a4" - integrity sha512-Hft/VaT8GYnItGCBbgWd75ICrIrIFrR7lVOhV/dQnqtfGqsVDlrztbSErvMkoPKt0UgAkd9/o44jmZ6X4U2nZQ== - dependencies: - "@chakra-ui/anatomy" "2.2.2" - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/theme-tools" "2.1.2" - -"@chakra-ui/toast@7.0.2": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/toast/-/toast-7.0.2.tgz#d1c396bbfced12e22b010899731fd8cc294d53ec" - integrity sha512-yvRP8jFKRs/YnkuE41BVTq9nB2v/KDRmje9u6dgDmE5+1bFt3bwjdf9gVbif4u5Ve7F7BGk5E093ARRVtvLvXA== - dependencies: - "@chakra-ui/alert" "2.2.2" - "@chakra-ui/close-button" "2.1.1" - "@chakra-ui/portal" "2.1.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-use-timeout" "2.1.0" - "@chakra-ui/react-use-update-effect" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/styled-system" "2.9.2" - "@chakra-ui/theme" "3.3.1" - -"@chakra-ui/tooltip@2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/tooltip/-/tooltip-2.3.1.tgz#29fb8508a37bb6b20ab8dbb32bca6cd59b098796" - integrity sha512-Rh39GBn/bL4kZpuEMPPRwYNnccRCL+w9OqamWHIB3Qboxs6h8cOyXfIdGxjo72lvhu1QI/a4KFqkM3St+WfC0A== - dependencies: - "@chakra-ui/dom-utils" "2.1.0" - "@chakra-ui/popper" "3.1.0" - "@chakra-ui/portal" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-disclosure" "2.1.0" - "@chakra-ui/react-use-event-listener" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/transition@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/transition/-/transition-2.1.0.tgz#c8e95564f7ab356e78119780037bae5ad150c7b3" - integrity sha512-orkT6T/Dt+/+kVwJNy7zwJ+U2xAZ3EU7M3XCs45RBvUnZDr/u9vdmaM/3D/rOpmQJWgQBwKPJleUXrYWUagEDQ== - dependencies: - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/utils@2.0.15": - version "2.0.15" - resolved "https://registry.yarnpkg.com/@chakra-ui/utils/-/utils-2.0.15.tgz#bd800b1cff30eb5a5e8c36fa039f49984b4c5e4a" - integrity sha512-El4+jL0WSaYYs+rJbuYFDbjmfCcfGDmRY95GO4xwzit6YAPZBLcR65rOEwLps+XWluZTy1xdMrusg/hW0c1aAA== - dependencies: - "@types/lodash.mergewith" "4.6.7" - css-box-model "1.2.1" - framesync "6.1.2" - lodash.mergewith "4.6.2" - -"@chakra-ui/visually-hidden@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/visually-hidden/-/visually-hidden-2.2.0.tgz#9b0ecef8f01263ab808ba3bda7b36a0d91b4d5c1" - integrity sha512-KmKDg01SrQ7VbTD3+cPWf/UfpF5MSwm3v7MWi0n5t8HnnadT13MF0MJCDSXbBWnzLv1ZKJ6zlyAOeARWX+DpjQ== - -"@emotion/babel-plugin@^11.11.0": - version "11.11.0" - resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c" - integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ== - dependencies: - "@babel/helper-module-imports" "^7.16.7" - "@babel/runtime" "^7.18.3" - "@emotion/hash" "^0.9.1" - "@emotion/memoize" "^0.8.1" - "@emotion/serialize" "^1.1.2" - babel-plugin-macros "^3.1.0" - convert-source-map "^1.5.0" - escape-string-regexp "^4.0.0" - find-root "^1.1.0" - source-map "^0.5.7" - stylis "4.2.0" - -"@emotion/cache@^11.11.0": - version "11.11.0" - resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff" - integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ== - dependencies: - "@emotion/memoize" "^0.8.1" - "@emotion/sheet" "^1.2.2" - "@emotion/utils" "^1.2.1" - "@emotion/weak-memoize" "^0.3.1" - stylis "4.2.0" - -"@emotion/hash@^0.9.1": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" - integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== - -"@emotion/is-prop-valid@^0.8.2": - version "0.8.8" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" - integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== - dependencies: - "@emotion/memoize" "0.7.4" - -"@emotion/is-prop-valid@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" - integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw== - dependencies: - "@emotion/memoize" "^0.8.1" - -"@emotion/memoize@0.7.4": - version "0.7.4" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" - integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== - -"@emotion/memoize@^0.8.1": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" - integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== - -"@emotion/react@^11.11.1": - version "11.11.3" - resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.3.tgz#96b855dc40a2a55f52a72f518a41db4f69c31a25" - integrity sha512-Cnn0kuq4DoONOMcnoVsTOR8E+AdnKFf//6kUWc4LCdnxj31pZWn7rIULd6Y7/Js1PiPHzn7SKCM9vB/jBni8eA== - dependencies: - "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.11.0" - "@emotion/cache" "^11.11.0" - "@emotion/serialize" "^1.1.3" - "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" - "@emotion/utils" "^1.2.1" - "@emotion/weak-memoize" "^0.3.1" - hoist-non-react-statics "^3.3.1" - -"@emotion/serialize@^1.1.2", "@emotion/serialize@^1.1.3": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.3.tgz#84b77bfcfe3b7bb47d326602f640ccfcacd5ffb0" - integrity sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA== - dependencies: - "@emotion/hash" "^0.9.1" - "@emotion/memoize" "^0.8.1" - "@emotion/unitless" "^0.8.1" - "@emotion/utils" "^1.2.1" - csstype "^3.0.2" - -"@emotion/sheet@^1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec" - integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== - -"@emotion/styled@^11.11.0": - version "11.11.0" - resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.0.tgz#26b75e1b5a1b7a629d7c0a8b708fbf5a9cdce346" - integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== - dependencies: - "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.11.0" - "@emotion/is-prop-valid" "^1.2.1" - "@emotion/serialize" "^1.1.2" - "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" - "@emotion/utils" "^1.2.1" - -"@emotion/unitless@^0.8.1": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" - integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== - -"@emotion/use-insertion-effect-with-fallbacks@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963" - integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw== - -"@emotion/utils@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4" - integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg== - -"@emotion/weak-memoize@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6" - integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== - -"@esbuild/aix-ppc64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz#2acd20be6d4f0458bc8c784103495ff24f13b1d3" - integrity sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g== - -"@esbuild/android-arm64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz#b45d000017385c9051a4f03e17078abb935be220" - integrity sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q== - -"@esbuild/android-arm@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.11.tgz#f46f55414e1c3614ac682b29977792131238164c" - integrity sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw== - -"@esbuild/android-x64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.11.tgz#bfc01e91740b82011ef503c48f548950824922b2" - integrity sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg== - -"@esbuild/darwin-arm64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz#533fb7f5a08c37121d82c66198263dcc1bed29bf" - integrity sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ== - -"@esbuild/darwin-x64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz#62f3819eff7e4ddc656b7c6815a31cf9a1e7d98e" - integrity sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g== - -"@esbuild/freebsd-arm64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz#d478b4195aa3ca44160272dab85ef8baf4175b4a" - integrity sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA== - -"@esbuild/freebsd-x64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz#7bdcc1917409178257ca6a1a27fe06e797ec18a2" - integrity sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw== - -"@esbuild/linux-arm64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz#58ad4ff11685fcc735d7ff4ca759ab18fcfe4545" - integrity sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg== - -"@esbuild/linux-arm@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz#ce82246d873b5534d34de1e5c1b33026f35e60e3" - integrity sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q== - -"@esbuild/linux-ia32@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz#cbae1f313209affc74b80f4390c4c35c6ab83fa4" - integrity sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA== - -"@esbuild/linux-loong64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz#5f32aead1c3ec8f4cccdb7ed08b166224d4e9121" - integrity sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg== - -"@esbuild/linux-mips64el@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz#38eecf1cbb8c36a616261de858b3c10d03419af9" - integrity sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg== - -"@esbuild/linux-ppc64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz#9c5725a94e6ec15b93195e5a6afb821628afd912" - integrity sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA== - -"@esbuild/linux-riscv64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz#2dc4486d474a2a62bbe5870522a9a600e2acb916" - integrity sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ== - -"@esbuild/linux-s390x@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz#4ad8567df48f7dd4c71ec5b1753b6f37561a65a8" - integrity sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q== - -"@esbuild/linux-x64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz#b7390c4d5184f203ebe7ddaedf073df82a658766" - integrity sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA== - -"@esbuild/netbsd-x64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz#d633c09492a1721377f3bccedb2d821b911e813d" - integrity sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ== - -"@esbuild/openbsd-x64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz#17388c76e2f01125bf831a68c03a7ffccb65d1a2" - integrity sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw== - -"@esbuild/sunos-x64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz#e320636f00bb9f4fdf3a80e548cb743370d41767" - integrity sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ== - -"@esbuild/win32-arm64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz#c778b45a496e90b6fc373e2a2bb072f1441fe0ee" - integrity sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ== - -"@esbuild/win32-ia32@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz#481a65fee2e5cce74ec44823e6b09ecedcc5194c" - integrity sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg== - -"@esbuild/win32-x64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz#a5d300008960bb39677c46bf16f53ec70d8dee04" - integrity sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw== - -"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": - version "4.4.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - -"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" - integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== - -"@eslint/eslintrc@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" - integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.6.0" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/js@8.56.0": - version "8.56.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b" - integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== - -"@humanwhocodes/config-array@^0.11.13": - version "0.11.13" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" - integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ== - dependencies: - "@humanwhocodes/object-schema" "^2.0.1" - debug "^4.1.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" - integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== - -"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" - integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/resolve-uri@^3.1.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" - integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== - -"@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": - version "1.4.15" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - -"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.20" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" - integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@ledgerhq/devices@^8.2.0": - version "8.2.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-8.2.0.tgz#ef67bf49628252d1779acaa151b1a941acba790e" - integrity sha512-XROTW2gTmmuy+YPPDjdtKKTQ3mfxrPtKtV+a9QFbj8f5MnjVMV0Zpy1BIB4CyIMsVVi4z6+nI67auT7IlsM3SQ== - dependencies: - "@ledgerhq/errors" "^6.16.1" - "@ledgerhq/logs" "^6.12.0" - rxjs "^7.8.1" - semver "^7.3.5" - -"@ledgerhq/errors@^6.14.0", "@ledgerhq/errors@^6.16.1": - version "6.16.1" - resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-6.16.1.tgz#df650a9ba105397dee2e8c0ceddf6931c5b25ede" - integrity sha512-4D4wKecGzQpIu7sx03Sg4uE1e8g1oZUndWgw9gw776H8h9ov9c5TxPaldTn2j6orPECAERViLf7LTO4L5pE2Cw== - -"@ledgerhq/hw-transport@^6.28.8": - version "6.30.1" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-6.30.1.tgz#fd3c825f41197aeaf705e3c066f82843eaf48cae" - integrity sha512-Xeeo4nt33g5Fsp3CdsPvcc2Uk7dwYeKRSlSFLWcYAAKprf/PmxgNekhke1eaNU/wLoeLOWhY2Cki8F8w9nLMdQ== - dependencies: - "@ledgerhq/devices" "^8.2.0" - "@ledgerhq/errors" "^6.16.1" - "@ledgerhq/logs" "^6.12.0" - events "^3.3.0" - -"@ledgerhq/logs@^6.12.0": - version "6.12.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/logs/-/logs-6.12.0.tgz#ad903528bf3687a44da435d7b2479d724d374f5d" - integrity sha512-ExDoj1QV5eC6TEbMdLUMMk9cfvNKhhv5gXol4SmULRVCx/3iyCPhJ74nsb3S0Vb+/f+XujBEj3vQn5+cwS0fNA== - -"@ledgerhq/wallet-api-client-react@^1.1.2": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/wallet-api-client-react/-/wallet-api-client-react-1.3.0.tgz#955bf9d163d683dfe7feb87d06ee852adf8453ef" - integrity sha512-UYNKQ1Yp/ZieqY4SGKgkoxKXJ3t0Zj/PPnZDoOrG/YbAFd4r3bL4XvTMa5T+bIdjbqITTo7VRiA9mhk5ootLrA== - dependencies: - "@ledgerhq/wallet-api-client" "1.5.0" - -"@ledgerhq/wallet-api-client@1.5.0", "@ledgerhq/wallet-api-client@^1.2.1": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/wallet-api-client/-/wallet-api-client-1.5.0.tgz#2c9cbe87c3f5c19a7e95d67d1d1c72dd1200cb12" - integrity sha512-I07RlTmHw0uia5xhHa8Z3I7yVlYkxUWPfKWruh0vM6o0hDzPddGp+oDJZlriJIIrj2eHfaUCO1bEgycewPe0jA== - dependencies: - "@ledgerhq/hw-transport" "^6.28.8" - "@ledgerhq/wallet-api-core" "1.6.0" - bignumber.js "^9.1.2" - -"@ledgerhq/wallet-api-core@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/wallet-api-core/-/wallet-api-core-1.6.0.tgz#41492a9393d432e71e25606305ec61d141ebe6b3" - integrity sha512-nVPN3yu5+5pbhfFYh0iKmij5U7KVKZfpDkusXbj4yKvueKY8ZXU1wgvw1rDhgxlqu+s7JTA50MX56doyhm46Qg== - dependencies: - "@ledgerhq/errors" "^6.14.0" - bignumber.js "^9.1.2" - uuid "^9.0.0" - zod "^3.22.2" - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@pkgr/core@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.0.tgz#7d8dacb7fdef0e4387caf7396cbd77f179867d06" - integrity sha512-Zwq5OCzuwJC2jwqmpEQt7Ds1DTi6BWSwoGkbb1n9pO3hzb35BoJELx7c0T23iDkBGkh2e7tvOtjF3tr3OaQHDQ== - -"@popperjs/core@^2.9.3": - version "2.11.8" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" - integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== - -"@rollup/rollup-android-arm-eabi@4.9.2": - version "4.9.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.2.tgz#ccb02257556bacbc1e756ab9b0b973cea2c7a664" - integrity sha512-RKzxFxBHq9ysZ83fn8Iduv3A283K7zPPYuhL/z9CQuyFrjwpErJx0h4aeb/bnJ+q29GRLgJpY66ceQ/Wcsn3wA== - -"@rollup/rollup-android-arm64@4.9.2": - version "4.9.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.2.tgz#21bd0fbafdf442c6a17645b840f6a94556b0e9bb" - integrity sha512-yZ+MUbnwf3SHNWQKJyWh88ii2HbuHCFQnAYTeeO1Nb8SyEiWASEi5dQUygt3ClHWtA9My9RQAYkjvrsZ0WK8Xg== - -"@rollup/rollup-darwin-arm64@4.9.2": - version "4.9.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.2.tgz#9f2e5d5637677f9839dbe1622130d0592179136a" - integrity sha512-vqJ/pAUh95FLc/G/3+xPqlSBgilPnauVf2EXOQCZzhZJCXDXt/5A8mH/OzU6iWhb3CNk5hPJrh8pqJUPldN5zw== - -"@rollup/rollup-darwin-x64@4.9.2": - version "4.9.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.2.tgz#1b06291ff1c41af94d2786cd167188c5bf7caec9" - integrity sha512-otPHsN5LlvedOprd3SdfrRNhOahhVBwJpepVKUN58L0RnC29vOAej1vMEaVU6DadnpjivVsNTM5eNt0CcwTahw== - -"@rollup/rollup-linux-arm-gnueabihf@4.9.2": - version "4.9.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.2.tgz#147069948bba00f435122f411210624e72638ebf" - integrity sha512-ewG5yJSp+zYKBYQLbd1CUA7b1lSfIdo9zJShNTyc2ZP1rcPrqyZcNlsHgs7v1zhgfdS+kW0p5frc0aVqhZCiYQ== - -"@rollup/rollup-linux-arm64-gnu@4.9.2": - version "4.9.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.2.tgz#3a50f0e7ae6e444d11c61fce12783196454a4efb" - integrity sha512-pL6QtV26W52aCWTG1IuFV3FMPL1m4wbsRG+qijIvgFO/VBsiXJjDPE/uiMdHBAO6YcpV4KvpKtd0v3WFbaxBtg== - -"@rollup/rollup-linux-arm64-musl@4.9.2": - version "4.9.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.2.tgz#82b5e75484d91c25d4e649d018d9523e72d6dac2" - integrity sha512-On+cc5EpOaTwPSNetHXBuqylDW+765G/oqB9xGmWU3npEhCh8xu0xqHGUA+4xwZLqBbIZNcBlKSIYfkBm6ko7g== - -"@rollup/rollup-linux-riscv64-gnu@4.9.2": - version "4.9.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.2.tgz#ca96f2d43a553d73aec736e991c07010561bc7a9" - integrity sha512-Wnx/IVMSZ31D/cO9HSsU46FjrPWHqtdF8+0eyZ1zIB5a6hXaZXghUKpRrC4D5DcRTZOjml2oBhXoqfGYyXKipw== - -"@rollup/rollup-linux-x64-gnu@4.9.2": - version "4.9.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.2.tgz#db1cece244ea46706c0e1a522ec19ca0173abc55" - integrity sha512-ym5x1cj4mUAMBummxxRkI4pG5Vht1QMsJexwGP8547TZ0sox9fCLDHw9KCH9c1FO5d9GopvkaJsBIOkTKxksdw== - -"@rollup/rollup-linux-x64-musl@4.9.2": - version "4.9.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.2.tgz#c15b26b86827f75977bf59ebd41ce5d788713936" - integrity sha512-m0hYELHGXdYx64D6IDDg/1vOJEaiV8f1G/iO+tejvRCJNSwK4jJ15e38JQy5Q6dGkn1M/9KcyEOwqmlZ2kqaZg== - -"@rollup/rollup-win32-arm64-msvc@4.9.2": - version "4.9.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.2.tgz#60152948f9fb08e8c50c1555e334ca9f9f1f53aa" - integrity sha512-x1CWburlbN5JjG+juenuNa4KdedBdXLjZMp56nHFSHTOsb/MI2DYiGzLtRGHNMyydPGffGId+VgjOMrcltOksA== - -"@rollup/rollup-win32-ia32-msvc@4.9.2": - version "4.9.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.2.tgz#657288cff10311f997d8dbd648590441760ae6d9" - integrity sha512-VVzCB5yXR1QlfsH1Xw1zdzQ4Pxuzv+CPr5qpElpKhVxlxD3CRdfubAG9mJROl6/dmj5gVYDDWk8sC+j9BI9/kQ== - -"@rollup/rollup-win32-x64-msvc@4.9.2": - version "4.9.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.2.tgz#830f3a3fba67f6216a5884368431918029045afe" - integrity sha512-SYRedJi+mweatroB+6TTnJYLts0L0bosg531xnQWtklOI6dezEagx4Q0qDyvRdK+qgdA3YZpjjGuPFtxBmddBA== - -"@thesis-co/eslint-config@^0.6.1": - version "0.6.1" - resolved "https://registry.yarnpkg.com/@thesis-co/eslint-config/-/eslint-config-0.6.1.tgz#70e419cd02b271ae447eebdefaa5359dca301285" - integrity sha512-0vJCCI4UwUdniDCQeTFlMBT+bSp5pGkrtHrZrG2vmyLZwSVdJNtInjkBc/Jd0sGfMtPo3pqQRwA40Zo80lPi+Q== - dependencies: - "@thesis-co/prettier-config" "github:thesis/prettier-config" - "@typescript-eslint/eslint-plugin" ">=6.4.1" - "@typescript-eslint/parser" ">=6.4.1" - eslint-config-airbnb "^19.0.4" - eslint-config-airbnb-base "^15.0.0" - eslint-config-airbnb-typescript "^17.1.0" - eslint-config-prettier "^9.0.0" - eslint-plugin-import "^2.28.1" - eslint-plugin-jsx-a11y "^6.7.1" - eslint-plugin-no-only-tests "^3.1.0" - eslint-plugin-prettier "^5.0.0" - eslint-plugin-react "^7.33.2" - eslint-plugin-react-hooks "^4.6.0" - -"@thesis-co/prettier-config@github:thesis/prettier-config": - version "0.0.2" - resolved "https://codeload.github.com/thesis/prettier-config/tar.gz/daeaac564056a7885e4366ce12bfde6fd823fc90" - -"@types/babel__core@^7.20.5": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" - integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== - dependencies: - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - -"@types/babel__generator@*": - version "7.6.8" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" - integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== - dependencies: - "@babel/types" "^7.0.0" - -"@types/babel__template@*": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" - integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - -"@types/babel__traverse@*": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.5.tgz#7b7502be0aa80cc4ef22978846b983edaafcd4dd" - integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== - dependencies: - "@babel/types" "^7.20.7" - -"@types/json-schema@^7.0.12": - version "7.0.15" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" - integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== - -"@types/lodash.mergewith@4.6.7": - version "4.6.7" - resolved "https://registry.yarnpkg.com/@types/lodash.mergewith/-/lodash.mergewith-4.6.7.tgz#eaa65aa5872abdd282f271eae447b115b2757212" - integrity sha512-3m+lkO5CLRRYU0fhGRp7zbsGi6+BZj0uTVSwvcKU+nSlhjA9/QRNfuSGnD2mX6hQA7ZbmcCkzk5h4ZYGOtk14A== - dependencies: - "@types/lodash" "*" - -"@types/lodash@*": - version "4.14.202" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8" - integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ== - -"@types/parse-json@^4.0.0": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" - integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== - -"@types/prop-types@*": - version "15.7.11" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563" - integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== - -"@types/react-dom@^18.2.17": - version "18.2.18" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.18.tgz#16946e6cd43971256d874bc3d0a72074bb8571dd" - integrity sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw== - dependencies: - "@types/react" "*" - -"@types/react@*", "@types/react@^18.2.38": - version "18.2.46" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.46.tgz#f04d6c528f8f136ea66333bc66abcae46e2680df" - integrity sha512-nNCvVBcZlvX4NU1nRRNV/mFl1nNRuTuslAJglQsq+8ldXe5Xv0Wd2f7WTE3jOxhLH2BFfiZGC6GCp+kHQbgG+w== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - -"@types/scheduler@*": - version "0.16.8" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" - integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== - -"@types/semver@^7.5.0": - version "7.5.6" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" - integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== - -"@typescript-eslint/eslint-plugin@>=6.4.1", "@typescript-eslint/eslint-plugin@^6.12.0": - version "6.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.17.0.tgz#dfc38f790704ba8a54a1277c51efdb489f6ecf9f" - integrity sha512-Vih/4xLXmY7V490dGwBQJTpIZxH4ZFH6eCVmQ4RFkB+wmaCTDAx4dtgoWwMNGKLkqRY1L6rPqzEbjorRnDo4rQ== - dependencies: - "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "6.17.0" - "@typescript-eslint/type-utils" "6.17.0" - "@typescript-eslint/utils" "6.17.0" - "@typescript-eslint/visitor-keys" "6.17.0" - debug "^4.3.4" - graphemer "^1.4.0" - ignore "^5.2.4" - natural-compare "^1.4.0" - semver "^7.5.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/parser@>=6.4.1", "@typescript-eslint/parser@^6.12.0": - version "6.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.17.0.tgz#8cd7a0599888ca6056082225b2fdf9a635bf32a1" - integrity sha512-C4bBaX2orvhK+LlwrY8oWGmSl4WolCfYm513gEccdWZj0CwGadbIADb0FtVEcI+WzUyjyoBj2JRP8g25E6IB8A== - dependencies: - "@typescript-eslint/scope-manager" "6.17.0" - "@typescript-eslint/types" "6.17.0" - "@typescript-eslint/typescript-estree" "6.17.0" - "@typescript-eslint/visitor-keys" "6.17.0" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@6.17.0": - version "6.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.17.0.tgz#70e6c1334d0d76562dfa61aed9009c140a7601b4" - integrity sha512-RX7a8lwgOi7am0k17NUO0+ZmMOX4PpjLtLRgLmT1d3lBYdWH4ssBUbwdmc5pdRX8rXon8v9x8vaoOSpkHfcXGA== - dependencies: - "@typescript-eslint/types" "6.17.0" - "@typescript-eslint/visitor-keys" "6.17.0" - -"@typescript-eslint/type-utils@6.17.0": - version "6.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.17.0.tgz#5febad3f523e393006614cbda28b826925b728d5" - integrity sha512-hDXcWmnbtn4P2B37ka3nil3yi3VCQO2QEB9gBiHJmQp5wmyQWqnjA85+ZcE8c4FqnaB6lBwMrPkgd4aBYz3iNg== - dependencies: - "@typescript-eslint/typescript-estree" "6.17.0" - "@typescript-eslint/utils" "6.17.0" - debug "^4.3.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/types@6.17.0": - version "6.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.17.0.tgz#844a92eb7c527110bf9a7d177e3f22bd5a2f40cb" - integrity sha512-qRKs9tvc3a4RBcL/9PXtKSehI/q8wuU9xYJxe97WFxnzH8NWWtcW3ffNS+EWg8uPvIerhjsEZ+rHtDqOCiH57A== - -"@typescript-eslint/typescript-estree@6.17.0": - version "6.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.17.0.tgz#b913d19886c52d8dc3db856903a36c6c64fd62aa" - integrity sha512-gVQe+SLdNPfjlJn5VNGhlOhrXz4cajwFd5kAgWtZ9dCZf4XJf8xmgCTLIqec7aha3JwgLI2CK6GY1043FRxZwg== - dependencies: - "@typescript-eslint/types" "6.17.0" - "@typescript-eslint/visitor-keys" "6.17.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - minimatch "9.0.3" - semver "^7.5.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/utils@6.17.0": - version "6.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.17.0.tgz#f2b16d4c9984474656c420438cdede7eccd4079e" - integrity sha512-LofsSPjN/ITNkzV47hxas2JCsNCEnGhVvocfyOcLzT9c/tSZE7SfhS/iWtzP1lKNOEfLhRTZz6xqI8N2RzweSQ== - dependencies: - "@eslint-community/eslint-utils" "^4.4.0" - "@types/json-schema" "^7.0.12" - "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.17.0" - "@typescript-eslint/types" "6.17.0" - "@typescript-eslint/typescript-estree" "6.17.0" - semver "^7.5.4" - -"@typescript-eslint/visitor-keys@6.17.0": - version "6.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.17.0.tgz#3ed043709c39b43ec1e58694f329e0b0430c26b6" - integrity sha512-H6VwB/k3IuIeQOyYczyyKN8wH6ed8EwliaYHLxOIhyF0dYEIsN8+Bk3GE19qafeMKyZJJHP8+O1HiFhFLUNKSg== - dependencies: - "@typescript-eslint/types" "6.17.0" - eslint-visitor-keys "^3.4.1" - -"@ungap/structured-clone@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" - integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== - -"@vitejs/plugin-react@^4.2.0": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.2.1.tgz#744d8e4fcb120fc3dbaa471dadd3483f5a304bb9" - integrity sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ== - dependencies: - "@babel/core" "^7.23.5" - "@babel/plugin-transform-react-jsx-self" "^7.23.3" - "@babel/plugin-transform-react-jsx-source" "^7.23.3" - "@types/babel__core" "^7.20.5" - react-refresh "^0.14.0" - -"@zag-js/dom-query@0.16.0": - version "0.16.0" - resolved "https://registry.yarnpkg.com/@zag-js/dom-query/-/dom-query-0.16.0.tgz#bca46bcd78f78c900064478646d95f9781ed098e" - integrity sha512-Oqhd6+biWyKnhKwFFuZrrf6lxBz2tX2pRQe6grUnYwO6HJ8BcbqZomy2lpOdr+3itlaUqx+Ywj5E5ZZDr/LBfQ== - -"@zag-js/element-size@0.10.5": - version "0.10.5" - resolved "https://registry.yarnpkg.com/@zag-js/element-size/-/element-size-0.10.5.tgz#a24bad2eeb7e2c8709e32be5336e158e1a1a174f" - integrity sha512-uQre5IidULANvVkNOBQ1tfgwTQcGl4hliPSe69Fct1VfYb2Fd0jdAcGzqQgPhfrXFpR62MxLPB7erxJ/ngtL8w== - -"@zag-js/focus-visible@0.16.0": - version "0.16.0" - resolved "https://registry.yarnpkg.com/@zag-js/focus-visible/-/focus-visible-0.16.0.tgz#c9e53e3dbab0f2649d04a489bb379f5800f4f069" - integrity sha512-a7U/HSopvQbrDU4GLerpqiMcHKEkQkNPeDZJWz38cw/6Upunh41GjHetq5TB84hxyCaDzJ6q2nEdNoBQfC0FKA== - dependencies: - "@zag-js/dom-query" "0.16.0" - -acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn@^8.9.0: - version "8.11.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" - integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== - -ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -aria-hidden@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.3.tgz#14aeb7fb692bbb72d69bebfa47279c1fd725e954" - integrity sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ== - dependencies: - tslib "^2.0.0" - -aria-query@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" - integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== - dependencies: - dequal "^2.0.3" - -array-buffer-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" - integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== - dependencies: - call-bind "^1.0.2" - is-array-buffer "^3.0.1" - -array-includes@^3.1.6, array-includes@^3.1.7: - version "3.1.7" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" - integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-string "^1.0.7" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array.prototype.findlastindex@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207" - integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.2.1" - -array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" - integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -array.prototype.flatmap@^1.3.1, array.prototype.flatmap@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" - integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -array.prototype.tosorted@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz#620eff7442503d66c799d95503f82b475745cefd" - integrity sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.2.1" - -arraybuffer.prototype.slice@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" - integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== - dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-array-buffer "^3.0.2" - is-shared-array-buffer "^1.0.2" - -ast-types-flow@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6" - integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== - -asynciterator.prototype@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz#8c5df0514936cdd133604dfcc9d3fb93f09b2b62" - integrity sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg== - dependencies: - has-symbols "^1.0.3" - -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== - -axe-core@=4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" - integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== - -axobject-query@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" - integrity sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg== - dependencies: - dequal "^2.0.3" - -babel-plugin-macros@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" - integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== - dependencies: - "@babel/runtime" "^7.12.5" - cosmiconfig "^7.0.0" - resolve "^1.19.0" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -bignumber.js@^9.1.2: - version "9.1.2" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" - integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browserslist@^4.22.2: - version "4.22.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.2.tgz#704c4943072bd81ea18997f3bd2180e89c77874b" - integrity sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A== - dependencies: - caniuse-lite "^1.0.30001565" - electron-to-chromium "^1.4.601" - node-releases "^2.0.14" - update-browserslist-db "^1.0.13" - -call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" - integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== - dependencies: - function-bind "^1.1.2" - get-intrinsic "^1.2.1" - set-function-length "^1.1.1" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -caniuse-lite@^1.0.30001565: - version "1.0.30001572" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001572.tgz#1ccf7dc92d2ee2f92ed3a54e11b7b4a3041acfa0" - integrity sha512-1Pbh5FLmn5y4+QhNyJE9j3/7dK44dGB83/ZMjv/qJk86TvDbjk0LosiZo0i0WB0Vx607qMX9jYrn1VLHCkN4rw== - -chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color2k@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/color2k/-/color2k-2.0.3.tgz#a771244f6b6285541c82aa65ff0a0c624046e533" - integrity sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog== - -compute-scroll-into-view@3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-3.0.3.tgz#c418900a5c56e2b04b885b54995df164535962b1" - integrity sha512-nadqwNxghAGTamwIqQSG433W6OADZx2vCo3UXHNrzTRHK/htu+7+L0zhjEoaeaQVNAi3YgqWDv8+tzf0hRfR+A== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -confusing-browser-globals@^1.0.10: - version "1.0.11" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" - integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== - -convert-source-map@^1.5.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" - integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== - -convert-source-map@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" - integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== - -copy-to-clipboard@3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0" - integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== - dependencies: - toggle-selection "^1.0.6" - -cosmiconfig@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" - integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - -cross-spawn@^7.0.2: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -css-box-model@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/css-box-model/-/css-box-model-1.2.1.tgz#59951d3b81fd6b2074a62d49444415b0d2b4d7c1" - integrity sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw== - dependencies: - tiny-invariant "^1.0.6" - -csstype@^3.0.2, csstype@^3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" - integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== - -damerau-levenshtein@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" - integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== - -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -deep-is@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -define-data-property@^1.0.1, define-data-property@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" - integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== - dependencies: - get-intrinsic "^1.2.1" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - -define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" - integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== - dependencies: - define-data-property "^1.0.1" - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -dequal@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" - integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== - -detect-node-es@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493" - integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -electron-to-chromium@^1.4.601: - version "1.4.616" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz#4bddbc2c76e1e9dbf449ecd5da3d8119826ea4fb" - integrity sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.22.1: - version "1.22.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" - integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== - dependencies: - array-buffer-byte-length "^1.0.0" - arraybuffer.prototype.slice "^1.0.2" - available-typed-arrays "^1.0.5" - call-bind "^1.0.5" - es-set-tostringtag "^2.0.1" - es-to-primitive "^1.2.1" - function.prototype.name "^1.1.6" - get-intrinsic "^1.2.2" - get-symbol-description "^1.0.0" - globalthis "^1.0.3" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - internal-slot "^1.0.5" - is-array-buffer "^3.0.2" - is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-typed-array "^1.1.12" - is-weakref "^1.0.2" - object-inspect "^1.13.1" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.1" - safe-array-concat "^1.0.1" - safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.8" - string.prototype.trimend "^1.0.7" - string.prototype.trimstart "^1.0.7" - typed-array-buffer "^1.0.0" - typed-array-byte-length "^1.0.0" - typed-array-byte-offset "^1.0.0" - typed-array-length "^1.0.4" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.13" - -es-iterator-helpers@^1.0.12, es-iterator-helpers@^1.0.15: - version "1.0.15" - resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz#bd81d275ac766431d19305923707c3efd9f1ae40" - integrity sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g== - dependencies: - asynciterator.prototype "^1.0.0" - call-bind "^1.0.2" - define-properties "^1.2.1" - es-abstract "^1.22.1" - es-set-tostringtag "^2.0.1" - function-bind "^1.1.1" - get-intrinsic "^1.2.1" - globalthis "^1.0.3" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - internal-slot "^1.0.5" - iterator.prototype "^1.1.2" - safe-array-concat "^1.0.1" - -es-set-tostringtag@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" - integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== - dependencies: - get-intrinsic "^1.2.2" - has-tostringtag "^1.0.0" - hasown "^2.0.0" - -es-shim-unscopables@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" - integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== - dependencies: - hasown "^2.0.0" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -esbuild@^0.19.3: - version "0.19.11" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.11.tgz#4a02dca031e768b5556606e1b468fe72e3325d96" - integrity sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA== - optionalDependencies: - "@esbuild/aix-ppc64" "0.19.11" - "@esbuild/android-arm" "0.19.11" - "@esbuild/android-arm64" "0.19.11" - "@esbuild/android-x64" "0.19.11" - "@esbuild/darwin-arm64" "0.19.11" - "@esbuild/darwin-x64" "0.19.11" - "@esbuild/freebsd-arm64" "0.19.11" - "@esbuild/freebsd-x64" "0.19.11" - "@esbuild/linux-arm" "0.19.11" - "@esbuild/linux-arm64" "0.19.11" - "@esbuild/linux-ia32" "0.19.11" - "@esbuild/linux-loong64" "0.19.11" - "@esbuild/linux-mips64el" "0.19.11" - "@esbuild/linux-ppc64" "0.19.11" - "@esbuild/linux-riscv64" "0.19.11" - "@esbuild/linux-s390x" "0.19.11" - "@esbuild/linux-x64" "0.19.11" - "@esbuild/netbsd-x64" "0.19.11" - "@esbuild/openbsd-x64" "0.19.11" - "@esbuild/sunos-x64" "0.19.11" - "@esbuild/win32-arm64" "0.19.11" - "@esbuild/win32-ia32" "0.19.11" - "@esbuild/win32-x64" "0.19.11" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eslint-config-airbnb-base@^15.0.0: - version "15.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz#6b09add90ac79c2f8d723a2580e07f3925afd236" - integrity sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig== - dependencies: - confusing-browser-globals "^1.0.10" - object.assign "^4.1.2" - object.entries "^1.1.5" - semver "^6.3.0" - -eslint-config-airbnb-typescript@^17.1.0: - version "17.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-17.1.0.tgz#fda960eee4a510f092a9a1c139035ac588937ddc" - integrity sha512-GPxI5URre6dDpJ0CtcthSZVBAfI+Uw7un5OYNVxP2EYi3H81Jw701yFP7AU+/vCE7xBtFmjge7kfhhk4+RAiig== - dependencies: - eslint-config-airbnb-base "^15.0.0" - -eslint-config-airbnb@^19.0.4: - version "19.0.4" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz#84d4c3490ad70a0ffa571138ebcdea6ab085fdc3" - integrity sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew== - dependencies: - eslint-config-airbnb-base "^15.0.0" - object.assign "^4.1.2" - object.entries "^1.1.5" - -eslint-config-prettier@^9.0.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f" - integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== - -eslint-import-resolver-node@^0.3.9: - version "0.3.9" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" - integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== - dependencies: - debug "^3.2.7" - is-core-module "^2.13.0" - resolve "^1.22.4" - -eslint-module-utils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" - integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== - dependencies: - debug "^3.2.7" - -eslint-plugin-import@^2.28.1: - version "2.29.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" - integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== - dependencies: - array-includes "^3.1.7" - array.prototype.findlastindex "^1.2.3" - array.prototype.flat "^1.3.2" - array.prototype.flatmap "^1.3.2" - debug "^3.2.7" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.9" - eslint-module-utils "^2.8.0" - hasown "^2.0.0" - is-core-module "^2.13.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.fromentries "^2.0.7" - object.groupby "^1.0.1" - object.values "^1.1.7" - semver "^6.3.1" - tsconfig-paths "^3.15.0" - -eslint-plugin-jsx-a11y@^6.7.1: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz#2fa9c701d44fcd722b7c771ec322432857fcbad2" - integrity sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA== - dependencies: - "@babel/runtime" "^7.23.2" - aria-query "^5.3.0" - array-includes "^3.1.7" - array.prototype.flatmap "^1.3.2" - ast-types-flow "^0.0.8" - axe-core "=4.7.0" - axobject-query "^3.2.1" - damerau-levenshtein "^1.0.8" - emoji-regex "^9.2.2" - es-iterator-helpers "^1.0.15" - hasown "^2.0.0" - jsx-ast-utils "^3.3.5" - language-tags "^1.0.9" - minimatch "^3.1.2" - object.entries "^1.1.7" - object.fromentries "^2.0.7" - -eslint-plugin-no-only-tests@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.1.0.tgz#f38e4935c6c6c4842bf158b64aaa20c366fe171b" - integrity sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw== - -eslint-plugin-prettier@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.2.tgz#584c94d4bf31329b2d4cbeb10fd600d17d6de742" - integrity sha512-dhlpWc9vOwohcWmClFcA+HjlvUpuyynYs0Rf+L/P6/0iQE6vlHW9l5bkfzN62/Stm9fbq8ku46qzde76T1xlSg== - dependencies: - prettier-linter-helpers "^1.0.0" - synckit "^0.8.6" - -eslint-plugin-react-hooks@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" - integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== - -eslint-plugin-react@^7.33.2: - version "7.33.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz#69ee09443ffc583927eafe86ffebb470ee737608" - integrity sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw== - dependencies: - array-includes "^3.1.6" - array.prototype.flatmap "^1.3.1" - array.prototype.tosorted "^1.1.1" - doctrine "^2.1.0" - es-iterator-helpers "^1.0.12" - estraverse "^5.3.0" - jsx-ast-utils "^2.4.1 || ^3.0.0" - minimatch "^3.1.2" - object.entries "^1.1.6" - object.fromentries "^2.0.6" - object.hasown "^1.1.2" - object.values "^1.1.6" - prop-types "^15.8.1" - resolve "^2.0.0-next.4" - semver "^6.3.1" - string.prototype.matchall "^4.0.8" - -eslint-scope@^7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" - integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: - version "3.4.3" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" - integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== - -eslint@^8.54.0: - version "8.56.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.56.0.tgz#4957ce8da409dc0809f99ab07a1b94832ab74b15" - integrity sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.4" - "@eslint/js" "8.56.0" - "@humanwhocodes/config-array" "^0.11.13" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - "@ungap/structured-clone" "^1.2.0" - ajv "^6.12.4" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.2" - eslint-visitor-keys "^3.4.3" - espree "^9.6.1" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" - ignore "^5.2.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - -espree@^9.6.0, espree@^9.6.1: - version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" - integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== - dependencies: - acorn "^8.9.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -events@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-diff@^1.1.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" - integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== - -fast-glob@^3.2.9: - version "3.3.2" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" - integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fastq@^1.6.0: - version "1.16.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.16.0.tgz#83b9a9375692db77a822df081edb6a9cf6839320" - integrity sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA== - dependencies: - reusify "^1.0.4" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-root@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" - integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -flat-cache@^3.0.4: - version "3.2.0" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" - integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== - dependencies: - flatted "^3.2.9" - keyv "^4.5.3" - rimraf "^3.0.2" - -flatted@^3.2.9: - version "3.2.9" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" - integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== - -focus-lock@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-1.0.0.tgz#2c50d8ce59d3d6608cda2672be9e65812459206c" - integrity sha512-a8Ge6cdKh9za/GZR/qtigTAk7SrGore56EFcoMshClsh7FLk1zwszc/ltuMfKhx56qeuyL/jWQ4J4axou0iJ9w== - dependencies: - tslib "^2.0.3" - -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - -framer-motion@^10.16.5: - version "10.16.16" - resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-10.16.16.tgz#a10a03e1190a717109163cfff212a84c8ad11b0c" - integrity sha512-je6j91rd7NmUX7L1XHouwJ4v3R+SO4umso2LUcgOct3rHZ0PajZ80ETYZTajzEXEl9DlKyzjyt4AvGQ+lrebOw== - dependencies: - tslib "^2.4.0" - optionalDependencies: - "@emotion/is-prop-valid" "^0.8.2" - -framesync@6.1.2: - version "6.1.2" - resolved "https://registry.yarnpkg.com/framesync/-/framesync-6.1.2.tgz#755eff2fb5b8f3b4d2b266dd18121b300aefea27" - integrity sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g== - dependencies: - tslib "2.4.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@~2.3.2, fsevents@~2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - -function-bind@^1.1.1, function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - -function.prototype.name@^1.1.5, function.prototype.name@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" - integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - functions-have-names "^1.2.3" - -functions-have-names@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" - integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== - dependencies: - function-bind "^1.1.2" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - -get-nonce@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" - integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob@^7.1.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^13.19.0: - version "13.24.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" - integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== - dependencies: - type-fest "^0.20.2" - -globalthis@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" - integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== - dependencies: - define-properties "^1.1.3" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - -graphemer@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" - integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== - -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-property-descriptors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" - integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== - dependencies: - get-intrinsic "^1.2.2" - -has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== - -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -hasown@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" - integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== - dependencies: - function-bind "^1.1.2" - -hoist-non-react-statics@^3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" - integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== - dependencies: - react-is "^16.7.0" - -ignore@^5.2.0, ignore@^5.2.4: - version "5.3.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" - integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== - -import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -internal-slot@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" - integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== - dependencies: - get-intrinsic "^1.2.2" - hasown "^2.0.0" - side-channel "^1.0.4" - -invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" - integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.0" - is-typed-array "^1.1.10" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-async-function@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.0.0.tgz#8e4418efd3e5d3a6ebb0164c05ef5afb69aa9646" - integrity sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA== - dependencies: - has-tostringtag "^1.0.0" - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-core-module@^2.13.0, is-core-module@^2.13.1: - version "2.13.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" - integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== - dependencies: - hasown "^2.0.0" - -is-date-object@^1.0.1, is-date-object@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-finalizationregistry@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz#c8749b65f17c133313e661b1289b95ad3dbd62e6" - integrity sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw== - dependencies: - call-bind "^1.0.2" - -is-generator-function@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" - integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== - dependencies: - has-tostringtag "^1.0.0" - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-map@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" - integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== - -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-set@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" - integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== - -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: - version "1.1.12" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" - integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== - dependencies: - which-typed-array "^1.1.11" - -is-weakmap@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" - integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== - -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - -is-weakset@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" - integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -iterator.prototype@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.2.tgz#5e29c8924f01916cb9335f1ff80619dcff22b0c0" - integrity sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w== - dependencies: - define-properties "^1.2.1" - get-intrinsic "^1.2.1" - has-symbols "^1.0.3" - reflect.getprototypeof "^1.0.4" - set-function-name "^2.0.1" - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -json-buffer@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" - integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json5@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" - integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== - dependencies: - minimist "^1.2.0" - -json5@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: - version "3.3.5" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" - integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== - dependencies: - array-includes "^3.1.6" - array.prototype.flat "^1.3.1" - object.assign "^4.1.4" - object.values "^1.1.6" - -keyv@^4.5.3: - version "4.5.4" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" - integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== - dependencies: - json-buffer "3.0.1" - -language-subtag-registry@^0.3.20: - version "0.3.22" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" - integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== - -language-tags@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.9.tgz#1ffdcd0ec0fafb4b1be7f8b11f306ad0f9c08777" - integrity sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA== - dependencies: - language-subtag-registry "^0.3.20" - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.mergewith@4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" - integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== - -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -minimatch@9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.0, minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -nanoid@^3.3.7: - version "3.3.7" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" - integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -node-releases@^2.0.14: - version "2.0.14" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" - integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== - -object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-inspect@^1.13.1, object-inspect@^1.9.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" - integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.2, object.assign@^4.1.4: - version "4.1.5" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" - integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== - dependencies: - call-bind "^1.0.5" - define-properties "^1.2.1" - has-symbols "^1.0.3" - object-keys "^1.1.1" - -object.entries@^1.1.5, object.entries@^1.1.6, object.entries@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.7.tgz#2b47760e2a2e3a752f39dd874655c61a7f03c131" - integrity sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -object.fromentries@^2.0.6, object.fromentries@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" - integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -object.groupby@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" - integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - -object.hasown@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.3.tgz#6a5f2897bb4d3668b8e79364f98ccf971bda55ae" - integrity sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA== - dependencies: - define-properties "^1.2.0" - es-abstract "^1.22.1" - -object.values@^1.1.6, object.values@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" - integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -optionator@^0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== - dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -postcss@^8.4.32: - version "8.4.32" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.32.tgz#1dac6ac51ab19adb21b8b34fd2d93a86440ef6c9" - integrity sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw== - dependencies: - nanoid "^3.3.7" - picocolors "^1.0.0" - source-map-js "^1.0.2" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" - integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== - dependencies: - fast-diff "^1.1.2" - -prettier@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.1.1.tgz#6ba9f23165d690b6cbdaa88cb0807278f7019848" - integrity sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw== - -prop-types@^15.6.2, prop-types@^15.8.1: - version "15.8.1" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" - integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.13.1" - -punycode@^2.1.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" - integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -react-clientside-effect@^1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz#29f9b14e944a376b03fb650eed2a754dd128ea3a" - integrity sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg== - dependencies: - "@babel/runtime" "^7.12.13" - -react-dom@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" - integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== - dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.0" - -react-fast-compare@3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" - integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== - -react-focus-lock@^2.9.4: - version "2.9.6" - resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.9.6.tgz#cad168a150fdd72d5ab2419ba8e62780788011b1" - integrity sha512-B7gYnCjHNrNYwY2juS71dHbf0+UpXXojt02svxybj8N5bxceAkzPChKEncHuratjUHkIFNCn06k2qj1DRlzTug== - dependencies: - "@babel/runtime" "^7.0.0" - focus-lock "^1.0.0" - prop-types "^15.6.2" - react-clientside-effect "^1.2.6" - use-callback-ref "^1.3.0" - use-sidecar "^1.1.2" - -react-is@^16.13.1, react-is@^16.7.0: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -react-refresh@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" - integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ== - -react-remove-scroll-bar@^2.3.4: - version "2.3.4" - resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz#53e272d7a5cb8242990c7f144c44d8bd8ab5afd9" - integrity sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A== - dependencies: - react-style-singleton "^2.2.1" - tslib "^2.0.0" - -react-remove-scroll@^2.5.6: - version "2.5.7" - resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz#15a1fd038e8497f65a695bf26a4a57970cac1ccb" - integrity sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA== - dependencies: - react-remove-scroll-bar "^2.3.4" - react-style-singleton "^2.2.1" - tslib "^2.1.0" - use-callback-ref "^1.3.0" - use-sidecar "^1.1.2" - -react-style-singleton@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4" - integrity sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g== - dependencies: - get-nonce "^1.0.0" - invariant "^2.2.4" - tslib "^2.0.0" - -react@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" - integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== - dependencies: - loose-envify "^1.1.0" - -reflect.getprototypeof@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3" - integrity sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - globalthis "^1.0.3" - which-builtin-type "^1.1.3" - -regenerator-runtime@^0.14.0: - version "0.14.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" - integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== - -regexp.prototype.flags@^1.5.0, regexp.prototype.flags@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" - integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - set-function-name "^2.0.0" - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve@^1.19.0, resolve@^1.22.4: - version "1.22.8" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" - integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -resolve@^2.0.0-next.4: - version "2.0.0-next.5" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" - integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -rollup@^4.2.0: - version "4.9.2" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.9.2.tgz#19d730219b7ec5f51372c6cf15cfb841990489fe" - integrity sha512-66RB8OtFKUTozmVEh3qyNfH+b+z2RXBVloqO2KCC/pjFaGaHtxP9fVfOQKPSGXg2mElmjmxjW/fZ7iKrEpMH5Q== - optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.9.2" - "@rollup/rollup-android-arm64" "4.9.2" - "@rollup/rollup-darwin-arm64" "4.9.2" - "@rollup/rollup-darwin-x64" "4.9.2" - "@rollup/rollup-linux-arm-gnueabihf" "4.9.2" - "@rollup/rollup-linux-arm64-gnu" "4.9.2" - "@rollup/rollup-linux-arm64-musl" "4.9.2" - "@rollup/rollup-linux-riscv64-gnu" "4.9.2" - "@rollup/rollup-linux-x64-gnu" "4.9.2" - "@rollup/rollup-linux-x64-musl" "4.9.2" - "@rollup/rollup-win32-arm64-msvc" "4.9.2" - "@rollup/rollup-win32-ia32-msvc" "4.9.2" - "@rollup/rollup-win32-x64-msvc" "4.9.2" - fsevents "~2.3.2" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -rxjs@^7.8.1: - version "7.8.1" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" - integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== - dependencies: - tslib "^2.1.0" - -safe-array-concat@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" - integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - has-symbols "^1.0.3" - isarray "^2.0.5" - -safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-regex "^1.1.4" - -scheduler@^0.23.0: - version "0.23.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" - integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== - dependencies: - loose-envify "^1.1.0" - -semver@^6.3.0, semver@^6.3.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^7.3.5, semver@^7.5.4: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -set-function-length@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" - integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== - dependencies: - define-data-property "^1.1.1" - get-intrinsic "^1.2.1" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - -set-function-name@^2.0.0, set-function-name@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" - integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== - dependencies: - define-data-property "^1.0.1" - functions-have-names "^1.2.3" - has-property-descriptors "^1.0.0" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -source-map-js@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" - integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== - -source-map@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== - -string.prototype.matchall@^4.0.8: - version "4.0.10" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz#a1553eb532221d4180c51581d6072cd65d1ee100" - integrity sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - has-symbols "^1.0.3" - internal-slot "^1.0.5" - regexp.prototype.flags "^1.5.0" - set-function-name "^2.0.0" - side-channel "^1.0.4" - -string.prototype.trim@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" - integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -string.prototype.trimend@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" - integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -string.prototype.trimstart@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" - integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -stylis@4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" - integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -synckit@^0.8.6: - version "0.8.8" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.8.tgz#fe7fe446518e3d3d49f5e429f443cf08b6edfcd7" - integrity sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ== - dependencies: - "@pkgr/core" "^0.1.0" - tslib "^2.6.2" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -tiny-invariant@^1.0.6: - version "1.3.1" - resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" - integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toggle-selection@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" - integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== - -ts-api-utils@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" - integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== - -tsconfig-paths@^3.15.0: - version "3.15.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" - integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== - -tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -typed-array-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" - integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - is-typed-array "^1.1.10" - -typed-array-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" - integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" - -typed-array-byte-offset@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" - integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" - -typed-array-length@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" - integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - is-typed-array "^1.1.9" - -typescript@^5.3.2: - version "5.3.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" - integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== - -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" - -update-browserslist-db@^1.0.13: - version "1.0.13" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" - integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -use-callback-ref@^1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.1.tgz#9be64c3902cbd72b07fe55e56408ae3a26036fd0" - integrity sha512-Lg4Vx1XZQauB42Hw3kK7JM6yjVjgFmFC5/Ab797s79aARomD2nEErc4mCgM8EZrARLmmbWpi5DGCadmK50DcAQ== - dependencies: - tslib "^2.0.0" - -use-sidecar@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2" - integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw== - dependencies: - detect-node-es "^1.1.0" - tslib "^2.0.0" - -uuid@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" - integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== - -vite@^5.0.2: - version "5.0.10" - resolved "https://registry.yarnpkg.com/vite/-/vite-5.0.10.tgz#1e13ef5c3cf5aa4eed81f5df6d107b3c3f1f6356" - integrity sha512-2P8J7WWgmc355HUMlFrwofacvr98DAjoE52BfdbwQtyLH06XKwaL/FMnmKM2crF0iX4MpmMKoDlNCB1ok7zHCw== - dependencies: - esbuild "^0.19.3" - postcss "^8.4.32" - rollup "^4.2.0" - optionalDependencies: - fsevents "~2.3.3" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-builtin-type@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.1.3.tgz#b1b8443707cc58b6e9bf98d32110ff0c2cbd029b" - integrity sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw== - dependencies: - function.prototype.name "^1.1.5" - has-tostringtag "^1.0.0" - is-async-function "^2.0.0" - is-date-object "^1.0.5" - is-finalizationregistry "^1.0.2" - is-generator-function "^1.0.10" - is-regex "^1.1.4" - is-weakref "^1.0.2" - isarray "^2.0.5" - which-boxed-primitive "^1.0.2" - which-collection "^1.0.1" - which-typed-array "^1.1.9" - -which-collection@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" - integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== - dependencies: - is-map "^2.0.1" - is-set "^2.0.1" - is-weakmap "^2.0.1" - is-weakset "^2.0.1" - -which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.9: - version "1.1.13" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" - integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.4" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yaml@^1.10.0: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -zod@^3.22.2: - version "3.22.4" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff" - integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg== From 19e78907f6b37a447541aaeacc11c51b903c2b45 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 3 Jan 2024 11:32:19 +0100 Subject: [PATCH 099/170] Adding NatSpec comments --- core/contracts/Acre.sol | 19 ++++++++++++++++--- core/contracts/Dispatcher.sol | 35 ++++++++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index ece9892f9..56bba2d8c 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -20,21 +20,34 @@ import "./Dispatcher.sol"; contract Acre is ERC4626, Ownable { using SafeERC20 for IERC20; - // Dispatcher contract that routes tBTC from Acre to a given vault and back. + /// Dispatcher contract that routes tBTC from Acre to a given vault and back. Dispatcher public dispatcher; - // Minimum amount for a single deposit operation. + /// Minimum amount for a single deposit operation. uint256 public minimumDepositAmount; - // Maximum total amount of tBTC token held by Acre. + /// Maximum total amount of tBTC token held by Acre. uint256 public maximumTotalAssets; + /// Emitted when a referral is used. + /// @param referral Used for referral program. + /// @param assets Amount of tBTC tokens staked. event StakeReferral(bytes32 indexed referral, uint256 assets); + /// Emitted when deposit parameters are updated. + /// @param minimumDepositAmount New value of the minimum deposit amount. + /// @param maximumTotalAssets New value of the maximum total assets amount. event DepositParametersUpdated( uint256 minimumDepositAmount, uint256 maximumTotalAssets ); + /// Emitted when the dispatcher contract is updated. + /// @param oldDispatcher Address of the old dispatcher contract. + /// @param newDispatcher Address of the new dispatcher contract. event DispatcherUpdated(address oldDispatcher, address newDispatcher); + /// Reverts if the amount is less than the minimum deposit amount. + /// @param amount Amount to check. + /// @param min Minimum amount to check 'amount' against. error DepositAmountLessThanMin(uint256 amount, uint256 min); + /// Reverts if the address is zero. error ZeroAddress(); constructor( diff --git a/core/contracts/Dispatcher.sol b/core/contracts/Dispatcher.sol index 9e2c47a64..6df8f69ce 100644 --- a/core/contracts/Dispatcher.sol +++ b/core/contracts/Dispatcher.sol @@ -14,40 +14,57 @@ import "./Acre.sol"; contract Dispatcher is Router, Ownable { using SafeERC20 for IERC20; + /// Struct holds information about a vault. struct VaultInfo { bool authorized; } - // Depositing tBTC into Acre returns stBTC. + /// Depositing tBTC into Acre returns stBTC. Acre public immutable acre; - // tBTC token contract. + /// tBTC token contract. IERC20 public immutable tbtc; - // Address of the maintainer bot. + /// Address of the maintainer bot. address public maintainer; - /// @notice Authorized Yield Vaults that implement ERC4626 standard. These - /// vaults deposit assets to yield strategies, e.g. Uniswap V3 - /// WBTC/TBTC pool. Vault can be a part of Acre ecosystem or can be - /// implemented externally. As long as it complies with ERC4626 - /// standard and is authorized by the owner it can be plugged into - /// Acre. + /// Authorized Yield Vaults that implement ERC4626 standard. These + /// vaults deposit assets to yield strategies, e.g. Uniswap V3 + /// WBTC/TBTC pool. Vault can be a part of Acre ecosystem or can be + /// implemented externally. As long as it complies with ERC4626 + /// standard and is authorized by the owner it can be plugged into + /// Acre. address[] public vaults; + /// Mapping of vaults to their information. mapping(address => VaultInfo) public vaultsInfo; + /// Emitted when a vault is authorized. + /// @param vault Address of the vault. event VaultAuthorized(address indexed vault); + /// Emitted when a vault is deauthorized. + /// @param vault Address of the vault. event VaultDeauthorized(address indexed vault); + /// Emitted when tBTC is routed to a vault. + /// @param vault Address of the vault. + /// @param amount Amount of tBTC. + /// @param sharesOut Amount of shares received by Acre. event DepositAllocated( address indexed vault, uint256 amount, uint256 sharesOut ); + /// Emitted when the maintainer address is updated. + /// @param maintainer Address of the new maintainer. event MaintainerUpdated(address indexed maintainer); + /// Reverts if the vault is already authorized. error VaultAlreadyAuthorized(); + /// Reverts if the vault is not authorized. error VaultUnauthorized(); + /// Reverts if the caller is not the maintainer. error NotMaintainer(); + /// Reverts if the address is zero. error ZeroAddress(); + /// Modifier that reverts if the caller is not the maintainer. modifier onlyMaintainer() { if (msg.sender != maintainer) { revert NotMaintainer(); From ce9e973d4e17fd63da29da3be277d84746b3aff4 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 3 Jan 2024 11:37:14 +0100 Subject: [PATCH 100/170] Smaller docs improvements --- core/contracts/Dispatcher.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/contracts/Dispatcher.sol b/core/contracts/Dispatcher.sol index 6df8f69ce..35954e68f 100644 --- a/core/contracts/Dispatcher.sol +++ b/core/contracts/Dispatcher.sol @@ -9,7 +9,7 @@ import "./Acre.sol"; /// @title Dispatcher /// @notice Dispatcher is a contract that routes tBTC from Acre (stBTC) to -/// a given vault and back. Vaults supply yield strategies with TBTC that +/// yield vaults and back. Vaults supply yield strategies with tBTC that /// generate yield for Bitcoin holders. contract Dispatcher is Router, Ownable { using SafeERC20 for IERC20; @@ -19,7 +19,7 @@ contract Dispatcher is Router, Ownable { bool authorized; } - /// Depositing tBTC into Acre returns stBTC. + /// The main Acre contract holding tBTC deposited by stakers. Acre public immutable acre; /// tBTC token contract. IERC20 public immutable tbtc; @@ -160,7 +160,7 @@ contract Dispatcher is Router, Ownable { /// @notice Returns true if the vault is authorized. /// @param vault Address of the vault to check. - function isVaultAuthorized(address vault) internal view returns (bool) { + function isVaultAuthorized(address vault) public view returns (bool) { return vaultsInfo[vault].authorized; } From a59d6f43f710c1f9ee96bb147450c800fd023f40 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 3 Jan 2024 11:40:24 +0100 Subject: [PATCH 101/170] Removing allowStubs tag check. Not needed. --- core/deploy/00_resolve_testing_erc4626.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/core/deploy/00_resolve_testing_erc4626.ts b/core/deploy/00_resolve_testing_erc4626.ts index 8fb6b0fce..b8e483897 100644 --- a/core/deploy/00_resolve_testing_erc4626.ts +++ b/core/deploy/00_resolve_testing_erc4626.ts @@ -5,20 +5,17 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { const { getNamedAccounts, deployments } = hre const { log } = deployments const { deployer } = await getNamedAccounts() - const tBTC = await deployments.get("TBTC") - if (hre.network.tags.allowStubs) { - log("deploying Mock ERC4626 Vault") + log("deploying Mock ERC4626 Vault") - await deployments.deploy("Vault", { - contract: "TestERC4626", - from: deployer, - args: [tBTC.address, "MockVault", "MV"], - log: true, - waitConfirmations: 1, - }) - } + await deployments.deploy("Vault", { + contract: "TestERC4626", + from: deployer, + args: [tBTC.address, "MockVault", "MV"], + log: true, + waitConfirmations: 1, + }) } export default func From 4bd6ca9a8745dd8312fa86e7ddf7796bd55f68b0 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 3 Jan 2024 11:48:43 +0100 Subject: [PATCH 102/170] Function reorder. External goes above public --- core/contracts/Acre.sol | 56 ++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 56bba2d8c..6ad176df4 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -80,6 +80,34 @@ contract Acre is ERC4626, Ownable { ); } + // TODO: Implement a governed upgrade process that initiates an update and + // then finalizes it after a delay. + /// @notice Updates the dispatcher contract and gives it an unlimited + /// allowance to transfer staked tBTC. + /// @param newDispatcher Address of the new dispatcher contract. + function updateDispatcher(Dispatcher newDispatcher) external onlyOwner { + if (address(newDispatcher) == address(0)) { + revert ZeroAddress(); + } + + address oldDispatcher = address(dispatcher); + + emit DispatcherUpdated(oldDispatcher, address(newDispatcher)); + dispatcher = newDispatcher; + + // TODO: Once withdrawal/rebalancing is implemented, we need to revoke the + // approval of the vaults share tokens from the old dispatcher and approve + // a new dispatcher to manage the share tokens. + + if (oldDispatcher != address(0)) { + // Setting allowance to zero for the old dispatcher + IERC20(asset()).forceApprove(oldDispatcher, 0); + } + + // Setting allowance to max for the new dispatcher + IERC20(asset()).forceApprove(address(dispatcher), type(uint256).max); + } + /// @notice Mints shares to receiver by depositing exactly amount of /// tBTC tokens. /// @dev Takes into account a deposit parameter, minimum deposit amount, @@ -140,34 +168,6 @@ contract Acre is ERC4626, Ownable { return shares; } - // TODO: Implement a governed upgrade process that initiates an update and - // then finalizes it after a delay. - /// @notice Updates the dispatcher contract and gives it an unlimited - /// allowance to transfer staked tBTC. - /// @param newDispatcher Address of the new dispatcher contract. - function updateDispatcher(Dispatcher newDispatcher) external onlyOwner { - if (address(newDispatcher) == address(0)) { - revert ZeroAddress(); - } - - address oldDispatcher = address(dispatcher); - - emit DispatcherUpdated(oldDispatcher, address(newDispatcher)); - dispatcher = newDispatcher; - - // TODO: Once withdrawal/rebalancing is implemented, we need to revoke the - // approval of the vaults share tokens from the old dispatcher and approve - // a new dispatcher to manage the share tokens. - - if (oldDispatcher != address(0)) { - // Setting allowance to zero for the old dispatcher - IERC20(asset()).forceApprove(oldDispatcher, 0); - } - - // Setting allowance to max for the new dispatcher - IERC20(asset()).forceApprove(address(dispatcher), type(uint256).max); - } - /// @notice Returns the maximum amount of the tBTC token that can be /// deposited into the vault for the receiver, through a deposit /// call. It takes into account the deposit parameter, maximum total From 73ccd1cf7f4a5973e9f23e8b00361c43dc32c0ac Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 3 Jan 2024 11:49:08 +0100 Subject: [PATCH 103/170] getVaults() making public instead of external --- core/contracts/Dispatcher.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/contracts/Dispatcher.sol b/core/contracts/Dispatcher.sol index 35954e68f..82200b986 100644 --- a/core/contracts/Dispatcher.sol +++ b/core/contracts/Dispatcher.sol @@ -154,7 +154,7 @@ contract Dispatcher is Router, Ownable { } /// @notice Returns the list of authorized vaults. - function getVaults() external view returns (address[] memory) { + function getVaults() public view returns (address[] memory) { return vaults; } From e74ac482449e2302f3578b2e00af7c60b508ae3c Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Wed, 3 Jan 2024 12:57:40 +0100 Subject: [PATCH 104/170] Disable unbound-method for all deploy scripts Instead of adding inline comments for unbound-method rule we define it in the eslint config, as the `const { log } = deployments` is and will be broadly used in the scripts. --- core/.eslintrc | 10 +++++++++- core/deploy/00_resolve_tbtc.ts | 1 - core/deploy/21_transfer_ownership_acre.ts | 1 - core/deploy/22_transfer_ownership_acre_router.ts | 1 - 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/core/.eslintrc b/core/.eslintrc index 39419600b..67ae8e215 100644 --- a/core/.eslintrc +++ b/core/.eslintrc @@ -13,5 +13,13 @@ ] } ] - } + }, + "overrides": [ + { + "files": ["deploy/*.ts"], + "rules": { + "@typescript-eslint/unbound-method": "off" + } + } + ] } diff --git a/core/deploy/00_resolve_tbtc.ts b/core/deploy/00_resolve_tbtc.ts index bf9f27d46..dc1bfeff5 100644 --- a/core/deploy/00_resolve_tbtc.ts +++ b/core/deploy/00_resolve_tbtc.ts @@ -4,7 +4,6 @@ import { isNonZeroAddress } from "../helpers/address" const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { const { getNamedAccounts, deployments } = hre - // eslint-disable-next-line @typescript-eslint/unbound-method const { log } = deployments const { deployer } = await getNamedAccounts() diff --git a/core/deploy/21_transfer_ownership_acre.ts b/core/deploy/21_transfer_ownership_acre.ts index df6794a7f..09a875a1d 100644 --- a/core/deploy/21_transfer_ownership_acre.ts +++ b/core/deploy/21_transfer_ownership_acre.ts @@ -4,7 +4,6 @@ import type { DeployFunction } from "hardhat-deploy/types" const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { const { getNamedAccounts, deployments } = hre const { deployer, governance } = await getNamedAccounts() - // eslint-disable-next-line @typescript-eslint/unbound-method const { log } = deployments log(`transferring ownership of Acre contract to ${governance}`) diff --git a/core/deploy/22_transfer_ownership_acre_router.ts b/core/deploy/22_transfer_ownership_acre_router.ts index 2c7322898..686d378c4 100644 --- a/core/deploy/22_transfer_ownership_acre_router.ts +++ b/core/deploy/22_transfer_ownership_acre_router.ts @@ -4,7 +4,6 @@ import type { DeployFunction } from "hardhat-deploy/types" const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { const { getNamedAccounts, deployments } = hre const { deployer, governance } = await getNamedAccounts() - // eslint-disable-next-line @typescript-eslint/unbound-method const { log } = deployments log(`transferring ownership of Dispatcher contract to ${governance}`) From fe8ac88935ae5d59f83d18c7e115d5b39173f30a Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 3 Jan 2024 13:08:44 +0100 Subject: [PATCH 105/170] Prepare custom action hooks for staking steps --- .../components/Modals/Staking/DepositBTC.tsx | 13 +++------- .../components/Modals/Staking/SignMessage.tsx | 24 +++-------------- dapp/src/hooks/index.ts | 2 ++ dapp/src/hooks/useDepositBTCTransaction.ts | 13 ++++++++++ dapp/src/hooks/useSignMessage.ts | 26 +++++++++++++++++++ dapp/src/types/callback.ts | 1 + dapp/src/types/index.ts | 1 + 7 files changed, 50 insertions(+), 30 deletions(-) create mode 100644 dapp/src/hooks/useDepositBTCTransaction.ts create mode 100644 dapp/src/hooks/useSignMessage.ts create mode 100644 dapp/src/types/callback.ts diff --git a/dapp/src/components/Modals/Staking/DepositBTC.tsx b/dapp/src/components/Modals/Staking/DepositBTC.tsx index 91e7c8789..befde8e9a 100644 --- a/dapp/src/components/Modals/Staking/DepositBTC.tsx +++ b/dapp/src/components/Modals/Staking/DepositBTC.tsx @@ -1,26 +1,19 @@ import React from "react" import Alert from "../../shared/Alert" -import { useModalFlowContext, useWalletContext } from "../../../hooks" +import { useDepositBTCTransaction, useModalFlowContext } from "../../../hooks" import StakeSteps from "./StakeSteps" import { TextMd } from "../../shared/Typography" export default function DepositBTC() { const { goNext } = useModalFlowContext() - const { btcAccount } = useWalletContext() - - const handleSendBTC = async () => { - if (!btcAccount?.id) return - - // TODO: Send the correct transaction - goNext() - } + const { depositBTC } = useDepositBTCTransaction(goNext) return ( diff --git a/dapp/src/components/Modals/Staking/SignMessage.tsx b/dapp/src/components/Modals/Staking/SignMessage.tsx index 9965966b8..e7f4abcc2 100644 --- a/dapp/src/components/Modals/Staking/SignMessage.tsx +++ b/dapp/src/components/Modals/Staking/SignMessage.tsx @@ -1,36 +1,20 @@ -import React, { useEffect } from "react" +import React from "react" import { Highlight } from "@chakra-ui/react" -import { useSignMessage } from "@ledgerhq/wallet-api-client-react" import Alert from "../../shared/Alert" -import { useModalFlowContext, useWalletContext } from "../../../hooks" +import { useModalFlowContext, useSignMessage } from "../../../hooks" import StakeSteps from "./StakeSteps" import { TextMd } from "../../shared/Typography" -const SIGN_MESSAGE = "Test message" - export default function SignMessage() { const { goNext } = useModalFlowContext() - const { ethAccount } = useWalletContext() - const { signMessage, signature } = useSignMessage() - - const handleSignMessage = async () => { - if (!ethAccount?.id) return - - await signMessage(ethAccount.id, Buffer.from(SIGN_MESSAGE, "utf-8")) - } - - useEffect(() => { - if (signature) { - goNext() - } - }, [goNext, signature]) + const { signMessage } = useSignMessage(goNext) return ( diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts index 076da9a53..f49a34ed6 100644 --- a/dapp/src/hooks/index.ts +++ b/dapp/src/hooks/index.ts @@ -5,3 +5,5 @@ export * from "./useWalletContext" export * from "./useSidebar" export * from "./useDocsDrawer" export * from "./useModalFlowContext" +export * from "./useSignMessage" +export * from "./useDepositBTCTransaction" diff --git a/dapp/src/hooks/useDepositBTCTransaction.ts b/dapp/src/hooks/useDepositBTCTransaction.ts new file mode 100644 index 000000000..a629e6485 --- /dev/null +++ b/dapp/src/hooks/useDepositBTCTransaction.ts @@ -0,0 +1,13 @@ +import { useCallback } from "react" +import { OnSuccessCallback } from "../types" + +export function useDepositBTCTransaction(onSuccess?: OnSuccessCallback) { + // TODO: sending transactions using the SDK + const depositBTC = useCallback(() => { + if (onSuccess) { + setTimeout(onSuccess, 1000) + } + }, [onSuccess]) + + return { depositBTC } +} diff --git a/dapp/src/hooks/useSignMessage.ts b/dapp/src/hooks/useSignMessage.ts new file mode 100644 index 000000000..cc3cadc3e --- /dev/null +++ b/dapp/src/hooks/useSignMessage.ts @@ -0,0 +1,26 @@ +import { useSignMessage as useSignMessageLedgerLive } from "@ledgerhq/wallet-api-client-react" +import { useCallback, useEffect } from "react" +import { useWalletContext } from "./useWalletContext" +import { OnSuccessCallback } from "../types" + +const SIGN_MESSAGE = "Test message" + +export function useSignMessage(onSuccess?: OnSuccessCallback) { + const { ethAccount } = useWalletContext() + const { signMessage, signature } = useSignMessageLedgerLive() + + useEffect(() => { + if (signature && onSuccess) { + onSuccess() + } + }, [onSuccess, signature]) + + // TODO: signing message using the SDK + const handleSignMessage = useCallback(async () => { + if (!ethAccount?.id) return + + await signMessage(ethAccount.id, Buffer.from(SIGN_MESSAGE, "utf-8")) + }, [ethAccount, signMessage]) + + return { signMessage: handleSignMessage } +} diff --git a/dapp/src/types/callback.ts b/dapp/src/types/callback.ts new file mode 100644 index 000000000..526705388 --- /dev/null +++ b/dapp/src/types/callback.ts @@ -0,0 +1 @@ +export type OnSuccessCallback = () => void | Promise diff --git a/dapp/src/types/index.ts b/dapp/src/types/index.ts index 1e77e81e7..e89af2ea6 100644 --- a/dapp/src/types/index.ts +++ b/dapp/src/types/index.ts @@ -1,2 +1,3 @@ export * from "./ledger-live-app" export * from "./currency" +export * from "./callback" From 1ed9381b3548ead55bd38e0e1a1c368a61190233 Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Wed, 3 Jan 2024 13:15:32 +0100 Subject: [PATCH 106/170] Use different staker and receiver in deposit test --- core/test/Acre.test.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 94af3f3aa..de8599a82 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -895,6 +895,8 @@ describe("Acre", () => { describe("deposit", () => { beforeAfterEachSnapshotWrapper() + const receiver = ethers.Wallet.createRandom() + let amountToDeposit: bigint let minimumDepositAmount: bigint @@ -908,7 +910,7 @@ describe("Acre", () => { }) it("should revert", async () => { - await expect(acre.deposit(amountToDeposit, staker1.address)) + await expect(acre.deposit(amountToDeposit, receiver.address)) .to.be.revertedWithCustomError(acre, "DepositAmountLessThanMin") .withArgs(amountToDeposit, minimumDepositAmount) }) @@ -925,7 +927,9 @@ describe("Acre", () => { expectedReceivedShares = amountToDeposit await tbtc.approve(await acre.getAddress(), amountToDeposit) - tx = await acre.deposit(amountToDeposit, staker1.address) + tx = await acre + .connect(staker1) + .deposit(amountToDeposit, receiver.address) }) it("should emit Deposit event", () => { @@ -933,7 +937,7 @@ describe("Acre", () => { // Caller. staker1.address, // Receiver. - staker1.address, + receiver.address, // Staked tokens. amountToDeposit, // Received shares. @@ -944,7 +948,7 @@ describe("Acre", () => { it("should mint stBTC tokens", async () => { await expect(tx).to.changeTokenBalances( acre, - [staker1.address], + [receiver.address], [expectedReceivedShares], ) }) From 755afbe5d609eabda34f4b2c88ee5d8afab02e98 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 3 Jan 2024 13:41:29 +0100 Subject: [PATCH 107/170] Create a custom theme for the spinner --- dapp/src/components/shared/Spinner/index.tsx | 10 +--------- dapp/src/theme/Spinner.ts | 13 +++++++++++++ dapp/src/theme/index.ts | 2 ++ 3 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 dapp/src/theme/Spinner.ts diff --git a/dapp/src/components/shared/Spinner/index.tsx b/dapp/src/components/shared/Spinner/index.tsx index 1e5c6a29d..144138932 100644 --- a/dapp/src/components/shared/Spinner/index.tsx +++ b/dapp/src/components/shared/Spinner/index.tsx @@ -5,13 +5,5 @@ import { } from "@chakra-ui/react" export default function Spinner({ ...spinnerProps }: ChakraSpinnerProps) { - return ( - - ) + return } diff --git a/dapp/src/theme/Spinner.ts b/dapp/src/theme/Spinner.ts new file mode 100644 index 000000000..1e6082e84 --- /dev/null +++ b/dapp/src/theme/Spinner.ts @@ -0,0 +1,13 @@ +import { defineStyle, defineStyleConfig } from "@chakra-ui/react" + +const baseStyle = defineStyle({ + color: "brand.400", + borderWidth: 3, + borderTopColor: "gold.400", + borderBottomColor: "gold.400", + borderLeftColor: "gold.400", +}) + +const Spinner = defineStyleConfig({ baseStyle }) + +export default Spinner diff --git a/dapp/src/theme/index.ts b/dapp/src/theme/index.ts index 6e7babc46..64ae2d130 100644 --- a/dapp/src/theme/index.ts +++ b/dapp/src/theme/index.ts @@ -17,6 +17,7 @@ import Alert from "./Alert" import Form from "./Form" import FormLabel from "./FormLabel" import FormError from "./FormError" +import Spinner from "./Spinner" const defaultTheme = { colors, @@ -50,6 +51,7 @@ const defaultTheme = { Form, FormLabel, FormError, + Spinner, }, } From 2ef73abd1d62a704fa0302eb8dcd3a279482953f Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 3 Jan 2024 13:57:48 +0100 Subject: [PATCH 108/170] Smaller cleanups, renames and adding an additional test Added test to Deployment.test.ts checking the initial state right after the deployment scripts execution. --- core/contracts/Router.sol | 13 +++++-- core/test/Acre.test.ts | 67 +++++++++++++++++++++++------------- core/test/Deployment.test.ts | 6 ++++ core/test/Dispatcher.test.ts | 56 +++++++++++++++++------------- 4 files changed, 92 insertions(+), 50 deletions(-) diff --git a/core/contracts/Router.sol b/core/contracts/Router.sol index b1359b1a4..babc54820 100644 --- a/core/contracts/Router.sol +++ b/core/contracts/Router.sol @@ -12,8 +12,15 @@ import "@openzeppelin/contracts/interfaces/IERC4626.sol"; abstract contract Router { using SafeERC20 for IERC20; - /// @notice thrown when amount of shares received is below the min set by caller - error MinSharesError(); + /// Thrown when amount of shares received is below the min set by caller. + /// @param vault Address of the vault. + /// @param sharesOut Amount of shares received by Acre. + /// @param minSharesOut Minimum amount of shares expected to receive. + error MinSharesError( + address vault, + uint256 sharesOut, + uint256 minSharesOut + ); /// @notice Routes funds from stBTC (Acre) to a vault. The amount of tBTC to /// Shares of deposited tBTC are minted to the stBTC contract. @@ -28,7 +35,7 @@ abstract contract Router { uint256 minSharesOut ) internal returns (uint256 sharesOut) { if ((sharesOut = vault.deposit(amount, receiver)) < minSharesOut) { - revert MinSharesError(); + revert MinSharesError(address(vault), sharesOut, minSharesOut); } } } diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index 3e9d8a0c7..fa6e5ddf1 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -23,27 +23,27 @@ async function fixture() { const { tbtc, acre, dispatcher } = await deployment() const { governance } = await getNamedSigner() - const [staker1, staker2] = await getUnnamedSigner() - const { governance: owner } = await getNamedSigner() + const [staker1, staker2, thirdParty] = await getUnnamedSigner() const amountToMint = to1e18(100000) tbtc.mint(staker1, amountToMint) tbtc.mint(staker2, amountToMint) - return { acre, tbtc, owner, staker1, staker2, dispatcher, governance } + return { acre, tbtc, staker1, staker2, dispatcher, governance, thirdParty } } describe("Acre", () => { let acre: Acre let tbtc: TestERC20 - let owner: HardhatEthersSigner - let staker1: HardhatEthersSigner - let staker2: HardhatEthersSigner let dispatcher: Dispatcher + let governance: HardhatEthersSigner + let staker1: HardhatEthersSigner + let staker2: HardhatEthersSigner + let thirdParty: HardhatEthersSigner before(async () => { - ;({ acre, tbtc, staker1, staker2, owner, dispatcher, governance } = + ;({ acre, tbtc, staker1, staker2, dispatcher, governance, thirdParty } = await loadFixture(fixture)) }) @@ -374,7 +374,7 @@ describe("Acre", () => { ) }) - it("the staker A should be able to redeem more tokens than before", async () => { + it("the staker A should redeem more tokens than before", async () => { const shares = await acre.balanceOf(staker1.address) const availableAssetsToRedeem = await acre.previewRedeem(shares) @@ -386,7 +386,7 @@ describe("Acre", () => { expect(availableAssetsToRedeem).to.be.eq(expectedAssetsToRedeem) }) - it("the staker B should be able to redeem more tokens than before", async () => { + it("the staker B should redeem more tokens than before", async () => { const shares = await acre.balanceOf(staker2.address) const availableAssetsToRedeem = await acre.previewRedeem(shares) @@ -440,7 +440,7 @@ describe("Acre", () => { expect(shares).to.be.eq(sharesBefore + expectedSharesToMint) }) - it("should be able to redeem more tokens than before", async () => { + it("should redeem more tokens than before", async () => { const shares = await acre.balanceOf(staker1.address) const availableToRedeem = await acre.previewRedeem(shares) @@ -518,7 +518,7 @@ describe("Acre", () => { expect(await acre.maxDeposit(staker1)).to.eq(0) }) - it("should not be able to stake more tokens", async () => { + it("should not stake more tokens", async () => { await expect(acre.stake(amountToStake, staker1, referral)) .to.be.revertedWithCustomError( acre, @@ -650,13 +650,13 @@ describe("Acre", () => { await snapshot.restore() }) - context("when is called by owner", () => { + context("when is called by governance", () => { context("when all parameters are valid", () => { let tx: ContractTransactionResponse beforeEach(async () => { tx = await acre - .connect(owner) + .connect(governance) .updateDepositParameters( validMinimumDepositAmount, validMaximumTotalAssetsAmount, @@ -683,7 +683,7 @@ describe("Acre", () => { beforeEach(async () => { await acre - .connect(owner) + .connect(governance) .updateDepositParameters( newMinimumDepositAmount, validMaximumTotalAssetsAmount, @@ -702,7 +702,7 @@ describe("Acre", () => { beforeEach(async () => { await acre - .connect(owner) + .connect(governance) .updateDepositParameters( validMinimumDepositAmount, newMaximumTotalAssets, @@ -715,7 +715,7 @@ describe("Acre", () => { }) }) - context("when it is called by non-owner", () => { + context("when it is called by non-governance", () => { it("should revert", async () => { await expect( acre @@ -789,7 +789,7 @@ describe("Acre", () => { beforeEach(async () => { await acre - .connect(owner) + .connect(governance) .updateDepositParameters(minimumDepositAmount, maximum) }) @@ -821,15 +821,25 @@ describe("Acre", () => { }) describe("updateDispatcher", () => { - context("when caller is not an owner", () => { + let snapshot: SnapshotRestorer + + before(async () => { + snapshot = await takeSnapshot() + }) + + after(async () => { + await snapshot.restore() + }) + + context("when caller is not governance", () => { it("should revert", async () => { - await expect(acre.connect(staker1).updateDispatcher(ZeroAddress)) + await expect(acre.connect(thirdParty).updateDispatcher(ZeroAddress)) .to.be.revertedWithCustomError(acre, "OwnableUnauthorizedAccount") - .withArgs(staker1.address) + .withArgs(thirdParty.address) }) }) - context("when caller is an owner", () => { + context("when caller is governance", () => { context("when a new dispatcher is zero address", () => { it("should revert", async () => { await expect( @@ -842,16 +852,19 @@ describe("Acre", () => { let newDispatcher: string let acreAddress: string let dispatcherAddress: string + let tx: ContractTransactionResponse before(async () => { + // Dispatcher is set by the deployment scripts. See deployment tests + // where initial parameters are checked. dispatcherAddress = await dispatcher.getAddress() newDispatcher = await ethers.Wallet.createRandom().getAddress() acreAddress = await acre.getAddress() - await acre.connect(governance).updateDispatcher(newDispatcher) + tx = await acre.connect(governance).updateDispatcher(newDispatcher) }) - it("should be able to update the dispatcher", async () => { + it("should update the dispatcher", async () => { expect(await acre.dispatcher()).to.be.equal(newDispatcher) }) @@ -864,6 +877,12 @@ describe("Acre", () => { const allowance = await tbtc.allowance(acreAddress, newDispatcher) expect(allowance).to.be.equal(MaxUint256) }) + + it("should emit DispatcherUpdated event", async () => { + await expect(tx) + .to.emit(acre, "DispatcherUpdated") + .withArgs(dispatcherAddress, newDispatcher) + }) }) }) }) @@ -942,7 +961,7 @@ describe("Acre", () => { beforeEach(async () => { await acre - .connect(owner) + .connect(governance) .updateDepositParameters(minimumDepositAmount, maximum) }) diff --git a/core/test/Deployment.test.ts b/core/test/Deployment.test.ts index 5b7a311ab..7f2b7bec6 100644 --- a/core/test/Deployment.test.ts +++ b/core/test/Deployment.test.ts @@ -27,6 +27,12 @@ describe("Deployment", () => { describe("updateDispatcher", () => { context("when a dispatcher has been set", () => { + it("should be set to a dispatcher address by the deployment script", async () => { + const actualDispatcher = await acre.dispatcher() + + expect(actualDispatcher).to.be.equal(await dispatcher.getAddress()) + }) + it("should approve max amount for the dispatcher", async () => { const actualDispatcher = await acre.dispatcher() const allowance = await tbtc.allowance( diff --git a/core/test/Dispatcher.test.ts b/core/test/Dispatcher.test.ts index 99d3247cb..beeff85e6 100644 --- a/core/test/Dispatcher.test.ts +++ b/core/test/Dispatcher.test.ts @@ -76,7 +76,7 @@ describe("Dispatcher", () => { await dispatcher.connect(governance).authorizeVault(vaultAddress3) }) - it("should be able to authorize vaults", async () => { + it("should authorize vaults", async () => { expect(await dispatcher.vaults(0)).to.equal(vaultAddress1) expect(await dispatcher.vaultsInfo(vaultAddress1)).to.be.equal(true) @@ -87,7 +87,7 @@ describe("Dispatcher", () => { expect(await dispatcher.vaultsInfo(vaultAddress3)).to.be.equal(true) }) - it("should not be able to authorize the same vault twice", async () => { + it("should not authorize the same vault twice", async () => { await expect( dispatcher.connect(governance).authorizeVault(vaultAddress1), ).to.be.revertedWithCustomError(dispatcher, "VaultAlreadyAuthorized") @@ -122,7 +122,7 @@ describe("Dispatcher", () => { }) context("when caller is a governance account", () => { - it("should be able to deauthorize vaults", async () => { + it("should deauthorize vaults", async () => { await dispatcher.connect(governance).deauthorizeVault(vaultAddress1) // Last vault replaced the first vault in the 'vaults' array @@ -142,7 +142,7 @@ describe("Dispatcher", () => { expect(await dispatcher.vaultsInfo(vaultAddress3)).to.be.equal(false) }) - it("should be able to deauthorize a vault and authorize it again", async () => { + it("should deauthorize a vault and authorize it again", async () => { await dispatcher.connect(governance).deauthorizeVault(vaultAddress1) expect(await dispatcher.vaultsInfo(vaultAddress1)).to.be.equal(false) @@ -150,7 +150,7 @@ describe("Dispatcher", () => { expect(await dispatcher.vaultsInfo(vaultAddress1)).to.be.equal(true) }) - it("should not be able to deauthorize a vault that is not authorized", async () => { + it("should not deauthorize a vault that is not authorized", async () => { await expect( dispatcher.connect(governance).deauthorizeVault(vaultAddress4), ).to.be.revertedWithCustomError(dispatcher, "VaultUnauthorized") @@ -215,15 +215,19 @@ describe("Dispatcher", () => { .depositToVault(vaultAddress, assetsToAllocate, minSharesOut) }) - it("should be able to deposit to an authorized Vault", async () => { - expect(await tbtc.balanceOf(vault.getAddress())).to.equal( - assetsToAllocate, + it("should deposit tBTC to a vault", async () => { + await expect(tx).to.changeTokenBalances( + tbtc, + [acre, vault], + [-assetsToAllocate, assetsToAllocate], ) }) - it("should be able to receive Vault's shares", async () => { - expect(await vault.balanceOf(acre.getAddress())).to.equal( - minSharesOut, + it("should mint vault's shares for Acre contract", async () => { + await expect(tx).to.changeTokenBalances( + vault, + [acre], + [minSharesOut], ) }) @@ -234,17 +238,23 @@ describe("Dispatcher", () => { }) }) - context("when allocation is not successful", () => { - const minShares = to1e18(101) - - it("should emit a MinSharesError event", async () => { - await expect( - dispatcher - .connect(maintainer) - .depositToVault(vaultAddress, assetsToAllocate, minShares), - ).to.be.revertedWithCustomError(dispatcher, "MinSharesError") - }) - }) + context( + "when the expected returned shares are less than the actual returned shares", + () => { + const sharesOut = assetsToAllocate + const minShares = to1e18(101) + + it("should emit a MinSharesError event", async () => { + await expect( + dispatcher + .connect(maintainer) + .depositToVault(vaultAddress, assetsToAllocate, minShares), + ) + .to.be.revertedWithCustomError(dispatcher, "MinSharesError") + .withArgs(vaultAddress, sharesOut, minShares) + }) + }, + ) }) }) }) @@ -287,7 +297,7 @@ describe("Dispatcher", () => { .updateMaintainer(newMaintainer) }) - it("should be able to update the maintainer", async () => { + it("should update the maintainer", async () => { expect(await dispatcher.maintainer()).to.be.equal(newMaintainer) }) From d2736999542f6c57f437e91ea60afdae731cef4d Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Wed, 3 Jan 2024 14:11:50 +0100 Subject: [PATCH 109/170] Extract snapshot wrappers to a separate file --- core/test/Acre.test.ts | 5 +++-- core/test/Dispatcher.test.ts | 8 ++++++-- core/test/helpers/context.ts | 37 +---------------------------------- core/test/helpers/index.ts | 1 + core/test/helpers/snapshot.ts | 36 ++++++++++++++++++++++++++++++++++ 5 files changed, 47 insertions(+), 40 deletions(-) create mode 100644 core/test/helpers/snapshot.ts diff --git a/core/test/Acre.test.ts b/core/test/Acre.test.ts index de8599a82..3b80c834c 100644 --- a/core/test/Acre.test.ts +++ b/core/test/Acre.test.ts @@ -16,8 +16,9 @@ import { beforeAfterEachSnapshotWrapper, beforeAfterSnapshotWrapper, deployment, -} from "./helpers/context" -import { getNamedSigner, getUnnamedSigner } from "./helpers/signer" + getNamedSigner, + getUnnamedSigner, +} from "./helpers" import { to1e18 } from "./utils" diff --git a/core/test/Dispatcher.test.ts b/core/test/Dispatcher.test.ts index 3b986674e..1ec669166 100644 --- a/core/test/Dispatcher.test.ts +++ b/core/test/Dispatcher.test.ts @@ -3,8 +3,12 @@ import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers" import { expect } from "chai" import { loadFixture } from "@nomicfoundation/hardhat-toolbox/network-helpers" import type { Dispatcher } from "../typechain" -import { beforeAfterEachSnapshotWrapper, deployment } from "./helpers/context" -import { getNamedSigner, getUnnamedSigner } from "./helpers/signer" +import { + beforeAfterEachSnapshotWrapper, + deployment, + getNamedSigner, + getUnnamedSigner, +} from "./helpers" async function fixture() { const { dispatcher } = await deployment() diff --git a/core/test/helpers/context.ts b/core/test/helpers/context.ts index 8bbc206f1..99f4696af 100644 --- a/core/test/helpers/context.ts +++ b/core/test/helpers/context.ts @@ -1,44 +1,9 @@ import { deployments } from "hardhat" -import { - SnapshotRestorer, - takeSnapshot, -} from "@nomicfoundation/hardhat-toolbox/network-helpers" import { getDeployedContract } from "./contract" import type { Acre, Dispatcher, TestERC20 } from "../../typechain" -/** - * Adds a before/after hook pair to snapshot the EVM state before and after tests - * in a test suite. - */ -export function beforeAfterSnapshotWrapper(): void { - let snapshot: SnapshotRestorer - - before(async () => { - snapshot = await takeSnapshot() - }) - - after(async () => { - await snapshot.restore() - }) -} - -/** - * Adds a beforeEach/afterEach hook pair to snapshot the EVM state before and - * after each of tests in a test suite. - */ -export function beforeAfterEachSnapshotWrapper(): void { - let snapshot: SnapshotRestorer - - beforeEach(async () => { - snapshot = await takeSnapshot() - }) - - afterEach(async () => { - await snapshot.restore() - }) -} - +// eslint-disable-next-line import/prefer-default-export export async function deployment() { await deployments.fixture() diff --git a/core/test/helpers/index.ts b/core/test/helpers/index.ts index 27ddcb0b9..e4df2196a 100644 --- a/core/test/helpers/index.ts +++ b/core/test/helpers/index.ts @@ -1,3 +1,4 @@ export * from "./context" export * from "./contract" export * from "./signer" +export * from "./snapshot" diff --git a/core/test/helpers/snapshot.ts b/core/test/helpers/snapshot.ts new file mode 100644 index 000000000..804c0455d --- /dev/null +++ b/core/test/helpers/snapshot.ts @@ -0,0 +1,36 @@ +import { + SnapshotRestorer, + takeSnapshot, +} from "@nomicfoundation/hardhat-toolbox/network-helpers" + +/** + * Adds a before/after hook pair to snapshot the EVM state before and after tests + * in a test suite. + */ +export function beforeAfterSnapshotWrapper(): void { + let snapshot: SnapshotRestorer + + before(async () => { + snapshot = await takeSnapshot() + }) + + after(async () => { + await snapshot.restore() + }) +} + +/** + * Adds a beforeEach/afterEach hook pair to snapshot the EVM state before and + * after each of tests in a test suite. + */ +export function beforeAfterEachSnapshotWrapper(): void { + let snapshot: SnapshotRestorer + + beforeEach(async () => { + snapshot = await takeSnapshot() + }) + + afterEach(async () => { + await snapshot.restore() + }) +} From d409aeacb98bfa16921f15901b86885296ae21a4 Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Wed, 3 Jan 2024 14:24:07 +0100 Subject: [PATCH 110/170] Fix ducumentation --- core/contracts/tbtc/TbtcDepositor.sol | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/core/contracts/tbtc/TbtcDepositor.sol b/core/contracts/tbtc/TbtcDepositor.sol index b149ef4bc..eb2cf3ad1 100644 --- a/core/contracts/tbtc/TbtcDepositor.sol +++ b/core/contracts/tbtc/TbtcDepositor.sol @@ -15,7 +15,7 @@ import {Acre} from "../Acre.sol"; /// @title tBTC Depositor contract. /// @notice The contract integrates Acre staking with tBTC minting. -/// User who want to stake BTC in Acre should submit a Bitcoin transaction +/// User who wants to stake BTC in Acre should submit a Bitcoin transaction /// to the most recently created off-chain ECDSA wallets of the tBTC Bridge /// using pay-to-script-hash (P2SH) or pay-to-witness-script-hash (P2WSH) /// containing hashed information about this Depositor contract address, @@ -177,7 +177,7 @@ contract TbtcDepositor { /// `amount = depositAmount - depositTreasuryFee - depositTxMaxFee` /// - for optimistically minted deposits: /// ``` - /// amount = depositAmount - depositTreasuryFee - depositTxMaxFee + /// amount = depositAmount - depositTreasuryFee - depositTxMaxFee /// - optimisticMintingFee /// ``` /// These calculation are simplified and can leave some positive @@ -188,9 +188,8 @@ contract TbtcDepositor { /// at the moment of the deposit reveal, there is a chance that the fee /// parameter is updated in the tBTC Vault contract before the optimistic /// minting is finalized. - /// The imbalance should be donated to the Acre staking contract by the - /// Governance. - /// @param depositKey Deposit key computed as + /// The imbalance is considered a part of the depositor fee. + /// @param depositKey Deposit key computed as /// `keccak256(fundingTxHash | fundingOutputIndex)`. function finalizeStake(uint256 depositKey) external { StakeRequest storage request = stakeRequests[depositKey]; @@ -224,7 +223,7 @@ contract TbtcDepositor { // Check if deposit was optimistically minted. if (optimisticMintingRequest.finalizedAt > 0) { // For tBTC minted with optimistic minting process additional fee - // is taken. The fee is calculated on `TBTCVautl.finalizeOptimisticMint` + // is taken. The fee is calculated on `TBTCVault.finalizeOptimisticMint` // call, and not stored in the contract. // There is a possibility the fee has changed since the snapshot of // the `tbtcOptimisticMintingFeeDivisor`, to cover this scenario @@ -294,7 +293,7 @@ contract TbtcDepositor { return bytes32(abi.encodePacked(receiver, referral)); } - /// @notice Decodes receiver address and referral from extera data, + /// @notice Decodes receiver address and referral from extra data, /// @dev Unpacks the data from bytes32: 20 bytes of receiver address and /// 2 bytes of referral, 10 bytes of trailing zeros. /// @param extraData Encoded extra data. From 4ea86174c4a3432c0a50263d0594a7c16379b2ae Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Wed, 3 Jan 2024 17:02:54 +0100 Subject: [PATCH 111/170] Emit events on stake initialization and finalization --- core/contracts/tbtc/TbtcDepositor.sol | 31 ++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/core/contracts/tbtc/TbtcDepositor.sol b/core/contracts/tbtc/TbtcDepositor.sol index eb2cf3ad1..2689f370f 100644 --- a/core/contracts/tbtc/TbtcDepositor.sol +++ b/core/contracts/tbtc/TbtcDepositor.sol @@ -70,6 +70,30 @@ contract TbtcDepositor { // TODO: Decide if leave or remove? uint64 public minimumFundingTransactionAmount; + /// @notice Emitted when a stake request is initialized. + /// @dev Deposit details can be fetched from {{ Bridge.DepositRevealed }} + /// event emitted in the same transaction. + /// @param depositKey Deposit identifier. + /// @param caller Address that initialized the stake request. + /// @param receiver The address to which the stBTC shares will be minted. + /// @return referral Data used for referral program. + event StakeInitialized( + uint256 indexed depositKey, + address indexed caller, + address receiver, + uint16 referral + ); + + /// @notice Emitted when a stake request is finalized. + /// @dev Deposit details can be fetched from {{ ERC4626.Deposit }} + /// event emitted in the same transaction. + /// @param depositKey Deposit identifier. + /// @param caller Address that finalized the stake request. + event StakeFinalized( + uint256 indexed depositKey, + address indexed caller + ); + /// @dev Receiver address is zero. error ReceiverIsZeroAddress(); /// @dev Attempted to initiate a stake request that was already initialized. @@ -144,12 +168,15 @@ contract TbtcDepositor { ) .hash256View(); + uint256 depositKey = calculateDepositKey(fundingTxHash, reveal.fundingOutputIndex); StakeRequest storage request = stakeRequests[ - calculateDepositKey(fundingTxHash, reveal.fundingOutputIndex) + depositKey ]; if (request.requestedAt > 0) revert StakeRequestAlreadyInProgress(); + emit StakeInitialized(depositKey, msg.sender, receiver, referral); + // solhint-disable-next-line not-rely-on-time request.requestedAt = uint64(block.timestamp); @@ -252,6 +279,8 @@ contract TbtcDepositor { bytes32 extraData = bridgeDepositRequest.extraData; (address receiver, uint16 referral) = decodeExtraData(extraData); + emit StakeFinalized(depositKey, msg.sender); + // Stake tBTC in Acre. IERC20(acre.asset()).safeIncreaseAllowance( address(acre), From 023f1d08f27301d03e40c8a43dcde8205c7242cb Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 3 Jan 2024 17:16:44 +0100 Subject: [PATCH 112/170] Cleanups across Solidity contracts and tests --- core/contracts/Acre.sol | 3 +++ core/contracts/Dispatcher.sol | 6 +++++ core/contracts/Router.sol | 4 --- core/test/Deployment.test.ts | 46 +++++++++++++++++++---------------- core/test/Dispatcher.test.ts | 15 +++++++----- 5 files changed, 43 insertions(+), 31 deletions(-) diff --git a/core/contracts/Acre.sol b/core/contracts/Acre.sol index 6ad176df4..2f2edbf6b 100644 --- a/core/contracts/Acre.sol +++ b/core/contracts/Acre.sol @@ -31,6 +31,7 @@ contract Acre is ERC4626, Ownable { /// @param referral Used for referral program. /// @param assets Amount of tBTC tokens staked. event StakeReferral(bytes32 indexed referral, uint256 assets); + /// Emitted when deposit parameters are updated. /// @param minimumDepositAmount New value of the minimum deposit amount. /// @param maximumTotalAssets New value of the maximum total assets amount. @@ -38,6 +39,7 @@ contract Acre is ERC4626, Ownable { uint256 minimumDepositAmount, uint256 maximumTotalAssets ); + /// Emitted when the dispatcher contract is updated. /// @param oldDispatcher Address of the old dispatcher contract. /// @param newDispatcher Address of the new dispatcher contract. @@ -47,6 +49,7 @@ contract Acre is ERC4626, Ownable { /// @param amount Amount to check. /// @param min Minimum amount to check 'amount' against. error DepositAmountLessThanMin(uint256 amount, uint256 min); + /// Reverts if the address is zero. error ZeroAddress(); diff --git a/core/contracts/Dispatcher.sol b/core/contracts/Dispatcher.sol index 82200b986..cbdc0dd0f 100644 --- a/core/contracts/Dispatcher.sol +++ b/core/contracts/Dispatcher.sol @@ -39,9 +39,11 @@ contract Dispatcher is Router, Ownable { /// Emitted when a vault is authorized. /// @param vault Address of the vault. event VaultAuthorized(address indexed vault); + /// Emitted when a vault is deauthorized. /// @param vault Address of the vault. event VaultDeauthorized(address indexed vault); + /// Emitted when tBTC is routed to a vault. /// @param vault Address of the vault. /// @param amount Amount of tBTC. @@ -51,16 +53,20 @@ contract Dispatcher is Router, Ownable { uint256 amount, uint256 sharesOut ); + /// Emitted when the maintainer address is updated. /// @param maintainer Address of the new maintainer. event MaintainerUpdated(address indexed maintainer); /// Reverts if the vault is already authorized. error VaultAlreadyAuthorized(); + /// Reverts if the vault is not authorized. error VaultUnauthorized(); + /// Reverts if the caller is not the maintainer. error NotMaintainer(); + /// Reverts if the address is zero. error ZeroAddress(); diff --git a/core/contracts/Router.sol b/core/contracts/Router.sol index babc54820..6d07a22a2 100644 --- a/core/contracts/Router.sol +++ b/core/contracts/Router.sol @@ -1,8 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.21; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import "@openzeppelin/contracts/interfaces/IERC20.sol"; import "@openzeppelin/contracts/interfaces/IERC4626.sol"; /// @title Router @@ -10,8 +8,6 @@ import "@openzeppelin/contracts/interfaces/IERC4626.sol"; /// a given vault and back. Vaults supply yield strategies with tBTC that /// generate yield for Bitcoin holders. abstract contract Router { - using SafeERC20 for IERC20; - /// Thrown when amount of shares received is below the min set by caller. /// @param vault Address of the vault. /// @param sharesOut Amount of shares received by Acre. diff --git a/core/test/Deployment.test.ts b/core/test/Deployment.test.ts index 7f2b7bec6..362e2f43c 100644 --- a/core/test/Deployment.test.ts +++ b/core/test/Deployment.test.ts @@ -25,32 +25,36 @@ describe("Deployment", () => { ;({ acre, dispatcher, tbtc, maintainer } = await loadFixture(fixture)) }) - describe("updateDispatcher", () => { - context("when a dispatcher has been set", () => { - it("should be set to a dispatcher address by the deployment script", async () => { - const actualDispatcher = await acre.dispatcher() - - expect(actualDispatcher).to.be.equal(await dispatcher.getAddress()) - }) - - it("should approve max amount for the dispatcher", async () => { - const actualDispatcher = await acre.dispatcher() - const allowance = await tbtc.allowance( - await acre.getAddress(), - actualDispatcher, - ) - - expect(allowance).to.be.equal(MaxUint256) + describe("Acre", () => { + describe("updateDispatcher", () => { + context("when a dispatcher has been set", () => { + it("should be set to a dispatcher address by the deployment script", async () => { + const actualDispatcher = await acre.dispatcher() + + expect(actualDispatcher).to.be.equal(await dispatcher.getAddress()) + }) + + it("should approve max amount for the dispatcher", async () => { + const actualDispatcher = await acre.dispatcher() + const allowance = await tbtc.allowance( + await acre.getAddress(), + actualDispatcher, + ) + + expect(allowance).to.be.equal(MaxUint256) + }) }) }) }) - describe("updateMaintainer", () => { - context("when a new maintainer has been set", () => { - it("should be set to a new maintainer address", async () => { - const actualMaintainer = await dispatcher.maintainer() + describe("Dispatcher", () => { + describe("updateMaintainer", () => { + context("when a new maintainer has been set", () => { + it("should be set to a new maintainer address", async () => { + const actualMaintainer = await dispatcher.maintainer() - expect(actualMaintainer).to.be.equal(await maintainer.getAddress()) + expect(actualMaintainer).to.be.equal(await maintainer.getAddress()) + }) }) }) }) diff --git a/core/test/Dispatcher.test.ts b/core/test/Dispatcher.test.ts index beeff85e6..435ee2808 100644 --- a/core/test/Dispatcher.test.ts +++ b/core/test/Dispatcher.test.ts @@ -24,12 +24,13 @@ describe("Dispatcher", () => { let snapshot: SnapshotRestorer let dispatcher: Dispatcher + let vault: TestERC4626 + let tbtc: TestERC20 + let acre: Acre + let governance: HardhatEthersSigner let thirdParty: HardhatEthersSigner let maintainer: HardhatEthersSigner - let vault: TestERC4626 - let acre: Acre - let tbtc: TestERC20 let vaultAddress1: string let vaultAddress2: string let vaultAddress3: string @@ -68,10 +69,10 @@ describe("Dispatcher", () => { }) context("when caller is a governance account", () => { - let tx1: ContractTransactionResponse + let tx: ContractTransactionResponse beforeEach(async () => { - tx1 = await dispatcher.connect(governance).authorizeVault(vaultAddress1) + tx = await dispatcher.connect(governance).authorizeVault(vaultAddress1) await dispatcher.connect(governance).authorizeVault(vaultAddress2) await dispatcher.connect(governance).authorizeVault(vaultAddress3) }) @@ -94,7 +95,7 @@ describe("Dispatcher", () => { }) it("should emit an event when adding a vault", async () => { - await expect(tx1) + await expect(tx) .to.emit(dispatcher, "VaultAuthorized") .withArgs(vaultAddress1) }) @@ -203,12 +204,14 @@ describe("Dispatcher", () => { context("when the vault is authorized", () => { let vaultAddress: string + before(async () => { vaultAddress = await vault.getAddress() }) context("when allocation is successful", () => { let tx: ContractTransactionResponse + before(async () => { tx = await dispatcher .connect(maintainer) From 02e8fbcf2edd0816f5489892b5bd8242581ed869 Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Wed, 3 Jan 2024 23:48:20 +0100 Subject: [PATCH 113/170] Generate markdown files for Solidity API documentation Use Open Zeppelin's [solidity-docgen tool](https://github.com/OpenZeppelin/solidity-docgen) to generate markdown files for solidity contracts documentation. To run the generation: `pnpm run docs` The files will be output in `gen/docs/` directory. --- core/.gitignore | 1 + core/hardhat.config.ts | 8 ++++++++ core/package.json | 4 +++- pnpm-lock.yaml | 13 +++++++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/core/.gitignore b/core/.gitignore index 38618816c..1f9e31a2d 100644 --- a/core/.gitignore +++ b/core/.gitignore @@ -3,4 +3,5 @@ build/ cache/ export.json export/ +gen/ typechain/ diff --git a/core/hardhat.config.ts b/core/hardhat.config.ts index 264e9fcbd..1c1c8fff6 100644 --- a/core/hardhat.config.ts +++ b/core/hardhat.config.ts @@ -3,6 +3,7 @@ import type { HardhatUserConfig } from "hardhat/config" import "@nomicfoundation/hardhat-toolbox" import "hardhat-contract-sizer" import "hardhat-deploy" +import "solidity-docgen" const config: HardhatUserConfig = { solidity: { @@ -86,6 +87,13 @@ const config: HardhatUserConfig = { typechain: { outDir: "typechain", }, + + docgen: { + outputDir: "./gen/docs", + pages: "files", + exclude: ["external/", "test/"], + collapseNewlines: true, + }, } export default config diff --git a/core/package.json b/core/package.json index ff7aa5197..58413adbc 100644 --- a/core/package.json +++ b/core/package.json @@ -14,9 +14,10 @@ "export.json" ], "scripts": { - "clean": "hardhat clean && rm -rf cache/ export/ export.json", + "clean": "hardhat clean && rm -rf cache/ export/ gen/ export.json", "build": "hardhat compile", "deploy": "hardhat deploy --export export.json", + "docs": "hardhat docgen", "format": "npm run lint:js && npm run lint:sol && npm run lint:config", "format:fix": "npm run lint:js:fix && npm run lint:sol:fix && npm run lint:config:fix", "lint:js": "eslint .", @@ -53,6 +54,7 @@ "solhint": "^4.0.0", "solhint-config-thesis": "github:thesis/solhint-config", "solidity-coverage": "^0.8.5", + "solidity-docgen": "0.6.0-beta.36", "ts-node": "^10.9.1", "typechain": "^8.3.2", "typescript": "^5.3.2" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1c334a15e..aab8f4cc6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -99,6 +99,9 @@ importers: solidity-coverage: specifier: ^0.8.5 version: 0.8.5(hardhat@2.19.1) + solidity-docgen: + specifier: 0.6.0-beta.36 + version: 0.6.0-beta.36(hardhat@2.19.1) ts-node: specifier: ^10.9.1 version: 10.9.1(@types/node@20.9.4)(typescript@5.3.2) @@ -14077,6 +14080,16 @@ packages: - supports-color dev: true + /solidity-docgen@0.6.0-beta.36(hardhat@2.19.1): + resolution: {integrity: sha512-f/I5G2iJgU1h0XrrjRD0hHMr7C10u276vYvm//rw1TzFcYQ4xTOyAoi9oNAHRU0JU4mY9eTuxdVc2zahdMuhaQ==} + peerDependencies: + hardhat: ^2.8.0 + dependencies: + handlebars: 4.7.8 + hardhat: 2.19.1(ts-node@10.9.1)(typescript@5.3.2) + solidity-ast: 0.4.53 + dev: true + /source-list-map@2.0.1: resolution: {integrity: sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==} From 2d0d7bf02ad31c340dd958ec23cfeee861041de4 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Thu, 4 Jan 2024 08:19:25 +0100 Subject: [PATCH 114/170] Separate constants and helper functions for overview modal --- .../StakingSteps.tsx} | 41 ++++++------------- .../Modals/Staking/Overview/index.tsx | 20 +++++++++ 2 files changed, 32 insertions(+), 29 deletions(-) rename dapp/src/components/Modals/Staking/{Overview.tsx => Overview/StakingSteps.tsx} (50%) create mode 100644 dapp/src/components/Modals/Staking/Overview/index.tsx diff --git a/dapp/src/components/Modals/Staking/Overview.tsx b/dapp/src/components/Modals/Staking/Overview/StakingSteps.tsx similarity index 50% rename from dapp/src/components/Modals/Staking/Overview.tsx rename to dapp/src/components/Modals/Staking/Overview/StakingSteps.tsx index dd95a152f..b34437226 100644 --- a/dapp/src/components/Modals/Staking/Overview.tsx +++ b/dapp/src/components/Modals/Staking/Overview/StakingSteps.tsx @@ -1,14 +1,7 @@ import React from "react" -import { - Button, - ModalBody, - ModalFooter, - ModalHeader, - StepNumber, -} from "@chakra-ui/react" -import { ModalStep } from "../../../contexts" -import StepperBase from "../../shared/StepperBase" -import { TextLg, TextMd } from "../../shared/Typography" +import { StepNumber } from "@chakra-ui/react" +import { TextLg, TextMd } from "../../../shared/Typography" +import StepperBase from "../../../shared/StepperBase" function Title({ children }: { children: React.ReactNode }) { return {children} @@ -40,25 +33,15 @@ const STEPS = [ }, ] -export default function Overview({ goNext }: ModalStep) { +export default function StakingSteps() { return ( - <> - Staking steps overview - - } - steps={STEPS} - /> - - - - - + } + steps={STEPS} + /> ) } diff --git a/dapp/src/components/Modals/Staking/Overview/index.tsx b/dapp/src/components/Modals/Staking/Overview/index.tsx new file mode 100644 index 000000000..04f858ec4 --- /dev/null +++ b/dapp/src/components/Modals/Staking/Overview/index.tsx @@ -0,0 +1,20 @@ +import React from "react" +import { Button, ModalBody, ModalFooter, ModalHeader } from "@chakra-ui/react" +import StakingSteps from "./StakingSteps" +import { ModalStep } from "../../../../contexts" + +export default function Overview({ goNext }: ModalStep) { + return ( + <> + Staking steps overview + + + + + + + + ) +} From cba01f4600195fe46dbdefc04543e6b51801cef1 Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Thu, 4 Jan 2024 09:35:16 +0100 Subject: [PATCH 115/170] Disable no-unused-expressions for test files We want to use `to.be.true` instead of `to.be.equal(true)`, so we need to disable the rule. --- core/.eslintrc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/.eslintrc b/core/.eslintrc index 67ae8e215..8090228c6 100644 --- a/core/.eslintrc +++ b/core/.eslintrc @@ -20,6 +20,12 @@ "rules": { "@typescript-eslint/unbound-method": "off" } + }, + { + "files": ["*.test.ts"], + "rules": { + "@typescript-eslint/no-unused-expressions": "off" + } } ] } From 3a585e4db8fa7d07bf34a6d292c94ab96b26ed43 Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Thu, 4 Jan 2024 09:39:52 +0100 Subject: [PATCH 116/170] Fix require-await error in deployment script 26:70 error Async arrow function has no 'await' expression @typescript-eslint/require-await --- core/deploy/00_resolve_testing_erc4626.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/deploy/00_resolve_testing_erc4626.ts b/core/deploy/00_resolve_testing_erc4626.ts index b8e483897..d1e82b665 100644 --- a/core/deploy/00_resolve_testing_erc4626.ts +++ b/core/deploy/00_resolve_testing_erc4626.ts @@ -24,4 +24,4 @@ func.tags = ["TestERC4626"] func.dependencies = ["TBTC"] func.skip = async (hre: HardhatRuntimeEnvironment): Promise => - hre.network.name === "mainnet" + Promise.resolve(hre.network.name === "mainnet") From a43d2424568d5adb7fe1d166d74c6cd6a55b8ddd Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Thu, 4 Jan 2024 09:50:44 +0100 Subject: [PATCH 117/170] Add an action icon for the alert --- .../components/Modals/Staking/DepositBTC.tsx | 2 +- .../components/Modals/Staking/SignMessage.tsx | 3 ++- .../Modals/Support/MissingAccount.tsx | 6 ++--- dapp/src/components/shared/Alert/index.tsx | 27 +++++++++++++++---- dapp/src/theme/Alert.ts | 18 ++++++++++++- 5 files changed, 45 insertions(+), 11 deletions(-) diff --git a/dapp/src/components/Modals/Staking/DepositBTC.tsx b/dapp/src/components/Modals/Staking/DepositBTC.tsx index befde8e9a..f07f0821d 100644 --- a/dapp/src/components/Modals/Staking/DepositBTC.tsx +++ b/dapp/src/components/Modals/Staking/DepositBTC.tsx @@ -15,7 +15,7 @@ export default function DepositBTC() { activeStep={1} onClick={depositBTC} > - + Make a Bitcoin transaction to deposit and stake your BTC. diff --git a/dapp/src/components/Modals/Staking/SignMessage.tsx b/dapp/src/components/Modals/Staking/SignMessage.tsx index e7f4abcc2..b78700ffc 100644 --- a/dapp/src/components/Modals/Staking/SignMessage.tsx +++ b/dapp/src/components/Modals/Staking/SignMessage.tsx @@ -16,7 +16,8 @@ export default function SignMessage() { activeStep={0} onClick={signMessage} > - + {/* TODO: Add the correct action after click */} + {}}> You will receive stBTC liquid staking token at this Ethereum address diff --git a/dapp/src/components/Modals/Support/MissingAccount.tsx b/dapp/src/components/Modals/Support/MissingAccount.tsx index 7b6216276..19566c355 100644 --- a/dapp/src/components/Modals/Support/MissingAccount.tsx +++ b/dapp/src/components/Modals/Support/MissingAccount.tsx @@ -9,7 +9,7 @@ import { } from "@chakra-ui/react" import { CurrencyType, RequestAccountParams } from "../../../types" import { TextMd } from "../../shared/Typography" -import AlertWrapper from "../../shared/Alert" +import Alert from "../../shared/Alert" import { CURRENCIES_BY_TYPE } from "../../../constants" type MissingAccountProps = { @@ -34,14 +34,14 @@ export default function MissingAccount({ {currency.name} account is required to make transactions for depositing and staking your {currency.symbol}. - + You will be sent to the Ledger Accounts section to perform this action. - + + + ) +} + +export default StakeForm diff --git a/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx b/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx new file mode 100644 index 000000000..c5343319d --- /dev/null +++ b/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx @@ -0,0 +1,39 @@ +import React from "react" +import { FormikProps } from "formik" +import { Form, FormTokenBalanceInput } from "../Form" +import { CurrencyType } from "../../../types" + +export type TokenAmountFormValues = { + amount?: bigint +} + +export type TokenAmountFormBaseProps = { + formId: string + tokenBalance: string + tokenBalanceInputPlaceholder: string + currencyType: CurrencyType + fieldName: string + children?: React.ReactNode +} + +export default function TokenAmountFormBase({ + formId, + tokenBalance, + currencyType, + tokenBalanceInputPlaceholder, + fieldName, + children, + ...formikProps +}: TokenAmountFormBaseProps & FormikProps) { + return ( + + + {children} + + ) +} diff --git a/dapp/src/components/shared/TokenAmountForm/TransactionDetails.tsx b/dapp/src/components/shared/TokenAmountForm/TransactionDetails.tsx deleted file mode 100644 index 4e9857d1e..000000000 --- a/dapp/src/components/shared/TokenAmountForm/TransactionDetails.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import React from "react" -import { Box, Flex, VStack } from "@chakra-ui/react" -import { useField } from "formik" -import { CurrencyBalanceWithConversion } from "../CurrencyBalanceWithConversion" -import { TextMd } from "../Typography" - -// TODO: Use data from the SDK -function getTransactionDetails(value: string): - | { - btcAmount: string - protocolFee: string - stakedAmount: string - } - | undefined { - const btcAmount = value ?? 0n - const btcAmountInBI = BigInt(btcAmount) - - if (btcAmountInBI <= 0n) return undefined - - const protocolFee = btcAmountInBI / 10000n - const stakedAmount = btcAmountInBI - protocolFee - - return { - btcAmount, - protocolFee: protocolFee.toString(), - stakedAmount: stakedAmount.toString(), - } -} - -function TransactionDetailsItem({ - text, - btcAmount, - usdAmount, -}: { - text: string - btcAmount?: string | number - usdAmount: string -}) { - return ( - - - {text} - - - - - - ) -} - -function TransactionDetails({ - fieldName, - btcAmountText, - estimatedAmountText, -}: { - fieldName: string - btcAmountText: string - estimatedAmountText: string -}) { - const [, { value }] = useField(fieldName) - - const details = getTransactionDetails(value) - - return ( - - - - - - ) -} - -export default TransactionDetails diff --git a/dapp/src/components/shared/TokenAmountForm/index.tsx b/dapp/src/components/shared/TokenAmountForm/index.tsx index fa2bda0b9..638ee56e4 100644 --- a/dapp/src/components/shared/TokenAmountForm/index.tsx +++ b/dapp/src/components/shared/TokenAmountForm/index.tsx @@ -1,56 +1,9 @@ -import React from "react" -import { Button } from "@chakra-ui/react" -import { FormikProps, FormikErrors, withFormik } from "formik" -import { Form, FormTokenBalanceInput } from "../Form" -import { CurrencyType } from "../../../types" -import TransactionDetails from "./TransactionDetails" +import { FormikErrors, withFormik } from "formik" import { getErrorsObj, validateTokenAmount } from "../../../utils" - -export type TokenAmountFormValues = { - amount?: bigint -} -type TokenAmountFormBaseProps = { - customData: { - buttonText: string - btcAmountText: string - estimatedAmountText: string - } - tokenBalance: string - tokenBalanceInputPlaceholder?: string - currencyType: CurrencyType - fieldName?: string - children?: React.ReactNode -} - -function TokenAmountFormBase({ - customData, - tokenBalance, - currencyType, - tokenBalanceInputPlaceholder = "BTC", - fieldName = "amount", - children, - ...formikProps -}: TokenAmountFormBaseProps & FormikProps) { - return ( -
- - - {children} - - - ) -} +import TokenAmountFormBase, { + TokenAmountFormBaseProps, + TokenAmountFormValues, +} from "./TokenAmountFormBase" type TokenAmountFormProps = { onSubmitForm: (values: TokenAmountFormValues) => void diff --git a/dapp/src/components/shared/TransactionDetails/AmountItem.tsx b/dapp/src/components/shared/TransactionDetails/AmountItem.tsx new file mode 100644 index 000000000..7acebc823 --- /dev/null +++ b/dapp/src/components/shared/TransactionDetails/AmountItem.tsx @@ -0,0 +1,36 @@ +import React, { ComponentProps } from "react" +import { Box } from "@chakra-ui/react" +import TransactionDetailsItem, { TransactionDetailsItemProps } from "." +import { CurrencyBalanceWithConversion } from "../CurrencyBalanceWithConversion" + +type TransactionDetailsAmountItemProps = ComponentProps< + typeof CurrencyBalanceWithConversion +> & + Pick + +function TransactionDetailsAmountItem({ + label, + from, + to, +}: TransactionDetailsAmountItemProps) { + return ( + + + + + + ) +} + +export default TransactionDetailsAmountItem diff --git a/dapp/src/components/shared/TransactionDetails/index.tsx b/dapp/src/components/shared/TransactionDetails/index.tsx new file mode 100644 index 000000000..bdaf6552c --- /dev/null +++ b/dapp/src/components/shared/TransactionDetails/index.tsx @@ -0,0 +1,32 @@ +import React from "react" +import { ListItem, ListItemProps } from "@chakra-ui/react" +import { TextMd } from "../Typography" + +export type TransactionDetailsItemProps = { + label: string + value?: string + children?: React.ReactNode +} & ListItemProps + +function TransactionDetailsItem({ + label, + value, + children, + ...listItemProps +}: TransactionDetailsItemProps) { + return ( + + + {label} + + {value ? {value} : children} + + ) +} + +export default TransactionDetailsItem diff --git a/dapp/src/constants/staking.ts b/dapp/src/constants/staking.ts index 421c57bb5..45bfcba88 100644 --- a/dapp/src/constants/staking.ts +++ b/dapp/src/constants/staking.ts @@ -1 +1,2 @@ export const BITCOIN_MIN_AMOUNT = "1000000" // 0.01 BTC +export const ZERO_AMOUNT = 0n diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts index 4f2b42d57..d4d7accb0 100644 --- a/dapp/src/hooks/index.ts +++ b/dapp/src/hooks/index.ts @@ -6,3 +6,4 @@ export * from "./useSidebar" export * from "./useDocsDrawer" export * from "./useModalFlowContext" export * from "./useTransactionContext" +export * from "./useTransactionDetails" diff --git a/dapp/src/hooks/useTransactionDetails.ts b/dapp/src/hooks/useTransactionDetails.ts new file mode 100644 index 000000000..4cf9e6711 --- /dev/null +++ b/dapp/src/hooks/useTransactionDetails.ts @@ -0,0 +1,26 @@ +import { useEffect, useState } from "react" +import { ZERO_AMOUNT } from "../constants" + +export function useTransactionDetails(amount: bigint): { + protocolFee: string + estimatedAmount: string +} { + const [protocolFee, setProtocolFee] = useState(ZERO_AMOUNT) + const [estimatedAmount, setEstimatedAmount] = useState(ZERO_AMOUNT) + + useEffect(() => { + if (amount <= ZERO_AMOUNT) { + setProtocolFee(ZERO_AMOUNT) + setEstimatedAmount(ZERO_AMOUNT) + } else { + const newProtocolFee = amount / 10000n + setProtocolFee(newProtocolFee) + setEstimatedAmount(amount - newProtocolFee) + } + }, [amount]) + + return { + protocolFee: protocolFee.toString(), + estimatedAmount: estimatedAmount.toString(), + } +} From d49a39c4e5b2a2bb78554c6f44610dec494c40fb Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 9 Jan 2024 11:48:49 +0100 Subject: [PATCH 141/170] Use `Currency` instead `CurrencyType` for TokenAmountForm --- dapp/src/components/Header/ConnectWallet.tsx | 2 +- .../Modals/Staking/StakeForm/Details.tsx | 18 +++++++++--------- .../Modals/Staking/StakeForm/index.tsx | 10 ++++------ .../components/Overview/PositionDetails.tsx | 4 ++-- .../shared/CurrencyBalance/index.tsx | 17 ++++++++++------- .../TokenAmountForm/TokenAmountFormBase.tsx | 8 ++++---- .../shared/TokenAmountForm/index.tsx | 4 ++-- .../shared/TokenBalanceInput/index.tsx | 18 ++++++------------ dapp/src/types/staking.ts | 4 ++-- dapp/src/utils/currency.ts | 4 ++++ dapp/src/utils/forms.ts | 7 +++---- 11 files changed, 47 insertions(+), 49 deletions(-) diff --git a/dapp/src/components/Header/ConnectWallet.tsx b/dapp/src/components/Header/ConnectWallet.tsx index 3bb5af7d9..90069b4e7 100644 --- a/dapp/src/components/Header/ConnectWallet.tsx +++ b/dapp/src/components/Header/ConnectWallet.tsx @@ -46,7 +46,7 @@ export default function ConnectWallet() { Balance diff --git a/dapp/src/components/Modals/Staking/StakeForm/Details.tsx b/dapp/src/components/Modals/Staking/StakeForm/Details.tsx index 8f1584c09..af84180a9 100644 --- a/dapp/src/components/Modals/Staking/StakeForm/Details.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm/Details.tsx @@ -3,14 +3,14 @@ import { List } from "@chakra-ui/react" import { useField } from "formik" import { useTransactionDetails } from "../../../../hooks" import TransactionDetailsAmountItem from "../../../shared/TransactionDetails/AmountItem" -import { CurrencyType } from "../../../../types" +import { Currency } from "../../../../types" function Details({ fieldName, - currencyType, + currency, }: { fieldName: string - currencyType: CurrencyType + currency: Currency }) { const [, { value }] = useField(fieldName) const btcAmount = value ?? 0n @@ -22,11 +22,11 @@ function Details({ { if (!values.amount) return - seTokenAmount({ amount: values.amount, currencyType: CURRENCY_TYPE }) + seTokenAmount({ amount: values.amount, currency: BITCOIN }) goNext() }, [goNext, seTokenAmount], @@ -32,12 +30,12 @@ function StakeForm({ goNext }: ModalStep) { formId={FORM_ID} fieldName={FORM_FIELD_NAME} tokenBalanceInputPlaceholder="BTC" - currencyType={CURRENCY_TYPE} + currency={BITCOIN} tokenBalance={btcAccount?.balance.toString() ?? "0"} minTokenAmount={BITCOIN_MIN_AMOUNT} onSubmitForm={handleSubmitForm} > -
+
- + ) } From c6b6c7b1a6044fc9d9b6fd6ac6a6aad4296c40a9 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 10 Jan 2024 12:05:11 +0100 Subject: [PATCH 148/170] Use always `CurrencyType` --- .../Modals/Staking/StakeForm/Details.tsx | 4 +-- .../Modals/Staking/StakeForm/index.tsx | 8 ++--- .../Modals/Support/MissingAccount.tsx | 12 ++++---- dapp/src/components/Modals/Support/index.tsx | 4 +-- .../shared/CurrencyBalance/index.tsx | 9 ++---- .../TokenAmountForm/TokenAmountFormBase.tsx | 4 +-- .../shared/TokenBalanceInput/index.tsx | 30 +++++++++++-------- dapp/src/types/staking.ts | 4 +-- dapp/src/utils/currency.ts | 8 ++--- dapp/src/utils/forms.ts | 8 +++-- 10 files changed, 45 insertions(+), 46 deletions(-) diff --git a/dapp/src/components/Modals/Staking/StakeForm/Details.tsx b/dapp/src/components/Modals/Staking/StakeForm/Details.tsx index eb548b449..e334c5403 100644 --- a/dapp/src/components/Modals/Staking/StakeForm/Details.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm/Details.tsx @@ -3,10 +3,10 @@ import { List } from "@chakra-ui/react" import { useField } from "formik" import { useTransactionDetails } from "../../../../hooks" import TransactionDetailsAmountItem from "../../../shared/TransactionDetails/AmountItem" -import { Currency } from "../../../../types" +import { CurrencyType } from "../../../../types" import { TOKEN_AMOUNT_FIELD_NAME } from "../../../../constants" -function Details({ currency }: { currency: Currency }) { +function Details({ currency }: { currency: CurrencyType }) { const [, { value }] = useField(TOKEN_AMOUNT_FIELD_NAME) const details = useTransactionDetails(value ?? 0n) diff --git a/dapp/src/components/Modals/Staking/StakeForm/index.tsx b/dapp/src/components/Modals/Staking/StakeForm/index.tsx index fba2566bb..38ea05136 100644 --- a/dapp/src/components/Modals/Staking/StakeForm/index.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm/index.tsx @@ -1,6 +1,6 @@ import React, { useCallback } from "react" import { Button } from "@chakra-ui/react" -import { BITCOIN, BITCOIN_MIN_AMOUNT } from "../../../../constants" +import { BITCOIN_MIN_AMOUNT } from "../../../../constants" import { ModalStep } from "../../../../contexts" import { useWalletContext, useTransactionContext } from "../../../../hooks" import TokenAmountForm from "../../../shared/TokenAmountForm" @@ -15,7 +15,7 @@ function StakeForm({ goNext }: ModalStep) { (values: TokenAmountFormValues) => { if (!values.amount) return - seTokenAmount({ amount: values.amount, currency: BITCOIN }) + seTokenAmount({ amount: values.amount, currency: "bitcoin" }) goNext() }, [goNext, seTokenAmount], @@ -24,12 +24,12 @@ function StakeForm({ goNext }: ModalStep) { return ( -
+
diff --git a/dapp/src/components/Modals/Support/MissingAccount.tsx b/dapp/src/components/Modals/Support/MissingAccount.tsx index e0b66938e..2c32b354e 100644 --- a/dapp/src/components/Modals/Support/MissingAccount.tsx +++ b/dapp/src/components/Modals/Support/MissingAccount.tsx @@ -13,26 +13,26 @@ import Alert from "../../shared/Alert" import { getCurrencyByType } from "../../../utils" type MissingAccountProps = { - currencyType: CurrencyType + currency: CurrencyType icon: typeof Icon requestAccount: (...params: RequestAccountParams) => Promise } export default function MissingAccount({ - currencyType, + currency, icon, requestAccount, }: MissingAccountProps) { - const currency = getCurrencyByType(currencyType) + const { name, symbol } = getCurrencyByType(currency) return ( <> - {currency.name} account not installed + {name} account not installed - {currency.name} account is required to make transactions for - depositing and staking your {currency.symbol}. + {name} account is required to make transactions for depositing and + staking your {symbol}. diff --git a/dapp/src/components/Modals/Support/index.tsx b/dapp/src/components/Modals/Support/index.tsx index c6d8953c2..c6784fff4 100644 --- a/dapp/src/components/Modals/Support/index.tsx +++ b/dapp/src/components/Modals/Support/index.tsx @@ -19,7 +19,7 @@ export default function SupportWrapper({ if (!btcAccount) return ( @@ -28,7 +28,7 @@ export default function SupportWrapper({ if (!ethAccount) return ( diff --git a/dapp/src/components/shared/CurrencyBalance/index.tsx b/dapp/src/components/shared/CurrencyBalance/index.tsx index 178e2ec0c..f44f7505e 100644 --- a/dapp/src/components/shared/CurrencyBalance/index.tsx +++ b/dapp/src/components/shared/CurrencyBalance/index.tsx @@ -3,13 +3,12 @@ import { Box, useMultiStyleConfig, TextProps } from "@chakra-ui/react" import { formatTokenAmount, getCurrencyByType, - isCurrencyType, numberToLocaleString, } from "../../../utils" -import { Currency, CurrencyType } from "../../../types" +import { CurrencyType } from "../../../types" export type CurrencyBalanceProps = { - currency: Currency | CurrencyType + currency: CurrencyType amount?: string | number shouldBeFormatted?: boolean desiredDecimals?: number @@ -28,9 +27,7 @@ export function CurrencyBalance({ }: CurrencyBalanceProps) { const styles = useMultiStyleConfig("CurrencyBalance", { size, variant }) - const { symbol, decimals } = isCurrencyType(currency) - ? getCurrencyByType(currency) - : currency + const { symbol, decimals } = getCurrencyByType(currency) const balance = useMemo(() => { const value = amount ?? 0 diff --git a/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx b/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx index fd4e5d5f1..fd4b6a05b 100644 --- a/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx +++ b/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx @@ -1,7 +1,7 @@ import React from "react" import { FormikProps } from "formik" import { Form, FormTokenBalanceInput } from "../Form" -import { Currency } from "../../../types" +import { CurrencyType } from "../../../types" import { TOKEN_AMOUNT_FIELD_NAME } from "../../../constants" export type TokenAmountFormValues = { @@ -12,7 +12,7 @@ export type TokenAmountFormBaseProps = { formId?: string tokenBalance: string tokenBalanceInputPlaceholder: string - currency: Currency + currency: CurrencyType children?: React.ReactNode } diff --git a/dapp/src/components/shared/TokenBalanceInput/index.tsx b/dapp/src/components/shared/TokenBalanceInput/index.tsx index e6a533671..82aa75fee 100644 --- a/dapp/src/components/shared/TokenBalanceInput/index.tsx +++ b/dapp/src/components/shared/TokenBalanceInput/index.tsx @@ -12,8 +12,12 @@ import { InputRightElement, useMultiStyleConfig, } from "@chakra-ui/react" -import { fixedPointNumberToString, userAmountToBigInt } from "../../../utils" -import { Currency, CurrencyType } from "../../../types" +import { + fixedPointNumberToString, + getCurrencyByType, + userAmountToBigInt, +} from "../../../utils" +import { CurrencyType } from "../../../types" import NumberFormatInput, { NumberFormatInputValues, } from "../NumberFormatInput" @@ -55,20 +59,20 @@ function HelperErrorText({ type FiatCurrencyBalanceProps = { fiatAmount?: string - fiatCurrencyType?: CurrencyType + fiatCurrency?: CurrencyType } function FiatCurrencyBalance({ fiatAmount, - fiatCurrencyType, + fiatCurrency, }: FiatCurrencyBalanceProps) { const styles = useMultiStyleConfig("Form") const { fontWeight } = styles.helperText - if (fiatAmount && fiatCurrencyType) { + if (fiatAmount && fiatCurrency) { return ( (amount) const styles = useMultiStyleConfig("TokenBalanceInput", { size }) + const { decimals } = getCurrencyByType(currency) + const handleValueChange = (value: string) => { - valueRef.current = value - ? userAmountToBigInt(value, currency.decimals) - : undefined + valueRef.current = value ? userAmountToBigInt(value, decimals) : undefined } return ( @@ -140,7 +144,7 @@ export default function TokenBalanceInput({ {...inputProps} value={ amount - ? fixedPointNumberToString(BigInt(amount), currency.decimals) + ? fixedPointNumberToString(BigInt(amount), decimals) : undefined } onValueChange={(values: NumberFormatInputValues) => @@ -165,7 +169,7 @@ export default function TokenBalanceInput({ )} diff --git a/dapp/src/types/staking.ts b/dapp/src/types/staking.ts index 009207492..56b4740be 100644 --- a/dapp/src/types/staking.ts +++ b/dapp/src/types/staking.ts @@ -1,6 +1,6 @@ -import { Currency } from "./currency" +import { CurrencyType } from "./currency" export type TokenAmount = { amount: bigint - currency: Currency + currency: CurrencyType } diff --git a/dapp/src/utils/currency.ts b/dapp/src/utils/currency.ts index 3763060f5..39eda0651 100644 --- a/dapp/src/utils/currency.ts +++ b/dapp/src/utils/currency.ts @@ -1,9 +1,5 @@ import { CURRENCIES_BY_TYPE } from "../constants" import { Currency, CurrencyType } from "../types" -export const getCurrencyByType = (type: CurrencyType): Currency => - CURRENCIES_BY_TYPE[type] - -export const isCurrencyType = ( - currency: Currency | CurrencyType, -): currency is CurrencyType => typeof currency === "string" +export const getCurrencyByType = (currency: CurrencyType): Currency => + CURRENCIES_BY_TYPE[currency] diff --git a/dapp/src/utils/forms.ts b/dapp/src/utils/forms.ts index 283d42595..9f7f34759 100644 --- a/dapp/src/utils/forms.ts +++ b/dapp/src/utils/forms.ts @@ -1,4 +1,5 @@ -import { Currency } from "../types" +import { CurrencyType } from "../types" +import { getCurrencyByType } from "./currency" import { formatTokenAmount } from "./numbers" const ERRORS = { @@ -18,11 +19,12 @@ export function validateTokenAmount( value: bigint | undefined, maxValue: string, minValue: string, - currency: Currency, + currency: CurrencyType, ): string | undefined { if (value === undefined) return ERRORS.REQUIRED - const { decimals } = currency + const { decimals } = getCurrencyByType(currency) + const maxValueInBI = BigInt(maxValue) const minValueInBI = BigInt(minValue) From 1f7419d6dd84939acb75e49feabb4e8a90be9d97 Mon Sep 17 00:00:00 2001 From: ioay Date: Tue, 9 Jan 2024 16:39:45 +0100 Subject: [PATCH 149/170] Thesis - eslint config --- dapp/package.json | 2 +- pnpm-lock.yaml | 33 ++------------------------------- 2 files changed, 3 insertions(+), 32 deletions(-) diff --git a/dapp/package.json b/dapp/package.json index 8345eb7e2..d2d3e6458 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -26,7 +26,7 @@ "react-number-format": "^5.3.1" }, "devDependencies": { - "@thesis-co/eslint-config": "^0.6.1", + "@thesis-co/eslint-config": "github:thesis/eslint-config#7b9bc8c", "@types/react": "^18.2.38", "@types/react-dom": "^18.2.17", "@typescript-eslint/eslint-plugin": "^6.12.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b5614ee89..9465bed28 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -143,8 +143,8 @@ importers: version: 5.3.1(react-dom@18.2.0)(react@18.2.0) devDependencies: '@thesis-co/eslint-config': - specifier: ^0.6.1 - version: 0.6.1(eslint@8.54.0)(prettier@3.1.0)(typescript@5.3.2) + specifier: github:thesis/eslint-config#7b9bc8c + version: github.com/thesis/eslint-config/7b9bc8c(eslint@8.54.0)(prettier@3.1.0)(typescript@5.3.2) '@types/react': specifier: ^18.2.38 version: 18.2.38 @@ -5425,35 +5425,6 @@ packages: dependencies: defer-to-connect: 2.0.1 - /@thesis-co/eslint-config@0.6.1(eslint@8.54.0)(prettier@3.1.0)(typescript@5.3.2): - resolution: {integrity: sha512-0vJCCI4UwUdniDCQeTFlMBT+bSp5pGkrtHrZrG2vmyLZwSVdJNtInjkBc/Jd0sGfMtPo3pqQRwA40Zo80lPi+Q==} - engines: {node: '>=14.0.0'} - peerDependencies: - eslint: '>=6.8.0' - dependencies: - '@thesis-co/prettier-config': github.com/thesis/prettier-config/daeaac564056a7885e4366ce12bfde6fd823fc90(prettier@3.1.0) - '@typescript-eslint/eslint-plugin': 6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.3.2) - '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.3.2) - eslint: 8.54.0 - eslint-config-airbnb: 19.0.4(eslint-plugin-import@2.29.0)(eslint-plugin-jsx-a11y@6.8.0)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.33.2)(eslint@8.54.0) - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.0)(eslint@8.54.0) - eslint-config-airbnb-typescript: 17.1.0(@typescript-eslint/eslint-plugin@6.12.0)(@typescript-eslint/parser@6.12.0)(eslint-plugin-import@2.29.0)(eslint@8.54.0) - eslint-config-prettier: 9.0.0(eslint@8.54.0) - eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0) - eslint-plugin-jsx-a11y: 6.8.0(eslint@8.54.0) - eslint-plugin-no-only-tests: 3.1.0 - eslint-plugin-prettier: 5.0.1(eslint-config-prettier@9.0.0)(eslint@8.54.0)(prettier@3.1.0) - eslint-plugin-react: 7.33.2(eslint@8.54.0) - eslint-plugin-react-hooks: 4.6.0(eslint@8.54.0) - transitivePeerDependencies: - - '@types/eslint' - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - prettier - - supports-color - - typescript - dev: true - /@tokenizer/token@0.3.0: resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} From 1c5a9604f0998d6f05ad1eb2477042033e8b5136 Mon Sep 17 00:00:00 2001 From: ioay Date: Tue, 9 Jan 2024 22:16:39 +0100 Subject: [PATCH 150/170] Added eslint rules --- dapp/.eslintrc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dapp/.eslintrc b/dapp/.eslintrc index 4317c87a7..a1c6935a5 100644 --- a/dapp/.eslintrc +++ b/dapp/.eslintrc @@ -15,6 +15,9 @@ 2, { "allowRequiredDefaults": true } ], - "react/require-default-props": [0] + "react/require-default-props": [0], + "@typescript-eslint/no-misused-promises": "off", + "@typescript-eslint/unbound-method": "off", + "@typescript-eslint/no-unsafe-member-access": "off" } } From 1cf230937dbcf50594c377d4d70924ac4b6402f6 Mon Sep 17 00:00:00 2001 From: ioay Date: Wed, 10 Jan 2024 10:39:16 +0100 Subject: [PATCH 151/170] Added comments to eslint config --- dapp/.eslintrc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dapp/.eslintrc b/dapp/.eslintrc index a1c6935a5..b8736f5e6 100644 --- a/dapp/.eslintrc +++ b/dapp/.eslintrc @@ -16,8 +16,12 @@ { "allowRequiredDefaults": true } ], "react/require-default-props": [0], + // Regarding the fact we are using now: @thesis-co/eslint-config": "github:thesis/eslint-config#7b9bc8c" + // Promise-returning function provided to attribute where a void return was expected. + // Avoid referencing unbound methods which may cause unintentional scoping of `this`, used in theme files. "@typescript-eslint/no-misused-promises": "off", "@typescript-eslint/unbound-method": "off", + // Computed name [status] resolves to any value (related to external chakra-ui package) "@typescript-eslint/no-unsafe-member-access": "off" } } From 25884ef5d921de010adda4da289ac3737f51a5ac Mon Sep 17 00:00:00 2001 From: ioay Date: Wed, 10 Jan 2024 12:34:03 +0100 Subject: [PATCH 152/170] Added new eslint rule related with the last #105 changes --- dapp/.eslintrc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dapp/.eslintrc b/dapp/.eslintrc index b8736f5e6..63815d434 100644 --- a/dapp/.eslintrc +++ b/dapp/.eslintrc @@ -22,6 +22,8 @@ "@typescript-eslint/no-misused-promises": "off", "@typescript-eslint/unbound-method": "off", // Computed name [status] resolves to any value (related to external chakra-ui package) - "@typescript-eslint/no-unsafe-member-access": "off" + "@typescript-eslint/no-unsafe-member-access": "off", + // Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator + "@typescript-eslint/no-floating-promises": "off" } } From 39cfbbcdb4e2190d37ff7575aab6a1fe9b70791d Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 10 Jan 2024 14:14:28 +0100 Subject: [PATCH 153/170] Fix typo from `seTokenAmount` to `setTokenAmount` --- dapp/src/components/Modals/Staking/StakeForm/index.tsx | 6 +++--- dapp/src/contexts/TransactionContext.tsx | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dapp/src/components/Modals/Staking/StakeForm/index.tsx b/dapp/src/components/Modals/Staking/StakeForm/index.tsx index 38ea05136..635e17e23 100644 --- a/dapp/src/components/Modals/Staking/StakeForm/index.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm/index.tsx @@ -9,16 +9,16 @@ import Details from "./Details" function StakeForm({ goNext }: ModalStep) { const { btcAccount } = useWalletContext() - const { seTokenAmount } = useTransactionContext() + const { setTokenAmount } = useTransactionContext() const handleSubmitForm = useCallback( (values: TokenAmountFormValues) => { if (!values.amount) return - seTokenAmount({ amount: values.amount, currency: "bitcoin" }) + setTokenAmount({ amount: values.amount, currency: "bitcoin" }) goNext() }, - [goNext, seTokenAmount], + [goNext, setTokenAmount], ) return ( diff --git a/dapp/src/contexts/TransactionContext.tsx b/dapp/src/contexts/TransactionContext.tsx index b0f92ac6c..384bfb2e5 100644 --- a/dapp/src/contexts/TransactionContext.tsx +++ b/dapp/src/contexts/TransactionContext.tsx @@ -3,12 +3,12 @@ import { TokenAmount } from "../types" type TransactionContextValue = { tokenAmount?: TokenAmount - seTokenAmount: React.Dispatch> + setTokenAmount: React.Dispatch> } export const TransactionContext = createContext({ tokenAmount: undefined, - seTokenAmount: () => {}, + setTokenAmount: () => {}, }) export function TransactionContextProvider({ @@ -16,7 +16,7 @@ export function TransactionContextProvider({ }: { children: React.ReactNode }): React.ReactElement { - const [tokenAmount, seTokenAmount] = useState( + const [tokenAmount, setTokenAmount] = useState( undefined, ) @@ -24,7 +24,7 @@ export function TransactionContextProvider({ useMemo( () => ({ tokenAmount, - seTokenAmount, + setTokenAmount, }), [tokenAmount], ) From 597a89072be9e3b31c7e03ef3636b9d68cb4294c Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 10 Jan 2024 14:21:52 +0100 Subject: [PATCH 154/170] Create a special hook for the token amount value from form --- .../components/Modals/Staking/StakeForm/Details.tsx | 6 ++---- .../shared/TokenAmountForm/TokenAmountFormBase.tsx | 13 +++++++++++-- dapp/src/constants/forms.ts | 1 - dapp/src/constants/index.ts | 1 - 4 files changed, 13 insertions(+), 8 deletions(-) delete mode 100644 dapp/src/constants/forms.ts diff --git a/dapp/src/components/Modals/Staking/StakeForm/Details.tsx b/dapp/src/components/Modals/Staking/StakeForm/Details.tsx index e334c5403..efa0f70a3 100644 --- a/dapp/src/components/Modals/Staking/StakeForm/Details.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm/Details.tsx @@ -1,14 +1,12 @@ import React from "react" import { List } from "@chakra-ui/react" -import { useField } from "formik" import { useTransactionDetails } from "../../../../hooks" import TransactionDetailsAmountItem from "../../../shared/TransactionDetails/AmountItem" import { CurrencyType } from "../../../../types" -import { TOKEN_AMOUNT_FIELD_NAME } from "../../../../constants" +import { useTokenAmountFormValue } from "../../../shared/TokenAmountForm/TokenAmountFormBase" function Details({ currency }: { currency: CurrencyType }) { - const [, { value }] = useField(TOKEN_AMOUNT_FIELD_NAME) - + const value = useTokenAmountFormValue() const details = useTransactionDetails(value ?? 0n) return ( diff --git a/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx b/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx index fd4b6a05b..7324f2251 100644 --- a/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx +++ b/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx @@ -1,13 +1,22 @@ import React from "react" -import { FormikProps } from "formik" +import { FormikProps, useField } from "formik" import { Form, FormTokenBalanceInput } from "../Form" import { CurrencyType } from "../../../types" -import { TOKEN_AMOUNT_FIELD_NAME } from "../../../constants" + +const TOKEN_AMOUNT_FIELD_NAME = "amount" export type TokenAmountFormValues = { [TOKEN_AMOUNT_FIELD_NAME]?: bigint } +export const useTokenAmountFormValue = () => { + const [, { value }] = useField< + TokenAmountFormValues[typeof TOKEN_AMOUNT_FIELD_NAME] + >(TOKEN_AMOUNT_FIELD_NAME) + + return value +} + export type TokenAmountFormBaseProps = { formId?: string tokenBalance: string diff --git a/dapp/src/constants/forms.ts b/dapp/src/constants/forms.ts deleted file mode 100644 index aba16ef3f..000000000 --- a/dapp/src/constants/forms.ts +++ /dev/null @@ -1 +0,0 @@ -export const TOKEN_AMOUNT_FIELD_NAME = "amount" diff --git a/dapp/src/constants/index.ts b/dapp/src/constants/index.ts index 46dfb30a7..a5cb59713 100644 --- a/dapp/src/constants/index.ts +++ b/dapp/src/constants/index.ts @@ -1,3 +1,2 @@ export * from "./currency" export * from "./staking" -export * from "./forms" From ed538622be7b58a064e005d7eae4c390c87b05d6 Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Thu, 11 Jan 2024 11:59:41 +0100 Subject: [PATCH 155/170] Use beforeAfterSnapshotWrapper in Dispatcher test file Use snapshots to isolate test suites, so the chain state doesn't leak from one test suite to another. --- core/test/Dispatcher.test.ts | 37 +++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/core/test/Dispatcher.test.ts b/core/test/Dispatcher.test.ts index 6abb80a1b..eabcc46ac 100644 --- a/core/test/Dispatcher.test.ts +++ b/core/test/Dispatcher.test.ts @@ -3,9 +3,10 @@ import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers" import { expect } from "chai" import { loadFixture } from "@nomicfoundation/hardhat-toolbox/network-helpers" -import { ZeroAddress } from "ethers" +import { ContractTransactionResponse, ZeroAddress } from "ethers" import { beforeAfterEachSnapshotWrapper, + beforeAfterSnapshotWrapper, deployment, getNamedSigner, getUnnamedSigner, @@ -47,10 +48,12 @@ describe("Dispatcher", () => { vaultAddress4 = await ethers.Wallet.createRandom().getAddress() }) - beforeAfterEachSnapshotWrapper() - describe("authorizeVault", () => { + beforeAfterSnapshotWrapper() + context("when caller is not a governance account", () => { + beforeAfterSnapshotWrapper() + it("should revert when adding a vault", async () => { await expect( dispatcher.connect(thirdParty).authorizeVault(vaultAddress1), @@ -64,9 +67,11 @@ describe("Dispatcher", () => { }) context("when caller is a governance account", () => { + beforeAfterSnapshotWrapper() + let tx: ContractTransactionResponse - beforeEach(async () => { + before(async () => { tx = await dispatcher.connect(governance).authorizeVault(vaultAddress1) await dispatcher.connect(governance).authorizeVault(vaultAddress2) await dispatcher.connect(governance).authorizeVault(vaultAddress3) @@ -98,7 +103,9 @@ describe("Dispatcher", () => { }) describe("deauthorizeVault", () => { - beforeEach(async () => { + beforeAfterSnapshotWrapper() + + before(async () => { await dispatcher.connect(governance).authorizeVault(vaultAddress1) await dispatcher.connect(governance).authorizeVault(vaultAddress2) await dispatcher.connect(governance).authorizeVault(vaultAddress3) @@ -118,6 +125,8 @@ describe("Dispatcher", () => { }) context("when caller is a governance account", () => { + beforeAfterEachSnapshotWrapper() + it("should deauthorize vaults", async () => { await dispatcher.connect(governance).deauthorizeVault(vaultAddress1) @@ -163,6 +172,8 @@ describe("Dispatcher", () => { }) describe("depositToVault", () => { + beforeAfterSnapshotWrapper() + const assetsToAllocate = to1e18(100) const minSharesOut = to1e18(100) @@ -172,6 +183,8 @@ describe("Dispatcher", () => { }) context("when caller is not maintainer", () => { + beforeAfterSnapshotWrapper() + it("should revert when depositing to a vault", async () => { await expect( dispatcher @@ -187,6 +200,8 @@ describe("Dispatcher", () => { context("when caller is maintainer", () => { context("when vault is not authorized", () => { + beforeAfterSnapshotWrapper() + it("should revert", async () => { const randomAddress = await ethers.Wallet.createRandom().getAddress() await expect( @@ -205,6 +220,8 @@ describe("Dispatcher", () => { }) context("when allocation is successful", () => { + beforeAfterSnapshotWrapper() + let tx: ContractTransactionResponse before(async () => { @@ -239,6 +256,8 @@ describe("Dispatcher", () => { context( "when the expected returned shares are less than the actual returned shares", () => { + beforeAfterSnapshotWrapper() + const sharesOut = assetsToAllocate const minShares = to1e18(101) @@ -258,6 +277,8 @@ describe("Dispatcher", () => { }) describe("updateMaintainer", () => { + beforeAfterSnapshotWrapper() + let newMaintainer: string before(async () => { @@ -265,6 +286,8 @@ describe("Dispatcher", () => { }) context("when caller is not an owner", () => { + beforeAfterSnapshotWrapper() + it("should revert", async () => { await expect( dispatcher.connect(thirdParty).updateMaintainer(newMaintainer), @@ -279,6 +302,8 @@ describe("Dispatcher", () => { context("when caller is an owner", () => { context("when maintainer is a zero address", () => { + beforeAfterSnapshotWrapper() + it("should revert", async () => { await expect( dispatcher.connect(governance).updateMaintainer(ZeroAddress), @@ -287,6 +312,8 @@ describe("Dispatcher", () => { }) context("when maintainer is not a zero address", () => { + beforeAfterSnapshotWrapper() + let tx: ContractTransactionResponse before(async () => { From 5e9248b1b22be032f011fa9eb45c01c39aa55242 Mon Sep 17 00:00:00 2001 From: ioay Date: Thu, 11 Jan 2024 14:17:34 +0100 Subject: [PATCH 156/170] Update config files --- dapp/.eslintrc | 10 +++ dapp/package.json | 6 +- dapp/tsconfig.json | 7 +- dapp/vite.config.ts | 10 ++- pnpm-lock.yaml | 186 +++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 211 insertions(+), 8 deletions(-) diff --git a/dapp/.eslintrc b/dapp/.eslintrc index 4317c87a7..528de4b43 100644 --- a/dapp/.eslintrc +++ b/dapp/.eslintrc @@ -16,5 +16,15 @@ { "allowRequiredDefaults": true } ], "react/require-default-props": [0] + }, + "settings": { + "import/resolver": { + "alias": { + "map": [ + ["~", "./src"] + ], + "extensions": [".js", ".jsx",".ts", ".tsx"] + } + } } } diff --git a/dapp/package.json b/dapp/package.json index c3b061d02..439201a1c 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -34,9 +34,13 @@ "@typescript-eslint/parser": "^6.12.0", "@vitejs/plugin-react": "^4.2.0", "eslint": "^8.54.0", + "eslint-import-resolver-alias": "^1.1.2", + "eslint-plugin-import": "^2.29.1", "prettier": "^3.1.0", "typescript": "^5.3.2", "vite": "^5.0.2", - "vite-plugin-node-polyfills": "^0.19.0" + "vite-plugin-eslint": "^1.8.1", + "vite-plugin-node-polyfills": "^0.19.0", + "vite-tsconfig-paths": "^4.2.3" } } diff --git a/dapp/tsconfig.json b/dapp/tsconfig.json index 2e31274ea..0d679c735 100644 --- a/dapp/tsconfig.json +++ b/dapp/tsconfig.json @@ -11,8 +11,11 @@ "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", - "strict": true + "strict": true, + "baseUrl": ".", + "paths": { + "~/*": ["./src/*"] + } }, - "include": ["src"], "references": [{ "path": "./tsconfig.node.json" }] } diff --git a/dapp/vite.config.ts b/dapp/vite.config.ts index cef82d65c..14ad46477 100644 --- a/dapp/vite.config.ts +++ b/dapp/vite.config.ts @@ -1,7 +1,15 @@ import { defineConfig } from "vite" import react from "@vitejs/plugin-react" import { nodePolyfills } from "vite-plugin-node-polyfills" +import eslint from "vite-plugin-eslint" + +import { resolve } from "path" export default defineConfig({ - plugins: [nodePolyfills(), react()], + resolve: { + alias: { + "~": resolve(__dirname, "./src"), + }, + }, + plugins: [nodePolyfills(), react(), eslint()], }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cbe06e8d4..48a4c27dc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -166,6 +166,12 @@ importers: eslint: specifier: ^8.54.0 version: 8.54.0 + eslint-import-resolver-alias: + specifier: ^1.1.2 + version: 1.1.2(eslint-plugin-import@2.29.1) + eslint-plugin-import: + specifier: ^2.29.1 + version: 2.29.1(@typescript-eslint/parser@6.12.0)(eslint@8.54.0) prettier: specifier: ^3.1.0 version: 3.1.0 @@ -175,9 +181,15 @@ importers: vite: specifier: ^5.0.2 version: 5.0.2 + vite-plugin-eslint: + specifier: ^1.8.1 + version: 1.8.1(eslint@8.54.0)(vite@5.0.2) vite-plugin-node-polyfills: specifier: ^0.19.0 version: 0.19.0(vite@5.0.2) + vite-tsconfig-paths: + specifier: ^4.2.3 + version: 4.2.3(typescript@5.3.2)(vite@5.0.2) sdk: devDependencies: @@ -5088,6 +5100,14 @@ packages: magic-string: 0.30.5 dev: true + /@rollup/pluginutils@4.2.1: + resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} + engines: {node: '>= 8.0.0'} + dependencies: + estree-walker: 2.0.2 + picomatch: 2.3.1 + dev: true + /@rollup/pluginutils@5.1.0: resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} engines: {node: '>=14.0.0'} @@ -5390,11 +5410,11 @@ packages: '@typescript-eslint/eslint-plugin': 6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.3.2) '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.3.2) eslint: 8.54.0 - eslint-config-airbnb: 19.0.4(eslint-plugin-import@2.29.0)(eslint-plugin-jsx-a11y@6.8.0)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.33.2)(eslint@8.54.0) - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.0)(eslint@8.54.0) - eslint-config-airbnb-typescript: 17.1.0(@typescript-eslint/eslint-plugin@6.12.0)(@typescript-eslint/parser@6.12.0)(eslint-plugin-import@2.29.0)(eslint@8.54.0) + eslint-config-airbnb: 19.0.4(eslint-plugin-import@2.29.1)(eslint-plugin-jsx-a11y@6.8.0)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.33.2)(eslint@8.54.0) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1)(eslint@8.54.0) + eslint-config-airbnb-typescript: 17.1.0(@typescript-eslint/eslint-plugin@6.12.0)(@typescript-eslint/parser@6.12.0)(eslint-plugin-import@2.29.1)(eslint@8.54.0) eslint-config-prettier: 9.0.0(eslint@8.54.0) - eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.12.0)(eslint@8.54.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.54.0) eslint-plugin-no-only-tests: 3.1.0 eslint-plugin-prettier: 5.0.1(eslint-config-prettier@9.0.0)(eslint@8.54.0)(prettier@3.1.0) @@ -8577,6 +8597,21 @@ packages: semver: 6.3.1 dev: true + /eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.29.1)(eslint@8.54.0): + resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + eslint: ^7.32.0 || ^8.2.0 + eslint-plugin-import: ^2.25.2 + dependencies: + confusing-browser-globals: 1.0.11 + eslint: 8.54.0 + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.12.0)(eslint@8.54.0) + object.assign: 4.1.4 + object.entries: 1.1.7 + semver: 6.3.1 + dev: true + /eslint-config-airbnb-typescript@17.1.0(@typescript-eslint/eslint-plugin@6.12.0)(@typescript-eslint/parser@6.12.0)(eslint-plugin-import@2.29.0)(eslint@8.54.0): resolution: {integrity: sha512-GPxI5URre6dDpJ0CtcthSZVBAfI+Uw7un5OYNVxP2EYi3H81Jw701yFP7AU+/vCE7xBtFmjge7kfhhk4+RAiig==} peerDependencies: @@ -8592,6 +8627,21 @@ packages: eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0) dev: true + /eslint-config-airbnb-typescript@17.1.0(@typescript-eslint/eslint-plugin@6.12.0)(@typescript-eslint/parser@6.12.0)(eslint-plugin-import@2.29.1)(eslint@8.54.0): + resolution: {integrity: sha512-GPxI5URre6dDpJ0CtcthSZVBAfI+Uw7un5OYNVxP2EYi3H81Jw701yFP7AU+/vCE7xBtFmjge7kfhhk4+RAiig==} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^5.13.0 || ^6.0.0 + '@typescript-eslint/parser': ^5.0.0 || ^6.0.0 + eslint: ^7.32.0 || ^8.2.0 + eslint-plugin-import: ^2.25.3 + dependencies: + '@typescript-eslint/eslint-plugin': 6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.3.2) + eslint: 8.54.0 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1)(eslint@8.54.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.12.0)(eslint@8.54.0) + dev: true + /eslint-config-airbnb@19.0.4(eslint-plugin-import@2.29.0)(eslint-plugin-jsx-a11y@6.8.0)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.33.2)(eslint@8.54.0): resolution: {integrity: sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==} engines: {node: ^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -8612,6 +8662,26 @@ packages: object.entries: 1.1.7 dev: true + /eslint-config-airbnb@19.0.4(eslint-plugin-import@2.29.1)(eslint-plugin-jsx-a11y@6.8.0)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.33.2)(eslint@8.54.0): + resolution: {integrity: sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==} + engines: {node: ^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.32.0 || ^8.2.0 + eslint-plugin-import: ^2.25.3 + eslint-plugin-jsx-a11y: ^6.5.1 + eslint-plugin-react: ^7.28.0 + eslint-plugin-react-hooks: ^4.3.0 + dependencies: + eslint: 8.54.0 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1)(eslint@8.54.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.12.0)(eslint@8.54.0) + eslint-plugin-jsx-a11y: 6.8.0(eslint@8.54.0) + eslint-plugin-react: 7.33.2(eslint@8.54.0) + eslint-plugin-react-hooks: 4.6.0(eslint@8.54.0) + object.assign: 4.1.4 + object.entries: 1.1.7 + dev: true + /eslint-config-prettier@9.0.0(eslint@8.54.0): resolution: {integrity: sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==} hasBin: true @@ -8657,6 +8727,15 @@ packages: eslint-plugin-react-hooks: 4.6.0(eslint@8.54.0) typescript: 5.3.2 + /eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.29.1): + resolution: {integrity: sha512-WdviM1Eu834zsfjHtcGHtGfcu+F30Od3V7I9Fi57uhBEwPkjDcii7/yW8jAT+gOhn4P/vOxxNAXbFAKsrrc15w==} + engines: {node: '>= 4'} + peerDependencies: + eslint-plugin-import: '>=1.4.0' + dependencies: + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.12.0)(eslint@8.54.0) + dev: true + /eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} dependencies: @@ -8738,6 +8817,41 @@ packages: - eslint-import-resolver-webpack - supports-color + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.12.0)(eslint@8.54.0): + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.3.2) + array-includes: 3.1.7 + array.prototype.findlastindex: 1.2.3 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.54.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-node@0.3.9)(eslint@8.54.0) + hasown: 2.0.0 + is-core-module: 2.13.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.7 + object.groupby: 1.0.1 + object.values: 1.1.7 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + /eslint-plugin-jsx-a11y@6.8.0(eslint@8.54.0): resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==} engines: {node: '>=4.0'} @@ -10431,6 +10545,10 @@ packages: merge2: 1.4.1 slash: 3.0.0 + /globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + dev: true + /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: @@ -13874,6 +13992,14 @@ packages: bn.js: 5.2.1 dev: true + /rollup@2.79.1: + resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.3 + dev: true + /rollup@4.5.1: resolution: {integrity: sha512-0EQribZoPKpb5z1NW/QYm3XSR//Xr8BeEXU49Lc/mQmpmVVG5jPUVrpc2iptup/0WMrY9mzas0fxH+TjYvG2CA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -15016,6 +15142,19 @@ packages: resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==} dev: true + /tsconfck@2.1.2(typescript@5.3.2): + resolution: {integrity: sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==} + engines: {node: ^14.13.1 || ^16 || >=18} + hasBin: true + peerDependencies: + typescript: ^4.3.5 || ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + typescript: 5.3.2 + dev: true + /tsconfig-paths@3.14.2: resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} dependencies: @@ -15024,6 +15163,15 @@ packages: minimist: 1.2.8 strip-bom: 3.0.0 + /tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} @@ -15420,6 +15568,19 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + /vite-plugin-eslint@1.8.1(eslint@8.54.0)(vite@5.0.2): + resolution: {integrity: sha512-PqdMf3Y2fLO9FsNPmMX+//2BF5SF8nEWspZdgl4kSt7UvHDRHVVfHvxsD7ULYzZrJDGRxR81Nq7TOFgwMnUang==} + peerDependencies: + eslint: '>=7' + vite: '>=2' + dependencies: + '@rollup/pluginutils': 4.2.1 + '@types/eslint': 8.44.7 + eslint: 8.54.0 + rollup: 2.79.1 + vite: 5.0.2 + dev: true + /vite-plugin-node-polyfills@0.19.0(vite@5.0.2): resolution: {integrity: sha512-AhdVxAmVnd1doUlIRGUGV6ZRPfB9BvIwDF10oCOmL742IsvsFIAV4tSMxSfu5e0Px0QeJLgWVOSbtHIvblzqMw==} peerDependencies: @@ -15432,6 +15593,23 @@ packages: - rollup dev: true + /vite-tsconfig-paths@4.2.3(typescript@5.3.2)(vite@5.0.2): + resolution: {integrity: sha512-xVsA2xe6QSlzBujtWF8q2NYexh7PAUYfzJ4C8Axpe/7d2pcERYxuxGgph9F4f0iQO36g5tyGq6eBUYIssdUrVw==} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: + optional: true + dependencies: + debug: 4.3.4(supports-color@8.1.1) + globrex: 0.1.2 + tsconfck: 2.1.2(typescript@5.3.2) + vite: 5.0.2 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + /vite@5.0.2: resolution: {integrity: sha512-6CCq1CAJCNM1ya2ZZA7+jS2KgnhbzvxakmlIjN24cF/PXhRMzpM/z8QgsVJA/Dm5fWUWnVEsmtBoMhmerPxT0g==} engines: {node: ^18.0.0 || >=20.0.0} From 2cdb45088f230e3e0c5f504b23ee2030c9dbfdda Mon Sep 17 00:00:00 2001 From: ioay Date: Thu, 11 Jan 2024 14:28:14 +0100 Subject: [PATCH 157/170] Update imports --- dapp/package.json | 1 - dapp/src/components/DocsDrawer/index.tsx | 4 +- dapp/src/components/GlobalStyles/index.tsx | 10 +-- dapp/src/components/Header/ConnectWallet.tsx | 10 +-- dapp/src/components/Header/index.tsx | 2 +- .../components/Modals/ActionForm/index.tsx | 2 +- .../components/Modals/Staking/DepositBTC.tsx | 6 +- .../Modals/Staking/Overview/index.tsx | 4 +- .../Modals/Staking/Overview/steps.tsx | 2 +- .../components/Modals/Staking/SignMessage.tsx | 6 +- .../Modals/Staking/StakeForm/Details.tsx | 8 +-- .../Modals/Staking/StakeForm/index.tsx | 10 +-- .../Staking/components/StakingSteps.tsx | 6 +- dapp/src/components/Modals/Staking/index.tsx | 4 +- .../Modals/Support/MissingAccount.tsx | 8 +-- dapp/src/components/Modals/Support/index.tsx | 4 +- .../components/Overview/PositionDetails.tsx | 6 +- dapp/src/components/Overview/Statistics.tsx | 2 +- .../Overview/TransactionHistory.tsx | 2 +- dapp/src/components/Overview/index.tsx | 8 +-- dapp/src/components/Sidebar/index.tsx | 2 +- dapp/src/components/shared/Alert/index.tsx | 2 +- .../shared/CurrencyBalance/index.tsx | 4 +- .../src/components/shared/ModalBase/index.tsx | 4 +- .../TokenAmountForm/TokenAmountFormBase.tsx | 2 +- .../shared/TokenAmountForm/index.tsx | 2 +- .../shared/TokenBalanceInput/index.tsx | 6 +- dapp/src/constants/currency.ts | 2 +- dapp/src/contexts/TransactionContext.tsx | 2 +- dapp/src/hooks/useDepositBTCTransaction.ts | 2 +- dapp/src/hooks/useDocsDrawer.ts | 2 +- dapp/src/hooks/useModalFlowContext.ts | 2 +- dapp/src/hooks/useRequestBitcoinAccount.ts | 6 +- dapp/src/hooks/useRequestEthereumAccount.ts | 6 +- dapp/src/hooks/useSidebar.ts | 2 +- dapp/src/hooks/useSignMessage.ts | 2 +- dapp/src/hooks/useTransactionContext.ts | 2 +- dapp/src/hooks/useWalletContext.ts | 2 +- dapp/src/utils/currency.ts | 4 +- dapp/src/utils/forms.ts | 2 +- dapp/vite.config.ts | 3 +- pnpm-lock.yaml | 63 +++++++------------ 42 files changed, 103 insertions(+), 126 deletions(-) diff --git a/dapp/package.json b/dapp/package.json index 439201a1c..9abe245b2 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -39,7 +39,6 @@ "prettier": "^3.1.0", "typescript": "^5.3.2", "vite": "^5.0.2", - "vite-plugin-eslint": "^1.8.1", "vite-plugin-node-polyfills": "^0.19.0", "vite-tsconfig-paths": "^4.2.3" } diff --git a/dapp/src/components/DocsDrawer/index.tsx b/dapp/src/components/DocsDrawer/index.tsx index 5082af57b..35e49647c 100644 --- a/dapp/src/components/DocsDrawer/index.tsx +++ b/dapp/src/components/DocsDrawer/index.tsx @@ -5,8 +5,8 @@ import { DrawerContent, DrawerOverlay, } from "@chakra-ui/react" -import { useDocsDrawer } from "../../hooks" -import { TextMd } from "../shared/Typography" +import { useDocsDrawer } from "~/hooks" +import { TextMd } from "~/components/shared/Typography" export default function DocsDrawer() { const { isOpen, onClose } = useDocsDrawer() diff --git a/dapp/src/components/GlobalStyles/index.tsx b/dapp/src/components/GlobalStyles/index.tsx index 80b36e6e8..d316cead6 100644 --- a/dapp/src/components/GlobalStyles/index.tsx +++ b/dapp/src/components/GlobalStyles/index.tsx @@ -1,11 +1,11 @@ import React from "react" import { Global } from "@emotion/react" -import SegmentRegular from "../../fonts/Segment-Regular.otf" -import SegmentMedium from "../../fonts/Segment-Medium.otf" -import SegmentSemiBold from "../../fonts/Segment-SemiBold.otf" -import SegmentBold from "../../fonts/Segment-Bold.otf" -import SegmentBlack from "../../fonts/Segment-Black.otf" +import SegmentRegular from "~/fonts/Segment-Regular.otf" +import SegmentMedium from "~/fonts/Segment-Medium.otf" +import SegmentSemiBold from "~/fonts/Segment-SemiBold.otf" +import SegmentBold from "~/fonts/Segment-Bold.otf" +import SegmentBlack from "~/fonts/Segment-Black.otf" export default function GlobalStyles() { return ( diff --git a/dapp/src/components/Header/ConnectWallet.tsx b/dapp/src/components/Header/ConnectWallet.tsx index 90069b4e7..28bad070d 100644 --- a/dapp/src/components/Header/ConnectWallet.tsx +++ b/dapp/src/components/Header/ConnectWallet.tsx @@ -1,15 +1,15 @@ import React from "react" import { Button, HStack, Icon } from "@chakra-ui/react" import { Account } from "@ledgerhq/wallet-api-client" -import { Bitcoin, Ethereum } from "../../static/icons" import { useRequestBitcoinAccount, useRequestEthereumAccount, useWalletContext, -} from "../../hooks" -import { truncateAddress } from "../../utils" -import { CurrencyBalance } from "../shared/CurrencyBalance" -import { TextMd } from "../shared/Typography" +} from "~/hooks" +import { CurrencyBalance } from "~/components/shared/CurrencyBalance" +import { TextMd } from "~/components/shared/Typography" +import { Bitcoin, Ethereum } from "~/static/icons" +import { truncateAddress } from "~/utils" export type ConnectButtonsProps = { leftIcon: typeof Icon diff --git a/dapp/src/components/Header/index.tsx b/dapp/src/components/Header/index.tsx index 544fbdee9..b0d47f2ab 100644 --- a/dapp/src/components/Header/index.tsx +++ b/dapp/src/components/Header/index.tsx @@ -1,7 +1,7 @@ import React from "react" import { Flex, HStack, Icon } from "@chakra-ui/react" +import { AcreLogo } from "~/static/icons" import ConnectWallet from "./ConnectWallet" -import { AcreLogo } from "../../static/icons" export default function Header() { return ( diff --git a/dapp/src/components/Modals/ActionForm/index.tsx b/dapp/src/components/Modals/ActionForm/index.tsx index 0eae3fe5b..d6a595d5d 100644 --- a/dapp/src/components/Modals/ActionForm/index.tsx +++ b/dapp/src/components/Modals/ActionForm/index.tsx @@ -7,8 +7,8 @@ import { TabPanels, TabPanel, } from "@chakra-ui/react" +import { useModalFlowContext } from "~/hooks" import StakeForm from "../Staking/StakeForm" -import { useModalFlowContext } from "../../../hooks" const TABS = ["stake", "unstake"] as const diff --git a/dapp/src/components/Modals/Staking/DepositBTC.tsx b/dapp/src/components/Modals/Staking/DepositBTC.tsx index 853159262..20e649956 100644 --- a/dapp/src/components/Modals/Staking/DepositBTC.tsx +++ b/dapp/src/components/Modals/Staking/DepositBTC.tsx @@ -1,7 +1,7 @@ import React from "react" -import Alert from "../../shared/Alert" -import { useDepositBTCTransaction, useModalFlowContext } from "../../../hooks" -import { TextMd } from "../../shared/Typography" +import { useDepositBTCTransaction, useModalFlowContext } from "~/hooks" +import Alert from "~/components/shared/Alert" +import { TextMd } from "~/components/shared/Typography" import StakingSteps from "./components/StakingSteps" export default function DepositBTC() { diff --git a/dapp/src/components/Modals/Staking/Overview/index.tsx b/dapp/src/components/Modals/Staking/Overview/index.tsx index ecb2c310a..330bb7289 100644 --- a/dapp/src/components/Modals/Staking/Overview/index.tsx +++ b/dapp/src/components/Modals/Staking/Overview/index.tsx @@ -6,8 +6,8 @@ import { ModalHeader, StepNumber, } from "@chakra-ui/react" -import { useModalFlowContext } from "../../../../hooks" -import StepperBase from "../../../shared/StepperBase" +import StepperBase from "~/components/shared/StepperBase" +import { useModalFlowContext } from "~/hooks" import { STEPS } from "./steps" export default function Overview() { diff --git a/dapp/src/components/Modals/Staking/Overview/steps.tsx b/dapp/src/components/Modals/Staking/Overview/steps.tsx index 257c671fa..532e35e50 100644 --- a/dapp/src/components/Modals/Staking/Overview/steps.tsx +++ b/dapp/src/components/Modals/Staking/Overview/steps.tsx @@ -1,5 +1,5 @@ import React from "react" -import { StepBase } from "../../../shared/StepperBase" +import { StepBase } from "~/components/shared/StepperBase" import { Description, Title } from "../components/StakingSteps" export const STEPS: StepBase[] = [ diff --git a/dapp/src/components/Modals/Staking/SignMessage.tsx b/dapp/src/components/Modals/Staking/SignMessage.tsx index 3c6442676..dfe7d2dc1 100644 --- a/dapp/src/components/Modals/Staking/SignMessage.tsx +++ b/dapp/src/components/Modals/Staking/SignMessage.tsx @@ -1,8 +1,8 @@ import React from "react" import { Highlight } from "@chakra-ui/react" -import Alert from "../../shared/Alert" -import { useModalFlowContext, useSignMessage } from "../../../hooks" -import { TextMd } from "../../shared/Typography" +import { useModalFlowContext, useSignMessage } from "~/hooks" +import Alert from "~/components/shared/Alert" +import { TextMd } from "~/components/shared/Typography" import StakingSteps from "./components/StakingSteps" export default function SignMessage() { diff --git a/dapp/src/components/Modals/Staking/StakeForm/Details.tsx b/dapp/src/components/Modals/Staking/StakeForm/Details.tsx index efa0f70a3..5d16cd8e2 100644 --- a/dapp/src/components/Modals/Staking/StakeForm/Details.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm/Details.tsx @@ -1,9 +1,9 @@ import React from "react" import { List } from "@chakra-ui/react" -import { useTransactionDetails } from "../../../../hooks" -import TransactionDetailsAmountItem from "../../../shared/TransactionDetails/AmountItem" -import { CurrencyType } from "../../../../types" -import { useTokenAmountFormValue } from "../../../shared/TokenAmountForm/TokenAmountFormBase" +import TransactionDetailsAmountItem from "~/components/shared/TransactionDetails/AmountItem" +import { useTokenAmountFormValue } from "~/components/shared/TokenAmountForm/TokenAmountFormBase" +import { useTransactionDetails } from "~/hooks" +import { CurrencyType } from "~/types" function Details({ currency }: { currency: CurrencyType }) { const value = useTokenAmountFormValue() diff --git a/dapp/src/components/Modals/Staking/StakeForm/index.tsx b/dapp/src/components/Modals/Staking/StakeForm/index.tsx index 635e17e23..5f9b57bf0 100644 --- a/dapp/src/components/Modals/Staking/StakeForm/index.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm/index.tsx @@ -1,10 +1,10 @@ import React, { useCallback } from "react" import { Button } from "@chakra-ui/react" -import { BITCOIN_MIN_AMOUNT } from "../../../../constants" -import { ModalStep } from "../../../../contexts" -import { useWalletContext, useTransactionContext } from "../../../../hooks" -import TokenAmountForm from "../../../shared/TokenAmountForm" -import { TokenAmountFormValues } from "../../../shared/TokenAmountForm/TokenAmountFormBase" +import { BITCOIN_MIN_AMOUNT } from "~/constants" +import { ModalStep } from "~/contexts" +import TokenAmountForm from "~/components/shared/TokenAmountForm" +import { TokenAmountFormValues } from "~/components/shared/TokenAmountForm/TokenAmountFormBase" +import { useWalletContext, useTransactionContext } from "~/hooks" import Details from "./Details" function StakeForm({ goNext }: ModalStep) { diff --git a/dapp/src/components/Modals/Staking/components/StakingSteps.tsx b/dapp/src/components/Modals/Staking/components/StakingSteps.tsx index a0ebfd4cb..4f0a11d06 100644 --- a/dapp/src/components/Modals/Staking/components/StakingSteps.tsx +++ b/dapp/src/components/Modals/Staking/components/StakingSteps.tsx @@ -6,9 +6,9 @@ import { ModalFooter, ModalHeader, } from "@chakra-ui/react" -import { TextLg, TextMd } from "../../../shared/Typography" -import StepperBase, { StepBase } from "../../../shared/StepperBase" -import Spinner from "../../../shared/Spinner" +import { TextLg, TextMd } from "~/components/shared/Typography" +import StepperBase, { StepBase } from "~/components/shared/StepperBase" +import Spinner from "~/components/shared/Spinner" export function Title({ children }: { children: React.ReactNode }) { return {children} diff --git a/dapp/src/components/Modals/Staking/index.tsx b/dapp/src/components/Modals/Staking/index.tsx index 78d04706c..8bad1b0c4 100644 --- a/dapp/src/components/Modals/Staking/index.tsx +++ b/dapp/src/components/Modals/Staking/index.tsx @@ -1,7 +1,7 @@ import React from "react" -import { useModalFlowContext } from "../../../hooks" +import { useModalFlowContext } from "~/hooks" +import ModalBase from "~/components/shared/ModalBase" import Overview from "./Overview" -import ModalBase from "../../shared/ModalBase" import ActionForm from "../ActionForm" import SignMessage from "./SignMessage" import DepositBTC from "./DepositBTC" diff --git a/dapp/src/components/Modals/Support/MissingAccount.tsx b/dapp/src/components/Modals/Support/MissingAccount.tsx index 2c32b354e..df879d260 100644 --- a/dapp/src/components/Modals/Support/MissingAccount.tsx +++ b/dapp/src/components/Modals/Support/MissingAccount.tsx @@ -7,10 +7,10 @@ import { ModalFooter, ModalHeader, } from "@chakra-ui/react" -import { CurrencyType, RequestAccountParams } from "../../../types" -import { TextMd } from "../../shared/Typography" -import Alert from "../../shared/Alert" -import { getCurrencyByType } from "../../../utils" +import { TextMd } from "~/components/shared/Typography" +import Alert from "~/components/shared/Alert" +import { getCurrencyByType } from "~/utils" +import { CurrencyType, RequestAccountParams } from "~/types" type MissingAccountProps = { currency: CurrencyType diff --git a/dapp/src/components/Modals/Support/index.tsx b/dapp/src/components/Modals/Support/index.tsx index c6784fff4..ca6e51453 100644 --- a/dapp/src/components/Modals/Support/index.tsx +++ b/dapp/src/components/Modals/Support/index.tsx @@ -3,9 +3,9 @@ import { useRequestBitcoinAccount, useRequestEthereumAccount, useWalletContext, -} from "../../../hooks" +} from "~/hooks" +import { ConnectBTCAccount, ConnectETHAccount } from "~/static/icons" import MissingAccount from "./MissingAccount" -import { ConnectBTCAccount, ConnectETHAccount } from "../../../static/icons" export default function SupportWrapper({ children, diff --git a/dapp/src/components/Overview/PositionDetails.tsx b/dapp/src/components/Overview/PositionDetails.tsx index c1de13f71..907be66f1 100644 --- a/dapp/src/components/Overview/PositionDetails.tsx +++ b/dapp/src/components/Overview/PositionDetails.tsx @@ -10,10 +10,10 @@ import { CardProps, useBoolean, } from "@chakra-ui/react" -import { Info } from "../../static/icons" +import { CurrencyBalanceWithConversion } from "~/components/shared/CurrencyBalanceWithConversion" +import { TextMd } from "~/components/shared/Typography" +import { Info } from "~/static/icons" import StakingModal from "../Modals/Staking" -import { CurrencyBalanceWithConversion } from "../shared/CurrencyBalanceWithConversion" -import { TextMd } from "../shared/Typography" export default function PositionDetails(props: CardProps) { const [isOpenStakingModal, stakingModal] = useBoolean() diff --git a/dapp/src/components/Overview/Statistics.tsx b/dapp/src/components/Overview/Statistics.tsx index 8b9c5979e..e8a5df0c5 100644 --- a/dapp/src/components/Overview/Statistics.tsx +++ b/dapp/src/components/Overview/Statistics.tsx @@ -1,6 +1,6 @@ import React from "react" import { CardBody, Card, CardProps } from "@chakra-ui/react" -import { TextMd } from "../shared/Typography" +import { TextMd } from "~/components/shared/Typography" export default function Statistics(props: CardProps) { return ( diff --git a/dapp/src/components/Overview/TransactionHistory.tsx b/dapp/src/components/Overview/TransactionHistory.tsx index e0ff1fb26..557556bd4 100644 --- a/dapp/src/components/Overview/TransactionHistory.tsx +++ b/dapp/src/components/Overview/TransactionHistory.tsx @@ -1,6 +1,6 @@ import React from "react" import { CardBody, Card, CardProps } from "@chakra-ui/react" -import { TextMd } from "../shared/Typography" +import { TextMd } from "~/components/shared/Typography" export default function TransactionHistory(props: CardProps) { return ( diff --git a/dapp/src/components/Overview/index.tsx b/dapp/src/components/Overview/index.tsx index 0ac2b4041..1bee1a175 100644 --- a/dapp/src/components/Overview/index.tsx +++ b/dapp/src/components/Overview/index.tsx @@ -1,12 +1,12 @@ import React from "react" import { Button, Flex, Grid, HStack, Icon, Switch } from "@chakra-ui/react" +import { useDocsDrawer } from "~/hooks" +import { TextSm } from "~/components/shared/Typography" +import { ArrowUpRight } from "~/static/icons" +import { USD } from "~/constants" import PositionDetails from "./PositionDetails" import Statistics from "./Statistics" import TransactionHistory from "./TransactionHistory" -import { USD } from "../../constants" -import { ArrowUpRight } from "../../static/icons" -import { TextSm } from "../shared/Typography" -import { useDocsDrawer } from "../../hooks" export default function Overview() { const { onOpen } = useDocsDrawer() diff --git a/dapp/src/components/Sidebar/index.tsx b/dapp/src/components/Sidebar/index.tsx index a7625698f..2217cfe7c 100644 --- a/dapp/src/components/Sidebar/index.tsx +++ b/dapp/src/components/Sidebar/index.tsx @@ -1,6 +1,6 @@ import React from "react" import { Box, Button, useMultiStyleConfig } from "@chakra-ui/react" -import { useDocsDrawer, useSidebar } from "../../hooks" +import { useDocsDrawer, useSidebar } from "~/hooks" export default function Sidebar() { const { isOpen } = useSidebar() diff --git a/dapp/src/components/shared/Alert/index.tsx b/dapp/src/components/shared/Alert/index.tsx index 2ab05a8f2..cb3d94fd1 100644 --- a/dapp/src/components/shared/Alert/index.tsx +++ b/dapp/src/components/shared/Alert/index.tsx @@ -7,7 +7,7 @@ import { Icon, useMultiStyleConfig, } from "@chakra-ui/react" -import { AlertInfo, ArrowUpRight } from "../../../static/icons" +import { AlertInfo, ArrowUpRight } from "~/static/icons" const ICONS = { info: AlertInfo, diff --git a/dapp/src/components/shared/CurrencyBalance/index.tsx b/dapp/src/components/shared/CurrencyBalance/index.tsx index f44f7505e..65991979a 100644 --- a/dapp/src/components/shared/CurrencyBalance/index.tsx +++ b/dapp/src/components/shared/CurrencyBalance/index.tsx @@ -4,8 +4,8 @@ import { formatTokenAmount, getCurrencyByType, numberToLocaleString, -} from "../../../utils" -import { CurrencyType } from "../../../types" +} from "~/utils" +import { CurrencyType } from "~/types" export type CurrencyBalanceProps = { currency: CurrencyType diff --git a/dapp/src/components/shared/ModalBase/index.tsx b/dapp/src/components/shared/ModalBase/index.tsx index cfeb34472..034527614 100644 --- a/dapp/src/components/shared/ModalBase/index.tsx +++ b/dapp/src/components/shared/ModalBase/index.tsx @@ -5,12 +5,12 @@ import { ModalContent, ModalOverlay, } from "@chakra-ui/react" +import { useSidebar } from "~/hooks" import { ModalFlowContext, ModalFlowContextValue, TransactionContextProvider, -} from "../../../contexts" -import { useSidebar } from "../../../hooks" +} from "~/contexts" import SupportWrapper from "../../Modals/Support" export default function ModalBase({ diff --git a/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx b/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx index 7324f2251..3f07bfe45 100644 --- a/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx +++ b/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx @@ -1,7 +1,7 @@ import React from "react" import { FormikProps, useField } from "formik" +import { CurrencyType } from "~/types" import { Form, FormTokenBalanceInput } from "../Form" -import { CurrencyType } from "../../../types" const TOKEN_AMOUNT_FIELD_NAME = "amount" diff --git a/dapp/src/components/shared/TokenAmountForm/index.tsx b/dapp/src/components/shared/TokenAmountForm/index.tsx index d6d0716c1..50a792af8 100644 --- a/dapp/src/components/shared/TokenAmountForm/index.tsx +++ b/dapp/src/components/shared/TokenAmountForm/index.tsx @@ -1,5 +1,5 @@ import { FormikErrors, withFormik } from "formik" -import { getErrorsObj, validateTokenAmount } from "../../../utils" +import { getErrorsObj, validateTokenAmount } from "~/utils" import TokenAmountFormBase, { TokenAmountFormBaseProps, TokenAmountFormValues, diff --git a/dapp/src/components/shared/TokenBalanceInput/index.tsx b/dapp/src/components/shared/TokenBalanceInput/index.tsx index 82aa75fee..289451c11 100644 --- a/dapp/src/components/shared/TokenBalanceInput/index.tsx +++ b/dapp/src/components/shared/TokenBalanceInput/index.tsx @@ -16,13 +16,13 @@ import { fixedPointNumberToString, getCurrencyByType, userAmountToBigInt, -} from "../../../utils" -import { CurrencyType } from "../../../types" +} from "~/utils" +import { AlertInfo } from "~/static/icons" +import { CurrencyType } from "~/types" import NumberFormatInput, { NumberFormatInputValues, } from "../NumberFormatInput" import { CurrencyBalance } from "../CurrencyBalance" -import { AlertInfo } from "../../../static/icons" const VARIANT = "balance" diff --git a/dapp/src/constants/currency.ts b/dapp/src/constants/currency.ts index 420adb8b6..75b1c572b 100644 --- a/dapp/src/constants/currency.ts +++ b/dapp/src/constants/currency.ts @@ -1,4 +1,4 @@ -import { Currency, CurrencyType } from "../types" +import { Currency, CurrencyType } from "~/types" export const BITCOIN: Currency = { name: "Bitcoin", diff --git a/dapp/src/contexts/TransactionContext.tsx b/dapp/src/contexts/TransactionContext.tsx index 384bfb2e5..47bb3b801 100644 --- a/dapp/src/contexts/TransactionContext.tsx +++ b/dapp/src/contexts/TransactionContext.tsx @@ -1,5 +1,5 @@ import React, { createContext, useMemo, useState } from "react" -import { TokenAmount } from "../types" +import { TokenAmount } from "~/types" type TransactionContextValue = { tokenAmount?: TokenAmount diff --git a/dapp/src/hooks/useDepositBTCTransaction.ts b/dapp/src/hooks/useDepositBTCTransaction.ts index a629e6485..861e55870 100644 --- a/dapp/src/hooks/useDepositBTCTransaction.ts +++ b/dapp/src/hooks/useDepositBTCTransaction.ts @@ -1,5 +1,5 @@ import { useCallback } from "react" -import { OnSuccessCallback } from "../types" +import { OnSuccessCallback } from "~/types" export function useDepositBTCTransaction(onSuccess?: OnSuccessCallback) { // TODO: sending transactions using the SDK diff --git a/dapp/src/hooks/useDocsDrawer.ts b/dapp/src/hooks/useDocsDrawer.ts index 4ce8bba3e..e560afa83 100644 --- a/dapp/src/hooks/useDocsDrawer.ts +++ b/dapp/src/hooks/useDocsDrawer.ts @@ -1,5 +1,5 @@ import { useContext } from "react" -import { DocsDrawerContext } from "../contexts" +import { DocsDrawerContext } from "~/contexts" export function useDocsDrawer() { const context = useContext(DocsDrawerContext) diff --git a/dapp/src/hooks/useModalFlowContext.ts b/dapp/src/hooks/useModalFlowContext.ts index 48882c561..fafb6a565 100644 --- a/dapp/src/hooks/useModalFlowContext.ts +++ b/dapp/src/hooks/useModalFlowContext.ts @@ -1,5 +1,5 @@ import { useContext } from "react" -import { ModalFlowContext } from "../contexts" +import { ModalFlowContext } from "~/contexts" export function useModalFlowContext() { const context = useContext(ModalFlowContext) diff --git a/dapp/src/hooks/useRequestBitcoinAccount.ts b/dapp/src/hooks/useRequestBitcoinAccount.ts index 036db196d..d780eb016 100644 --- a/dapp/src/hooks/useRequestBitcoinAccount.ts +++ b/dapp/src/hooks/useRequestBitcoinAccount.ts @@ -1,8 +1,8 @@ import { useRequestAccount } from "@ledgerhq/wallet-api-client-react" import { useCallback, useContext, useEffect } from "react" -import { CURRENCY_ID_BITCOIN } from "../constants" -import { UseRequestAccountReturn } from "../types" -import { WalletContext } from "../contexts" +import { WalletContext } from "~/contexts" +import { UseRequestAccountReturn } from "~/types" +import { CURRENCY_ID_BITCOIN } from "~/constants" export function useRequestBitcoinAccount(): UseRequestAccountReturn { const { setBtcAccount } = useContext(WalletContext) diff --git a/dapp/src/hooks/useRequestEthereumAccount.ts b/dapp/src/hooks/useRequestEthereumAccount.ts index 5c3cad1f1..d1dd87ad7 100644 --- a/dapp/src/hooks/useRequestEthereumAccount.ts +++ b/dapp/src/hooks/useRequestEthereumAccount.ts @@ -1,8 +1,8 @@ import { useRequestAccount } from "@ledgerhq/wallet-api-client-react" import { useCallback, useContext, useEffect } from "react" -import { CURRENCY_ID_ETHEREUM } from "../constants" -import { UseRequestAccountReturn } from "../types" -import { WalletContext } from "../contexts" +import { WalletContext } from "~/contexts" +import { UseRequestAccountReturn } from "~/types" +import { CURRENCY_ID_ETHEREUM } from "~/constants" export function useRequestEthereumAccount(): UseRequestAccountReturn { const { setEthAccount } = useContext(WalletContext) diff --git a/dapp/src/hooks/useSidebar.ts b/dapp/src/hooks/useSidebar.ts index 986143a89..714330b48 100644 --- a/dapp/src/hooks/useSidebar.ts +++ b/dapp/src/hooks/useSidebar.ts @@ -1,5 +1,5 @@ import { useContext } from "react" -import { SidebarContext } from "../contexts" +import { SidebarContext } from "~/contexts" export function useSidebar() { const context = useContext(SidebarContext) diff --git a/dapp/src/hooks/useSignMessage.ts b/dapp/src/hooks/useSignMessage.ts index cc3cadc3e..21ef804b0 100644 --- a/dapp/src/hooks/useSignMessage.ts +++ b/dapp/src/hooks/useSignMessage.ts @@ -1,7 +1,7 @@ import { useSignMessage as useSignMessageLedgerLive } from "@ledgerhq/wallet-api-client-react" import { useCallback, useEffect } from "react" +import { OnSuccessCallback } from "~/types" import { useWalletContext } from "./useWalletContext" -import { OnSuccessCallback } from "../types" const SIGN_MESSAGE = "Test message" diff --git a/dapp/src/hooks/useTransactionContext.ts b/dapp/src/hooks/useTransactionContext.ts index d28c8bf1b..85b663a51 100644 --- a/dapp/src/hooks/useTransactionContext.ts +++ b/dapp/src/hooks/useTransactionContext.ts @@ -1,5 +1,5 @@ import { useContext } from "react" -import { TransactionContext } from "../contexts" +import { TransactionContext } from "~/contexts" export function useTransactionContext() { const context = useContext(TransactionContext) diff --git a/dapp/src/hooks/useWalletContext.ts b/dapp/src/hooks/useWalletContext.ts index 0da19204b..c786a76dd 100644 --- a/dapp/src/hooks/useWalletContext.ts +++ b/dapp/src/hooks/useWalletContext.ts @@ -1,5 +1,5 @@ import { useContext } from "react" -import { WalletContext } from "../contexts" +import { WalletContext } from "~/contexts" export function useWalletContext() { const context = useContext(WalletContext) diff --git a/dapp/src/utils/currency.ts b/dapp/src/utils/currency.ts index 39eda0651..99d93710a 100644 --- a/dapp/src/utils/currency.ts +++ b/dapp/src/utils/currency.ts @@ -1,5 +1,5 @@ -import { CURRENCIES_BY_TYPE } from "../constants" -import { Currency, CurrencyType } from "../types" +import { Currency, CurrencyType } from "~/types" +import { CURRENCIES_BY_TYPE } from "~/constants" export const getCurrencyByType = (currency: CurrencyType): Currency => CURRENCIES_BY_TYPE[currency] diff --git a/dapp/src/utils/forms.ts b/dapp/src/utils/forms.ts index 9f7f34759..a2fc7b8c4 100644 --- a/dapp/src/utils/forms.ts +++ b/dapp/src/utils/forms.ts @@ -1,4 +1,4 @@ -import { CurrencyType } from "../types" +import { CurrencyType } from "~/types" import { getCurrencyByType } from "./currency" import { formatTokenAmount } from "./numbers" diff --git a/dapp/vite.config.ts b/dapp/vite.config.ts index 14ad46477..71034c086 100644 --- a/dapp/vite.config.ts +++ b/dapp/vite.config.ts @@ -1,7 +1,6 @@ import { defineConfig } from "vite" import react from "@vitejs/plugin-react" import { nodePolyfills } from "vite-plugin-node-polyfills" -import eslint from "vite-plugin-eslint" import { resolve } from "path" @@ -11,5 +10,5 @@ export default defineConfig({ "~": resolve(__dirname, "./src"), }, }, - plugins: [nodePolyfills(), react(), eslint()], + plugins: [nodePolyfills(), react()], }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 48a4c27dc..89f1905c3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -181,9 +181,6 @@ importers: vite: specifier: ^5.0.2 version: 5.0.2 - vite-plugin-eslint: - specifier: ^1.8.1 - version: 1.8.1(eslint@8.54.0)(vite@5.0.2) vite-plugin-node-polyfills: specifier: ^0.19.0 version: 0.19.0(vite@5.0.2) @@ -385,7 +382,7 @@ packages: '@babel/traverse': 7.23.4 '@babel/types': 7.23.4 convert-source-map: 2.0.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -1629,7 +1626,7 @@ packages: '@babel/helper-split-export-declaration': 7.22.6 '@babel/parser': 7.23.4 '@babel/types': 7.23.4 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -3182,7 +3179,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 espree: 9.6.1 globals: 13.23.0 ignore: 5.3.0 @@ -3787,7 +3784,7 @@ packages: engines: {node: '>=10.10.0'} dependencies: '@humanwhocodes/object-schema': 2.0.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -5100,14 +5097,6 @@ packages: magic-string: 0.30.5 dev: true - /@rollup/pluginutils@4.2.1: - resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} - engines: {node: '>= 8.0.0'} - dependencies: - estree-walker: 2.0.2 - picomatch: 2.3.1 - dev: true - /@rollup/pluginutils@5.1.0: resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} engines: {node: '>=14.0.0'} @@ -5813,7 +5802,7 @@ packages: '@typescript-eslint/type-utils': 6.12.0(eslint@8.54.0)(typescript@5.3.2) '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.3.2) '@typescript-eslint/visitor-keys': 6.12.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 eslint: 8.54.0 graphemer: 1.4.0 ignore: 5.3.0 @@ -5858,7 +5847,7 @@ packages: '@typescript-eslint/types': 6.12.0 '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.3.2) '@typescript-eslint/visitor-keys': 6.12.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 eslint: 8.54.0 typescript: 5.3.2 transitivePeerDependencies: @@ -5909,7 +5898,7 @@ packages: dependencies: '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.3.2) '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.3.2) - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 eslint: 8.54.0 ts-api-utils: 1.0.3(typescript@5.3.2) typescript: 5.3.2 @@ -5956,7 +5945,7 @@ packages: dependencies: '@typescript-eslint/types': 6.12.0 '@typescript-eslint/visitor-keys': 6.12.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 @@ -7986,6 +7975,17 @@ packages: dependencies: ms: 2.1.3 + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + /debug@4.3.4(supports-color@8.1.1): resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -9046,7 +9046,7 @@ packages: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -13992,14 +13992,6 @@ packages: bn.js: 5.2.1 dev: true - /rollup@2.79.1: - resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} - engines: {node: '>=10.0.0'} - hasBin: true - optionalDependencies: - fsevents: 2.3.3 - dev: true - /rollup@4.5.1: resolution: {integrity: sha512-0EQribZoPKpb5z1NW/QYm3XSR//Xr8BeEXU49Lc/mQmpmVVG5jPUVrpc2iptup/0WMrY9mzas0fxH+TjYvG2CA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -15568,19 +15560,6 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - /vite-plugin-eslint@1.8.1(eslint@8.54.0)(vite@5.0.2): - resolution: {integrity: sha512-PqdMf3Y2fLO9FsNPmMX+//2BF5SF8nEWspZdgl4kSt7UvHDRHVVfHvxsD7ULYzZrJDGRxR81Nq7TOFgwMnUang==} - peerDependencies: - eslint: '>=7' - vite: '>=2' - dependencies: - '@rollup/pluginutils': 4.2.1 - '@types/eslint': 8.44.7 - eslint: 8.54.0 - rollup: 2.79.1 - vite: 5.0.2 - dev: true - /vite-plugin-node-polyfills@0.19.0(vite@5.0.2): resolution: {integrity: sha512-AhdVxAmVnd1doUlIRGUGV6ZRPfB9BvIwDF10oCOmL742IsvsFIAV4tSMxSfu5e0Px0QeJLgWVOSbtHIvblzqMw==} peerDependencies: @@ -15601,7 +15580,7 @@ packages: vite: optional: true dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 globrex: 0.1.2 tsconfck: 2.1.2(typescript@5.3.2) vite: 5.0.2 From 59731bbba5c2e933be8d3f3e1655b157ff03cf6e Mon Sep 17 00:00:00 2001 From: ioay Date: Thu, 11 Jan 2024 16:14:04 +0100 Subject: [PATCH 158/170] Change prefix for alias: ~ -> # --- dapp/.eslintrc | 2 +- dapp/src/components/DocsDrawer/index.tsx | 4 ++-- dapp/src/components/GlobalStyles/index.tsx | 10 +++++----- dapp/src/components/Header/ConnectWallet.tsx | 10 +++++----- dapp/src/components/Header/index.tsx | 2 +- dapp/src/components/Modals/ActionForm/index.tsx | 2 +- dapp/src/components/Modals/Staking/DepositBTC.tsx | 6 +++--- dapp/src/components/Modals/Staking/Overview/index.tsx | 4 ++-- dapp/src/components/Modals/Staking/Overview/steps.tsx | 2 +- dapp/src/components/Modals/Staking/SignMessage.tsx | 6 +++--- .../components/Modals/Staking/StakeForm/Details.tsx | 8 ++++---- dapp/src/components/Modals/Staking/StakeForm/index.tsx | 10 +++++----- .../Modals/Staking/components/StakingSteps.tsx | 6 +++--- dapp/src/components/Modals/Staking/index.tsx | 4 ++-- dapp/src/components/Modals/Support/MissingAccount.tsx | 8 ++++---- dapp/src/components/Modals/Support/index.tsx | 4 ++-- dapp/src/components/Overview/PositionDetails.tsx | 6 +++--- dapp/src/components/Overview/Statistics.tsx | 2 +- dapp/src/components/Overview/TransactionHistory.tsx | 2 +- dapp/src/components/Overview/index.tsx | 8 ++++---- dapp/src/components/Sidebar/index.tsx | 2 +- dapp/src/components/shared/Alert/index.tsx | 2 +- dapp/src/components/shared/CurrencyBalance/index.tsx | 4 ++-- dapp/src/components/shared/ModalBase/index.tsx | 4 ++-- .../shared/TokenAmountForm/TokenAmountFormBase.tsx | 2 +- dapp/src/components/shared/TokenAmountForm/index.tsx | 2 +- dapp/src/components/shared/TokenBalanceInput/index.tsx | 6 +++--- dapp/src/constants/currency.ts | 2 +- dapp/src/contexts/TransactionContext.tsx | 2 +- dapp/src/hooks/useDepositBTCTransaction.ts | 2 +- dapp/src/hooks/useDocsDrawer.ts | 2 +- dapp/src/hooks/useModalFlowContext.ts | 2 +- dapp/src/hooks/useRequestBitcoinAccount.ts | 6 +++--- dapp/src/hooks/useRequestEthereumAccount.ts | 6 +++--- dapp/src/hooks/useSidebar.ts | 2 +- dapp/src/hooks/useSignMessage.ts | 2 +- dapp/src/hooks/useTransactionContext.ts | 2 +- dapp/src/hooks/useWalletContext.ts | 2 +- dapp/src/utils/currency.ts | 4 ++-- dapp/src/utils/forms.ts | 2 +- dapp/tsconfig.json | 2 +- dapp/vite.config.ts | 2 +- 42 files changed, 84 insertions(+), 84 deletions(-) diff --git a/dapp/.eslintrc b/dapp/.eslintrc index 528de4b43..637e91d05 100644 --- a/dapp/.eslintrc +++ b/dapp/.eslintrc @@ -21,7 +21,7 @@ "import/resolver": { "alias": { "map": [ - ["~", "./src"] + ["#", "./src"] ], "extensions": [".js", ".jsx",".ts", ".tsx"] } diff --git a/dapp/src/components/DocsDrawer/index.tsx b/dapp/src/components/DocsDrawer/index.tsx index 35e49647c..060c6e731 100644 --- a/dapp/src/components/DocsDrawer/index.tsx +++ b/dapp/src/components/DocsDrawer/index.tsx @@ -5,8 +5,8 @@ import { DrawerContent, DrawerOverlay, } from "@chakra-ui/react" -import { useDocsDrawer } from "~/hooks" -import { TextMd } from "~/components/shared/Typography" +import { useDocsDrawer } from "#/hooks" +import { TextMd } from "#/components/shared/Typography" export default function DocsDrawer() { const { isOpen, onClose } = useDocsDrawer() diff --git a/dapp/src/components/GlobalStyles/index.tsx b/dapp/src/components/GlobalStyles/index.tsx index d316cead6..352fe7af0 100644 --- a/dapp/src/components/GlobalStyles/index.tsx +++ b/dapp/src/components/GlobalStyles/index.tsx @@ -1,11 +1,11 @@ import React from "react" import { Global } from "@emotion/react" -import SegmentRegular from "~/fonts/Segment-Regular.otf" -import SegmentMedium from "~/fonts/Segment-Medium.otf" -import SegmentSemiBold from "~/fonts/Segment-SemiBold.otf" -import SegmentBold from "~/fonts/Segment-Bold.otf" -import SegmentBlack from "~/fonts/Segment-Black.otf" +import SegmentRegular from "#/fonts/Segment-Regular.otf" +import SegmentMedium from "#/fonts/Segment-Medium.otf" +import SegmentSemiBold from "#/fonts/Segment-SemiBold.otf" +import SegmentBold from "#/fonts/Segment-Bold.otf" +import SegmentBlack from "#/fonts/Segment-Black.otf" export default function GlobalStyles() { return ( diff --git a/dapp/src/components/Header/ConnectWallet.tsx b/dapp/src/components/Header/ConnectWallet.tsx index 28bad070d..5319a04ca 100644 --- a/dapp/src/components/Header/ConnectWallet.tsx +++ b/dapp/src/components/Header/ConnectWallet.tsx @@ -5,11 +5,11 @@ import { useRequestBitcoinAccount, useRequestEthereumAccount, useWalletContext, -} from "~/hooks" -import { CurrencyBalance } from "~/components/shared/CurrencyBalance" -import { TextMd } from "~/components/shared/Typography" -import { Bitcoin, Ethereum } from "~/static/icons" -import { truncateAddress } from "~/utils" +} from "#/hooks" +import { CurrencyBalance } from "#/components/shared/CurrencyBalance" +import { TextMd } from "#/components/shared/Typography" +import { Bitcoin, Ethereum } from "#/static/icons" +import { truncateAddress } from "#/utils" export type ConnectButtonsProps = { leftIcon: typeof Icon diff --git a/dapp/src/components/Header/index.tsx b/dapp/src/components/Header/index.tsx index b0d47f2ab..480cb502e 100644 --- a/dapp/src/components/Header/index.tsx +++ b/dapp/src/components/Header/index.tsx @@ -1,6 +1,6 @@ import React from "react" import { Flex, HStack, Icon } from "@chakra-ui/react" -import { AcreLogo } from "~/static/icons" +import { AcreLogo } from "#/static/icons" import ConnectWallet from "./ConnectWallet" export default function Header() { diff --git a/dapp/src/components/Modals/ActionForm/index.tsx b/dapp/src/components/Modals/ActionForm/index.tsx index d6a595d5d..eabb156bb 100644 --- a/dapp/src/components/Modals/ActionForm/index.tsx +++ b/dapp/src/components/Modals/ActionForm/index.tsx @@ -7,7 +7,7 @@ import { TabPanels, TabPanel, } from "@chakra-ui/react" -import { useModalFlowContext } from "~/hooks" +import { useModalFlowContext } from "#/hooks" import StakeForm from "../Staking/StakeForm" const TABS = ["stake", "unstake"] as const diff --git a/dapp/src/components/Modals/Staking/DepositBTC.tsx b/dapp/src/components/Modals/Staking/DepositBTC.tsx index 20e649956..924a0ee24 100644 --- a/dapp/src/components/Modals/Staking/DepositBTC.tsx +++ b/dapp/src/components/Modals/Staking/DepositBTC.tsx @@ -1,7 +1,7 @@ import React from "react" -import { useDepositBTCTransaction, useModalFlowContext } from "~/hooks" -import Alert from "~/components/shared/Alert" -import { TextMd } from "~/components/shared/Typography" +import { useDepositBTCTransaction, useModalFlowContext } from "#/hooks" +import Alert from "#/components/shared/Alert" +import { TextMd } from "#/components/shared/Typography" import StakingSteps from "./components/StakingSteps" export default function DepositBTC() { diff --git a/dapp/src/components/Modals/Staking/Overview/index.tsx b/dapp/src/components/Modals/Staking/Overview/index.tsx index 330bb7289..af2485db6 100644 --- a/dapp/src/components/Modals/Staking/Overview/index.tsx +++ b/dapp/src/components/Modals/Staking/Overview/index.tsx @@ -6,8 +6,8 @@ import { ModalHeader, StepNumber, } from "@chakra-ui/react" -import StepperBase from "~/components/shared/StepperBase" -import { useModalFlowContext } from "~/hooks" +import StepperBase from "#/components/shared/StepperBase" +import { useModalFlowContext } from "#/hooks" import { STEPS } from "./steps" export default function Overview() { diff --git a/dapp/src/components/Modals/Staking/Overview/steps.tsx b/dapp/src/components/Modals/Staking/Overview/steps.tsx index 532e35e50..7a6c3ce7a 100644 --- a/dapp/src/components/Modals/Staking/Overview/steps.tsx +++ b/dapp/src/components/Modals/Staking/Overview/steps.tsx @@ -1,5 +1,5 @@ import React from "react" -import { StepBase } from "~/components/shared/StepperBase" +import { StepBase } from "#/components/shared/StepperBase" import { Description, Title } from "../components/StakingSteps" export const STEPS: StepBase[] = [ diff --git a/dapp/src/components/Modals/Staking/SignMessage.tsx b/dapp/src/components/Modals/Staking/SignMessage.tsx index dfe7d2dc1..e3cda7886 100644 --- a/dapp/src/components/Modals/Staking/SignMessage.tsx +++ b/dapp/src/components/Modals/Staking/SignMessage.tsx @@ -1,8 +1,8 @@ import React from "react" import { Highlight } from "@chakra-ui/react" -import { useModalFlowContext, useSignMessage } from "~/hooks" -import Alert from "~/components/shared/Alert" -import { TextMd } from "~/components/shared/Typography" +import { useModalFlowContext, useSignMessage } from "#/hooks" +import Alert from "#/components/shared/Alert" +import { TextMd } from "#/components/shared/Typography" import StakingSteps from "./components/StakingSteps" export default function SignMessage() { diff --git a/dapp/src/components/Modals/Staking/StakeForm/Details.tsx b/dapp/src/components/Modals/Staking/StakeForm/Details.tsx index 5d16cd8e2..698e6da54 100644 --- a/dapp/src/components/Modals/Staking/StakeForm/Details.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm/Details.tsx @@ -1,9 +1,9 @@ import React from "react" import { List } from "@chakra-ui/react" -import TransactionDetailsAmountItem from "~/components/shared/TransactionDetails/AmountItem" -import { useTokenAmountFormValue } from "~/components/shared/TokenAmountForm/TokenAmountFormBase" -import { useTransactionDetails } from "~/hooks" -import { CurrencyType } from "~/types" +import TransactionDetailsAmountItem from "#/components/shared/TransactionDetails/AmountItem" +import { useTokenAmountFormValue } from "#/components/shared/TokenAmountForm/TokenAmountFormBase" +import { useTransactionDetails } from "#/hooks" +import { CurrencyType } from "#/types" function Details({ currency }: { currency: CurrencyType }) { const value = useTokenAmountFormValue() diff --git a/dapp/src/components/Modals/Staking/StakeForm/index.tsx b/dapp/src/components/Modals/Staking/StakeForm/index.tsx index 5f9b57bf0..e5d5a0754 100644 --- a/dapp/src/components/Modals/Staking/StakeForm/index.tsx +++ b/dapp/src/components/Modals/Staking/StakeForm/index.tsx @@ -1,10 +1,10 @@ import React, { useCallback } from "react" import { Button } from "@chakra-ui/react" -import { BITCOIN_MIN_AMOUNT } from "~/constants" -import { ModalStep } from "~/contexts" -import TokenAmountForm from "~/components/shared/TokenAmountForm" -import { TokenAmountFormValues } from "~/components/shared/TokenAmountForm/TokenAmountFormBase" -import { useWalletContext, useTransactionContext } from "~/hooks" +import { BITCOIN_MIN_AMOUNT } from "#/constants" +import { ModalStep } from "#/contexts" +import TokenAmountForm from "#/components/shared/TokenAmountForm" +import { TokenAmountFormValues } from "#/components/shared/TokenAmountForm/TokenAmountFormBase" +import { useWalletContext, useTransactionContext } from "#/hooks" import Details from "./Details" function StakeForm({ goNext }: ModalStep) { diff --git a/dapp/src/components/Modals/Staking/components/StakingSteps.tsx b/dapp/src/components/Modals/Staking/components/StakingSteps.tsx index 4f0a11d06..f092ad079 100644 --- a/dapp/src/components/Modals/Staking/components/StakingSteps.tsx +++ b/dapp/src/components/Modals/Staking/components/StakingSteps.tsx @@ -6,9 +6,9 @@ import { ModalFooter, ModalHeader, } from "@chakra-ui/react" -import { TextLg, TextMd } from "~/components/shared/Typography" -import StepperBase, { StepBase } from "~/components/shared/StepperBase" -import Spinner from "~/components/shared/Spinner" +import { TextLg, TextMd } from "#/components/shared/Typography" +import StepperBase, { StepBase } from "#/components/shared/StepperBase" +import Spinner from "#/components/shared/Spinner" export function Title({ children }: { children: React.ReactNode }) { return {children} diff --git a/dapp/src/components/Modals/Staking/index.tsx b/dapp/src/components/Modals/Staking/index.tsx index 8bad1b0c4..e74dd57ea 100644 --- a/dapp/src/components/Modals/Staking/index.tsx +++ b/dapp/src/components/Modals/Staking/index.tsx @@ -1,6 +1,6 @@ import React from "react" -import { useModalFlowContext } from "~/hooks" -import ModalBase from "~/components/shared/ModalBase" +import { useModalFlowContext } from "#/hooks" +import ModalBase from "#/components/shared/ModalBase" import Overview from "./Overview" import ActionForm from "../ActionForm" import SignMessage from "./SignMessage" diff --git a/dapp/src/components/Modals/Support/MissingAccount.tsx b/dapp/src/components/Modals/Support/MissingAccount.tsx index df879d260..89ca3effd 100644 --- a/dapp/src/components/Modals/Support/MissingAccount.tsx +++ b/dapp/src/components/Modals/Support/MissingAccount.tsx @@ -7,10 +7,10 @@ import { ModalFooter, ModalHeader, } from "@chakra-ui/react" -import { TextMd } from "~/components/shared/Typography" -import Alert from "~/components/shared/Alert" -import { getCurrencyByType } from "~/utils" -import { CurrencyType, RequestAccountParams } from "~/types" +import { TextMd } from "#/components/shared/Typography" +import Alert from "#/components/shared/Alert" +import { getCurrencyByType } from "#/utils" +import { CurrencyType, RequestAccountParams } from "#/types" type MissingAccountProps = { currency: CurrencyType diff --git a/dapp/src/components/Modals/Support/index.tsx b/dapp/src/components/Modals/Support/index.tsx index ca6e51453..ae5aa98eb 100644 --- a/dapp/src/components/Modals/Support/index.tsx +++ b/dapp/src/components/Modals/Support/index.tsx @@ -3,8 +3,8 @@ import { useRequestBitcoinAccount, useRequestEthereumAccount, useWalletContext, -} from "~/hooks" -import { ConnectBTCAccount, ConnectETHAccount } from "~/static/icons" +} from "#/hooks" +import { ConnectBTCAccount, ConnectETHAccount } from "#/static/icons" import MissingAccount from "./MissingAccount" export default function SupportWrapper({ diff --git a/dapp/src/components/Overview/PositionDetails.tsx b/dapp/src/components/Overview/PositionDetails.tsx index 907be66f1..0555c3ddf 100644 --- a/dapp/src/components/Overview/PositionDetails.tsx +++ b/dapp/src/components/Overview/PositionDetails.tsx @@ -10,9 +10,9 @@ import { CardProps, useBoolean, } from "@chakra-ui/react" -import { CurrencyBalanceWithConversion } from "~/components/shared/CurrencyBalanceWithConversion" -import { TextMd } from "~/components/shared/Typography" -import { Info } from "~/static/icons" +import { CurrencyBalanceWithConversion } from "#/components/shared/CurrencyBalanceWithConversion" +import { TextMd } from "#/components/shared/Typography" +import { Info } from "#/static/icons" import StakingModal from "../Modals/Staking" export default function PositionDetails(props: CardProps) { diff --git a/dapp/src/components/Overview/Statistics.tsx b/dapp/src/components/Overview/Statistics.tsx index e8a5df0c5..b8681ac3e 100644 --- a/dapp/src/components/Overview/Statistics.tsx +++ b/dapp/src/components/Overview/Statistics.tsx @@ -1,6 +1,6 @@ import React from "react" import { CardBody, Card, CardProps } from "@chakra-ui/react" -import { TextMd } from "~/components/shared/Typography" +import { TextMd } from "#/components/shared/Typography" export default function Statistics(props: CardProps) { return ( diff --git a/dapp/src/components/Overview/TransactionHistory.tsx b/dapp/src/components/Overview/TransactionHistory.tsx index 557556bd4..a151804df 100644 --- a/dapp/src/components/Overview/TransactionHistory.tsx +++ b/dapp/src/components/Overview/TransactionHistory.tsx @@ -1,6 +1,6 @@ import React from "react" import { CardBody, Card, CardProps } from "@chakra-ui/react" -import { TextMd } from "~/components/shared/Typography" +import { TextMd } from "#/components/shared/Typography" export default function TransactionHistory(props: CardProps) { return ( diff --git a/dapp/src/components/Overview/index.tsx b/dapp/src/components/Overview/index.tsx index 1bee1a175..d67bed7a8 100644 --- a/dapp/src/components/Overview/index.tsx +++ b/dapp/src/components/Overview/index.tsx @@ -1,9 +1,9 @@ import React from "react" import { Button, Flex, Grid, HStack, Icon, Switch } from "@chakra-ui/react" -import { useDocsDrawer } from "~/hooks" -import { TextSm } from "~/components/shared/Typography" -import { ArrowUpRight } from "~/static/icons" -import { USD } from "~/constants" +import { useDocsDrawer } from "#/hooks" +import { TextSm } from "#/components/shared/Typography" +import { ArrowUpRight } from "#/static/icons" +import { USD } from "#/constants" import PositionDetails from "./PositionDetails" import Statistics from "./Statistics" import TransactionHistory from "./TransactionHistory" diff --git a/dapp/src/components/Sidebar/index.tsx b/dapp/src/components/Sidebar/index.tsx index 2217cfe7c..faebd8be0 100644 --- a/dapp/src/components/Sidebar/index.tsx +++ b/dapp/src/components/Sidebar/index.tsx @@ -1,6 +1,6 @@ import React from "react" import { Box, Button, useMultiStyleConfig } from "@chakra-ui/react" -import { useDocsDrawer, useSidebar } from "~/hooks" +import { useDocsDrawer, useSidebar } from "#/hooks" export default function Sidebar() { const { isOpen } = useSidebar() diff --git a/dapp/src/components/shared/Alert/index.tsx b/dapp/src/components/shared/Alert/index.tsx index cb3d94fd1..687e0599b 100644 --- a/dapp/src/components/shared/Alert/index.tsx +++ b/dapp/src/components/shared/Alert/index.tsx @@ -7,7 +7,7 @@ import { Icon, useMultiStyleConfig, } from "@chakra-ui/react" -import { AlertInfo, ArrowUpRight } from "~/static/icons" +import { AlertInfo, ArrowUpRight } from "#/static/icons" const ICONS = { info: AlertInfo, diff --git a/dapp/src/components/shared/CurrencyBalance/index.tsx b/dapp/src/components/shared/CurrencyBalance/index.tsx index 65991979a..fdf136420 100644 --- a/dapp/src/components/shared/CurrencyBalance/index.tsx +++ b/dapp/src/components/shared/CurrencyBalance/index.tsx @@ -4,8 +4,8 @@ import { formatTokenAmount, getCurrencyByType, numberToLocaleString, -} from "~/utils" -import { CurrencyType } from "~/types" +} from "#/utils" +import { CurrencyType } from "#/types" export type CurrencyBalanceProps = { currency: CurrencyType diff --git a/dapp/src/components/shared/ModalBase/index.tsx b/dapp/src/components/shared/ModalBase/index.tsx index 034527614..a2c31cddd 100644 --- a/dapp/src/components/shared/ModalBase/index.tsx +++ b/dapp/src/components/shared/ModalBase/index.tsx @@ -5,12 +5,12 @@ import { ModalContent, ModalOverlay, } from "@chakra-ui/react" -import { useSidebar } from "~/hooks" +import { useSidebar } from "#/hooks" import { ModalFlowContext, ModalFlowContextValue, TransactionContextProvider, -} from "~/contexts" +} from "#/contexts" import SupportWrapper from "../../Modals/Support" export default function ModalBase({ diff --git a/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx b/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx index 3f07bfe45..18e4bd712 100644 --- a/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx +++ b/dapp/src/components/shared/TokenAmountForm/TokenAmountFormBase.tsx @@ -1,6 +1,6 @@ import React from "react" import { FormikProps, useField } from "formik" -import { CurrencyType } from "~/types" +import { CurrencyType } from "#/types" import { Form, FormTokenBalanceInput } from "../Form" const TOKEN_AMOUNT_FIELD_NAME = "amount" diff --git a/dapp/src/components/shared/TokenAmountForm/index.tsx b/dapp/src/components/shared/TokenAmountForm/index.tsx index 50a792af8..c4b8dfec7 100644 --- a/dapp/src/components/shared/TokenAmountForm/index.tsx +++ b/dapp/src/components/shared/TokenAmountForm/index.tsx @@ -1,5 +1,5 @@ import { FormikErrors, withFormik } from "formik" -import { getErrorsObj, validateTokenAmount } from "~/utils" +import { getErrorsObj, validateTokenAmount } from "#/utils" import TokenAmountFormBase, { TokenAmountFormBaseProps, TokenAmountFormValues, diff --git a/dapp/src/components/shared/TokenBalanceInput/index.tsx b/dapp/src/components/shared/TokenBalanceInput/index.tsx index 289451c11..68975da92 100644 --- a/dapp/src/components/shared/TokenBalanceInput/index.tsx +++ b/dapp/src/components/shared/TokenBalanceInput/index.tsx @@ -16,9 +16,9 @@ import { fixedPointNumberToString, getCurrencyByType, userAmountToBigInt, -} from "~/utils" -import { AlertInfo } from "~/static/icons" -import { CurrencyType } from "~/types" +} from "#/utils" +import { AlertInfo } from "#/static/icons" +import { CurrencyType } from "#/types" import NumberFormatInput, { NumberFormatInputValues, } from "../NumberFormatInput" diff --git a/dapp/src/constants/currency.ts b/dapp/src/constants/currency.ts index 75b1c572b..6f747bb1a 100644 --- a/dapp/src/constants/currency.ts +++ b/dapp/src/constants/currency.ts @@ -1,4 +1,4 @@ -import { Currency, CurrencyType } from "~/types" +import { Currency, CurrencyType } from "#/types" export const BITCOIN: Currency = { name: "Bitcoin", diff --git a/dapp/src/contexts/TransactionContext.tsx b/dapp/src/contexts/TransactionContext.tsx index 47bb3b801..3064bd530 100644 --- a/dapp/src/contexts/TransactionContext.tsx +++ b/dapp/src/contexts/TransactionContext.tsx @@ -1,5 +1,5 @@ import React, { createContext, useMemo, useState } from "react" -import { TokenAmount } from "~/types" +import { TokenAmount } from "#/types" type TransactionContextValue = { tokenAmount?: TokenAmount diff --git a/dapp/src/hooks/useDepositBTCTransaction.ts b/dapp/src/hooks/useDepositBTCTransaction.ts index 861e55870..0bef0c4be 100644 --- a/dapp/src/hooks/useDepositBTCTransaction.ts +++ b/dapp/src/hooks/useDepositBTCTransaction.ts @@ -1,5 +1,5 @@ import { useCallback } from "react" -import { OnSuccessCallback } from "~/types" +import { OnSuccessCallback } from "#/types" export function useDepositBTCTransaction(onSuccess?: OnSuccessCallback) { // TODO: sending transactions using the SDK diff --git a/dapp/src/hooks/useDocsDrawer.ts b/dapp/src/hooks/useDocsDrawer.ts index e560afa83..3536dba2a 100644 --- a/dapp/src/hooks/useDocsDrawer.ts +++ b/dapp/src/hooks/useDocsDrawer.ts @@ -1,5 +1,5 @@ import { useContext } from "react" -import { DocsDrawerContext } from "~/contexts" +import { DocsDrawerContext } from "#/contexts" export function useDocsDrawer() { const context = useContext(DocsDrawerContext) diff --git a/dapp/src/hooks/useModalFlowContext.ts b/dapp/src/hooks/useModalFlowContext.ts index fafb6a565..fda6eb681 100644 --- a/dapp/src/hooks/useModalFlowContext.ts +++ b/dapp/src/hooks/useModalFlowContext.ts @@ -1,5 +1,5 @@ import { useContext } from "react" -import { ModalFlowContext } from "~/contexts" +import { ModalFlowContext } from "#/contexts" export function useModalFlowContext() { const context = useContext(ModalFlowContext) diff --git a/dapp/src/hooks/useRequestBitcoinAccount.ts b/dapp/src/hooks/useRequestBitcoinAccount.ts index d780eb016..051467dcf 100644 --- a/dapp/src/hooks/useRequestBitcoinAccount.ts +++ b/dapp/src/hooks/useRequestBitcoinAccount.ts @@ -1,8 +1,8 @@ import { useRequestAccount } from "@ledgerhq/wallet-api-client-react" import { useCallback, useContext, useEffect } from "react" -import { WalletContext } from "~/contexts" -import { UseRequestAccountReturn } from "~/types" -import { CURRENCY_ID_BITCOIN } from "~/constants" +import { WalletContext } from "#/contexts" +import { UseRequestAccountReturn } from "#/types" +import { CURRENCY_ID_BITCOIN } from "#/constants" export function useRequestBitcoinAccount(): UseRequestAccountReturn { const { setBtcAccount } = useContext(WalletContext) diff --git a/dapp/src/hooks/useRequestEthereumAccount.ts b/dapp/src/hooks/useRequestEthereumAccount.ts index d1dd87ad7..fcf18c6ff 100644 --- a/dapp/src/hooks/useRequestEthereumAccount.ts +++ b/dapp/src/hooks/useRequestEthereumAccount.ts @@ -1,8 +1,8 @@ import { useRequestAccount } from "@ledgerhq/wallet-api-client-react" import { useCallback, useContext, useEffect } from "react" -import { WalletContext } from "~/contexts" -import { UseRequestAccountReturn } from "~/types" -import { CURRENCY_ID_ETHEREUM } from "~/constants" +import { WalletContext } from "#/contexts" +import { UseRequestAccountReturn } from "#/types" +import { CURRENCY_ID_ETHEREUM } from "#/constants" export function useRequestEthereumAccount(): UseRequestAccountReturn { const { setEthAccount } = useContext(WalletContext) diff --git a/dapp/src/hooks/useSidebar.ts b/dapp/src/hooks/useSidebar.ts index 714330b48..944364076 100644 --- a/dapp/src/hooks/useSidebar.ts +++ b/dapp/src/hooks/useSidebar.ts @@ -1,5 +1,5 @@ import { useContext } from "react" -import { SidebarContext } from "~/contexts" +import { SidebarContext } from "#/contexts" export function useSidebar() { const context = useContext(SidebarContext) diff --git a/dapp/src/hooks/useSignMessage.ts b/dapp/src/hooks/useSignMessage.ts index 21ef804b0..cd38d1001 100644 --- a/dapp/src/hooks/useSignMessage.ts +++ b/dapp/src/hooks/useSignMessage.ts @@ -1,6 +1,6 @@ import { useSignMessage as useSignMessageLedgerLive } from "@ledgerhq/wallet-api-client-react" import { useCallback, useEffect } from "react" -import { OnSuccessCallback } from "~/types" +import { OnSuccessCallback } from "#/types" import { useWalletContext } from "./useWalletContext" const SIGN_MESSAGE = "Test message" diff --git a/dapp/src/hooks/useTransactionContext.ts b/dapp/src/hooks/useTransactionContext.ts index 85b663a51..41a8a8359 100644 --- a/dapp/src/hooks/useTransactionContext.ts +++ b/dapp/src/hooks/useTransactionContext.ts @@ -1,5 +1,5 @@ import { useContext } from "react" -import { TransactionContext } from "~/contexts" +import { TransactionContext } from "#/contexts" export function useTransactionContext() { const context = useContext(TransactionContext) diff --git a/dapp/src/hooks/useWalletContext.ts b/dapp/src/hooks/useWalletContext.ts index c786a76dd..afca84aff 100644 --- a/dapp/src/hooks/useWalletContext.ts +++ b/dapp/src/hooks/useWalletContext.ts @@ -1,5 +1,5 @@ import { useContext } from "react" -import { WalletContext } from "~/contexts" +import { WalletContext } from "#/contexts" export function useWalletContext() { const context = useContext(WalletContext) diff --git a/dapp/src/utils/currency.ts b/dapp/src/utils/currency.ts index 99d93710a..4d8b02a78 100644 --- a/dapp/src/utils/currency.ts +++ b/dapp/src/utils/currency.ts @@ -1,5 +1,5 @@ -import { Currency, CurrencyType } from "~/types" -import { CURRENCIES_BY_TYPE } from "~/constants" +import { Currency, CurrencyType } from "#/types" +import { CURRENCIES_BY_TYPE } from "#/constants" export const getCurrencyByType = (currency: CurrencyType): Currency => CURRENCIES_BY_TYPE[currency] diff --git a/dapp/src/utils/forms.ts b/dapp/src/utils/forms.ts index a2fc7b8c4..97872a8f4 100644 --- a/dapp/src/utils/forms.ts +++ b/dapp/src/utils/forms.ts @@ -1,4 +1,4 @@ -import { CurrencyType } from "~/types" +import { CurrencyType } from "#/types" import { getCurrencyByType } from "./currency" import { formatTokenAmount } from "./numbers" diff --git a/dapp/tsconfig.json b/dapp/tsconfig.json index 0d679c735..03b8b2fe1 100644 --- a/dapp/tsconfig.json +++ b/dapp/tsconfig.json @@ -14,7 +14,7 @@ "strict": true, "baseUrl": ".", "paths": { - "~/*": ["./src/*"] + "#/*": ["./src/*"] } }, "references": [{ "path": "./tsconfig.node.json" }] diff --git a/dapp/vite.config.ts b/dapp/vite.config.ts index 71034c086..b60415bd0 100644 --- a/dapp/vite.config.ts +++ b/dapp/vite.config.ts @@ -7,7 +7,7 @@ import { resolve } from "path" export default defineConfig({ resolve: { alias: { - "~": resolve(__dirname, "./src"), + "#": resolve(__dirname, "./src"), }, }, plugins: [nodePolyfills(), react()], From 2e2737be8d49fb2f108115cf08e7fabbf02e7133 Mon Sep 17 00:00:00 2001 From: ioay Date: Thu, 11 Jan 2024 16:25:28 +0100 Subject: [PATCH 159/170] Removed vite-tsconfig-paths package --- dapp/package.json | 3 +-- pnpm-lock.yaml | 37 ------------------------------------- 2 files changed, 1 insertion(+), 39 deletions(-) diff --git a/dapp/package.json b/dapp/package.json index 9abe245b2..98a2673bf 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -39,7 +39,6 @@ "prettier": "^3.1.0", "typescript": "^5.3.2", "vite": "^5.0.2", - "vite-plugin-node-polyfills": "^0.19.0", - "vite-tsconfig-paths": "^4.2.3" + "vite-plugin-node-polyfills": "^0.19.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 89f1905c3..ef9c6254c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -184,9 +184,6 @@ importers: vite-plugin-node-polyfills: specifier: ^0.19.0 version: 0.19.0(vite@5.0.2) - vite-tsconfig-paths: - specifier: ^4.2.3 - version: 4.2.3(typescript@5.3.2)(vite@5.0.2) sdk: devDependencies: @@ -10545,10 +10542,6 @@ packages: merge2: 1.4.1 slash: 3.0.0 - /globrex@0.1.2: - resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} - dev: true - /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: @@ -15134,19 +15127,6 @@ packages: resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==} dev: true - /tsconfck@2.1.2(typescript@5.3.2): - resolution: {integrity: sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==} - engines: {node: ^14.13.1 || ^16 || >=18} - hasBin: true - peerDependencies: - typescript: ^4.3.5 || ^5.0.0 - peerDependenciesMeta: - typescript: - optional: true - dependencies: - typescript: 5.3.2 - dev: true - /tsconfig-paths@3.14.2: resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} dependencies: @@ -15572,23 +15552,6 @@ packages: - rollup dev: true - /vite-tsconfig-paths@4.2.3(typescript@5.3.2)(vite@5.0.2): - resolution: {integrity: sha512-xVsA2xe6QSlzBujtWF8q2NYexh7PAUYfzJ4C8Axpe/7d2pcERYxuxGgph9F4f0iQO36g5tyGq6eBUYIssdUrVw==} - peerDependencies: - vite: '*' - peerDependenciesMeta: - vite: - optional: true - dependencies: - debug: 4.3.4 - globrex: 0.1.2 - tsconfck: 2.1.2(typescript@5.3.2) - vite: 5.0.2 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - /vite@5.0.2: resolution: {integrity: sha512-6CCq1CAJCNM1ya2ZZA7+jS2KgnhbzvxakmlIjN24cF/PXhRMzpM/z8QgsVJA/Dm5fWUWnVEsmtBoMhmerPxT0g==} engines: {node: ^18.0.0 || >=20.0.0} From 23ca229f99d450c5829466a8ad662137c3c3c37b Mon Sep 17 00:00:00 2001 From: ioay Date: Thu, 11 Jan 2024 17:06:49 +0100 Subject: [PATCH 160/170] Update path in ModalBase component --- dapp/src/components/shared/ModalBase/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dapp/src/components/shared/ModalBase/index.tsx b/dapp/src/components/shared/ModalBase/index.tsx index a2c31cddd..6b253e89d 100644 --- a/dapp/src/components/shared/ModalBase/index.tsx +++ b/dapp/src/components/shared/ModalBase/index.tsx @@ -11,7 +11,7 @@ import { ModalFlowContextValue, TransactionContextProvider, } from "#/contexts" -import SupportWrapper from "../../Modals/Support" +import SupportWrapper from "#/components/Modals/Support" export default function ModalBase({ isOpen, From bc983bed7c6ed9f17d9f666074d7912069926414 Mon Sep 17 00:00:00 2001 From: ioay Date: Thu, 11 Jan 2024 19:44:12 +0100 Subject: [PATCH 161/170] Removal of global exclusion rules, added temporary overrides rules for existing files --- dapp/.eslintrc | 51 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/dapp/.eslintrc b/dapp/.eslintrc index 63815d434..de11435fb 100644 --- a/dapp/.eslintrc +++ b/dapp/.eslintrc @@ -16,14 +16,45 @@ { "allowRequiredDefaults": true } ], "react/require-default-props": [0], - // Regarding the fact we are using now: @thesis-co/eslint-config": "github:thesis/eslint-config#7b9bc8c" - // Promise-returning function provided to attribute where a void return was expected. - // Avoid referencing unbound methods which may cause unintentional scoping of `this`, used in theme files. - "@typescript-eslint/no-misused-promises": "off", - "@typescript-eslint/unbound-method": "off", - // Computed name [status] resolves to any value (related to external chakra-ui package) - "@typescript-eslint/no-unsafe-member-access": "off", - // Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator - "@typescript-eslint/no-floating-promises": "off" - } + }, + // FIXME: + // This is temporary solution after changes of the eslint-config version: @thesis-co/eslint-config: "github:thesis/eslint-config#7b9bc8c" + // Overrides rules should be fixed file by file. + "overrides": [ + { + "files": [ + "src/components/Header/ConnectWallet.tsx", + "src/components/Modals/Support/MissingAccount.tsx", + "src/components/Modals/Staking/SignMessage.tsx", + "src/hooks/useDepositBTCTransaction.ts" + ], + "rules": { + "@typescript-eslint/no-misused-promises": "off" + } + }, + { + "files": [ + "src/hooks/useSignMessage.ts" + ], + "rules": { + "@typescript-eslint/no-floating-promises": "off" + } + }, + { + "files": [ + "src/theme/*" + ], + "rules": { + "@typescript-eslint/unbound-method": "off" + } + }, + { + "files": [ + "src/theme/Alert.ts" + ], + "rules": { + "@typescript-eslint/no-unsafe-member-access": "off" + } + } + ] } From f903ed1905df488ce58431435ec03919eddb0fe0 Mon Sep 17 00:00:00 2001 From: ioay Date: Thu, 11 Jan 2024 19:59:12 +0100 Subject: [PATCH 162/170] Eslint rules extension after last changes on main branch --- dapp/.eslintrc | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/dapp/.eslintrc b/dapp/.eslintrc index 67b8362d7..35437e4ed 100644 --- a/dapp/.eslintrc +++ b/dapp/.eslintrc @@ -26,7 +26,8 @@ "src/components/Header/ConnectWallet.tsx", "src/components/Modals/Support/MissingAccount.tsx", "src/components/Modals/Staking/SignMessage.tsx", - "src/hooks/useDepositBTCTransaction.ts" + "src/hooks/useDepositBTCTransaction.ts", + "src/components/shared/Form/FormTokenBalanceInput.tsx" ], "rules": { "@typescript-eslint/no-misused-promises": "off" @@ -55,6 +56,22 @@ "rules": { "@typescript-eslint/no-unsafe-member-access": "off" } + }, + { + "files": [ + "src/components/shared/Form/FormTokenBalanceInput.tsx" + ], + "rules": { + "@typescript-eslint/no-unsafe-assignment": "off" + } + }, + { + "files": [ + "src/components/shared/TokenAmountForm/index.tsx" + ], + "rules": { + "@typescript-eslint/require-await": "off" + } } ], "settings": { From 81aa38eca21d9c598c8df4ce17753d05278aa12e Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Mon, 15 Jan 2024 16:35:04 +0100 Subject: [PATCH 163/170] Add unit tests for finalizeStake function --- core/test/TbtcDepositor.test.ts | 331 +++++++++++++++++++++++++++++++- 1 file changed, 326 insertions(+), 5 deletions(-) diff --git a/core/test/TbtcDepositor.test.ts b/core/test/TbtcDepositor.test.ts index 674046552..349d4676a 100644 --- a/core/test/TbtcDepositor.test.ts +++ b/core/test/TbtcDepositor.test.ts @@ -4,30 +4,64 @@ import { loadFixture } from "@nomicfoundation/hardhat-toolbox/network-helpers" import { expect } from "chai" import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers" import { ContractTransactionResponse, ZeroAddress } from "ethers" -import type { BridgeStub, TBTCVaultStub, TbtcDepositor } from "../typechain" +import type { + Acre, + BridgeStub, + TBTCVaultStub, + TbtcDepositor, + TestERC20, +} from "../typechain" import { deployment, getNamedSigner, getUnnamedSigner } from "./helpers" import { beforeAfterSnapshotWrapper } from "./helpers/snapshot" import { tbtcDepositData } from "./data/tbtc" import { lastBlockTime } from "./helpers/time" +import { to1ePrecision } from "./utils" async function fixture() { - const { tbtcDepositor, tbtcBridge, tbtcVault } = await deployment() + const { tbtcDepositor, tbtcBridge, tbtcVault, acre, tbtc } = + await deployment() - return { tbtcDepositor, tbtcBridge, tbtcVault } + return { tbtcDepositor, tbtcBridge, tbtcVault, acre, tbtc } } describe("TbtcDepositor", () => { + const defaultDepositTreasuryFeeDivisor = 2000 // 1/2000 = 0.05% = 0.0005 + const defaultDepositTxMaxFee = 1000 // 1000 satoshi = 0.00001 BTC + const defaultOptimisticFeeDivisor = 500 // 1/500 = 0.002 = 0.2% + const defaultDepositorFeeDivisor = 80 // 1/80 = 0.0125 = 1.25% + let tbtcDepositor: TbtcDepositor let tbtcBridge: BridgeStub let tbtcVault: TBTCVaultStub + let acre: Acre + let tbtc: TestERC20 let governance: HardhatEthersSigner let thirdParty: HardhatEthersSigner before(async () => { - ;({ tbtcDepositor, tbtcBridge, tbtcVault } = await loadFixture(fixture)) + ;({ tbtcDepositor, tbtcBridge, tbtcVault, acre, tbtc } = + await loadFixture(fixture)) ;({ governance } = await getNamedSigner()) ;[thirdParty] = await getUnnamedSigner() + + await acre.connect(governance).updateDepositParameters( + 10000000000000, // 0.00001 + await acre.maximumTotalAssets(), + ) + + await tbtcBridge + .connect(governance) + .setDepositTreasuryFeeDivisor(defaultDepositTreasuryFeeDivisor) + await tbtcBridge + .connect(governance) + .setDepositTxMaxFee(defaultDepositTxMaxFee) + await tbtcVault + .connect(governance) + .setOptimisticMintingFeeDivisor(defaultOptimisticFeeDivisor) + await tbtcDepositor + .connect(governance) + .updateDepositorFeeDivisor(defaultDepositorFeeDivisor) }) describe("initializeStake", () => { @@ -159,7 +193,294 @@ describe("TbtcDepositor", () => { }) }) - describe("finalizeStake", () => {}) + describe("finalizeStake", () => { + beforeAfterSnapshotWrapper() + + // Funding transaction amount: 10000 satoshi + // tBTC Deposit Treasury Fee: 0.05% = 10000 * 0.05% = 5 satoshi + // tBTC Deposit Transaction Max Fee: 1000 satoshi + // tBTC Optimistic Minting Fee: 0.2% = 10000 * 0.2% = 20 satoshi + // Depositor Fee: 1.25% = 10000 * 1.25% = 125 satoshi + + describe("when stake request has not been initialized", () => { + it("should revert", async () => { + await expect( + tbtcDepositor + .connect(thirdParty) + .finalizeStake(tbtcDepositData.depositKey), + ).to.be.revertedWithCustomError( + tbtcDepositor, + "StakeRequestNotInitialized", + ) + }) + }) + + describe("when stake request has been initialized", () => { + function initializeStake() { + return tbtcDepositor + .connect(thirdParty) + .initializeStake( + tbtcDepositData.fundingTxInfo, + tbtcDepositData.reveal, + tbtcDepositData.receiver, + tbtcDepositData.referral, + ) + } + + describe("when stake request has not been finalized", () => { + function testFinalizeStake( + expectedAssetsAmount: bigint, + expectedReceivedSharesAmount = expectedAssetsAmount, + ) { + let tx: ContractTransactionResponse + + before(async () => { + tx = await tbtcDepositor + .connect(thirdParty) + .finalizeStake(tbtcDepositData.depositKey) + }) + + it("should emit StakeFinalized event", async () => { + await expect(tx) + .to.emit(tbtcDepositor, "StakeFinalized") + .withArgs(tbtcDepositData.depositKey, thirdParty.address) + }) + + it("should emit StakeReferral event", async () => { + await expect(tx) + .to.emit(acre, "StakeReferral") + .withArgs(tbtcDepositData.referral, expectedAssetsAmount) + }) + + it("should emit Deposit event", async () => { + await expect(tx) + .to.emit(acre, "Deposit") + .withArgs( + await tbtcDepositor.getAddress(), + tbtcDepositData.receiver, + expectedAssetsAmount, + expectedReceivedSharesAmount, + ) + }) + + it("should stake in Acre contract", async () => { + await expect( + tx, + "invalid minted stBTC amount", + ).to.changeTokenBalances( + acre, + [tbtcDepositData.receiver], + [expectedReceivedSharesAmount], + ) + + await expect( + tx, + "invalid staked tBTC amount", + ).to.changeTokenBalances(tbtc, [acre], [expectedAssetsAmount]) + }) + } + + describe("when revealed depositor doesn't match tbtc depositor contract", () => { + beforeAfterSnapshotWrapper() + + before(async () => { + await initializeStake() + + await tbtcBridge.setDepositor( + tbtcDepositData.depositKey, + thirdParty.address, + ) + }) + + it("should revert", async () => { + await expect( + tbtcDepositor + .connect(thirdParty) + .finalizeStake(tbtcDepositData.depositKey), + ).to.be.revertedWithCustomError( + tbtcDepositor, + "UnexpectedDepositor", + ) + }) + }) + + describe("when revealed depositor matches tbtc depositor contract", () => { + beforeAfterSnapshotWrapper() + + describe("when minting request was finalized by optimistic minting", () => { + describe("when optimistic minting fee divisor is zero", () => { + beforeAfterSnapshotWrapper() + + const expectedAssetsAmount = to1ePrecision(8870, 10) // 8870 satoshi + + before(async () => { + await tbtcVault.setOptimisticMintingFeeDivisor(0) + + await initializeStake() + + // Simulate deposit request finalization via optimistic minting. + await tbtcVault.finalizeOptimisticMinting( + tbtcDepositData.depositKey, + ) + }) + + testFinalizeStake(expectedAssetsAmount) + }) + + describe("when optimistic minting fee divisor is not zero", () => { + beforeAfterSnapshotWrapper() + + before(async () => { + await tbtcVault.setOptimisticMintingFeeDivisor( + defaultOptimisticFeeDivisor, + ) + }) + + describe("when current optimistic minting fee is greater than it was on stake initialization", () => { + beforeAfterSnapshotWrapper() + + const expectedAssetsAmount = to1ePrecision(8830, 10) // 8830 satoshi + + before(async () => { + await initializeStake() + + await tbtcVault.setOptimisticMintingFeeDivisor( + defaultOptimisticFeeDivisor / 2, + ) // 1/250 = 0.004 = 0.4% + + // Simulate deposit request finalization via optimistic minting. + await tbtcVault.finalizeOptimisticMinting( + tbtcDepositData.depositKey, + ) + }) + + testFinalizeStake(expectedAssetsAmount) + }) + + describe("when current optimistic minting fee is lower than it was on stake initialization", () => { + beforeAfterSnapshotWrapper() + + // Since the current Optimistic Fee (10 satoshi) is lower than + // the one calculated on request initialization (20 satoshi) the + // higher value is deducted from the funding transaction amount. + const expectedAssetsAmount = to1ePrecision(8850, 10) // 8850 satoshi + + before(async () => { + await initializeStake() + + await tbtcVault.setOptimisticMintingFeeDivisor( + defaultOptimisticFeeDivisor * 2, + ) // 1/1000 = 0.001 = 0.1% + + // Simulate deposit request finalization via optimistic minting. + await tbtcVault.finalizeOptimisticMinting( + tbtcDepositData.depositKey, + ) + }) + + testFinalizeStake(expectedAssetsAmount) + }) + }) + }) + + describe("when minting request was not finalized by optimistic minting", () => { + beforeAfterSnapshotWrapper() + + before(async () => { + await initializeStake() + }) + + describe("when minting request has not been swept", () => { + beforeAfterSnapshotWrapper() + + it("should revert", async () => { + await expect( + tbtcDepositor + .connect(thirdParty) + .finalizeStake(tbtcDepositData.depositKey), + ).to.be.revertedWithCustomError( + tbtcDepositor, + "TbtcDepositNotCompleted", + ) + }) + }) + + describe("when minting request was swept", () => { + describe("when depositor fee divisor is zero", () => { + beforeAfterSnapshotWrapper() + + const expectedAssetsAmount = to1ePrecision(8995, 10) // 8995 satoshi + + before(async () => { + await tbtcDepositor + .connect(governance) + .updateDepositorFeeDivisor(0) + + // Simulate deposit request finalization via sweeping. + await tbtcBridge.sweep( + tbtcDepositData.fundingTxHash, + tbtcDepositData.reveal.fundingOutputIndex, + ) + }) + + testFinalizeStake(expectedAssetsAmount) + }) + + describe("when depositor fee divisor is not zero", () => { + beforeAfterSnapshotWrapper() + + const expectedAssetsAmount = to1ePrecision(8870, 10) // 8870 satoshi + + before(async () => { + await tbtcDepositor + .connect(governance) + .updateDepositorFeeDivisor(defaultDepositorFeeDivisor) + + // Simulate deposit request finalization via sweeping. + await tbtcBridge.sweep( + tbtcDepositData.fundingTxHash, + tbtcDepositData.reveal.fundingOutputIndex, + ) + }) + + testFinalizeStake(expectedAssetsAmount) + }) + }) + }) + }) + }) + + describe("when stake request has been finalized", () => { + beforeAfterSnapshotWrapper() + + before(async () => { + await initializeStake() + + // Simulate deposit request finalization via sweeping. + await tbtcBridge.sweep( + tbtcDepositData.fundingTxHash, + tbtcDepositData.reveal.fundingOutputIndex, + ) + + // Finalize stake request. + await tbtcDepositor + .connect(thirdParty) + .finalizeStake(tbtcDepositData.depositKey) + }) + + it("should revert", async () => { + await expect( + tbtcDepositor + .connect(thirdParty) + .finalizeStake(tbtcDepositData.depositKey), + ).to.be.revertedWithCustomError( + tbtcDepositor, + "StakeRequestAlreadyFinalized", + ) + }) + }) + }) + }) describe("updateDepositorFeeDivisor", () => { beforeAfterSnapshotWrapper() From b6f52f40f0e30a2cc63ab837e8ea74bc606b0cd3 Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Mon, 15 Jan 2024 16:35:21 +0100 Subject: [PATCH 164/170] Add clarification for depositor address check --- core/contracts/tbtc/TbtcDepositor.sol | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/contracts/tbtc/TbtcDepositor.sol b/core/contracts/tbtc/TbtcDepositor.sol index 59cdc8a22..86e4211b5 100644 --- a/core/contracts/tbtc/TbtcDepositor.sol +++ b/core/contracts/tbtc/TbtcDepositor.sol @@ -263,6 +263,11 @@ contract TbtcDepositor is Ownable { // Check if Depositor revealed to the tBTC Bridge contract matches the // current contract address. + // This is very unlikely scenario, that would require unexpected change or + // bug in tBTC Bridge contract, as the depositor is set automatically + // to the reveal deposit message sender, which will be this contract. + // Anyway we check if the depositor that got the tBTC tokens minted + // is this contract, before we stake them. if (bridgeDepositRequest.depositor != address(this)) revert UnexpectedDepositor(bridgeDepositRequest.depositor); From b918ee86197945372bd2b0b654619192547197da Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Mon, 15 Jan 2024 16:35:46 +0100 Subject: [PATCH 165/170] Use Math.min for OM fee divisors comparison We want to take the bigger fee, so we need to use the smaller divisor. --- core/contracts/tbtc/TbtcDepositor.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/contracts/tbtc/TbtcDepositor.sol b/core/contracts/tbtc/TbtcDepositor.sol index 86e4211b5..a5566590a 100644 --- a/core/contracts/tbtc/TbtcDepositor.sol +++ b/core/contracts/tbtc/TbtcDepositor.sol @@ -285,8 +285,8 @@ contract TbtcDepositor is Ownable { // call, and not stored in the contract. // There is a possibility the fee has changed since the snapshot of // the `tbtcOptimisticMintingFeeDivisor`, to cover this scenario - // in fee computation we use the bigger of these. - uint256 optimisticMintingFeeDivisor = Math.max( + // we want to assume the bigger fee, so we use the smaller divisor. + uint256 optimisticMintingFeeDivisor = Math.min( request.tbtcOptimisticMintingFeeDivisor, tbtcVault.optimisticMintingFeeDivisor() ); From 0909d828f2b63f583c50e9505bef612cc1011614 Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Mon, 15 Jan 2024 16:36:38 +0100 Subject: [PATCH 166/170] Add name and symbol to TestERC20 constructor We want to use the contract in different tests, so we want to have the flexibility to use different names. --- core/contracts/test/TestERC20.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/contracts/test/TestERC20.sol b/core/contracts/test/TestERC20.sol index 44e5e14dc..c6b25896d 100644 --- a/core/contracts/test/TestERC20.sol +++ b/core/contracts/test/TestERC20.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.21; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract TestERC20 is ERC20 { - constructor() ERC20("Test Token", "TEST") {} + constructor(string memory name, string memory symbol) ERC20(name, symbol) {} function mint(address account, uint256 value) external { _mint(account, value); From 4ca73bf17ef32ef8df985488e941c4485d70e017 Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Mon, 15 Jan 2024 16:38:01 +0100 Subject: [PATCH 167/170] Remove estimateFee function The calculations are not required on-chain, so we remove the function. The calculations should be performed off-chain by SDK. --- core/contracts/tbtc/TbtcDepositor.sol | 55 --------------------------- 1 file changed, 55 deletions(-) diff --git a/core/contracts/tbtc/TbtcDepositor.sol b/core/contracts/tbtc/TbtcDepositor.sol index a5566590a..19b5a2375 100644 --- a/core/contracts/tbtc/TbtcDepositor.sol +++ b/core/contracts/tbtc/TbtcDepositor.sol @@ -336,61 +336,6 @@ contract TbtcDepositor is Ownable { acre.stake(amountToStakeTbtc, receiver, referral); } - /// @notice Estimate and breakdown fees taken for `amount` of stake. - /// @dev It doesn't validate the amount against minimum and maximum limits - /// for tBTC minting and Acre depositing processes. - /// @param amount Amount of Bitcoin the user wants to stake. - /// @return maxTbtcMintingFee Maximum tBTC protocol minting fees for the given - /// amount. - /// @return tbtcDepositorFee TbtcDepositor fee for the given amount. - /// @return acreDepositFee Acre deposit fee for the given amount. - function estimateFees( - uint256 amount - ) - external - view - returns ( - uint256 maxTbtcMintingFee, - uint256 tbtcDepositorFee, - uint256 acreDepositFee - ) - { - ( - , - uint64 tbtcDepositTreasuryFeeDivisor, - uint64 tbtcDepositTxMaxFee, - - ) = bridge.depositParameters(); - - // Calculate Treasury fee. - uint256 tbtcTreasuryFee = tbtcDepositTreasuryFeeDivisor > 0 - ? amount / tbtcDepositTreasuryFeeDivisor - : 0; - - // Calculate Optimistic Minting fee. - uint32 tbtcOptimisticMintingFeeDivisor = tbtcVault - .optimisticMintingFeeDivisor(); - uint256 optimisticMintingFee = tbtcOptimisticMintingFeeDivisor > 0 - ? (amount / tbtcOptimisticMintingFeeDivisor) - : 0; - - // Total maximum tBTC minting fees. - maxTbtcMintingFee = - tbtcTreasuryFee + - tbtcDepositTxMaxFee + - optimisticMintingFee; - - // Calculate TbtcDepositor fee. - tbtcDepositorFee = depositorFeeDivisor > 0 - ? amount / depositorFeeDivisor - : 0; - - // Calculate Acre deposit fee. - // TODO: Make sure the calculation takes into account the Acre contract - // deposit fee charged by `Acre.deposit` function once it is implemented. - acreDepositFee = 0; - } - /// @notice Updates the depositor fee divisor. /// @param newDepositorFeeDivisor New depositor fee divisor value. function updateDepositorFeeDivisor( From 89d6df3b45a5303c5997f0f9cc30dce7d62c9b85 Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Mon, 15 Jan 2024 16:40:07 +0100 Subject: [PATCH 168/170] Add tBTC Bridge and tBTC Vault contracts stubs The contracts are used by tBTC Depositor contract for integration. The logic in stubs follows the actual code from the tbtc-v2 repository. --- core/contracts/test/BridgeStub.sol | 140 ++++++++++++++++++++++++++ core/contracts/test/TBTCVaultStub.sol | 56 +++++++++++ 2 files changed, 196 insertions(+) create mode 100644 core/contracts/test/BridgeStub.sol create mode 100644 core/contracts/test/TBTCVaultStub.sol diff --git a/core/contracts/test/BridgeStub.sol b/core/contracts/test/BridgeStub.sol new file mode 100644 index 000000000..f52390ad3 --- /dev/null +++ b/core/contracts/test/BridgeStub.sol @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-3.0-only +pragma solidity ^0.8.21; + +import {BTCUtils} from "@keep-network/bitcoin-spv-sol/contracts/BTCUtils.sol"; +import {IBridge} from "../external/tbtc/IBridge.sol"; +import {TestERC20} from "./TestERC20.sol"; + +contract BridgeStub is IBridge { + using BTCUtils for bytes; + + TestERC20 public tbtc; + + /// @notice Multiplier to convert satoshi to TBTC token units. + uint256 public constant SATOSHI_MULTIPLIER = 10 ** 10; + + // The values set here are tweaked for test purposes. These are not + // the exact values used in the Bridge contract on mainnet. + // See: https://github.com/keep-network/tbtc-v2/blob/103411a595c33895ff6bff8457383a69eca4963c/solidity/test/bridge/Bridge.Deposit.test.ts#L70-L77 + uint64 public depositDustThreshold = 10000; // 10000 satoshi = 0.0001 BTC + uint64 public depositTreasuryFeeDivisor = 2000; // 1/2000 == 5bps == 0.05% == 0.0005 + uint64 public depositTxMaxFee = 1000; // 1000 satoshi = 0.00001 BTC + uint32 public depositRevealAheadPeriod = 15 days; + + mapping(uint256 => DepositRequest) depositsMap; + + constructor(TestERC20 _tbtc) { + tbtc = _tbtc; + } + + function revealDepositWithExtraData( + BitcoinTxInfo calldata fundingTx, + DepositRevealInfo calldata reveal, + bytes32 extraData + ) external { + bytes32 fundingTxHash = abi + .encodePacked( + fundingTx.version, + fundingTx.inputVector, + fundingTx.outputVector, + fundingTx.locktime + ) + .hash256View(); + + DepositRequest storage deposit = depositsMap[ + calculateDepositKey(fundingTxHash, reveal.fundingOutputIndex) + ]; + + require(deposit.revealedAt == 0, "Deposit already revealed"); + + bytes memory fundingOutput = fundingTx + .outputVector + .extractOutputAtIndex(reveal.fundingOutputIndex); + + uint64 fundingOutputAmount = fundingOutput.extractValue(); + + require( + fundingOutputAmount >= depositDustThreshold, + "Deposit amount too small" + ); + + deposit.amount = fundingOutputAmount; + deposit.depositor = msg.sender; + /* solhint-disable-next-line not-rely-on-time */ + deposit.revealedAt = uint32(block.timestamp); + deposit.vault = reveal.vault; + deposit.treasuryFee = depositTreasuryFeeDivisor > 0 + ? fundingOutputAmount / depositTreasuryFeeDivisor + : 0; + deposit.extraData = extraData; + } + + function deposits( + uint256 depositKey + ) external view returns (DepositRequest memory) { + return depositsMap[depositKey]; + } + + function sweep(bytes32 fundingTxHash, uint32 fundingOutputIndex) external { + DepositRequest storage deposit = depositsMap[ + calculateDepositKey(fundingTxHash, fundingOutputIndex) + ]; + + deposit.sweptAt = uint32(block.timestamp); + + (, , uint64 depositTxMaxFee, ) = depositParameters(); + // For test purposes as deposit tx fee we take value lower than the max + // possible value as this follows how Bridge may sweep the deposit + // with a fee lower than the max. + // Here we arbitrary choose the deposit tx fee to be at 80% of max deposit fee. + uint64 depositTxFee = (depositTxMaxFee * 8) / 10; + + uint64 amountToMintSat = deposit.amount - + deposit.treasuryFee - + depositTxFee; + + tbtc.mint(deposit.depositor, amountToMintSat * SATOSHI_MULTIPLIER); + } + + function depositParameters() + public + view + returns (uint64, uint64, uint64, uint32) + { + return ( + depositDustThreshold, + depositTreasuryFeeDivisor, + depositTxMaxFee, + depositRevealAheadPeriod + ); + } + + function calculateDepositKey( + bytes32 fundingTxHash, + uint32 fundingOutputIndex + ) private pure returns (uint256) { + return + uint256( + keccak256(abi.encodePacked(fundingTxHash, fundingOutputIndex)) + ); + } + + function setDepositDustThreshold(uint64 _depositDustThreshold) external { + depositDustThreshold = _depositDustThreshold; + } + + function setDepositTreasuryFeeDivisor( + uint64 _depositTreasuryFeeDivisor + ) external { + depositTreasuryFeeDivisor = _depositTreasuryFeeDivisor; + } + + function setDepositTxMaxFee(uint64 _depositTxMaxFee) external { + depositTxMaxFee = _depositTxMaxFee; + } + + function setDepositor(uint256 depositKey, address _depositor) external { + DepositRequest storage deposit = depositsMap[depositKey]; + deposit.depositor = _depositor; + } +} diff --git a/core/contracts/test/TBTCVaultStub.sol b/core/contracts/test/TBTCVaultStub.sol new file mode 100644 index 000000000..6d38ae4bd --- /dev/null +++ b/core/contracts/test/TBTCVaultStub.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-3.0-only +pragma solidity ^0.8.21; +import {ITBTCVault} from "../tbtc/TbtcDepositor.sol"; +import {IBridge} from "../external/tbtc/IBridge.sol"; +import {TestERC20} from "./TestERC20.sol"; + +contract TBTCVaultStub is ITBTCVault { + TestERC20 public tbtc; + IBridge public bridge; + + /// @notice Multiplier to convert satoshi to TBTC token units. + uint256 public constant SATOSHI_MULTIPLIER = 10 ** 10; + + uint32 public optimisticMintingFeeDivisor = 500; // 1/500 = 0.002 = 0.2% + + mapping(uint256 => OptimisticMintingRequest) public requests; + + constructor(TestERC20 _tbtc, IBridge _bridge) { + tbtc = _tbtc; + bridge = _bridge; + } + + function optimisticMintingRequests( + uint256 depositKey + ) external view returns (OptimisticMintingRequest memory) { + return requests[depositKey]; + } + + function mintTbtc(address account, uint256 valueSat) public { + tbtc.mint(account, valueSat * SATOSHI_MULTIPLIER); + } + + function finalizeOptimisticMinting(uint256 depositKey) external { + OptimisticMintingRequest storage request = requests[depositKey]; + + IBridge.DepositRequest memory deposit = bridge.deposits(depositKey); + + uint256 amountToMint = (deposit.amount - deposit.treasuryFee) * + SATOSHI_MULTIPLIER; + + uint256 optimisticMintFee = optimisticMintingFeeDivisor > 0 + ? (amountToMint / optimisticMintingFeeDivisor) + : 0; + + tbtc.mint(deposit.depositor, amountToMint - optimisticMintFee); + + /* solhint-disable-next-line not-rely-on-time */ + request.finalizedAt = uint64(block.timestamp); + } + + function setOptimisticMintingFeeDivisor( + uint32 _optimisticMintingFeeDivisor + ) public { + optimisticMintingFeeDivisor = _optimisticMintingFeeDivisor; + } +} From 8ed2a3b4ba051ae94f925ede4478ea694e57f767 Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Mon, 15 Jan 2024 16:41:35 +0100 Subject: [PATCH 169/170] Update deployment scripts for tBTC Depositor We deploy stubs used in tests and tBTC Depositor contract. --- core/deploy/00_resolve_tbtc_bridge.ts | 37 +++++++++++++++++ ...solve_tbtc.ts => 00_resolve_tbtc_token.ts} | 13 ++++-- core/deploy/00_resolve_tbtc_vault.ts | 41 +++++++++++++++++++ core/deploy/03_deploy_tbtc_depositor.ts | 26 ++++++++++++ core/test/helpers/context.ts | 11 ++++- 5 files changed, 123 insertions(+), 5 deletions(-) create mode 100644 core/deploy/00_resolve_tbtc_bridge.ts rename core/deploy/{00_resolve_tbtc.ts => 00_resolve_tbtc_token.ts} (72%) create mode 100644 core/deploy/00_resolve_tbtc_vault.ts create mode 100644 core/deploy/03_deploy_tbtc_depositor.ts diff --git a/core/deploy/00_resolve_tbtc_bridge.ts b/core/deploy/00_resolve_tbtc_bridge.ts new file mode 100644 index 000000000..4b69a2343 --- /dev/null +++ b/core/deploy/00_resolve_tbtc_bridge.ts @@ -0,0 +1,37 @@ +import type { DeployFunction } from "hardhat-deploy/types" +import type { + HardhatNetworkConfig, + HardhatRuntimeEnvironment, +} from "hardhat/types" +import { isNonZeroAddress } from "../helpers/address" + +const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { getNamedAccounts, deployments } = hre + const { log } = deployments + const { deployer } = await getNamedAccounts() + + const bridge = await deployments.getOrNull("Bridge") + + if (bridge && isNonZeroAddress(bridge.address)) { + log(`using Bridge contract at ${bridge.address}`) + } else if ((hre.network.config as HardhatNetworkConfig)?.forking?.enabled) { + throw new Error("deployed Bridge contract not found") + } else { + log("deploying Bridge contract stub") + + const tbtc = await deployments.get("TBTC") + + await deployments.deploy("Bridge", { + contract: "BridgeStub", + args: [tbtc.address], + from: deployer, + log: true, + waitConfirmations: 1, + }) + } +} + +export default func + +func.tags = ["TBTC", "Bridge"] +func.dependencies = ["TBTCToken"] diff --git a/core/deploy/00_resolve_tbtc.ts b/core/deploy/00_resolve_tbtc_token.ts similarity index 72% rename from core/deploy/00_resolve_tbtc.ts rename to core/deploy/00_resolve_tbtc_token.ts index dc1bfeff5..3eb9ce90c 100644 --- a/core/deploy/00_resolve_tbtc.ts +++ b/core/deploy/00_resolve_tbtc_token.ts @@ -1,5 +1,8 @@ -import type { HardhatRuntimeEnvironment } from "hardhat/types" import type { DeployFunction } from "hardhat-deploy/types" +import type { + HardhatNetworkConfig, + HardhatRuntimeEnvironment, +} from "hardhat/types" import { isNonZeroAddress } from "../helpers/address" const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { @@ -11,13 +14,17 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { if (tbtc && isNonZeroAddress(tbtc.address)) { log(`using TBTC contract at ${tbtc.address}`) - } else if (!hre.network.tags.allowStubs) { + } else if ( + !hre.network.tags.allowStubs || + (hre.network.config as HardhatNetworkConfig)?.forking?.enabled + ) { throw new Error("deployed TBTC contract not found") } else { log("deploying TBTC contract stub") await deployments.deploy("TBTC", { contract: "TestERC20", + args: ["Test tBTC", "TestTBTC"], from: deployer, log: true, waitConfirmations: 1, @@ -27,4 +34,4 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { export default func -func.tags = ["TBTC"] +func.tags = ["TBTC", "TBTCToken"] diff --git a/core/deploy/00_resolve_tbtc_vault.ts b/core/deploy/00_resolve_tbtc_vault.ts new file mode 100644 index 000000000..8088f69e1 --- /dev/null +++ b/core/deploy/00_resolve_tbtc_vault.ts @@ -0,0 +1,41 @@ +import type { DeployFunction } from "hardhat-deploy/types" +import type { + HardhatNetworkConfig, + HardhatRuntimeEnvironment, +} from "hardhat/types" +import { isNonZeroAddress } from "../helpers/address" + +const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { getNamedAccounts, deployments } = hre + const { log } = deployments + const { deployer } = await getNamedAccounts() + + const tbtcVault = await deployments.getOrNull("TBTCVault") + + if (tbtcVault && isNonZeroAddress(tbtcVault.address)) { + log(`using TBTCVault contract at ${tbtcVault.address}`) + } else if ( + !hre.network.tags.allowStubs || + (hre.network.config as HardhatNetworkConfig)?.forking?.enabled + ) { + throw new Error("deployed TBTCVault contract not found") + } else { + log("deploying TBTCVault contract stub") + + const tbtc = await deployments.get("TBTC") + const bridge = await deployments.get("Bridge") + + await deployments.deploy("TBTCVault", { + contract: "TBTCVaultStub", + args: [tbtc.address, bridge.address], + from: deployer, + log: true, + waitConfirmations: 1, + }) + } +} + +export default func + +func.tags = ["TBTC", "TBTCVault"] +func.dependencies = ["TBTCToken", "Bridge"] diff --git a/core/deploy/03_deploy_tbtc_depositor.ts b/core/deploy/03_deploy_tbtc_depositor.ts new file mode 100644 index 000000000..9d81cf364 --- /dev/null +++ b/core/deploy/03_deploy_tbtc_depositor.ts @@ -0,0 +1,26 @@ +import type { DeployFunction } from "hardhat-deploy/types" +import type { HardhatRuntimeEnvironment } from "hardhat/types" + +const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { getNamedAccounts, deployments } = hre + const { deployer } = await getNamedAccounts() + + const bridge = await deployments.get("Bridge") + const tbtcVault = await deployments.get("TBTCVault") + const acre = await deployments.get("Acre") + + await deployments.deploy("TbtcDepositor", { + from: deployer, + args: [bridge.address, tbtcVault.address, acre.address], + log: true, + waitConfirmations: 1, + }) + + // TODO: Add Etherscan verification + // TODO: Add Tenderly verification +} + +export default func + +func.tags = ["TbtcDepositor"] +func.dependencies = ["TBTC", "Acre"] diff --git a/core/test/helpers/context.ts b/core/test/helpers/context.ts index 84d661445..d6b41a822 100644 --- a/core/test/helpers/context.ts +++ b/core/test/helpers/context.ts @@ -7,19 +7,26 @@ import type { Dispatcher, TestERC20, TbtcDepositor, + BridgeStub, TestERC4626, + TBTCVaultStub, } from "../../typechain" // eslint-disable-next-line import/prefer-default-export export async function deployment() { await deployments.fixture() - const tbtc: TestERC20 = await getDeployedContract("TBTC") const acre: Acre = await getDeployedContract("Acre") const tbtcDepositor: TbtcDepositor = await getDeployedContract("TbtcDepositor") + + const tbtc: TestERC20 = await getDeployedContract("TBTC") + const tbtcBridge: BridgeStub = await getDeployedContract("Bridge") + const tbtcVault: TBTCVaultStub = await getDeployedContract("TBTCVault") + const dispatcher: Dispatcher = await getDeployedContract("Dispatcher") + const vault: TestERC4626 = await getDeployedContract("Vault") - return { tbtc, acre, tbtcDepositor, dispatcher, vault } + return { tbtc, acre, tbtcDepositor, tbtcBridge, tbtcVault, dispatcher, vault } } From 7c2fea3aff83269751a244b4a5fb8564da5c5dfc Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Mon, 15 Jan 2024 16:46:25 +0100 Subject: [PATCH 170/170] Fix solhint problems --- core/contracts/test/BridgeStub.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/contracts/test/BridgeStub.sol b/core/contracts/test/BridgeStub.sol index f52390ad3..2e6213134 100644 --- a/core/contracts/test/BridgeStub.sol +++ b/core/contracts/test/BridgeStub.sol @@ -21,7 +21,7 @@ contract BridgeStub is IBridge { uint64 public depositTxMaxFee = 1000; // 1000 satoshi = 0.00001 BTC uint32 public depositRevealAheadPeriod = 15 days; - mapping(uint256 => DepositRequest) depositsMap; + mapping(uint256 => DepositRequest) internal depositsMap; constructor(TestERC20 _tbtc) { tbtc = _tbtc; @@ -80,6 +80,7 @@ contract BridgeStub is IBridge { calculateDepositKey(fundingTxHash, fundingOutputIndex) ]; + // solhint-disable-next-line not-rely-on-time deposit.sweptAt = uint32(block.timestamp); (, , uint64 depositTxMaxFee, ) = depositParameters();