{"sources":{"src/CipherNexusRebate.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {ERC721} from \"solady/tokens/ERC721.sol\";\nimport {Base64} from \"solady/utils/Base64.sol\";\nimport {LibString} from \"solady/utils/LibString.sol\";\n\ninterface IERC721AgentRegistryC2 {\n    function balanceOf(address owner) external view returns (uint256);\n}\n\n/**\n * @title CipherNexusRebate (Scheme C2 V2: Two-Way Referral Matrix + Tiered Partner Rebate + Co-Win Epoch Vault)\n * @notice Provably fair on-chain referral, multi-key partner progression & co-win jackpot protocol (Red-Team Hardened V2):\n *         - Tier 0 (Free Pass, up to 120): 1 free mint per .ai Agent ID holder (0 BNB).\n *         - Tier 1 (Nexus Gold Key): Standard price 0.0015 BNB; Referral price 0.00135 BNB (10% instant discount).\n *         - Multi-Key Partner Rebate Progression (incentivizes buying multiple Gold Keys):\n *             * 0 Gold Keys (Standard Referrer): 15% instant BNB rebate\n *             * 1-2 Gold Keys (Silver Partner): 25% instant BNB rebate\n *             * >=3 Gold Keys (Sovereign Partner): 35% instant BNB rebate\n *         - Every-5th-Key Co-Win Epoch Vault (20% of every sale enters `vaultPool`):\n *             * Every 5th Gold Key (#5, #10, #15...) triggers the Epoch Vault:\n *               - Buyer immediately wins 75% of `vaultPool` (>100% instant +EV!)\n *               - Buyer's bound Referrer simultaneously wins 10% of `vaultPool` (Co-Win Bonus!)\n *               - 15% rolls over to seed the next Epoch!\n *         - Fomo3D Tail Vault Rescue: after 12h without a new Gold Key or upon sellout, `lastGoldBuyer`\n *           sweeps 100% of remaining `vaultPool` (zero locked funds).\n */\ncontract CipherNexusRebate is ERC721 {\n    using LibString for uint256;\n\n    address public constant AGENT_ID_REGISTRY = 0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F;\n\n    address public immutable PAYEE;\n    address public immutable OWNER;\n\n    uint256 public constant MAX_FREE_SUPPLY = 120;\n    uint256 public constant MAX_GOLD_SUPPLY = 1380;\n    uint256 public constant MAX_SUPPLY = MAX_FREE_SUPPLY + MAX_GOLD_SUPPLY;\n    uint256 public constant FREE_SUPPLY = MAX_FREE_SUPPLY;\n\n    uint256 public constant KEY_PRICE = 0.0015 ether;\n    uint256 public constant PRICE = KEY_PRICE;\n    uint256 public constant REF_DISCOUNT_PRICE = 0.00135 ether; // 10% instant discount for buyer\n\n    uint256 public constant MAX_FREE_PER_WALLET = 1;\n    uint256 public constant MAX_GOLD_PER_WALLET = 20;\n    uint256 public constant MAX_PER_TX = 10;\n\n    // Tiered Partner Rebate Basis Points (out of 10,000 of actual paid amount)\n    uint256 public constant BASE_REFERRER_BPS = 1500;      // 15% (0 Gold Keys)\n    uint256 public constant SILVER_PARTNER_BPS = 2500;     // 25% (1-2 Gold Keys)\n    uint256 public constant SOVEREIGN_PARTNER_BPS = 3500;  // 35% (>=3 Gold Keys)\n\n    // Epoch Vault Parameters\n    uint256 public constant VAULT_POOL_BPS = 2000;         // 20% to Epoch Vault Pool\n    uint256 public constant EPOCH_SIZE = 5;                // Every 5th Gold Key triggers the Epoch Vault\n    uint256 public constant VAULT_BUYER_WIN_BPS = 7500;    // 75% of vaultPool to milestone buyer\n    uint256 public constant VAULT_REF_COWIN_BPS = 1000;    // 10% of vaultPool co-won by buyer's referrer!\n    uint256 public constant TAIL_TIMEOUT = 12 hours;\n\n    uint256 public totalSupply;\n    uint256 public freeMinted;\n    uint256 public goldMinted;\n\n    uint256 public vaultPool;\n    uint256 public totalReferralPaid;\n    uint256 public totalVaultPaid;\n    uint256 public totalEscrowedPayouts;\n\n    address public lastGoldBuyer;\n    uint256 public lastGoldMintTime;\n    bool public lastGoldBuyerIsAgent;\n\n    mapping(address => bool) public claimedFree;\n    mapping(address => uint256) public mintedBy;\n    mapping(address => uint256) public goldMintedBy;\n    mapping(address => address) public boundReferrer;\n    mapping(address => uint256) public referralEarnedBy;\n    mapping(address => uint256) public referralCountBy;\n    mapping(address => uint256) public claimablePayout;\n\n    mapping(uint256 => bool) public isGoldKey;\n    mapping(uint256 => uint256) public goldKeyNumber;\n\n    uint256 private _locked = 1;\n\n    event FreePassMinted(address indexed buyer, uint256 indexed tokenId);\n    event NexusKeyMinted(\n        address indexed buyer,\n        address indexed referrer,\n        uint256 indexed startTokenId,\n        uint256 qty,\n        uint256 totalPaid,\n        uint256 referrerRebate,\n        uint256 vaultWon\n    );\n    event ReferralRebatePaid(address indexed referrer, address indexed buyer, uint256 amount, uint256 rebateBps);\n    event EpochVaultWon(address indexed winner, address indexed referrer, uint256 indexed goldKeyNumber, uint256 buyerPrize, uint256 refCoPrize);\n    event TailVaultClaimed(address indexed winner, uint256 amount);\n    event PayoutCredited(address indexed recipient, uint256 amount);\n    event PayoutWithdrawn(address indexed recipient, address indexed to, uint256 amount);\n\n    error SoldOut();\n    error InvalidQuantity();\n    error WalletLimitExceeded();\n    error InsufficientPayment();\n    error FreeQuotaExhaustedOrNotAgent();\n    error InvalidReferrer();\n    error SlippageStateChanged();\n    error TailNotUnlocked();\n    error ZeroAddress();\n    error NothingToClaim();\n    error TransferFailed();\n    error Reentrancy();\n\n    modifier nonReentrant() {\n        if (_locked != 1) revert Reentrancy();\n        _locked = 2;\n        _;\n        _locked = 1;\n    }\n\n    constructor(address payee_) {\n        if (payee_ == address(0)) revert ZeroAddress();\n        PAYEE = payee_;\n        OWNER = payee_;\n    }\n\n    function name() public pure override returns (string memory) {\n        return \"Cipher Nexus Rebate\";\n    }\n\n    function symbol() public pure override returns (string memory) {\n        return \"CNEXUS\";\n    }\n\n    function owner() external view returns (address) {\n        return OWNER;\n    }\n\n    function totalMinted() external view returns (uint256) {\n        return totalSupply;\n    }\n\n    function mintOpen() external view returns (bool) {\n        return totalSupply < MAX_SUPPLY;\n    }\n\n    function MAX_PER_WALLET() external pure returns (uint256) {\n        return MAX_GOLD_PER_WALLET + MAX_FREE_PER_WALLET;\n    }\n\n    function supportsInterface(bytes4 interfaceId) public view override returns (bool) {\n        return interfaceId == 0x2a55205a || super.supportsInterface(interfaceId);\n    }\n\n    function royaltyInfo(uint256, uint256 salePrice) external view returns (address receiver, uint256 royaltyAmount) {\n        return (PAYEE, (salePrice * 500) / 10000);\n    }\n\n    function contractURI() external pure returns (string memory) {\n        string memory json = '{\"name\":\"Cipher Nexus Rebate\",\"description\":\"Two-way on-chain referral & every-5th-key co-win Epoch Vault on BNB Chain.\",\"fee_recipient\":\"0x0000000000000000000000000000000000000000\",\"seller_fee_basis_points\":500}';\n        return string(abi.encodePacked(\"data:application/json;base64,\", Base64.encode(bytes(json))));\n    }\n\n    /* -------------------------------------------------------------------------- */\n    /*                          VIEW & QUOTING FUNCTIONS                          */\n    /* -------------------------------------------------------------------------- */\n\n    function isEligibleFree(address account) public view returns (bool) {\n        if (freeMinted >= MAX_FREE_SUPPLY || totalSupply >= MAX_SUPPLY) return false;\n        if (claimedFree[account]) return false;\n        return _hasAgentId(account);\n    }\n\n    function isGoldPartner(address account) public view returns (bool) {\n        return goldMintedBy[account] > 0;\n    }\n\n    function referrerRebateBps(address referrer) public view returns (uint256) {\n        if (referrer == address(0)) return 0;\n        uint256 golds = goldMintedBy[referrer];\n        if (golds >= 3) return SOVEREIGN_PARTNER_BPS;\n        if (golds >= 1) return SILVER_PARTNER_BPS;\n        return BASE_REFERRER_BPS;\n    }\n\n    function price() public view returns (uint256) {\n        if (freeMinted < MAX_FREE_SUPPLY) return 0;\n        return KEY_PRICE;\n    }\n\n    function mintPrice() external view returns (uint256) {\n        return price();\n    }\n\n    function quote(address buyer, uint256 qty) public view returns (uint256) {\n        if (qty == 0) return 0;\n        if (qty == 1 && isEligibleFree(buyer)) return 0;\n        if (boundReferrer[buyer] != address(0)) {\n            return qty * REF_DISCOUNT_PRICE;\n        }\n        return qty * KEY_PRICE;\n    }\n\n    function quoteWithRef(address buyer, uint256 qty, address referrer)\n        public\n        view\n        returns (\n            uint256 buyerCost,\n            uint256 referrerRebate,\n            uint256 expectedBuyerVaultWin,\n            uint256 expectedRefCoWin\n        )\n    {\n        if (qty == 0) return (0, 0, 0, 0);\n        address activeRef = boundReferrer[buyer];\n        if (activeRef == address(0) && referrer != address(0) && referrer != buyer) {\n            activeRef = referrer;\n        }\n        bool hasRef = activeRef != address(0);\n\n        uint256 unitPrice = hasRef ? REF_DISCOUNT_PRICE : KEY_PRICE;\n        buyerCost = qty * unitPrice;\n\n        if (hasRef) {\n            referrerRebate = (buyerCost * referrerRebateBps(activeRef)) / 10000;\n        }\n\n        uint256 simPool = vaultPool;\n        uint256 currentGold = goldMinted;\n        uint256 perKeyVaultAdd = (unitPrice * VAULT_POOL_BPS) / 10000;\n        for (uint256 i = 1; i <= qty; ++i) {\n            simPool += perKeyVaultAdd;\n            if ((currentGold + i) % EPOCH_SIZE == 0) {\n                uint256 bWin = (simPool * VAULT_BUYER_WIN_BPS) / 10000;\n                uint256 rWin = hasRef ? (simPool * VAULT_REF_COWIN_BPS) / 10000 : 0;\n                simPool -= (bWin + rWin);\n                expectedBuyerVaultWin += bWin;\n                expectedRefCoWin += rWin;\n            }\n        }\n    }\n\n    function keysUntilNextVault() public view returns (uint256) {\n        uint256 rem = goldMinted % EPOCH_SIZE;\n        return EPOCH_SIZE - rem;\n    }\n\n    /* -------------------------------------------------------------------------- */\n    /*                             MINTING ENTRYPOINTS                            */\n    /* -------------------------------------------------------------------------- */\n\n    function mint() external payable nonReentrant {\n        _smartMint(msg.sender, 1, address(0), false);\n    }\n\n    function mint(uint256 qty) external payable nonReentrant {\n        _smartMint(msg.sender, qty, address(0), false);\n    }\n\n    function freeMint() external payable nonReentrant {\n        _smartMint(msg.sender, 1, address(0), false);\n    }\n\n    function claim() external payable nonReentrant {\n        _smartMint(msg.sender, 1, address(0), false);\n    }\n\n    function buyKey(uint256 qty) external payable nonReentrant {\n        _mintPaidKeys(msg.sender, qty, address(0), false);\n    }\n\n    function mintWithRef(uint256 qty, address referrer) external payable nonReentrant {\n        _mintPaidKeys(msg.sender, qty, referrer, true);\n    }\n\n    function buyKeyWithRef(uint256 qty, address referrer) external payable nonReentrant {\n        _mintPaidKeys(msg.sender, qty, referrer, true);\n    }\n\n    function mintWithRefExact(uint256 qty, address referrer, uint256 expectedGoldMinted) external payable nonReentrant {\n        if (goldMinted != expectedGoldMinted) revert SlippageStateChanged();\n        _mintPaidKeys(msg.sender, qty, referrer, true);\n    }\n\n    function _smartMint(address buyer, uint256 qty, address referrer, bool explicitRefCall) internal {\n        if (qty == 0 || qty > MAX_PER_TX) revert InvalidQuantity();\n        if (totalSupply + qty > MAX_SUPPLY) revert SoldOut();\n\n        uint256 minPaid = qty * (boundReferrer[buyer] != address(0) ? REF_DISCOUNT_PRICE : KEY_PRICE);\n        if (msg.value >= minPaid) {\n            _mintPaidKeys(buyer, qty, referrer, explicitRefCall);\n            return;\n        }\n\n        if (msg.value == 0 && qty == 1 && freeMinted < MAX_FREE_SUPPLY && !explicitRefCall) {\n            if (claimedFree[buyer] || !_hasAgentId(buyer)) revert FreeQuotaExhaustedOrNotAgent();\n            claimedFree[buyer] = true;\n            freeMinted += 1;\n            mintedBy[buyer] += 1;\n            uint256 tokenId = ++totalSupply;\n            _mint(buyer, tokenId);\n            emit FreePassMinted(buyer, tokenId);\n            return;\n        }\n\n        revert InsufficientPayment();\n    }\n\n    function _mintPaidKeys(address buyer, uint256 qty, address referrer, bool explicitRefCall) internal {\n        if (qty == 0 || qty > MAX_PER_TX) revert InvalidQuantity();\n        if (goldMinted + qty > MAX_GOLD_SUPPLY || totalSupply + qty > MAX_SUPPLY) revert SoldOut();\n        if (goldMintedBy[buyer] + qty > MAX_GOLD_PER_WALLET) revert WalletLimitExceeded();\n\n        lastGoldBuyerIsAgent = _hasAgentId(buyer);\n        lastGoldBuyer = buyer;\n        lastGoldMintTime = block.timestamp;\n\n        address activeRef = _resolveReferrer(buyer, referrer, explicitRefCall);\n        uint256 unitPrice = activeRef != address(0) ? REF_DISCOUNT_PRICE : KEY_PRICE;\n        uint256 requiredCost = qty * unitPrice;\n        if (msg.value < requiredCost) revert InsufficientPayment();\n\n        uint256 startTokenId = totalSupply + 1;\n        (uint256 buyerVaultWon, uint256 refVaultCoWon) = _mintAndSettleVault(\n            buyer,\n            activeRef,\n            qty,\n            (unitPrice * VAULT_POOL_BPS) / 10000\n        );\n\n        goldMintedBy[buyer] += qty;\n        mintedBy[buyer] += qty;\n\n        uint256 refRebate = _settleReferral(activeRef, buyer, qty, requiredCost, refVaultCoWon);\n        uint256 vaultContribution = ((unitPrice * VAULT_POOL_BPS) / 10000) * qty;\n\n        emit NexusKeyMinted(buyer, activeRef, startTokenId, qty, requiredCost, refRebate, buyerVaultWon);\n\n        _deliverOrCredit(PAYEE, requiredCost - vaultContribution - refRebate);\n        if (refRebate + refVaultCoWon > 0) {\n            _deliverOrCredit(activeRef, refRebate + refVaultCoWon);\n        }\n        if (buyerVaultWon > 0) {\n            totalVaultPaid += buyerVaultWon + refVaultCoWon;\n            _deliverOrCredit(buyer, buyerVaultWon);\n        }\n        if (msg.value > requiredCost) {\n            _deliverOrCredit(buyer, msg.value - requiredCost);\n        }\n    }\n\n    function _resolveReferrer(address buyer, address referrer, bool explicitRefCall) internal returns (address activeRef) {\n        address existing = boundReferrer[buyer];\n        if (existing != address(0)) {\n            if (explicitRefCall && referrer == buyer) revert InvalidReferrer();\n            return existing;\n        }\n        if (explicitRefCall) {\n            if (referrer == address(0) || referrer == buyer) revert InvalidReferrer();\n            boundReferrer[buyer] = referrer;\n            return referrer;\n        }\n        return address(0);\n    }\n\n    function _mintAndSettleVault(\n        address buyer,\n        address activeRef,\n        uint256 qty,\n        uint256 perKeyVaultAdd\n    ) internal returns (uint256 buyerVaultWon, uint256 refVaultCoWon) {\n        uint256 currentGold = goldMinted;\n        uint256 simPool = vaultPool;\n        for (uint256 i = 0; i < qty; ++i) {\n            uint256 tokenId = ++totalSupply;\n            uint256 nextGold = ++currentGold;\n            isGoldKey[tokenId] = true;\n            goldKeyNumber[tokenId] = nextGold;\n\n            simPool += perKeyVaultAdd;\n            if (nextGold % EPOCH_SIZE == 0) {\n                uint256 bPrize = (simPool * VAULT_BUYER_WIN_BPS) / 10000;\n                uint256 rPrize = activeRef != address(0) ? (simPool * VAULT_REF_COWIN_BPS) / 10000 : 0;\n                simPool -= (bPrize + rPrize);\n                buyerVaultWon += bPrize;\n                refVaultCoWon += rPrize;\n                emit EpochVaultWon(buyer, activeRef, nextGold, bPrize, rPrize);\n            }\n            _mint(buyer, tokenId);\n        }\n        goldMinted = currentGold;\n        vaultPool = simPool;\n    }\n\n    function _settleReferral(\n        address activeRef,\n        address buyer,\n        uint256 qty,\n        uint256 requiredCost,\n        uint256 refVaultCoWon\n    ) internal returns (uint256 refRebate) {\n        if (activeRef == address(0)) return 0;\n        uint256 bps = referrerRebateBps(activeRef);\n        refRebate = (requiredCost * bps) / 10000;\n        referralEarnedBy[activeRef] += refRebate + refVaultCoWon;\n        referralCountBy[activeRef] += qty;\n        totalReferralPaid += refRebate;\n        emit ReferralRebatePaid(activeRef, buyer, refRebate, bps);\n    }\n\n    /* -------------------------------------------------------------------------- */\n    /*                    TAIL VAULT RESCUE & PAYOUT WITHDRAWAL                   */\n    /* -------------------------------------------------------------------------- */\n\n    function claimTailVault() external nonReentrant {\n        if (vaultPool == 0 || lastGoldBuyer == address(0)) revert NothingToClaim();\n        bool soldOut = (goldMinted == MAX_GOLD_SUPPLY || totalSupply == MAX_SUPPLY);\n        bool timedOut = (block.timestamp >= lastGoldMintTime + TAIL_TIMEOUT);\n        if (!soldOut && !timedOut) revert TailNotUnlocked();\n\n        uint256 prize = vaultPool;\n        vaultPool = 0;\n        totalVaultPaid += prize;\n        address winner = lastGoldBuyer;\n\n        emit TailVaultClaimed(winner, prize);\n        _deliverOrCredit(winner, prize);\n    }\n\n    function withdrawPayout() external nonReentrant {\n        _withdrawPayoutTo(msg.sender, msg.sender);\n    }\n\n    function withdrawPayoutTo(address to) external nonReentrant {\n        if (to == address(0)) revert ZeroAddress();\n        _withdrawPayoutTo(msg.sender, to);\n    }\n\n    function flushPayout(address account) external nonReentrant {\n        _withdrawPayoutTo(account, account);\n    }\n\n    function _withdrawPayoutTo(address account, address to) internal {\n        uint256 amount = claimablePayout[account];\n        if (amount == 0) revert NothingToClaim();\n        claimablePayout[account] = 0;\n        totalEscrowedPayouts -= amount;\n\n        (bool ok, ) = to.call{value: amount}(\"\");\n        if (!ok) revert TransferFailed();\n        emit PayoutWithdrawn(account, to, amount);\n    }\n\n    function _deliverOrCredit(address recipient, uint256 amount) internal {\n        if (amount == 0) return;\n        bool ok;\n        assembly {\n            ok := call(50000, recipient, amount, 0, 0, 0, 0)\n        }\n        if (!ok) {\n            claimablePayout[recipient] += amount;\n            totalEscrowedPayouts += amount;\n            emit PayoutCredited(recipient, amount);\n        }\n    }\n\n    function _hasAgentId(address account) internal view returns (bool) {\n        (bool ok, bytes memory data) = AGENT_ID_REGISTRY.staticcall(\n            abi.encodeWithSelector(IERC721AgentRegistryC2.balanceOf.selector, account)\n        );\n        if (!ok || data.length < 32) return false;\n        return abi.decode(data, (uint256)) > 0;\n    }\n\n    /* -------------------------------------------------------------------------- */\n    /*                         ON-CHAIN SVG & METADATA                            */\n    /* -------------------------------------------------------------------------- */\n\n    function tokenURI(uint256 tokenId) public view override returns (string memory) {\n        if (!_exists(tokenId)) revert TokenDoesNotExist();\n        bool gold = isGoldKey[tokenId];\n        string memory idStr = tokenId.toString();\n        string memory serialStr = goldKeyNumber[tokenId].toString();\n\n        string memory tierName = gold ? \"Nexus Sovereign Partner Key (Up to 35% Rebate)\" : \"Nexus Access Pass (15% Base Rebate)\";\n        string memory accent = gold ? \"#10b981\" : \"#6366f1\";\n\n        string memory svgHead = string(\n            abi.encodePacked(\n                '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 500 500\" width=\"500\" height=\"500\">',\n                '<rect width=\"500\" height=\"500\" fill=\"#060b14\"/>',\n                '<circle cx=\"250\" cy=\"220\" r=\"125\" fill=\"none\" stroke=\"',\n                accent,\n                '\" stroke-width=\"3\"/>',\n                '<text x=\"32\" y=\"50\" fill=\"',\n                accent,\n                '\" font-family=\"monospace\" font-size=\"18\" font-weight=\"bold\">CIPHER NEXUS // #',\n                idStr,\n                \"</text>\"\n            )\n        );\n\n        string memory svgBody = string(\n            abi.encodePacked(\n                '<text x=\"32\" y=\"405\" fill=\"#f8fafc\" font-family=\"monospace\" font-size=\"14\">',\n                tierName,\n                '</text><text x=\"32\" y=\"435\" fill=\"#94a3b8\" font-family=\"monospace\" font-size=\"13\">BUYER REF DISCOUNT: 10% OFF | PARTNER REBATE: 15%-35%</text>',\n                '<text x=\"32\" y=\"465\" fill=\"#34d399\" font-family=\"monospace\" font-size=\"13\">EVERY 5TH GOLD KEY: 75% BUYER + 10% REFERRER VAULT</text></svg>'\n            )\n        );\n\n        string memory attrs = string(\n            abi.encodePacked(\n                '[{\"trait_type\":\"Tier\",\"value\":\"',\n                tierName,\n                '\"},{\"trait_type\":\"Gold Key Serial\",\"value\":',\n                serialStr,\n                \"}]\"\n            )\n        );\n\n        string memory json = string(\n            abi.encodePacked(\n                '{\"name\":\"Cipher Nexus #',\n                idStr,\n                '\",\"description\":\"Cipher Nexus Rebate Key on BNB Chain. Buyers using a referrer save 10% instantly; Partners earn 15%-35% instant BNB rebates plus co-win 10% of the Epoch Vault on every 5th Gold Key.\",\"image\":\"data:image/svg+xml;base64,',\n                Base64.encode(bytes(string(abi.encodePacked(svgHead, svgBody)))),\n                '\",\"attributes\":',\n                attrs,\n                \"}\"\n            )\n        );\n\n        return string(abi.encodePacked(\"data:application/json;base64,\", Base64.encode(bytes(json))));\n    }\n}\n"},"lib/solady/src/tokens/ERC721.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Simple ERC721 implementation with storage hitchhiking.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC721.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)\n/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC721/ERC721.sol)\n///\n/// @dev Note:\n/// - The ERC721 standard allows for self-approvals.\n///   For performance, this implementation WILL NOT revert for such actions.\n///   Please add any checks with overrides if desired.\n/// - For performance, methods are made payable where permitted by the ERC721 standard.\n/// - The `safeTransfer` functions use the identity precompile (0x4)\n///   to copy memory internally.\n///\n/// If you are overriding:\n/// - NEVER violate the ERC721 invariant:\n///   the balance of an owner MUST always be equal to their number of ownership slots.\n///   The transfer functions do not have an underflow guard for user token balances.\n/// - Make sure all variables written to storage are properly cleaned\n///   (e.g. the bool value for `isApprovedForAll` MUST be either 1 or 0 under the hood).\n/// - Check that the overridden function is actually used in the function you want to\n///   change the behavior of. Much of the code has been manually inlined for performance.\nabstract contract ERC721 {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev An account can hold up to 4294967295 tokens.\n    uint256 internal constant _MAX_ACCOUNT_BALANCE = 0xffffffff;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Only the token owner or an approved account can manage the token.\n    error NotOwnerNorApproved();\n\n    /// @dev The token does not exist.\n    error TokenDoesNotExist();\n\n    /// @dev The token already exists.\n    error TokenAlreadyExists();\n\n    /// @dev Cannot query the balance for the zero address.\n    error BalanceQueryForZeroAddress();\n\n    /// @dev Cannot mint or transfer to the zero address.\n    error TransferToZeroAddress();\n\n    /// @dev The token must be owned by `from`.\n    error TransferFromIncorrectOwner();\n\n    /// @dev The recipient's balance has overflowed.\n    error AccountBalanceOverflow();\n\n    /// @dev Cannot safely transfer to a contract that does not implement\n    /// the ERC721Receiver interface.\n    error TransferToNonERC721ReceiverImplementer();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           EVENTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Emitted when token `id` is transferred from `from` to `to`.\n    event Transfer(address indexed from, address indexed to, uint256 indexed id);\n\n    /// @dev Emitted when `owner` enables `account` to manage the `id` token.\n    event Approval(address indexed owner, address indexed account, uint256 indexed id);\n\n    /// @dev Emitted when `owner` enables or disables `operator` to manage all of their tokens.\n    event ApprovalForAll(address indexed owner, address indexed operator, bool isApproved);\n\n    /// @dev `keccak256(bytes(\"Transfer(address,address,uint256)\"))`.\n    uint256 private constant _TRANSFER_EVENT_SIGNATURE =\n        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;\n\n    /// @dev `keccak256(bytes(\"Approval(address,address,uint256)\"))`.\n    uint256 private constant _APPROVAL_EVENT_SIGNATURE =\n        0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925;\n\n    /// @dev `keccak256(bytes(\"ApprovalForAll(address,address,bool)\"))`.\n    uint256 private constant _APPROVAL_FOR_ALL_EVENT_SIGNATURE =\n        0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STORAGE                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The ownership data slot of `id` is given by:\n    /// ```\n    ///     mstore(0x00, id)\n    ///     mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n    ///     let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n    /// ```\n    /// Bits Layout:\n    /// - [0..159]   `addr`\n    /// - [160..255] `extraData`\n    ///\n    /// The approved address slot is given by: `add(1, ownershipSlot)`.\n    ///\n    /// See: https://notes.ethereum.org/%40vbuterin/verkle_tree_eip\n    ///\n    /// The balance slot of `owner` is given by:\n    /// ```\n    ///     mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n    ///     mstore(0x00, owner)\n    ///     let balanceSlot := keccak256(0x0c, 0x1c)\n    /// ```\n    /// Bits Layout:\n    /// - [0..31]   `balance`\n    /// - [32..255] `aux`\n    ///\n    /// The `operator` approval slot of `owner` is given by:\n    /// ```\n    ///     mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator))\n    ///     mstore(0x00, owner)\n    ///     let operatorApprovalSlot := keccak256(0x0c, 0x30)\n    /// ```\n    uint256 private constant _ERC721_MASTER_SLOT_SEED = 0x7d8825530a5a2e7a << 192;\n\n    /// @dev Pre-shifted and pre-masked constant.\n    uint256 private constant _ERC721_MASTER_SLOT_SEED_MASKED = 0x0a5a2e7a00000000;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                      ERC721 METADATA                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the token collection name.\n    function name() public view virtual returns (string memory);\n\n    /// @dev Returns the token collection symbol.\n    function symbol() public view virtual returns (string memory);\n\n    /// @dev Returns the Uniform Resource Identifier (URI) for token `id`.\n    function tokenURI(uint256 id) public view virtual returns (string memory);\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           ERC721                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the owner of token `id`.\n    ///\n    /// Requirements:\n    /// - Token `id` must exist.\n    function ownerOf(uint256 id) public view virtual returns (address result) {\n        result = _ownerOf(id);\n        /// @solidity memory-safe-assembly\n        assembly {\n            if iszero(result) {\n                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.\n                revert(0x1c, 0x04)\n            }\n        }\n    }\n\n    /// @dev Returns the number of tokens owned by `owner`.\n    ///\n    /// Requirements:\n    /// - `owner` must not be the zero address.\n    function balanceOf(address owner) public view virtual returns (uint256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Revert if the `owner` is the zero address.\n            if iszero(owner) {\n                mstore(0x00, 0x8f4eb604) // `BalanceQueryForZeroAddress()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            mstore(0x00, owner)\n            result := and(sload(keccak256(0x0c, 0x1c)), _MAX_ACCOUNT_BALANCE)\n        }\n    }\n\n    /// @dev Returns the account approved to manage token `id`.\n    ///\n    /// Requirements:\n    /// - Token `id` must exist.\n    function getApproved(uint256 id) public view virtual returns (address result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, id)\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n            if iszero(shl(96, sload(ownershipSlot))) {\n                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.\n                revert(0x1c, 0x04)\n            }\n            result := sload(add(1, ownershipSlot))\n        }\n    }\n\n    /// @dev Sets `account` as the approved account to manage token `id`.\n    ///\n    /// Requirements:\n    /// - Token `id` must exist.\n    /// - The caller must be the owner of the token,\n    ///   or an approved operator for the token owner.\n    ///\n    /// Emits an {Approval} event.\n    function approve(address account, uint256 id) public payable virtual {\n        _approve(msg.sender, account, id);\n    }\n\n    /// @dev Returns whether `operator` is approved to manage the tokens of `owner`.\n    function isApprovedForAll(address owner, address operator)\n        public\n        view\n        virtual\n        returns (bool result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x1c, operator)\n            mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED)\n            mstore(0x00, owner)\n            result := sload(keccak256(0x0c, 0x30))\n        }\n    }\n\n    /// @dev Sets whether `operator` is approved to manage the tokens of the caller.\n    ///\n    /// Emits an {ApprovalForAll} event.\n    function setApprovalForAll(address operator, bool isApproved) public virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Convert to 0 or 1.\n            isApproved := iszero(iszero(isApproved))\n            // Update the `isApproved` for (`msg.sender`, `operator`).\n            mstore(0x1c, operator)\n            mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED)\n            mstore(0x00, caller())\n            sstore(keccak256(0x0c, 0x30), isApproved)\n            // Emit the {ApprovalForAll} event.\n            mstore(0x00, isApproved)\n            // forgefmt: disable-next-item\n            log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, caller(), shr(96, shl(96, operator)))\n        }\n    }\n\n    /// @dev Transfers token `id` from `from` to `to`.\n    ///\n    /// Requirements:\n    ///\n    /// - Token `id` must exist.\n    /// - `from` must be the owner of the token.\n    /// - `to` cannot be the zero address.\n    /// - The caller must be the owner of the token, or be approved to manage the token.\n    ///\n    /// Emits a {Transfer} event.\n    function transferFrom(address from, address to, uint256 id) public payable virtual {\n        _beforeTokenTransfer(from, to, id);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clear the upper 96 bits.\n            let bitmaskAddress := shr(96, not(0))\n            from := and(bitmaskAddress, from)\n            to := and(bitmaskAddress, to)\n            // Load the ownership data.\n            mstore(0x00, id)\n            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, caller()))\n            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n            let ownershipPacked := sload(ownershipSlot)\n            let owner := and(bitmaskAddress, ownershipPacked)\n            // Revert if the token does not exist, or if `from` is not the owner.\n            if iszero(mul(owner, eq(owner, from))) {\n                // `TokenDoesNotExist()`, `TransferFromIncorrectOwner()`.\n                mstore(shl(2, iszero(owner)), 0xceea21b6a1148100)\n                revert(0x1c, 0x04)\n            }\n            // Load, check, and update the token approval.\n            {\n                mstore(0x00, from)\n                let approvedAddress := sload(add(1, ownershipSlot))\n                // Revert if the caller is not the owner, nor approved.\n                if iszero(or(eq(caller(), from), eq(caller(), approvedAddress))) {\n                    if iszero(sload(keccak256(0x0c, 0x30))) {\n                        mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.\n                        revert(0x1c, 0x04)\n                    }\n                }\n                // Delete the approved address if any.\n                if approvedAddress { sstore(add(1, ownershipSlot), 0) }\n            }\n            // Update with the new owner.\n            sstore(ownershipSlot, xor(ownershipPacked, xor(from, to)))\n            // Decrement the balance of `from`.\n            {\n                let fromBalanceSlot := keccak256(0x0c, 0x1c)\n                sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1))\n            }\n            // Increment the balance of `to`.\n            {\n                mstore(0x00, to)\n                let toBalanceSlot := keccak256(0x0c, 0x1c)\n                let toBalanceSlotPacked := add(sload(toBalanceSlot), 1)\n                // Revert if `to` is the zero address, or if the account balance overflows.\n                if iszero(mul(to, and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE))) {\n                    // `TransferToZeroAddress()`, `AccountBalanceOverflow()`.\n                    mstore(shl(2, iszero(to)), 0xea553b3401336cea)\n                    revert(0x1c, 0x04)\n                }\n                sstore(toBalanceSlot, toBalanceSlotPacked)\n            }\n            // Emit the {Transfer} event.\n            log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id)\n        }\n        _afterTokenTransfer(from, to, id);\n    }\n\n    /// @dev Equivalent to `safeTransferFrom(from, to, id, \"\")`.\n    function safeTransferFrom(address from, address to, uint256 id) public payable virtual {\n        transferFrom(from, to, id);\n        if (_hasCode(to)) _checkOnERC721Received(from, to, id, \"\");\n    }\n\n    /// @dev Transfers token `id` from `from` to `to`.\n    ///\n    /// Requirements:\n    ///\n    /// - Token `id` must exist.\n    /// - `from` must be the owner of the token.\n    /// - `to` cannot be the zero address.\n    /// - The caller must be the owner of the token, or be approved to manage the token.\n    /// - If `to` refers to a smart contract, it must implement\n    ///   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n    ///\n    /// Emits a {Transfer} event.\n    function safeTransferFrom(address from, address to, uint256 id, bytes calldata data)\n        public\n        payable\n        virtual\n    {\n        transferFrom(from, to, id);\n        if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);\n    }\n\n    /// @dev Returns true if this contract implements the interface defined by `interfaceId`.\n    /// See: https://eips.ethereum.org/EIPS/eip-165\n    /// This function call must use less than 30000 gas.\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let s := shr(224, interfaceId)\n            // ERC165: 0x01ffc9a7, ERC721: 0x80ac58cd, ERC721Metadata: 0x5b5e139f.\n            result := or(or(eq(s, 0x01ffc9a7), eq(s, 0x80ac58cd)), eq(s, 0x5b5e139f))\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  INTERNAL QUERY FUNCTIONS                  */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns if token `id` exists.\n    function _exists(uint256 id) internal view virtual returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, id)\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            result := iszero(iszero(shl(96, sload(add(id, add(id, keccak256(0x00, 0x20)))))))\n        }\n    }\n\n    /// @dev Returns the owner of token `id`.\n    /// Returns the zero address instead of reverting if the token does not exist.\n    function _ownerOf(uint256 id) internal view virtual returns (address result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, id)\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            result := shr(96, shl(96, sload(add(id, add(id, keccak256(0x00, 0x20))))))\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*            INTERNAL DATA HITCHHIKING FUNCTIONS             */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    // For performance, no events are emitted for the hitchhiking setters.\n    // Please emit your own events if required.\n\n    /// @dev Returns the auxiliary data for `owner`.\n    /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data.\n    /// Auxiliary data can be set for any address, even if it does not have any tokens.\n    function _getAux(address owner) internal view virtual returns (uint224 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            mstore(0x00, owner)\n            result := shr(32, sload(keccak256(0x0c, 0x1c)))\n        }\n    }\n\n    /// @dev Set the auxiliary data for `owner` to `value`.\n    /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data.\n    /// Auxiliary data can be set for any address, even if it does not have any tokens.\n    function _setAux(address owner, uint224 value) internal virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            mstore(0x00, owner)\n            let balanceSlot := keccak256(0x0c, 0x1c)\n            let packed := sload(balanceSlot)\n            sstore(balanceSlot, xor(packed, shl(32, xor(value, shr(32, packed)))))\n        }\n    }\n\n    /// @dev Returns the extra data for token `id`.\n    /// Minting, transferring, burning a token will not change the extra data.\n    /// The extra data can be set on a non-existent token.\n    function _getExtraData(uint256 id) internal view virtual returns (uint96 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, id)\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            result := shr(160, sload(add(id, add(id, keccak256(0x00, 0x20)))))\n        }\n    }\n\n    /// @dev Sets the extra data for token `id` to `value`.\n    /// Minting, transferring, burning a token will not change the extra data.\n    /// The extra data can be set on a non-existent token.\n    function _setExtraData(uint256 id, uint96 value) internal virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, id)\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n            let packed := sload(ownershipSlot)\n            sstore(ownershipSlot, xor(packed, shl(160, xor(value, shr(160, packed)))))\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  INTERNAL MINT FUNCTIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Mints token `id` to `to`.\n    ///\n    /// Requirements:\n    ///\n    /// - Token `id` must not exist.\n    /// - `to` cannot be the zero address.\n    ///\n    /// Emits a {Transfer} event.\n    function _mint(address to, uint256 id) internal virtual {\n        _beforeTokenTransfer(address(0), to, id);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clear the upper 96 bits.\n            to := shr(96, shl(96, to))\n            // Load the ownership data.\n            mstore(0x00, id)\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n            let ownershipPacked := sload(ownershipSlot)\n            // Revert if the token already exists.\n            if shl(96, ownershipPacked) {\n                mstore(0x00, 0xc991cbb1) // `TokenAlreadyExists()`.\n                revert(0x1c, 0x04)\n            }\n            // Update with the owner.\n            sstore(ownershipSlot, or(ownershipPacked, to))\n            // Increment the balance of the owner.\n            {\n                mstore(0x00, to)\n                let balanceSlot := keccak256(0x0c, 0x1c)\n                let balanceSlotPacked := add(sload(balanceSlot), 1)\n                // Revert if `to` is the zero address, or if the account balance overflows.\n                if iszero(mul(to, and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE))) {\n                    // `TransferToZeroAddress()`, `AccountBalanceOverflow()`.\n                    mstore(shl(2, iszero(to)), 0xea553b3401336cea)\n                    revert(0x1c, 0x04)\n                }\n                sstore(balanceSlot, balanceSlotPacked)\n            }\n            // Emit the {Transfer} event.\n            log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id)\n        }\n        _afterTokenTransfer(address(0), to, id);\n    }\n\n    /// @dev Mints token `id` to `to`, and updates the extra data for token `id` to `value`.\n    /// Does NOT check if token `id` already exists (assumes `id` is auto-incrementing).\n    ///\n    /// Requirements:\n    ///\n    /// - `to` cannot be the zero address.\n    ///\n    /// Emits a {Transfer} event.\n    function _mintAndSetExtraDataUnchecked(address to, uint256 id, uint96 value) internal virtual {\n        _beforeTokenTransfer(address(0), to, id);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clear the upper 96 bits.\n            to := shr(96, shl(96, to))\n            // Update with the owner and extra data.\n            mstore(0x00, id)\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            sstore(add(id, add(id, keccak256(0x00, 0x20))), or(shl(160, value), to))\n            // Increment the balance of the owner.\n            {\n                mstore(0x00, to)\n                let balanceSlot := keccak256(0x0c, 0x1c)\n                let balanceSlotPacked := add(sload(balanceSlot), 1)\n                // Revert if `to` is the zero address, or if the account balance overflows.\n                if iszero(mul(to, and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE))) {\n                    // `TransferToZeroAddress()`, `AccountBalanceOverflow()`.\n                    mstore(shl(2, iszero(to)), 0xea553b3401336cea)\n                    revert(0x1c, 0x04)\n                }\n                sstore(balanceSlot, balanceSlotPacked)\n            }\n            // Emit the {Transfer} event.\n            log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id)\n        }\n        _afterTokenTransfer(address(0), to, id);\n    }\n\n    /// @dev Equivalent to `_safeMint(to, id, \"\")`.\n    function _safeMint(address to, uint256 id) internal virtual {\n        _safeMint(to, id, \"\");\n    }\n\n    /// @dev Mints token `id` to `to`.\n    ///\n    /// Requirements:\n    ///\n    /// - Token `id` must not exist.\n    /// - `to` cannot be the zero address.\n    /// - If `to` refers to a smart contract, it must implement\n    ///   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n    ///\n    /// Emits a {Transfer} event.\n    function _safeMint(address to, uint256 id, bytes memory data) internal virtual {\n        _mint(to, id);\n        if (_hasCode(to)) _checkOnERC721Received(address(0), to, id, data);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  INTERNAL BURN FUNCTIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Equivalent to `_burn(address(0), id)`.\n    function _burn(uint256 id) internal virtual {\n        _burn(address(0), id);\n    }\n\n    /// @dev Destroys token `id`, using `by`.\n    ///\n    /// Requirements:\n    ///\n    /// - Token `id` must exist.\n    /// - If `by` is not the zero address,\n    ///   it must be the owner of the token, or be approved to manage the token.\n    ///\n    /// Emits a {Transfer} event.\n    function _burn(address by, uint256 id) internal virtual {\n        address owner = ownerOf(id);\n        _beforeTokenTransfer(owner, address(0), id);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clear the upper 96 bits.\n            by := shr(96, shl(96, by))\n            // Load the ownership data.\n            mstore(0x00, id)\n            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))\n            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n            let ownershipPacked := sload(ownershipSlot)\n            // Reload the owner in case it is changed in `_beforeTokenTransfer`.\n            owner := shr(96, shl(96, ownershipPacked))\n            // Revert if the token does not exist.\n            if iszero(owner) {\n                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.\n                revert(0x1c, 0x04)\n            }\n            // Load and check the token approval.\n            {\n                mstore(0x00, owner)\n                let approvedAddress := sload(add(1, ownershipSlot))\n                // If `by` is not the zero address, do the authorization check.\n                // Revert if the `by` is not the owner, nor approved.\n                if iszero(or(iszero(by), or(eq(by, owner), eq(by, approvedAddress)))) {\n                    if iszero(sload(keccak256(0x0c, 0x30))) {\n                        mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.\n                        revert(0x1c, 0x04)\n                    }\n                }\n                // Delete the approved address if any.\n                if approvedAddress { sstore(add(1, ownershipSlot), 0) }\n            }\n            // Clear the owner.\n            sstore(ownershipSlot, xor(ownershipPacked, owner))\n            // Decrement the balance of `owner`.\n            {\n                let balanceSlot := keccak256(0x0c, 0x1c)\n                sstore(balanceSlot, sub(sload(balanceSlot), 1))\n            }\n            // Emit the {Transfer} event.\n            log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, owner, 0, id)\n        }\n        _afterTokenTransfer(owner, address(0), id);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                INTERNAL APPROVAL FUNCTIONS                 */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns whether `account` is the owner of token `id`, or is approved to manage it.\n    ///\n    /// Requirements:\n    /// - Token `id` must exist.\n    function _isApprovedOrOwner(address account, uint256 id)\n        internal\n        view\n        virtual\n        returns (bool result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := 1\n            // Clear the upper 96 bits.\n            account := shr(96, shl(96, account))\n            // Load the ownership data.\n            mstore(0x00, id)\n            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, account))\n            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n            let owner := shr(96, shl(96, sload(ownershipSlot)))\n            // Revert if the token does not exist.\n            if iszero(owner) {\n                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.\n                revert(0x1c, 0x04)\n            }\n            // Check if `account` is the `owner`.\n            if iszero(eq(account, owner)) {\n                mstore(0x00, owner)\n                // Check if `account` is approved to manage the token.\n                if iszero(sload(keccak256(0x0c, 0x30))) {\n                    result := eq(account, sload(add(1, ownershipSlot)))\n                }\n            }\n        }\n    }\n\n    /// @dev Returns the account approved to manage token `id`.\n    /// Returns the zero address instead of reverting if the token does not exist.\n    function _getApproved(uint256 id) internal view virtual returns (address result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, id)\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            result := sload(add(1, add(id, add(id, keccak256(0x00, 0x20)))))\n        }\n    }\n\n    /// @dev Equivalent to `_approve(address(0), account, id)`.\n    function _approve(address account, uint256 id) internal virtual {\n        _approve(address(0), account, id);\n    }\n\n    /// @dev Sets `account` as the approved account to manage token `id`, using `by`.\n    ///\n    /// Requirements:\n    /// - Token `id` must exist.\n    /// - If `by` is not the zero address, `by` must be the owner\n    ///   or an approved operator for the token owner.\n    ///\n    /// Emits a {Approval} event.\n    function _approve(address by, address account, uint256 id) internal virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clear the upper 96 bits.\n            let bitmaskAddress := shr(96, not(0))\n            account := and(bitmaskAddress, account)\n            by := and(bitmaskAddress, by)\n            // Load the owner of the token.\n            mstore(0x00, id)\n            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))\n            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n            let owner := and(bitmaskAddress, sload(ownershipSlot))\n            // Revert if the token does not exist.\n            if iszero(owner) {\n                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.\n                revert(0x1c, 0x04)\n            }\n            // If `by` is not the zero address, do the authorization check.\n            // Revert if `by` is not the owner, nor approved.\n            if iszero(or(iszero(by), eq(by, owner))) {\n                mstore(0x00, owner)\n                if iszero(sload(keccak256(0x0c, 0x30))) {\n                    mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.\n                    revert(0x1c, 0x04)\n                }\n            }\n            // Sets `account` as the approved account to manage `id`.\n            sstore(add(1, ownershipSlot), account)\n            // Emit the {Approval} event.\n            log4(codesize(), 0x00, _APPROVAL_EVENT_SIGNATURE, owner, account, id)\n        }\n    }\n\n    /// @dev Approve or remove the `operator` as an operator for `by`,\n    /// without authorization checks.\n    ///\n    /// Emits an {ApprovalForAll} event.\n    function _setApprovalForAll(address by, address operator, bool isApproved) internal virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clear the upper 96 bits.\n            by := shr(96, shl(96, by))\n            operator := shr(96, shl(96, operator))\n            // Convert to 0 or 1.\n            isApproved := iszero(iszero(isApproved))\n            // Update the `isApproved` for (`by`, `operator`).\n            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator))\n            mstore(0x00, by)\n            sstore(keccak256(0x0c, 0x30), isApproved)\n            // Emit the {ApprovalForAll} event.\n            mstore(0x00, isApproved)\n            log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, by, operator)\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                INTERNAL TRANSFER FUNCTIONS                 */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Equivalent to `_transfer(address(0), from, to, id)`.\n    function _transfer(address from, address to, uint256 id) internal virtual {\n        _transfer(address(0), from, to, id);\n    }\n\n    /// @dev Transfers token `id` from `from` to `to`.\n    ///\n    /// Requirements:\n    ///\n    /// - Token `id` must exist.\n    /// - `from` must be the owner of the token.\n    /// - `to` cannot be the zero address.\n    /// - If `by` is not the zero address,\n    ///   it must be the owner of the token, or be approved to manage the token.\n    ///\n    /// Emits a {Transfer} event.\n    function _transfer(address by, address from, address to, uint256 id) internal virtual {\n        _beforeTokenTransfer(from, to, id);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clear the upper 96 bits.\n            let bitmaskAddress := shr(96, not(0))\n            from := and(bitmaskAddress, from)\n            to := and(bitmaskAddress, to)\n            by := and(bitmaskAddress, by)\n            // Load the ownership data.\n            mstore(0x00, id)\n            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))\n            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n            let ownershipPacked := sload(ownershipSlot)\n            let owner := and(bitmaskAddress, ownershipPacked)\n            // Revert if the token does not exist, or if `from` is not the owner.\n            if iszero(mul(owner, eq(owner, from))) {\n                // `TokenDoesNotExist()`, `TransferFromIncorrectOwner()`.\n                mstore(shl(2, iszero(owner)), 0xceea21b6a1148100)\n                revert(0x1c, 0x04)\n            }\n            // Load, check, and update the token approval.\n            {\n                mstore(0x00, from)\n                let approvedAddress := sload(add(1, ownershipSlot))\n                // If `by` is not the zero address, do the authorization check.\n                // Revert if the `by` is not the owner, nor approved.\n                if iszero(or(iszero(by), or(eq(by, from), eq(by, approvedAddress)))) {\n                    if iszero(sload(keccak256(0x0c, 0x30))) {\n                        mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.\n                        revert(0x1c, 0x04)\n                    }\n                }\n                // Delete the approved address if any.\n                if approvedAddress { sstore(add(1, ownershipSlot), 0) }\n            }\n            // Update with the new owner.\n            sstore(ownershipSlot, xor(ownershipPacked, xor(from, to)))\n            // Decrement the balance of `from`.\n            {\n                let fromBalanceSlot := keccak256(0x0c, 0x1c)\n                sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1))\n            }\n            // Increment the balance of `to`.\n            {\n                mstore(0x00, to)\n                let toBalanceSlot := keccak256(0x0c, 0x1c)\n                let toBalanceSlotPacked := add(sload(toBalanceSlot), 1)\n                // Revert if `to` is the zero address, or if the account balance overflows.\n                if iszero(mul(to, and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE))) {\n                    // `TransferToZeroAddress()`, `AccountBalanceOverflow()`.\n                    mstore(shl(2, iszero(to)), 0xea553b3401336cea)\n                    revert(0x1c, 0x04)\n                }\n                sstore(toBalanceSlot, toBalanceSlotPacked)\n            }\n            // Emit the {Transfer} event.\n            log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id)\n        }\n        _afterTokenTransfer(from, to, id);\n    }\n\n    /// @dev Equivalent to `_safeTransfer(from, to, id, \"\")`.\n    function _safeTransfer(address from, address to, uint256 id) internal virtual {\n        _safeTransfer(from, to, id, \"\");\n    }\n\n    /// @dev Transfers token `id` from `from` to `to`.\n    ///\n    /// Requirements:\n    ///\n    /// - Token `id` must exist.\n    /// - `from` must be the owner of the token.\n    /// - `to` cannot be the zero address.\n    /// - The caller must be the owner of the token, or be approved to manage the token.\n    /// - If `to` refers to a smart contract, it must implement\n    ///   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n    ///\n    /// Emits a {Transfer} event.\n    function _safeTransfer(address from, address to, uint256 id, bytes memory data)\n        internal\n        virtual\n    {\n        _transfer(address(0), from, to, id);\n        if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);\n    }\n\n    /// @dev Equivalent to `_safeTransfer(by, from, to, id, \"\")`.\n    function _safeTransfer(address by, address from, address to, uint256 id) internal virtual {\n        _safeTransfer(by, from, to, id, \"\");\n    }\n\n    /// @dev Transfers token `id` from `from` to `to`.\n    ///\n    /// Requirements:\n    ///\n    /// - Token `id` must exist.\n    /// - `from` must be the owner of the token.\n    /// - `to` cannot be the zero address.\n    /// - If `by` is not the zero address,\n    ///   it must be the owner of the token, or be approved to manage the token.\n    /// - If `to` refers to a smart contract, it must implement\n    ///   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n    ///\n    /// Emits a {Transfer} event.\n    function _safeTransfer(address by, address from, address to, uint256 id, bytes memory data)\n        internal\n        virtual\n    {\n        _transfer(by, from, to, id);\n        if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                    HOOKS FOR OVERRIDING                    */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Hook that is called before any token transfers, including minting and burning.\n    function _beforeTokenTransfer(address from, address to, uint256 id) internal virtual {}\n\n    /// @dev Hook that is called after any token transfers, including minting and burning.\n    function _afterTokenTransfer(address from, address to, uint256 id) internal virtual {}\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                      PRIVATE HELPERS                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns if `a` has bytecode of non-zero length.\n    function _hasCode(address a) private view returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := extcodesize(a) // Can handle dirty upper bits.\n        }\n    }\n\n    /// @dev Perform a call to invoke {IERC721Receiver-onERC721Received} on `to`.\n    /// Reverts if the target does not support the function correctly.\n    function _checkOnERC721Received(address from, address to, uint256 id, bytes memory data)\n        private\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Prepare the calldata.\n            let m := mload(0x40)\n            let onERC721ReceivedSelector := 0x150b7a02\n            mstore(m, onERC721ReceivedSelector)\n            mstore(add(m, 0x20), caller()) // The `operator`, which is always `msg.sender`.\n            mstore(add(m, 0x40), shr(96, shl(96, from)))\n            mstore(add(m, 0x60), id)\n            mstore(add(m, 0x80), 0x80)\n            let n := mload(data)\n            mstore(add(m, 0xa0), n)\n            if n { pop(staticcall(gas(), 4, add(data, 0x20), n, add(m, 0xc0), n)) }\n            // Revert if the call reverts.\n            if iszero(call(gas(), to, 0, add(m, 0x1c), add(n, 0xa4), m, 0x20)) {\n                if returndatasize() {\n                    // Bubble up the revert if the call reverts.\n                    returndatacopy(m, 0x00, returndatasize())\n                    revert(m, returndatasize())\n                }\n            }\n            // Load the returndata and compare it.\n            if iszero(eq(mload(m), shl(224, onERC721ReceivedSelector))) {\n                mstore(0x00, 0xd1a57ed6) // `TransferToNonERC721ReceiverImplementer()`.\n                revert(0x1c, 0x04)\n            }\n        }\n    }\n}\n"},"lib/solady/src/utils/Base64.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Library to encode strings in Base64.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/Base64.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Base64.sol)\n/// @author Modified from (https://github.com/Brechtpd/base64/blob/main/base64.sol) by Brecht Devos - <brecht@loopring.org>.\nlibrary Base64 {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                    ENCODING / DECODING                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Encodes `data` using the base64 encoding described in RFC 4648.\n    /// See: https://datatracker.ietf.org/doc/html/rfc4648\n    /// @param fileSafe  Whether to replace '+' with '-' and '/' with '_'.\n    /// @param noPadding Whether to strip away the padding.\n    function encode(bytes memory data, bool fileSafe, bool noPadding)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let dataLength := mload(data)\n\n            if dataLength {\n                // Multiply by 4/3 rounded up.\n                // The `shl(2, ...)` is equivalent to multiplying by 4.\n                let encodedLength := shl(2, div(add(dataLength, 2), 3))\n\n                // Set `result` to point to the start of the free memory.\n                result := mload(0x40)\n\n                // Store the table into the scratch space.\n                // Offsetted by -1 byte so that the `mload` will load the character.\n                // We will rewrite the free memory pointer at `0x40` later with\n                // the allocated size.\n                // The magic constant 0x0670 will turn \"-_\" into \"+/\".\n                mstore(0x1f, \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef\")\n                mstore(0x3f, xor(\"ghijklmnopqrstuvwxyz0123456789-_\", mul(iszero(fileSafe), 0x0670)))\n\n                // Skip the first slot, which stores the length.\n                let ptr := add(result, 0x20)\n                let end := add(ptr, encodedLength)\n\n                let dataEnd := add(add(0x20, data), dataLength)\n                let dataEndValue := mload(dataEnd) // Cache the value at the `dataEnd` slot.\n                mstore(dataEnd, 0x00) // Zeroize the `dataEnd` slot to clear dirty bits.\n\n                // Run over the input, 3 bytes at a time.\n                for {} 1 {} {\n                    data := add(data, 3) // Advance 3 bytes.\n                    let input := mload(data)\n\n                    // Write 4 bytes. Optimized for fewer stack operations.\n                    mstore8(0, mload(and(shr(18, input), 0x3F)))\n                    mstore8(1, mload(and(shr(12, input), 0x3F)))\n                    mstore8(2, mload(and(shr(6, input), 0x3F)))\n                    mstore8(3, mload(and(input, 0x3F)))\n                    mstore(ptr, mload(0x00))\n\n                    ptr := add(ptr, 4) // Advance 4 bytes.\n                    if iszero(lt(ptr, end)) { break }\n                }\n                mstore(dataEnd, dataEndValue) // Restore the cached value at `dataEnd`.\n                mstore(0x40, add(end, 0x20)) // Allocate the memory.\n                // Equivalent to `o = [0, 2, 1][dataLength % 3]`.\n                let o := div(2, mod(dataLength, 3))\n                // Offset `ptr` and pad with '='. We can simply write over the end.\n                mstore(sub(ptr, o), shl(240, 0x3d3d))\n                // Set `o` to zero if there is padding.\n                o := mul(iszero(iszero(noPadding)), o)\n                mstore(sub(ptr, o), 0) // Zeroize the slot after the string.\n                mstore(result, sub(encodedLength, o)) // Store the length.\n            }\n        }\n    }\n\n    /// @dev Encodes `data` using the base64 encoding described in RFC 4648.\n    /// Equivalent to `encode(data, false, false)`.\n    function encode(bytes memory data) internal pure returns (string memory result) {\n        result = encode(data, false, false);\n    }\n\n    /// @dev Encodes `data` using the base64 encoding described in RFC 4648.\n    /// Equivalent to `encode(data, fileSafe, false)`.\n    function encode(bytes memory data, bool fileSafe)\n        internal\n        pure\n        returns (string memory result)\n    {\n        result = encode(data, fileSafe, false);\n    }\n\n    /// @dev Decodes base64 encoded `data`.\n    ///\n    /// Supports:\n    /// - RFC 4648 (both standard and file-safe mode).\n    /// - RFC 3501 (63: ',').\n    ///\n    /// Does not support:\n    /// - Line breaks.\n    ///\n    /// Note: For performance reasons,\n    /// this function will NOT revert on invalid `data` inputs.\n    /// Outputs for invalid inputs will simply be undefined behaviour.\n    /// It is the user's responsibility to ensure that the `data`\n    /// is a valid base64 encoded string.\n    function decode(string memory data) internal pure returns (bytes memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let dataLength := mload(data)\n\n            if dataLength {\n                let decodedLength := mul(shr(2, dataLength), 3)\n\n                for {} 1 {} {\n                    // If padded.\n                    if iszero(and(dataLength, 3)) {\n                        let t := xor(mload(add(data, dataLength)), 0x3d3d)\n                        // forgefmt: disable-next-item\n                        decodedLength := sub(\n                            decodedLength,\n                            add(iszero(byte(30, t)), iszero(byte(31, t)))\n                        )\n                        break\n                    }\n                    // If non-padded.\n                    decodedLength := add(decodedLength, sub(and(dataLength, 3), 1))\n                    break\n                }\n                result := mload(0x40)\n\n                // Write the length of the bytes.\n                mstore(result, decodedLength)\n\n                // Skip the first slot, which stores the length.\n                let ptr := add(result, 0x20)\n                let end := add(ptr, decodedLength)\n\n                // Load the table into the scratch space.\n                // Constants are optimized for smaller bytecode with zero gas overhead.\n                // `m` also doubles as the mask of the upper 6 bits.\n                let m := 0xfc000000fc00686c7074787c8084888c9094989ca0a4a8acb0b4b8bcc0c4c8cc\n                mstore(0x5b, m)\n                mstore(0x3b, 0x04080c1014181c2024282c3034383c4044484c5054585c6064)\n                mstore(0x1a, 0xf8fcf800fcd0d4d8dce0e4e8ecf0f4)\n\n                for {} 1 {} {\n                    // Read 4 bytes.\n                    data := add(data, 4)\n                    let input := mload(data)\n\n                    // Write 3 bytes.\n                    // forgefmt: disable-next-item\n                    mstore(ptr, or(\n                        and(m, mload(byte(28, input))),\n                        shr(6, or(\n                            and(m, mload(byte(29, input))),\n                            shr(6, or(\n                                and(m, mload(byte(30, input))),\n                                shr(6, mload(byte(31, input)))\n                            ))\n                        ))\n                    ))\n                    ptr := add(ptr, 3)\n                    if iszero(lt(ptr, end)) { break }\n                }\n                mstore(0x40, add(end, 0x20)) // Allocate the memory.\n                mstore(end, 0) // Zeroize the slot after the bytes.\n                mstore(0x60, 0) // Restore the zero slot.\n            }\n        }\n    }\n}\n"},"lib/solady/src/utils/LibString.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {LibBytes} from \"./LibBytes.sol\";\n\n/// @notice Library for converting numbers into strings and other string operations.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibString.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol)\n///\n/// @dev Note:\n/// For performance and bytecode compactness, most of the string operations are restricted to\n/// byte strings (7-bit ASCII), except where otherwise specified.\n/// Usage of byte string operations on charsets with runes spanning two or more bytes\n/// can lead to undefined behavior.\nlibrary LibString {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STRUCTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Goated string storage struct that totally MOGs, no cap, fr.\n    /// Uses less gas and bytecode than Solidity's native string storage. It's meta af.\n    /// Packs length with the first 31 bytes if <255 bytes, so it’s mad tight.\n    struct StringStorage {\n        bytes32 _spacer;\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                        CUSTOM ERRORS                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The length of the output is too small to contain all the hex digits.\n    error HexLengthInsufficient();\n\n    /// @dev The length of the string is more than 32 bytes.\n    error TooBigForSmallString();\n\n    /// @dev The input string must be a 7-bit ASCII.\n    error StringNot7BitASCII();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The constant returned when the `search` is not found in the string.\n    uint256 internal constant NOT_FOUND = type(uint256).max;\n\n    /// @dev Lookup for '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.\n    uint128 internal constant ALPHANUMERIC_7_BIT_ASCII = 0x7fffffe07fffffe03ff000000000000;\n\n    /// @dev Lookup for 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.\n    uint128 internal constant LETTERS_7_BIT_ASCII = 0x7fffffe07fffffe0000000000000000;\n\n    /// @dev Lookup for 'abcdefghijklmnopqrstuvwxyz'.\n    uint128 internal constant LOWERCASE_7_BIT_ASCII = 0x7fffffe000000000000000000000000;\n\n    /// @dev Lookup for 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.\n    uint128 internal constant UPPERCASE_7_BIT_ASCII = 0x7fffffe0000000000000000;\n\n    /// @dev Lookup for '0123456789'.\n    uint128 internal constant DIGITS_7_BIT_ASCII = 0x3ff000000000000;\n\n    /// @dev Lookup for '0123456789abcdefABCDEF'.\n    uint128 internal constant HEXDIGITS_7_BIT_ASCII = 0x7e0000007e03ff000000000000;\n\n    /// @dev Lookup for '01234567'.\n    uint128 internal constant OCTDIGITS_7_BIT_ASCII = 0xff000000000000;\n\n    /// @dev Lookup for '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&\\'()*+,-./:;<=>?@[\\\\]^_`{|}~ \\t\\n\\r\\x0b\\x0c'.\n    uint128 internal constant PRINTABLE_7_BIT_ASCII = 0x7fffffffffffffffffffffff00003e00;\n\n    /// @dev Lookup for '!\"#$%&\\'()*+,-./:;<=>?@[\\\\]^_`{|}~'.\n    uint128 internal constant PUNCTUATION_7_BIT_ASCII = 0x78000001f8000001fc00fffe00000000;\n\n    /// @dev Lookup for ' \\t\\n\\r\\x0b\\x0c'.\n    uint128 internal constant WHITESPACE_7_BIT_ASCII = 0x100003e00;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                 STRING STORAGE OPERATIONS                  */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Sets the value of the string storage `$` to `s`.\n    function set(StringStorage storage $, string memory s) internal {\n        LibBytes.set(bytesStorage($), bytes(s));\n    }\n\n    /// @dev Sets the value of the string storage `$` to `s`.\n    function setCalldata(StringStorage storage $, string calldata s) internal {\n        LibBytes.setCalldata(bytesStorage($), bytes(s));\n    }\n\n    /// @dev Sets the value of the string storage `$` to the empty string.\n    function clear(StringStorage storage $) internal {\n        delete $._spacer;\n    }\n\n    /// @dev Returns whether the value stored is `$` is the empty string \"\".\n    function isEmpty(StringStorage storage $) internal view returns (bool) {\n        return uint256($._spacer) & 0xff == uint256(0);\n    }\n\n    /// @dev Returns the length of the value stored in `$`.\n    function length(StringStorage storage $) internal view returns (uint256) {\n        return LibBytes.length(bytesStorage($));\n    }\n\n    /// @dev Returns the value stored in `$`.\n    function get(StringStorage storage $) internal view returns (string memory) {\n        return string(LibBytes.get(bytesStorage($)));\n    }\n\n    /// @dev Returns the uint8 at index `i`. If out-of-bounds, returns 0.\n    function uint8At(StringStorage storage $, uint256 i) internal view returns (uint8) {\n        return LibBytes.uint8At(bytesStorage($), i);\n    }\n\n    /// @dev Helper to cast `$` to a `BytesStorage`.\n    function bytesStorage(StringStorage storage $)\n        internal\n        pure\n        returns (LibBytes.BytesStorage storage casted)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            casted.slot := $.slot\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     DECIMAL OPERATIONS                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the base 10 decimal representation of `value`.\n    function toString(uint256 value) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // The maximum value of a uint256 contains 78 digits (1 byte per digit), but\n            // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.\n            // We will need 1 word for the trailing zeros padding, 1 word for the length,\n            // and 3 words for a maximum of 78 digits.\n            result := add(mload(0x40), 0x80)\n            mstore(0x40, add(result, 0x20)) // Allocate memory.\n            mstore(result, 0) // Zeroize the slot after the string.\n\n            let end := result // Cache the end of the memory to calculate the length later.\n            let w := not(0) // Tsk.\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for { let temp := value } 1 {} {\n                result := add(result, w) // `sub(result, 1)`.\n                // Store the character to the pointer.\n                // The ASCII index of the '0' character is 48.\n                mstore8(result, add(48, mod(temp, 10)))\n                temp := div(temp, 10) // Keep dividing `temp` until zero.\n                if iszero(temp) { break }\n            }\n            let n := sub(end, result)\n            result := sub(result, 0x20) // Move the pointer 32 bytes back to make room for the length.\n            mstore(result, n) // Store the length.\n        }\n    }\n\n    /// @dev Returns the base 10 decimal representation of `value`.\n    function toString(int256 value) internal pure returns (string memory result) {\n        if (value >= 0) return toString(uint256(value));\n        unchecked {\n            result = toString(~uint256(value) + 1);\n        }\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We still have some spare memory space on the left,\n            // as we have allocated 3 words (96 bytes) for up to 78 digits.\n            let n := mload(result) // Load the string length.\n            mstore(result, 0x2d) // Store the '-' character.\n            result := sub(result, 1) // Move back the string pointer by a byte.\n            mstore(result, add(n, 1)) // Update the string length.\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   HEXADECIMAL OPERATIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the hexadecimal representation of `value`,\n    /// left-padded to an input length of `byteCount` bytes.\n    /// The output is prefixed with \"0x\" encoded using 2 hexadecimal digits per byte,\n    /// giving a total length of `byteCount * 2 + 2` bytes.\n    /// Reverts if `byteCount` is too small for the output to contain all the digits.\n    function toHexString(uint256 value, uint256 byteCount)\n        internal\n        pure\n        returns (string memory result)\n    {\n        result = toHexStringNoPrefix(value, byteCount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := add(mload(result), 2) // Compute the length.\n            mstore(result, 0x3078) // Store the \"0x\" prefix.\n            result := sub(result, 2) // Move the pointer.\n            mstore(result, n) // Store the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`,\n    /// left-padded to an input length of `byteCount` bytes.\n    /// The output is not prefixed with \"0x\" and is encoded using 2 hexadecimal digits per byte,\n    /// giving a total length of `byteCount * 2` bytes.\n    /// Reverts if `byteCount` is too small for the output to contain all the digits.\n    function toHexStringNoPrefix(uint256 value, uint256 byteCount)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We need 0x20 bytes for the trailing zeros padding, `byteCount * 2` bytes\n            // for the digits, 0x02 bytes for the prefix, and 0x20 bytes for the length.\n            // We add 0x20 to the total and round down to a multiple of 0x20.\n            // (0x20 + 0x20 + 0x02 + 0x20) = 0x62.\n            result := add(mload(0x40), and(add(shl(1, byteCount), 0x42), not(0x1f)))\n            mstore(0x40, add(result, 0x20)) // Allocate memory.\n            mstore(result, 0) // Zeroize the slot after the string.\n\n            let end := result // Cache the end to calculate the length later.\n            // Store \"0123456789abcdef\" in scratch space.\n            mstore(0x0f, 0x30313233343536373839616263646566)\n\n            let start := sub(result, add(byteCount, byteCount))\n            let w := not(1) // Tsk.\n            let temp := value\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for {} 1 {} {\n                result := add(result, w) // `sub(result, 2)`.\n                mstore8(add(result, 1), mload(and(temp, 15)))\n                mstore8(result, mload(and(shr(4, temp), 15)))\n                temp := shr(8, temp)\n                if iszero(xor(result, start)) { break }\n            }\n            if temp {\n                mstore(0x00, 0x2194895a) // `HexLengthInsufficient()`.\n                revert(0x1c, 0x04)\n            }\n            let n := sub(end, result)\n            result := sub(result, 0x20)\n            mstore(result, n) // Store the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\" and encoded using 2 hexadecimal digits per byte.\n    /// As address are 20 bytes long, the output will left-padded to have\n    /// a length of `20 * 2 + 2` bytes.\n    function toHexString(uint256 value) internal pure returns (string memory result) {\n        result = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := add(mload(result), 2) // Compute the length.\n            mstore(result, 0x3078) // Store the \"0x\" prefix.\n            result := sub(result, 2) // Move the pointer.\n            mstore(result, n) // Store the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\".\n    /// The output excludes leading \"0\" from the `toHexString` output.\n    /// `0x00: \"0x0\", 0x01: \"0x1\", 0x12: \"0x12\", 0x123: \"0x123\"`.\n    function toMinimalHexString(uint256 value) internal pure returns (string memory result) {\n        result = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let o := eq(byte(0, mload(add(result, 0x20))), 0x30) // Whether leading zero is present.\n            let n := add(mload(result), 2) // Compute the length.\n            mstore(add(result, o), 0x3078) // Store the \"0x\" prefix, accounting for leading zero.\n            result := sub(add(result, o), 2) // Move the pointer, accounting for leading zero.\n            mstore(result, sub(n, o)) // Store the length, accounting for leading zero.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output excludes leading \"0\" from the `toHexStringNoPrefix` output.\n    /// `0x00: \"0\", 0x01: \"1\", 0x12: \"12\", 0x123: \"123\"`.\n    function toMinimalHexStringNoPrefix(uint256 value)\n        internal\n        pure\n        returns (string memory result)\n    {\n        result = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let o := eq(byte(0, mload(add(result, 0x20))), 0x30) // Whether leading zero is present.\n            let n := mload(result) // Get the length.\n            result := add(result, o) // Move the pointer, accounting for leading zero.\n            mstore(result, sub(n, o)) // Store the length, accounting for leading zero.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    /// As address are 20 bytes long, the output will left-padded to have\n    /// a length of `20 * 2` bytes.\n    function toHexStringNoPrefix(uint256 value) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,\n            // 0x02 bytes for the prefix, and 0x40 bytes for the digits.\n            // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x40) is 0xa0.\n            result := add(mload(0x40), 0x80)\n            mstore(0x40, add(result, 0x20)) // Allocate memory.\n            mstore(result, 0) // Zeroize the slot after the string.\n\n            let end := result // Cache the end to calculate the length later.\n            mstore(0x0f, 0x30313233343536373839616263646566) // Store the \"0123456789abcdef\" lookup.\n\n            let w := not(1) // Tsk.\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for { let temp := value } 1 {} {\n                result := add(result, w) // `sub(result, 2)`.\n                mstore8(add(result, 1), mload(and(temp, 15)))\n                mstore8(result, mload(and(shr(4, temp), 15)))\n                temp := shr(8, temp)\n                if iszero(temp) { break }\n            }\n            let n := sub(end, result)\n            result := sub(result, 0x20)\n            mstore(result, n) // Store the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\", encoded using 2 hexadecimal digits per byte,\n    /// and the alphabets are capitalized conditionally according to\n    /// https://eips.ethereum.org/EIPS/eip-55\n    function toHexStringChecksummed(address value) internal pure returns (string memory result) {\n        result = toHexString(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let mask := shl(6, div(not(0), 255)) // `0b010000000100000000 ...`\n            let o := add(result, 0x22)\n            let hashed := and(keccak256(o, 40), mul(34, mask)) // `0b10001000 ... `\n            let t := shl(240, 136) // `0b10001000 << 240`\n            for { let i := 0 } 1 {} {\n                mstore(add(i, i), mul(t, byte(i, hashed)))\n                i := add(i, 1)\n                if eq(i, 20) { break }\n            }\n            mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask)))))\n            o := add(o, 0x20)\n            mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask)))))\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\" and encoded using 2 hexadecimal digits per byte.\n    function toHexString(address value) internal pure returns (string memory result) {\n        result = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := add(mload(result), 2) // Compute the length.\n            mstore(result, 0x3078) // Store the \"0x\" prefix.\n            result := sub(result, 2) // Move the pointer.\n            mstore(result, n) // Store the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexStringNoPrefix(address value) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            // Allocate memory.\n            // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,\n            // 0x02 bytes for the prefix, and 0x28 bytes for the digits.\n            // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80.\n            mstore(0x40, add(result, 0x80))\n            mstore(0x0f, 0x30313233343536373839616263646566) // Store the \"0123456789abcdef\" lookup.\n\n            result := add(result, 2)\n            mstore(result, 40) // Store the length.\n            let o := add(result, 0x20)\n            mstore(add(o, 40), 0) // Zeroize the slot after the string.\n            value := shl(96, value)\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for { let i := 0 } 1 {} {\n                let p := add(o, add(i, i))\n                let temp := byte(i, value)\n                mstore8(add(p, 1), mload(and(temp, 15)))\n                mstore8(p, mload(shr(4, temp)))\n                i := add(i, 1)\n                if eq(i, 20) { break }\n            }\n        }\n    }\n\n    /// @dev Returns the hex encoded string from the raw bytes.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexString(bytes memory raw) internal pure returns (string memory result) {\n        result = toHexStringNoPrefix(raw);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := add(mload(result), 2) // Compute the length.\n            mstore(result, 0x3078) // Store the \"0x\" prefix.\n            result := sub(result, 2) // Move the pointer.\n            mstore(result, n) // Store the length.\n        }\n    }\n\n    /// @dev Returns the hex encoded string from the raw bytes.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexStringNoPrefix(bytes memory raw) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := mload(raw)\n            result := add(mload(0x40), 2) // Skip 2 bytes for the optional prefix.\n            mstore(result, add(n, n)) // Store the length of the output.\n\n            mstore(0x0f, 0x30313233343536373839616263646566) // Store the \"0123456789abcdef\" lookup.\n            let o := add(result, 0x20)\n            let end := add(raw, n)\n            for {} iszero(eq(raw, end)) {} {\n                raw := add(raw, 1)\n                mstore8(add(o, 1), mload(and(mload(raw), 15)))\n                mstore8(o, mload(and(shr(4, mload(raw)), 15)))\n                o := add(o, 2)\n            }\n            mstore(o, 0) // Zeroize the slot after the string.\n            mstore(0x40, add(o, 0x20)) // Allocate memory.\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   RUNE STRING OPERATIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the number of UTF characters in the string.\n    function runeCount(string memory s) internal pure returns (uint256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if mload(s) {\n                mstore(0x00, div(not(0), 255))\n                mstore(0x20, 0x0202020202020202020202020202020202020202020202020303030304040506)\n                let o := add(s, 0x20)\n                let end := add(o, mload(s))\n                for { result := 1 } 1 { result := add(result, 1) } {\n                    o := add(o, byte(0, mload(shr(250, mload(o)))))\n                    if iszero(lt(o, end)) { break }\n                }\n            }\n        }\n    }\n\n    /// @dev Returns if this string is a 7-bit ASCII string.\n    /// (i.e. all characters codes are in [0..127])\n    function is7BitASCII(string memory s) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := 1\n            let mask := shl(7, div(not(0), 255))\n            let n := mload(s)\n            if n {\n                let o := add(s, 0x20)\n                let end := add(o, n)\n                let last := mload(end)\n                mstore(end, 0)\n                for {} 1 {} {\n                    if and(mask, mload(o)) {\n                        result := 0\n                        break\n                    }\n                    o := add(o, 0x20)\n                    if iszero(lt(o, end)) { break }\n                }\n                mstore(end, last)\n            }\n        }\n    }\n\n    /// @dev Returns if this string is a 7-bit ASCII string,\n    /// AND all characters are in the `allowed` lookup.\n    /// Note: If `s` is empty, returns true regardless of `allowed`.\n    function is7BitASCII(string memory s, uint128 allowed) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := 1\n            if mload(s) {\n                let allowed_ := shr(128, shl(128, allowed))\n                let o := add(s, 0x20)\n                for { let end := add(o, mload(s)) } 1 {} {\n                    result := and(result, shr(byte(0, mload(o)), allowed_))\n                    o := add(o, 1)\n                    if iszero(and(result, lt(o, end))) { break }\n                }\n            }\n        }\n    }\n\n    /// @dev Converts the bytes in the 7-bit ASCII string `s` to\n    /// an allowed lookup for use in `is7BitASCII(s, allowed)`.\n    /// To save runtime gas, you can cache the result in an immutable variable.\n    function to7BitASCIIAllowedLookup(string memory s) internal pure returns (uint128 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if mload(s) {\n                let o := add(s, 0x20)\n                for { let end := add(o, mload(s)) } 1 {} {\n                    result := or(result, shl(byte(0, mload(o)), 1))\n                    o := add(o, 1)\n                    if iszero(lt(o, end)) { break }\n                }\n                if shr(128, result) {\n                    mstore(0x00, 0xc9807e0d) // `StringNot7BitASCII()`.\n                    revert(0x1c, 0x04)\n                }\n            }\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   BYTE STRING OPERATIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    // For performance and bytecode compactness, byte string operations are restricted\n    // to 7-bit ASCII strings. All offsets are byte offsets, not UTF character offsets.\n    // Usage of byte string operations on charsets with runes spanning two or more bytes\n    // can lead to undefined behavior.\n\n    /// @dev Returns `subject` all occurrences of `needle` replaced with `replacement`.\n    function replace(string memory subject, string memory needle, string memory replacement)\n        internal\n        pure\n        returns (string memory)\n    {\n        return string(LibBytes.replace(bytes(subject), bytes(needle), bytes(replacement)));\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from left to right, starting from `from`.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function indexOf(string memory subject, string memory needle, uint256 from)\n        internal\n        pure\n        returns (uint256)\n    {\n        return LibBytes.indexOf(bytes(subject), bytes(needle), from);\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from left to right.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function indexOf(string memory subject, string memory needle) internal pure returns (uint256) {\n        return LibBytes.indexOf(bytes(subject), bytes(needle), 0);\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from right to left, starting from `from`.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function lastIndexOf(string memory subject, string memory needle, uint256 from)\n        internal\n        pure\n        returns (uint256)\n    {\n        return LibBytes.lastIndexOf(bytes(subject), bytes(needle), from);\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from right to left.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function lastIndexOf(string memory subject, string memory needle)\n        internal\n        pure\n        returns (uint256)\n    {\n        return LibBytes.lastIndexOf(bytes(subject), bytes(needle), type(uint256).max);\n    }\n\n    /// @dev Returns true if `needle` is found in `subject`, false otherwise.\n    function contains(string memory subject, string memory needle) internal pure returns (bool) {\n        return LibBytes.contains(bytes(subject), bytes(needle));\n    }\n\n    /// @dev Returns whether `subject` starts with `needle`.\n    function startsWith(string memory subject, string memory needle) internal pure returns (bool) {\n        return LibBytes.startsWith(bytes(subject), bytes(needle));\n    }\n\n    /// @dev Returns whether `subject` ends with `needle`.\n    function endsWith(string memory subject, string memory needle) internal pure returns (bool) {\n        return LibBytes.endsWith(bytes(subject), bytes(needle));\n    }\n\n    /// @dev Returns `subject` repeated `times`.\n    function repeat(string memory subject, uint256 times) internal pure returns (string memory) {\n        return string(LibBytes.repeat(bytes(subject), times));\n    }\n\n    /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive).\n    /// `start` and `end` are byte offsets.\n    function slice(string memory subject, uint256 start, uint256 end)\n        internal\n        pure\n        returns (string memory)\n    {\n        return string(LibBytes.slice(bytes(subject), start, end));\n    }\n\n    /// @dev Returns a copy of `subject` sliced from `start` to the end of the string.\n    /// `start` is a byte offset.\n    function slice(string memory subject, uint256 start) internal pure returns (string memory) {\n        return string(LibBytes.slice(bytes(subject), start, type(uint256).max));\n    }\n\n    /// @dev Returns all the indices of `needle` in `subject`.\n    /// The indices are byte offsets.\n    function indicesOf(string memory subject, string memory needle)\n        internal\n        pure\n        returns (uint256[] memory)\n    {\n        return LibBytes.indicesOf(bytes(subject), bytes(needle));\n    }\n\n    /// @dev Returns an arrays of strings based on the `delimiter` inside of the `subject` string.\n    function split(string memory subject, string memory delimiter)\n        internal\n        pure\n        returns (string[] memory result)\n    {\n        bytes[] memory a = LibBytes.split(bytes(subject), bytes(delimiter));\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := a\n        }\n    }\n\n    /// @dev Returns a concatenated string of `a` and `b`.\n    /// Cheaper than `string.concat()` and does not de-align the free memory pointer.\n    function concat(string memory a, string memory b) internal pure returns (string memory) {\n        return string(LibBytes.concat(bytes(a), bytes(b)));\n    }\n\n    /// @dev Returns a copy of the string in either lowercase or UPPERCASE.\n    /// WARNING! This function is only compatible with 7-bit ASCII strings.\n    function toCase(string memory subject, bool toUpper)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := mload(subject)\n            if n {\n                result := mload(0x40)\n                let o := add(result, 0x20)\n                let d := sub(subject, result)\n                let flags := shl(add(70, shl(5, toUpper)), 0x3ffffff)\n                for { let end := add(o, n) } 1 {} {\n                    let b := byte(0, mload(add(d, o)))\n                    mstore8(o, xor(and(shr(b, flags), 0x20), b))\n                    o := add(o, 1)\n                    if eq(o, end) { break }\n                }\n                mstore(result, n) // Store the length.\n                mstore(o, 0) // Zeroize the slot after the string.\n                mstore(0x40, add(o, 0x20)) // Allocate memory.\n            }\n        }\n    }\n\n    /// @dev Returns a string from a small bytes32 string.\n    /// `s` must be null-terminated, or behavior will be undefined.\n    function fromSmallString(bytes32 s) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            let n := 0\n            for {} byte(n, s) { n := add(n, 1) } {} // Scan for '\\0'.\n            mstore(result, n) // Store the length.\n            let o := add(result, 0x20)\n            mstore(o, s) // Store the bytes of the string.\n            mstore(add(o, n), 0) // Zeroize the slot after the string.\n            mstore(0x40, add(result, 0x40)) // Allocate memory.\n        }\n    }\n\n    /// @dev Returns the small string, with all bytes after the first null byte zeroized.\n    function normalizeSmallString(bytes32 s) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            for {} byte(result, s) { result := add(result, 1) } {} // Scan for '\\0'.\n            mstore(0x00, s)\n            mstore(result, 0x00)\n            result := mload(0x00)\n        }\n    }\n\n    /// @dev Returns the string as a normalized null-terminated small string.\n    function toSmallString(string memory s) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(s)\n            if iszero(lt(result, 33)) {\n                mstore(0x00, 0xec92f9a3) // `TooBigForSmallString()`.\n                revert(0x1c, 0x04)\n            }\n            result := shl(shl(3, sub(32, result)), mload(add(s, result)))\n        }\n    }\n\n    /// @dev Returns a lowercased copy of the string.\n    /// WARNING! This function is only compatible with 7-bit ASCII strings.\n    function lower(string memory subject) internal pure returns (string memory result) {\n        result = toCase(subject, false);\n    }\n\n    /// @dev Returns an UPPERCASED copy of the string.\n    /// WARNING! This function is only compatible with 7-bit ASCII strings.\n    function upper(string memory subject) internal pure returns (string memory result) {\n        result = toCase(subject, true);\n    }\n\n    /// @dev Escapes the string to be used within HTML tags.\n    function escapeHTML(string memory s) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            let end := add(s, mload(s))\n            let o := add(result, 0x20)\n            // Store the bytes of the packed offsets and strides into the scratch space.\n            // `packed = (stride << 5) | offset`. Max offset is 20. Max stride is 6.\n            mstore(0x1f, 0x900094)\n            mstore(0x08, 0xc0000000a6ab)\n            // Store \"&quot;&amp;&#39;&lt;&gt;\" into the scratch space.\n            mstore(0x00, shl(64, 0x2671756f743b26616d703b262333393b266c743b2667743b))\n            for {} iszero(eq(s, end)) {} {\n                s := add(s, 1)\n                let c := and(mload(s), 0xff)\n                // Not in `[\"\\\"\",\"'\",\"&\",\"<\",\">\"]`.\n                if iszero(and(shl(c, 1), 0x500000c400000000)) {\n                    mstore8(o, c)\n                    o := add(o, 1)\n                    continue\n                }\n                let t := shr(248, mload(c))\n                mstore(o, mload(and(t, 0x1f)))\n                o := add(o, shr(5, t))\n            }\n            mstore(o, 0) // Zeroize the slot after the string.\n            mstore(result, sub(o, add(result, 0x20))) // Store the length.\n            mstore(0x40, add(o, 0x20)) // Allocate memory.\n        }\n    }\n\n    /// @dev Escapes the string to be used within double-quotes in a JSON.\n    /// If `addDoubleQuotes` is true, the result will be enclosed in double-quotes.\n    function escapeJSON(string memory s, bool addDoubleQuotes)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            let o := add(result, 0x20)\n            if addDoubleQuotes {\n                mstore8(o, 34)\n                o := add(1, o)\n            }\n            // Store \"\\\\u0000\" in scratch space.\n            // Store \"0123456789abcdef\" in scratch space.\n            // Also, store `{0x08:\"b\", 0x09:\"t\", 0x0a:\"n\", 0x0c:\"f\", 0x0d:\"r\"}`.\n            // into the scratch space.\n            mstore(0x15, 0x5c75303030303031323334353637383961626364656662746e006672)\n            // Bitmask for detecting `[\"\\\"\",\"\\\\\"]`.\n            let e := or(shl(0x22, 1), shl(0x5c, 1))\n            for { let end := add(s, mload(s)) } iszero(eq(s, end)) {} {\n                s := add(s, 1)\n                let c := and(mload(s), 0xff)\n                if iszero(lt(c, 0x20)) {\n                    if iszero(and(shl(c, 1), e)) {\n                        // Not in `[\"\\\"\",\"\\\\\"]`.\n                        mstore8(o, c)\n                        o := add(o, 1)\n                        continue\n                    }\n                    mstore8(o, 0x5c) // \"\\\\\".\n                    mstore8(add(o, 1), c)\n                    o := add(o, 2)\n                    continue\n                }\n                if iszero(and(shl(c, 1), 0x3700)) {\n                    // Not in `[\"\\b\",\"\\t\",\"\\n\",\"\\f\",\"\\d\"]`.\n                    mstore8(0x1d, mload(shr(4, c))) // Hex value.\n                    mstore8(0x1e, mload(and(c, 15))) // Hex value.\n                    mstore(o, mload(0x19)) // \"\\\\u00XX\".\n                    o := add(o, 6)\n                    continue\n                }\n                mstore8(o, 0x5c) // \"\\\\\".\n                mstore8(add(o, 1), mload(add(c, 8)))\n                o := add(o, 2)\n            }\n            if addDoubleQuotes {\n                mstore8(o, 34)\n                o := add(1, o)\n            }\n            mstore(o, 0) // Zeroize the slot after the string.\n            mstore(result, sub(o, add(result, 0x20))) // Store the length.\n            mstore(0x40, add(o, 0x20)) // Allocate memory.\n        }\n    }\n\n    /// @dev Escapes the string to be used within double-quotes in a JSON.\n    function escapeJSON(string memory s) internal pure returns (string memory result) {\n        result = escapeJSON(s, false);\n    }\n\n    /// @dev Encodes `s` so that it can be safely used in a URI,\n    /// just like `encodeURIComponent` in JavaScript.\n    /// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent\n    /// See: https://datatracker.ietf.org/doc/html/rfc2396\n    /// See: https://datatracker.ietf.org/doc/html/rfc3986\n    function encodeURIComponent(string memory s) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            // Store \"0123456789ABCDEF\" in scratch space.\n            // Uppercased to be consistent with JavaScript's implementation.\n            mstore(0x0f, 0x30313233343536373839414243444546)\n            let o := add(result, 0x20)\n            for { let end := add(s, mload(s)) } iszero(eq(s, end)) {} {\n                s := add(s, 1)\n                let c := and(mload(s), 0xff)\n                // If not in `[0-9A-Z-a-z-_.!~*'()]`.\n                if iszero(and(1, shr(c, 0x47fffffe87fffffe03ff678200000000))) {\n                    mstore8(o, 0x25) // '%'.\n                    mstore8(add(o, 1), mload(and(shr(4, c), 15)))\n                    mstore8(add(o, 2), mload(and(c, 15)))\n                    o := add(o, 3)\n                    continue\n                }\n                mstore8(o, c)\n                o := add(o, 1)\n            }\n            mstore(result, sub(o, add(result, 0x20))) // Store the length.\n            mstore(o, 0) // Zeroize the slot after the string.\n            mstore(0x40, add(o, 0x20)) // Allocate memory.\n        }\n    }\n\n    /// @dev Returns whether `a` equals `b`.\n    function eq(string memory a, string memory b) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b)))\n        }\n    }\n\n    /// @dev Returns whether `a` equals `b`, where `b` is a null-terminated small string.\n    function eqs(string memory a, bytes32 b) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // These should be evaluated on compile time, as far as possible.\n            let m := not(shl(7, div(not(iszero(b)), 255))) // `0x7f7f ...`.\n            let x := not(or(m, or(b, add(m, and(b, m)))))\n            let r := shl(7, iszero(iszero(shr(128, x))))\n            r := or(r, shl(6, iszero(iszero(shr(64, 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            result := gt(eq(mload(a), add(iszero(x), xor(31, shr(3, r)))),\n                xor(shr(add(8, r), b), shr(add(8, r), mload(add(a, 0x20)))))\n        }\n    }\n\n    /// @dev Returns 0 if `a == b`, -1 if `a < b`, +1 if `a > b`.\n    /// If `a` == b[:a.length]`, and `a.length < b.length`, returns -1.\n    function cmp(string memory a, string memory b) internal pure returns (int256) {\n        return LibBytes.cmp(bytes(a), bytes(b));\n    }\n\n    /// @dev Packs a single string with its length into a single word.\n    /// Returns `bytes32(0)` if the length is zero or greater than 31.\n    function packOne(string memory a) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We don't need to zero right pad the string,\n            // since this is our own custom non-standard packing scheme.\n            result :=\n                mul(\n                    // Load the length and the bytes.\n                    mload(add(a, 0x1f)),\n                    // `length != 0 && length < 32`. Abuses underflow.\n                    // Assumes that the length is valid and within the block gas limit.\n                    lt(sub(mload(a), 1), 0x1f)\n                )\n        }\n    }\n\n    /// @dev Unpacks a string packed using {packOne}.\n    /// Returns the empty string if `packed` is `bytes32(0)`.\n    /// If `packed` is not an output of {packOne}, the output behavior is undefined.\n    function unpackOne(bytes32 packed) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40) // Grab the free memory pointer.\n            mstore(0x40, add(result, 0x40)) // Allocate 2 words (1 for the length, 1 for the bytes).\n            mstore(result, 0) // Zeroize the length slot.\n            mstore(add(result, 0x1f), packed) // Store the length and bytes.\n            mstore(add(add(result, 0x20), mload(result)), 0) // Right pad with zeroes.\n        }\n    }\n\n    /// @dev Packs two strings with their lengths into a single word.\n    /// Returns `bytes32(0)` if combined length is zero or greater than 30.\n    function packTwo(string memory a, string memory b) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let aLen := mload(a)\n            // We don't need to zero right pad the strings,\n            // since this is our own custom non-standard packing scheme.\n            result :=\n                mul(\n                    or( // Load the length and the bytes of `a` and `b`.\n                    shl(shl(3, sub(0x1f, aLen)), mload(add(a, aLen))), mload(sub(add(b, 0x1e), aLen))),\n                    // `totalLen != 0 && totalLen < 31`. Abuses underflow.\n                    // Assumes that the lengths are valid and within the block gas limit.\n                    lt(sub(add(aLen, mload(b)), 1), 0x1e)\n                )\n        }\n    }\n\n    /// @dev Unpacks strings packed using {packTwo}.\n    /// Returns the empty strings if `packed` is `bytes32(0)`.\n    /// If `packed` is not an output of {packTwo}, the output behavior is undefined.\n    function unpackTwo(bytes32 packed)\n        internal\n        pure\n        returns (string memory resultA, string memory resultB)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            resultA := mload(0x40) // Grab the free memory pointer.\n            resultB := add(resultA, 0x40)\n            // Allocate 2 words for each string (1 for the length, 1 for the byte). Total 4 words.\n            mstore(0x40, add(resultB, 0x40))\n            // Zeroize the length slots.\n            mstore(resultA, 0)\n            mstore(resultB, 0)\n            // Store the lengths and bytes.\n            mstore(add(resultA, 0x1f), packed)\n            mstore(add(resultB, 0x1f), mload(add(add(resultA, 0x20), mload(resultA))))\n            // Right pad with zeroes.\n            mstore(add(add(resultA, 0x20), mload(resultA)), 0)\n            mstore(add(add(resultB, 0x20), mload(resultB)), 0)\n        }\n    }\n\n    /// @dev Directly returns `a` without copying.\n    function directReturn(string memory a) internal pure {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Assumes that the string does not start from the scratch space.\n            let retStart := sub(a, 0x20)\n            let retUnpaddedSize := add(mload(a), 0x40)\n            // Right pad with zeroes. Just in case the string is produced\n            // by a method that doesn't zero right pad.\n            mstore(add(retStart, retUnpaddedSize), 0)\n            mstore(retStart, 0x20) // Store the return offset.\n            // End the transaction, returning the string.\n            return(retStart, and(not(0x1f), add(0x1f, retUnpaddedSize)))\n        }\n    }\n}\n"},"lib/solady/src/utils/LibBytes.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Library for byte related operations.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBytes.sol)\nlibrary LibBytes {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STRUCTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Goated bytes storage struct that totally MOGs, no cap, fr.\n    /// Uses less gas and bytecode than Solidity's native bytes storage. It's meta af.\n    /// Packs length with the first 31 bytes if <255 bytes, so it’s mad tight.\n    struct BytesStorage {\n        bytes32 _spacer;\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The constant returned when the `search` is not found in the bytes.\n    uint256 internal constant NOT_FOUND = type(uint256).max;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  BYTE STORAGE OPERATIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Sets the value of the bytes storage `$` to `s`.\n    function set(BytesStorage storage $, bytes memory s) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := mload(s)\n            let packed := or(0xff, shl(8, n))\n            for { let i := 0 } 1 {} {\n                if iszero(gt(n, 0xfe)) {\n                    i := 0x1f\n                    packed := or(n, shl(8, mload(add(s, i))))\n                    if iszero(gt(n, i)) { break }\n                }\n                let o := add(s, 0x20)\n                mstore(0x00, $.slot)\n                for { let p := keccak256(0x00, 0x20) } 1 {} {\n                    sstore(add(p, shr(5, i)), mload(add(o, i)))\n                    i := add(i, 0x20)\n                    if iszero(lt(i, n)) { break }\n                }\n                break\n            }\n            sstore($.slot, packed)\n        }\n    }\n\n    /// @dev Sets the value of the bytes storage `$` to `s`.\n    function setCalldata(BytesStorage storage $, bytes calldata s) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let packed := or(0xff, shl(8, s.length))\n            for { let i := 0 } 1 {} {\n                if iszero(gt(s.length, 0xfe)) {\n                    i := 0x1f\n                    packed := or(s.length, shl(8, shr(8, calldataload(s.offset))))\n                    if iszero(gt(s.length, i)) { break }\n                }\n                mstore(0x00, $.slot)\n                for { let p := keccak256(0x00, 0x20) } 1 {} {\n                    sstore(add(p, shr(5, i)), calldataload(add(s.offset, i)))\n                    i := add(i, 0x20)\n                    if iszero(lt(i, s.length)) { break }\n                }\n                break\n            }\n            sstore($.slot, packed)\n        }\n    }\n\n    /// @dev Sets the value of the bytes storage `$` to the empty bytes.\n    function clear(BytesStorage storage $) internal {\n        delete $._spacer;\n    }\n\n    /// @dev Returns whether the value stored is `$` is the empty bytes \"\".\n    function isEmpty(BytesStorage storage $) internal view returns (bool) {\n        return uint256($._spacer) & 0xff == uint256(0);\n    }\n\n    /// @dev Returns the length of the value stored in `$`.\n    function length(BytesStorage storage $) internal view returns (uint256 result) {\n        result = uint256($._spacer);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := and(0xff, result)\n            result := or(mul(shr(8, result), eq(0xff, n)), mul(n, iszero(eq(0xff, n))))\n        }\n    }\n\n    /// @dev Returns the value stored in `$`.\n    function get(BytesStorage storage $) internal view returns (bytes memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            let o := add(result, 0x20)\n            let packed := sload($.slot)\n            let n := shr(8, packed)\n            for { let i := 0 } 1 {} {\n                if iszero(eq(or(packed, 0xff), packed)) {\n                    mstore(o, packed)\n                    n := and(0xff, packed)\n                    i := 0x1f\n                    if iszero(gt(n, i)) { break }\n                }\n                mstore(0x00, $.slot)\n                for { let p := keccak256(0x00, 0x20) } 1 {} {\n                    mstore(add(o, i), sload(add(p, shr(5, i))))\n                    i := add(i, 0x20)\n                    if iszero(lt(i, n)) { break }\n                }\n                break\n            }\n            mstore(result, n) // Store the length of the memory.\n            mstore(add(o, n), 0) // Zeroize the slot after the bytes.\n            mstore(0x40, add(add(o, n), 0x20)) // Allocate memory.\n        }\n    }\n\n    /// @dev Returns the uint8 at index `i`. If out-of-bounds, returns 0.\n    function uint8At(BytesStorage storage $, uint256 i) internal view returns (uint8 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            for { let packed := sload($.slot) } 1 {} {\n                if iszero(eq(or(packed, 0xff), packed)) {\n                    if iszero(gt(i, 0x1e)) {\n                        result := byte(i, packed)\n                        break\n                    }\n                    if iszero(gt(i, and(0xff, packed))) {\n                        mstore(0x00, $.slot)\n                        let j := sub(i, 0x1f)\n                        result := byte(and(j, 0x1f), sload(add(keccak256(0x00, 0x20), shr(5, j))))\n                    }\n                    break\n                }\n                if iszero(gt(i, shr(8, packed))) {\n                    mstore(0x00, $.slot)\n                    result := byte(and(i, 0x1f), sload(add(keccak256(0x00, 0x20), shr(5, i))))\n                }\n                break\n            }\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                      BYTES OPERATIONS                      */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns `subject` all occurrences of `needle` replaced with `replacement`.\n    function replace(bytes memory subject, bytes memory needle, bytes memory replacement)\n        internal\n        pure\n        returns (bytes memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            let needleLen := mload(needle)\n            let replacementLen := mload(replacement)\n            let d := sub(result, subject) // Memory difference.\n            let i := add(subject, 0x20) // Subject bytes pointer.\n            mstore(0x00, add(i, mload(subject))) // End of subject.\n            if iszero(gt(needleLen, mload(subject))) {\n                let subjectSearchEnd := add(sub(mload(0x00), needleLen), 1)\n                let h := 0 // The hash of `needle`.\n                if iszero(lt(needleLen, 0x20)) { h := keccak256(add(needle, 0x20), needleLen) }\n                let s := mload(add(needle, 0x20))\n                for { let m := shl(3, sub(0x20, and(needleLen, 0x1f))) } 1 {} {\n                    let t := mload(i)\n                    // Whether the first `needleLen % 32` bytes of `subject` and `needle` matches.\n                    if iszero(shr(m, xor(t, s))) {\n                        if h {\n                            if iszero(eq(keccak256(i, needleLen), h)) {\n                                mstore(add(i, d), t)\n                                i := add(i, 1)\n                                if iszero(lt(i, subjectSearchEnd)) { break }\n                                continue\n                            }\n                        }\n                        // Copy the `replacement` one word at a time.\n                        for { let j := 0 } 1 {} {\n                            mstore(add(add(i, d), j), mload(add(add(replacement, 0x20), j)))\n                            j := add(j, 0x20)\n                            if iszero(lt(j, replacementLen)) { break }\n                        }\n                        d := sub(add(d, replacementLen), needleLen)\n                        if needleLen {\n                            i := add(i, needleLen)\n                            if iszero(lt(i, subjectSearchEnd)) { break }\n                            continue\n                        }\n                    }\n                    mstore(add(i, d), t)\n                    i := add(i, 1)\n                    if iszero(lt(i, subjectSearchEnd)) { break }\n                }\n            }\n            let end := mload(0x00)\n            let n := add(sub(d, add(result, 0x20)), end)\n            // Copy the rest of the bytes one word at a time.\n            for {} lt(i, end) { i := add(i, 0x20) } { mstore(add(i, d), mload(i)) }\n            let o := add(i, d)\n            mstore(o, 0) // Zeroize the slot after the bytes.\n            mstore(0x40, add(o, 0x20)) // Allocate memory.\n            mstore(result, n) // Store the length.\n        }\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from left to right, starting from `from`.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function indexOf(bytes memory subject, bytes memory needle, uint256 from)\n        internal\n        pure\n        returns (uint256 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := not(0) // Initialize to `NOT_FOUND`.\n            for { let subjectLen := mload(subject) } 1 {} {\n                if iszero(mload(needle)) {\n                    result := from\n                    if iszero(gt(from, subjectLen)) { break }\n                    result := subjectLen\n                    break\n                }\n                let needleLen := mload(needle)\n                let subjectStart := add(subject, 0x20)\n\n                subject := add(subjectStart, from)\n                let end := add(sub(add(subjectStart, subjectLen), needleLen), 1)\n                let m := shl(3, sub(0x20, and(needleLen, 0x1f)))\n                let s := mload(add(needle, 0x20))\n\n                if iszero(and(lt(subject, end), lt(from, subjectLen))) { break }\n\n                if iszero(lt(needleLen, 0x20)) {\n                    for { let h := keccak256(add(needle, 0x20), needleLen) } 1 {} {\n                        if iszero(shr(m, xor(mload(subject), s))) {\n                            if eq(keccak256(subject, needleLen), h) {\n                                result := sub(subject, subjectStart)\n                                break\n                            }\n                        }\n                        subject := add(subject, 1)\n                        if iszero(lt(subject, end)) { break }\n                    }\n                    break\n                }\n                for {} 1 {} {\n                    if iszero(shr(m, xor(mload(subject), s))) {\n                        result := sub(subject, subjectStart)\n                        break\n                    }\n                    subject := add(subject, 1)\n                    if iszero(lt(subject, end)) { break }\n                }\n                break\n            }\n        }\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from left to right, starting from `from`. Optimized for byte needles.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function indexOfByte(bytes memory subject, bytes1 needle, uint256 from)\n        internal\n        pure\n        returns (uint256 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := not(0) // Initialize to `NOT_FOUND`.\n            if gt(mload(subject), from) {\n                let start := add(subject, 0x20)\n                let end := add(start, mload(subject))\n                let m := div(not(0), 255) // `0x0101 ... `.\n                let h := mul(byte(0, needle), m) // Replicating needle mask.\n                m := not(shl(7, m)) // `0x7f7f ... `.\n                for { let i := add(start, from) } 1 {} {\n                    let c := xor(mload(i), h) // Load 32-byte chunk and xor with mask.\n                    c := not(or(or(add(and(c, m), m), c), m)) // Each needle byte will be `0x80`.\n                    if c {\n                        c := and(not(shr(shl(3, sub(end, i)), not(0))), c) // Truncate bytes past the end.\n                        if c {\n                            let r := shl(7, lt(0x8421084210842108cc6318c6db6d54be, c)) // Save bytecode.\n                            r := or(shl(6, lt(0xffffffffffffffff, shr(r, c))), r)\n                            // forgefmt: disable-next-item\n                            result := add(sub(i, start), shr(3, xor(byte(and(0x1f, shr(byte(24,\n                                mul(0x02040810204081, shr(r, c))), 0x8421084210842108cc6318c6db6d54be)),\n                                0xc0c8c8d0c8e8d0d8c8e8e0e8d0d8e0f0c8d0e8d0e0e0d8f0d0d0e0d8f8f8f8f8), r)))\n                            break\n                        }\n                    }\n                    i := add(i, 0x20)\n                    if iszero(lt(i, end)) { break }\n                }\n            }\n        }\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from left to right. Optimized for byte needles.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function indexOfByte(bytes memory subject, bytes1 needle)\n        internal\n        pure\n        returns (uint256 result)\n    {\n        return indexOfByte(subject, needle, 0);\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from left to right.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function indexOf(bytes memory subject, bytes memory needle) internal pure returns (uint256) {\n        return indexOf(subject, needle, 0);\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from right to left, starting from `from`.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function lastIndexOf(bytes memory subject, bytes memory needle, uint256 from)\n        internal\n        pure\n        returns (uint256 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            for {} 1 {} {\n                result := not(0) // Initialize to `NOT_FOUND`.\n                let needleLen := mload(needle)\n                if gt(needleLen, mload(subject)) { break }\n                let w := result\n\n                let fromMax := sub(mload(subject), needleLen)\n                if iszero(gt(fromMax, from)) { from := fromMax }\n\n                let end := add(add(subject, 0x20), w)\n                subject := add(add(subject, 0x20), from)\n                if iszero(gt(subject, end)) { break }\n                // As this function is not too often used,\n                // we shall simply use keccak256 for smaller bytecode size.\n                for { let h := keccak256(add(needle, 0x20), needleLen) } 1 {} {\n                    if eq(keccak256(subject, needleLen), h) {\n                        result := sub(subject, add(end, 1))\n                        break\n                    }\n                    subject := add(subject, w) // `sub(subject, 1)`.\n                    if iszero(gt(subject, end)) { break }\n                }\n                break\n            }\n        }\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from right to left.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function lastIndexOf(bytes memory subject, bytes memory needle)\n        internal\n        pure\n        returns (uint256)\n    {\n        return lastIndexOf(subject, needle, type(uint256).max);\n    }\n\n    /// @dev Returns true if `needle` is found in `subject`, false otherwise.\n    function contains(bytes memory subject, bytes memory needle) internal pure returns (bool) {\n        return indexOf(subject, needle) != NOT_FOUND;\n    }\n\n    /// @dev Returns whether `subject` starts with `needle`.\n    function startsWith(bytes memory subject, bytes memory needle)\n        internal\n        pure\n        returns (bool result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := mload(needle)\n            // Just using keccak256 directly is actually cheaper.\n            let t := eq(keccak256(add(subject, 0x20), n), keccak256(add(needle, 0x20), n))\n            result := lt(gt(n, mload(subject)), t)\n        }\n    }\n\n    /// @dev Returns whether `subject` ends with `needle`.\n    function endsWith(bytes memory subject, bytes memory needle)\n        internal\n        pure\n        returns (bool result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := mload(needle)\n            let notInRange := gt(n, mload(subject))\n            // `subject + 0x20 + max(subject.length - needle.length, 0)`.\n            let t := add(add(subject, 0x20), mul(iszero(notInRange), sub(mload(subject), n)))\n            // Just using keccak256 directly is actually cheaper.\n            result := gt(eq(keccak256(t, n), keccak256(add(needle, 0x20), n)), notInRange)\n        }\n    }\n\n    /// @dev Returns `subject` repeated `times`.\n    function repeat(bytes memory subject, uint256 times)\n        internal\n        pure\n        returns (bytes memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let l := mload(subject) // Subject length.\n            if iszero(or(iszero(times), iszero(l))) {\n                result := mload(0x40)\n                subject := add(subject, 0x20)\n                let o := add(result, 0x20)\n                for {} 1 {} {\n                    // Copy the `subject` one word at a time.\n                    for { let j := 0 } 1 {} {\n                        mstore(add(o, j), mload(add(subject, j)))\n                        j := add(j, 0x20)\n                        if iszero(lt(j, l)) { break }\n                    }\n                    o := add(o, l)\n                    times := sub(times, 1)\n                    if iszero(times) { break }\n                }\n                mstore(o, 0) // Zeroize the slot after the bytes.\n                mstore(0x40, add(o, 0x20)) // Allocate memory.\n                mstore(result, sub(o, add(result, 0x20))) // Store the length.\n            }\n        }\n    }\n\n    /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive).\n    /// `start` and `end` are byte offsets.\n    function slice(bytes memory subject, uint256 start, uint256 end)\n        internal\n        pure\n        returns (bytes memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let l := mload(subject) // Subject length.\n            if iszero(gt(l, end)) { end := l }\n            if iszero(gt(l, start)) { start := l }\n            if lt(start, end) {\n                result := mload(0x40)\n                let n := sub(end, start)\n                let i := add(subject, start)\n                let w := not(0x1f)\n                // Copy the `subject` one word at a time, backwards.\n                for { let j := and(add(n, 0x1f), w) } 1 {} {\n                    mstore(add(result, j), mload(add(i, j)))\n                    j := add(j, w) // `sub(j, 0x20)`.\n                    if iszero(j) { break }\n                }\n                let o := add(add(result, 0x20), n)\n                mstore(o, 0) // Zeroize the slot after the bytes.\n                mstore(0x40, add(o, 0x20)) // Allocate memory.\n                mstore(result, n) // Store the length.\n            }\n        }\n    }\n\n    /// @dev Returns a copy of `subject` sliced from `start` to the end of the bytes.\n    /// `start` is a byte offset.\n    function slice(bytes memory subject, uint256 start)\n        internal\n        pure\n        returns (bytes memory result)\n    {\n        result = slice(subject, start, type(uint256).max);\n    }\n\n    /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive).\n    /// `start` and `end` are byte offsets. Faster than Solidity's native slicing.\n    function sliceCalldata(bytes calldata subject, uint256 start, uint256 end)\n        internal\n        pure\n        returns (bytes calldata result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            end := xor(end, mul(xor(end, subject.length), lt(subject.length, end)))\n            start := xor(start, mul(xor(start, subject.length), lt(subject.length, start)))\n            result.offset := add(subject.offset, start)\n            result.length := mul(lt(start, end), sub(end, start))\n        }\n    }\n\n    /// @dev Returns a copy of `subject` sliced from `start` to the end of the bytes.\n    /// `start` is a byte offset. Faster than Solidity's native slicing.\n    function sliceCalldata(bytes calldata subject, uint256 start)\n        internal\n        pure\n        returns (bytes calldata result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            start := xor(start, mul(xor(start, subject.length), lt(subject.length, start)))\n            result.offset := add(subject.offset, start)\n            result.length := mul(lt(start, subject.length), sub(subject.length, start))\n        }\n    }\n\n    /// @dev Reduces the size of `subject` to `n`.\n    /// If `n` is greater than the size of `subject`, this will be a no-op.\n    function truncate(bytes memory subject, uint256 n)\n        internal\n        pure\n        returns (bytes memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := subject\n            mstore(mul(lt(n, mload(result)), result), n)\n        }\n    }\n\n    /// @dev Returns a copy of `subject`, with the length reduced to `n`.\n    /// If `n` is greater than the size of `subject`, this will be a no-op.\n    function truncatedCalldata(bytes calldata subject, uint256 n)\n        internal\n        pure\n        returns (bytes calldata result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result.offset := subject.offset\n            result.length := xor(n, mul(xor(n, subject.length), lt(subject.length, n)))\n        }\n    }\n\n    /// @dev Returns all the indices of `needle` in `subject`.\n    /// The indices are byte offsets.\n    function indicesOf(bytes memory subject, bytes memory needle)\n        internal\n        pure\n        returns (uint256[] memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let searchLen := mload(needle)\n            if iszero(gt(searchLen, mload(subject))) {\n                result := mload(0x40)\n                let i := add(subject, 0x20)\n                let o := add(result, 0x20)\n                let subjectSearchEnd := add(sub(add(i, mload(subject)), searchLen), 1)\n                let h := 0 // The hash of `needle`.\n                if iszero(lt(searchLen, 0x20)) { h := keccak256(add(needle, 0x20), searchLen) }\n                let s := mload(add(needle, 0x20))\n                for { let m := shl(3, sub(0x20, and(searchLen, 0x1f))) } 1 {} {\n                    let t := mload(i)\n                    // Whether the first `searchLen % 32` bytes of `subject` and `needle` matches.\n                    if iszero(shr(m, xor(t, s))) {\n                        if h {\n                            if iszero(eq(keccak256(i, searchLen), h)) {\n                                i := add(i, 1)\n                                if iszero(lt(i, subjectSearchEnd)) { break }\n                                continue\n                            }\n                        }\n                        mstore(o, sub(i, add(subject, 0x20))) // Append to `result`.\n                        o := add(o, 0x20)\n                        i := add(i, searchLen) // Advance `i` by `searchLen`.\n                        if searchLen {\n                            if iszero(lt(i, subjectSearchEnd)) { break }\n                            continue\n                        }\n                    }\n                    i := add(i, 1)\n                    if iszero(lt(i, subjectSearchEnd)) { break }\n                }\n                mstore(result, shr(5, sub(o, add(result, 0x20)))) // Store the length of `result`.\n                // Allocate memory for result.\n                // We allocate one more word, so this array can be recycled for {split}.\n                mstore(0x40, add(o, 0x20))\n            }\n        }\n    }\n\n    /// @dev Returns an arrays of bytess based on the `delimiter` inside of the `subject` bytes.\n    function split(bytes memory subject, bytes memory delimiter)\n        internal\n        pure\n        returns (bytes[] memory result)\n    {\n        uint256[] memory indices = indicesOf(subject, delimiter);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let w := not(0x1f)\n            let indexPtr := add(indices, 0x20)\n            let indicesEnd := add(indexPtr, shl(5, add(mload(indices), 1)))\n            mstore(add(indicesEnd, w), mload(subject))\n            mstore(indices, add(mload(indices), 1))\n            for { let prevIndex := 0 } 1 {} {\n                let index := mload(indexPtr)\n                mstore(indexPtr, 0x60)\n                if iszero(eq(index, prevIndex)) {\n                    let element := mload(0x40)\n                    let l := sub(index, prevIndex)\n                    mstore(element, l) // Store the length of the element.\n                    // Copy the `subject` one word at a time, backwards.\n                    for { let o := and(add(l, 0x1f), w) } 1 {} {\n                        mstore(add(element, o), mload(add(add(subject, prevIndex), o)))\n                        o := add(o, w) // `sub(o, 0x20)`.\n                        if iszero(o) { break }\n                    }\n                    mstore(add(add(element, 0x20), l), 0) // Zeroize the slot after the bytes.\n                    // Allocate memory for the length and the bytes, rounded up to a multiple of 32.\n                    mstore(0x40, add(element, and(add(l, 0x3f), w)))\n                    mstore(indexPtr, element) // Store the `element` into the array.\n                }\n                prevIndex := add(index, mload(delimiter))\n                indexPtr := add(indexPtr, 0x20)\n                if iszero(lt(indexPtr, indicesEnd)) { break }\n            }\n            result := indices\n            if iszero(mload(delimiter)) {\n                result := add(indices, 0x20)\n                mstore(result, sub(mload(indices), 2))\n            }\n        }\n    }\n\n    /// @dev Returns a concatenated bytes of `a` and `b`.\n    /// Cheaper than `bytes.concat()` and does not de-align the free memory pointer.\n    function concat(bytes memory a, bytes memory b) internal pure returns (bytes memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            let w := not(0x1f)\n            let aLen := mload(a)\n            // Copy `a` one word at a time, backwards.\n            for { let o := and(add(aLen, 0x20), w) } 1 {} {\n                mstore(add(result, o), mload(add(a, o)))\n                o := add(o, w) // `sub(o, 0x20)`.\n                if iszero(o) { break }\n            }\n            let bLen := mload(b)\n            let output := add(result, aLen)\n            // Copy `b` one word at a time, backwards.\n            for { let o := and(add(bLen, 0x20), w) } 1 {} {\n                mstore(add(output, o), mload(add(b, o)))\n                o := add(o, w) // `sub(o, 0x20)`.\n                if iszero(o) { break }\n            }\n            let totalLen := add(aLen, bLen)\n            let last := add(add(result, 0x20), totalLen)\n            mstore(last, 0) // Zeroize the slot after the bytes.\n            mstore(result, totalLen) // Store the length.\n            mstore(0x40, add(last, 0x20)) // Allocate memory.\n        }\n    }\n\n    /// @dev Returns whether `a` equals `b`.\n    function eq(bytes memory a, bytes memory b) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b)))\n        }\n    }\n\n    /// @dev Returns whether `a` equals `b`, where `b` is a null-terminated small bytes.\n    function eqs(bytes memory a, bytes32 b) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // These should be evaluated on compile time, as far as possible.\n            let m := not(shl(7, div(not(iszero(b)), 255))) // `0x7f7f ...`.\n            let x := not(or(m, or(b, add(m, and(b, m)))))\n            let r := shl(7, iszero(iszero(shr(128, x))))\n            r := or(r, shl(6, iszero(iszero(shr(64, 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            result := gt(eq(mload(a), add(iszero(x), xor(31, shr(3, r)))),\n                xor(shr(add(8, r), b), shr(add(8, r), mload(add(a, 0x20)))))\n        }\n    }\n\n    /// @dev Returns 0 if `a == b`, -1 if `a < b`, +1 if `a > b`.\n    /// If `a` == b[:a.length]`, and `a.length < b.length`, returns -1.\n    function cmp(bytes memory a, bytes memory b) internal pure returns (int256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let aLen := mload(a)\n            let bLen := mload(b)\n            let n := and(xor(aLen, mul(xor(aLen, bLen), lt(bLen, aLen))), not(0x1f))\n            if n {\n                for { let i := 0x20 } 1 {} {\n                    let x := mload(add(a, i))\n                    let y := mload(add(b, i))\n                    if iszero(or(xor(x, y), eq(i, n))) {\n                        i := add(i, 0x20)\n                        continue\n                    }\n                    result := sub(gt(x, y), lt(x, y))\n                    break\n                }\n            }\n            // forgefmt: disable-next-item\n            if iszero(result) {\n                let l := 0x201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a090807060504030201\n                let x := and(mload(add(add(a, 0x20), n)), shl(shl(3, byte(sub(aLen, n), l)), not(0)))\n                let y := and(mload(add(add(b, 0x20), n)), shl(shl(3, byte(sub(bLen, n), l)), not(0)))\n                result := sub(gt(x, y), lt(x, y))\n                if iszero(result) { result := sub(gt(aLen, bLen), lt(aLen, bLen)) }\n            }\n        }\n    }\n\n    /// @dev Directly returns `a` without copying.\n    function directReturn(bytes memory a) internal pure {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Assumes that the bytes does not start from the scratch space.\n            let retStart := sub(a, 0x20)\n            let retUnpaddedSize := add(mload(a), 0x40)\n            // Right pad with zeroes. Just in case the bytes is produced\n            // by a method that doesn't zero right pad.\n            mstore(add(retStart, retUnpaddedSize), 0)\n            mstore(retStart, 0x20) // Store the return offset.\n            // End the transaction, returning the bytes.\n            return(retStart, and(not(0x1f), add(0x1f, retUnpaddedSize)))\n        }\n    }\n\n    /// @dev Directly returns `a` with minimal copying.\n    function directReturn(bytes[] memory a) internal pure {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := mload(a) // `a.length`.\n            let o := add(a, 0x20) // Start of elements in `a`.\n            let u := a // Highest memory slot.\n            let w := not(0x1f)\n            for { let i := 0 } iszero(eq(i, n)) { i := add(i, 1) } {\n                let c := add(o, shl(5, i)) // Location of pointer to `a[i]`.\n                let s := mload(c) // `a[i]`.\n                let l := mload(s) // `a[i].length`.\n                let r := and(l, 0x1f) // `a[i].length % 32`.\n                let z := add(0x20, and(l, w)) // Offset of last word in `a[i]` from `s`.\n                // If `s` comes before `o`, or `s` is not zero right padded.\n                if iszero(lt(lt(s, o), or(iszero(r), iszero(shl(shl(3, r), mload(add(s, z))))))) {\n                    let m := mload(0x40)\n                    mstore(m, l) // Copy `a[i].length`.\n                    for {} 1 {} {\n                        mstore(add(m, z), mload(add(s, z))) // Copy `a[i]`, backwards.\n                        z := add(z, w) // `sub(z, 0x20)`.\n                        if iszero(z) { break }\n                    }\n                    let e := add(add(m, 0x20), l)\n                    mstore(e, 0) // Zeroize the slot after the copied bytes.\n                    mstore(0x40, add(e, 0x20)) // Allocate memory.\n                    s := m\n                }\n                mstore(c, sub(s, o)) // Convert to calldata offset.\n                let t := add(l, add(s, 0x20))\n                if iszero(lt(t, u)) { u := t }\n            }\n            let retStart := add(a, w) // Assumes `a` doesn't start from scratch space.\n            mstore(retStart, 0x20) // Store the return offset.\n            return(retStart, add(0x40, sub(u, retStart))) // End the transaction.\n        }\n    }\n\n    /// @dev Returns the word at `offset`, without any bounds checks.\n    function load(bytes memory a, uint256 offset) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(add(add(a, 0x20), offset))\n        }\n    }\n\n    /// @dev Returns the word at `offset`, without any bounds checks.\n    function loadCalldata(bytes calldata a, uint256 offset)\n        internal\n        pure\n        returns (bytes32 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := calldataload(add(a.offset, offset))\n        }\n    }\n\n    /// @dev Returns a slice representing a static struct in the calldata. Performs bounds checks.\n    function staticStructInCalldata(bytes calldata a, uint256 offset)\n        internal\n        pure\n        returns (bytes calldata result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let l := sub(a.length, 0x20)\n            result.offset := add(a.offset, offset)\n            result.length := sub(a.length, offset)\n            if or(shr(64, or(l, a.offset)), gt(offset, l)) { revert(l, 0x00) }\n        }\n    }\n\n    /// @dev Returns a slice representing a dynamic struct in the calldata. Performs bounds checks.\n    function dynamicStructInCalldata(bytes calldata a, uint256 offset)\n        internal\n        pure\n        returns (bytes calldata result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let l := sub(a.length, 0x20)\n            let s := calldataload(add(a.offset, offset)) // Relative offset of `result` from `a.offset`.\n            result.offset := add(a.offset, s)\n            result.length := sub(a.length, s)\n            if or(shr(64, or(s, or(l, a.offset))), gt(offset, l)) { revert(l, 0x00) }\n        }\n    }\n\n    /// @dev Returns bytes in calldata. Performs bounds checks.\n    function bytesInCalldata(bytes calldata a, uint256 offset)\n        internal\n        pure\n        returns (bytes calldata result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let l := sub(a.length, 0x20)\n            let s := calldataload(add(a.offset, offset)) // Relative offset of `result` from `a.offset`.\n            result.offset := add(add(a.offset, s), 0x20)\n            result.length := calldataload(add(a.offset, s))\n            // forgefmt: disable-next-item\n            if or(shr(64, or(result.length, or(s, or(l, a.offset)))),\n                or(gt(add(s, result.length), l), gt(offset, l))) { revert(l, 0x00) }\n        }\n    }\n\n    /// @dev Checks if `x` is in `a`. Assumes `a` has been checked.\n    function checkInCalldata(bytes calldata x, bytes calldata a) internal pure {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if or(\n                or(lt(x.offset, a.offset), gt(add(x.offset, x.length), add(a.length, a.offset))),\n                shr(64, or(x.length, x.offset))\n            ) { revert(0x00, 0x00) }\n        }\n    }\n\n    /// @dev Checks if `x` is in `a`. Assumes `a` has been checked.\n    function checkInCalldata(bytes[] calldata x, bytes calldata a) internal pure {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let e := sub(add(a.length, a.offset), 0x20)\n            if or(lt(x.offset, a.offset), shr(64, x.offset)) { revert(0x00, 0x00) }\n            for { let i := 0 } iszero(eq(x.length, i)) { i := add(i, 1) } {\n                let o := calldataload(add(x.offset, shl(5, i)))\n                let t := add(o, x.offset)\n                let l := calldataload(t)\n                if or(shr(64, or(l, o)), gt(add(t, l), e)) { revert(0x00, 0x00) }\n            }\n        }\n    }\n\n    /// @dev Returns empty calldata bytes. For silencing the compiler.\n    function emptyCalldata() internal pure returns (bytes calldata result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result.length := 0\n        }\n    }\n\n    /// @dev Returns the most significant 20 bytes as an address.\n    function msbToAddress(bytes32 x) internal pure returns (address) {\n        return address(bytes20(x));\n    }\n\n    /// @dev Returns the least significant 20 bytes as an address.\n    function lsbToAddress(bytes32 x) internal pure returns (address) {\n        return address(uint160(uint256(x)));\n    }\n}\n"}},"abi":[{"type":"constructor","inputs":[{"name":"payee_","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"name":"AccountBalanceOverflow","type":"error","inputs":[]},{"name":"BalanceQueryForZeroAddress","type":"error","inputs":[]},{"name":"FreeQuotaExhaustedOrNotAgent","type":"error","inputs":[]},{"name":"InsufficientPayment","type":"error","inputs":[]},{"name":"InvalidQuantity","type":"error","inputs":[]},{"name":"InvalidReferrer","type":"error","inputs":[]},{"name":"NotOwnerNorApproved","type":"error","inputs":[]},{"name":"NothingToClaim","type":"error","inputs":[]},{"name":"Reentrancy","type":"error","inputs":[]},{"name":"SlippageStateChanged","type":"error","inputs":[]},{"name":"SoldOut","type":"error","inputs":[]},{"name":"TailNotUnlocked","type":"error","inputs":[]},{"name":"TokenAlreadyExists","type":"error","inputs":[]},{"name":"TokenDoesNotExist","type":"error","inputs":[]},{"name":"TransferFailed","type":"error","inputs":[]},{"name":"TransferFromIncorrectOwner","type":"error","inputs":[]},{"name":"TransferToNonERC721ReceiverImplementer","type":"error","inputs":[]},{"name":"TransferToZeroAddress","type":"error","inputs":[]},{"name":"WalletLimitExceeded","type":"error","inputs":[]},{"name":"ZeroAddress","type":"error","inputs":[]},{"name":"Approval","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"id","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"ApprovalForAll","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"isApproved","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"EpochVaultWon","type":"event","inputs":[{"name":"winner","type":"address","indexed":true,"internalType":"address"},{"name":"referrer","type":"address","indexed":true,"internalType":"address"},{"name":"goldKeyNumber","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"buyerPrize","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"refCoPrize","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"FreePassMinted","type":"event","inputs":[{"name":"buyer","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"NexusKeyMinted","type":"event","inputs":[{"name":"buyer","type":"address","indexed":true,"internalType":"address"},{"name":"referrer","type":"address","indexed":true,"internalType":"address"},{"name":"startTokenId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"qty","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"totalPaid","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"referrerRebate","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"vaultWon","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"PayoutCredited","type":"event","inputs":[{"name":"recipient","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"PayoutWithdrawn","type":"event","inputs":[{"name":"recipient","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"ReferralRebatePaid","type":"event","inputs":[{"name":"referrer","type":"address","indexed":true,"internalType":"address"},{"name":"buyer","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"rebateBps","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"TailVaultClaimed","type":"event","inputs":[{"name":"winner","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Transfer","type":"event","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"id","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"AGENT_ID_REGISTRY","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"BASE_REFERRER_BPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"EPOCH_SIZE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"FREE_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"KEY_PRICE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_FREE_PER_WALLET","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_FREE_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_GOLD_PER_WALLET","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_GOLD_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_PER_TX","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_PER_WALLET","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"pure"},{"name":"MAX_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"OWNER","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"PAYEE","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"PRICE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"REF_DISCOUNT_PRICE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"SILVER_PARTNER_BPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"SOVEREIGN_PARTNER_BPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"TAIL_TIMEOUT","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"VAULT_BUYER_WIN_BPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"VAULT_POOL_BPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"VAULT_REF_COWIN_BPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"approve","type":"function","inputs":[{"name":"account","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"balanceOf","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"result","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"boundReferrer","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"buyKey","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"buyKeyWithRef","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"},{"name":"referrer","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"payable"},{"name":"claim","type":"function","inputs":[],"outputs":[],"stateMutability":"payable"},{"name":"claimTailVault","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"claimablePayout","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"claimedFree","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"contractURI","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"pure"},{"name":"flushPayout","type":"function","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"freeMint","type":"function","inputs":[],"outputs":[],"stateMutability":"payable"},{"name":"freeMinted","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getApproved","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"result","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"goldKeyNumber","type":"function","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"goldMinted","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"goldMintedBy","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"isApprovedForAll","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"result","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isEligibleFree","type":"function","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isGoldKey","type":"function","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isGoldPartner","type":"function","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"keysUntilNextVault","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"lastGoldBuyer","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"lastGoldBuyerIsAgent","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"lastGoldMintTime","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[],"outputs":[],"stateMutability":"payable"},{"name":"mint","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"mintOpen","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"mintPrice","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"mintWithRef","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"},{"name":"referrer","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"payable"},{"name":"mintWithRefExact","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"},{"name":"referrer","type":"address","internalType":"address"},{"name":"expectedGoldMinted","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"mintedBy","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"name","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"pure"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"ownerOf","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"result","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"price","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"quote","type":"function","inputs":[{"name":"buyer","type":"address","internalType":"address"},{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"quoteWithRef","type":"function","inputs":[{"name":"buyer","type":"address","internalType":"address"},{"name":"qty","type":"uint256","internalType":"uint256"},{"name":"referrer","type":"address","internalType":"address"}],"outputs":[{"name":"buyerCost","type":"uint256","internalType":"uint256"},{"name":"referrerRebate","type":"uint256","internalType":"uint256"},{"name":"expectedBuyerVaultWin","type":"uint256","internalType":"uint256"},{"name":"expectedRefCoWin","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"referralCountBy","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"referralEarnedBy","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"referrerRebateBps","type":"function","inputs":[{"name":"referrer","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"royaltyInfo","type":"function","inputs":[{"name":"","type":"uint256","internalType":"uint256"},{"name":"salePrice","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"receiver","type":"address","internalType":"address"},{"name":"royaltyAmount","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"safeTransferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"safeTransferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"payable"},{"name":"setApprovalForAll","type":"function","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"isApproved","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"supportsInterface","type":"function","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"symbol","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"pure"},{"name":"tokenURI","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"totalEscrowedPayouts","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalMinted","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalReferralPaid","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalVaultPaid","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"vaultPool","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"withdrawPayout","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"withdrawPayoutTo","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"}],"matchId":"57663096","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-10-30T10:05:23Z","match":"exact_match","chainId":"56","address":"0xb804BaF3511cEF9706De33F14cF7949791847a29"}