{"status":"1","message":"OK","result":[{"ABI":"[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"authority\",\"type\":\"address\"}],\"name\":\"AccessManagedInvalidAuthority\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"delay\",\"type\":\"uint32\"}],\"name\":\"AccessManagedRequiredDelay\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AccessManagedUnauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerIsNotInvestor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CapitalRecipientZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DealZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"id\",\"type\":\"string\"}],\"name\":\"DuplicatePayoutId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FeeRecipientZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientTotalSupply\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nav\",\"type\":\"uint256\"}],\"name\":\"InvalidDealNAV\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint48\",\"name\":\"periodStartTime\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"periodEndTime\",\"type\":\"uint48\"}],\"name\":\"InvalidInterestPayoutPeriod\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"}],\"name\":\"InvestmentAmountTooLow\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MinInvestmentTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MinInvestmentTooLow\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NothingToClaim\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"acceptedAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"offerAmount\",\"type\":\"uint256\"}],\"name\":\"OfferAcceptedAmountTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OfferEscrowPeriodTooLong\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint48\",\"name\":\"escrowReleaseDate\",\"type\":\"uint48\"}],\"name\":\"OfferIsLocked\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"calculatedFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"OfferMaxFeeExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OfferNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OriginationFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentCurrencyDealDecimalMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentCurrencyInvalidDecimals\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentCurrencyZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"acceptedAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestedRedemptionAmount\",\"type\":\"uint256\"}],\"name\":\"RedemptionAcceptedAmountTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"}],\"name\":\"RedemptionAmountTooLow\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RedemptionFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RedemptionLockPeriodTooLong\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"calculatedFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"RedemptionMaxFeeExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RedemptionRequestAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RedemptionRequestAlreadyReviewed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint48\",\"name\":\"requestReleaseDate\",\"type\":\"uint48\"}],\"name\":\"RedemptionRequestIsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RedemptionRequestNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrancy\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"}],\"name\":\"RelayingRedemptionRequestForNonFiatAccount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"RevokingPayoutFromEligibleAccount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"bits\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SafeCastOverflowedUintDowncast\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ServiceFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"YieldGenerationNotStarted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroPayoutBalance\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"authority\",\"type\":\"address\"}],\"name\":\"AuthorityUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldCapitalRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCapitalRecipient\",\"type\":\"address\"}],\"name\":\"CapitalRecipientUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldFeeRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeRecipient\",\"type\":\"address\"}],\"name\":\"FeeRecipientUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"id\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isFiatAccount\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"periodStartTime\",\"type\":\"uint48\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"periodEndTime\",\"type\":\"uint48\"}],\"name\":\"InterestPayoutAccounted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"id\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"onchainPayoutAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"periodStartTime\",\"type\":\"uint48\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"periodEndTime\",\"type\":\"uint48\"}],\"name\":\"InterestPayoutFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldMinInvestment\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newMinInvestment\",\"type\":\"uint256\"}],\"name\":\"MinInvestmentUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"}],\"name\":\"OfferCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"OfferDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"oldPeriod\",\"type\":\"uint48\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"newPeriod\",\"type\":\"uint48\"}],\"name\":\"OfferEscrowPeriodUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"acceptedAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"refundAmount\",\"type\":\"uint256\"}],\"name\":\"OfferReviewed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"BasisPoints\",\"name\":\"fee\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"escrowAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"escrowReleaseDate\",\"type\":\"uint48\"}],\"name\":\"OfferSubmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"BasisPoints\",\"name\":\"oldOriginationFee\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"BasisPoints\",\"name\":\"newOriginationFee\",\"type\":\"uint16\"}],\"name\":\"OriginationFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"PayoutBalanceUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"PayoutClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"PayoutPushSkippedIneligible\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"PayoutPushed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"PayoutRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"id\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isFiatAccount\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokensBurned\",\"type\":\"uint256\"}],\"name\":\"PrincipalPayoutAccounted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"id\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalPayoutAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"onchainPayoutAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokensBurned\",\"type\":\"uint256\"}],\"name\":\"PrincipalPayoutFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newAmount\",\"type\":\"uint256\"}],\"name\":\"RedemptionAmountUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldRedemptionBudget\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newRedemptionBudget\",\"type\":\"uint256\"}],\"name\":\"RedemptionBudgetUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"}],\"name\":\"RedemptionCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"RedemptionDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"availableAmount\",\"type\":\"uint256\"}],\"name\":\"RedemptionExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"BasisPoints\",\"name\":\"oldRedemptionFee\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"BasisPoints\",\"name\":\"newRedemptionFee\",\"type\":\"uint16\"}],\"name\":\"RedemptionFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"oldRedemptionLockPeriod\",\"type\":\"uint48\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"newRedemptionLockPeriod\",\"type\":\"uint48\"}],\"name\":\"RedemptionLockPeriodUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"BasisPoints\",\"name\":\"fee\",\"type\":\"uint16\"}],\"name\":\"RedemptionRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"acceptedAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rejectedAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"redeemedAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"availableAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"requestReleaseDate\",\"type\":\"uint48\"}],\"name\":\"RedemptionReviewed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"RedemptionSkippedIneligible\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"BasisPoints\",\"name\":\"oldServiceFee\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"BasisPoints\",\"name\":\"newServiceFee\",\"type\":\"uint16\"}],\"name\":\"ServiceFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokenMintSkippedIneligible\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalBurned\",\"type\":\"uint256\"}],\"name\":\"TokensBurned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalMinted\",\"type\":\"uint256\"}],\"name\":\"TokensMinted\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"}],\"name\":\"addDealEligibleAccounts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"}],\"name\":\"addDealFiatAccounts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"authority\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"availableForInvestment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"availableFunds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct IDeal.Burn[]\",\"name\":\"targets\",\"type\":\"tuple[]\"}],\"name\":\"burnDealTokens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"totalBurned\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"calculateOriginationFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"calculateRedemptionFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"calculateServiceFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelOffer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelRedemptionRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"capitalRecipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimPayout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deal\",\"outputs\":[{\"internalType\":\"contract IDeal\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeRecipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"payoutId\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"onchainPayoutAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"periodEndTime\",\"type\":\"uint48\"}],\"name\":\"initiateInterestPayout\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"payoutId\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"totalPayoutAmount\",\"type\":\"uint256\"}],\"name\":\"initiatePrincipalPayout\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"investmentOffer\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"escrowAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"},{\"internalType\":\"BasisPoints\",\"name\":\"fee\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"escrowReleaseDate\",\"type\":\"uint48\"}],\"internalType\":\"struct IInvestmentManager.InvestmentOffer\",\"name\":\"offer\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"investmentOffers\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"escrowAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"},{\"internalType\":\"BasisPoints\",\"name\":\"fee\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"escrowReleaseDate\",\"type\":\"uint48\"}],\"internalType\":\"struct IInvestmentManager.InvestmentOffer[]\",\"name\":\"offers\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isConsumingScheduledOp\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isEligibleAccount\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minInvestment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minRedemption\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct IDeal.Mint[]\",\"name\":\"targets\",\"type\":\"tuple[]\"}],\"name\":\"mintDealTokens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"totalMinted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"eligibleCount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offerEscrowPeriod\",\"outputs\":[{\"internalType\":\"uint48\",\"name\":\"\",\"type\":\"uint48\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"originationFee\",\"outputs\":[{\"internalType\":\"BasisPoints\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paymentCurrency\",\"outputs\":[{\"internalType\":\"contract IERC20Metadata\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"payoutBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"payoutBalances\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"internalType\":\"struct IPayoutManager.PayoutBalance[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"payoutDustThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"payoutPeriodStartTime\",\"outputs\":[{\"internalType\":\"uint48\",\"name\":\"\",\"type\":\"uint48\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"onchainPayoutAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"periodStartTime\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"periodEndTime\",\"type\":\"uint48\"}],\"name\":\"previewInterestPayout\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isFiatAccount\",\"type\":\"bool\"}],\"internalType\":\"struct IPayoutManager.InterestPayout[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"totalPayoutAmount\",\"type\":\"uint256\"}],\"name\":\"previewPrincipalPayout\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"burnTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newTokenBalance\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isFiatAccount\",\"type\":\"bool\"}],\"internalType\":\"struct IPayoutManager.PrincipalPayout[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"}],\"name\":\"pushPayout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"redemptionBudget\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"redemptionFee\",\"outputs\":[{\"internalType\":\"BasisPoints\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"redemptionLockPeriod\",\"outputs\":[{\"internalType\":\"uint48\",\"name\":\"\",\"type\":\"uint48\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"redemptionQueueTotal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"}],\"name\":\"redemptionRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableAmount\",\"type\":\"uint256\"},{\"internalType\":\"BasisPoints\",\"name\":\"fee\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"requestReleaseDate\",\"type\":\"uint48\"},{\"internalType\":\"bool\",\"name\":\"queued\",\"type\":\"bool\"}],\"internalType\":\"struct IRedemptionManager.RedemptionRequest\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"redemptionRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableAmount\",\"type\":\"uint256\"},{\"internalType\":\"BasisPoints\",\"name\":\"fee\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"requestReleaseDate\",\"type\":\"uint48\"},{\"internalType\":\"bool\",\"name\":\"queued\",\"type\":\"bool\"}],\"internalType\":\"struct IRedemptionManager.RedemptionRequest\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"redemptionRequests\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableAmount\",\"type\":\"uint256\"},{\"internalType\":\"BasisPoints\",\"name\":\"fee\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"requestReleaseDate\",\"type\":\"uint48\"},{\"internalType\":\"bool\",\"name\":\"queued\",\"type\":\"bool\"}],\"internalType\":\"struct IRedemptionManager.RedemptionRequest[]\",\"name\":\"requests\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"relayRedemptionRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableAmount\",\"type\":\"uint256\"},{\"internalType\":\"BasisPoints\",\"name\":\"fee\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"requestReleaseDate\",\"type\":\"uint48\"},{\"internalType\":\"bool\",\"name\":\"queued\",\"type\":\"bool\"}],\"internalType\":\"struct IRedemptionManager.RedemptionRequest\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"}],\"name\":\"removeDealEligibleAccounts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"}],\"name\":\"removeDealFiatAccounts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reservedFunds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"locked\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"acceptedAmount\",\"type\":\"uint256\"}],\"name\":\"reviewOffer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"acceptedAmount\",\"type\":\"uint256\"}],\"name\":\"reviewRedemptionRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokePayout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"serviceFee\",\"outputs\":[{\"internalType\":\"BasisPoints\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAuthority\",\"type\":\"address\"}],\"name\":\"setAuthority\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"setCapitalRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxHolders\",\"type\":\"uint16\"}],\"name\":\"setDealMaxHolders\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"metadataURI\",\"type\":\"string\"}],\"name\":\"setDealMetadataURI\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nav\",\"type\":\"uint256\"}],\"name\":\"setDealNAV\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"status\",\"type\":\"bool\"}],\"name\":\"setDealOpenEnded\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"totalSize\",\"type\":\"uint256\"}],\"name\":\"setDealTotalSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"setFeeRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"setMinInvestment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint48\",\"name\":\"period\",\"type\":\"uint48\"}],\"name\":\"setOfferEscrowPeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"BasisPoints\",\"name\":\"fee\",\"type\":\"uint16\"}],\"name\":\"setOriginationFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"budget\",\"type\":\"uint256\"}],\"name\":\"setRedemptionBudget\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"BasisPoints\",\"name\":\"fee\",\"type\":\"uint16\"}],\"name\":\"setRedemptionFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint48\",\"name\":\"period\",\"type\":\"uint48\"}],\"name\":\"setRedemptionLockPeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"BasisPoints\",\"name\":\"fee\",\"type\":\"uint16\"}],\"name\":\"setServiceFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"submitOffer\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"escrowAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"},{\"internalType\":\"BasisPoints\",\"name\":\"fee\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"escrowReleaseDate\",\"type\":\"uint48\"}],\"internalType\":\"struct IInvestmentManager.InvestmentOffer\",\"name\":\"offer\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"submitRedemptionRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"investor\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableAmount\",\"type\":\"uint256\"},{\"internalType\":\"BasisPoints\",\"name\":\"fee\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"requestReleaseDate\",\"type\":\"uint48\"},{\"internalType\":\"bool\",\"name\":\"queued\",\"type\":\"bool\"}],\"internalType\":\"struct IRedemptionManager.RedemptionRequest\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalEscrowBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalPayoutBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferDealTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFundsToCapitalRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]","SourceCode":"{{\"language\":\"Solidity\",\"settings\":{\"codegen\":\"yul\",\"enableEraVMExtensions\":false,\"evmVersion\":\"cancun\",\"forceEVMLA\":false,\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"disable_system_request_memoization\":true,\"enabled\":true,\"fallback_to_optimizing_for_size\":true,\"mode\":\"z\"},\"outputSelection\":{\"*\":{\"\":[],\"*\":[\"abi\"]}},\"remappings\":[\"@oz/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/\",\"@oz/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\"@oz/upgrades/=lib/openzeppelin-foundry-upgrades/src/\",\"@solady/=lib/solady/src/\",\"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\"@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/\",\"ds-test/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/\",\"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/\",\"forge-std/=lib/forge-std/src/\",\"halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/\",\"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\"openzeppelin-contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/\",\"openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/\",\"solady/=lib/solady/src/\",\"solidity-stringutils/=lib/openzeppelin-foundry-upgrades/lib/solidity-stringutils/\"],\"viaIR\":false},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/manager/AccessManagedUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/manager/AccessManaged.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IAuthority} from \\\"@openzeppelin/contracts/access/manager/IAuthority.sol\\\";\\nimport {AuthorityUtils} from \\\"@openzeppelin/contracts/access/manager/AuthorityUtils.sol\\\";\\nimport {IAccessManager} from \\\"@openzeppelin/contracts/access/manager/IAccessManager.sol\\\";\\nimport {IAccessManaged} from \\\"@openzeppelin/contracts/access/manager/IAccessManaged.sol\\\";\\nimport {ContextUpgradeable} from \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This contract module makes available a {restricted} modifier. Functions decorated with this modifier will be\\n * permissioned according to an \\\"authority\\\": a contract like {AccessManager} that follows the {IAuthority} interface,\\n * implementing a policy that allows certain callers to access certain functions.\\n *\\n * IMPORTANT: The `restricted` modifier should never be used on `internal` functions, judiciously used in `public`\\n * functions, and ideally only used in `external` functions. See {restricted}.\\n */\\nabstract contract AccessManagedUpgradeable is Initializable, ContextUpgradeable, IAccessManaged {\\n    /// @custom:storage-location erc7201:openzeppelin.storage.AccessManaged\\n    struct AccessManagedStorage {\\n        address _authority;\\n\\n        bool _consumingSchedule;\\n    }\\n\\n    // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.AccessManaged\\\")) - 1)) & ~bytes32(uint256(0xff))\\n    bytes32 private constant AccessManagedStorageLocation = 0xf3177357ab46d8af007ab3fdb9af81da189e1068fefdc0073dca88a2cab40a00;\\n\\n    function _getAccessManagedStorage() private pure returns (AccessManagedStorage storage $) {\\n        assembly {\\n            $.slot := AccessManagedStorageLocation\\n        }\\n    }\\n\\n    /**\\n     * @dev Initializes the contract connected to an initial authority.\\n     */\\n    function __AccessManaged_init(address initialAuthority) internal onlyInitializing {\\n        __AccessManaged_init_unchained(initialAuthority);\\n    }\\n\\n    function __AccessManaged_init_unchained(address initialAuthority) internal onlyInitializing {\\n        _setAuthority(initialAuthority);\\n    }\\n\\n    /**\\n     * @dev Restricts access to a function as defined by the connected Authority for this contract and the\\n     * caller and selector of the function that entered the contract.\\n     *\\n     * [IMPORTANT]\\n     * ====\\n     * In general, this modifier should only be used on `external` functions. It is okay to use it on `public`\\n     * functions that are used as external entry points and are not called internally. Unless you know what you're\\n     * doing, it should never be used on `internal` functions. Failure to follow these rules can have critical security\\n     * implications! This is because the permissions are determined by the function that entered the contract, i.e. the\\n     * function at the bottom of the call stack, and not the function where the modifier is visible in the source code.\\n     * ====\\n     *\\n     * [WARNING]\\n     * ====\\n     * Avoid adding this modifier to the https://docs.soliditylang.org/en/v0.8.20/contracts.html#receive-ether-function[`receive()`]\\n     * function or the https://docs.soliditylang.org/en/v0.8.20/contracts.html#fallback-function[`fallback()`]. These\\n     * functions are the only execution paths where a function selector cannot be unambiguously determined from the calldata\\n     * since the selector defaults to `0x00000000` in the `receive()` function and similarly in the `fallback()` function\\n     * if no calldata is provided. (See {_checkCanCall}).\\n     *\\n     * The `receive()` function will always panic whereas the `fallback()` may panic depending on the calldata length.\\n     * ====\\n     */\\n    modifier restricted() {\\n        _checkCanCall(_msgSender(), _msgData());\\n        _;\\n    }\\n\\n    /// @inheritdoc IAccessManaged\\n    function authority() public view virtual returns (address) {\\n        AccessManagedStorage storage $ = _getAccessManagedStorage();\\n        return $._authority;\\n    }\\n\\n    /// @inheritdoc IAccessManaged\\n    function setAuthority(address newAuthority) public virtual {\\n        address caller = _msgSender();\\n        if (caller != authority()) {\\n            revert AccessManagedUnauthorized(caller);\\n        }\\n        if (newAuthority.code.length == 0) {\\n            revert AccessManagedInvalidAuthority(newAuthority);\\n        }\\n        _setAuthority(newAuthority);\\n    }\\n\\n    /// @inheritdoc IAccessManaged\\n    function isConsumingScheduledOp() public view returns (bytes4) {\\n        AccessManagedStorage storage $ = _getAccessManagedStorage();\\n        return $._consumingSchedule ? this.isConsumingScheduledOp.selector : bytes4(0);\\n    }\\n\\n    /**\\n     * @dev Transfers control to a new authority. Internal function with no access restriction. Allows bypassing the\\n     * permissions set by the current authority.\\n     */\\n    function _setAuthority(address newAuthority) internal virtual {\\n        AccessManagedStorage storage $ = _getAccessManagedStorage();\\n        $._authority = newAuthority;\\n        emit AuthorityUpdated(newAuthority);\\n    }\\n\\n    /**\\n     * @dev Reverts if the caller is not allowed to call the function identified by a selector. Panics if the calldata\\n     * is less than 4 bytes long.\\n     */\\n    function _checkCanCall(address caller, bytes calldata data) internal virtual {\\n        AccessManagedStorage storage $ = _getAccessManagedStorage();\\n        (bool immediate, uint32 delay) = AuthorityUtils.canCallWithDelay(\\n            authority(),\\n            caller,\\n            address(this),\\n            bytes4(data[0:4])\\n        );\\n        if (!immediate) {\\n            if (delay > 0) {\\n                $._consumingSchedule = true;\\n                IAccessManager(authority()).consumeScheduledOp(caller, data);\\n                $._consumingSchedule = false;\\n            } else {\\n                revert AccessManagedUnauthorized(caller);\\n            }\\n        }\\n    }\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n *     function initialize() initializer public {\\n *         __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n *     }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n *     function initializeV2() reinitializer(2) public {\\n *         __ERC20Permit_init(\\\"MyToken\\\");\\n *     }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n *     _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n    /**\\n     * @dev Storage of the initializable contract.\\n     *\\n     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\\n     * when using with upgradeable contracts.\\n     *\\n     * @custom:storage-location erc7201:openzeppelin.storage.Initializable\\n     */\\n    struct InitializableStorage {\\n        /**\\n         * @dev Indicates that the contract has been initialized.\\n         */\\n        uint64 _initialized;\\n        /**\\n         * @dev Indicates that the contract is in the process of being initialized.\\n         */\\n        bool _initializing;\\n    }\\n\\n    // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Initializable\\\")) - 1)) & ~bytes32(uint256(0xff))\\n    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\\n\\n    /**\\n     * @dev The contract is already initialized.\\n     */\\n    error InvalidInitialization();\\n\\n    /**\\n     * @dev The contract is not initializing.\\n     */\\n    error NotInitializing();\\n\\n    /**\\n     * @dev Triggered when the contract has been initialized or reinitialized.\\n     */\\n    event Initialized(uint64 version);\\n\\n    /**\\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n     * `onlyInitializing` functions can be used to initialize parent contracts.\\n     *\\n     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\\n     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\\n     * production.\\n     *\\n     * Emits an {Initialized} event.\\n     */\\n    modifier initializer() {\\n        // solhint-disable-next-line var-name-mixedcase\\n        InitializableStorage storage $ = _getInitializableStorage();\\n\\n        // Cache values to avoid duplicated sloads\\n        bool isTopLevelCall = !$._initializing;\\n        uint64 initialized = $._initialized;\\n\\n        // Allowed calls:\\n        // - initialSetup: the contract is not in the initializing state and no previous version was\\n        //                 initialized\\n        // - construction: the contract is initialized at version 1 (no reininitialization) and the\\n        //                 current contract is just being deployed\\n        bool initialSetup = initialized == 0 && isTopLevelCall;\\n        bool construction = initialized == 1 && address(this).code.length == 0;\\n\\n        if (!initialSetup && !construction) {\\n            revert InvalidInitialization();\\n        }\\n        $._initialized = 1;\\n        if (isTopLevelCall) {\\n            $._initializing = true;\\n        }\\n        _;\\n        if (isTopLevelCall) {\\n            $._initializing = false;\\n            emit Initialized(1);\\n        }\\n    }\\n\\n    /**\\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n     * used to initialize parent contracts.\\n     *\\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n     * are added through upgrades and that require initialization.\\n     *\\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\\n     *\\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n     * a contract, executing them in the right order is up to the developer or operator.\\n     *\\n     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\\n     *\\n     * Emits an {Initialized} event.\\n     */\\n    modifier reinitializer(uint64 version) {\\n        // solhint-disable-next-line var-name-mixedcase\\n        InitializableStorage storage $ = _getInitializableStorage();\\n\\n        if ($._initializing || $._initialized >= version) {\\n            revert InvalidInitialization();\\n        }\\n        $._initialized = version;\\n        $._initializing = true;\\n        _;\\n        $._initializing = false;\\n        emit Initialized(version);\\n    }\\n\\n    /**\\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n     */\\n    modifier onlyInitializing() {\\n        _checkInitializing();\\n        _;\\n    }\\n\\n    /**\\n     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\\n     */\\n    function _checkInitializing() internal view virtual {\\n        if (!_isInitializing()) {\\n            revert NotInitializing();\\n        }\\n    }\\n\\n    /**\\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n     * through proxies.\\n     *\\n     * Emits an {Initialized} event the first time it is successfully executed.\\n     */\\n    function _disableInitializers() internal virtual {\\n        // solhint-disable-next-line var-name-mixedcase\\n        InitializableStorage storage $ = _getInitializableStorage();\\n\\n        if ($._initializing) {\\n            revert InvalidInitialization();\\n        }\\n        if ($._initialized != type(uint64).max) {\\n            $._initialized = type(uint64).max;\\n            emit Initialized(type(uint64).max);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n     */\\n    function _getInitializedVersion() internal view returns (uint64) {\\n        return _getInitializableStorage()._initialized;\\n    }\\n\\n    /**\\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n     */\\n    function _isInitializing() internal view returns (bool) {\\n        return _getInitializableStorage()._initializing;\\n    }\\n\\n    /**\\n     * @dev Returns a pointer to the storage namespace.\\n     */\\n    // solhint-disable-next-line var-name-mixedcase\\n    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\\n        assembly {\\n            $.slot := INITIALIZABLE_STORAGE\\n        }\\n    }\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\\n\\npragma solidity ^0.8.20;\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n    function __Context_init() internal onlyInitializing {\\n    }\\n\\n    function __Context_init_unchained() internal onlyInitializing {\\n    }\\n    function _msgSender() internal view virtual returns (address) {\\n        return msg.sender;\\n    }\\n\\n    function _msgData() internal view virtual returns (bytes calldata) {\\n        return msg.data;\\n    }\\n\\n    function _contextSuffixLength() internal view virtual returns (uint256) {\\n        return 0;\\n    }\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/access/manager/AuthorityUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/manager/AuthorityUtils.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IAuthority} from \\\"./IAuthority.sol\\\";\\n\\nlibrary AuthorityUtils {\\n    /**\\n     * @dev Since `AccessManager` implements an extended IAuthority interface, invoking `canCall` with backwards compatibility\\n     * for the preexisting `IAuthority` interface requires special care to avoid reverting on insufficient return data.\\n     * This helper function takes care of invoking `canCall` in a backwards compatible way without reverting.\\n     */\\n    function canCallWithDelay(\\n        address authority,\\n        address caller,\\n        address target,\\n        bytes4 selector\\n    ) internal view returns (bool immediate, uint32 delay) {\\n        (bool success, bytes memory data) = authority.staticcall(\\n            abi.encodeCall(IAuthority.canCall, (caller, target, selector))\\n        );\\n        if (success) {\\n            if (data.length >= 0x40) {\\n                (immediate, delay) = abi.decode(data, (bool, uint32));\\n            } else if (data.length >= 0x20) {\\n                immediate = abi.decode(data, (bool));\\n            }\\n        }\\n        return (immediate, delay);\\n    }\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/access/manager/IAccessManaged.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/manager/IAccessManaged.sol)\\n\\npragma solidity ^0.8.20;\\n\\ninterface IAccessManaged {\\n    /**\\n     * @dev Authority that manages this contract was updated.\\n     */\\n    event AuthorityUpdated(address authority);\\n\\n    error AccessManagedUnauthorized(address caller);\\n    error AccessManagedRequiredDelay(address caller, uint32 delay);\\n    error AccessManagedInvalidAuthority(address authority);\\n\\n    /**\\n     * @dev Returns the current authority.\\n     */\\n    function authority() external view returns (address);\\n\\n    /**\\n     * @dev Transfers control to a new authority. The caller must be the current authority.\\n     */\\n    function setAuthority(address) external;\\n\\n    /**\\n     * @dev Returns true only in the context of a delayed restricted call, at the moment that the scheduled operation is\\n     * being consumed. Prevents denial of service for delayed restricted calls in the case that the contract performs\\n     * attacker controlled calls.\\n     */\\n    function isConsumingScheduledOp() external view returns (bytes4);\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/access/manager/IAccessManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/manager/IAccessManager.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IAccessManaged} from \\\"./IAccessManaged.sol\\\";\\nimport {Time} from \\\"../../utils/types/Time.sol\\\";\\n\\ninterface IAccessManager {\\n    /**\\n     * @dev A delayed operation was scheduled.\\n     */\\n    event OperationScheduled(\\n        bytes32 indexed operationId,\\n        uint32 indexed nonce,\\n        uint48 schedule,\\n        address caller,\\n        address target,\\n        bytes data\\n    );\\n\\n    /**\\n     * @dev A scheduled operation was executed.\\n     */\\n    event OperationExecuted(bytes32 indexed operationId, uint32 indexed nonce);\\n\\n    /**\\n     * @dev A scheduled operation was canceled.\\n     */\\n    event OperationCanceled(bytes32 indexed operationId, uint32 indexed nonce);\\n\\n    /**\\n     * @dev Informational labelling for a roleId.\\n     */\\n    event RoleLabel(uint64 indexed roleId, string label);\\n\\n    /**\\n     * @dev Emitted when `account` is granted `roleId`.\\n     *\\n     * NOTE: The meaning of the `since` argument depends on the `newMember` argument.\\n     * If the role is granted to a new member, the `since` argument indicates when the account becomes a member of the role,\\n     * otherwise it indicates the execution delay for this account and roleId is updated.\\n     */\\n    event RoleGranted(uint64 indexed roleId, address indexed account, uint32 delay, uint48 since, bool newMember);\\n\\n    /**\\n     * @dev Emitted when `account` membership or `roleId` is revoked. Unlike granting, revoking is instantaneous.\\n     */\\n    event RoleRevoked(uint64 indexed roleId, address indexed account);\\n\\n    /**\\n     * @dev Role acting as admin over a given `roleId` is updated.\\n     */\\n    event RoleAdminChanged(uint64 indexed roleId, uint64 indexed admin);\\n\\n    /**\\n     * @dev Role acting as guardian over a given `roleId` is updated.\\n     */\\n    event RoleGuardianChanged(uint64 indexed roleId, uint64 indexed guardian);\\n\\n    /**\\n     * @dev Grant delay for a given `roleId` will be updated to `delay` when `since` is reached.\\n     */\\n    event RoleGrantDelayChanged(uint64 indexed roleId, uint32 delay, uint48 since);\\n\\n    /**\\n     * @dev Target mode is updated (true = closed, false = open).\\n     */\\n    event TargetClosed(address indexed target, bool closed);\\n\\n    /**\\n     * @dev Role required to invoke `selector` on `target` is updated to `roleId`.\\n     */\\n    event TargetFunctionRoleUpdated(address indexed target, bytes4 selector, uint64 indexed roleId);\\n\\n    /**\\n     * @dev Admin delay for a given `target` will be updated to `delay` when `since` is reached.\\n     */\\n    event TargetAdminDelayUpdated(address indexed target, uint32 delay, uint48 since);\\n\\n    error AccessManagerAlreadyScheduled(bytes32 operationId);\\n    error AccessManagerNotScheduled(bytes32 operationId);\\n    error AccessManagerNotReady(bytes32 operationId);\\n    error AccessManagerExpired(bytes32 operationId);\\n    error AccessManagerLockedRole(uint64 roleId);\\n    error AccessManagerBadConfirmation();\\n    error AccessManagerUnauthorizedAccount(address msgsender, uint64 roleId);\\n    error AccessManagerUnauthorizedCall(address caller, address target, bytes4 selector);\\n    error AccessManagerUnauthorizedConsume(address target);\\n    error AccessManagerUnauthorizedCancel(address msgsender, address caller, address target, bytes4 selector);\\n    error AccessManagerInvalidInitialAdmin(address initialAdmin);\\n\\n    /**\\n     * @dev Check if an address (`caller`) is authorised to call a given function on a given contract directly (with\\n     * no restriction). Additionally, it returns the delay needed to perform the call indirectly through the {schedule}\\n     * & {execute} workflow.\\n     *\\n     * This function is usually called by the targeted contract to control immediate execution of restricted functions.\\n     * Therefore we only return true if the call can be performed without any delay. If the call is subject to a\\n     * previously set delay (not zero), then the function should return false and the caller should schedule the operation\\n     * for future execution.\\n     *\\n     * If `immediate` is true, the delay can be disregarded and the operation can be immediately executed, otherwise\\n     * the operation can be executed if and only if delay is greater than 0.\\n     *\\n     * NOTE: The IAuthority interface does not include the `uint32` delay. This is an extension of that interface that\\n     * is backward compatible. Some contracts may thus ignore the second return argument. In that case they will fail\\n     * to identify the indirect workflow, and will consider calls that require a delay to be forbidden.\\n     *\\n     * NOTE: This function does not report the permissions of the admin functions in the manager itself. These are defined by the\\n     * {AccessManager} documentation.\\n     */\\n    function canCall(\\n        address caller,\\n        address target,\\n        bytes4 selector\\n    ) external view returns (bool allowed, uint32 delay);\\n\\n    /**\\n     * @dev Expiration delay for scheduled proposals. Defaults to 1 week.\\n     *\\n     * IMPORTANT: Avoid overriding the expiration with 0. Otherwise every contract proposal will be expired immediately,\\n     * disabling any scheduling usage.\\n     */\\n    function expiration() external view returns (uint32);\\n\\n    /**\\n     * @dev Minimum setback for all delay updates, with the exception of execution delays. It\\n     * can be increased without setback (and reset via {revokeRole} in the case event of an\\n     * accidental increase). Defaults to 5 days.\\n     */\\n    function minSetback() external view returns (uint32);\\n\\n    /**\\n     * @dev Get whether the contract is closed disabling any access. Otherwise role permissions are applied.\\n     *\\n     * NOTE: When the manager itself is closed, admin functions are still accessible to avoid locking the contract.\\n     */\\n    function isTargetClosed(address target) external view returns (bool);\\n\\n    /**\\n     * @dev Get the role required to call a function.\\n     */\\n    function getTargetFunctionRole(address target, bytes4 selector) external view returns (uint64);\\n\\n    /**\\n     * @dev Get the admin delay for a target contract. Changes to contract configuration are subject to this delay.\\n     */\\n    function getTargetAdminDelay(address target) external view returns (uint32);\\n\\n    /**\\n     * @dev Get the id of the role that acts as an admin for the given role.\\n     *\\n     * The admin permission is required to grant the role, revoke the role and update the execution delay to execute\\n     * an operation that is restricted to this role.\\n     */\\n    function getRoleAdmin(uint64 roleId) external view returns (uint64);\\n\\n    /**\\n     * @dev Get the role that acts as a guardian for a given role.\\n     *\\n     * The guardian permission allows canceling operations that have been scheduled under the role.\\n     */\\n    function getRoleGuardian(uint64 roleId) external view returns (uint64);\\n\\n    /**\\n     * @dev Get the role current grant delay.\\n     *\\n     * Its value may change at any point without an event emitted following a call to {setGrantDelay}.\\n     * Changes to this value, including effect timepoint are notified in advance by the {RoleGrantDelayChanged} event.\\n     */\\n    function getRoleGrantDelay(uint64 roleId) external view returns (uint32);\\n\\n    /**\\n     * @dev Get the access details for a given account for a given role. These details include the timepoint at which\\n     * membership becomes active, and the delay applied to all operation by this user that requires this permission\\n     * level.\\n     *\\n     * Returns:\\n     * [0] Timestamp at which the account membership becomes valid. 0 means role is not granted.\\n     * [1] Current execution delay for the account.\\n     * [2] Pending execution delay for the account.\\n     * [3] Timestamp at which the pending execution delay will become active. 0 means no delay update is scheduled.\\n     */\\n    function getAccess(\\n        uint64 roleId,\\n        address account\\n    ) external view returns (uint48 since, uint32 currentDelay, uint32 pendingDelay, uint48 effect);\\n\\n    /**\\n     * @dev Check if a given account currently has the permission level corresponding to a given role. Note that this\\n     * permission might be associated with an execution delay. {getAccess} can provide more details.\\n     */\\n    function hasRole(uint64 roleId, address account) external view returns (bool isMember, uint32 executionDelay);\\n\\n    /**\\n     * @dev Give a label to a role, for improved role discoverability by UIs.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must be a global admin\\n     *\\n     * Emits a {RoleLabel} event.\\n     */\\n    function labelRole(uint64 roleId, string calldata label) external;\\n\\n    /**\\n     * @dev Add `account` to `roleId`, or change its execution delay.\\n     *\\n     * This gives the account the authorization to call any function that is restricted to this role. An optional\\n     * execution delay (in seconds) can be set. If that delay is non 0, the user is required to schedule any operation\\n     * that is restricted to members of this role. The user will only be able to execute the operation after the delay has\\n     * passed, before it has expired. During this period, admin and guardians can cancel the operation (see {cancel}).\\n     *\\n     * If the account has already been granted this role, the execution delay will be updated. This update is not\\n     * immediate and follows the delay rules. For example, if a user currently has a delay of 3 hours, and this is\\n     * called to reduce that delay to 1 hour, the new delay will take some time to take effect, enforcing that any\\n     * operation executed in the 3 hours that follows this update was indeed scheduled before this update.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must be an admin for the role (see {getRoleAdmin})\\n     * - granted role must not be the `PUBLIC_ROLE`\\n     *\\n     * Emits a {RoleGranted} event.\\n     */\\n    function grantRole(uint64 roleId, address account, uint32 executionDelay) external;\\n\\n    /**\\n     * @dev Remove an account from a role, with immediate effect. If the account does not have the role, this call has\\n     * no effect.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must be an admin for the role (see {getRoleAdmin})\\n     * - revoked role must not be the `PUBLIC_ROLE`\\n     *\\n     * Emits a {RoleRevoked} event if the account had the role.\\n     */\\n    function revokeRole(uint64 roleId, address account) external;\\n\\n    /**\\n     * @dev Renounce role permissions for the calling account with immediate effect. If the sender is not in\\n     * the role this call has no effect.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must be `callerConfirmation`.\\n     *\\n     * Emits a {RoleRevoked} event if the account had the role.\\n     */\\n    function renounceRole(uint64 roleId, address callerConfirmation) external;\\n\\n    /**\\n     * @dev Change admin role for a given role.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must be a global admin\\n     *\\n     * Emits a {RoleAdminChanged} event\\n     */\\n    function setRoleAdmin(uint64 roleId, uint64 admin) external;\\n\\n    /**\\n     * @dev Change guardian role for a given role.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must be a global admin\\n     *\\n     * Emits a {RoleGuardianChanged} event\\n     */\\n    function setRoleGuardian(uint64 roleId, uint64 guardian) external;\\n\\n    /**\\n     * @dev Update the delay for granting a `roleId`.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must be a global admin\\n     *\\n     * Emits a {RoleGrantDelayChanged} event.\\n     */\\n    function setGrantDelay(uint64 roleId, uint32 newDelay) external;\\n\\n    /**\\n     * @dev Set the role required to call functions identified by the `selectors` in the `target` contract.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must be a global admin\\n     *\\n     * Emits a {TargetFunctionRoleUpdated} event per selector.\\n     */\\n    function setTargetFunctionRole(address target, bytes4[] calldata selectors, uint64 roleId) external;\\n\\n    /**\\n     * @dev Set the delay for changing the configuration of a given target contract.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must be a global admin\\n     *\\n     * Emits a {TargetAdminDelayUpdated} event.\\n     */\\n    function setTargetAdminDelay(address target, uint32 newDelay) external;\\n\\n    /**\\n     * @dev Set the closed flag for a contract.\\n     *\\n     * Closing the manager itself won't disable access to admin methods to avoid locking the contract.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must be a global admin\\n     *\\n     * Emits a {TargetClosed} event.\\n     */\\n    function setTargetClosed(address target, bool closed) external;\\n\\n    /**\\n     * @dev Return the timepoint at which a scheduled operation will be ready for execution. This returns 0 if the\\n     * operation is not yet scheduled, has expired, was executed, or was canceled.\\n     */\\n    function getSchedule(bytes32 id) external view returns (uint48);\\n\\n    /**\\n     * @dev Return the nonce for the latest scheduled operation with a given id. Returns 0 if the operation has never\\n     * been scheduled.\\n     */\\n    function getNonce(bytes32 id) external view returns (uint32);\\n\\n    /**\\n     * @dev Schedule a delayed operation for future execution, and return the operation identifier. It is possible to\\n     * choose the timestamp at which the operation becomes executable as long as it satisfies the execution delays\\n     * required for the caller. The special value zero will automatically set the earliest possible time.\\n     *\\n     * Returns the `operationId` that was scheduled. Since this value is a hash of the parameters, it can reoccur when\\n     * the same parameters are used; if this is relevant, the returned `nonce` can be used to uniquely identify this\\n     * scheduled operation from other occurrences of the same `operationId` in invocations of {execute} and {cancel}.\\n     *\\n     * Emits a {OperationScheduled} event.\\n     *\\n     * NOTE: It is not possible to concurrently schedule more than one operation with the same `target` and `data`. If\\n     * this is necessary, a random byte can be appended to `data` to act as a salt that will be ignored by the target\\n     * contract if it is using standard Solidity ABI encoding.\\n     */\\n    function schedule(\\n        address target,\\n        bytes calldata data,\\n        uint48 when\\n    ) external returns (bytes32 operationId, uint32 nonce);\\n\\n    /**\\n     * @dev Execute a function that is delay restricted, provided it was properly scheduled beforehand, or the\\n     * execution delay is 0.\\n     *\\n     * Returns the nonce that identifies the previously scheduled operation that is executed, or 0 if the\\n     * operation wasn't previously scheduled (if the caller doesn't have an execution delay).\\n     *\\n     * Emits an {OperationExecuted} event only if the call was scheduled and delayed.\\n     */\\n    function execute(address target, bytes calldata data) external payable returns (uint32);\\n\\n    /**\\n     * @dev Cancel a scheduled (delayed) operation. Returns the nonce that identifies the previously scheduled\\n     * operation that is cancelled.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must be the proposer, a guardian of the targeted function, or a global admin\\n     *\\n     * Emits a {OperationCanceled} event.\\n     */\\n    function cancel(address caller, address target, bytes calldata data) external returns (uint32);\\n\\n    /**\\n     * @dev Consume a scheduled operation targeting the caller. If such an operation exists, mark it as consumed\\n     * (emit an {OperationExecuted} event and clean the state). Otherwise, throw an error.\\n     *\\n     * This is useful for contract that want to enforce that calls targeting them were scheduled on the manager,\\n     * with all the verifications that it implies.\\n     *\\n     * Emit a {OperationExecuted} event.\\n     */\\n    function consumeScheduledOp(address caller, bytes calldata data) external;\\n\\n    /**\\n     * @dev Hashing function for delayed operations.\\n     */\\n    function hashOperation(address caller, address target, bytes calldata data) external view returns (bytes32);\\n\\n    /**\\n     * @dev Changes the authority of a target managed by this manager instance.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must be a global admin\\n     */\\n    function updateAuthority(address target, address newAuthority) external;\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/access/manager/IAuthority.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/manager/IAuthority.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard interface for permissioning originally defined in Dappsys.\\n */\\ninterface IAuthority {\\n    /**\\n     * @dev Returns true if the caller can invoke on a target the function identified by a function selector.\\n     */\\n    function canCall(address caller, address target, bytes4 selector) external view returns (bool allowed);\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1363.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"./IERC20.sol\\\";\\nimport {IERC165} from \\\"./IERC165.sol\\\";\\n\\n/**\\n * @title IERC1363\\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\\n *\\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\\n */\\ninterface IERC1363 is IERC20, IERC165 {\\n    /*\\n     * Note: the ERC-165 identifier for this interface is 0xb0202a11.\\n     * 0xb0202a11 ===\\n     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^\\n     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\\n     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^\\n     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\\n     */\\n\\n    /**\\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\\n     * @param to The address which you want to transfer to.\\n     * @param value The amount of tokens to be transferred.\\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\\n     */\\n    function transferAndCall(address to, uint256 value) external returns (bool);\\n\\n    /**\\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\\n     * @param to The address which you want to transfer to.\\n     * @param value The amount of tokens to be transferred.\\n     * @param data Additional data with no specified format, sent in call to `to`.\\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\\n     */\\n    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\\n\\n    /**\\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\\n     * @param from The address which you want to send tokens from.\\n     * @param to The address which you want to transfer to.\\n     * @param value The amount of tokens to be transferred.\\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\\n     */\\n    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\\n\\n    /**\\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\\n     * @param from The address which you want to send tokens from.\\n     * @param to The address which you want to transfer to.\\n     * @param value The amount of tokens to be transferred.\\n     * @param data Additional data with no specified format, sent in call to `to`.\\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\\n     */\\n    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\\n\\n    /**\\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\\n     * @param spender The address which will spend the funds.\\n     * @param value The amount of tokens to be spent.\\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\\n     */\\n    function approveAndCall(address spender, uint256 value) external returns (bool);\\n\\n    /**\\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\\n     * @param spender The address which will spend the funds.\\n     * @param value The amount of tokens to be spent.\\n     * @param data Additional data with no specified format, sent in call to `spender`.\\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\\n     */\\n    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"../utils/introspection/IERC165.sol\\\";\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../token/ERC20/IERC20.sol\\\";\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC6372.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC6372.sol)\\n\\npragma solidity ^0.8.20;\\n\\ninterface IERC6372 {\\n    /**\\n     * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting).\\n     */\\n    function clock() external view returns (uint48);\\n\\n    /**\\n     * @dev Description of the clock\\n     */\\n    // solhint-disable-next-line func-name-mixedcase\\n    function CLOCK_MODE() external view returns (string memory);\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard ERC-20 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.\\n */\\ninterface IERC20Errors {\\n    /**\\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n     * @param sender Address whose tokens are being transferred.\\n     * @param balance Current balance for the interacting account.\\n     * @param needed Minimum amount required to perform a transfer.\\n     */\\n    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\\n\\n    /**\\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\\n     * @param sender Address whose tokens are being transferred.\\n     */\\n    error ERC20InvalidSender(address sender);\\n\\n    /**\\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n     * @param receiver Address to which tokens are being transferred.\\n     */\\n    error ERC20InvalidReceiver(address receiver);\\n\\n    /**\\n     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\\n     * @param allowance Amount of tokens a `spender` is allowed to operate with.\\n     * @param needed Minimum amount required to perform a transfer.\\n     */\\n    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\\n\\n    /**\\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n     * @param approver Address initiating an approval operation.\\n     */\\n    error ERC20InvalidApprover(address approver);\\n\\n    /**\\n     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\\n     */\\n    error ERC20InvalidSpender(address spender);\\n}\\n\\n/**\\n * @dev Standard ERC-721 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.\\n */\\ninterface IERC721Errors {\\n    /**\\n     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.\\n     * Used in balance queries.\\n     * @param owner Address of the current owner of a token.\\n     */\\n    error ERC721InvalidOwner(address owner);\\n\\n    /**\\n     * @dev Indicates a `tokenId` whose `owner` is the zero address.\\n     * @param tokenId Identifier number of a token.\\n     */\\n    error ERC721NonexistentToken(uint256 tokenId);\\n\\n    /**\\n     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\\n     * @param sender Address whose tokens are being transferred.\\n     * @param tokenId Identifier number of a token.\\n     * @param owner Address of the current owner of a token.\\n     */\\n    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\\n\\n    /**\\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\\n     * @param sender Address whose tokens are being transferred.\\n     */\\n    error ERC721InvalidSender(address sender);\\n\\n    /**\\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n     * @param receiver Address to which tokens are being transferred.\\n     */\\n    error ERC721InvalidReceiver(address receiver);\\n\\n    /**\\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\\n     * @param tokenId Identifier number of a token.\\n     */\\n    error ERC721InsufficientApproval(address operator, uint256 tokenId);\\n\\n    /**\\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n     * @param approver Address initiating an approval operation.\\n     */\\n    error ERC721InvalidApprover(address approver);\\n\\n    /**\\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\\n     */\\n    error ERC721InvalidOperator(address operator);\\n}\\n\\n/**\\n * @dev Standard ERC-1155 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.\\n */\\ninterface IERC1155Errors {\\n    /**\\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n     * @param sender Address whose tokens are being transferred.\\n     * @param balance Current balance for the interacting account.\\n     * @param needed Minimum amount required to perform a transfer.\\n     * @param tokenId Identifier number of a token.\\n     */\\n    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\\n\\n    /**\\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\\n     * @param sender Address whose tokens are being transferred.\\n     */\\n    error ERC1155InvalidSender(address sender);\\n\\n    /**\\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n     * @param receiver Address to which tokens are being transferred.\\n     */\\n    error ERC1155InvalidReceiver(address receiver);\\n\\n    /**\\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\\n     * @param owner Address of the current owner of a token.\\n     */\\n    error ERC1155MissingApprovalForAll(address operator, address owner);\\n\\n    /**\\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n     * @param approver Address initiating an approval operation.\\n     */\\n    error ERC1155InvalidApprover(address approver);\\n\\n    /**\\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\\n     */\\n    error ERC1155InvalidOperator(address operator);\\n\\n    /**\\n     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\\n     * Used in batch transfers.\\n     * @param idsLength Length of the array of token identifiers\\n     * @param valuesLength Length of the array of token amounts\\n     */\\n    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n    /**\\n     * @dev Must return an address that can be used as a delegate call target.\\n     *\\n     * {UpgradeableBeacon} will check that this address is a contract.\\n     */\\n    function implementation() external view returns (address);\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-20 standard as defined in the ERC.\\n */\\ninterface IERC20 {\\n    /**\\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n     * another (`to`).\\n     *\\n     * Note that `value` may be zero.\\n     */\\n    event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n    /**\\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n     * a call to {approve}. `value` is the new allowance.\\n     */\\n    event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n    /**\\n     * @dev Returns the value of tokens in existence.\\n     */\\n    function totalSupply() external view returns (uint256);\\n\\n    /**\\n     * @dev Returns the value of tokens owned by `account`.\\n     */\\n    function balanceOf(address account) external view returns (uint256);\\n\\n    /**\\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transfer(address to, uint256 value) external returns (bool);\\n\\n    /**\\n     * @dev Returns the remaining number of tokens that `spender` will be\\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n     * zero by default.\\n     *\\n     * This value changes when {approve} or {transferFrom} are called.\\n     */\\n    function allowance(address owner, address spender) external view returns (uint256);\\n\\n    /**\\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n     * caller's tokens.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n     * that someone may use both the old and the new allowance by unfortunate\\n     * transaction ordering. One possible solution to mitigate this race\\n     * condition is to first reduce the spender's allowance to 0 and set the\\n     * desired value afterwards:\\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n     *\\n     * Emits an {Approval} event.\\n     */\\n    function approve(address spender, uint256 value) external returns (bool);\\n\\n    /**\\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n     * allowance mechanism. `value` is then deducted from the caller's\\n     * allowance.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\\n */\\ninterface IERC20Metadata is IERC20 {\\n    /**\\n     * @dev Returns the name of the token.\\n     */\\n    function name() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the symbol of the token.\\n     */\\n    function symbol() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the decimals places of the token.\\n     */\\n    function decimals() external view returns (uint8);\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../IERC20.sol\\\";\\nimport {IERC1363} from \\\"../../../interfaces/IERC1363.sol\\\";\\nimport {Address} from \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC-20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n    /**\\n     * @dev An operation with an ERC-20 token failed.\\n     */\\n    error SafeERC20FailedOperation(address token);\\n\\n    /**\\n     * @dev Indicates a failed `decreaseAllowance` request.\\n     */\\n    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\\n\\n    /**\\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n     * non-reverting calls are assumed to be successful.\\n     */\\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));\\n    }\\n\\n    /**\\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n     */\\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));\\n    }\\n\\n    /**\\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n     * non-reverting calls are assumed to be successful.\\n     */\\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n        uint256 oldAllowance = token.allowance(address(this), spender);\\n        forceApprove(token, spender, oldAllowance + value);\\n    }\\n\\n    /**\\n     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\\n     * value, non-reverting calls are assumed to be successful.\\n     */\\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\\n        unchecked {\\n            uint256 currentAllowance = token.allowance(address(this), spender);\\n            if (currentAllowance < requestedDecrease) {\\n                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\\n            }\\n            forceApprove(token, spender, currentAllowance - requestedDecrease);\\n        }\\n    }\\n\\n    /**\\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n     * to be set to zero before setting it to a non-zero value, such as USDT.\\n     */\\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));\\n\\n        if (!_callOptionalReturnBool(token, approvalCall)) {\\n            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));\\n            _callOptionalReturn(token, approvalCall);\\n        }\\n    }\\n\\n    /**\\n     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\\n     * targeting contracts.\\n     *\\n     * Reverts if the returned value is other than `true`.\\n     */\\n    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\\n        if (to.code.length == 0) {\\n            safeTransfer(token, to, value);\\n        } else if (!token.transferAndCall(to, value, data)) {\\n            revert SafeERC20FailedOperation(address(token));\\n        }\\n    }\\n\\n    /**\\n     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\\n     * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\\n     * targeting contracts.\\n     *\\n     * Reverts if the returned value is other than `true`.\\n     */\\n    function transferFromAndCallRelaxed(\\n        IERC1363 token,\\n        address from,\\n        address to,\\n        uint256 value,\\n        bytes memory data\\n    ) internal {\\n        if (to.code.length == 0) {\\n            safeTransferFrom(token, from, to, value);\\n        } else if (!token.transferFromAndCall(from, to, value, data)) {\\n            revert SafeERC20FailedOperation(address(token));\\n        }\\n    }\\n\\n    /**\\n     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\\n     * targeting contracts.\\n     *\\n     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\\n     * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\\n     * once without retrying, and relies on the returned value to be true.\\n     *\\n     * Reverts if the returned value is other than `true`.\\n     */\\n    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\\n        if (to.code.length == 0) {\\n            forceApprove(token, to, value);\\n        } else if (!token.approveAndCall(to, value, data)) {\\n            revert SafeERC20FailedOperation(address(token));\\n        }\\n    }\\n\\n    /**\\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\\n     * @param token The token targeted by the call.\\n     * @param data The call data (encoded using abi.encode or one of its variants).\\n     *\\n     * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.\\n     */\\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n        uint256 returnSize;\\n        uint256 returnValue;\\n        assembly (\\\"memory-safe\\\") {\\n            let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\\n            // bubble errors\\n            if iszero(success) {\\n                let ptr := mload(0x40)\\n                returndatacopy(ptr, 0, returndatasize())\\n                revert(ptr, returndatasize())\\n            }\\n            returnSize := returndatasize()\\n            returnValue := mload(0)\\n        }\\n\\n        if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {\\n            revert SafeERC20FailedOperation(address(token));\\n        }\\n    }\\n\\n    /**\\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\\n     * @param token The token targeted by the call.\\n     * @param data The call data (encoded using abi.encode or one of its variants).\\n     *\\n     * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.\\n     */\\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n        bool success;\\n        uint256 returnSize;\\n        uint256 returnValue;\\n        assembly (\\\"memory-safe\\\") {\\n            success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\\n            returnSize := returndatasize()\\n            returnValue := mload(0)\\n        }\\n        return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);\\n    }\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Errors} from \\\"./Errors.sol\\\";\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n    /**\\n     * @dev There's no code at `target` (it is not a contract).\\n     */\\n    error AddressEmptyCode(address target);\\n\\n    /**\\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n     * `recipient`, forwarding all available gas and reverting on errors.\\n     *\\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n     * imposed by `transfer`, making them unable to receive funds via\\n     * `transfer`. {sendValue} removes this limitation.\\n     *\\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n     *\\n     * IMPORTANT: because control is transferred to `recipient`, care must be\\n     * taken to not create reentrancy vulnerabilities. Consider using\\n     * {ReentrancyGuard} or the\\n     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n     */\\n    function sendValue(address payable recipient, uint256 amount) internal {\\n        if (address(this).balance < amount) {\\n            revert Errors.InsufficientBalance(address(this).balance, amount);\\n        }\\n\\n        (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n        if (!success) {\\n            revert Errors.FailedCall();\\n        }\\n    }\\n\\n    /**\\n     * @dev Performs a Solidity function call using a low level `call`. A\\n     * plain `call` is an unsafe replacement for a function call: use this\\n     * function instead.\\n     *\\n     * If `target` reverts with a revert reason or custom error, it is bubbled\\n     * up by this function (like regular Solidity function calls). However, if\\n     * the call reverted with no returned reason, this function reverts with a\\n     * {Errors.FailedCall} error.\\n     *\\n     * Returns the raw returned data. To convert to the expected return value,\\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n     *\\n     * Requirements:\\n     *\\n     * - `target` must be a contract.\\n     * - calling `target` with `data` must not revert.\\n     */\\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, 0);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but also transferring `value` wei to `target`.\\n     *\\n     * Requirements:\\n     *\\n     * - the calling contract must have an ETH balance of at least `value`.\\n     * - the called Solidity function must be `payable`.\\n     */\\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n        if (address(this).balance < value) {\\n            revert Errors.InsufficientBalance(address(this).balance, value);\\n        }\\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\\n        return verifyCallResultFromTarget(target, success, returndata);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a static call.\\n     */\\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n        (bool success, bytes memory returndata) = target.staticcall(data);\\n        return verifyCallResultFromTarget(target, success, returndata);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a delegate call.\\n     */\\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n        (bool success, bytes memory returndata) = target.delegatecall(data);\\n        return verifyCallResultFromTarget(target, success, returndata);\\n    }\\n\\n    /**\\n     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\\n     * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case\\n     * of an unsuccessful call.\\n     */\\n    function verifyCallResultFromTarget(\\n        address target,\\n        bool success,\\n        bytes memory returndata\\n    ) internal view returns (bytes memory) {\\n        if (!success) {\\n            _revert(returndata);\\n        } else {\\n            // only check if target is a contract if the call was successful and the return data is empty\\n            // otherwise we already know that it was a contract\\n            if (returndata.length == 0 && target.code.length == 0) {\\n                revert AddressEmptyCode(target);\\n            }\\n            return returndata;\\n        }\\n    }\\n\\n    /**\\n     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\\n     * revert reason or with a default {Errors.FailedCall} error.\\n     */\\n    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\\n        if (!success) {\\n            _revert(returndata);\\n        } else {\\n            return returndata;\\n        }\\n    }\\n\\n    /**\\n     * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}.\\n     */\\n    function _revert(bytes memory returndata) private pure {\\n        // Look for revert reason and bubble it up if present\\n        if (returndata.length > 0) {\\n            // The easiest way to bubble the revert reason is using memory via assembly\\n            /// @solidity memory-safe-assembly\\n            assembly {\\n                let returndata_size := mload(returndata)\\n                revert(add(32, returndata), returndata_size)\\n            }\\n        } else {\\n            revert Errors.FailedCall();\\n        }\\n    }\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Collection of common custom errors used in multiple contracts\\n *\\n * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.\\n * It is recommended to avoid relying on the error API for critical functionality.\\n */\\nlibrary Errors {\\n    /**\\n     * @dev The ETH balance of the account is not enough to perform the operation.\\n     */\\n    error InsufficientBalance(uint256 balance, uint256 needed);\\n\\n    /**\\n     * @dev A call to an address target failed. The target may have reverted.\\n     */\\n    error FailedCall();\\n\\n    /**\\n     * @dev The deployment failed.\\n     */\\n    error FailedDeployment();\\n\\n    /**\\n     * @dev A necessary precompile is missing.\\n     */\\n    error MissingPrecompile(address);\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Panic.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Helper library for emitting standardized panic codes.\\n *\\n * ```solidity\\n * contract Example {\\n *      using Panic for uint256;\\n *\\n *      // Use any of the declared internal constants\\n *      function foo() { Panic.GENERIC.panic(); }\\n *\\n *      // Alternatively\\n *      function foo() { Panic.panic(Panic.GENERIC); }\\n * }\\n * ```\\n *\\n * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].\\n */\\n// slither-disable-next-line unused-state\\nlibrary Panic {\\n    /// @dev generic / unspecified error\\n    uint256 internal constant GENERIC = 0x00;\\n    /// @dev used by the assert() builtin\\n    uint256 internal constant ASSERT = 0x01;\\n    /// @dev arithmetic underflow or overflow\\n    uint256 internal constant UNDER_OVERFLOW = 0x11;\\n    /// @dev division or modulo by zero\\n    uint256 internal constant DIVISION_BY_ZERO = 0x12;\\n    /// @dev enum conversion error\\n    uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;\\n    /// @dev invalid encoding in storage\\n    uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;\\n    /// @dev empty array pop\\n    uint256 internal constant EMPTY_ARRAY_POP = 0x31;\\n    /// @dev array out of bounds access\\n    uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;\\n    /// @dev resource error (too large allocation or too large array)\\n    uint256 internal constant RESOURCE_ERROR = 0x41;\\n    /// @dev calling invalid internal function\\n    uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;\\n\\n    /// @dev Reverts with a panic code. Recommended to use with\\n    /// the internal constants with predefined codes.\\n    function panic(uint256 code) internal pure {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            mstore(0x00, 0x4e487b71)\\n            mstore(0x20, code)\\n            revert(0x1c, 0x24)\\n        }\\n    }\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n    /**\\n     * @dev Returns true if this contract implements the interface defined by\\n     * `interfaceId`. See the corresponding\\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\\n     * to learn more about how these ids are created.\\n     *\\n     * This function call must use less than 30 000 gas.\\n     */\\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Panic} from \\\"../Panic.sol\\\";\\nimport {SafeCast} from \\\"./SafeCast.sol\\\";\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n    enum Rounding {\\n        Floor, // Toward negative infinity\\n        Ceil, // Toward positive infinity\\n        Trunc, // Toward zero\\n        Expand // Away from zero\\n    }\\n\\n    /**\\n     * @dev Returns the addition of two unsigned integers, with an success flag (no overflow).\\n     */\\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\\n        unchecked {\\n            uint256 c = a + b;\\n            if (c < a) return (false, 0);\\n            return (true, c);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow).\\n     */\\n    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\\n        unchecked {\\n            if (b > a) return (false, 0);\\n            return (true, a - b);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow).\\n     */\\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\\n        unchecked {\\n            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n            // benefit is lost if 'b' is also tested.\\n            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n            if (a == 0) return (true, 0);\\n            uint256 c = a * b;\\n            if (c / a != b) return (false, 0);\\n            return (true, c);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).\\n     */\\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\\n        unchecked {\\n            if (b == 0) return (false, 0);\\n            return (true, a / b);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).\\n     */\\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\\n        unchecked {\\n            if (b == 0) return (false, 0);\\n            return (true, a % b);\\n        }\\n    }\\n\\n    /**\\n     * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.\\n     *\\n     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.\\n     * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute\\n     * one branch when needed, making this function more expensive.\\n     */\\n    function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {\\n        unchecked {\\n            // branchless ternary works because:\\n            // b ^ (a ^ b) == a\\n            // b ^ 0 == b\\n            return b ^ ((a ^ b) * SafeCast.toUint(condition));\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the largest of two numbers.\\n     */\\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return ternary(a > b, a, b);\\n    }\\n\\n    /**\\n     * @dev Returns the smallest of two numbers.\\n     */\\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return ternary(a < b, a, b);\\n    }\\n\\n    /**\\n     * @dev Returns the average of two numbers. The result is rounded towards\\n     * zero.\\n     */\\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n        // (a + b) / 2 can overflow.\\n        return (a & b) + (a ^ b) / 2;\\n    }\\n\\n    /**\\n     * @dev Returns the ceiling of the division of two numbers.\\n     *\\n     * This differs from standard division with `/` in that it rounds towards infinity instead\\n     * of rounding towards zero.\\n     */\\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n        if (b == 0) {\\n            // Guarantee the same behavior as in a regular Solidity division.\\n            Panic.panic(Panic.DIVISION_BY_ZERO);\\n        }\\n\\n        // The following calculation ensures accurate ceiling division without overflow.\\n        // Since a is non-zero, (a - 1) / b will not overflow.\\n        // The largest possible result occurs when (a - 1) / b is type(uint256).max,\\n        // but the largest value we can obtain is type(uint256).max - 1, which happens\\n        // when a = type(uint256).max and b = 1.\\n        unchecked {\\n            return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);\\n        }\\n    }\\n\\n    /**\\n     * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\\n     * denominator == 0.\\n     *\\n     * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\\n     * Uniswap Labs also under MIT license.\\n     */\\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n        unchecked {\\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use\\n            // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n            // variables such that product = prod1 * 2²⁵⁶ + prod0.\\n            uint256 prod0 = x * y; // Least significant 256 bits of the product\\n            uint256 prod1; // Most significant 256 bits of the product\\n            assembly {\\n                let mm := mulmod(x, y, not(0))\\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n            }\\n\\n            // Handle non-overflow cases, 256 by 256 division.\\n            if (prod1 == 0) {\\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n                // The surrounding unchecked block does not change this fact.\\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n                return prod0 / denominator;\\n            }\\n\\n            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.\\n            if (denominator <= prod1) {\\n                Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));\\n            }\\n\\n            ///////////////////////////////////////////////\\n            // 512 by 256 division.\\n            ///////////////////////////////////////////////\\n\\n            // Make division exact by subtracting the remainder from [prod1 prod0].\\n            uint256 remainder;\\n            assembly {\\n                // Compute remainder using mulmod.\\n                remainder := mulmod(x, y, denominator)\\n\\n                // Subtract 256 bit number from 512 bit number.\\n                prod1 := sub(prod1, gt(remainder, prod0))\\n                prod0 := sub(prod0, remainder)\\n            }\\n\\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\\n            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\\n\\n            uint256 twos = denominator & (0 - denominator);\\n            assembly {\\n                // Divide denominator by twos.\\n                denominator := div(denominator, twos)\\n\\n                // Divide [prod1 prod0] by twos.\\n                prod0 := div(prod0, twos)\\n\\n                // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.\\n                twos := add(div(sub(0, twos), twos), 1)\\n            }\\n\\n            // Shift in bits from prod1 into prod0.\\n            prod0 |= prod1 * twos;\\n\\n            // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such\\n            // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for\\n            // four bits. That is, denominator * inv ≡ 1 mod 2⁴.\\n            uint256 inverse = (3 * denominator) ^ 2;\\n\\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\\n            // works in modular arithmetic, doubling the correct bits in each step.\\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁸\\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶\\n            inverse *= 2 - denominator * inverse; // inverse mod 2³²\\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴\\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸\\n            inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶\\n\\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n            // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is\\n            // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and prod1\\n            // is no longer required.\\n            result = prod0 * inverse;\\n            return result;\\n        }\\n    }\\n\\n    /**\\n     * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.\\n     */\\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n        return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);\\n    }\\n\\n    /**\\n     * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.\\n     *\\n     * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, expect 0.\\n     * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.\\n     *\\n     * If the input value is not inversible, 0 is returned.\\n     *\\n     * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the\\n     * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.\\n     */\\n    function invMod(uint256 a, uint256 n) internal pure returns (uint256) {\\n        unchecked {\\n            if (n == 0) return 0;\\n\\n            // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)\\n            // Used to compute integers x and y such that: ax + ny = gcd(a, n).\\n            // When the gcd is 1, then the inverse of a modulo n exists and it's x.\\n            // ax + ny = 1\\n            // ax = 1 + (-y)n\\n            // ax ≡ 1 (mod n) # x is the inverse of a modulo n\\n\\n            // If the remainder is 0 the gcd is n right away.\\n            uint256 remainder = a % n;\\n            uint256 gcd = n;\\n\\n            // Therefore the initial coefficients are:\\n            // ax + ny = gcd(a, n) = n\\n            // 0a + 1n = n\\n            int256 x = 0;\\n            int256 y = 1;\\n\\n            while (remainder != 0) {\\n                uint256 quotient = gcd / remainder;\\n\\n                (gcd, remainder) = (\\n                    // The old remainder is the next gcd to try.\\n                    remainder,\\n                    // Compute the next remainder.\\n                    // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd\\n                    // where gcd is at most n (capped to type(uint256).max)\\n                    gcd - remainder * quotient\\n                );\\n\\n                (x, y) = (\\n                    // Increment the coefficient of a.\\n                    y,\\n                    // Decrement the coefficient of n.\\n                    // Can overflow, but the result is casted to uint256 so that the\\n                    // next value of y is \\\"wrapped around\\\" to a value between 0 and n - 1.\\n                    x - y * int256(quotient)\\n                );\\n            }\\n\\n            if (gcd != 1) return 0; // No inverse exists.\\n            return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.\\n        }\\n    }\\n\\n    /**\\n     * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.\\n     *\\n     * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is\\n     * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that\\n     * `a**(p-2)` is the modular multiplicative inverse of a in Fp.\\n     *\\n     * NOTE: this function does NOT check that `p` is a prime greater than `2`.\\n     */\\n    function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {\\n        unchecked {\\n            return Math.modExp(a, p - 2, p);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)\\n     *\\n     * Requirements:\\n     * - modulus can't be zero\\n     * - underlying staticcall to precompile must succeed\\n     *\\n     * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make\\n     * sure the chain you're using it on supports the precompiled contract for modular exponentiation\\n     * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,\\n     * the underlying function will succeed given the lack of a revert, but the result may be incorrectly\\n     * interpreted as 0.\\n     */\\n    function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {\\n        (bool success, uint256 result) = tryModExp(b, e, m);\\n        if (!success) {\\n            Panic.panic(Panic.DIVISION_BY_ZERO);\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).\\n     * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying\\n     * to operate modulo 0 or if the underlying precompile reverted.\\n     *\\n     * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain\\n     * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in\\n     * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack\\n     * of a revert, but the result may be incorrectly interpreted as 0.\\n     */\\n    function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {\\n        if (m == 0) return (false, 0);\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            let ptr := mload(0x40)\\n            // | Offset    | Content    | Content (Hex)                                                      |\\n            // |-----------|------------|--------------------------------------------------------------------|\\n            // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\\n            // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\\n            // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\\n            // | 0x60:0x7f | value of b | 0x<.............................................................b> |\\n            // | 0x80:0x9f | value of e | 0x<.............................................................e> |\\n            // | 0xa0:0xbf | value of m | 0x<.............................................................m> |\\n            mstore(ptr, 0x20)\\n            mstore(add(ptr, 0x20), 0x20)\\n            mstore(add(ptr, 0x40), 0x20)\\n            mstore(add(ptr, 0x60), b)\\n            mstore(add(ptr, 0x80), e)\\n            mstore(add(ptr, 0xa0), m)\\n\\n            // Given the result < m, it's guaranteed to fit in 32 bytes,\\n            // so we can use the memory scratch space located at offset 0.\\n            success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)\\n            result := mload(0x00)\\n        }\\n    }\\n\\n    /**\\n     * @dev Variant of {modExp} that supports inputs of arbitrary length.\\n     */\\n    function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {\\n        (bool success, bytes memory result) = tryModExp(b, e, m);\\n        if (!success) {\\n            Panic.panic(Panic.DIVISION_BY_ZERO);\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Variant of {tryModExp} that supports inputs of arbitrary length.\\n     */\\n    function tryModExp(\\n        bytes memory b,\\n        bytes memory e,\\n        bytes memory m\\n    ) internal view returns (bool success, bytes memory result) {\\n        if (_zeroBytes(m)) return (false, new bytes(0));\\n\\n        uint256 mLen = m.length;\\n\\n        // Encode call args in result and move the free memory pointer\\n        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);\\n\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            let dataPtr := add(result, 0x20)\\n            // Write result on top of args to avoid allocating extra memory.\\n            success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)\\n            // Overwrite the length.\\n            // result.length > returndatasize() is guaranteed because returndatasize() == m.length\\n            mstore(result, mLen)\\n            // Set the memory pointer after the returned data.\\n            mstore(0x40, add(dataPtr, mLen))\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns whether the provided byte array is zero.\\n     */\\n    function _zeroBytes(bytes memory byteArray) private pure returns (bool) {\\n        for (uint256 i = 0; i < byteArray.length; ++i) {\\n            if (byteArray[i] != 0) {\\n                return false;\\n            }\\n        }\\n        return true;\\n    }\\n\\n    /**\\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\\n     * towards zero.\\n     *\\n     * This method is based on Newton's method for computing square roots; the algorithm is restricted to only\\n     * using integer operations.\\n     */\\n    function sqrt(uint256 a) internal pure returns (uint256) {\\n        unchecked {\\n            // Take care of easy edge cases when a == 0 or a == 1\\n            if (a <= 1) {\\n                return a;\\n            }\\n\\n            // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a\\n            // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between\\n            // the current value as `ε_n = | x_n - sqrt(a) |`.\\n            //\\n            // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root\\n            // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is\\n            // bigger than any uint256.\\n            //\\n            // By noticing that\\n            // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`\\n            // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar\\n            // to the msb function.\\n            uint256 aa = a;\\n            uint256 xn = 1;\\n\\n            if (aa >= (1 << 128)) {\\n                aa >>= 128;\\n                xn <<= 64;\\n            }\\n            if (aa >= (1 << 64)) {\\n                aa >>= 64;\\n                xn <<= 32;\\n            }\\n            if (aa >= (1 << 32)) {\\n                aa >>= 32;\\n                xn <<= 16;\\n            }\\n            if (aa >= (1 << 16)) {\\n                aa >>= 16;\\n                xn <<= 8;\\n            }\\n            if (aa >= (1 << 8)) {\\n                aa >>= 8;\\n                xn <<= 4;\\n            }\\n            if (aa >= (1 << 4)) {\\n                aa >>= 4;\\n                xn <<= 2;\\n            }\\n            if (aa >= (1 << 2)) {\\n                xn <<= 1;\\n            }\\n\\n            // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).\\n            //\\n            // We can refine our estimation by noticing that the middle of that interval minimizes the error.\\n            // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).\\n            // This is going to be our x_0 (and ε_0)\\n            xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)\\n\\n            // From here, Newton's method give us:\\n            // x_{n+1} = (x_n + a / x_n) / 2\\n            //\\n            // One should note that:\\n            // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a\\n            //              = ((x_n² + a) / (2 * x_n))² - a\\n            //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a\\n            //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)\\n            //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)\\n            //              = (x_n² - a)² / (2 * x_n)²\\n            //              = ((x_n² - a) / (2 * x_n))²\\n            //              ≥ 0\\n            // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n\\n            //\\n            // This gives us the proof of quadratic convergence of the sequence:\\n            // ε_{n+1} = | x_{n+1} - sqrt(a) |\\n            //         = | (x_n + a / x_n) / 2 - sqrt(a) |\\n            //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |\\n            //         = | (x_n - sqrt(a))² / (2 * x_n) |\\n            //         = | ε_n² / (2 * x_n) |\\n            //         = ε_n² / | (2 * x_n) |\\n            //\\n            // For the first iteration, we have a special case where x_0 is known:\\n            // ε_1 = ε_0² / | (2 * x_0) |\\n            //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))\\n            //     ≤ 2**(2*e-4) / (3 * 2**(e-1))\\n            //     ≤ 2**(e-3) / 3\\n            //     ≤ 2**(e-3-log2(3))\\n            //     ≤ 2**(e-4.5)\\n            //\\n            // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:\\n            // ε_{n+1} = ε_n² / | (2 * x_n) |\\n            //         ≤ (2**(e-k))² / (2 * 2**(e-1))\\n            //         ≤ 2**(2*e-2*k) / 2**e\\n            //         ≤ 2**(e-2*k)\\n            xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above\\n            xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5\\n            xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9\\n            xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18\\n            xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36\\n            xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72\\n\\n            // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision\\n            // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either\\n            // sqrt(a) or sqrt(a) + 1.\\n            return xn - SafeCast.toUint(xn > a / xn);\\n        }\\n    }\\n\\n    /**\\n     * @dev Calculates sqrt(a), following the selected rounding direction.\\n     */\\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n        unchecked {\\n            uint256 result = sqrt(a);\\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);\\n        }\\n    }\\n\\n    /**\\n     * @dev Return the log in base 2 of a positive value rounded towards zero.\\n     * Returns 0 if given 0.\\n     */\\n    function log2(uint256 value) internal pure returns (uint256) {\\n        uint256 result = 0;\\n        uint256 exp;\\n        unchecked {\\n            exp = 128 * SafeCast.toUint(value > (1 << 128) - 1);\\n            value >>= exp;\\n            result += exp;\\n\\n            exp = 64 * SafeCast.toUint(value > (1 << 64) - 1);\\n            value >>= exp;\\n            result += exp;\\n\\n            exp = 32 * SafeCast.toUint(value > (1 << 32) - 1);\\n            value >>= exp;\\n            result += exp;\\n\\n            exp = 16 * SafeCast.toUint(value > (1 << 16) - 1);\\n            value >>= exp;\\n            result += exp;\\n\\n            exp = 8 * SafeCast.toUint(value > (1 << 8) - 1);\\n            value >>= exp;\\n            result += exp;\\n\\n            exp = 4 * SafeCast.toUint(value > (1 << 4) - 1);\\n            value >>= exp;\\n            result += exp;\\n\\n            exp = 2 * SafeCast.toUint(value > (1 << 2) - 1);\\n            value >>= exp;\\n            result += exp;\\n\\n            result += SafeCast.toUint(value > 1);\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n        unchecked {\\n            uint256 result = log2(value);\\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Return the log in base 10 of a positive value rounded towards zero.\\n     * Returns 0 if given 0.\\n     */\\n    function log10(uint256 value) internal pure returns (uint256) {\\n        uint256 result = 0;\\n        unchecked {\\n            if (value >= 10 ** 64) {\\n                value /= 10 ** 64;\\n                result += 64;\\n            }\\n            if (value >= 10 ** 32) {\\n                value /= 10 ** 32;\\n                result += 32;\\n            }\\n            if (value >= 10 ** 16) {\\n                value /= 10 ** 16;\\n                result += 16;\\n            }\\n            if (value >= 10 ** 8) {\\n                value /= 10 ** 8;\\n                result += 8;\\n            }\\n            if (value >= 10 ** 4) {\\n                value /= 10 ** 4;\\n                result += 4;\\n            }\\n            if (value >= 10 ** 2) {\\n                value /= 10 ** 2;\\n                result += 2;\\n            }\\n            if (value >= 10 ** 1) {\\n                result += 1;\\n            }\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n        unchecked {\\n            uint256 result = log10(value);\\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Return the log in base 256 of a positive value rounded towards zero.\\n     * Returns 0 if given 0.\\n     *\\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n     */\\n    function log256(uint256 value) internal pure returns (uint256) {\\n        uint256 result = 0;\\n        uint256 isGt;\\n        unchecked {\\n            isGt = SafeCast.toUint(value > (1 << 128) - 1);\\n            value >>= isGt * 128;\\n            result += isGt * 16;\\n\\n            isGt = SafeCast.toUint(value > (1 << 64) - 1);\\n            value >>= isGt * 64;\\n            result += isGt * 8;\\n\\n            isGt = SafeCast.toUint(value > (1 << 32) - 1);\\n            value >>= isGt * 32;\\n            result += isGt * 4;\\n\\n            isGt = SafeCast.toUint(value > (1 << 16) - 1);\\n            value >>= isGt * 16;\\n            result += isGt * 2;\\n\\n            result += SafeCast.toUint(value > (1 << 8) - 1);\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n        unchecked {\\n            uint256 result = log256(value);\\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\\n     */\\n    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\\n        return uint8(rounding) % 2 == 1;\\n    }\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeCast {\\n    /**\\n     * @dev Value doesn't fit in an uint of `bits` size.\\n     */\\n    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\\n\\n    /**\\n     * @dev An int value doesn't fit in an uint of `bits` size.\\n     */\\n    error SafeCastOverflowedIntToUint(int256 value);\\n\\n    /**\\n     * @dev Value doesn't fit in an int of `bits` size.\\n     */\\n    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\\n\\n    /**\\n     * @dev An uint value doesn't fit in an int of `bits` size.\\n     */\\n    error SafeCastOverflowedUintToInt(uint256 value);\\n\\n    /**\\n     * @dev Returns the downcasted uint248 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint248).\\n     *\\n     * Counterpart to Solidity's `uint248` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 248 bits\\n     */\\n    function toUint248(uint256 value) internal pure returns (uint248) {\\n        if (value > type(uint248).max) {\\n            revert SafeCastOverflowedUintDowncast(248, value);\\n        }\\n        return uint248(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint240 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint240).\\n     *\\n     * Counterpart to Solidity's `uint240` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 240 bits\\n     */\\n    function toUint240(uint256 value) internal pure returns (uint240) {\\n        if (value > type(uint240).max) {\\n            revert SafeCastOverflowedUintDowncast(240, value);\\n        }\\n        return uint240(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint232 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint232).\\n     *\\n     * Counterpart to Solidity's `uint232` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 232 bits\\n     */\\n    function toUint232(uint256 value) internal pure returns (uint232) {\\n        if (value > type(uint232).max) {\\n            revert SafeCastOverflowedUintDowncast(232, value);\\n        }\\n        return uint232(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint224 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint224).\\n     *\\n     * Counterpart to Solidity's `uint224` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 224 bits\\n     */\\n    function toUint224(uint256 value) internal pure returns (uint224) {\\n        if (value > type(uint224).max) {\\n            revert SafeCastOverflowedUintDowncast(224, value);\\n        }\\n        return uint224(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint216 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint216).\\n     *\\n     * Counterpart to Solidity's `uint216` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 216 bits\\n     */\\n    function toUint216(uint256 value) internal pure returns (uint216) {\\n        if (value > type(uint216).max) {\\n            revert SafeCastOverflowedUintDowncast(216, value);\\n        }\\n        return uint216(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint208 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint208).\\n     *\\n     * Counterpart to Solidity's `uint208` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 208 bits\\n     */\\n    function toUint208(uint256 value) internal pure returns (uint208) {\\n        if (value > type(uint208).max) {\\n            revert SafeCastOverflowedUintDowncast(208, value);\\n        }\\n        return uint208(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint200 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint200).\\n     *\\n     * Counterpart to Solidity's `uint200` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 200 bits\\n     */\\n    function toUint200(uint256 value) internal pure returns (uint200) {\\n        if (value > type(uint200).max) {\\n            revert SafeCastOverflowedUintDowncast(200, value);\\n        }\\n        return uint200(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint192 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint192).\\n     *\\n     * Counterpart to Solidity's `uint192` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 192 bits\\n     */\\n    function toUint192(uint256 value) internal pure returns (uint192) {\\n        if (value > type(uint192).max) {\\n            revert SafeCastOverflowedUintDowncast(192, value);\\n        }\\n        return uint192(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint184 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint184).\\n     *\\n     * Counterpart to Solidity's `uint184` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 184 bits\\n     */\\n    function toUint184(uint256 value) internal pure returns (uint184) {\\n        if (value > type(uint184).max) {\\n            revert SafeCastOverflowedUintDowncast(184, value);\\n        }\\n        return uint184(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint176 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint176).\\n     *\\n     * Counterpart to Solidity's `uint176` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 176 bits\\n     */\\n    function toUint176(uint256 value) internal pure returns (uint176) {\\n        if (value > type(uint176).max) {\\n            revert SafeCastOverflowedUintDowncast(176, value);\\n        }\\n        return uint176(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint168 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint168).\\n     *\\n     * Counterpart to Solidity's `uint168` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 168 bits\\n     */\\n    function toUint168(uint256 value) internal pure returns (uint168) {\\n        if (value > type(uint168).max) {\\n            revert SafeCastOverflowedUintDowncast(168, value);\\n        }\\n        return uint168(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint160 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint160).\\n     *\\n     * Counterpart to Solidity's `uint160` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 160 bits\\n     */\\n    function toUint160(uint256 value) internal pure returns (uint160) {\\n        if (value > type(uint160).max) {\\n            revert SafeCastOverflowedUintDowncast(160, value);\\n        }\\n        return uint160(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint152 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint152).\\n     *\\n     * Counterpart to Solidity's `uint152` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 152 bits\\n     */\\n    function toUint152(uint256 value) internal pure returns (uint152) {\\n        if (value > type(uint152).max) {\\n            revert SafeCastOverflowedUintDowncast(152, value);\\n        }\\n        return uint152(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint144 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint144).\\n     *\\n     * Counterpart to Solidity's `uint144` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 144 bits\\n     */\\n    function toUint144(uint256 value) internal pure returns (uint144) {\\n        if (value > type(uint144).max) {\\n            revert SafeCastOverflowedUintDowncast(144, value);\\n        }\\n        return uint144(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint136 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint136).\\n     *\\n     * Counterpart to Solidity's `uint136` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 136 bits\\n     */\\n    function toUint136(uint256 value) internal pure returns (uint136) {\\n        if (value > type(uint136).max) {\\n            revert SafeCastOverflowedUintDowncast(136, value);\\n        }\\n        return uint136(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint128 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint128).\\n     *\\n     * Counterpart to Solidity's `uint128` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 128 bits\\n     */\\n    function toUint128(uint256 value) internal pure returns (uint128) {\\n        if (value > type(uint128).max) {\\n            revert SafeCastOverflowedUintDowncast(128, value);\\n        }\\n        return uint128(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint120 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint120).\\n     *\\n     * Counterpart to Solidity's `uint120` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 120 bits\\n     */\\n    function toUint120(uint256 value) internal pure returns (uint120) {\\n        if (value > type(uint120).max) {\\n            revert SafeCastOverflowedUintDowncast(120, value);\\n        }\\n        return uint120(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint112 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint112).\\n     *\\n     * Counterpart to Solidity's `uint112` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 112 bits\\n     */\\n    function toUint112(uint256 value) internal pure returns (uint112) {\\n        if (value > type(uint112).max) {\\n            revert SafeCastOverflowedUintDowncast(112, value);\\n        }\\n        return uint112(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint104 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint104).\\n     *\\n     * Counterpart to Solidity's `uint104` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 104 bits\\n     */\\n    function toUint104(uint256 value) internal pure returns (uint104) {\\n        if (value > type(uint104).max) {\\n            revert SafeCastOverflowedUintDowncast(104, value);\\n        }\\n        return uint104(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint96 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint96).\\n     *\\n     * Counterpart to Solidity's `uint96` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 96 bits\\n     */\\n    function toUint96(uint256 value) internal pure returns (uint96) {\\n        if (value > type(uint96).max) {\\n            revert SafeCastOverflowedUintDowncast(96, value);\\n        }\\n        return uint96(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint88 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint88).\\n     *\\n     * Counterpart to Solidity's `uint88` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 88 bits\\n     */\\n    function toUint88(uint256 value) internal pure returns (uint88) {\\n        if (value > type(uint88).max) {\\n            revert SafeCastOverflowedUintDowncast(88, value);\\n        }\\n        return uint88(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint80 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint80).\\n     *\\n     * Counterpart to Solidity's `uint80` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 80 bits\\n     */\\n    function toUint80(uint256 value) internal pure returns (uint80) {\\n        if (value > type(uint80).max) {\\n            revert SafeCastOverflowedUintDowncast(80, value);\\n        }\\n        return uint80(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint72 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint72).\\n     *\\n     * Counterpart to Solidity's `uint72` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 72 bits\\n     */\\n    function toUint72(uint256 value) internal pure returns (uint72) {\\n        if (value > type(uint72).max) {\\n            revert SafeCastOverflowedUintDowncast(72, value);\\n        }\\n        return uint72(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint64 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint64).\\n     *\\n     * Counterpart to Solidity's `uint64` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 64 bits\\n     */\\n    function toUint64(uint256 value) internal pure returns (uint64) {\\n        if (value > type(uint64).max) {\\n            revert SafeCastOverflowedUintDowncast(64, value);\\n        }\\n        return uint64(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint56 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint56).\\n     *\\n     * Counterpart to Solidity's `uint56` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 56 bits\\n     */\\n    function toUint56(uint256 value) internal pure returns (uint56) {\\n        if (value > type(uint56).max) {\\n            revert SafeCastOverflowedUintDowncast(56, value);\\n        }\\n        return uint56(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint48 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint48).\\n     *\\n     * Counterpart to Solidity's `uint48` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 48 bits\\n     */\\n    function toUint48(uint256 value) internal pure returns (uint48) {\\n        if (value > type(uint48).max) {\\n            revert SafeCastOverflowedUintDowncast(48, value);\\n        }\\n        return uint48(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint40 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint40).\\n     *\\n     * Counterpart to Solidity's `uint40` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 40 bits\\n     */\\n    function toUint40(uint256 value) internal pure returns (uint40) {\\n        if (value > type(uint40).max) {\\n            revert SafeCastOverflowedUintDowncast(40, value);\\n        }\\n        return uint40(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint32 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint32).\\n     *\\n     * Counterpart to Solidity's `uint32` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 32 bits\\n     */\\n    function toUint32(uint256 value) internal pure returns (uint32) {\\n        if (value > type(uint32).max) {\\n            revert SafeCastOverflowedUintDowncast(32, value);\\n        }\\n        return uint32(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint24 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint24).\\n     *\\n     * Counterpart to Solidity's `uint24` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 24 bits\\n     */\\n    function toUint24(uint256 value) internal pure returns (uint24) {\\n        if (value > type(uint24).max) {\\n            revert SafeCastOverflowedUintDowncast(24, value);\\n        }\\n        return uint24(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint16 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint16).\\n     *\\n     * Counterpart to Solidity's `uint16` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 16 bits\\n     */\\n    function toUint16(uint256 value) internal pure returns (uint16) {\\n        if (value > type(uint16).max) {\\n            revert SafeCastOverflowedUintDowncast(16, value);\\n        }\\n        return uint16(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint8 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint8).\\n     *\\n     * Counterpart to Solidity's `uint8` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 8 bits\\n     */\\n    function toUint8(uint256 value) internal pure returns (uint8) {\\n        if (value > type(uint8).max) {\\n            revert SafeCastOverflowedUintDowncast(8, value);\\n        }\\n        return uint8(value);\\n    }\\n\\n    /**\\n     * @dev Converts a signed int256 into an unsigned uint256.\\n     *\\n     * Requirements:\\n     *\\n     * - input must be greater than or equal to 0.\\n     */\\n    function toUint256(int256 value) internal pure returns (uint256) {\\n        if (value < 0) {\\n            revert SafeCastOverflowedIntToUint(value);\\n        }\\n        return uint256(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int248 from int256, reverting on\\n     * overflow (when the input is less than smallest int248 or\\n     * greater than largest int248).\\n     *\\n     * Counterpart to Solidity's `int248` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 248 bits\\n     */\\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n        downcasted = int248(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(248, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int240 from int256, reverting on\\n     * overflow (when the input is less than smallest int240 or\\n     * greater than largest int240).\\n     *\\n     * Counterpart to Solidity's `int240` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 240 bits\\n     */\\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n        downcasted = int240(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(240, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int232 from int256, reverting on\\n     * overflow (when the input is less than smallest int232 or\\n     * greater than largest int232).\\n     *\\n     * Counterpart to Solidity's `int232` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 232 bits\\n     */\\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n        downcasted = int232(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(232, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int224 from int256, reverting on\\n     * overflow (when the input is less than smallest int224 or\\n     * greater than largest int224).\\n     *\\n     * Counterpart to Solidity's `int224` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 224 bits\\n     */\\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n        downcasted = int224(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(224, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int216 from int256, reverting on\\n     * overflow (when the input is less than smallest int216 or\\n     * greater than largest int216).\\n     *\\n     * Counterpart to Solidity's `int216` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 216 bits\\n     */\\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n        downcasted = int216(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(216, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int208 from int256, reverting on\\n     * overflow (when the input is less than smallest int208 or\\n     * greater than largest int208).\\n     *\\n     * Counterpart to Solidity's `int208` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 208 bits\\n     */\\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n        downcasted = int208(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(208, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int200 from int256, reverting on\\n     * overflow (when the input is less than smallest int200 or\\n     * greater than largest int200).\\n     *\\n     * Counterpart to Solidity's `int200` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 200 bits\\n     */\\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n        downcasted = int200(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(200, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int192 from int256, reverting on\\n     * overflow (when the input is less than smallest int192 or\\n     * greater than largest int192).\\n     *\\n     * Counterpart to Solidity's `int192` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 192 bits\\n     */\\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n        downcasted = int192(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(192, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int184 from int256, reverting on\\n     * overflow (when the input is less than smallest int184 or\\n     * greater than largest int184).\\n     *\\n     * Counterpart to Solidity's `int184` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 184 bits\\n     */\\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n        downcasted = int184(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(184, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int176 from int256, reverting on\\n     * overflow (when the input is less than smallest int176 or\\n     * greater than largest int176).\\n     *\\n     * Counterpart to Solidity's `int176` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 176 bits\\n     */\\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n        downcasted = int176(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(176, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int168 from int256, reverting on\\n     * overflow (when the input is less than smallest int168 or\\n     * greater than largest int168).\\n     *\\n     * Counterpart to Solidity's `int168` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 168 bits\\n     */\\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n        downcasted = int168(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(168, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int160 from int256, reverting on\\n     * overflow (when the input is less than smallest int160 or\\n     * greater than largest int160).\\n     *\\n     * Counterpart to Solidity's `int160` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 160 bits\\n     */\\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n        downcasted = int160(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(160, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int152 from int256, reverting on\\n     * overflow (when the input is less than smallest int152 or\\n     * greater than largest int152).\\n     *\\n     * Counterpart to Solidity's `int152` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 152 bits\\n     */\\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n        downcasted = int152(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(152, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int144 from int256, reverting on\\n     * overflow (when the input is less than smallest int144 or\\n     * greater than largest int144).\\n     *\\n     * Counterpart to Solidity's `int144` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 144 bits\\n     */\\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n        downcasted = int144(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(144, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int136 from int256, reverting on\\n     * overflow (when the input is less than smallest int136 or\\n     * greater than largest int136).\\n     *\\n     * Counterpart to Solidity's `int136` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 136 bits\\n     */\\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n        downcasted = int136(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(136, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int128 from int256, reverting on\\n     * overflow (when the input is less than smallest int128 or\\n     * greater than largest int128).\\n     *\\n     * Counterpart to Solidity's `int128` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 128 bits\\n     */\\n    function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n        downcasted = int128(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(128, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int120 from int256, reverting on\\n     * overflow (when the input is less than smallest int120 or\\n     * greater than largest int120).\\n     *\\n     * Counterpart to Solidity's `int120` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 120 bits\\n     */\\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n        downcasted = int120(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(120, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int112 from int256, reverting on\\n     * overflow (when the input is less than smallest int112 or\\n     * greater than largest int112).\\n     *\\n     * Counterpart to Solidity's `int112` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 112 bits\\n     */\\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n        downcasted = int112(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(112, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int104 from int256, reverting on\\n     * overflow (when the input is less than smallest int104 or\\n     * greater than largest int104).\\n     *\\n     * Counterpart to Solidity's `int104` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 104 bits\\n     */\\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n        downcasted = int104(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(104, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int96 from int256, reverting on\\n     * overflow (when the input is less than smallest int96 or\\n     * greater than largest int96).\\n     *\\n     * Counterpart to Solidity's `int96` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 96 bits\\n     */\\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n        downcasted = int96(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(96, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int88 from int256, reverting on\\n     * overflow (when the input is less than smallest int88 or\\n     * greater than largest int88).\\n     *\\n     * Counterpart to Solidity's `int88` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 88 bits\\n     */\\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n        downcasted = int88(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(88, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int80 from int256, reverting on\\n     * overflow (when the input is less than smallest int80 or\\n     * greater than largest int80).\\n     *\\n     * Counterpart to Solidity's `int80` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 80 bits\\n     */\\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n        downcasted = int80(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(80, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int72 from int256, reverting on\\n     * overflow (when the input is less than smallest int72 or\\n     * greater than largest int72).\\n     *\\n     * Counterpart to Solidity's `int72` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 72 bits\\n     */\\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n        downcasted = int72(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(72, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int64 from int256, reverting on\\n     * overflow (when the input is less than smallest int64 or\\n     * greater than largest int64).\\n     *\\n     * Counterpart to Solidity's `int64` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 64 bits\\n     */\\n    function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n        downcasted = int64(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(64, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int56 from int256, reverting on\\n     * overflow (when the input is less than smallest int56 or\\n     * greater than largest int56).\\n     *\\n     * Counterpart to Solidity's `int56` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 56 bits\\n     */\\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n        downcasted = int56(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(56, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int48 from int256, reverting on\\n     * overflow (when the input is less than smallest int48 or\\n     * greater than largest int48).\\n     *\\n     * Counterpart to Solidity's `int48` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 48 bits\\n     */\\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n        downcasted = int48(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(48, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int40 from int256, reverting on\\n     * overflow (when the input is less than smallest int40 or\\n     * greater than largest int40).\\n     *\\n     * Counterpart to Solidity's `int40` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 40 bits\\n     */\\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n        downcasted = int40(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(40, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int32 from int256, reverting on\\n     * overflow (when the input is less than smallest int32 or\\n     * greater than largest int32).\\n     *\\n     * Counterpart to Solidity's `int32` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 32 bits\\n     */\\n    function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n        downcasted = int32(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(32, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int24 from int256, reverting on\\n     * overflow (when the input is less than smallest int24 or\\n     * greater than largest int24).\\n     *\\n     * Counterpart to Solidity's `int24` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 24 bits\\n     */\\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n        downcasted = int24(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(24, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int16 from int256, reverting on\\n     * overflow (when the input is less than smallest int16 or\\n     * greater than largest int16).\\n     *\\n     * Counterpart to Solidity's `int16` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 16 bits\\n     */\\n    function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n        downcasted = int16(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(16, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int8 from int256, reverting on\\n     * overflow (when the input is less than smallest int8 or\\n     * greater than largest int8).\\n     *\\n     * Counterpart to Solidity's `int8` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 8 bits\\n     */\\n    function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n        downcasted = int8(value);\\n        if (downcasted != value) {\\n            revert SafeCastOverflowedIntDowncast(8, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Converts an unsigned uint256 into a signed int256.\\n     *\\n     * Requirements:\\n     *\\n     * - input must be less than or equal to maxInt256.\\n     */\\n    function toInt256(uint256 value) internal pure returns (int256) {\\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n        if (value > uint256(type(int256).max)) {\\n            revert SafeCastOverflowedUintToInt(value);\\n        }\\n        return int256(value);\\n    }\\n\\n    /**\\n     * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\\n     */\\n    function toUint(bool b) internal pure returns (uint256 u) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            u := iszero(iszero(b))\\n        }\\n    }\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/structs/DoubleEndedQueue.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/DoubleEndedQueue.sol)\\npragma solidity ^0.8.20;\\n\\nimport {Panic} from \\\"../Panic.sol\\\";\\n\\n/**\\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\\n * the existing queue contents are left in storage.\\n *\\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\\n * used in storage, and not in memory.\\n * ```solidity\\n * DoubleEndedQueue.Bytes32Deque queue;\\n * ```\\n */\\nlibrary DoubleEndedQueue {\\n    /**\\n     * @dev Indices are 128 bits so begin and end are packed in a single storage slot for efficient access.\\n     *\\n     * Struct members have an underscore prefix indicating that they are \\\"private\\\" and should not be read or written to\\n     * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\\n     * lead to unexpected behavior.\\n     *\\n     * The first item is at data[begin] and the last item is at data[end - 1]. This range can wrap around.\\n     */\\n    struct Bytes32Deque {\\n        uint128 _begin;\\n        uint128 _end;\\n        mapping(uint128 index => bytes32) _data;\\n    }\\n\\n    /**\\n     * @dev Inserts an item at the end of the queue.\\n     *\\n     * Reverts with {Panic-RESOURCE_ERROR} if the queue is full.\\n     */\\n    function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\\n        unchecked {\\n            uint128 backIndex = deque._end;\\n            if (backIndex + 1 == deque._begin) Panic.panic(Panic.RESOURCE_ERROR);\\n            deque._data[backIndex] = value;\\n            deque._end = backIndex + 1;\\n        }\\n    }\\n\\n    /**\\n     * @dev Removes the item at the end of the queue and returns it.\\n     *\\n     * Reverts with {Panic-EMPTY_ARRAY_POP} if the queue is empty.\\n     */\\n    function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\\n        unchecked {\\n            uint128 backIndex = deque._end;\\n            if (backIndex == deque._begin) Panic.panic(Panic.EMPTY_ARRAY_POP);\\n            --backIndex;\\n            value = deque._data[backIndex];\\n            delete deque._data[backIndex];\\n            deque._end = backIndex;\\n        }\\n    }\\n\\n    /**\\n     * @dev Inserts an item at the beginning of the queue.\\n     *\\n     * Reverts with {Panic-RESOURCE_ERROR} if the queue is full.\\n     */\\n    function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\\n        unchecked {\\n            uint128 frontIndex = deque._begin - 1;\\n            if (frontIndex == deque._end) Panic.panic(Panic.RESOURCE_ERROR);\\n            deque._data[frontIndex] = value;\\n            deque._begin = frontIndex;\\n        }\\n    }\\n\\n    /**\\n     * @dev Removes the item at the beginning of the queue and returns it.\\n     *\\n     * Reverts with {Panic-EMPTY_ARRAY_POP} if the queue is empty.\\n     */\\n    function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\\n        unchecked {\\n            uint128 frontIndex = deque._begin;\\n            if (frontIndex == deque._end) Panic.panic(Panic.EMPTY_ARRAY_POP);\\n            value = deque._data[frontIndex];\\n            delete deque._data[frontIndex];\\n            deque._begin = frontIndex + 1;\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the item at the beginning of the queue.\\n     *\\n     * Reverts with {Panic-ARRAY_OUT_OF_BOUNDS} if the queue is empty.\\n     */\\n    function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\\n        if (empty(deque)) Panic.panic(Panic.ARRAY_OUT_OF_BOUNDS);\\n        return deque._data[deque._begin];\\n    }\\n\\n    /**\\n     * @dev Returns the item at the end of the queue.\\n     *\\n     * Reverts with {Panic-ARRAY_OUT_OF_BOUNDS} if the queue is empty.\\n     */\\n    function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\\n        if (empty(deque)) Panic.panic(Panic.ARRAY_OUT_OF_BOUNDS);\\n        unchecked {\\n            return deque._data[deque._end - 1];\\n        }\\n    }\\n\\n    /**\\n     * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\\n     * `length(deque) - 1`.\\n     *\\n     * Reverts with {Panic-ARRAY_OUT_OF_BOUNDS} if the index is out of bounds.\\n     */\\n    function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\\n        if (index >= length(deque)) Panic.panic(Panic.ARRAY_OUT_OF_BOUNDS);\\n        // By construction, length is a uint128, so the check above ensures that index can be safely downcast to uint128\\n        unchecked {\\n            return deque._data[deque._begin + uint128(index)];\\n        }\\n    }\\n\\n    /**\\n     * @dev Resets the queue back to being empty.\\n     *\\n     * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\\n     * out on potential gas refunds.\\n     */\\n    function clear(Bytes32Deque storage deque) internal {\\n        deque._begin = 0;\\n        deque._end = 0;\\n    }\\n\\n    /**\\n     * @dev Returns the number of items in the queue.\\n     */\\n    function length(Bytes32Deque storage deque) internal view returns (uint256) {\\n        unchecked {\\n            return uint256(deque._end - deque._begin);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns true if the queue is empty.\\n     */\\n    function empty(Bytes32Deque storage deque) internal view returns (bool) {\\n        return deque._end == deque._begin;\\n    }\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableMap.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableMap.js.\\n\\npragma solidity ^0.8.20;\\n\\nimport {EnumerableSet} from \\\"./EnumerableSet.sol\\\";\\n\\n/**\\n * @dev Library for managing an enumerable variant of Solidity's\\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\\n * type.\\n *\\n * Maps have the following properties:\\n *\\n * - Entries are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n *     // Add the library methods\\n *     using EnumerableMap for EnumerableMap.UintToAddressMap;\\n *\\n *     // Declare a set state variable\\n *     EnumerableMap.UintToAddressMap private myMap;\\n * }\\n * ```\\n *\\n * The following map types are supported:\\n *\\n * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0\\n * - `address -> uint256` (`AddressToUintMap`) since v4.6.0\\n * - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0\\n * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0\\n * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0\\n * - `uint256 -> bytes32` (`UintToBytes32Map`) since v5.1.0\\n * - `address -> address` (`AddressToAddressMap`) since v5.1.0\\n * - `address -> bytes32` (`AddressToBytes32Map`) since v5.1.0\\n * - `bytes32 -> address` (`Bytes32ToAddressMap`) since v5.1.0\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableMap.\\n * ====\\n */\\nlibrary EnumerableMap {\\n    using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n    // To implement this library for multiple types with as little code repetition as possible, we write it in\\n    // terms of a generic Map type with bytes32 keys and values. The Map implementation uses private functions,\\n    // and user-facing implementations such as `UintToAddressMap` are just wrappers around the underlying Map.\\n    // This means that we can only create new EnumerableMaps for types that fit in bytes32.\\n\\n    /**\\n     * @dev Query for a nonexistent map key.\\n     */\\n    error EnumerableMapNonexistentKey(bytes32 key);\\n\\n    struct Bytes32ToBytes32Map {\\n        // Storage of keys\\n        EnumerableSet.Bytes32Set _keys;\\n        mapping(bytes32 key => bytes32) _values;\\n    }\\n\\n    /**\\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\\n     * key. O(1).\\n     *\\n     * Returns true if the key was added to the map, that is if it was not\\n     * already present.\\n     */\\n    function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value) internal returns (bool) {\\n        map._values[key] = value;\\n        return map._keys.add(key);\\n    }\\n\\n    /**\\n     * @dev Removes a key-value pair from a map. O(1).\\n     *\\n     * Returns true if the key was removed from the map, that is if it was present.\\n     */\\n    function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) {\\n        delete map._values[key];\\n        return map._keys.remove(key);\\n    }\\n\\n    /**\\n     * @dev Returns true if the key is in the map. O(1).\\n     */\\n    function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) {\\n        return map._keys.contains(key);\\n    }\\n\\n    /**\\n     * @dev Returns the number of key-value pairs in the map. O(1).\\n     */\\n    function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) {\\n        return map._keys.length();\\n    }\\n\\n    /**\\n     * @dev Returns the key-value pair stored at position `index` in the map. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of entries inside the\\n     * array, and it may change when more entries are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) {\\n        bytes32 key = map._keys.at(index);\\n        return (key, map._values[key]);\\n    }\\n\\n    /**\\n     * @dev Tries to returns the value associated with `key`. O(1).\\n     * Does not revert if `key` is not in the map.\\n     */\\n    function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) {\\n        bytes32 value = map._values[key];\\n        if (value == bytes32(0)) {\\n            return (contains(map, key), bytes32(0));\\n        } else {\\n            return (true, value);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the value associated with `key`. O(1).\\n     *\\n     * Requirements:\\n     *\\n     * - `key` must be in the map.\\n     */\\n    function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) {\\n        bytes32 value = map._values[key];\\n        if (value == 0 && !contains(map, key)) {\\n            revert EnumerableMapNonexistentKey(key);\\n        }\\n        return value;\\n    }\\n\\n    /**\\n     * @dev Return the an array containing all the keys\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) {\\n        return map._keys.values();\\n    }\\n\\n    // UintToUintMap\\n\\n    struct UintToUintMap {\\n        Bytes32ToBytes32Map _inner;\\n    }\\n\\n    /**\\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\\n     * key. O(1).\\n     *\\n     * Returns true if the key was added to the map, that is if it was not\\n     * already present.\\n     */\\n    function set(UintToUintMap storage map, uint256 key, uint256 value) internal returns (bool) {\\n        return set(map._inner, bytes32(key), bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a map. O(1).\\n     *\\n     * Returns true if the key was removed from the map, that is if it was present.\\n     */\\n    function remove(UintToUintMap storage map, uint256 key) internal returns (bool) {\\n        return remove(map._inner, bytes32(key));\\n    }\\n\\n    /**\\n     * @dev Returns true if the key is in the map. O(1).\\n     */\\n    function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) {\\n        return contains(map._inner, bytes32(key));\\n    }\\n\\n    /**\\n     * @dev Returns the number of elements in the map. O(1).\\n     */\\n    function length(UintToUintMap storage map) internal view returns (uint256) {\\n        return length(map._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the element stored at position `index` in the map. O(1).\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) {\\n        (bytes32 key, bytes32 value) = at(map._inner, index);\\n        return (uint256(key), uint256(value));\\n    }\\n\\n    /**\\n     * @dev Tries to returns the value associated with `key`. O(1).\\n     * Does not revert if `key` is not in the map.\\n     */\\n    function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) {\\n        (bool success, bytes32 value) = tryGet(map._inner, bytes32(key));\\n        return (success, uint256(value));\\n    }\\n\\n    /**\\n     * @dev Returns the value associated with `key`. O(1).\\n     *\\n     * Requirements:\\n     *\\n     * - `key` must be in the map.\\n     */\\n    function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) {\\n        return uint256(get(map._inner, bytes32(key)));\\n    }\\n\\n    /**\\n     * @dev Return the an array containing all the keys\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function keys(UintToUintMap storage map) internal view returns (uint256[] memory) {\\n        bytes32[] memory store = keys(map._inner);\\n        uint256[] memory result;\\n\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n\\n    // UintToAddressMap\\n\\n    struct UintToAddressMap {\\n        Bytes32ToBytes32Map _inner;\\n    }\\n\\n    /**\\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\\n     * key. O(1).\\n     *\\n     * Returns true if the key was added to the map, that is if it was not\\n     * already present.\\n     */\\n    function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\\n        return set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a map. O(1).\\n     *\\n     * Returns true if the key was removed from the map, that is if it was present.\\n     */\\n    function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\\n        return remove(map._inner, bytes32(key));\\n    }\\n\\n    /**\\n     * @dev Returns true if the key is in the map. O(1).\\n     */\\n    function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\\n        return contains(map._inner, bytes32(key));\\n    }\\n\\n    /**\\n     * @dev Returns the number of elements in the map. O(1).\\n     */\\n    function length(UintToAddressMap storage map) internal view returns (uint256) {\\n        return length(map._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the element stored at position `index` in the map. O(1).\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\\n        (bytes32 key, bytes32 value) = at(map._inner, index);\\n        return (uint256(key), address(uint160(uint256(value))));\\n    }\\n\\n    /**\\n     * @dev Tries to returns the value associated with `key`. O(1).\\n     * Does not revert if `key` is not in the map.\\n     */\\n    function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\\n        (bool success, bytes32 value) = tryGet(map._inner, bytes32(key));\\n        return (success, address(uint160(uint256(value))));\\n    }\\n\\n    /**\\n     * @dev Returns the value associated with `key`. O(1).\\n     *\\n     * Requirements:\\n     *\\n     * - `key` must be in the map.\\n     */\\n    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\\n        return address(uint160(uint256(get(map._inner, bytes32(key)))));\\n    }\\n\\n    /**\\n     * @dev Return the an array containing all the keys\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function keys(UintToAddressMap storage map) internal view returns (uint256[] memory) {\\n        bytes32[] memory store = keys(map._inner);\\n        uint256[] memory result;\\n\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n\\n    // UintToBytes32Map\\n\\n    struct UintToBytes32Map {\\n        Bytes32ToBytes32Map _inner;\\n    }\\n\\n    /**\\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\\n     * key. O(1).\\n     *\\n     * Returns true if the key was added to the map, that is if it was not\\n     * already present.\\n     */\\n    function set(UintToBytes32Map storage map, uint256 key, bytes32 value) internal returns (bool) {\\n        return set(map._inner, bytes32(key), value);\\n    }\\n\\n    /**\\n     * @dev Removes a value from a map. O(1).\\n     *\\n     * Returns true if the key was removed from the map, that is if it was present.\\n     */\\n    function remove(UintToBytes32Map storage map, uint256 key) internal returns (bool) {\\n        return remove(map._inner, bytes32(key));\\n    }\\n\\n    /**\\n     * @dev Returns true if the key is in the map. O(1).\\n     */\\n    function contains(UintToBytes32Map storage map, uint256 key) internal view returns (bool) {\\n        return contains(map._inner, bytes32(key));\\n    }\\n\\n    /**\\n     * @dev Returns the number of elements in the map. O(1).\\n     */\\n    function length(UintToBytes32Map storage map) internal view returns (uint256) {\\n        return length(map._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the element stored at position `index` in the map. O(1).\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(UintToBytes32Map storage map, uint256 index) internal view returns (uint256, bytes32) {\\n        (bytes32 key, bytes32 value) = at(map._inner, index);\\n        return (uint256(key), value);\\n    }\\n\\n    /**\\n     * @dev Tries to returns the value associated with `key`. O(1).\\n     * Does not revert if `key` is not in the map.\\n     */\\n    function tryGet(UintToBytes32Map storage map, uint256 key) internal view returns (bool, bytes32) {\\n        (bool success, bytes32 value) = tryGet(map._inner, bytes32(key));\\n        return (success, value);\\n    }\\n\\n    /**\\n     * @dev Returns the value associated with `key`. O(1).\\n     *\\n     * Requirements:\\n     *\\n     * - `key` must be in the map.\\n     */\\n    function get(UintToBytes32Map storage map, uint256 key) internal view returns (bytes32) {\\n        return get(map._inner, bytes32(key));\\n    }\\n\\n    /**\\n     * @dev Return the an array containing all the keys\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function keys(UintToBytes32Map storage map) internal view returns (uint256[] memory) {\\n        bytes32[] memory store = keys(map._inner);\\n        uint256[] memory result;\\n\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n\\n    // AddressToUintMap\\n\\n    struct AddressToUintMap {\\n        Bytes32ToBytes32Map _inner;\\n    }\\n\\n    /**\\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\\n     * key. O(1).\\n     *\\n     * Returns true if the key was added to the map, that is if it was not\\n     * already present.\\n     */\\n    function set(AddressToUintMap storage map, address key, uint256 value) internal returns (bool) {\\n        return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a map. O(1).\\n     *\\n     * Returns true if the key was removed from the map, that is if it was present.\\n     */\\n    function remove(AddressToUintMap storage map, address key) internal returns (bool) {\\n        return remove(map._inner, bytes32(uint256(uint160(key))));\\n    }\\n\\n    /**\\n     * @dev Returns true if the key is in the map. O(1).\\n     */\\n    function contains(AddressToUintMap storage map, address key) internal view returns (bool) {\\n        return contains(map._inner, bytes32(uint256(uint160(key))));\\n    }\\n\\n    /**\\n     * @dev Returns the number of elements in the map. O(1).\\n     */\\n    function length(AddressToUintMap storage map) internal view returns (uint256) {\\n        return length(map._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the element stored at position `index` in the map. O(1).\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) {\\n        (bytes32 key, bytes32 value) = at(map._inner, index);\\n        return (address(uint160(uint256(key))), uint256(value));\\n    }\\n\\n    /**\\n     * @dev Tries to returns the value associated with `key`. O(1).\\n     * Does not revert if `key` is not in the map.\\n     */\\n    function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) {\\n        (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key))));\\n        return (success, uint256(value));\\n    }\\n\\n    /**\\n     * @dev Returns the value associated with `key`. O(1).\\n     *\\n     * Requirements:\\n     *\\n     * - `key` must be in the map.\\n     */\\n    function get(AddressToUintMap storage map, address key) internal view returns (uint256) {\\n        return uint256(get(map._inner, bytes32(uint256(uint160(key)))));\\n    }\\n\\n    /**\\n     * @dev Return the an array containing all the keys\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function keys(AddressToUintMap storage map) internal view returns (address[] memory) {\\n        bytes32[] memory store = keys(map._inner);\\n        address[] memory result;\\n\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n\\n    // AddressToAddressMap\\n\\n    struct AddressToAddressMap {\\n        Bytes32ToBytes32Map _inner;\\n    }\\n\\n    /**\\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\\n     * key. O(1).\\n     *\\n     * Returns true if the key was added to the map, that is if it was not\\n     * already present.\\n     */\\n    function set(AddressToAddressMap storage map, address key, address value) internal returns (bool) {\\n        return set(map._inner, bytes32(uint256(uint160(key))), bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a map. O(1).\\n     *\\n     * Returns true if the key was removed from the map, that is if it was present.\\n     */\\n    function remove(AddressToAddressMap storage map, address key) internal returns (bool) {\\n        return remove(map._inner, bytes32(uint256(uint160(key))));\\n    }\\n\\n    /**\\n     * @dev Returns true if the key is in the map. O(1).\\n     */\\n    function contains(AddressToAddressMap storage map, address key) internal view returns (bool) {\\n        return contains(map._inner, bytes32(uint256(uint160(key))));\\n    }\\n\\n    /**\\n     * @dev Returns the number of elements in the map. O(1).\\n     */\\n    function length(AddressToAddressMap storage map) internal view returns (uint256) {\\n        return length(map._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the element stored at position `index` in the map. O(1).\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(AddressToAddressMap storage map, uint256 index) internal view returns (address, address) {\\n        (bytes32 key, bytes32 value) = at(map._inner, index);\\n        return (address(uint160(uint256(key))), address(uint160(uint256(value))));\\n    }\\n\\n    /**\\n     * @dev Tries to returns the value associated with `key`. O(1).\\n     * Does not revert if `key` is not in the map.\\n     */\\n    function tryGet(AddressToAddressMap storage map, address key) internal view returns (bool, address) {\\n        (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key))));\\n        return (success, address(uint160(uint256(value))));\\n    }\\n\\n    /**\\n     * @dev Returns the value associated with `key`. O(1).\\n     *\\n     * Requirements:\\n     *\\n     * - `key` must be in the map.\\n     */\\n    function get(AddressToAddressMap storage map, address key) internal view returns (address) {\\n        return address(uint160(uint256(get(map._inner, bytes32(uint256(uint160(key)))))));\\n    }\\n\\n    /**\\n     * @dev Return the an array containing all the keys\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function keys(AddressToAddressMap storage map) internal view returns (address[] memory) {\\n        bytes32[] memory store = keys(map._inner);\\n        address[] memory result;\\n\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n\\n    // AddressToBytes32Map\\n\\n    struct AddressToBytes32Map {\\n        Bytes32ToBytes32Map _inner;\\n    }\\n\\n    /**\\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\\n     * key. O(1).\\n     *\\n     * Returns true if the key was added to the map, that is if it was not\\n     * already present.\\n     */\\n    function set(AddressToBytes32Map storage map, address key, bytes32 value) internal returns (bool) {\\n        return set(map._inner, bytes32(uint256(uint160(key))), value);\\n    }\\n\\n    /**\\n     * @dev Removes a value from a map. O(1).\\n     *\\n     * Returns true if the key was removed from the map, that is if it was present.\\n     */\\n    function remove(AddressToBytes32Map storage map, address key) internal returns (bool) {\\n        return remove(map._inner, bytes32(uint256(uint160(key))));\\n    }\\n\\n    /**\\n     * @dev Returns true if the key is in the map. O(1).\\n     */\\n    function contains(AddressToBytes32Map storage map, address key) internal view returns (bool) {\\n        return contains(map._inner, bytes32(uint256(uint160(key))));\\n    }\\n\\n    /**\\n     * @dev Returns the number of elements in the map. O(1).\\n     */\\n    function length(AddressToBytes32Map storage map) internal view returns (uint256) {\\n        return length(map._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the element stored at position `index` in the map. O(1).\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(AddressToBytes32Map storage map, uint256 index) internal view returns (address, bytes32) {\\n        (bytes32 key, bytes32 value) = at(map._inner, index);\\n        return (address(uint160(uint256(key))), value);\\n    }\\n\\n    /**\\n     * @dev Tries to returns the value associated with `key`. O(1).\\n     * Does not revert if `key` is not in the map.\\n     */\\n    function tryGet(AddressToBytes32Map storage map, address key) internal view returns (bool, bytes32) {\\n        (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key))));\\n        return (success, value);\\n    }\\n\\n    /**\\n     * @dev Returns the value associated with `key`. O(1).\\n     *\\n     * Requirements:\\n     *\\n     * - `key` must be in the map.\\n     */\\n    function get(AddressToBytes32Map storage map, address key) internal view returns (bytes32) {\\n        return get(map._inner, bytes32(uint256(uint160(key))));\\n    }\\n\\n    /**\\n     * @dev Return the an array containing all the keys\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function keys(AddressToBytes32Map storage map) internal view returns (address[] memory) {\\n        bytes32[] memory store = keys(map._inner);\\n        address[] memory result;\\n\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n\\n    // Bytes32ToUintMap\\n\\n    struct Bytes32ToUintMap {\\n        Bytes32ToBytes32Map _inner;\\n    }\\n\\n    /**\\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\\n     * key. O(1).\\n     *\\n     * Returns true if the key was added to the map, that is if it was not\\n     * already present.\\n     */\\n    function set(Bytes32ToUintMap storage map, bytes32 key, uint256 value) internal returns (bool) {\\n        return set(map._inner, key, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a map. O(1).\\n     *\\n     * Returns true if the key was removed from the map, that is if it was present.\\n     */\\n    function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) {\\n        return remove(map._inner, key);\\n    }\\n\\n    /**\\n     * @dev Returns true if the key is in the map. O(1).\\n     */\\n    function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) {\\n        return contains(map._inner, key);\\n    }\\n\\n    /**\\n     * @dev Returns the number of elements in the map. O(1).\\n     */\\n    function length(Bytes32ToUintMap storage map) internal view returns (uint256) {\\n        return length(map._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the element stored at position `index` in the map. O(1).\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) {\\n        (bytes32 key, bytes32 value) = at(map._inner, index);\\n        return (key, uint256(value));\\n    }\\n\\n    /**\\n     * @dev Tries to returns the value associated with `key`. O(1).\\n     * Does not revert if `key` is not in the map.\\n     */\\n    function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) {\\n        (bool success, bytes32 value) = tryGet(map._inner, key);\\n        return (success, uint256(value));\\n    }\\n\\n    /**\\n     * @dev Returns the value associated with `key`. O(1).\\n     *\\n     * Requirements:\\n     *\\n     * - `key` must be in the map.\\n     */\\n    function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) {\\n        return uint256(get(map._inner, key));\\n    }\\n\\n    /**\\n     * @dev Return the an array containing all the keys\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function keys(Bytes32ToUintMap storage map) internal view returns (bytes32[] memory) {\\n        bytes32[] memory store = keys(map._inner);\\n        bytes32[] memory result;\\n\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n\\n    // Bytes32ToAddressMap\\n\\n    struct Bytes32ToAddressMap {\\n        Bytes32ToBytes32Map _inner;\\n    }\\n\\n    /**\\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\\n     * key. O(1).\\n     *\\n     * Returns true if the key was added to the map, that is if it was not\\n     * already present.\\n     */\\n    function set(Bytes32ToAddressMap storage map, bytes32 key, address value) internal returns (bool) {\\n        return set(map._inner, key, bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a map. O(1).\\n     *\\n     * Returns true if the key was removed from the map, that is if it was present.\\n     */\\n    function remove(Bytes32ToAddressMap storage map, bytes32 key) internal returns (bool) {\\n        return remove(map._inner, key);\\n    }\\n\\n    /**\\n     * @dev Returns true if the key is in the map. O(1).\\n     */\\n    function contains(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (bool) {\\n        return contains(map._inner, key);\\n    }\\n\\n    /**\\n     * @dev Returns the number of elements in the map. O(1).\\n     */\\n    function length(Bytes32ToAddressMap storage map) internal view returns (uint256) {\\n        return length(map._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the element stored at position `index` in the map. O(1).\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(Bytes32ToAddressMap storage map, uint256 index) internal view returns (bytes32, address) {\\n        (bytes32 key, bytes32 value) = at(map._inner, index);\\n        return (key, address(uint160(uint256(value))));\\n    }\\n\\n    /**\\n     * @dev Tries to returns the value associated with `key`. O(1).\\n     * Does not revert if `key` is not in the map.\\n     */\\n    function tryGet(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (bool, address) {\\n        (bool success, bytes32 value) = tryGet(map._inner, key);\\n        return (success, address(uint160(uint256(value))));\\n    }\\n\\n    /**\\n     * @dev Returns the value associated with `key`. O(1).\\n     *\\n     * Requirements:\\n     *\\n     * - `key` must be in the map.\\n     */\\n    function get(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (address) {\\n        return address(uint160(uint256(get(map._inner, key))));\\n    }\\n\\n    /**\\n     * @dev Return the an array containing all the keys\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function keys(Bytes32ToAddressMap storage map) internal view returns (bytes32[] memory) {\\n        bytes32[] memory store = keys(map._inner);\\n        bytes32[] memory result;\\n\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n *     // Add the library methods\\n *     using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n *     // Declare a set state variable\\n *     EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n    // To implement this library for multiple types with as little code\\n    // repetition as possible, we write it in terms of a generic Set type with\\n    // bytes32 values.\\n    // The Set implementation uses private functions, and user-facing\\n    // implementations (such as AddressSet) are just wrappers around the\\n    // underlying Set.\\n    // This means that we can only create new EnumerableSets for types that fit\\n    // in bytes32.\\n\\n    struct Set {\\n        // Storage of set values\\n        bytes32[] _values;\\n        // Position is the index of the value in the `values` array plus 1.\\n        // Position 0 is used to mean a value is not in the set.\\n        mapping(bytes32 value => uint256) _positions;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function _add(Set storage set, bytes32 value) private returns (bool) {\\n        if (!_contains(set, value)) {\\n            set._values.push(value);\\n            // The value is stored at length-1, but we add 1 to all indexes\\n            // and use 0 as a sentinel value\\n            set._positions[value] = set._values.length;\\n            return true;\\n        } else {\\n            return false;\\n        }\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\\n        // We cache the value's position to prevent multiple reads from the same storage slot\\n        uint256 position = set._positions[value];\\n\\n        if (position != 0) {\\n            // Equivalent to contains(set, value)\\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\\n            // This modifies the order of the array, as noted in {at}.\\n\\n            uint256 valueIndex = position - 1;\\n            uint256 lastIndex = set._values.length - 1;\\n\\n            if (valueIndex != lastIndex) {\\n                bytes32 lastValue = set._values[lastIndex];\\n\\n                // Move the lastValue to the index where the value to delete is\\n                set._values[valueIndex] = lastValue;\\n                // Update the tracked position of the lastValue (that was just moved)\\n                set._positions[lastValue] = position;\\n            }\\n\\n            // Delete the slot where the moved value was stored\\n            set._values.pop();\\n\\n            // Delete the tracked position for the deleted slot\\n            delete set._positions[value];\\n\\n            return true;\\n        } else {\\n            return false;\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n        return set._positions[value] != 0;\\n    }\\n\\n    /**\\n     * @dev Returns the number of values on the set. O(1).\\n     */\\n    function _length(Set storage set) private view returns (uint256) {\\n        return set._values.length;\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n        return set._values[index];\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function _values(Set storage set) private view returns (bytes32[] memory) {\\n        return set._values;\\n    }\\n\\n    // Bytes32Set\\n\\n    struct Bytes32Set {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n        return _add(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n        return _remove(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n        return _contains(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Returns the number of values in the set. O(1).\\n     */\\n    function length(Bytes32Set storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n        return _at(set._inner, index);\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n        bytes32[] memory store = _values(set._inner);\\n        bytes32[] memory result;\\n\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n\\n    // AddressSet\\n\\n    struct AddressSet {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(AddressSet storage set, address value) internal returns (bool) {\\n        return _add(set._inner, bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(AddressSet storage set, address value) internal returns (bool) {\\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Returns the number of values in the set. O(1).\\n     */\\n    function length(AddressSet storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n        return address(uint160(uint256(_at(set._inner, index))));\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function values(AddressSet storage set) internal view returns (address[] memory) {\\n        bytes32[] memory store = _values(set._inner);\\n        address[] memory result;\\n\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n\\n    // UintSet\\n\\n    struct UintSet {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\\n        return _add(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n        return _remove(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n        return _contains(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Returns the number of values in the set. O(1).\\n     */\\n    function length(UintSet storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n        return uint256(_at(set._inner, index));\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\\n        bytes32[] memory store = _values(set._inner);\\n        uint256[] memory result;\\n\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n}\\n\"},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/types/Time.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/types/Time.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Math} from \\\"../math/Math.sol\\\";\\nimport {SafeCast} from \\\"../math/SafeCast.sol\\\";\\n\\n/**\\n * @dev This library provides helpers for manipulating time-related objects.\\n *\\n * It uses the following types:\\n * - `uint48` for timepoints\\n * - `uint32` for durations\\n *\\n * While the library doesn't provide specific types for timepoints and duration, it does provide:\\n * - a `Delay` type to represent duration that can be programmed to change value automatically at a given point\\n * - additional helper functions\\n */\\nlibrary Time {\\n    using Time for *;\\n\\n    /**\\n     * @dev Get the block timestamp as a Timepoint.\\n     */\\n    function timestamp() internal view returns (uint48) {\\n        return SafeCast.toUint48(block.timestamp);\\n    }\\n\\n    /**\\n     * @dev Get the block number as a Timepoint.\\n     */\\n    function blockNumber() internal view returns (uint48) {\\n        return SafeCast.toUint48(block.number);\\n    }\\n\\n    // ==================================================== Delay =====================================================\\n    /**\\n     * @dev A `Delay` is a uint32 duration that can be programmed to change value automatically at a given point in the\\n     * future. The \\\"effect\\\" timepoint describes when the transitions happens from the \\\"old\\\" value to the \\\"new\\\" value.\\n     * This allows updating the delay applied to some operation while keeping some guarantees.\\n     *\\n     * In particular, the {update} function guarantees that if the delay is reduced, the old delay still applies for\\n     * some time. For example if the delay is currently 7 days to do an upgrade, the admin should not be able to set\\n     * the delay to 0 and upgrade immediately. If the admin wants to reduce the delay, the old delay (7 days) should\\n     * still apply for some time.\\n     *\\n     *\\n     * The `Delay` type is 112 bits long, and packs the following:\\n     *\\n     * ```\\n     *   | [uint48]: effect date (timepoint)\\n     *   |           | [uint32]: value before (duration)\\n     *   ↓           ↓       ↓ [uint32]: value after (duration)\\n     * 0xAAAAAAAAAAAABBBBBBBBCCCCCCCC\\n     * ```\\n     *\\n     * NOTE: The {get} and {withUpdate} functions operate using timestamps. Block number based delays are not currently\\n     * supported.\\n     */\\n    type Delay is uint112;\\n\\n    /**\\n     * @dev Wrap a duration into a Delay to add the one-step \\\"update in the future\\\" feature\\n     */\\n    function toDelay(uint32 duration) internal pure returns (Delay) {\\n        return Delay.wrap(duration);\\n    }\\n\\n    /**\\n     * @dev Get the value at a given timepoint plus the pending value and effect timepoint if there is a scheduled\\n     * change after this timepoint. If the effect timepoint is 0, then the pending value should not be considered.\\n     */\\n    function _getFullAt(Delay self, uint48 timepoint) private pure returns (uint32, uint32, uint48) {\\n        (uint32 valueBefore, uint32 valueAfter, uint48 effect) = self.unpack();\\n        return effect <= timepoint ? (valueAfter, 0, 0) : (valueBefore, valueAfter, effect);\\n    }\\n\\n    /**\\n     * @dev Get the current value plus the pending value and effect timepoint if there is a scheduled change. If the\\n     * effect timepoint is 0, then the pending value should not be considered.\\n     */\\n    function getFull(Delay self) internal view returns (uint32, uint32, uint48) {\\n        return _getFullAt(self, timestamp());\\n    }\\n\\n    /**\\n     * @dev Get the current value.\\n     */\\n    function get(Delay self) internal view returns (uint32) {\\n        (uint32 delay, , ) = self.getFull();\\n        return delay;\\n    }\\n\\n    /**\\n     * @dev Update a Delay object so that it takes a new duration after a timepoint that is automatically computed to\\n     * enforce the old delay at the moment of the update. Returns the updated Delay object and the timestamp when the\\n     * new delay becomes effective.\\n     */\\n    function withUpdate(\\n        Delay self,\\n        uint32 newValue,\\n        uint32 minSetback\\n    ) internal view returns (Delay updatedDelay, uint48 effect) {\\n        uint32 value = self.get();\\n        uint32 setback = uint32(Math.max(minSetback, value > newValue ? value - newValue : 0));\\n        effect = timestamp() + setback;\\n        return (pack(value, newValue, effect), effect);\\n    }\\n\\n    /**\\n     * @dev Split a delay into its components: valueBefore, valueAfter and effect (transition timepoint).\\n     */\\n    function unpack(Delay self) internal pure returns (uint32 valueBefore, uint32 valueAfter, uint48 effect) {\\n        uint112 raw = Delay.unwrap(self);\\n\\n        valueAfter = uint32(raw);\\n        valueBefore = uint32(raw >> 32);\\n        effect = uint48(raw >> 64);\\n\\n        return (valueBefore, valueAfter, effect);\\n    }\\n\\n    /**\\n     * @dev pack the components into a Delay object.\\n     */\\n    function pack(uint32 valueBefore, uint32 valueAfter, uint48 effect) internal pure returns (Delay) {\\n        return Delay.wrap((uint112(effect) << 64) | (uint112(valueBefore) << 32) | uint112(valueAfter));\\n    }\\n}\\n\"},\"lib/solady/src/utils/FixedPointMathLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\n/// @notice Arithmetic library with operations for fixed-point numbers.\\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/FixedPointMathLib.sol)\\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)\\nlibrary FixedPointMathLib {\\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\\n    /*                       CUSTOM ERRORS                        */\\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\\n\\n    /// @dev The operation failed, as the output exceeds the maximum value of uint256.\\n    error ExpOverflow();\\n\\n    /// @dev The operation failed, as the output exceeds the maximum value of uint256.\\n    error FactorialOverflow();\\n\\n    /// @dev The operation failed, due to an overflow.\\n    error RPowOverflow();\\n\\n    /// @dev The mantissa is too big to fit.\\n    error MantissaOverflow();\\n\\n    /// @dev The operation failed, due to an multiplication overflow.\\n    error MulWadFailed();\\n\\n    /// @dev The operation failed, due to an multiplication overflow.\\n    error SMulWadFailed();\\n\\n    /// @dev The operation failed, either due to a multiplication overflow, or a division by a zero.\\n    error DivWadFailed();\\n\\n    /// @dev The operation failed, either due to a multiplication overflow, or a division by a zero.\\n    error SDivWadFailed();\\n\\n    /// @dev The operation failed, either due to a multiplication overflow, or a division by a zero.\\n    error MulDivFailed();\\n\\n    /// @dev The division failed, as the denominator is zero.\\n    error DivFailed();\\n\\n    /// @dev The full precision multiply-divide operation failed, either due\\n    /// to the result being larger than 256 bits, or a division by a zero.\\n    error FullMulDivFailed();\\n\\n    /// @dev The output is undefined, as the input is less-than-or-equal to zero.\\n    error LnWadUndefined();\\n\\n    /// @dev The input outside the acceptable domain.\\n    error OutOfDomain();\\n\\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\\n    /*                         CONSTANTS                          */\\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\\n\\n    /// @dev The scalar of ETH and most ERC20s.\\n    uint256 internal constant WAD = 1e18;\\n\\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\\n    /*              SIMPLIFIED FIXED POINT OPERATIONS             */\\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\\n\\n    /// @dev Equivalent to `(x * y) / WAD` rounded down.\\n    function mulWad(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            // Equivalent to `require(y == 0 || x <= type(uint256).max / y)`.\\n            if mul(y, gt(x, div(not(0), y))) {\\n                mstore(0x00, 0xbac65e5b) // `MulWadFailed()`.\\n                revert(0x1c, 0x04)\\n            }\\n            z := div(mul(x, y), WAD)\\n        }\\n    }\\n\\n    /// @dev Equivalent to `(x * y) / WAD` rounded down.\\n    function sMulWad(int256 x, int256 y) internal pure returns (int256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := mul(x, y)\\n            // Equivalent to `require((x == 0 || z / x == y) && !(x == -1 && y == type(int256).min))`.\\n            if iszero(gt(or(iszero(x), eq(sdiv(z, x), y)), lt(not(x), eq(y, shl(255, 1))))) {\\n                mstore(0x00, 0xedcd4dd4) // `SMulWadFailed()`.\\n                revert(0x1c, 0x04)\\n            }\\n            z := sdiv(z, WAD)\\n        }\\n    }\\n\\n    /// @dev Equivalent to `(x * y) / WAD` rounded down, but without overflow checks.\\n    function rawMulWad(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := div(mul(x, y), WAD)\\n        }\\n    }\\n\\n    /// @dev Equivalent to `(x * y) / WAD` rounded down, but without overflow checks.\\n    function rawSMulWad(int256 x, int256 y) internal pure returns (int256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := sdiv(mul(x, y), WAD)\\n        }\\n    }\\n\\n    /// @dev Equivalent to `(x * y) / WAD` rounded up.\\n    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            // Equivalent to `require(y == 0 || x <= type(uint256).max / y)`.\\n            if mul(y, gt(x, div(not(0), y))) {\\n                mstore(0x00, 0xbac65e5b) // `MulWadFailed()`.\\n                revert(0x1c, 0x04)\\n            }\\n            z := add(iszero(iszero(mod(mul(x, y), WAD))), div(mul(x, y), WAD))\\n        }\\n    }\\n\\n    /// @dev Equivalent to `(x * y) / WAD` rounded up, but without overflow checks.\\n    function rawMulWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := add(iszero(iszero(mod(mul(x, y), WAD))), div(mul(x, y), WAD))\\n        }\\n    }\\n\\n    /// @dev Equivalent to `(x * WAD) / y` rounded down.\\n    function divWad(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            // Equivalent to `require(y != 0 && (WAD == 0 || x <= type(uint256).max / WAD))`.\\n            if iszero(mul(y, iszero(mul(WAD, gt(x, div(not(0), WAD)))))) {\\n                mstore(0x00, 0x7c5f487d) // `DivWadFailed()`.\\n                revert(0x1c, 0x04)\\n            }\\n            z := div(mul(x, WAD), y)\\n        }\\n    }\\n\\n    /// @dev Equivalent to `(x * WAD) / y` rounded down.\\n    function sDivWad(int256 x, int256 y) internal pure returns (int256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := mul(x, WAD)\\n            // Equivalent to `require(y != 0 && ((x * WAD) / WAD == x))`.\\n            if iszero(and(iszero(iszero(y)), eq(sdiv(z, WAD), x))) {\\n                mstore(0x00, 0x5c43740d) // `SDivWadFailed()`.\\n                revert(0x1c, 0x04)\\n            }\\n            z := sdiv(mul(x, WAD), y)\\n        }\\n    }\\n\\n    /// @dev Equivalent to `(x * WAD) / y` rounded down, but without overflow and divide by zero checks.\\n    function rawDivWad(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := div(mul(x, WAD), y)\\n        }\\n    }\\n\\n    /// @dev Equivalent to `(x * WAD) / y` rounded down, but without overflow and divide by zero checks.\\n    function rawSDivWad(int256 x, int256 y) internal pure returns (int256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := sdiv(mul(x, WAD), y)\\n        }\\n    }\\n\\n    /// @dev Equivalent to `(x * WAD) / y` rounded up.\\n    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            // Equivalent to `require(y != 0 && (WAD == 0 || x <= type(uint256).max / WAD))`.\\n            if iszero(mul(y, iszero(mul(WAD, gt(x, div(not(0), WAD)))))) {\\n                mstore(0x00, 0x7c5f487d) // `DivWadFailed()`.\\n                revert(0x1c, 0x04)\\n            }\\n            z := add(iszero(iszero(mod(mul(x, WAD), y))), div(mul(x, WAD), y))\\n        }\\n    }\\n\\n    /// @dev Equivalent to `(x * WAD) / y` rounded up, but without overflow and divide by zero checks.\\n    function rawDivWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := add(iszero(iszero(mod(mul(x, WAD), y))), div(mul(x, WAD), y))\\n        }\\n    }\\n\\n    /// @dev Equivalent to `x` to the power of `y`.\\n    /// because `x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)`.\\n    /// Note: This function is an approximation.\\n    function powWad(int256 x, int256 y) internal pure returns (int256) {\\n        // Using `ln(x)` means `x` must be greater than 0.\\n        return expWad((lnWad(x) * y) / int256(WAD));\\n    }\\n\\n    /// @dev Returns `exp(x)`, denominated in `WAD`.\\n    /// Credit to Remco Bloemen under MIT license: https://2π.com/22/exp-ln\\n    /// Note: This function is an approximation. Monotonically increasing.\\n    function expWad(int256 x) internal pure returns (int256 r) {\\n        unchecked {\\n            // When the result is less than 0.5 we return zero.\\n            // This happens when `x <= (log(1e-18) * 1e18) ~ -4.15e19`.\\n            if (x <= -41446531673892822313) return r;\\n\\n            /// @solidity memory-safe-assembly\\n            assembly {\\n                // When the result is greater than `(2**255 - 1) / 1e18` we can not represent it as\\n                // an int. This happens when `x >= floor(log((2**255 - 1) / 1e18) * 1e18) ≈ 135`.\\n                if iszero(slt(x, 135305999368893231589)) {\\n                    mstore(0x00, 0xa37bfec9) // `ExpOverflow()`.\\n                    revert(0x1c, 0x04)\\n                }\\n            }\\n\\n            // `x` is now in the range `(-42, 136) * 1e18`. Convert to `(-42, 136) * 2**96`\\n            // for more intermediate precision and a binary basis. This base conversion\\n            // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.\\n            x = (x << 78) / 5 ** 18;\\n\\n            // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers\\n            // of two such that exp(x) = exp(x') * 2**k, where k is an integer.\\n            // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).\\n            int256 k = ((x << 96) / 54916777467707473351141471128 + 2 ** 95) >> 96;\\n            x = x - k * 54916777467707473351141471128;\\n\\n            // `k` is in the range `[-61, 195]`.\\n\\n            // Evaluate using a (6, 7)-term rational approximation.\\n            // `p` is made monic, we'll multiply by a scale factor later.\\n            int256 y = x + 1346386616545796478920950773328;\\n            y = ((y * x) >> 96) + 57155421227552351082224309758442;\\n            int256 p = y + x - 94201549194550492254356042504812;\\n            p = ((p * y) >> 96) + 28719021644029726153956944680412240;\\n            p = p * x + (4385272521454847904659076985693276 << 96);\\n\\n            // We leave `p` in `2**192` basis so we don't need to scale it back up for the division.\\n            int256 q = x - 2855989394907223263936484059900;\\n            q = ((q * x) >> 96) + 50020603652535783019961831881945;\\n            q = ((q * x) >> 96) - 533845033583426703283633433725380;\\n            q = ((q * x) >> 96) + 3604857256930695427073651918091429;\\n            q = ((q * x) >> 96) - 14423608567350463180887372962807573;\\n            q = ((q * x) >> 96) + 26449188498355588339934803723976023;\\n\\n            /// @solidity memory-safe-assembly\\n            assembly {\\n                // Div in assembly because solidity adds a zero check despite the unchecked.\\n                // The q polynomial won't have zeros in the domain as all its roots are complex.\\n                // No scaling is necessary because p is already `2**96` too large.\\n                r := sdiv(p, q)\\n            }\\n\\n            // r should be in the range `(0.09, 0.25) * 2**96`.\\n\\n            // We now need to multiply r by:\\n            // - The scale factor `s ≈ 6.031367120`.\\n            // - The `2**k` factor from the range reduction.\\n            // - The `1e18 / 2**96` factor for base conversion.\\n            // We do this all at once, with an intermediate result in `2**213`\\n            // basis, so the final right shift is always by a positive amount.\\n            r = int256(\\n                (uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k)\\n            );\\n        }\\n    }\\n\\n    /// @dev Returns `ln(x)`, denominated in `WAD`.\\n    /// Credit to Remco Bloemen under MIT license: https://2π.com/22/exp-ln\\n    /// Note: This function is an approximation. Monotonically increasing.\\n    function lnWad(int256 x) internal pure returns (int256 r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            // We want to convert `x` from `10**18` fixed point to `2**96` fixed point.\\n            // We do this by multiplying by `2**96 / 10**18`. But since\\n            // `ln(x * C) = ln(x) + ln(C)`, we can simply do nothing here\\n            // and add `ln(2**96 / 10**18)` at the end.\\n\\n            // Compute `k = log2(x) - 96`, `r = 159 - k = 255 - log2(x) = 255 ^ log2(x)`.\\n            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\\n            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\\n            r := or(r, shl(4, lt(0xffff, shr(r, x))))\\n            r := or(r, shl(3, lt(0xff, shr(r, x))))\\n            // We place the check here for more optimal stack operations.\\n            if iszero(sgt(x, 0)) {\\n                mstore(0x00, 0x1615e638) // `LnWadUndefined()`.\\n                revert(0x1c, 0x04)\\n            }\\n            // forgefmt: disable-next-item\\n            r := xor(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),\\n                0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff))\\n\\n            // Reduce range of x to (1, 2) * 2**96\\n            // ln(2^k * x) = k * ln(2) + ln(x)\\n            x := shr(159, shl(r, x))\\n\\n            // Evaluate using a (8, 8)-term rational approximation.\\n            // `p` is made monic, we will multiply by a scale factor later.\\n            // forgefmt: disable-next-item\\n            let p := sub( // This heavily nested expression is to avoid stack-too-deep for via-ir.\\n                sar(96, mul(add(43456485725739037958740375743393,\\n                sar(96, mul(add(24828157081833163892658089445524,\\n                sar(96, mul(add(3273285459638523848632254066296,\\n                    x), x))), x))), x)), 11111509109440967052023855526967)\\n            p := sub(sar(96, mul(p, x)), 45023709667254063763336534515857)\\n            p := sub(sar(96, mul(p, x)), 14706773417378608786704636184526)\\n            p := sub(mul(p, x), shl(96, 795164235651350426258249787498))\\n            // We leave `p` in `2**192` basis so we don't need to scale it back up for the division.\\n\\n            // `q` is monic by convention.\\n            let q := add(5573035233440673466300451813936, x)\\n            q := add(71694874799317883764090561454958, sar(96, mul(x, q)))\\n            q := add(283447036172924575727196451306956, sar(96, mul(x, q)))\\n            q := add(401686690394027663651624208769553, sar(96, mul(x, q)))\\n            q := add(204048457590392012362485061816622, sar(96, mul(x, q)))\\n            q := add(31853899698501571402653359427138, sar(96, mul(x, q)))\\n            q := add(909429971244387300277376558375, sar(96, mul(x, q)))\\n\\n            // `p / q` is in the range `(0, 0.125) * 2**96`.\\n\\n            // Finalization, we need to:\\n            // - Multiply by the scale factor `s = 5.549…`.\\n            // - Add `ln(2**96 / 10**18)`.\\n            // - Add `k * ln(2)`.\\n            // - Multiply by `10**18 / 2**96 = 5**18 >> 78`.\\n\\n            // The q polynomial is known not to have zeros in the domain.\\n            // No scaling required because p is already `2**96` too large.\\n            p := sdiv(p, q)\\n            // Multiply by the scaling factor: `s * 5**18 * 2**96`, base is now `5**18 * 2**192`.\\n            p := mul(1677202110996718588342820967067443963516166, p)\\n            // Add `ln(2) * k * 5**18 * 2**192`.\\n            // forgefmt: disable-next-item\\n            p := add(mul(16597577552685614221487285958193947469193820559219878177908093499208371, sub(159, r)), p)\\n            // Add `ln(2**96 / 10**18) * 5**18 * 2**192`.\\n            p := add(600920179829731861736702779321621459595472258049074101567377883020018308, p)\\n            // Base conversion: mul `2**18 / 2**192`.\\n            r := sar(174, p)\\n        }\\n    }\\n\\n    /// @dev Returns `W_0(x)`, denominated in `WAD`.\\n    /// See: https://en.wikipedia.org/wiki/Lambert_W_function\\n    /// a.k.a. Product log function. This is an approximation of the principal branch.\\n    /// Note: This function is an approximation. Monotonically increasing.\\n    function lambertW0Wad(int256 x) internal pure returns (int256 w) {\\n        // forgefmt: disable-next-item\\n        unchecked {\\n            if ((w = x) <= -367879441171442322) revert OutOfDomain(); // `x` less than `-1/e`.\\n            int256 wad = int256(WAD);\\n            int256 p = x;\\n            uint256 c; // Whether we need to avoid catastrophic cancellation.\\n            uint256 i = 4; // Number of iterations.\\n            if (w <= 0x1ffffffffffff) {\\n                if (-0x4000000000000 <= w) {\\n                    i = 1; // Inputs near zero only take one step to converge.\\n                } else if (w <= -0x3ffffffffffffff) {\\n                    i = 32; // Inputs near `-1/e` take very long to converge.\\n                }\\n            } else if (uint256(w >> 63) == uint256(0)) {\\n                /// @solidity memory-safe-assembly\\n                assembly {\\n                    // Inline log2 for more performance, since the range is small.\\n                    let v := shr(49, w)\\n                    let l := shl(3, lt(0xff, v))\\n                    l := add(or(l, byte(and(0x1f, shr(shr(l, v), 0x8421084210842108cc6318c6db6d54be)),\\n                        0x0706060506020504060203020504030106050205030304010505030400000000)), 49)\\n                    w := sdiv(shl(l, 7), byte(sub(l, 31), 0x0303030303030303040506080c13))\\n                    c := gt(l, 60)\\n                    i := add(2, add(gt(l, 53), c))\\n                }\\n            } else {\\n                int256 ll = lnWad(w = lnWad(w));\\n                /// @solidity memory-safe-assembly\\n                assembly {\\n                    // `w = ln(x) - ln(ln(x)) + b * ln(ln(x)) / ln(x)`.\\n                    w := add(sdiv(mul(ll, 1023715080943847266), w), sub(w, ll))\\n                    i := add(3, iszero(shr(68, x)))\\n                    c := iszero(shr(143, x))\\n                }\\n                if (c == uint256(0)) {\\n                    do { // If `x` is big, use Newton's so that intermediate values won't overflow.\\n                        int256 e = expWad(w);\\n                        /// @solidity memory-safe-assembly\\n                        assembly {\\n                            let t := mul(w, div(e, wad))\\n                            w := sub(w, sdiv(sub(t, x), div(add(e, t), wad)))\\n                        }\\n                        if (p <= w) break;\\n                        p = w;\\n                    } while (--i != uint256(0));\\n                    /// @solidity memory-safe-assembly\\n                    assembly {\\n                        w := sub(w, sgt(w, 2))\\n                    }\\n                    return w;\\n                }\\n            }\\n            do { // Otherwise, use Halley's for faster convergence.\\n                int256 e = expWad(w);\\n                /// @solidity memory-safe-assembly\\n                assembly {\\n                    let t := add(w, wad)\\n                    let s := sub(mul(w, e), mul(x, wad))\\n                    w := sub(w, sdiv(mul(s, wad), sub(mul(e, t), sdiv(mul(add(t, wad), s), add(t, t)))))\\n                }\\n                if (p <= w) break;\\n                p = w;\\n            } while (--i != c);\\n            /// @solidity memory-safe-assembly\\n            assembly {\\n                w := sub(w, sgt(w, 2))\\n            }\\n            // For certain ranges of `x`, we'll use the quadratic-rate recursive formula of\\n            // R. Iacono and J.P. Boyd for the last iteration, to avoid catastrophic cancellation.\\n            if (c == uint256(0)) return w;\\n            int256 t = w | 1;\\n            /// @solidity memory-safe-assembly\\n            assembly {\\n                x := sdiv(mul(x, wad), t)\\n            }\\n            x = (t * (wad + lnWad(x)));\\n            /// @solidity memory-safe-assembly\\n            assembly {\\n                w := sdiv(x, add(wad, t))\\n            }\\n        }\\n    }\\n\\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\\n    /*                  GENERAL NUMBER UTILITIES                  */\\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\\n\\n    /// @dev Calculates `floor(x * y / d)` with full precision.\\n    /// Throws if result overflows a uint256 or when `d` is zero.\\n    /// Credit to Remco Bloemen under MIT license: https://2π.com/21/muldiv\\n    function fullMulDiv(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 result) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            // 512-bit multiply `[p1 p0] = x * y`.\\n            // Compute the product mod `2**256` and mod `2**256 - 1`\\n            // then use the Chinese Remainder Theorem to reconstruct\\n            // the 512 bit result. The result is stored in two 256\\n            // variables such that `product = p1 * 2**256 + p0`.\\n\\n            // Temporarily use `result` as `p0` to save gas.\\n            result := mul(x, y) // Lower 256 bits of `x * y`.\\n            for {} 1 {} {\\n                // If overflows.\\n                if iszero(mul(or(iszero(x), eq(div(result, x), y)), d)) {\\n                    let mm := mulmod(x, y, not(0))\\n                    let p1 := sub(mm, add(result, lt(mm, result))) // Upper 256 bits of `x * y`.\\n\\n                    /*------------------- 512 by 256 division --------------------*/\\n\\n                    // Make division exact by subtracting the remainder from `[p1 p0]`.\\n                    let r := mulmod(x, y, d) // Compute remainder using mulmod.\\n                    let t := and(d, sub(0, d)) // The least significant bit of `d`. `t >= 1`.\\n                    // Make sure the result is less than `2**256`. Also prevents `d == 0`.\\n                    // Placing the check here seems to give more optimal stack operations.\\n                    if iszero(gt(d, p1)) {\\n                        mstore(0x00, 0xae47f702) // `FullMulDivFailed()`.\\n                        revert(0x1c, 0x04)\\n                    }\\n                    d := div(d, t) // Divide `d` by `t`, which is a power of two.\\n                    // Invert `d mod 2**256`\\n                    // Now that `d` is an odd number, it has an inverse\\n                    // modulo `2**256` such that `d * inv = 1 mod 2**256`.\\n                    // Compute the inverse by starting with a seed that is correct\\n                    // correct for four bits. That is, `d * inv = 1 mod 2**4`.\\n                    let inv := xor(2, mul(3, d))\\n                    // Now use Newton-Raphson iteration to improve the precision.\\n                    // Thanks to Hensel's lifting lemma, this also works in modular\\n                    // arithmetic, doubling the correct bits in each step.\\n                    inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**8\\n                    inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**16\\n                    inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**32\\n                    inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**64\\n                    inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**128\\n                    result :=\\n                        mul(\\n                            // Divide [p1 p0] by the factors of two.\\n                            // Shift in bits from `p1` into `p0`. For this we need\\n                            // to flip `t` such that it is `2**256 / t`.\\n                            or(\\n                                mul(sub(p1, gt(r, result)), add(div(sub(0, t), t), 1)),\\n                                div(sub(result, r), t)\\n                            ),\\n                            mul(sub(2, mul(d, inv)), inv) // inverse mod 2**256\\n                        )\\n                    break\\n                }\\n                result := div(result, d)\\n                break\\n            }\\n        }\\n    }\\n\\n    /// @dev Calculates `floor(x * y / d)` with full precision.\\n    /// Behavior is undefined if `d` is zero or the final result cannot fit in 256 bits.\\n    /// Performs the full 512 bit calculation regardless.\\n    function fullMulDivUnchecked(uint256 x, uint256 y, uint256 d)\\n        internal\\n        pure\\n        returns (uint256 result)\\n    {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := mul(x, y)\\n            let mm := mulmod(x, y, not(0))\\n            let p1 := sub(mm, add(result, lt(mm, result)))\\n            let t := and(d, sub(0, d))\\n            let r := mulmod(x, y, d)\\n            d := div(d, t)\\n            let inv := xor(2, mul(3, d))\\n            inv := mul(inv, sub(2, mul(d, inv)))\\n            inv := mul(inv, sub(2, mul(d, inv)))\\n            inv := mul(inv, sub(2, mul(d, inv)))\\n            inv := mul(inv, sub(2, mul(d, inv)))\\n            inv := mul(inv, sub(2, mul(d, inv)))\\n            result :=\\n                mul(\\n                    or(mul(sub(p1, gt(r, result)), add(div(sub(0, t), t), 1)), div(sub(result, r), t)),\\n                    mul(sub(2, mul(d, inv)), inv)\\n                )\\n        }\\n    }\\n\\n    /// @dev Calculates `floor(x * y / d)` with full precision, rounded up.\\n    /// Throws if result overflows a uint256 or when `d` is zero.\\n    /// Credit to Uniswap-v3-core under MIT license:\\n    /// https://github.com/Uniswap/v3-core/blob/main/contracts/libraries/FullMath.sol\\n    function fullMulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 result) {\\n        result = fullMulDiv(x, y, d);\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            if mulmod(x, y, d) {\\n                result := add(result, 1)\\n                if iszero(result) {\\n                    mstore(0x00, 0xae47f702) // `FullMulDivFailed()`.\\n                    revert(0x1c, 0x04)\\n                }\\n            }\\n        }\\n    }\\n\\n    /// @dev Returns `floor(x * y / d)`.\\n    /// Reverts if `x * y` overflows, or `d` is zero.\\n    function mulDiv(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := mul(x, y)\\n            // Equivalent to `require(d != 0 && (y == 0 || x <= type(uint256).max / y))`.\\n            if iszero(mul(or(iszero(x), eq(div(z, x), y)), d)) {\\n                mstore(0x00, 0xad251c27) // `MulDivFailed()`.\\n                revert(0x1c, 0x04)\\n            }\\n            z := div(z, d)\\n        }\\n    }\\n\\n    /// @dev Returns `ceil(x * y / d)`.\\n    /// Reverts if `x * y` overflows, or `d` is zero.\\n    function mulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := mul(x, y)\\n            // Equivalent to `require(d != 0 && (y == 0 || x <= type(uint256).max / y))`.\\n            if iszero(mul(or(iszero(x), eq(div(z, x), y)), d)) {\\n                mstore(0x00, 0xad251c27) // `MulDivFailed()`.\\n                revert(0x1c, 0x04)\\n            }\\n            z := add(iszero(iszero(mod(z, d))), div(z, d))\\n        }\\n    }\\n\\n    /// @dev Returns `ceil(x / d)`.\\n    /// Reverts if `d` is zero.\\n    function divUp(uint256 x, uint256 d) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            if iszero(d) {\\n                mstore(0x00, 0x65244e4e) // `DivFailed()`.\\n                revert(0x1c, 0x04)\\n            }\\n            z := add(iszero(iszero(mod(x, d))), div(x, d))\\n        }\\n    }\\n\\n    /// @dev Returns `max(0, x - y)`.\\n    function zeroFloorSub(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := mul(gt(x, y), sub(x, y))\\n        }\\n    }\\n\\n    /// @dev Returns `condition ? x : y`, without branching.\\n    function ternary(bool condition, uint256 x, uint256 y) internal pure returns (uint256 result) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := xor(x, mul(xor(x, y), iszero(condition)))\\n        }\\n    }\\n\\n    /// @dev Exponentiate `x` to `y` by squaring, denominated in base `b`.\\n    /// Reverts if the computation overflows.\\n    function rpow(uint256 x, uint256 y, uint256 b) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := mul(b, iszero(y)) // `0 ** 0 = 1`. Otherwise, `0 ** n = 0`.\\n            if x {\\n                z := xor(b, mul(xor(b, x), and(y, 1))) // `z = isEven(y) ? scale : x`\\n                let half := shr(1, b) // Divide `b` by 2.\\n                // Divide `y` by 2 every iteration.\\n                for { y := shr(1, y) } y { y := shr(1, y) } {\\n                    let xx := mul(x, x) // Store x squared.\\n                    let xxRound := add(xx, half) // Round to the nearest number.\\n                    // Revert if `xx + half` overflowed, or if `x ** 2` overflows.\\n                    if or(lt(xxRound, xx), shr(128, x)) {\\n                        mstore(0x00, 0x49f7642b) // `RPowOverflow()`.\\n                        revert(0x1c, 0x04)\\n                    }\\n                    x := div(xxRound, b) // Set `x` to scaled `xxRound`.\\n                    // If `y` is odd:\\n                    if and(y, 1) {\\n                        let zx := mul(z, x) // Compute `z * x`.\\n                        let zxRound := add(zx, half) // Round to the nearest number.\\n                        // If `z * x` overflowed or `zx + half` overflowed:\\n                        if or(xor(div(zx, x), z), lt(zxRound, zx)) {\\n                            // Revert if `x` is non-zero.\\n                            if x {\\n                                mstore(0x00, 0x49f7642b) // `RPowOverflow()`.\\n                                revert(0x1c, 0x04)\\n                            }\\n                        }\\n                        z := div(zxRound, b) // Return properly scaled `zxRound`.\\n                    }\\n                }\\n            }\\n        }\\n    }\\n\\n    /// @dev Returns the square root of `x`, rounded down.\\n    function sqrt(uint256 x) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            // `floor(sqrt(2**15)) = 181`. `sqrt(2**15) - 181 = 2.84`.\\n            z := 181 // The \\\"correct\\\" value is 1, but this saves a multiplication later.\\n\\n            // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\\n            // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\\n\\n            // Let `y = x / 2**r`. We check `y >= 2**(k + 8)`\\n            // but shift right by `k` bits to ensure that if `x >= 256`, then `y >= 256`.\\n            let r := shl(7, lt(0xffffffffffffffffffffffffffffffffff, x))\\n            r := or(r, shl(6, lt(0xffffffffffffffffff, shr(r, x))))\\n            r := or(r, shl(5, lt(0xffffffffff, shr(r, x))))\\n            r := or(r, shl(4, lt(0xffffff, shr(r, x))))\\n            z := shl(shr(1, r), z)\\n\\n            // Goal was to get `z*z*y` within a small factor of `x`. More iterations could\\n            // get y in a tighter range. Currently, we will have y in `[256, 256*(2**16))`.\\n            // We ensured `y >= 256` so that the relative difference between `y` and `y+1` is small.\\n            // That's not possible if `x < 256` but we can just verify those cases exhaustively.\\n\\n            // Now, `z*z*y <= x < z*z*(y+1)`, and `y <= 2**(16+8)`, and either `y >= 256`, or `x < 256`.\\n            // Correctness can be checked exhaustively for `x < 256`, so we assume `y >= 256`.\\n            // Then `z*sqrt(y)` is within `sqrt(257)/sqrt(256)` of `sqrt(x)`, or about 20bps.\\n\\n            // For `s` in the range `[1/256, 256]`, the estimate `f(s) = (181/1024) * (s+1)`\\n            // is in the range `(1/2.84 * sqrt(s), 2.84 * sqrt(s))`,\\n            // with largest error when `s = 1` and when `s = 256` or `1/256`.\\n\\n            // Since `y` is in `[256, 256*(2**16))`, let `a = y/65536`, so that `a` is in `[1/256, 256)`.\\n            // Then we can estimate `sqrt(y)` using\\n            // `sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2**18`.\\n\\n            // There is no overflow risk here since `y < 2**136` after the first branch above.\\n            z := shr(18, mul(z, add(shr(r, x), 65536))) // A `mul()` is saved from starting `z` at 181.\\n\\n            // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\\n            z := shr(1, add(z, div(x, z)))\\n            z := shr(1, add(z, div(x, z)))\\n            z := shr(1, add(z, div(x, z)))\\n            z := shr(1, add(z, div(x, z)))\\n            z := shr(1, add(z, div(x, z)))\\n            z := shr(1, add(z, div(x, z)))\\n            z := shr(1, add(z, div(x, z)))\\n\\n            // If `x+1` is a perfect square, the Babylonian method cycles between\\n            // `floor(sqrt(x))` and `ceil(sqrt(x))`. This statement ensures we return floor.\\n            // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\\n            z := sub(z, lt(div(x, z), z))\\n        }\\n    }\\n\\n    /// @dev Returns the cube root of `x`, rounded down.\\n    /// Credit to bout3fiddy and pcaversaccio under AGPLv3 license:\\n    /// https://github.com/pcaversaccio/snekmate/blob/main/src/utils/Math.vy\\n    function cbrt(uint256 x) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            let r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\\n            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\\n            r := or(r, shl(4, lt(0xffff, shr(r, x))))\\n            r := or(r, shl(3, lt(0xff, shr(r, x))))\\n\\n            z := div(shl(div(r, 3), shl(lt(0xf, shr(r, x)), 0xf)), xor(7, mod(r, 3)))\\n\\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\\n\\n            z := sub(z, lt(div(x, mul(z, z)), z))\\n        }\\n    }\\n\\n    /// @dev Returns the square root of `x`, denominated in `WAD`, rounded down.\\n    function sqrtWad(uint256 x) internal pure returns (uint256 z) {\\n        unchecked {\\n            if (x <= type(uint256).max / 10 ** 18) return sqrt(x * 10 ** 18);\\n            z = (1 + sqrt(x)) * 10 ** 9;\\n            z = (fullMulDivUnchecked(x, 10 ** 18, z) + z) >> 1;\\n        }\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := sub(z, gt(999999999999999999, sub(mulmod(z, z, x), 1)))\\n        }\\n    }\\n\\n    /// @dev Returns the cube root of `x`, denominated in `WAD`, rounded down.\\n    function cbrtWad(uint256 x) internal pure returns (uint256 z) {\\n        unchecked {\\n            if (x <= type(uint256).max / 10 ** 36) return cbrt(x * 10 ** 36);\\n            z = (1 + cbrt(x)) * 10 ** 12;\\n            z = (fullMulDivUnchecked(x, 10 ** 36, z * z) + z + z) / 3;\\n        }\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            let p := x\\n            for {} 1 {} {\\n                if iszero(shr(229, p)) {\\n                    if iszero(shr(199, p)) {\\n                        p := mul(p, 100000000000000000)\\n                        break\\n                    }\\n                    p := mul(p, 100000000)\\n                    break\\n                }\\n                if iszero(shr(249, p)) { p := mul(p, 100) }\\n                break\\n            }\\n            let t := mulmod(mul(z, z), z, p)\\n            z := sub(z, gt(lt(t, shr(1, p)), iszero(t)))\\n        }\\n    }\\n\\n    /// @dev Returns the factorial of `x`.\\n    function factorial(uint256 x) internal pure returns (uint256 result) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            result := 1\\n            if iszero(lt(x, 58)) {\\n                mstore(0x00, 0xaba0f2a2) // `FactorialOverflow()`.\\n                revert(0x1c, 0x04)\\n            }\\n            for {} x { x := sub(x, 1) } { result := mul(result, x) }\\n        }\\n    }\\n\\n    /// @dev Returns the log2 of `x`.\\n    /// Equivalent to computing the index of the most significant bit (MSB) of `x`.\\n    /// Returns 0 if `x` is zero.\\n    function log2(uint256 x) internal pure returns (uint256 r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\\n            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\\n            r := or(r, shl(4, lt(0xffff, shr(r, x))))\\n            r := or(r, shl(3, lt(0xff, shr(r, x))))\\n            // forgefmt: disable-next-item\\n            r := or(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),\\n                0x0706060506020504060203020504030106050205030304010505030400000000))\\n        }\\n    }\\n\\n    /// @dev Returns the log2 of `x`, rounded up.\\n    /// Returns 0 if `x` is zero.\\n    function log2Up(uint256 x) internal pure returns (uint256 r) {\\n        r = log2(x);\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r := add(r, lt(shl(r, 1), x))\\n        }\\n    }\\n\\n    /// @dev Returns the log10 of `x`.\\n    /// Returns 0 if `x` is zero.\\n    function log10(uint256 x) internal pure returns (uint256 r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            if iszero(lt(x, 100000000000000000000000000000000000000)) {\\n                x := div(x, 100000000000000000000000000000000000000)\\n                r := 38\\n            }\\n            if iszero(lt(x, 100000000000000000000)) {\\n                x := div(x, 100000000000000000000)\\n                r := add(r, 20)\\n            }\\n            if iszero(lt(x, 10000000000)) {\\n                x := div(x, 10000000000)\\n                r := add(r, 10)\\n            }\\n            if iszero(lt(x, 100000)) {\\n                x := div(x, 100000)\\n                r := add(r, 5)\\n            }\\n            r := add(r, add(gt(x, 9), add(gt(x, 99), add(gt(x, 999), gt(x, 9999)))))\\n        }\\n    }\\n\\n    /// @dev Returns the log10 of `x`, rounded up.\\n    /// Returns 0 if `x` is zero.\\n    function log10Up(uint256 x) internal pure returns (uint256 r) {\\n        r = log10(x);\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r := add(r, lt(exp(10, r), x))\\n        }\\n    }\\n\\n    /// @dev Returns the log256 of `x`.\\n    /// Returns 0 if `x` is zero.\\n    function log256(uint256 x) internal pure returns (uint256 r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\\n            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\\n            r := or(r, shl(4, lt(0xffff, shr(r, x))))\\n            r := or(shr(3, r), lt(0xff, shr(r, x)))\\n        }\\n    }\\n\\n    /// @dev Returns the log256 of `x`, rounded up.\\n    /// Returns 0 if `x` is zero.\\n    function log256Up(uint256 x) internal pure returns (uint256 r) {\\n        r = log256(x);\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r := add(r, lt(shl(shl(3, r), 1), x))\\n        }\\n    }\\n\\n    /// @dev Returns the scientific notation format `mantissa * 10 ** exponent` of `x`.\\n    /// Useful for compressing prices (e.g. using 25 bit mantissa and 7 bit exponent).\\n    function sci(uint256 x) internal pure returns (uint256 mantissa, uint256 exponent) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            mantissa := x\\n            if mantissa {\\n                if iszero(mod(mantissa, 1000000000000000000000000000000000)) {\\n                    mantissa := div(mantissa, 1000000000000000000000000000000000)\\n                    exponent := 33\\n                }\\n                if iszero(mod(mantissa, 10000000000000000000)) {\\n                    mantissa := div(mantissa, 10000000000000000000)\\n                    exponent := add(exponent, 19)\\n                }\\n                if iszero(mod(mantissa, 1000000000000)) {\\n                    mantissa := div(mantissa, 1000000000000)\\n                    exponent := add(exponent, 12)\\n                }\\n                if iszero(mod(mantissa, 1000000)) {\\n                    mantissa := div(mantissa, 1000000)\\n                    exponent := add(exponent, 6)\\n                }\\n                if iszero(mod(mantissa, 10000)) {\\n                    mantissa := div(mantissa, 10000)\\n                    exponent := add(exponent, 4)\\n                }\\n                if iszero(mod(mantissa, 100)) {\\n                    mantissa := div(mantissa, 100)\\n                    exponent := add(exponent, 2)\\n                }\\n                if iszero(mod(mantissa, 10)) {\\n                    mantissa := div(mantissa, 10)\\n                    exponent := add(exponent, 1)\\n                }\\n            }\\n        }\\n    }\\n\\n    /// @dev Convenience function for packing `x` into a smaller number using `sci`.\\n    /// The `mantissa` will be in bits [7..255] (the upper 249 bits).\\n    /// The `exponent` will be in bits [0..6] (the lower 7 bits).\\n    /// Use `SafeCastLib` to safely ensure that the `packed` number is small\\n    /// enough to fit in the desired unsigned integer type:\\n    /// ```\\n    ///     uint32 packed = SafeCastLib.toUint32(FixedPointMathLib.packSci(777 ether));\\n    /// ```\\n    function packSci(uint256 x) internal pure returns (uint256 packed) {\\n        (x, packed) = sci(x); // Reuse for `mantissa` and `exponent`.\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            if shr(249, x) {\\n                mstore(0x00, 0xce30380c) // `MantissaOverflow()`.\\n                revert(0x1c, 0x04)\\n            }\\n            packed := or(shl(7, x), packed)\\n        }\\n    }\\n\\n    /// @dev Convenience function for unpacking a packed number from `packSci`.\\n    function unpackSci(uint256 packed) internal pure returns (uint256 unpacked) {\\n        unchecked {\\n            unpacked = (packed >> 7) * 10 ** (packed & 0x7f);\\n        }\\n    }\\n\\n    /// @dev Returns the average of `x` and `y`. Rounds towards zero.\\n    function avg(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        unchecked {\\n            z = (x & y) + ((x ^ y) >> 1);\\n        }\\n    }\\n\\n    /// @dev Returns the average of `x` and `y`. Rounds towards negative infinity.\\n    function avg(int256 x, int256 y) internal pure returns (int256 z) {\\n        unchecked {\\n            z = (x >> 1) + (y >> 1) + (x & y & 1);\\n        }\\n    }\\n\\n    /// @dev Returns the absolute value of `x`.\\n    function abs(int256 x) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := xor(sar(255, x), add(sar(255, x), x))\\n        }\\n    }\\n\\n    /// @dev Returns the absolute distance between `x` and `y`.\\n    function dist(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := xor(mul(xor(sub(y, x), sub(x, y)), gt(x, y)), sub(y, x))\\n        }\\n    }\\n\\n    /// @dev Returns the absolute distance between `x` and `y`.\\n    function dist(int256 x, int256 y) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := xor(mul(xor(sub(y, x), sub(x, y)), sgt(x, y)), sub(y, x))\\n        }\\n    }\\n\\n    /// @dev Returns the minimum of `x` and `y`.\\n    function min(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := xor(x, mul(xor(x, y), lt(y, x)))\\n        }\\n    }\\n\\n    /// @dev Returns the minimum of `x` and `y`.\\n    function min(int256 x, int256 y) internal pure returns (int256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := xor(x, mul(xor(x, y), slt(y, x)))\\n        }\\n    }\\n\\n    /// @dev Returns the maximum of `x` and `y`.\\n    function max(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := xor(x, mul(xor(x, y), gt(y, x)))\\n        }\\n    }\\n\\n    /// @dev Returns the maximum of `x` and `y`.\\n    function max(int256 x, int256 y) internal pure returns (int256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := xor(x, mul(xor(x, y), sgt(y, x)))\\n        }\\n    }\\n\\n    /// @dev Returns `x`, bounded to `minValue` and `maxValue`.\\n    function clamp(uint256 x, uint256 minValue, uint256 maxValue)\\n        internal\\n        pure\\n        returns (uint256 z)\\n    {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := xor(x, mul(xor(x, minValue), gt(minValue, x)))\\n            z := xor(z, mul(xor(z, maxValue), lt(maxValue, z)))\\n        }\\n    }\\n\\n    /// @dev Returns `x`, bounded to `minValue` and `maxValue`.\\n    function clamp(int256 x, int256 minValue, int256 maxValue) internal pure returns (int256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := xor(x, mul(xor(x, minValue), sgt(minValue, x)))\\n            z := xor(z, mul(xor(z, maxValue), slt(maxValue, z)))\\n        }\\n    }\\n\\n    /// @dev Returns greatest common divisor of `x` and `y`.\\n    function gcd(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            for { z := x } y {} {\\n                let t := y\\n                y := mod(z, y)\\n                z := t\\n            }\\n        }\\n    }\\n\\n    /// @dev Returns `a + (b - a) * (t - begin) / (end - begin)`,\\n    /// with `t` clamped between `begin` and `end` (inclusive).\\n    /// Agnostic to the order of (`a`, `b`) and (`end`, `begin`).\\n    /// If `begins == end`, returns `t <= begin ? a : b`.\\n    function lerp(uint256 a, uint256 b, uint256 t, uint256 begin, uint256 end)\\n        internal\\n        pure\\n        returns (uint256)\\n    {\\n        if (begin > end) {\\n            t = ~t;\\n            begin = ~begin;\\n            end = ~end;\\n        }\\n        if (t <= begin) return a;\\n        if (t >= end) return b;\\n        unchecked {\\n            if (b >= a) return a + fullMulDiv(b - a, t - begin, end - begin);\\n            return a - fullMulDiv(a - b, t - begin, end - begin);\\n        }\\n    }\\n\\n    /// @dev Returns `a + (b - a) * (t - begin) / (end - begin)`.\\n    /// with `t` clamped between `begin` and `end` (inclusive).\\n    /// Agnostic to the order of (`a`, `b`) and (`end`, `begin`).\\n    /// If `begins == end`, returns `t <= begin ? a : b`.\\n    function lerp(int256 a, int256 b, int256 t, int256 begin, int256 end)\\n        internal\\n        pure\\n        returns (int256)\\n    {\\n        if (begin > end) {\\n            t = int256(~uint256(t));\\n            begin = int256(~uint256(begin));\\n            end = int256(~uint256(end));\\n        }\\n        if (t <= begin) return a;\\n        if (t >= end) return b;\\n        // forgefmt: disable-next-item\\n        unchecked {\\n            if (b >= a) return int256(uint256(a) + fullMulDiv(uint256(b) - uint256(a),\\n                uint256(t) - uint256(begin), uint256(end) - uint256(begin)));\\n            return int256(uint256(a) - fullMulDiv(uint256(a) - uint256(b),\\n                uint256(t) - uint256(begin), uint256(end) - uint256(begin)));\\n        }\\n    }\\n\\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\\n    /*                   RAW NUMBER OPERATIONS                    */\\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\\n\\n    /// @dev Returns `x + y`, without checking for overflow.\\n    function rawAdd(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        unchecked {\\n            z = x + y;\\n        }\\n    }\\n\\n    /// @dev Returns `x + y`, without checking for overflow.\\n    function rawAdd(int256 x, int256 y) internal pure returns (int256 z) {\\n        unchecked {\\n            z = x + y;\\n        }\\n    }\\n\\n    /// @dev Returns `x - y`, without checking for underflow.\\n    function rawSub(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        unchecked {\\n            z = x - y;\\n        }\\n    }\\n\\n    /// @dev Returns `x - y`, without checking for underflow.\\n    function rawSub(int256 x, int256 y) internal pure returns (int256 z) {\\n        unchecked {\\n            z = x - y;\\n        }\\n    }\\n\\n    /// @dev Returns `x * y`, without checking for overflow.\\n    function rawMul(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        unchecked {\\n            z = x * y;\\n        }\\n    }\\n\\n    /// @dev Returns `x * y`, without checking for overflow.\\n    function rawMul(int256 x, int256 y) internal pure returns (int256 z) {\\n        unchecked {\\n            z = x * y;\\n        }\\n    }\\n\\n    /// @dev Returns `x / y`, returning 0 if `y` is zero.\\n    function rawDiv(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := div(x, y)\\n        }\\n    }\\n\\n    /// @dev Returns `x / y`, returning 0 if `y` is zero.\\n    function rawSDiv(int256 x, int256 y) internal pure returns (int256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := sdiv(x, y)\\n        }\\n    }\\n\\n    /// @dev Returns `x % y`, returning 0 if `y` is zero.\\n    function rawMod(uint256 x, uint256 y) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := mod(x, y)\\n        }\\n    }\\n\\n    /// @dev Returns `x % y`, returning 0 if `y` is zero.\\n    function rawSMod(int256 x, int256 y) internal pure returns (int256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := smod(x, y)\\n        }\\n    }\\n\\n    /// @dev Returns `(x + y) % d`, return 0 if `d` if zero.\\n    function rawAddMod(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := addmod(x, y, d)\\n        }\\n    }\\n\\n    /// @dev Returns `(x * y) % d`, return 0 if `d` if zero.\\n    function rawMulMod(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            z := mulmod(x, y, d)\\n        }\\n    }\\n}\\n\"},\"lib/solady/src/utils/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\n/// @notice Reentrancy guard mixin.\\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ReentrancyGuard.sol)\\nabstract contract ReentrancyGuard {\\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\\n    /*                       CUSTOM ERRORS                        */\\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\\n\\n    /// @dev Unauthorized reentrant call.\\n    error Reentrancy();\\n\\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\\n    /*                          STORAGE                           */\\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\\n\\n    /// @dev Equivalent to: `uint72(bytes9(keccak256(\\\"_REENTRANCY_GUARD_SLOT\\\")))`.\\n    /// 9 bytes is large enough to avoid collisions with lower slots,\\n    /// but not too large to result in excessive bytecode bloat.\\n    uint256 private constant _REENTRANCY_GUARD_SLOT = 0x929eee149b4bd21268;\\n\\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\\n    /*                      REENTRANCY GUARD                      */\\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\\n\\n    /// @dev Guards a function from reentrancy.\\n    modifier nonReentrant() virtual {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            if eq(sload(_REENTRANCY_GUARD_SLOT), address()) {\\n                mstore(0x00, 0xab143c06) // `Reentrancy()`.\\n                revert(0x1c, 0x04)\\n            }\\n            sstore(_REENTRANCY_GUARD_SLOT, address())\\n        }\\n        _;\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            sstore(_REENTRANCY_GUARD_SLOT, codesize())\\n        }\\n    }\\n\\n    /// @dev Guards a view function from read-only reentrancy.\\n    modifier nonReadReentrant() virtual {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            if eq(sload(_REENTRANCY_GUARD_SLOT), address()) {\\n                mstore(0x00, 0xab143c06) // `Reentrancy()`.\\n                revert(0x1c, 0x04)\\n            }\\n        }\\n        _;\\n    }\\n}\\n\"},\"src/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.27;\\n\\n/// @dev The maximum number of holders.\\nuint16 constant DEAL_MAX_HOLDERS = 1000;\\n\\n/// @dev The maximum service fee in basis points.\\nuint16 constant DEAL_MAX_SERVICE_FEE = 0.25e4; // 25%\\n\\n/// @dev The maximum origination fee in basis points.\\nuint16 constant DEAL_MAX_ORIGINATION_FEE = 0.1e4; // 10%\\n\\n/// @dev The maximum redemption fee in basis points.\\nuint16 constant DEAL_MAX_REDEMPTION_FEE = 0.1e4; // 10%\\n\\n/// @dev The default investment offer escrow period.\\nuint48 constant DEAL_DEFAULT_OFFER_ESCROW_PERIOD = 5 days;\\n/// @dev The maximum investment offer escrow period.\\nuint48 constant DEAL_MAX_OFFER_ESCROW_PERIOD = 30 days;\\n\\n/// @dev The default redemption lock period.\\nuint48 constant DEAL_DEFAULT_REDEMPTION_LOCK_PERIOD = 5 days;\\n/// @dev The maximum redemption lock period.\\nuint48 constant DEAL_MAX_REDEMPTION_LOCK_PERIOD = 30 days;\\n\\nlibrary Roles {\\n    uint64 public constant ADMIN = type(uint64).min; // 0\\n    uint64 public constant DEAL_ADMIN = 1;\\n    uint64 public constant DEAL_REGISTRAR = 2;\\n\\n    uint64 public constant PUBLIC = type(uint64).max; // 2**64-1\\n}\\n\"},\"src/DealManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.27;\\n\\nimport { AccessManagedUpgradeable } from \\\"@oz/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol\\\";\\nimport { IERC20Metadata } from \\\"@oz/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\nimport { SafeERC20 } from \\\"@oz/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Initializable } from \\\"@oz/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\n\\nimport { IBaseManager, BaseManager, IKYCManager } from \\\"./abstracts/BaseManager.sol\\\";\\nimport { IInvestmentManager, InvestmentManager } from \\\"./abstracts/InvestmentManager.sol\\\";\\nimport { IPayoutManager, PayoutManager } from \\\"./abstracts/PayoutManager.sol\\\";\\nimport { IDealManager } from \\\"./interfaces/IDealManager.sol\\\";\\nimport { IRedemptionManager } from \\\"./interfaces/manager/IRedemptionManager.sol\\\";\\nimport { IDeal } from \\\"./interfaces/IDeal.sol\\\";\\nimport { IDealFactory } from \\\"./interfaces/IDealFactory.sol\\\";\\nimport { BasisPoints } from \\\"./types/BasisPoints.sol\\\";\\n\\n/**\\n * @title DealManager\\n * @notice The DealManager contract is deployed per deal, establishing a 1-to-1 relationship between a Deal token\\n * contract and its corresponding DealManager. Each instance of DealManager is responsible for managing a single deal,\\n * including investment offers, payouts, and token operations. It serves as the core contract for deal\\n * management, integrating multiple responsibilities such as access control, KYC verification, and payout processing,\\n * ensuring that all deal-related operations are handled within a dedicated and isolated environment.\\n *\\n * @notice This contract implements the `IDealManager` interface and inherits functionality from several modules:\\n * - AccessManaged: Controls access management and authority delegation.\\n * - BaseManager: Manages capital and fee recipients, and handles currency conversion related to deals.\\n * - KYCManager: Manages KYC verification and eligibility for deal participation.\\n * - InvestmentManager: Manages investment offers.\\n * - RedemptionManager: Manages redemption requests.\\n * - PayoutManager: Oversees payout distribution to deal participants and manages balances and fees.\\n *\\n * ## Key Features:\\n * - **Dedicated Deal Management**: Each DealManager is responsible for a single deal, ensuring isolated and focused\\n *   management of all deal-related operations.\\n * - **Multi-Role Management**: Efficiently integrates access management, capital allocation, KYC, and payout\\n *   distribution under one unified contract.\\n * - **Token Operations**: Supports minting, burning, and transferring deal-specific tokens, enabling flexible\\n *   distribution to participants.\\n * - **KYC Verification**: Ensures that only eligible participants, as verified by a KYC process, can engage in deals.\\n * - **Investments Handling**: Manages investment offers, escrow periods, and origination fees, providing a streamlined\\n *   and secure investment process.\\n * - **Redemption Handling**: Manages investor redemption requests, allowing investors to redeem their tokens under\\n *   predefined conditions.\\n * - **Pro Rata Payouts**: Distributes both principal and interest payouts to participants based on their share in the\\n *   deal.\\n * - **Service Fee Management**: Automatically calculates and applies service fees during payouts, offering transparency\\n *   and accountability.\\n * - **Comprehensive Payout Tracking**: Supports tracking of payout balances, ensuring that participants can claim or\\n *   receive payouts based on their deal involvement.\\n * - **Fiat and Crypto Support**: Seamlessly handles both fiat and on-chain accounts, allowing for flexibility in deal\\n *   participation and payouts.\\n */\\ncontract DealManager is\\n    Initializable,\\n    AccessManagedUpgradeable,\\n    BaseManager,\\n    InvestmentManager,\\n    PayoutManager,\\n    IDealManager\\n{\\n    using SafeERC20 for IERC20Metadata;\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                    MODIFIERS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Ensures the available funds are sufficient for the operation.\\n    modifier hasSufficientAvailableFunds(uint256 amount) {\\n        uint256 available = availableFunds();\\n        if (available < amount) revert InsufficientFunds(available, amount);\\n        _;\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                   PUBLIC FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @custom:oz-upgrades-unsafe-allow constructor\\n    constructor() {\\n        _disableInitializers();\\n    }\\n\\n    /// @notice Initializes the proxy contract.\\n    function initialize() external initializer {\\n        IDealFactory dealFactory = IDealFactory(msg.sender);\\n        IDealFactory.DealManagerInitParams memory params = dealFactory.dealManagerInitParams();\\n\\n        __AccessManaged_init(dealFactory.authority());\\n        __BaseManager_init(\\n            params.deal, params.config.paymentCurrency, params.config.capitalRecipient, params.config.feeRecipient\\n        );\\n        __PayoutManager_init(params.config.serviceFee);\\n        __InvestmentManager_init(params.config.originationFee, params.config.redemptionFee, params.config.minInvestment);\\n    }\\n\\n    /// @inheritdoc IBaseManager\\n    function withdrawFundsToCapitalRecipient(uint256 amount) external restricted hasSufficientAvailableFunds(amount) {\\n        address recipient = capitalRecipient();\\n        if (recipient == address(0)) revert CapitalRecipientZeroAddress();\\n\\n        paymentCurrency().safeTransfer(recipient, amount);\\n    }\\n\\n    /// @inheritdoc IBaseManager\\n    function setCapitalRecipient(address recipient) external restricted {\\n        _setCapitalRecipient(recipient);\\n    }\\n\\n    /// @inheritdoc IBaseManager\\n    function setFeeRecipient(address recipient) external restricted {\\n        _setFeeRecipient(recipient);\\n    }\\n\\n    /// @inheritdoc IInvestmentManager\\n    function setMinInvestment(uint256 amount) external restricted {\\n        _setMinInvestment(amount);\\n    }\\n\\n    /// @inheritdoc IInvestmentManager\\n    function setOriginationFee(BasisPoints fee) external restricted {\\n        _setOriginationFee(fee);\\n    }\\n\\n    /// @inheritdoc IInvestmentManager\\n    function setOfferEscrowPeriod(uint48 period) external restricted {\\n        _setOfferEscrowPeriod(period);\\n    }\\n\\n    /// @inheritdoc IInvestmentManager\\n    function submitOffer(uint256 amount, uint256 maxFee) external returns (InvestmentOffer memory offer) {\\n        return _submitOffer(amount, maxFee);\\n    }\\n\\n    /// @inheritdoc IInvestmentManager\\n    function cancelOffer(uint256 id) external onlyOfferInvestor(id) {\\n        _cancelOffer(id);\\n    }\\n\\n    /// @inheritdoc IInvestmentManager\\n    function reviewOffer(uint256 id, uint256 acceptedAmount) external restricted {\\n        _reviewOffer(id, acceptedAmount);\\n    }\\n\\n    /// @inheritdoc IPayoutManager\\n    function setServiceFee(BasisPoints fee) external restricted {\\n        _setServiceFee(fee);\\n    }\\n\\n    /// @inheritdoc IPayoutManager\\n    function initiatePrincipalPayout(\\n        string calldata payoutId,\\n        uint256 totalPayoutAmount\\n    )\\n        external\\n        restricted\\n        ensureUniquePayoutId(payoutId)\\n        returns (uint256, uint256)\\n    {\\n        return _initiatePrincipalPayout(payoutId, totalPayoutAmount, availableFunds(), _afterPrincipalPayout);\\n    }\\n\\n    /// @inheritdoc IPayoutManager\\n    function initiateInterestPayout(\\n        string calldata payoutId,\\n        uint256 onchainPayoutAmount,\\n        uint48 periodEndTime\\n    )\\n        external\\n        restricted\\n        ensureUniquePayoutId(payoutId)\\n        hasSufficientAvailableFunds(onchainPayoutAmount)\\n        returns (uint256, uint256)\\n    {\\n        return _initiateInterestPayout(payoutId, onchainPayoutAmount, periodEndTime);\\n    }\\n\\n    /// @inheritdoc IPayoutManager\\n    function pushPayout(address[] calldata accounts) external restricted {\\n        _pushPayout(accounts);\\n    }\\n\\n    /// @inheritdoc IPayoutManager\\n    function revokePayout(address account) external restricted {\\n        _revokePayout(account);\\n    }\\n\\n    /// @inheritdoc IDealManager\\n    function addDealFiatAccounts(address[] calldata accounts) external restricted {\\n        deal().addFiatAccounts(accounts);\\n    }\\n\\n    /// @inheritdoc IDealManager\\n    function removeDealFiatAccounts(address[] calldata accounts) external restricted {\\n        deal().removeFiatAccounts(accounts);\\n    }\\n\\n    /// @inheritdoc IKYCManager\\n    function addDealEligibleAccounts(address[] calldata accounts) external restricted {\\n        deal().addEligibleAccounts(accounts);\\n    }\\n\\n    /// @inheritdoc IKYCManager\\n    function removeDealEligibleAccounts(address[] calldata accounts) external restricted {\\n        deal().removeEligibleAccounts(accounts);\\n        for (uint256 i = 0; i < accounts.length; i++) {\\n            _deleteRedemptionRequest(accounts[i]);\\n        }\\n    }\\n\\n    /// @inheritdoc IDealManager\\n    function mintDealTokens(IDeal.Mint[] calldata targets)\\n        external\\n        restricted\\n        returns (uint256 totalMinted, uint256 eligibleCount)\\n    {\\n        IDeal.Mint[] memory eligibleTargets = new IDeal.Mint[](targets.length);\\n        for (uint256 i = 0; i < targets.length; i++) {\\n            if (!isEligibleAccount(targets[i].to)) {\\n                emit TokenMintSkippedIneligible(targets[i].to, targets[i].amount);\\n                continue;\\n            }\\n            eligibleTargets[eligibleCount++] = targets[i];\\n        }\\n\\n        if (eligibleCount > 0) {\\n            if (eligibleCount < targets.length) {\\n                assembly {\\n                    mstore(eligibleTargets, eligibleCount)\\n                }\\n            }\\n            totalMinted = deal().mint(eligibleTargets);\\n        }\\n        emit TokensMinted(totalMinted);\\n    }\\n\\n    /// @inheritdoc IDealManager\\n    function burnDealTokens(IDeal.Burn[] calldata targets) external restricted returns (uint256 totalBurned) {\\n        IDeal dealToken = deal();\\n        totalBurned = dealToken.burn(targets);\\n        emit TokensBurned(totalBurned);\\n\\n        for (uint256 i = 0; i < targets.length; ++i) {\\n            _decreaseRedemptionAmount(targets[i].from, dealToken.balanceOf(targets[i].from));\\n        }\\n    }\\n\\n    /// @inheritdoc IDealManager\\n    function transferDealTokens(address from, address to, uint256 amount) external restricted {\\n        deal().managedTransfer(from, to, amount);\\n        _afterTransfer(from, to, amount);\\n    }\\n\\n    /// @inheritdoc IDealManager\\n    function setDealNAV(uint256 nav) external restricted {\\n        deal().setNAV(nav);\\n    }\\n\\n    /// @inheritdoc IDealManager\\n    function setDealMetadataURI(string calldata metadataURI) external restricted {\\n        deal().setMetadataURI(metadataURI);\\n    }\\n\\n    /// @inheritdoc IDealManager\\n    function setDealTotalSize(uint256 totalSize) external restricted {\\n        deal().setTotalSize(totalSize);\\n    }\\n\\n    /// @inheritdoc IDealManager\\n    function setDealOpenEnded(bool status) external restricted {\\n        deal().setOpenEnded(status);\\n    }\\n\\n    /// @inheritdoc IDealManager\\n    function setDealMaxHolders(uint16 maxHolders) external restricted {\\n        deal().setMaxHolders(maxHolders);\\n    }\\n\\n    /// @inheritdoc IRedemptionManager\\n    function setRedemptionFee(BasisPoints fee) external restricted {\\n        _setRedemptionFee(fee);\\n    }\\n\\n    /// @inheritdoc IRedemptionManager\\n    function setRedemptionLockPeriod(uint48 period) external restricted {\\n        _setRedemptionLockPeriod(period);\\n    }\\n\\n    /// @inheritdoc IRedemptionManager\\n    /// @dev We cannot use `hasSufficientAvailableFunds` here because the current budget must be factored in as well.\\n    function setRedemptionBudget(uint256 budget) external restricted {\\n        uint256 available = availableFunds() + redemptionBudget();\\n        if (available < budget) revert InsufficientFunds(available, budget);\\n        _setRedemptionBudget(budget);\\n    }\\n\\n    /// @inheritdoc IRedemptionManager\\n    function submitRedemptionRequest(uint256 amount, uint256 maxFee) external returns (RedemptionRequest memory) {\\n        return _submitRedemptionRequest(msg.sender, amount, maxFee);\\n    }\\n\\n    /// @inheritdoc IRedemptionManager\\n    function relayRedemptionRequest(\\n        address investor,\\n        uint256 amount\\n    )\\n        external\\n        restricted\\n        returns (RedemptionRequest memory)\\n    {\\n        // Check if the account is a fiat account.\\n        // The redemption request cannot be relayed for non-fiat accounts.\\n        if (!deal().isFiatAccount(investor)) revert RelayingRedemptionRequestForNonFiatAccount(investor);\\n\\n        // Current fees accepted automatically.\\n        return _submitRedemptionRequest(investor, amount, calculateRedemptionFee(amount));\\n    }\\n\\n    /// @inheritdoc IRedemptionManager\\n    function reviewRedemptionRequest(uint256 id, uint256 acceptedAmount) external restricted {\\n        _reviewRedemptionRequest(id, acceptedAmount);\\n    }\\n\\n    /// @inheritdoc IRedemptionManager\\n    function cancelRedemptionRequest(uint256 id) external onlyRequestedInvestor(id) {\\n        _cancelRedemptionRequest(id);\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                               PUBLIC VIEW FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @inheritdoc IDealManager\\n    function availableFunds() public view returns (uint256) {\\n        uint256 lockedBalance = reservedFunds();\\n        uint256 totalBalance = paymentCurrency().balanceOf(address(this));\\n        if (totalBalance <= lockedBalance) return 0;\\n\\n        return totalBalance - lockedBalance;\\n    }\\n\\n    /// @inheritdoc IDealManager\\n    /// @dev The reserved funds include escrowed investment offers, unclaimed payouts, and other locked funds which make\\n    /// them unavailable for originator withdrawal.\\n    function reservedFunds() public view returns (uint256 locked) {\\n        locked += PayoutManager.totalPayoutBalance();\\n        locked += InvestmentManager.totalEscrowBalance();\\n        locked += InvestmentManager.redemptionBudget();\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                               INTERNAL FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Principal payout callback function.\\n    function _afterPrincipalPayout(IPayoutManager.PrincipalPayout memory payout) internal {\\n        _decreaseRedemptionAmount(payout.account, payout.newTokenBalance);\\n    }\\n\\n    /// @notice Transfer callback function.\\n    function _afterTransfer(address from, address, uint256) internal {\\n        _decreaseRedemptionAmount(from, deal().balanceOf(from));\\n    }\\n}\\n\"},\"src/abstracts/BaseManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.27;\\n\\nimport { Initializable } from \\\"@oz/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport { IERC20Metadata } from \\\"@oz/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\nimport { ReentrancyGuard } from \\\"@solady/utils/ReentrancyGuard.sol\\\";\\n\\nimport { IBaseManager } from \\\"../interfaces/manager/IBaseManager.sol\\\";\\nimport { IDeal } from \\\"../interfaces/IDeal.sol\\\";\\nimport { IKYCManager } from \\\"../interfaces/manager/IKYCManager.sol\\\";\\n\\nabstract contract BaseManager is Initializable, ReentrancyGuard, IBaseManager, IKYCManager {\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                     STORAGE\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @param deal The deal contract.\\n    /// @param paymentCurrency The currency used for investments and disbursements.\\n    /// @param capitalRecipient The where the invested capital is sent.\\n    /// @param feeRecipient The address where the fees are sent.\\n    struct BaseManagerStorage {\\n        IDeal deal;\\n        IERC20Metadata paymentCurrency;\\n        address capitalRecipient;\\n        address feeRecipient;\\n    }\\n\\n    /// @custom:storage-location erc7201:tradable.storage.BaseManager\\n    bytes32 private constant _BASE_MANAGER_STORAGE_LOCATION =\\n        0xc4182b3cc3f0fc99e336580520fec5f367f0a498d6a2835f174cd5d205331400;\\n\\n    /// @notice Resolve the storage slot.\\n    function _bmStorage() private pure returns (BaseManagerStorage storage $) {\\n        assembly {\\n            $.slot := _BASE_MANAGER_STORAGE_LOCATION\\n        }\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                   INITIALIZER\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    function __BaseManager_init(\\n        IDeal deal_,\\n        IERC20Metadata paymentCurrency_,\\n        address capitalRecipient_,\\n        address feeRecipient_\\n    )\\n        internal\\n        onlyInitializing\\n    {\\n        if (address(deal_) == address(0)) revert DealZeroAddress();\\n        if (address(paymentCurrency_) == address(0)) revert PaymentCurrencyZeroAddress();\\n\\n        // Retrieve payment currency decimals to ensure correct scaling in calculations.\\n        uint8 paymentCurrencyDecimals = paymentCurrency_.decimals();\\n        if (paymentCurrencyDecimals < 2 || paymentCurrencyDecimals > 18) revert PaymentCurrencyInvalidDecimals();\\n\\n        // Ensure deal token and payment have compatible decimals.\\n        if (deal_.decimals() != paymentCurrencyDecimals) revert PaymentCurrencyDealDecimalMismatch();\\n\\n        BaseManagerStorage storage $ = _bmStorage();\\n        $.deal = deal_;\\n        $.paymentCurrency = paymentCurrency_;\\n\\n        _setCapitalRecipient(capitalRecipient_);\\n        _setFeeRecipient(feeRecipient_);\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                PUBLIC FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @inheritdoc IKYCManager\\n    function isEligibleAccount(address account) public view returns (bool) {\\n        return deal().isEligibleAccount(account);\\n    }\\n\\n    /// @inheritdoc IBaseManager\\n    function deal() public view returns (IDeal) {\\n        return _bmStorage().deal;\\n    }\\n\\n    /// @inheritdoc IBaseManager\\n    function paymentCurrency() public view returns (IERC20Metadata) {\\n        return _bmStorage().paymentCurrency;\\n    }\\n\\n    /// @inheritdoc IBaseManager\\n    function capitalRecipient() public view returns (address) {\\n        return _bmStorage().capitalRecipient;\\n    }\\n\\n    /// @inheritdoc IBaseManager\\n    function feeRecipient() public view returns (address) {\\n        return _bmStorage().feeRecipient;\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                               INTERNAL FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    function _checkAccountEligibility(address account) internal view {\\n        deal().checkAccountEligibility(account);\\n    }\\n\\n    function _setCapitalRecipient(address capitalRecipient_) internal {\\n        if (capitalRecipient_ == address(0)) revert CapitalRecipientZeroAddress();\\n        BaseManagerStorage storage $ = _bmStorage();\\n        emit CapitalRecipientUpdated($.capitalRecipient, capitalRecipient_);\\n        $.capitalRecipient = capitalRecipient_;\\n    }\\n\\n    function _setFeeRecipient(address feeRecipient_) internal {\\n        if (feeRecipient_ == address(0)) revert FeeRecipientZeroAddress();\\n        BaseManagerStorage storage $ = _bmStorage();\\n        emit FeeRecipientUpdated($.feeRecipient, feeRecipient_);\\n        $.feeRecipient = feeRecipient_;\\n    }\\n}\\n\"},\"src/abstracts/InvestmentManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.27;\\n\\nimport { Time } from \\\"@oz/contracts/utils/types/Time.sol\\\";\\nimport { EnumerableSet } from \\\"@oz/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { EnumerableMap } from \\\"@oz/contracts/utils/structs/EnumerableMap.sol\\\";\\nimport { DoubleEndedQueue } from \\\"@oz/contracts/utils/structs/DoubleEndedQueue.sol\\\";\\nimport { IERC20 } from \\\"@oz/contracts/token/ERC20/IERC20.sol\\\";\\nimport { SafeERC20 } from \\\"@oz/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { IERC20Errors } from \\\"@oz/contracts/interfaces/draft-IERC6093.sol\\\";\\nimport { FixedPointMathLib } from \\\"@solady/utils/FixedPointMathLib.sol\\\";\\n\\nimport { BasisPoints } from \\\"src/types/BasisPoints.sol\\\";\\nimport { IDeal } from \\\"src/interfaces/IDeal.sol\\\";\\nimport { IInvestmentManager } from \\\"src/interfaces/manager/IInvestmentManager.sol\\\";\\nimport { IRedemptionManager } from \\\"src/interfaces/manager/IRedemptionManager.sol\\\";\\nimport { BaseManager } from \\\"./BaseManager.sol\\\";\\n\\nimport {\\n    DEAL_DEFAULT_OFFER_ESCROW_PERIOD,\\n    DEAL_MAX_OFFER_ESCROW_PERIOD,\\n    DEAL_DEFAULT_REDEMPTION_LOCK_PERIOD,\\n    DEAL_MAX_REDEMPTION_LOCK_PERIOD,\\n    DEAL_MAX_ORIGINATION_FEE,\\n    DEAL_MAX_REDEMPTION_FEE\\n} from \\\"src/Constants.sol\\\";\\n\\nabstract contract InvestmentManager is BaseManager, IInvestmentManager, IRedemptionManager {\\n    using SafeERC20 for *;\\n    using EnumerableSet for EnumerableSet.UintSet;\\n    using EnumerableMap for EnumerableMap.AddressToUintMap;\\n    using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque;\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                     STORAGE\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Investment manager storage layout.\\n    /// @param originationFee Fee for originating an investment offer, in basis points.\\n    /// @param offerEscrowPeriod Duration (in seconds) funds are held in escrow before release.\\n    /// @param minInvestment Minimum amount required for an investment offer, in payment currency units.\\n    /// @param nextOfferId ID for the next investment offer, ensuring unique identification.\\n    /// @param totalEscrowBalance Total amount if investor funds held in escrow, in payment currency units.\\n    /// @param offerIds Set of IDs for all active investment offers.\\n    /// @param investmentOffers Mapping from offer ID to investment offer details.\\n    struct IMStorage {\\n        BasisPoints originationFee;\\n        uint48 offerEscrowPeriod;\\n        uint256 minInvestment;\\n        uint256 nextOfferId;\\n        uint256 totalEscrowBalance;\\n        EnumerableSet.UintSet offerIds;\\n        mapping(uint256 id => InvestmentOffer) investmentOffers;\\n    }\\n\\n    /// @notice Redemption manager storage layout.\\n    /// @param redemptionFee Fee for processing a redemption request, in basis points.\\n    /// @param redemptionLockPeriod Duration (in seconds) a redemption request is locked before it can be cancelled.\\n    /// @param nextRedemptionRequestId ID for the next redemption request, ensuring unique identification.\\n    /// @param investorRedemptionRequests Map of investor addresses to their redemption request IDs.\\n    /// @param redemptionRequests Mapping from redemption request ID to details of the redemption request.\\n    /// @param redemptionQueue Queue for managing and processing redemption requests.\\n    /// @param redemptionQueueTotal Total amount of deal tokens available in the redemption queue.\\n    /// @param redemptionBudget The available amount of payment currency allocated for redemptions by the originator.\\n    struct RMStorage {\\n        BasisPoints redemptionFee;\\n        uint48 redemptionLockPeriod;\\n        uint256 nextRedemptionRequestId;\\n        EnumerableMap.AddressToUintMap investorRedemptionRequests;\\n        mapping(uint256 id => RedemptionRequest) redemptionRequests;\\n        DoubleEndedQueue.Bytes32Deque redemptionQueue;\\n        uint256 redemptionQueueTotal;\\n        uint256 redemptionBudget;\\n    }\\n\\n    /// @custom:storage-location erc7201:tradable.storage.InvestmentManager\\n    bytes32 private constant _INVESTMENT_MANAGER_STORAGE_LOCATION =\\n        0x21bf53182fb2620c3ed6f4d208b46728bf1190fa8153bbbeaed032407174d200;\\n\\n    /// @custom:storage-location erc7201:tradable.storage.RedemptionManager\\n    bytes32 private constant _REDEMPTION_MANAGER_STORAGE_LOCATION =\\n        0xbe00cc4d0915aa2808218139ba7eb11a600645f392c64b3a518a691485eb4400;\\n\\n    /// @notice Resolve the storage slot.\\n    function _imStorage() private pure returns (IMStorage storage $) {\\n        assembly {\\n            $.slot := _INVESTMENT_MANAGER_STORAGE_LOCATION\\n        }\\n    }\\n\\n    /// @notice Resolve the storage slot.\\n    function _rmStorage() private pure returns (RMStorage storage $) {\\n        assembly {\\n            $.slot := _REDEMPTION_MANAGER_STORAGE_LOCATION\\n        }\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                   INITIALIZER\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    function __InvestmentManager_init(\\n        BasisPoints originationFee_,\\n        BasisPoints redemptionFee_,\\n        uint256 minInvestment_\\n    )\\n        internal\\n        onlyInitializing\\n    {\\n        // Initialize ID sequences.\\n        _imStorage().nextOfferId = 1;\\n        _rmStorage().nextRedemptionRequestId = 1;\\n\\n        _setMinInvestment(minInvestment_);\\n        _setOriginationFee(originationFee_);\\n        _setRedemptionFee(redemptionFee_);\\n        _setOfferEscrowPeriod(DEAL_DEFAULT_OFFER_ESCROW_PERIOD);\\n        _setRedemptionLockPeriod(DEAL_DEFAULT_REDEMPTION_LOCK_PERIOD);\\n        _setRedemptionBudget(0);\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                   MODIFIERS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    modifier onlyOfferInvestor(uint256 offerId) {\\n        if (_imStorage().investmentOffers[offerId].investor != msg.sender) revert CallerIsNotInvestor();\\n        _;\\n    }\\n\\n    modifier onlyRequestedInvestor(uint256 rrId) {\\n        if (_rmStorage().redemptionRequests[rrId].investor != msg.sender) revert CallerIsNotInvestor();\\n        _;\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                PUBLIC FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @inheritdoc IInvestmentManager\\n    function investmentOffer(uint256 id) public view returns (InvestmentOffer memory offer) {\\n        offer = _imStorage().investmentOffers[id];\\n        if (offer.id == 0) revert OfferNotFound();\\n    }\\n\\n    /// @inheritdoc IInvestmentManager\\n    function investmentOffers() public view returns (InvestmentOffer[] memory offers) {\\n        IMStorage storage $ = _imStorage();\\n        offers = new InvestmentOffer[]($.offerIds.length());\\n        for (uint256 i = 0; i < offers.length; i++) {\\n            offers[i] = $.investmentOffers[$.offerIds.at(i)];\\n        }\\n    }\\n\\n    /// @inheritdoc IInvestmentManager\\n    function totalEscrowBalance() public view returns (uint256) {\\n        return _imStorage().totalEscrowBalance;\\n    }\\n\\n    /// @inheritdoc IInvestmentManager\\n    function offerEscrowPeriod() public view returns (uint48) {\\n        return _imStorage().offerEscrowPeriod;\\n    }\\n\\n    /// @inheritdoc IInvestmentManager\\n    function minInvestment() public view returns (uint256) {\\n        return _imStorage().minInvestment;\\n    }\\n\\n    /// @inheritdoc IInvestmentManager\\n    function originationFee() public view returns (BasisPoints) {\\n        return _imStorage().originationFee;\\n    }\\n\\n    /// @inheritdoc IInvestmentManager\\n    function calculateOriginationFee(uint256 amount) public view returns (uint256) {\\n        return _imStorage().originationFee.percent(amount);\\n    }\\n\\n    /// @notice Returns the max amount that can be invested in the deal.\\n    function availableForInvestment() public view returns (uint256) {\\n        IDeal dealToken = deal();\\n        uint256 totalSupply = dealToken.totalSupply();\\n        // If the deal is open-ended, it is effectively unlimited.\\n        if (dealToken.isOpenEnded()) return type(uint256).max - totalSupply;\\n\\n        // Calculate the available emission.\\n        uint256 totalSize = dealToken.totalSize();\\n        uint256 availableEmission = totalSize > totalSupply ? totalSize - totalSupply : 0;\\n\\n        // If the deal is not open-ended, the investment cap is the sum of the available emission,\\n        // the deal token balance of the manager contract and the total amount in the redemption queue.\\n        return availableEmission + dealToken.balanceOf(address(this)) + redemptionQueueTotal();\\n    }\\n\\n    /// @inheritdoc IRedemptionManager\\n    function redemptionLockPeriod() public view returns (uint48) {\\n        return _rmStorage().redemptionLockPeriod;\\n    }\\n\\n    /// @inheritdoc IRedemptionManager\\n    function redemptionBudget() public view returns (uint256) {\\n        return _rmStorage().redemptionBudget;\\n    }\\n\\n    /// @inheritdoc IRedemptionManager\\n    function minRedemption() public view returns (uint256) {\\n        // Min redemption amount is the same as the min investment amount.\\n        return _imStorage().minInvestment;\\n    }\\n\\n    /// @inheritdoc IRedemptionManager\\n    function redemptionFee() public view returns (BasisPoints) {\\n        return _rmStorage().redemptionFee;\\n    }\\n\\n    /// @inheritdoc IRedemptionManager\\n    function calculateRedemptionFee(uint256 amount) public view returns (uint256) {\\n        // Since the payment currency has the same decimals as the deal token we can use amount interchangeably.\\n        return _rmStorage().redemptionFee.percent(amount);\\n    }\\n\\n    /// @inheritdoc IRedemptionManager\\n    function redemptionQueueTotal() public view returns (uint256) {\\n        return _rmStorage().redemptionQueueTotal;\\n    }\\n\\n    /// @inheritdoc IRedemptionManager\\n    function redemptionRequest(address investor) public view returns (RedemptionRequest memory) {\\n        RMStorage storage $ = _rmStorage();\\n        (bool exist, uint256 rrId) = $.investorRedemptionRequests.tryGet(investor);\\n        if (!exist) revert RedemptionRequestNotFound();\\n        return $.redemptionRequests[rrId];\\n    }\\n\\n    /// @inheritdoc IRedemptionManager\\n    function redemptionRequest(uint256 id) public view returns (RedemptionRequest memory) {\\n        RedemptionRequest storage rr = _rmStorage().redemptionRequests[id];\\n        if (id == 0 || rr.id == 0) revert RedemptionRequestNotFound();\\n        return rr;\\n    }\\n\\n    function redemptionRequests() public view returns (RedemptionRequest[] memory requests) {\\n        RMStorage storage $ = _rmStorage();\\n        requests = new RedemptionRequest[]($.investorRedemptionRequests.length());\\n        for (uint256 i = 0; i < requests.length; i++) {\\n            (, uint256 id) = $.investorRedemptionRequests.at(i);\\n            requests[i] = $.redemptionRequests[id];\\n        }\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                               INTERNAL FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    function _setMinInvestment(uint256 minInvestment_) internal {\\n        // minimal investment must be greater than $0.01 equivalent in payment currency.\\n        if (minInvestment_ < 10 ** uint256(paymentCurrency().decimals() - 2)) revert MinInvestmentTooLow();\\n        IMStorage storage $ = _imStorage();\\n        emit MinInvestmentUpdated($.minInvestment, minInvestment_);\\n        $.minInvestment = minInvestment_;\\n    }\\n\\n    function _setOfferEscrowPeriod(uint48 offerEscrowPeriod_) internal {\\n        if (offerEscrowPeriod_ > DEAL_MAX_OFFER_ESCROW_PERIOD) revert OfferEscrowPeriodTooLong();\\n        IMStorage storage $ = _imStorage();\\n        emit OfferEscrowPeriodUpdated($.offerEscrowPeriod, offerEscrowPeriod_);\\n        $.offerEscrowPeriod = offerEscrowPeriod_;\\n    }\\n\\n    function _setOriginationFee(BasisPoints originationFee_) internal {\\n        if (originationFee_.toUint() > DEAL_MAX_ORIGINATION_FEE) revert OriginationFeeTooHigh();\\n        IMStorage storage $ = _imStorage();\\n        emit OriginationFeeUpdated($.originationFee, originationFee_);\\n        $.originationFee = originationFee_;\\n    }\\n\\n    /// @notice Submit an investment offer.\\n    /// @dev Handles am investment offer submission and emits the `OfferSubmitted` event.\\n    /// @param offerAmount The amount investor is willing to invest.\\n    /// @param maxFee The maximum fee the investor is willing to pay.\\n    /// @return offer The investment offer structure.\\n    function _submitOffer(uint256 offerAmount, uint256 maxFee) internal returns (InvestmentOffer memory offer) {\\n        _checkAccountEligibility(msg.sender);\\n\\n        // Check the investment amount.\\n        if (offerAmount == 0) revert ZeroAmount();\\n        uint256 min = minInvestment();\\n        if (min > 0 && offerAmount < min) revert InvestmentAmountTooLow(offerAmount, min);\\n\\n        // Calculate the max origination fee, assuming the offer is accepted in full.\\n        IMStorage storage $ = _imStorage();\\n        BasisPoints fee = $.originationFee;\\n        uint256 maxOriginationFee = fee.percent(offerAmount);\\n        if (maxOriginationFee > maxFee) revert OfferMaxFeeExceeded(maxOriginationFee, maxFee);\\n\\n        uint256 id = $.nextOfferId++;\\n        assert($.offerIds.add(id));\\n\\n        uint48 escrowReleaseDate = Time.timestamp() + $.offerEscrowPeriod;\\n        uint256 escrowAmount = offerAmount + maxOriginationFee;\\n\\n        offer = InvestmentOffer({\\n            id: id,\\n            investor: msg.sender,\\n            amount: offerAmount,\\n            fee: fee,\\n            escrowAmount: escrowAmount,\\n            escrowReleaseDate: escrowReleaseDate\\n        });\\n\\n        $.investmentOffers[id] = offer;\\n\\n        // Escrow funds until the offer is reviewed.\\n        $.totalEscrowBalance += escrowAmount;\\n        paymentCurrency().safeTransferFrom(msg.sender, address(this), escrowAmount);\\n\\n        emit OfferSubmitted(id, msg.sender, offerAmount, fee, escrowAmount, escrowReleaseDate);\\n    }\\n\\n    /// @notice Review an investment offer.\\n    /// @dev Handles the offer review and emits the `OfferReviewed` event.\\n    /// @param offerId The offer ID.\\n    /// @param acceptedAmount The amount of the offer that is accepted.\\n    function _reviewOffer(uint256 offerId, uint256 acceptedAmount) internal {\\n        IMStorage storage $ = _imStorage();\\n        if (offerId == 0 || !$.offerIds.contains(offerId)) revert OfferNotFound();\\n\\n        // Retrieve and cache offer details to reduce storage reads.\\n        InvestmentOffer memory offer = $.investmentOffers[offerId];\\n\\n        // Validate the accepted amount.\\n        // Check: accepted amount <= offered amount <= available liquidity.\\n        if (acceptedAmount > offer.amount) revert OfferAcceptedAmountTooHigh(acceptedAmount, offer.amount);\\n        if (acceptedAmount > availableForInvestment()) revert InsufficientLiquidity();\\n\\n        // Delete the offer from the storage.\\n        _deleteOffer(offerId);\\n\\n        // Capture computed values for the event.\\n        uint256 feeAmount;\\n        uint256 refundAmount;\\n\\n        IERC20 paymentCurrency = paymentCurrency();\\n        if (acceptedAmount == 0) {\\n            // Refund the full escrowed amount if the offer is rejected.\\n            refundAmount = offer.escrowAmount;\\n            paymentCurrency.safeTransfer(offer.investor, refundAmount);\\n        } else {\\n            // Ensure the investor is still eligible to invest.\\n            _checkAccountEligibility(offer.investor);\\n\\n            // Note: There are 3 sources of liquidity (deal tokens) that must be used in the following order:\\n            // 1. Tokens held by the manager contract.\\n            // 2. Tokens held by investors, waiting for redemption.\\n            // 3. New tokens minted by the manager contract.\\n            uint256 remainingAmount = acceptedAmount;\\n\\n            IDeal dealToken = deal();\\n            IDeal.NAV memory dealNAV = dealToken.nav();\\n\\n            // Calculate token amount based on NAV instead of 1:1\\n            if (dealNAV.value > 0) {\\n                remainingAmount = acceptedAmount * (10 ** dealNAV.decimals) / dealNAV.value;\\n            }\\n\\n\\n            // 1. Use tokens held by the manager contract.\\n            uint256 ownBalance = dealToken.balanceOf(address(this));\\n            if (ownBalance > 0) {\\n                uint256 transferAmount = FixedPointMathLib.min(remainingAmount, ownBalance);\\n                dealToken.managedTransfer(address(this), offer.investor, transferAmount);\\n                remainingAmount -= transferAmount;\\n            }\\n\\n            // 2. Use tokens held by investors, waiting for redemption.\\n            uint256 redeemedAmount;\\n            if (remainingAmount > 0) {\\n                uint256 beforeRedemption = remainingAmount;\\n                remainingAmount = _processRedemptionQueue(remainingAmount, offer.investor);\\n                assert(remainingAmount <= beforeRedemption);\\n                redeemedAmount = beforeRedemption - remainingAmount;\\n            }\\n\\n            // 3. Mint new tokens if necessary.\\n            if (remainingAmount > 0) {\\n                IDeal.Mint[] memory mints = new IDeal.Mint[](1);\\n                mints[0] = IDeal.Mint(offer.investor, remainingAmount);\\n                deal().mint(mints);\\n\\n                // Newly issued tokens are subject to the origination fee paid in payment currency.\\n                if (dealNAV.value > 0) {\\n                    feeAmount = offer.fee.percent(remainingAmount * dealNAV.value / (10 ** dealNAV.decimals));\\n                } else { // if NAV is 0, we assume 1:1 for comp\\n                    feeAmount = offer.fee.percent(remainingAmount);\\n                }\\n                if (feeAmount > 0) paymentCurrency.safeTransfer(feeRecipient(), feeAmount);\\n\\n                // Offer fulfilled.\\n                remainingAmount = 0;\\n            }\\n\\n            assert(remainingAmount == 0);\\n\\n            // Refund the remaining escrowed amount, if any.\\n            refundAmount = offer.escrowAmount - acceptedAmount - feeAmount;\\n            if (refundAmount > 0) paymentCurrency.safeTransfer(offer.investor, refundAmount);\\n\\n            // Transfer the remaining accepted amount to capital recipient.\\n            paymentCurrency.safeTransfer(capitalRecipient(), acceptedAmount - redeemedAmount);\\n        }\\n\\n        emit OfferReviewed({\\n            id: offerId,\\n            investor: offer.investor,\\n            acceptedAmount: acceptedAmount,\\n            feeAmount: feeAmount,\\n            refundAmount: refundAmount\\n        });\\n    }\\n\\n    /// @notice Cancel an investment offer.\\n    /// @dev Handles the offer cancellation and emits the `OfferCancelled` event.\\n    /// @param offerId The offer ID.\\n    function _cancelOffer(uint256 offerId) internal {\\n        IMStorage storage $ = _imStorage();\\n        if (offerId == 0 || !$.offerIds.contains(offerId)) revert OfferNotFound();\\n\\n        InvestmentOffer memory offer = $.investmentOffers[offerId];\\n        if (Time.timestamp() < offer.escrowReleaseDate) revert OfferIsLocked(offer.escrowReleaseDate);\\n\\n        emit OfferCancelled(offerId, offer.investor);\\n        _deleteOffer(offerId);\\n\\n        paymentCurrency().safeTransfer(offer.investor, offer.escrowAmount);\\n    }\\n\\n    /// @notice Submit a redemption request.\\n    /// @dev Handles the redemption request submission and emits the `RedemptionRequested` event.\\n    /// @param investor The investor address.\\n    /// @param redemptionAmount The amount of deal tokens the investor wants to redeem.\\n    /// @param maxFee The maximum fee the investor is willing to pay.\\n    /// @return rr The redemption request structure.\\n    function _submitRedemptionRequest(\\n        address investor,\\n        uint256 redemptionAmount,\\n        uint256 maxFee\\n    )\\n        internal\\n        returns (RedemptionRequest memory rr)\\n    {\\n        _checkAccountEligibility(investor);\\n\\n        // Validate redemption request parameters.\\n        if (redemptionAmount == 0) revert ZeroAmount();\\n        uint256 min = minRedemption();\\n        if (min > 0 && redemptionAmount < min) revert RedemptionAmountTooLow(redemptionAmount, min);\\n\\n        // Check if the investor has sufficient balance of deal tokens.\\n        uint256 investorBalance = deal().balanceOf(investor);\\n        if (investorBalance < redemptionAmount) {\\n            revert IERC20Errors.ERC20InsufficientBalance(investor, investorBalance, redemptionAmount);\\n        }\\n\\n        // Ensure single redemption request per investor.\\n        RMStorage storage $ = _rmStorage();\\n        if ($.investorRedemptionRequests.contains(investor)) revert RedemptionRequestAlreadyExists();\\n\\n        // Calculate the redemption fee, assuming the request is accepted in full.\\n        BasisPoints fee = $.redemptionFee;\\n        uint256 maxRedemptionFee = fee.percent(redemptionAmount);\\n        if (maxRedemptionFee > maxFee) revert RedemptionMaxFeeExceeded(maxRedemptionFee, maxFee);\\n\\n        uint256 id = $.nextRedemptionRequestId++;\\n        rr = RedemptionRequest({\\n            id: id,\\n            amount: redemptionAmount,\\n            investor: investor,\\n            fee: fee,\\n            availableAmount: 0, // Available amount is determined when the request is accepted.\\n            requestReleaseDate: 0, // Redemption request is not locked until it is queued.\\n            queued: false\\n        });\\n\\n        $.redemptionRequests[id] = rr;\\n        $.investorRedemptionRequests.set(investor, id);\\n\\n        emit RedemptionRequested(id, investor, redemptionAmount, fee);\\n    }\\n\\n    /// @notice Review a redemption request.\\n    /// @dev Handles the redemption request review and emits the `RedemptionReviewed` event.\\n    /// @param id The redemption request ID.\\n    /// @param acceptedAmount The amount of the redemption request that is accepted.\\n    function _reviewRedemptionRequest(uint256 id, uint256 acceptedAmount) internal nonReentrant {\\n        RMStorage storage $ = _rmStorage();\\n\\n        // Retrieve the redemption request and validate operation.\\n        RedemptionRequest memory rr = $.redemptionRequests[id];\\n        if (id == 0 || rr.id == 0) revert RedemptionRequestNotFound();\\n\\n        // If have been already reviewed.\\n        if (rr.queued) revert RedemptionRequestAlreadyReviewed();\\n\\n        // If the redemption request is rejected, delete it.\\n        if (acceptedAmount == 0) {\\n            emit RedemptionReviewed({\\n                id: id,\\n                investor: rr.investor,\\n                acceptedAmount: 0,\\n                redeemedAmount: 0,\\n                rejectedAmount: rr.amount,\\n                availableAmount: 0,\\n                requestReleaseDate: 0\\n            });\\n            _deleteRedemptionRequest(id);\\n            return;\\n        }\\n\\n        // Validate the accepted amount.\\n        if (acceptedAmount > rr.amount) revert RedemptionAcceptedAmountTooHigh(acceptedAmount, rr.amount);\\n\\n        // Ensure the investor is eligible to redeem.\\n        _checkAccountEligibility(rr.investor);\\n\\n        // Calculate immediately redeemable amount based on the available redemption budget.\\n        // NOTE: We can compare tokens and payment currency amounts directly as they have the same decimals.\\n        uint256 redeemedAmount = FixedPointMathLib.min(acceptedAmount, $.redemptionBudget);\\n\\n        // Fulfill the redemption request immediately if the budget allows.\\n        if (redeemedAmount > 0) {\\n            // Use the redemption budget.\\n            $.redemptionBudget -= redeemedAmount;\\n\\n            // Transfer redeemed deal tokens to the manager contract.\\n            deal().managedTransfer(rr.investor, address(this), redeemedAmount);\\n\\n            // Calculate payment amount based on NAV instead of 1:1\\n            IDeal.NAV memory dealNAV = deal().nav();\\n            uint256 paymentAmount = redeemedAmount;\\n            if (dealNAV.value > 0) {\\n                paymentAmount = redeemedAmount * dealNAV.value / (10 ** dealNAV.decimals);\\n            }\\n\\n            // Charge the redemption fees.\\n            uint256 feeAmount = rr.fee.percent(paymentAmount);\\n            if (feeAmount > 0) paymentCurrency().safeTransfer(feeRecipient(), feeAmount);\\n\\n            // Pay out the investor based on NAV pricing minus the fee.\\n            paymentCurrency().safeTransfer(rr.investor, paymentAmount - feeAmount);\\n\\n            emit RedemptionExecuted({\\n                id: id,\\n                investor: rr.investor,\\n                amount: acceptedAmount,\\n                feeAmount: feeAmount,\\n                availableAmount: acceptedAmount - redeemedAmount\\n            });\\n\\n            // If the redemption request is fully redeemed, delete it.\\n            if (redeemedAmount == acceptedAmount) {\\n                emit RedemptionReviewed({\\n                    id: id,\\n                    investor: rr.investor,\\n                    acceptedAmount: acceptedAmount,\\n                    rejectedAmount: rr.amount - acceptedAmount,\\n                    redeemedAmount: redeemedAmount,\\n                    availableAmount: 0,\\n                    requestReleaseDate: 0\\n                });\\n                _deleteRedemptionRequest(id);\\n                return;\\n            }\\n        }\\n\\n        // Queue the remaining unfulfilled redemption request.\\n        uint256 queuedAmount = acceptedAmount - redeemedAmount;\\n\\n        // Check if the investor still has sufficient balance of deal tokens.\\n        uint256 balance = deal().balanceOf(rr.investor);\\n        if (balance < queuedAmount) {\\n            revert IERC20Errors.ERC20InsufficientBalance(rr.investor, balance, queuedAmount);\\n        }\\n\\n        // Compute the redemption request release date.\\n        uint48 requestReleaseDate = Time.timestamp() + $.redemptionLockPeriod;\\n\\n        // Update the redemption request.\\n        rr.requestReleaseDate = requestReleaseDate;\\n        rr.availableAmount = queuedAmount;\\n        rr.queued = true;\\n        $.redemptionRequests[id] = rr;\\n\\n        // Enqueue the redemption request.\\n        $.redemptionQueue.pushBack(bytes32(id));\\n        $.redemptionQueueTotal += queuedAmount;\\n\\n        emit RedemptionReviewed({\\n            id: id,\\n            investor: rr.investor,\\n            acceptedAmount: acceptedAmount,\\n            rejectedAmount: rr.amount - acceptedAmount,\\n            redeemedAmount: redeemedAmount,\\n            availableAmount: queuedAmount,\\n            requestReleaseDate: requestReleaseDate\\n        });\\n    }\\n\\n    /// @notice Cancel a redemption request.\\n    function _cancelRedemptionRequest(uint256 id) internal {\\n        RMStorage storage $ = _rmStorage();\\n        RedemptionRequest storage rr = $.redemptionRequests[id];\\n        if (id == 0 || rr.id == 0) revert RedemptionRequestNotFound();\\n        // The redemption request cannot be cancelled if it is locked up in the redemption queue.\\n        if (Time.timestamp() < rr.requestReleaseDate) revert RedemptionRequestIsLocked(rr.requestReleaseDate);\\n\\n        emit RedemptionCancelled(id, rr.investor);\\n        _deleteRedemptionRequest(id);\\n    }\\n\\n    /// @notice Decreases the redemption request amount if the investor's balance is not sufficient.\\n    function _decreaseRedemptionAmount(address investor, uint256 newTokenBalance) internal {\\n        RMStorage storage $ = _rmStorage();\\n        // Check whether investor has an active redemption request.\\n        (bool exist, uint256 id) = $.investorRedemptionRequests.tryGet(investor);\\n        if (!exist) return;\\n\\n        // Check if the balance dropped to zero. Delete the redemption request if so.\\n        if (newTokenBalance == 0) {\\n            _deleteRedemptionRequest(id);\\n            return;\\n        }\\n\\n        // Retrieve the redemption request.\\n        RedemptionRequest storage rr = $.redemptionRequests[id];\\n\\n        // The adjustable amount depends on the redemption request phase.\\n        uint256 rrAmount = rr.queued ? rr.availableAmount : rr.amount;\\n        if (newTokenBalance < rrAmount) {\\n            emit RedemptionAmountUpdated(id, rrAmount, newTokenBalance);\\n            if (rr.queued) {\\n                rr.availableAmount = newTokenBalance;\\n                $.redemptionQueueTotal -= (rrAmount - newTokenBalance);\\n            } else {\\n                rr.amount = newTokenBalance;\\n            }\\n        }\\n    }\\n\\n    function _setRedemptionFee(BasisPoints redemptionFee_) internal {\\n        if (redemptionFee_.toUint() > DEAL_MAX_REDEMPTION_FEE) revert RedemptionFeeTooHigh();\\n        RMStorage storage $ = _rmStorage();\\n        emit RedemptionFeeUpdated($.redemptionFee, redemptionFee_);\\n        $.redemptionFee = redemptionFee_;\\n    }\\n\\n    function _setRedemptionLockPeriod(uint48 redemptionLockPeriod_) internal {\\n        if (redemptionLockPeriod_ > DEAL_MAX_REDEMPTION_LOCK_PERIOD) revert RedemptionLockPeriodTooLong();\\n        RMStorage storage $ = _rmStorage();\\n        emit RedemptionLockPeriodUpdated($.redemptionLockPeriod, redemptionLockPeriod_);\\n        $.redemptionLockPeriod = redemptionLockPeriod_;\\n    }\\n\\n    function _setRedemptionBudget(uint256 redemptionBudget_) internal {\\n        RMStorage storage $ = _rmStorage();\\n        emit RedemptionBudgetUpdated($.redemptionBudget, redemptionBudget_);\\n\\n        bool budgetIncreased = redemptionBudget_ > $.redemptionBudget;\\n        $.redemptionBudget = redemptionBudget_;\\n\\n        // Process the redemption queue if the budget is increased.\\n        if (budgetIncreased) {\\n            // After processing the queue, save new redemption budget.\\n            $.redemptionBudget = _processRedemptionQueue(redemptionBudget_, address(this));\\n        }\\n    }\\n\\n    function _processRedemptionQueue(\\n        uint256 availableLiquidity,\\n        address redeemer\\n    )\\n        internal\\n        nonReentrant\\n        returns (uint256)\\n    {\\n        RMStorage storage $ = _rmStorage();\\n\\n        // Early exit if there's nothing to process.\\n        if (availableLiquidity == 0 || $.redemptionQueueTotal == 0) return availableLiquidity;\\n\\n        // Cache external contract instances and addresses.\\n        IDeal dealToken = deal();\\n        IERC20 paymentCurrency = paymentCurrency();\\n        address feeRecipientAddress = feeRecipient();\\n\\n        // Get the current queue length.\\n        uint256 queueLength = $.redemptionQueue.length();\\n\\n        // Process all redemption requests in the queue.\\n        for (uint256 i = 0; i < queueLength && availableLiquidity > 0; i++) {\\n            // Peek at the front of the queue without removing it.\\n            uint256 id = uint256($.redemptionQueue.front());\\n            RedemptionRequest memory rr = $.redemptionRequests[id];\\n\\n            // Remove invalid or deleted redemption request and continue to the next one.\\n            if (rr.id == 0) {\\n                $.redemptionQueue.popFront();\\n                continue;\\n            }\\n\\n            // Skip and remove the request if the investor is ineligible for redemption.\\n            if (!isEligibleAccount(rr.investor)) {\\n                $.redemptionQueue.popFront();\\n                _deleteRedemptionRequest(id);\\n                emit RedemptionSkippedIneligible(rr.investor, rr.availableAmount);\\n                continue;\\n            }\\n\\n            // Calculate the amount to redeem, ensuring it doesn't exceed the available liquidity.\\n            uint256 redeemedAmount = FixedPointMathLib.min(rr.availableAmount, availableLiquidity);\\n            // Consume the available liquidity.\\n            availableLiquidity -= redeemedAmount;\\n\\n            // Transfer redeemed deal tokens. The redeemed tokens must always go to the manager contract first.\\n            dealToken.managedTransfer(rr.investor, address(this), redeemedAmount);\\n            if (redeemer != address(this)) {\\n                dealToken.managedTransfer(address(this), redeemer, redeemedAmount);\\n            }\\n\\n            IDeal.NAV memory dealNAV = dealToken.nav();\\n\\n            // Calculate payment amount based on NAV instead of 1:1\\n            uint256 paymentAmount = redeemedAmount;\\n            if (dealNAV.value > 0) {\\n                paymentAmount = redeemedAmount * dealNAV.value / (10 ** dealNAV.decimals);\\n            }\\n\\n            // Charge the redemption fee.\\n            uint256 feeAmount = rr.fee.percent(paymentAmount);\\n            if (feeAmount > 0) paymentCurrency.safeTransfer(feeRecipientAddress, feeAmount);\\n\\n            // Pay out the investor based on NAV pricing minus the fee.\\n            paymentCurrency.safeTransfer(rr.investor, paymentAmount - feeAmount);\\n\\n            emit RedemptionExecuted({\\n                id: id,\\n                investor: rr.investor,\\n                amount: redeemedAmount,\\n                feeAmount: feeAmount,\\n                availableAmount: rr.availableAmount - redeemedAmount\\n            });\\n\\n            // Update the redemption request's available amount.\\n            if (redeemedAmount == rr.availableAmount) {\\n                // Fully redeemed.\\n                // Delete the redemption request.\\n                $.redemptionQueue.popFront();\\n                _deleteRedemptionRequest(id);\\n            } else {\\n                // Partially redeemed.\\n                // Update the amounts and keep the request in the front of the queue.\\n                $.redemptionRequests[id].availableAmount -= redeemedAmount;\\n                $.redemptionQueueTotal -= redeemedAmount;\\n\\n                // All the available liquidity must be consumed.\\n                assert(availableLiquidity == 0);\\n            }\\n        }\\n\\n        return availableLiquidity;\\n    }\\n\\n    function _deleteRedemptionRequest(address investor) internal {\\n        RMStorage storage $ = _rmStorage();\\n        (bool exist, uint256 id) = $.investorRedemptionRequests.tryGet(investor);\\n        if (exist) _deleteRedemptionRequest(id);\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                               PRIVATE FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    function _deleteOffer(uint256 id) private {\\n        IMStorage storage $ = _imStorage();\\n        assert($.offerIds.remove(id));\\n        $.totalEscrowBalance -= $.investmentOffers[id].escrowAmount;\\n        delete $.investmentOffers[id];\\n        emit OfferDeleted(id);\\n    }\\n\\n    function _deleteRedemptionRequest(uint256 id) private {\\n        RMStorage storage $ = _rmStorage();\\n        RedemptionRequest storage rr = $.redemptionRequests[id];\\n        assert($.investorRedemptionRequests.remove(rr.investor));\\n        $.redemptionQueueTotal -= rr.availableAmount;\\n        delete $.redemptionRequests[id];\\n        emit RedemptionDeleted(id);\\n    }\\n}\\n\"},\"src/abstracts/PayoutManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.27;\\n\\nimport { EnumerableSet } from \\\"@oz/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { EnumerableMap } from \\\"@oz/contracts/utils/structs/EnumerableMap.sol\\\";\\nimport { IERC20Metadata } from \\\"@oz/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\nimport { SafeERC20 } from \\\"@oz/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { FixedPointMathLib } from \\\"@solady/utils/FixedPointMathLib.sol\\\";\\n\\nimport { DEAL_MAX_SERVICE_FEE } from \\\"../Constants.sol\\\";\\nimport { BasisPoints } from \\\"../types/BasisPoints.sol\\\";\\nimport { IPayoutManager } from \\\"../interfaces/manager/IPayoutManager.sol\\\";\\nimport { IDeal } from \\\"../interfaces/IDeal.sol\\\";\\nimport { BaseManager } from \\\"./BaseManager.sol\\\";\\n\\nabstract contract PayoutManager is BaseManager, IPayoutManager {\\n    using SafeERC20 for IERC20Metadata;\\n    using FixedPointMathLib for uint256;\\n    using EnumerableSet for EnumerableSet.AddressSet;\\n    using EnumerableMap for EnumerableMap.AddressToUintMap;\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                     STORAGE\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    struct PMStorage {\\n        BasisPoints serviceFee;\\n        uint48 latestInterestPeriodEnd;\\n        uint256 totalPayoutBalance;\\n        EnumerableMap.AddressToUintMap payoutBalances;\\n        mapping(string payoutId => bool) usedPayoutIds;\\n    }\\n\\n    /// @custom:storage-location erc7201:tradable.storage.PayoutManager\\n    bytes32 private constant _PAYOUT_MANAGER_STORAGE_LOCATION =\\n        0xd2ef356666d8c61c7121e429abea0ebce969912ba7bb7a4724f837d4c3bb4500;\\n\\n    /// @notice Resolve the storage slot.\\n    function _pmStorage() private pure returns (PMStorage storage $) {\\n        assembly {\\n            $.slot := _PAYOUT_MANAGER_STORAGE_LOCATION\\n        }\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                   INITIALIZER\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    function __PayoutManager_init(BasisPoints serviceFee_) internal onlyInitializing {\\n        _setServiceFee(serviceFee_);\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                   MODIFIERS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    modifier ensureUniquePayoutId(string memory id) {\\n        if (_pmStorage().usedPayoutIds[id]) revert DuplicatePayoutId(id);\\n        _;\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                PUBLIC FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @inheritdoc IPayoutManager\\n    function claimPayout() public {\\n        _checkAccountEligibility(msg.sender);\\n        uint256 amount = payoutBalance(msg.sender);\\n        if (amount == 0) revert ZeroPayoutBalance();\\n        _decrementPayoutBalance(msg.sender, amount);\\n        emit PayoutClaimed(msg.sender, amount);\\n        paymentCurrency().safeTransfer(msg.sender, amount);\\n    }\\n\\n    /// @inheritdoc IPayoutManager\\n    function previewPrincipalPayout(uint256 totalPayoutAmount)\\n        public\\n        view\\n        returns (PrincipalPayout[] memory, uint256, uint256)\\n    {\\n        return _principalPayoutDistribution(totalPayoutAmount);\\n    }\\n\\n    /// @inheritdoc IPayoutManager\\n    function previewInterestPayout(\\n        uint256 onchainPayoutAmount,\\n        uint48 periodStartTime,\\n        uint48 periodEndTime\\n    )\\n        public\\n        view\\n        returns (InterestPayout[] memory, uint256, uint256)\\n    {\\n        return _interestPayoutDistribution(onchainPayoutAmount, periodStartTime, periodEndTime);\\n    }\\n\\n    /// @inheritdoc IPayoutManager\\n    function serviceFee() public view returns (BasisPoints) {\\n        return _pmStorage().serviceFee;\\n    }\\n\\n    /// @inheritdoc IPayoutManager\\n    function totalPayoutBalance() public view returns (uint256) {\\n        return _pmStorage().totalPayoutBalance;\\n    }\\n\\n    /// @inheritdoc IPayoutManager\\n    function payoutBalance(address account) public view returns (uint256 balance) {\\n        (, balance) = _pmStorage().payoutBalances.tryGet(account);\\n    }\\n\\n    /// @inheritdoc IPayoutManager\\n    function payoutBalances() public view returns (PayoutBalance[] memory) {\\n        PMStorage storage $ = _pmStorage();\\n        PayoutBalance[] memory balances = new PayoutBalance[]($.payoutBalances.length());\\n        for (uint256 i = 0; i < balances.length; i++) {\\n            (address account, uint256 balance) = $.payoutBalances.at(i);\\n            balances[i] = PayoutBalance({ account: account, balance: balance });\\n        }\\n        return balances;\\n    }\\n\\n    /// @inheritdoc IPayoutManager\\n    function payoutPeriodStartTime() public view returns (uint48) {\\n        PMStorage storage $ = _pmStorage();\\n\\n        // By default, the payout period starts at the previous period end.\\n        if ($.latestInterestPeriodEnd > 0) return $.latestInterestPeriodEnd;\\n\\n        // If there are no interest payouts yet, return the yield generation start.\\n        uint48 yieldGenerationStart = deal().yieldGenerationStart();\\n        if (yieldGenerationStart == 0) revert YieldGenerationNotStarted();\\n\\n        return yieldGenerationStart;\\n    }\\n\\n    /// @inheritdoc IPayoutManager\\n    function calculateServiceFee(uint256 amount) public view returns (uint256) {\\n        return _pmStorage().serviceFee.percent(amount);\\n    }\\n\\n    /// @inheritdoc IPayoutManager\\n    /// @dev The dust threshold is set to $0.01 equivalent, expressed as 0.01e4 (100 base units)\\n    /// @dev Example: USDC (6 decimals), Dust Threshold = 10 ** (6 - 2) = 10 ** 4 = 10,000 (0.01 USDC)\\n    /// @dev Example: DAI (18 decimals), Dust Threshold = 10 ** (18 - 2) = 10 ** 16 = 10^16 (0.01 DAI)\\n    function payoutDustThreshold() public view returns (uint256) {\\n        return 10 ** uint256(paymentCurrency().decimals() - 2);\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                               INTERNAL FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    function _setServiceFee(BasisPoints serviceFee_) internal {\\n        if (serviceFee_.toUint() > DEAL_MAX_SERVICE_FEE) revert ServiceFeeTooHigh();\\n        PMStorage storage $ = _pmStorage();\\n        emit ServiceFeeUpdated($.serviceFee, serviceFee_);\\n        $.serviceFee = serviceFee_;\\n    }\\n\\n    function _initiatePrincipalPayout(\\n        string memory id,\\n        uint256 totalPayoutAmount,\\n        uint256 availableFunds,\\n        function (PrincipalPayout memory) afterPayout\\n    )\\n        internal\\n        returns (uint256 onchainPayoutAmount, uint256 tokensBurned)\\n    {\\n        PrincipalPayout[] memory payouts;\\n        (payouts, onchainPayoutAmount, tokensBurned) = _principalPayoutDistribution(totalPayoutAmount);\\n\\n        // Check if there are enough available funds to cover the payout.\\n        if (availableFunds < onchainPayoutAmount) revert InsufficientFunds(availableFunds, onchainPayoutAmount);\\n\\n        uint256 length = payouts.length;\\n        IDeal.Burn[] memory tokensToBurn = new IDeal.Burn[](length);\\n\\n        for (uint256 i = 0; i < length; i++) {\\n            PrincipalPayout memory payout = payouts[i];\\n            tokensToBurn[i] = IDeal.Burn({ from: payout.account, amount: payout.burnTokenAmount });\\n\\n            // Increment the payout balance for the onchain accounts only.\\n            if (!payout.isFiatAccount && payout.amount > 0) _incrementPayoutBalance(payout.account, payout.amount);\\n\\n            emit PrincipalPayoutAccounted({\\n                id: id,\\n                account: payout.account,\\n                isFiatAccount: payout.isFiatAccount,\\n                amount: payout.amount,\\n                tokensBurned: payout.burnTokenAmount\\n            });\\n\\n            // Execute payout hook.\\n            afterPayout(payout);\\n        }\\n\\n        // Mark the payout id as used.\\n        _pmStorage().usedPayoutIds[id] = true;\\n\\n        // Burn the deal tokens.\\n        deal().burn(tokensToBurn);\\n\\n        emit PrincipalPayoutFinalized({\\n            id: id,\\n            totalPayoutAmount: totalPayoutAmount,\\n            onchainPayoutAmount: onchainPayoutAmount,\\n            tokensBurned: tokensBurned\\n        });\\n    }\\n\\n    function _initiateInterestPayout(\\n        string calldata id,\\n        uint256 onchainPayoutAmount,\\n        uint48 periodEndTime\\n    )\\n        internal\\n        returns (uint256 effectiveOnchainPayoutAmount, uint256 feeAmount)\\n    {\\n        uint48 periodStartTime = payoutPeriodStartTime();\\n        InterestPayout[] memory payouts;\\n        // forgefmt: disable-next-item\\n        (payouts, effectiveOnchainPayoutAmount, feeAmount) = _interestPayoutDistribution(\\n          onchainPayoutAmount, periodStartTime, periodEndTime\\n        );\\n\\n        uint256 length = payouts.length;\\n        for (uint256 i = 0; i < length; i++) {\\n            InterestPayout memory payout = payouts[i];\\n\\n            // Ignore the fiat accounts, and increment the payout balance for the on-chain accounts only.\\n            if (payout.isFiatAccount) continue;\\n            if (payout.amount > 0) _incrementPayoutBalance(payout.account, payout.amount);\\n\\n            // Note: the event will not be emitted for the fiat accounts.\\n            emit InterestPayoutAccounted({\\n                id: id,\\n                account: payout.account,\\n                isFiatAccount: payout.isFiatAccount,\\n                amount: payout.amount,\\n                periodStartTime: periodStartTime,\\n                periodEndTime: periodEndTime\\n            });\\n        }\\n\\n        PMStorage storage $ = _pmStorage();\\n        // Close the interest payout period.\\n        $.latestInterestPeriodEnd = periodEndTime;\\n        // Mark the payout id as used.\\n        $.usedPayoutIds[id] = true;\\n\\n        // Transfer the service fee to the fee recipient.\\n        if (feeAmount > 0) paymentCurrency().safeTransfer(feeRecipient(), feeAmount);\\n\\n        emit InterestPayoutFinalized({\\n            id: id,\\n            onchainPayoutAmount: effectiveOnchainPayoutAmount,\\n            feeAmount: feeAmount,\\n            periodStartTime: periodStartTime,\\n            periodEndTime: periodEndTime\\n        });\\n    }\\n\\n    function _pushPayout(address[] calldata accounts) internal {\\n        IERC20Metadata paymentCurrency = paymentCurrency();\\n        for (uint256 i = 0; i < accounts.length; i++) {\\n            address account = accounts[i];\\n            // Retrieve the payout balance for the account.\\n            uint256 amount = payoutBalance(account);\\n\\n            // Skip the account if the payout balance is zero.\\n            if (amount == 0) continue;\\n\\n            // Skip the account if it is not eligible for payout.\\n            if (!isEligibleAccount(account)) {\\n                emit PayoutPushSkippedIneligible(account, amount);\\n                continue;\\n            }\\n\\n            // Otherwise, decrement the payout balance and transfer the funds.\\n            _decrementPayoutBalance(account, amount);\\n            emit PayoutPushed(account, amount);\\n            paymentCurrency.safeTransfer(account, amount);\\n        }\\n    }\\n\\n    function _revokePayout(address account) internal {\\n        // Check if the account has a positive payout balance.\\n        uint256 amount = payoutBalance(account);\\n        if (amount == 0) revert ZeroPayoutBalance();\\n\\n        // Check if the account fails the eligibility check.\\n        // The payout cannot not be revoked if the account is eligible for payout.\\n        if (isEligibleAccount(account)) revert RevokingPayoutFromEligibleAccount(account);\\n\\n        address recipient = capitalRecipient();\\n        if (recipient == address(0)) revert CapitalRecipientZeroAddress();\\n\\n        // Send the entire payout balance to the capital recipient account.\\n        _decrementPayoutBalance(account, amount);\\n        paymentCurrency().safeTransfer(recipient, amount);\\n\\n        emit PayoutRevoked(account, amount);\\n    }\\n\\n    function _principalPayoutDistribution(uint256 totalPayoutAmount)\\n        internal\\n        view\\n        returns (\\n            PrincipalPayout[] memory payouts,\\n            uint256 effectiveOnchainPayoutAmount,\\n            uint256 effectiveTokenBurnAmount\\n        )\\n    {\\n        if (totalPayoutAmount == 0) revert ZeroAmount();\\n\\n        // Check if there is enough tokens to burn.\\n        IDeal deal = deal();\\n        uint256 totalSupply = deal.totalSupply();\\n        if (totalSupply == 0 || totalPayoutAmount > totalSupply) revert InsufficientTotalSupply();\\n\\n        IDeal.TokenHolder[] memory dealHolders = deal.holders();\\n        uint256 dustThreshold = payoutDustThreshold();\\n        payouts = new PrincipalPayout[](dealHolders.length);\\n        for (uint256 i = 0; i < payouts.length; i++) {\\n            IDeal.TokenHolder memory holder = dealHolders[i];\\n\\n            // The payout amount is calculated pro rata to the account balance.\\n            uint256 accountPayoutAmount = holder.balance.mulDiv(totalPayoutAmount, totalSupply);\\n            // Increase the onchain payout amount for the on-chain accounts only.\\n            if (!holder.isFiatAccount) {\\n                effectiveOnchainPayoutAmount += accountPayoutAmount;\\n            }\\n\\n            IDeal.NAV memory dealNAV = deal.nav();\\n\\n            // Calculate tokens to burn based on NAV price\\n            uint256 accountTokensToBurn;\\n            if (dealNAV.value > 0) {\\n                accountTokensToBurn = accountPayoutAmount * (10 ** dealNAV.decimals) / dealNAV.value;\\n            } else {\\n                // Fallback to 1:1 if NAV is zero for compatibility with previous versions.\\n                accountTokensToBurn = accountPayoutAmount;\\n            }\\n\\n            // Although, if the balance drops below the dust threshold, burn the remaining balance.\\n            if (holder.balance - accountTokensToBurn < dustThreshold) {\\n                accountTokensToBurn = holder.balance;\\n            }\\n            effectiveTokenBurnAmount += accountTokensToBurn;\\n\\n            payouts[i] = PrincipalPayout({\\n                account: holder.account,\\n                amount: accountPayoutAmount,\\n                burnTokenAmount: accountTokensToBurn,\\n                newTokenBalance: holder.balance - accountTokensToBurn,\\n                isFiatAccount: holder.isFiatAccount\\n            });\\n        }\\n    }\\n\\n    function _interestPayoutDistribution(\\n        uint256 onchainPayoutAmount,\\n        uint48 periodStartTime,\\n        uint48 periodEndTime\\n    )\\n        internal\\n        view\\n        returns (InterestPayout[] memory interestPayouts, uint256 effectiveOnchainPayoutAmount, uint256 feeAmount)\\n    {\\n        // Validate the interest payout period.\\n        if (periodStartTime == 0 || periodEndTime > block.timestamp || periodStartTime >= periodEndTime) {\\n            revert InvalidInterestPayoutPeriod(periodStartTime, periodEndTime);\\n        }\\n\\n        IDeal deal = deal();\\n        uint256 totalYield = deal.totalYield(periodStartTime, periodEndTime);\\n        if (totalYield == 0) return (new InterestPayout[](0), 0, 0);\\n\\n        uint256 fiatAccountsTotalYield = deal.fiatAccountsTotalYield(periodStartTime, periodEndTime);\\n        uint256 onchainAccountsTotalYield = totalYield - fiatAccountsTotalYield;\\n\\n        // Apply service fee to the on-chain payout amount.\\n        feeAmount = calculateServiceFee(onchainPayoutAmount);\\n        uint256 netOnchainPayout = onchainPayoutAmount - feeAmount;\\n\\n        IDeal.YieldRecipient[] memory yieldDistribution = deal.yieldDistribution(periodStartTime, periodEndTime);\\n        uint256 length = yieldDistribution.length;\\n\\n        interestPayouts = new InterestPayout[](length);\\n        for (uint256 i = 0; i < length; i++) {\\n            IDeal.YieldRecipient memory investor = yieldDistribution[i];\\n\\n            // Calculate the payout amount for the on-chain accounts only.\\n            uint256 amount = 0;\\n            if (!investor.isFiatAccount) {\\n                amount = investor.yield.mulDiv(netOnchainPayout, onchainAccountsTotalYield);\\n                effectiveOnchainPayoutAmount += amount;\\n            }\\n\\n            // forgefmt: disable-next-item\\n            interestPayouts[i] = InterestPayout({\\n                account: investor.account,\\n                amount: amount,\\n                isFiatAccount: investor.isFiatAccount\\n            });\\n        }\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                               PRIVATE FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    function _incrementPayoutBalance(address account, uint256 amount) private {\\n        PMStorage storage $ = _pmStorage();\\n        (, uint256 oldBalance) = $.payoutBalances.tryGet(account);\\n        uint256 newBalance = oldBalance + amount;\\n        $.payoutBalances.set(account, newBalance);\\n        $.totalPayoutBalance += amount;\\n        emit PayoutBalanceUpdated(account, oldBalance, newBalance);\\n    }\\n\\n    function _decrementPayoutBalance(address account, uint256 amount) private {\\n        PMStorage storage $ = _pmStorage();\\n        (, uint256 oldBalance) = $.payoutBalances.tryGet(account);\\n        uint256 newBalance = oldBalance - amount;\\n        if (newBalance == 0) {\\n            $.payoutBalances.remove(account);\\n        } else {\\n            $.payoutBalances.set(account, newBalance);\\n        }\\n        $.totalPayoutBalance -= amount;\\n        emit PayoutBalanceUpdated(account, oldBalance, newBalance);\\n    }\\n}\\n\"},\"src/interfaces/IDeal.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.27;\\n\\nimport { IERC6372 } from \\\"@oz/contracts/interfaces/IERC6372.sol\\\";\\n\\nimport { IERC20Metadata } from \\\"@oz/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\n\\ninterface IDeal is IERC20Metadata, IERC6372 {\\n    /// @param value The NAV value.\\n    /// @param timestamp The NAV latest update timestamp.\\n    /// @param decimals The NAV decimals.\\n    struct NAV {\\n        uint256 value;\\n        uint48 timestamp;\\n        uint8 decimals;\\n    }\\n\\n    /// @notice The share price struct.\\n    /// @param value The share price value.\\n    /// @param decimals The share price decimals.\\n    /// @param timestamp The price latest update timestamp.\\n    struct Price {\\n        uint256 value;\\n        uint8 decimals;\\n        uint48 timestamp;\\n    }\\n\\n    /// @param isFiatAccount Indicates whether the account is a fiat account.\\n    /// @param account The account address.\\n    /// @param yield The account yield.\\n    struct YieldRecipient {\\n        bool isFiatAccount;\\n        address account;\\n        uint256 yield;\\n    }\\n\\n    /// @param isFiatAccount Indicates whether the account is a fiat account.\\n    /// @param account The account address.\\n    /// @param balance The account balance.\\n    struct TokenHolder {\\n        bool isFiatAccount;\\n        address account;\\n        uint256 balance;\\n    }\\n\\n    /// @notice A structure to communicate single burn request for batch burning.\\n    /// @param from The account for which the tokens are burned.\\n    /// @param amount The amount of tokens to burn.\\n    struct Burn {\\n        address from;\\n        uint256 amount;\\n    }\\n\\n    /// @notice A structure to communicate single mint request for batch minting.\\n    /// @param to The recipient of the minted tokens.\\n    /// @param amount The amount of tokens to mint.\\n    struct Mint {\\n        address to;\\n        uint256 amount;\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       EVENTS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Emitted when the account's accumulated yield is updated.\\n    event AccountYieldUpdated(address indexed account, uint208 yield);\\n\\n    /// @notice Emitted when the deal total accumulated yield is updated.\\n    event TotalYieldUpdated(uint208 yield);\\n\\n    /// @notice Emitted when the fiat account status of an account changes.\\n    event AccountFiatStatusUpdated(address indexed account, bool status);\\n\\n    /// @notice Emitted when the eligibility status of an account changes.\\n    event AccountEligibilityStatusUpdated(address indexed account, bool status);\\n\\n    /// @notice Emitted when the Metadata URI is updated.\\n    event MetadataURIUpdated(string oldURI, string newURI);\\n\\n    /// @notice Emitted when the deal size is updated.\\n    event TotalSizeUpdated(uint256 oldDealSize, uint256 newDealSize);\\n\\n    /// @notice Emitted when an new account joins or leaves the deal.\\n    event HolderStatusUpdated(address indexed holder, bool status);\\n\\n    /// @notice Emitted when the NAV is updated.\\n    event NAVUpdated(uint256 oldNAV, uint256 newNAV);\\n\\n    /// @notice Emitted when the max holders limit is updated.\\n    event MaxHoldersUpdated(uint256 oldMaxHolders, uint256 newMaxHolders);\\n\\n    /// @notice Emitted when the deal is\\n    event OpenEndedStatusUpdated(bool status);\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       ERRORS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Thrown if the provided deal manager address is zero.\\n    error DealManagerZeroAddress();\\n\\n    /// @notice Thrown if the caller is not the deal manager.\\n    error UnauthorizedAccount();\\n\\n    /// @notice Thrown when provided deal ID is empty.\\n    error DealIdZeroLength();\\n\\n    /// @notice Thrown upon calling the ERC20 `approve` function.\\n    error ERC20ApproveDisabled();\\n\\n    /// @notice Thrown upon calling the ERC20 `transferFrom` function.\\n    error ERC20TransferFromDisabled();\\n\\n    /// @notice Thrown upon calling the ERC20 `transfer` function.\\n    error ERC20TransferDisabled();\\n\\n    /// @notice Thrown upon attempting to mint or send deal tokens to the deal contract.\\n    error DealContractCannotReceiveOwnTokens();\\n\\n    /// @notice Thrown when the metadata URI is empty.\\n    error MetadataURIEmpty();\\n\\n    /// @notice Thrown if the fiat account address is zero.\\n    error FiatAccountZeroAddress();\\n\\n    /// @notice Thrown if the eligible account address is zero.\\n    error EligibleAccountZeroAddress();\\n\\n    /// @notice Thrown if the account is not eligible for participation in the deal.\\n    error AccountNotEligible(address account);\\n\\n    /// @notice Thrown if the end timestamp is in the past.\\n    error DealYieldPastLookup(uint48 periodEndTime, uint48 yieldGenerationStart);\\n\\n    /// @notice Thrown if the start timestamp is in the future.\\n    error DealYieldFutureLookup(uint48 periodStartTime, uint48 currentTimestamp);\\n\\n    /// @notice Thrown if the end timestamp is before the start timestamp.\\n    error DealYieldInvalidPeriod(uint48 periodStartTime, uint48 periodEndTime);\\n\\n    /// @notice Thrown if he clock was incorrectly modified.\\n    error ERC6372InconsistentClock();\\n\\n    /// @notice Thrown if the max holders limit is exceeded.\\n    error MaxHoldersExceeded(uint256 maxHolders);\\n\\n    /// @notice Thrown if the total deal size is exceeded upon minting.\\n    error TotalSizeExceeded(uint256 totalSize);\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Set max holders limit.\\n    /// @param value New max holders limit.\\n    function setMaxHolders(uint16 value) external;\\n\\n    /// @notice Updates the NAV value.\\n    /// @param value New NAV value.\\n    function setNAV(uint256 value) external;\\n\\n    /// @notice Updates the Metadata URI.\\n    /// @param uri New metadata URI.\\n    function setMetadataURI(string calldata uri) external;\\n\\n    /// @notice Updates the total deal size.\\n    /// @param value New total deal size in deal tokens.\\n    function setTotalSize(uint256 value) external;\\n\\n    /// @notice Updates the open-ended status of the deal.\\n    /// @param status New open-ended status.\\n    function setOpenEnded(bool status) external;\\n\\n    /// @notice Allows to mint tokens to multiple addresses.\\n    /// @param targets Array of mint amounts and addresses.\\n    /// @return totalMinted The total amount of tokens minted.\\n    function mint(Mint[] calldata targets) external returns (uint256 totalMinted);\\n\\n    /// @notice Allows to burn tokens from multiple addresses.\\n    /// @param targets Array of burn amounts and addresses.\\n    /// @return totalBurned The total amount of tokens burned.\\n    function burn(Burn[] calldata targets) external returns (uint256 totalBurned);\\n\\n    /// @notice Allows manager to transfer tokens between arbitrary accounts.\\n    /// @param from The address to transfer from.\\n    /// @param to The address to transfer to.\\n    /// @param amount The amount to transfer.\\n    function managedTransfer(address from, address to, uint256 amount) external;\\n\\n    /// @notice Marks multiple accounts as fiat accounts.\\n    /// @param accounts Array of accounts to mark as fiat accounts.\\n    function addFiatAccounts(address[] calldata accounts) external;\\n\\n    /// @notice Removes multiple accounts from the fiat accounts list.\\n    /// @param accounts Array of accounts to remove from the fiat accounts list.\\n    function removeFiatAccounts(address[] calldata accounts) external;\\n\\n    /// @notice Marks multiple accounts as eligible for participation in the deal.\\n    function addEligibleAccounts(address[] calldata accounts) external;\\n\\n    /// @notice Removes multiple accounts from the eligible accounts list.\\n    function removeEligibleAccounts(address[] calldata accounts) external;\\n\\n    /// @notice Calculates accounts' yield for a period.\\n    /// @param periodStartTime The period start timestamp.\\n    /// @param periodEndTime The period end timestamp.\\n    /// @param accounts The account to calculate the yield for.\\n    /// @return The array of yields for the accounts, in the same order as the input.\\n    function accountYield(\\n        uint48 periodStartTime,\\n        uint48 periodEndTime,\\n        address[] calldata accounts\\n    )\\n        external\\n        view\\n        returns (uint256[] memory);\\n\\n    /// @notice Calculates the yield for the total supply for a period.\\n    /// @param periodStartTime The start timestamp.\\n    /// @param periodEndTime The end timestamp.\\n    /// @return The yield for the period.\\n    function totalYield(uint48 periodStartTime, uint48 periodEndTime) external view returns (uint256);\\n\\n    /// @notice Returns the yield distribution for a period.\\n    /// @dev The yield is distributed pro rata based on the deal historical holding share of each holder in the period.\\n    /// @dev CAUTION: This function is gas-intensive and should be used with caution in transactional contexts.\\n    /// @param periodStartTime The start timestamp.\\n    /// @param periodEndTime The end timestamp.\\n    function yieldDistribution(\\n        uint48 periodStartTime,\\n        uint48 periodEndTime\\n    )\\n        external\\n        view\\n        returns (YieldRecipient[] memory);\\n\\n    /// @notice Returns the start timestamp of the yield generation.\\n    function yieldGenerationStart() external view returns (uint48);\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                   VIEW FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Returns the list of current deal holders.\\n    function holders() external view returns (TokenHolder[] memory);\\n\\n    /// @notice Returns the holder details.\\n    /// @param account The account to get the holder details for.\\n    function holder(address account) external view returns (TokenHolder memory);\\n\\n    /// @notice Returns the deal manager address.\\n    function manager() external view returns (address);\\n\\n    /// @notice Returns the unique identifier of the deal.\\n    function id() external view returns (string memory);\\n\\n    /// @notice Returns the deal NAV.\\n    function nav() external view returns (NAV memory);\\n\\n    /// @notice Returns the deal share price.\\n    function price() external view returns (Price memory);\\n\\n    /// @notice Returns the deal metadata URI.\\n    function metadataURI() external view returns (string memory);\\n\\n    /// @notice Returns the total deal size.\\n    function totalSize() external view returns (uint256);\\n\\n    /// @notice Returns the open-ended status of the deal.\\n    function isOpenEnded() external view returns (bool);\\n\\n    /// @notice Returns the maximum number of holders for the deal.\\n    function maxHolders() external view returns (uint16);\\n\\n    /// @notice Returns the list of eligible accounts.\\n    function eligibleAccounts() external view returns (address[] memory);\\n\\n    /// @notice Returns whether an account is eligible for participation in the deal.\\n    function isEligibleAccount(address account) external view returns (bool);\\n\\n    /// @notice Reverts if the account is not eligible for participation in the deal.\\n    function checkAccountEligibility(address account) external view;\\n\\n    /// @notice Returns the list of fiat accounts.\\n    function fiatAccounts() external view returns (address[] memory);\\n\\n    /// @notice Returns whether an account is a fiat account.\\n    function isFiatAccount(address account) external view returns (bool);\\n\\n    /// @notice Returns the total yield of all fiat accounts.\\n    /// @param periodStartTime The start time of the yield calculation period.\\n    /// @param periodEndTime The end time of the yield calculation period.\\n    function fiatAccountsTotalYield(uint48 periodStartTime, uint48 periodEndTime) external view returns (uint256);\\n}\\n\"},\"src/interfaces/IDealFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.27;\\n\\nimport { IBeacon } from \\\"@oz/contracts/proxy/beacon/IBeacon.sol\\\";\\nimport { IERC20Metadata } from \\\"@oz/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\nimport { IAccessManaged } from \\\"@oz/contracts/access/manager/IAccessManaged.sol\\\";\\n\\nimport { BasisPoints } from \\\"../types/BasisPoints.sol\\\";\\nimport { IDeal } from \\\"./IDeal.sol\\\";\\nimport { IDealManager } from \\\"./IDealManager.sol\\\";\\nimport { IDealRegistryAware } from \\\"./IDealRegistryAware.sol\\\";\\n\\ninterface IDealFactory is IAccessManaged, IDealRegistryAware {\\n    /// @param deal The deal contract.\\n    /// @param config The deal manager configuration.\\n    struct DealManagerInitParams {\\n        IDeal deal;\\n        DealManagerConfig config;\\n    }\\n\\n    /// @param paymentCurrency The deal payment currency contract.\\n    /// @param minInvestment The minimum amount of deal shares an investor can acquire.\\n    /// @param capitalRecipient The account where the invested funds are transferred to.\\n    /// @param feeRecipient The account where the all the fees are transferred to.\\n    /// @param originationFee The origination fee in basis points.\\n    /// @param serviceFee The service fee in basis points.\\n    /// @param redemptionFee The redemption fee in basis points.\\n    struct DealManagerConfig {\\n        IERC20Metadata paymentCurrency;\\n        uint256 minInvestment;\\n        address capitalRecipient;\\n        address feeRecipient;\\n        BasisPoints originationFee;\\n        BasisPoints serviceFee;\\n        BasisPoints redemptionFee;\\n    }\\n\\n    /// @param dealManager The deal manager contract.\\n    /// @param config The deal configuration.\\n    /// @param paymentCurrency The deal payment currency contract.\\n    struct DealInitParams {\\n        IDealManager dealManager;\\n        DealConfig config;\\n        IERC20Metadata paymentCurrency;\\n    }\\n\\n    /// @param tokenName The name of the deal ERC20 token.\\n    /// @param tokenSymbol The symbol of the dael ERC20 token.\\n    /// @param id The unique identifier of the deal.\\n    /// @param metadataURI The URI of the metadata stored off-chain.\\n    /// @param totalSize The total size of the deal.\\n    /// @param isOpenEnded Whether the deal is open-ended or not.\\n    struct DealConfig {\\n        string tokenName;\\n        string tokenSymbol;\\n        string id;\\n        string metadataURI;\\n        uint256 totalSize;\\n        bool isOpenEnded;\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       EVENTS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Emitted when a new deal is deployed.\\n    event DealDeployed(string indexed id, IDeal indexed deal, IDealManager indexed manager);\\n\\n    /// @notice Emitted when the deal beacon is updated.\\n    event DealBeaconUpdated(IBeacon indexed oldBeacon, IBeacon indexed newBeacon);\\n\\n    /// @notice Emitted when the deal manager beacon is updated.\\n    event DealManagerBeaconUpdated(IBeacon indexed oldBeacon, IBeacon indexed newBeacon);\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       ERRORS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Thrown when the deal beacon address is zero.\\n    error DealBeaconZeroAddress();\\n\\n    /// @notice Thrown when the deal manager beacon address is zero.\\n    error DealManagerBeaconZeroAddress();\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Deploys a new deal.\\n    /// @dev The deal manager is created and the deal is registered in the deal registry.\\n    /// @param dealConfig The deal configuration.\\n    /// @param dealManagerConfig The deal manager configuration.\\n    /// @return The deal and deal manager contracts.\\n    function deployDeal(\\n        DealConfig calldata dealConfig,\\n        DealManagerConfig calldata dealManagerConfig\\n    )\\n        external\\n        returns (IDeal, IDealManager);\\n\\n    /// @notice Updates the deal beacon address.\\n    /// @param beacon The address of the beacon contract.\\n    function setDealBeacon(IBeacon beacon) external;\\n\\n    /// @notice Updates the deal manager beacon address.\\n    /// @param beacon The address of the deal manager beacon.\\n    function setDealManagerBeacon(IBeacon beacon) external;\\n\\n    /// @notice Returns the beacon address.\\n    function dealBeacon() external view returns (IBeacon);\\n\\n    /// @notice Returns the deal manager beacon address.\\n    function dealManagerBeacon() external view returns (IBeacon);\\n\\n    /// @notice Returns the deal transient initialization parameters.\\n    /// @dev These parameters are meant to be read by the deal initialization function.\\n    function dealInitParams() external view returns (DealInitParams memory);\\n\\n    /// @notice Returns the deal manager transient initialization parameters.\\n    /// @dev These parameters are meant to be read by the deal manager initialization function.\\n    function dealManagerInitParams() external view returns (DealManagerInitParams memory);\\n}\\n\"},\"src/interfaces/IDealManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.27;\\n\\nimport { IAccessManaged } from \\\"@oz/contracts/access/manager/IAccessManaged.sol\\\";\\n\\nimport { IDeal } from \\\"./IDeal.sol\\\";\\nimport { IBaseManager } from \\\"./manager/IBaseManager.sol\\\";\\nimport { IInvestmentManager } from \\\"./manager/IInvestmentManager.sol\\\";\\nimport { IPayoutManager } from \\\"./manager/IPayoutManager.sol\\\";\\nimport { IRedemptionManager } from \\\"./manager/IRedemptionManager.sol\\\";\\nimport { IKYCManager } from \\\"./manager/IKYCManager.sol\\\";\\n\\ninterface IDealManager is\\n    IAccessManaged,\\n    IBaseManager,\\n    IKYCManager,\\n    IInvestmentManager,\\n    IRedemptionManager,\\n    IPayoutManager\\n{\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       EVENTS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Emitted when the account is skipped during token minting due to ineligibility.\\n    event TokenMintSkippedIneligible(address indexed account, uint256 amount);\\n\\n    /// @notice Emitted when the deal tokens are minted.\\n    event TokensMinted(uint256 totalMinted);\\n\\n    /// @notice Emitted when the deal tokens are burned.\\n    event TokensBurned(uint256 totalBurned);\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Marks multiple accounts as fiat accounts.\\n    /// @param accounts Array of accounts to mark as fiat accounts.\\n    function addDealFiatAccounts(address[] calldata accounts) external;\\n\\n    /// @notice Removes multiple accounts from the fiat accounts list.\\n    /// @param accounts Array of accounts to remove from the fiat accounts list.\\n    function removeDealFiatAccounts(address[] calldata accounts) external;\\n\\n    /**\\n     * @notice Allows to mint tokens to multiple addresses.\\n     * @dev Should the contract be unable to mint tokens to a specific account, due to ineligibility or any other\\n     * constrain violation, that account will be skipped and the corresponding event will be emitted.\\n     * @param targets Array of mint amounts and addresses.\\n     * @return totalMinted The total amount of tokens minted.\\n     * @return count The number of eligible accounts that were minted.\\n     */\\n    function mintDealTokens(IDeal.Mint[] calldata targets) external returns (uint256 totalMinted, uint256 count);\\n\\n    /// @notice Allows to burn tokens from multiple addresses.\\n    /// @param targets Array of burn amounts and addresses.\\n    /// @return totalBurned The total amount of tokens burned.\\n    function burnDealTokens(IDeal.Burn[] calldata targets) external returns (uint256 totalBurned);\\n\\n    /// @notice Transfers deal tokens between accounts.\\n    /// @param from The account to transfer tokens from.\\n    /// @param to The account to transfer tokens to.\\n    /// @param amount The amount of tokens to transfer.\\n    function transferDealTokens(address from, address to, uint256 amount) external;\\n\\n    /// @notice Updates the deal NAV.\\n    /// @param nav New NAV value.\\n    function setDealNAV(uint256 nav) external;\\n\\n    /// @notice Updates the deal metadata URI.\\n    /// @param metadataURI New metadata URI.\\n    function setDealMetadataURI(string calldata metadataURI) external;\\n\\n    /// @notice Updates the total deal size.\\n    /// @param totalSize New total deal size.\\n    function setDealTotalSize(uint256 totalSize) external;\\n\\n    /// @notice Updates the deal open-ended status.\\n    /// @param status New open-ended status.\\n    function setDealOpenEnded(bool status) external;\\n\\n    /// @notice Updates the maximum number of holders for the deal.\\n    /// @param maxHolders New maximum number of holders.\\n    function setDealMaxHolders(uint16 maxHolders) external;\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                   VIEW FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Returns the available funds in the payment currency.\\n    /// @dev The available funds can be used for allocating new payouts OR can be withdrawn by the originator.\\n    function availableFunds() external view returns (uint256);\\n\\n    /// @notice The total amount of reserved funds.\\n    function reservedFunds() external view returns (uint256);\\n}\\n\"},\"src/interfaces/IDealRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.27;\\n\\ninterface IDealRegistry {\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       EVENTS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Emitted when a deal is added to the registry.\\n    event DealAdded(string indexed id, address indexed deal);\\n\\n    /// @notice Emitted when a deal is removed from the registry.\\n    event DealRemoved(string indexed id, address indexed deal);\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       ERRORS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Thrown when the deal is already registered.\\n    error DuplicateDeal(string id, address deal);\\n\\n    /// @notice Thrown when the deal is not found.\\n    error DealNotFound(string id);\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Adds a deal to the registry.\\n    /// @param id The deal ID.\\n    /// @param deal The deal address.\\n    function add(string calldata id, address deal) external;\\n\\n    /// @notice Removes a deal from the registry by ID.\\n    /// @param id The deal ID.\\n    function remove(string calldata id) external;\\n\\n    /// @notice Returns a deal entry by ID.\\n    /// @param id The deal ID.\\n    /// @return The deal address.\\n    function get(string calldata id) external view returns (address);\\n\\n    /// @notice Checks if the deal is registered.\\n    /// @param id The deal ID.\\n    /// @return True if the deal is registered, false otherwise.\\n    function contains(string calldata id) external view returns (bool);\\n\\n    /// @notice Returns the list of all deals.\\n    /// @return The list of deal addresses.\\n    function list() external view returns (address[] memory);\\n\\n    /// @notice Returns the number of deals in the registry.\\n    /// @return The number of deals.\\n    function count() external view returns (uint256);\\n\\n    /// @notice Returns the deal address by index.\\n    /// @param index The deal index.\\n    /// @return The deal address.\\n    function at(uint256 index) external view returns (address);\\n}\\n\"},\"src/interfaces/IDealRegistryAware.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.27;\\n\\nimport { IDealRegistry } from \\\"./IDealRegistry.sol\\\";\\n\\ninterface IDealRegistryAware {\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       EVENTS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Emitted when the deal registry is updated.\\n    event DealRegistryUpdated(IDealRegistry indexed oldRegistry, IDealRegistry indexed newRegistry);\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       ERRORS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Thrown when the deal registry address is zero.\\n    error DealRegistryZeroAddress();\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Updates the deal registry address.\\n    /// @param registry The address of the deal registry.\\n    function setDealRegistry(IDealRegistry registry) external;\\n\\n    /// @notice Returns the deal registry address.\\n    function dealRegistry() external view returns (IDealRegistry);\\n}\\n\"},\"src/interfaces/manager/IBaseManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.27;\\n\\nimport { IERC20Metadata } from \\\"@oz/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\n\\nimport { IDeal } from \\\"../IDeal.sol\\\";\\n\\ninterface IBaseManager {\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       EVENTS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Emitted when the capital recipient is updated.\\n    event CapitalRecipientUpdated(address oldCapitalRecipient, address newCapitalRecipient);\\n\\n    /// @notice Emitted when the fee recipient is updated.\\n    event FeeRecipientUpdated(address oldFeeRecipient, address newFeeRecipient);\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       ERRORS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Thrown if the provided amount is zero, when it should be greater than zero.\\n    error ZeroAmount();\\n\\n    /// @notice Thrown if the deal address is zero.\\n    error DealZeroAddress();\\n\\n    /// @notice Thrown if the deal token decimals differ from the payment currency decimals.\\n    error PaymentCurrencyDealDecimalMismatch();\\n\\n    /// @notice Thrown if the payment currency decimals value is greater than deal token decimals.\\n    error PaymentCurrencyInvalidDecimals();\\n\\n    /// @notice Thrown if the currency address is zero.\\n    error PaymentCurrencyZeroAddress();\\n\\n    /// @notice Thrown if the capital recipient address is zero.\\n    error CapitalRecipientZeroAddress();\\n\\n    /// @notice Thrown if the fee recipient address is zero.\\n    error FeeRecipientZeroAddress();\\n\\n    /// @notice Thrown when the available funds are insufficient for the operation.\\n    error InsufficientFunds(uint256 available, uint256 required);\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                        FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Sends the payment currency to the capital recipient.\\n    /// @param amount The amount of the payment currency.\\n    function withdrawFundsToCapitalRecipient(uint256 amount) external;\\n\\n    /// @notice Updates the capital recipient address.\\n    /// @param recipient New capital recipient address.\\n    function setCapitalRecipient(address recipient) external;\\n\\n    /// @notice Updates the fee recipient address.\\n    /// @param recipient New fee recipient address.\\n    function setFeeRecipient(address recipient) external;\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                   VIEW FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Returns the address of the deal under management.\\n    function deal() external view returns (IDeal);\\n\\n    /// @notice Returns the capital recipient address.\\n    function capitalRecipient() external view returns (address);\\n\\n    /// @notice Returns the fee recipient address.\\n    function feeRecipient() external view returns (address);\\n\\n    /// @notice Returns the deal payment currency address.\\n    function paymentCurrency() external view returns (IERC20Metadata);\\n}\\n\"},\"src/interfaces/manager/IInvestmentManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.27;\\n\\nimport { BasisPoints } from \\\"../../types/BasisPoints.sol\\\";\\n\\ninterface IInvestmentManager {\\n    /// @notice The investment offer struct.\\n    /// @param id The offer ID.\\n    /// @param amount The offered amount.\\n    /// @param escrowAmount The amount that is currently escrowed (including the reserved fee).\\n    /// @param investor The investor address.\\n    /// @param fee The fee (in basis points) that will be applied to the invested amount.\\n    /// @param escrowReleaseDate The date (timestamp) the investment will be escrowed until.\\n    struct InvestmentOffer {\\n        uint256 id;\\n        uint256 amount;\\n        uint256 escrowAmount;\\n        address investor;\\n        BasisPoints fee;\\n        uint48 escrowReleaseDate;\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       EVENTS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Emitted when the origination fee is updated.\\n    event OriginationFeeUpdated(BasisPoints oldOriginationFee, BasisPoints newOriginationFee);\\n\\n    /// @notice Emitted when the minimum investment is updated.\\n    event MinInvestmentUpdated(uint256 oldMinInvestment, uint256 newMinInvestment);\\n\\n    /// @notice Emitted when an investment offer is submitted.\\n    event OfferSubmitted(\\n        uint256 indexed id,\\n        address indexed investor,\\n        uint256 amount,\\n        BasisPoints fee,\\n        uint256 escrowAmount,\\n        uint48 escrowReleaseDate\\n    );\\n\\n    /// @notice Emitted when an investment offer is reviewed by the originator\\n    event OfferReviewed(\\n        uint256 indexed id, address indexed investor, uint256 acceptedAmount, uint256 feeAmount, uint256 refundAmount\\n    );\\n\\n    /// @notice Emitted when an investment offer is cancelled by the investor.\\n    event OfferCancelled(uint256 indexed id, address indexed investor);\\n\\n    /// @notice Emitted when an investment offer is deleted.\\n    event OfferDeleted(uint256 indexed id);\\n\\n    /// @notice Emitted when the escrow period is updated.\\n    event OfferEscrowPeriodUpdated(uint48 oldPeriod, uint48 newPeriod);\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       ERRORS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Thrown when the non-zero min investment amount is too low for safe computations.\\n    error MinInvestmentTooLow();\\n\\n    /// @notice Thrown if the min investment amount is too high (above the maximum investment amount).\\n    error MinInvestmentTooHigh();\\n\\n    /// @notice Thrown if the origination fee is too high.\\n    error OriginationFeeTooHigh();\\n\\n    /// @notice Thrown if the caller is not an expected investor account.\\n    error CallerIsNotInvestor();\\n\\n    /// @notice Thrown if the investment offer is not found.\\n    error OfferNotFound();\\n\\n    /// @notice Thrown upon an attempt to cancel offer prior to escrow release date.\\n    error OfferIsLocked(uint48 escrowReleaseDate);\\n\\n    /// @notice Thrown if the calculated fee exceeds the maximum fee investor is willing to pay.\\n    error OfferMaxFeeExceeded(uint256 calculatedFee, uint256 maxFee);\\n\\n    /// @notice Thrown if the investment offer escrow period is too long.\\n    error OfferEscrowPeriodTooLong();\\n\\n    /// @notice Thrown if the investment amount is too low.\\n    error InvestmentAmountTooLow(uint256 amount, uint256 min);\\n\\n    /// @notice Thrown if the accepted amount is higher than the offered amount.\\n    error OfferAcceptedAmountTooHigh(uint256 acceptedAmount, uint256 offerAmount);\\n\\n    /// @notice Thrown if the there is not enough deal tokens available to fulfill the investment offer.\\n    error InsufficientLiquidity();\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Updates the minimum investment.\\n    /// @param amount New minimum investment amount in payment currency.\\n    function setMinInvestment(uint256 amount) external;\\n\\n    /// @notice Updates the origination fee.\\n    /// @param fee New origination fee.\\n    function setOriginationFee(BasisPoints fee) external;\\n\\n    /// @notice Sets the period of time the investment offer will be escrowed.\\n    function setOfferEscrowPeriod(uint48 period) external;\\n\\n    /// @notice Allows investors to submit an investment offer.\\n    /// @param amount The amount investor is willing to invest.\\n    /// @param maxFee The maximum fee (in payment currency) the investor is willing to pay.\\n    /// @return The investment offer structure.\\n    function submitOffer(uint256 amount, uint256 maxFee) external returns (InvestmentOffer memory);\\n\\n    /// @notice Allows investors to cancel their investment offer after escrow period.\\n    /// @dev The investor will receive a refund of the escrowed amount.\\n    /// @param id The investment offer ID.\\n    function cancelOffer(uint256 id) external;\\n\\n    /// @notice Allows the originator to accept or reject an investment offer.\\n    /// @dev Partial acceptance is allowed.\\n    /// @param id The investment offer ID.\\n    /// @param acceptedAmount The amount of the investment offer accepted.\\n    function reviewOffer(uint256 id, uint256 acceptedAmount) external;\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                   VIEW FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Returns the investment offer by ID.\\n    /// @param id The investment offer ID.\\n    /// @return The investment offer details.\\n    function investmentOffer(uint256 id) external view returns (InvestmentOffer memory);\\n\\n    /// @notice Returns all investment offers.\\n    function investmentOffers() external view returns (InvestmentOffer[] memory offers);\\n\\n    /// @notice Returns the current escrow balance.\\n    /// @dev The escrow balance is the sum of all investment offers escrowed amounts.\\n    function totalEscrowBalance() external view returns (uint256);\\n\\n    /// @notice Returns the period of time the investment offer will be escrowed.\\n    function offerEscrowPeriod() external view returns (uint48);\\n\\n    /// @notice Returns the minimum investment amount in payment currency.\\n    function minInvestment() external view returns (uint256);\\n\\n    /// @notice Returns the origination fee.\\n    function originationFee() external view returns (BasisPoints);\\n\\n    /// @notice Returns the origination fee amount in payment currency.\\n    /// @param amount The investment amount to calculate the fee for.\\n    function calculateOriginationFee(uint256 amount) external view returns (uint256);\\n\\n    /// @notice Returns the amount available for investment.\\n    function availableForInvestment() external view returns (uint256);\\n}\\n\"},\"src/interfaces/manager/IKYCManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.27;\\n\\ninterface IKYCManager {\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Marks multiple accounts as eligible for participating in the deal.\\n    /// @param accounts Array of accounts to mark as eligible.\\n    function addDealEligibleAccounts(address[] calldata accounts) external;\\n\\n    /// @notice Removes multiple accounts from the eligible accounts list.\\n    /// @param accounts Array of accounts to remove from the eligible accounts list.\\n    function removeDealEligibleAccounts(address[] calldata accounts) external;\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                   VIEW FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Returns true if the account is eligible to participate in the managed deal.\\n    function isEligibleAccount(address account) external returns (bool);\\n}\\n\"},\"src/interfaces/manager/IPayoutManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.27;\\n\\nimport { BasisPoints } from \\\"../../types/BasisPoints.sol\\\";\\n\\ninterface IPayoutManager {\\n    struct PayoutBalance {\\n        address account;\\n        uint256 balance;\\n    }\\n\\n    struct PrincipalPayout {\\n        address account;\\n        uint256 amount;\\n        uint256 burnTokenAmount;\\n        uint256 newTokenBalance;\\n        bool isFiatAccount;\\n    }\\n\\n    struct InterestPayout {\\n        address account;\\n        uint256 amount;\\n        bool isFiatAccount;\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       EVENTS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Emitted when the principal payout amount is accounted for an individual account.\\n    event PrincipalPayoutAccounted(\\n        string indexed id, address indexed account, bool isFiatAccount, uint256 amount, uint256 tokensBurned\\n    );\\n\\n    /// @notice Emitted once the principal payout process is finalized.\\n    event PrincipalPayoutFinalized(\\n        string indexed id, uint256 totalPayoutAmount, uint256 onchainPayoutAmount, uint256 tokensBurned\\n    );\\n\\n    /// @notice Emitted when the interest payout amount is accounted for a holder.\\n    event InterestPayoutAccounted(\\n        string indexed id,\\n        address indexed account,\\n        bool isFiatAccount,\\n        uint256 amount,\\n        uint48 periodStartTime,\\n        uint48 periodEndTime\\n    );\\n\\n    /// @notice Emitted when the interest payout process is initiated.\\n    event InterestPayoutFinalized(\\n        string indexed id, uint256 onchainPayoutAmount, uint256 feeAmount, uint48 periodStartTime, uint48 periodEndTime\\n    );\\n\\n    /// @notice Emitted when the balance of an account is updated.\\n    event PayoutBalanceUpdated(address indexed account, uint256 oldBalance, uint256 newBalance);\\n\\n    /// @notice Emitted when the interest payout amount is claimed by an account.\\n    event PayoutClaimed(address indexed account, uint256 amount);\\n\\n    /// @notice Emitted when the interest payout amount is pushed to an account by the deal admin.\\n    event PayoutPushed(address indexed account, uint256 amount);\\n\\n    /// @notice Emitted when the interest payout amount is revoked from an account by the admin.\\n    event PayoutRevoked(address indexed account, uint256 amount);\\n\\n    /// @notice Emitted when the account is skipped during the payout push due to ineligibility.\\n    event PayoutPushSkippedIneligible(address indexed account, uint256 amount);\\n\\n    /// @notice Emitted when the service fee is updated.\\n    event ServiceFeeUpdated(BasisPoints oldServiceFee, BasisPoints newServiceFee);\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       ERRORS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Thrown if the payout ID already exists.\\n    error DuplicatePayoutId(string id);\\n\\n    /// @notice Thrown when account claiming the payout has no owed amount.\\n    error NothingToClaim();\\n\\n    /// @notice Thrown if the service fee is too high.\\n    error ServiceFeeTooHigh();\\n\\n    /// @notice Thrown if the end timestamp is before the start timestamp.\\n    error InvalidInterestPayoutPeriod(uint48 periodStartTime, uint48 periodEndTime);\\n\\n    /// @notice Thrown if the total supply is insufficient to accommodate the burn, required for the payout.\\n    error InsufficientTotalSupply();\\n\\n    /// @notice Thrown if when payout is calculated for a deal before the yield generation is started.\\n    error YieldGenerationNotStarted();\\n\\n    /// @notice Thrown if an account has no payout balance, therefore the payout cannot be revoked, claimed or pushed.\\n    error ZeroPayoutBalance();\\n\\n    /// @notice Thrown upon an attempt to revoke a payout from an account that is eligible for the payout.\\n    error RevokingPayoutFromEligibleAccount(address account);\\n\\n    /// @notice Thrown if the deal NAV is invalid.\\n    error InvalidDealNAV(uint256 nav);\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Updates the service fee.\\n    /// @param fee New service fee.\\n    function setServiceFee(BasisPoints fee) external;\\n\\n    /// @notice Initiates the principal payout process.\\n    /// @dev The funds are distributed pro rata based on the deal current holding share of each holder.\\n    /// @param id The unique ID of the payout.\\n    /// @param totalPayoutAmount The total amount to be paid out (fiat and crypto combined).\\n    /// @return onchainPayoutAmount The effective amount to be paid out on-chain (sum of payouts to non-fiat accounts).\\n    /// @return totalTokensBurned The total amount of tokens burned.\\n    function initiatePrincipalPayout(\\n        string calldata id,\\n        uint256 totalPayoutAmount\\n    )\\n        external\\n        returns (uint256 onchainPayoutAmount, uint256 totalTokensBurned);\\n\\n    /// @notice Initiates the interest payout process.\\n    /// @dev The funds are distributed pro rata based on the deal historical holding share of each holder.\\n    /// @param id The unique ID of the payout.\\n    /// @param onchainPayoutAmount The amount of payment currency to be distributed on-chain.\\n    /// @param periodEndTime The end time of the interest payout period.\\n    /// @return effectiveOnchainPayoutAmount The effective payout amount (sum of individual payouts).\\n    /// @return feeAmount The service fee amount.\\n    function initiateInterestPayout(\\n        string calldata id,\\n        uint256 onchainPayoutAmount,\\n        uint48 periodEndTime\\n    )\\n        external\\n        returns (uint256 effectiveOnchainPayoutAmount, uint256 feeAmount);\\n\\n    /// @notice Returns the distribution of the principal payout amount.\\n    /// @dev Allows to preview the distribution before initiating the payout.\\n    /// @param totalPayoutAmount The gross total amount to be paid out (fiat and crypto combined).\\n    /// @return The list of payouts.\\n    /// @return effectiveOnchainPayoutAmount The effective amount to be paid out onchain (sum of payouts to non-fiat\\n    /// accounts).\\n    /// @return tokensToBurn The total amount of tokens to burn.\\n    function previewPrincipalPayout(uint256 totalPayoutAmount)\\n        external\\n        view\\n        returns (PrincipalPayout[] memory, uint256 effectiveOnchainPayoutAmount, uint256 tokensToBurn);\\n\\n    /// @notice Returns the distribution of the interest payout amount.\\n    /// @dev Allows to preview the distribution before initiating the payout.\\n    /// @param onchainPayoutAmount The amount to distribute.\\n    /// @param periodStartTime The start time of the interest payout period.\\n    /// @param periodEndTime The end time of the interest payout period.\\n    /// @return The list of payouts.\\n    /// @return effectiveOnchainPayoutAmount The sum of the payout amounts.\\n    /// @return serviceFeeAmount The service fee amount.\\n    function previewInterestPayout(\\n        uint256 onchainPayoutAmount,\\n        uint48 periodStartTime,\\n        uint48 periodEndTime\\n    )\\n        external\\n        view\\n        returns (InterestPayout[] memory, uint256 effectiveOnchainPayoutAmount, uint256 serviceFeeAmount);\\n\\n    /// @notice Sends the owed amount to the provided accounts.\\n    /// @param accounts The list of accounts to push the owed amounts to.\\n    function pushPayout(address[] calldata accounts) external;\\n\\n    /// @notice Sends any remaining owed amount to the caller.\\n    function claimPayout() external;\\n\\n    /// @notice Revokes full accounted payout amount for an account and transfers the funds back to the originator.\\n    function revokePayout(address account) external;\\n\\n    /// @notice Returns the service fee.\\n    function serviceFee() external view returns (BasisPoints);\\n\\n    /// @notice Returns the total payout balance.\\n    function totalPayoutBalance() external view returns (uint256);\\n\\n    /// @notice Returns the outstanding payout amount for an account.\\n    function payoutBalance(address account) external view returns (uint256);\\n\\n    /// @notice Returns the outstanding payout balances for all accounts.\\n    function payoutBalances() external view returns (PayoutBalance[] memory);\\n\\n    /// @notice Returns the start time of the current payout period.\\n    function payoutPeriodStartTime() external view returns (uint48);\\n\\n    /// @notice Returns the serve fee amount in payment currency.\\n    /// @param amount The amount to calculate the service fee for.\\n    function calculateServiceFee(uint256 amount) external view returns (uint256);\\n\\n    /// @notice Returns the minimum allowed deal token balance after the payout.\\n    /// @dev The deal token balance below this threshold is considered dust and must be burned during the payout.\\n    function payoutDustThreshold() external view returns (uint256);\\n}\\n\"},\"src/interfaces/manager/IRedemptionManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.27;\\n\\nimport { BasisPoints } from \\\"../../types/BasisPoints.sol\\\";\\n\\ninterface IRedemptionManager {\\n    /// @notice The redemption request struct.\\n    /// @param id The redemption request ID.\\n    /// @param investor The account that requested the redemption.\\n    /// @param amount The amount of tokens requested for redemption.\\n    /// @param availableAmount The accepted amount of tokens that are not redeemed yet.\\n    /// @param fee The fee (in basis points) that will be applied to the redeemed amount.\\n    /// @param requestReleaseDate The date (timestamp) the redemption request will be locked until.\\n    /// @param queued The flag indicating if the request is accepted and queued for processing.\\n    struct RedemptionRequest {\\n        uint256 id;\\n        address investor;\\n        uint256 amount;\\n        uint256 availableAmount;\\n        BasisPoints fee;\\n        uint48 requestReleaseDate;\\n        bool queued;\\n    }\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       EVENTS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Emitted when the redemption fee is updated.\\n    event RedemptionFeeUpdated(BasisPoints oldRedemptionFee, BasisPoints newRedemptionFee);\\n\\n    /// @notice Emitted when the redemption lock period is updated.\\n    event RedemptionLockPeriodUpdated(uint48 oldRedemptionLockPeriod, uint48 newRedemptionLockPeriod);\\n\\n    /// @notice Emitted when the redemption budget is updated.\\n    event RedemptionBudgetUpdated(uint256 oldRedemptionBudget, uint256 newRedemptionBudget);\\n\\n    /// @notice Emitted when a redemption request is submitted.\\n    event RedemptionRequested(uint256 indexed id, address indexed investor, uint256 amount, BasisPoints fee);\\n\\n    /// @notice Emitted when a redemption request is reviewed by the originator and enqueued for processing.\\n    event RedemptionReviewed(\\n        uint256 indexed id,\\n        address indexed investor,\\n        uint256 acceptedAmount,\\n        uint256 rejectedAmount,\\n        uint256 redeemedAmount,\\n        uint256 availableAmount,\\n        uint48 requestReleaseDate\\n    );\\n\\n    /// @notice Emitted when a redemption request is processed and the tokens are redeemed (fully or partially).\\n    event RedemptionExecuted(\\n        uint256 indexed id, address indexed investor, uint256 amount, uint256 feeAmount, uint256 availableAmount\\n    );\\n\\n    /// @notice Emitted when a redemption request is cancelled by the investor.\\n    event RedemptionCancelled(uint256 indexed id, address indexed investor);\\n\\n    /// @notice Emitted when a redemption request is deleted.\\n    event RedemptionDeleted(uint256 indexed id);\\n\\n    /// @notice Emitted when the redemption request amount is updated.\\n    event RedemptionAmountUpdated(uint256 indexed id, uint256 oldAmount, uint256 newAmount);\\n\\n    /// @notice Emitted when the account is skipped during token redemption due to ineligibility.\\n    event RedemptionSkippedIneligible(address indexed investor, uint256 amount);\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       ERRORS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Thrown when the redemption fee is too high.\\n    error RedemptionFeeTooHigh();\\n\\n    /// @notice Thrown when the requested redemption amount is too low.\\n    error RedemptionAmountTooLow(uint256 amount, uint256 min);\\n\\n    /// @notice Throws if the redemption lock period is too long.\\n    error RedemptionLockPeriodTooLong();\\n\\n    /// @notice Thrown when the calculated fee exceeds the fee investor is willing to pay.\\n    error RedemptionMaxFeeExceeded(uint256 calculatedFee, uint256 maxFee);\\n\\n    /// @notice Thrown when an investor attempts to submit a new redemption request, while another request is pending.\\n    error RedemptionRequestAlreadyExists();\\n\\n    /// @notice Thrown when the redemption request is not found.\\n    error RedemptionRequestNotFound();\\n\\n    /// @notice Trows when redemption request already reviewed\\n    error RedemptionRequestAlreadyReviewed();\\n\\n    /// @notice Thrown upon an attempt to cancel redemption request prior to release date.\\n    error RedemptionRequestIsLocked(uint48 requestReleaseDate);\\n\\n    /// @notice Thrown if the accepted amount is higher than the requested redemption amount.\\n    error RedemptionAcceptedAmountTooHigh(uint256 acceptedAmount, uint256 requestedRedemptionAmount);\\n\\n    /// @notice Thrown upon an attempt to relay redemption request for non-fiat account.\\n    error RelayingRedemptionRequestForNonFiatAccount(address investor);\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                       FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Updates the redemption fee.\\n    /// @param fee The new redemption fee.\\n    function setRedemptionFee(BasisPoints fee) external;\\n\\n    /// @notice Updates the redemption lock period.\\n    /// @param period The new redemption lock period.\\n    function setRedemptionLockPeriod(uint48 period) external;\\n\\n    /// @notice Updates the redemption budget.\\n    /// @param budget The new redemption budget (in payment currency).\\n    function setRedemptionBudget(uint256 budget) external;\\n\\n    /// @notice Submits a redemption request.\\n    /// @param amount The amount of tokens to redeem.\\n    /// @param maxFee The maximum fee (in payment currency) the investor is willing to pay.\\n    /// @return The redemption request.\\n    function submitRedemptionRequest(uint256 amount, uint256 maxFee) external returns (RedemptionRequest memory);\\n\\n    /// @notice Allows admin to submit a redemption request on behalf of the fiat account.\\n    /// @param investor The investor address.\\n    /// @param amount The amount of tokens to redeem.\\n    function relayRedemptionRequest(address investor, uint256 amount) external returns (RedemptionRequest memory);\\n\\n    /// @notice Allows originator to review and accept a redemption request.\\n    /// @param id The redemption request ID.\\n    /// @param acceptedAmount The amount of the deal tokens accepted for redemption.\\n    function reviewRedemptionRequest(uint256 id, uint256 acceptedAmount) external;\\n\\n    /// @notice Allows investor to withdraw their redemption request.\\n    /// @param id The redemption request ID.\\n    function cancelRedemptionRequest(uint256 id) external;\\n\\n    /*//////////////////////////////////////////////////////////////////////////\\n                                   VIEW FUNCTIONS\\n    //////////////////////////////////////////////////////////////////////////*/\\n\\n    /// @notice Returns the redemption request for given investor.\\n    /// @param investor The investor address.\\n    /// @return The redemption request details.\\n    function redemptionRequest(address investor) external view returns (RedemptionRequest memory);\\n\\n    /// @notice Returns the redemption request by ID.\\n    /// @param id The redemption request ID.\\n    /// @return The redemption request details.\\n    function redemptionRequest(uint256 id) external view returns (RedemptionRequest memory);\\n\\n    /// @notice Returns all redemption requests.\\n    function redemptionRequests() external view returns (RedemptionRequest[] memory);\\n\\n    /// @notice Returns the redemption lock period.\\n    function redemptionLockPeriod() external view returns (uint48);\\n\\n    /// @notice Returns the redemption budget.\\n    function redemptionBudget() external view returns (uint256);\\n\\n    /// @notice Returns the minimum redemption amount.\\n    function minRedemption() external view returns (uint256);\\n\\n    /// @notice Returns the redemption fee.\\n    function redemptionFee() external view returns (BasisPoints);\\n\\n    /// @notice Returns the redemption fee amount (in payment currency) for redeeming the specified amount of tokens.\\n    /// @param amount The amount of tokens to redeem.\\n    function calculateRedemptionFee(uint256 amount) external view returns (uint256);\\n\\n    /// @notice Returns the redemption queue total value.\\n    /// @dev This is the total amount of deal tokens that are currently locked in redemption queue.\\n    function redemptionQueueTotal() external view returns (uint256);\\n}\\n\"},\"src/types/BasisPoints.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.27;\\n\\nimport { FixedPointMathLib } from \\\"@solady/utils/FixedPointMathLib.sol\\\";\\n\\ntype BasisPoints is uint16;\\n\\nusing BasisPointsLib for BasisPoints global;\\n\\n// solhint-disable-next-line private-vars-leading-underscore\\nfunction bp(uint16 value) pure returns (BasisPoints) {\\n    return BasisPoints.wrap(value);\\n}\\n\\nlibrary BasisPointsLib {\\n    using FixedPointMathLib for uint256;\\n\\n    /// @notice Special constant for one basis point (0.01%).\\n    uint256 public constant DENOMINATOR = 1e4; // 10000 basis points = 100%\\n\\n    /// @notice Calculates the percentage of a value.\\n    function percent(BasisPoints basisPoints, uint256 value) internal pure returns (uint256) {\\n        return value.mulDivUp(BasisPoints.unwrap(basisPoints), DENOMINATOR);\\n    }\\n\\n    /// @notice Unwrap the basis points value to a uint256.\\n    function toUint(BasisPoints basisPoints) internal pure returns (uint256) {\\n        return BasisPoints.unwrap(basisPoints);\\n    }\\n}\\n\"}}}}","ConstructorArguments":"","ContractName":"src/DealManager.sol:DealManager","EVMVersion":"Default","OptimizationUsed":"1","Library":"","LicenseType":"","CompilerVersion":"zkVM-0.8.27-1.0.1","Runs":"","SwarmSource":"","Proxy":"0","Implementation":"","ZkSolcVersion":"v1.5.4","ZkCompilerVersion":"v1.5.4"}]}