{"sources":{"src/facets/DiceFacet.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nimport {AppStorage, LibAppStorage, Modifiers} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiceStorage, DiceStorage} from \"../libraries/LibDiceStorage.sol\";\n\nimport {FacetCommons} from \"../shared/FacetCommons.sol\";\n\nimport {ECDSA} from \"openzeppelin/utils/cryptography/ECDSA.sol\";\n\n// return on chain metadata with latest evolution svgs\ncontract DiceFacet is Modifiers, FacetCommons {\n    using ECDSA for bytes32;\n    using ECDSA for bytes;\n\n    event DiceJoin(\n        uint256 indexed gameId,\n        uint256 petId,\n        uint256 indexed number\n    );\n    event DiceSettle(uint256 gameId, uint256 winningNumber, uint256 winner);\n\n    function diceCanSettleGame() public view returns (bool) {\n        return LibDiceStorage.diceStorage().playerIndex == 6;\n    }\n\n    function diceGetWinner(\n        uint256 gameId,\n        bytes32 reveal\n    ) internal view returns (uint256 winningNumber, uint256 winner) {\n        uint256[6] memory players = LibDiceStorage\n            .diceStorage()\n            .gameIdToPlayers[gameId];\n        uint256 winnerIndex = uint256(\n            keccak256(\n                abi.encodePacked(\n                    players, // use the players ids\n                    reveal // use reveal\n                )\n            )\n        ) % 6;\n\n        winningNumber = winnerIndex + 1;\n        winner = players[winnerIndex];\n    }\n\n    function diceSignatureMatchGameData(\n        uint256 gameId,\n        bytes32 commit,\n        bytes memory signature\n    ) internal view returns (bool) {\n        bytes32 message = keccak256(abi.encodePacked(gameId, commit))\n            .toEthSignedMessageHash();\n\n        address signer = message.recover(signature);\n\n        return signer == LibDiceStorage.diceStorage().gameSigner;\n    }\n\n    function diceJoin(\n        uint256 petId,\n        bytes32 commit,\n        bytes memory signature\n    ) external {\n        AppStorage storage s = LibAppStorage.appStorage();\n        DiceStorage storage d = LibDiceStorage.diceStorage();\n\n        require(s.nft.ownerOf(petId) == msg.sender, \"!you must own the pet\");\n\n        uint256 gameId = d.currentGame;\n        uint256 nbPlayers = d.playerIndex;\n\n        if (nbPlayers == 0) {\n            require(\n                diceSignatureMatchGameData(gameId, commit, signature),\n                \"can't join\"\n            );\n\n            d.gameIdToCommit[gameId] = commit;\n        } else {\n            require(nbPlayers != 6, \"Can't join, wait for new game\");\n            require(commit == d.gameIdToCommit[gameId], \"can't join\");\n        }\n\n        s.token.transferFrom(msg.sender, address(this), d.gameAmt);\n\n        d.gameIdToPlayers[gameId][nbPlayers] = petId;\n\n        d.playerIndex++;\n\n        emit DiceJoin(gameId, petId, nbPlayers + 1);\n    }\n\n    function diceSettleGame(bytes32 reveal) external {\n        DiceStorage storage d = LibDiceStorage.diceStorage();\n\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        bytes32 commit = keccak256(abi.encode(reveal));\n\n        uint256 gameId = d.currentGame;\n        require(\n            commit == d.gameIdToCommit[gameId],\n            \"not valid reveal, can't settle\"\n        );\n\n        require(diceCanSettleGame(), \"waiting for participants\");\n\n        (uint256 winningNumber, uint256 winner) = diceGetWinner(gameId, reveal);\n\n        s.token.burn(d.gameAmt); //we burn 10%\n\n        s.token.transfer(s.nft.ownerOf(winner), (d.gameAmt * 6) - d.gameAmt);\n\n        emit DiceSettle(gameId, winningNumber, winner);\n\n        d.gameIdToWinner[gameId] = winner;\n        d.gameIdToWinningNumber[gameId] = winningNumber;\n\n        // new game starts\n        d.currentGame++;\n        d.playerIndex = 0;\n    }\n\n    function diceSetNewPrice(\n        uint256 newPrice,\n        address _gameSigner\n    ) external onlyOwner {\n        LibDiceStorage.diceStorage().gameAmt = newPrice;\n        LibDiceStorage.diceStorage().gameSigner = _gameSigner;\n    }\n\n    // getters\n\n    function gameSigner() public view returns (address) {\n        DiceStorage storage d = LibDiceStorage.diceStorage();\n\n        return d.gameSigner;\n    }\n\n    function gameAmt() public view returns (uint256) {\n        DiceStorage storage d = LibDiceStorage.diceStorage();\n\n        return d.gameAmt;\n    }\n\n    function playerIndex() public view returns (uint256) {\n        DiceStorage storage d = LibDiceStorage.diceStorage();\n\n        return d.playerIndex;\n    }\n\n    function gameIdToCommit(uint256 _gameId) public view returns (bytes32) {\n        DiceStorage storage d = LibDiceStorage.diceStorage();\n\n        return d.gameIdToCommit[_gameId];\n    }\n\n    function gameIdToPlayers(\n        uint256 _gameId\n    ) public view returns (uint256[6] memory) {\n        DiceStorage storage d = LibDiceStorage.diceStorage();\n\n        return d.gameIdToPlayers[_gameId];\n    }\n\n    function gameIdToWinningNumber(\n        uint256 _gameId\n    ) public view returns (uint256) {\n        DiceStorage storage d = LibDiceStorage.diceStorage();\n\n        return d.gameIdToWinningNumber[_gameId];\n    }\n\n    function gameIdToWinner(uint256 _gameId) public view returns (uint256) {\n        DiceStorage storage d = LibDiceStorage.diceStorage();\n\n        return d.gameIdToWinner[_gameId];\n    }\n\n    function currentGame() public view returns (uint256) {\n        DiceStorage storage d = LibDiceStorage.diceStorage();\n\n        return d.currentGame;\n    }\n}\n"},"src/libraries/LibMeta.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nlibrary LibMeta {\n    bytes32 internal constant EIP712_DOMAIN_TYPEHASH =\n        keccak256(\n            bytes(\n                \"EIP712Domain(string name,string version,uint256 salt,address verifyingContract)\"\n            )\n        );\n\n    function domainSeparator(\n        string memory name,\n        string memory version\n    ) internal view returns (bytes32 domainSeparator_) {\n        domainSeparator_ = keccak256(\n            abi.encode(\n                EIP712_DOMAIN_TYPEHASH,\n                keccak256(bytes(name)),\n                keccak256(bytes(version)),\n                getChainID(),\n                address(this)\n            )\n        );\n    }\n\n    function getChainID() internal view returns (uint256 id) {\n        assembly {\n            id := chainid()\n        }\n    }\n\n    function msgSender() internal view returns (address sender_) {\n        if (msg.sender == address(this)) {\n            bytes memory array = msg.data;\n            uint256 index = msg.data.length;\n            assembly {\n                // Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.\n                sender_ := and(\n                    mload(add(array, index)),\n                    0xffffffffffffffffffffffffffffffffffffffff\n                )\n            }\n        } else {\n            sender_ = msg.sender;\n        }\n    }\n}\n"},"src/facets/FrenPetFacet.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nimport {AppStorage, LibAppStorage, Modifiers} from \"../libraries/LibAppStorage.sol\";\nimport {DiceStorage, LibDiceStorage} from \"../libraries/LibDiceStorage.sol\";\n\nimport {LibMeta} from \"../libraries/LibMeta.sol\";\n\nimport {EnumerableMap} from \"openzeppelin/utils/structs/EnumerableMap.sol\";\nimport {FixedPointMathLib} from \"solmate/utils/FixedPointMathLib.sol\";\nimport {SafeMath} from \"openzeppelin/utils/math/SafeMath.sol\";\nimport \"../../lib/forge-std/src/console.sol\";\n\n// use this contract to return all getters\n\ncontract FrenPetFacet is Modifiers {\n    using EnumerableMap for EnumerableMap.UintToUintMap;\n    using FixedPointMathLib for uint256;\n    using SafeMath for uint256;\n\n    /*//////////////////////////////////////////////////////////////\n                        Game Getters\n    //////////////////////////////////////////////////////////////*/\n\n    function getDna(uint256 petId) public view returns (uint256[] memory) {\n        AppStorage storage s = LibAppStorage.appStorage();\n        return s.petDna[petId];\n    }\n\n    function rewardsDebt(uint256 petId) public view returns (uint256) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        return s.petRewardDebt[petId];\n    }\n\n    function pendingEth(uint256 petId) public view returns (uint256) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        uint256 _ethAccPerShare = s.ethAccPerShare;\n\n        //petRewardDebt can sometimes be bigger by 1 wei do to several mulDivDowns so we do extra checks\n        if (\n            s.petScore[petId].mulDivDown(_ethAccPerShare, s.PRECISION) <\n            s.petRewardDebt[petId]\n        ) {\n            return s.ethOwed[petId];\n        } else {\n            return\n                (s.petScore[petId].mulDivDown(_ethAccPerShare, s.PRECISION))\n                    .sub(s.petRewardDebt[petId])\n                    .add(s.ethOwed[petId]);\n        }\n    }\n\n    function petItems(\n        uint256 _id,\n        uint256 _itemId\n    ) public view returns (uint256) {\n        AppStorage storage s = LibAppStorage.appStorage();\n        EnumerableMap.UintToUintMap storage itemsOwned = s.itemsOwned[_id];\n\n        return itemsOwned.get(_itemId);\n    }\n\n    function getStatus(uint256 pet) public view returns (uint256 _health) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        //  enum Status {\n        //         HAPPY,\n        //         HUNGRY,\n        //         STARVING,\n        //         DYING,\n        //         DEAD\n        //     }\n        if (!isPetAlive(pet)) {\n            return 4;\n        }\n\n        if (s.timeUntilStarving[pet] > block.timestamp + 16 hours) return 0;\n        if (\n            s.timeUntilStarving[pet] > block.timestamp + 12 hours &&\n            s.timeUntilStarving[pet] < block.timestamp + 16 hours\n        ) return 1;\n\n        if (\n            s.timeUntilStarving[pet] > block.timestamp + 8 hours &&\n            s.timeUntilStarving[pet] < block.timestamp + 12 hours\n        ) return 2;\n\n        if (s.timeUntilStarving[pet] < block.timestamp + 8 hours) return 3;\n    }\n\n    function itemExists(uint256 itemId) public view returns (bool) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        if (bytes(s.itemName[itemId]).length > 0) {\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    // check that Pet didn't starve\n    function isPetAlive(uint256 _nftId) public view returns (bool) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        uint256 _timeUntilStarving = s.timeUntilStarving[_nftId];\n        if (_timeUntilStarving != 0 && _timeUntilStarving >= block.timestamp) {\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    function getItemInfo(\n        uint256 _itemId\n    )\n        public\n        view\n        returns (\n            string memory _name,\n            uint256 _price,\n            uint256 _sellPrice,\n            uint256 _points,\n            uint256 _timeExtension,\n            uint256 _itemDelta,\n            uint256 _itemEquipExpires,\n            uint256 _bought,\n            uint256 _supply,\n            bool _itemIsSellable\n        )\n    {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        _name = s.itemName[_itemId];\n        _price = s.itemPrice[_itemId];\n        _sellPrice = ((s.itemPrice[_itemId] - s.itemDelta[_itemId]) * 90) / 100;\n        _timeExtension = s.itemTimeExtension[_itemId];\n        _points = s.itemPoints[_itemId];\n        _itemDelta = s.itemDelta[_itemId];\n        _itemEquipExpires = s.itemEquipExpires[_itemId];\n        _bought = s.itemBought[_itemId];\n        _supply = s.itemSupply[_itemId];\n        _itemIsSellable = s.itemIsSellable[_itemId];\n    }\n\n    function getPetInfo(\n        uint256 _nftId\n    )\n        public\n        view\n        returns (\n            string memory _name,\n            uint256 _status,\n            uint256 _score,\n            uint256 _level,\n            uint256 _timeUntilStarving,\n            uint256 _lastAttacked,\n            uint256 _lastAttackUsed,\n            address _owner,\n            uint256 _rewards\n        )\n    {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        _name = s.petName[_nftId];\n        _status = getStatus(_nftId);\n        _score = s.petScore[_nftId];\n        _level = level(_nftId);\n        _timeUntilStarving = s.timeUntilStarving[_nftId];\n        _lastAttacked = s.lastAttacked[_nftId];\n        _lastAttackUsed = s.lastAttackUsed[_nftId];\n        _owner = !isPetAlive(_nftId) && _score == 0\n            ? address(0x0)\n            : s.nft.ownerOf(_nftId);\n        _rewards = pendingEth(_nftId);\n    }\n\n    // calculate level based on points\n    function level(uint256 tokenId) public view returns (uint256) {\n        // This is the formula L(x) = 2 * sqrt(x * 2)\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        uint256 _score = s.petScore[tokenId] / 1e12;\n        _score = _score / 100;\n        if (_score == 0) {\n            return 1;\n        }\n        uint256 _level = _sqrtu(_score * s.la);\n        return (_level * s.lb);\n    }\n\n    function ethAccPerShare() public view returns (uint256) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        return s.ethAccPerShare;\n    }\n\n    function totalScores() public view returns (uint256) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        return s.totalScores;\n    }\n\n    function ethOwed(uint256 petId) public view returns (uint256) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        return s.ethOwed[petId];\n    }\n\n    function petRewardDebt(uint256 petId) public view returns (uint256) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        return s.petRewardDebt[petId];\n    }\n\n    function lastAttackUsed(uint256 petId) public view returns (uint256) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        return s.lastAttackUsed[petId];\n    }\n\n    function lastAttacked(uint256 petId) public view returns (uint256) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        return s.lastAttacked[petId];\n    }\n\n    function stars(uint256 petId) public view returns (uint256) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        return s.stars[petId];\n    }\n\n    function petName(uint256 petId) public view returns (string memory) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        return s.petName[petId];\n    }\n\n    // random vars\n    function minPrice() public view returns (uint256) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        return s.minPrice;\n    }\n\n    function petScore(uint256 petId) public view returns (uint256) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        return s.petScore[petId];\n    }\n\n    function timePetBorn(uint256 petId) public view returns (uint256) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        return s.timePetBorn[petId];\n    }\n\n    function hasTheDiamond() public view returns (uint256) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        return s.hasTheDiamond;\n    }\n\n    function timeUntilStarving(uint256 petId) public view returns (uint256) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        return s.timeUntilStarving[petId];\n    }\n\n    function _sqrtu(uint256 x) private pure returns (uint128) {\n        if (x == 0) return 0;\n        else {\n            uint256 xx = x;\n            uint256 r = 1;\n            if (xx >= 0x100000000000000000000000000000000) {\n                xx >>= 128;\n                r <<= 64;\n            }\n            if (xx >= 0x10000000000000000) {\n                xx >>= 64;\n                r <<= 32;\n            }\n            if (xx >= 0x100000000) {\n                xx >>= 32;\n                r <<= 16;\n            }\n            if (xx >= 0x10000) {\n                xx >>= 16;\n                r <<= 8;\n            }\n            if (xx >= 0x100) {\n                xx >>= 8;\n                r <<= 4;\n            }\n            if (xx >= 0x10) {\n                xx >>= 4;\n                r <<= 2;\n            }\n            if (xx >= 0x8) {\n                r <<= 1;\n            }\n            r = (r + x / r) >> 1;\n            r = (r + x / r) >> 1;\n            r = (r + x / r) >> 1;\n            r = (r + x / r) >> 1;\n            r = (r + x / r) >> 1;\n            r = (r + x / r) >> 1;\n            r = (r + x / r) >> 1; // Seven iterations should be enough\n            uint256 r1 = x / r;\n            return uint128(r < r1 ? r : r1);\n        }\n    }\n\n    // dice\n\n    // get mint price\n    function getPrice() public pure returns (uint256) {\n        return 100 ether;\n    }\n}\n"},"src/interfaces/IDiamond.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\n/******************************************************************************\\\n* Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamond {\n    enum FacetCutAction {\n        Add,\n        Replace,\n        Remove\n    }\n    // Add=0, Replace=1, Remove=2\n\n    struct FacetCut {\n        address facetAddress;\n        FacetCutAction action;\n        bytes4[] functionSelectors;\n    }\n\n    event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n"},"src/shared/FacetCommons.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nimport {AppStorage, LibAppStorage, Modifiers} from \"../libraries/LibAppStorage.sol\";\nimport {ReferralStorage, LibReferralStorage} from \"../libraries/LibReferralStorage.sol\";\n\nimport {FrenPetFacet} from \"../facets/FrenPetFacet.sol\";\n\nimport {SafeTransferLib} from \"solmate/utils/SafeTransferLib.sol\";\n\nimport {FixedPointMathLib} from \"solmate/utils/FixedPointMathLib.sol\";\n\nimport {EnumerableMap} from \"openzeppelin/utils/structs/EnumerableMap.sol\";\n\nimport \"../../lib/forge-std/src/console.sol\";\n\nabstract contract FacetCommons {\n    using SafeTransferLib for address payable;\n    using FixedPointMathLib for uint256;\n\n    using EnumerableMap for EnumerableMap.UintToUintMap;\n\n    event RedeemRewards(uint256 indexed petId, uint256 reward);\n\n    function _redeem(uint256 petId, address _to) internal {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        uint256 pending = frenPetFacet().pendingEth(petId);\n\n        s.totalScores -= s.petScore[petId];\n        s.petScore[petId] = 0;\n        s.ethOwed[petId] = 0;\n        s.petRewardDebt[petId] = 0;\n\n        payable(_to).safeTransferETH(pending);\n\n        emit RedeemRewards(petId, pending);\n    }\n\n    function frenPetFacet() internal view returns (FrenPetFacet fpFacet) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        fpFacet = FrenPetFacet(s.DIAMOND_ADDRESS);\n    }\n\n    function random(uint256 seed, uint256 max) internal view returns (uint) {\n        uint hashNumber = uint(\n            keccak256(\n                abi.encodePacked(\n                    block.number,\n                    seed,\n                    block.difficulty,\n                    block.timestamp,\n                    msg.sender\n                )\n            )\n        );\n        return hashNumber % max;\n    }\n\n    function equipItem(uint256 petId, uint256 itemId) internal {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        require(s.itemBought[itemId] < s.itemSupply[itemId], \"sold out\");\n\n        s.itemBought[itemId] += 1;\n\n        EnumerableMap.UintToUintMap storage itemsOwned = s.itemsOwned[petId];\n\n        // credit to user\n        (, uint256 totalOwned) = itemsOwned.tryGet(itemId);\n\n        // console.log(\"totlOwned\", totalOwned);\n\n        itemsOwned.set(itemId, totalOwned + 1);\n\n        // when expires\n        s.petItemExpires[petId][itemId] = s.itemEquipExpires[itemId] > 0\n            ? block.timestamp + s.itemEquipExpires[itemId]\n            : 0;\n\n        //add delta\n        s.itemPrice[itemId] += s.itemDelta[itemId];\n\n        //lower from supply\n    }\n\n    function updatePointsAndRewards(uint256 _petId, uint256 _points) internal {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        if (s.petScore[_petId] > 0) {\n            s.ethOwed[_petId] = frenPetFacet().pendingEth(_petId);\n        }\n\n        s.petScore[_petId] += _points;\n\n        s.petRewardDebt[_petId] = s.petScore[_petId].mulDivDown(\n            s.ethAccPerShare,\n            s.PRECISION\n        );\n\n        s.totalScores += _points;\n    }\n\n    function distributeToRef(uint256 _petId, uint256 refAmt) internal {\n        ReferralStorage storage r = LibReferralStorage.referralStorage();\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        address addr = r.petToRef[_petId];\n\n        if (addr == address(0)) {\n            s.token.transfer(\n                0xFF0C532FDB8Cd566Ae169C1CB157ff2Bdc83E105,\n                refAmt\n            );\n        } else {\n            s.token.transfer(addr, refAmt);\n        }\n    }\n}\n"},"src/libraries/LibDiamond.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\n/******************************************************************************\\\n* Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamond} from \"../interfaces/IDiamond.sol\";\nimport {IDiamondCut} from \"../interfaces/IDiamondCut.sol\";\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nerror NoSelectorsGivenToAdd();\nerror NotContractOwner(address _user, address _contractOwner);\nerror NoSelectorsProvidedForFacetForCut(address _facetAddress);\nerror CannotAddSelectorsToZeroAddress(bytes4[] _selectors);\nerror NoBytecodeAtAddress(address _contractAddress, string _message);\nerror IncorrectFacetCutAction(uint8 _action);\nerror CannotAddFunctionToDiamondThatAlreadyExists(bytes4 _selector);\nerror CannotReplaceFunctionsFromFacetWithZeroAddress(bytes4[] _selectors);\nerror CannotReplaceImmutableFunction(bytes4 _selector);\nerror CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet(\n    bytes4 _selector\n);\nerror CannotReplaceFunctionThatDoesNotExists(bytes4 _selector);\nerror RemoveFacetAddressMustBeZeroAddress(address _facetAddress);\nerror CannotRemoveFunctionThatDoesNotExist(bytes4 _selector);\nerror CannotRemoveImmutableFunction(bytes4 _selector);\nerror InitializationFunctionReverted(\n    address _initializationContractAddress,\n    bytes _calldata\n);\n\nlibrary LibDiamond {\n    bytes32 constant DIAMOND_STORAGE_POSITION =\n        keccak256(\"diamond.standard.diamond.storage\");\n\n    struct FacetAddressAndSelectorPosition {\n        address facetAddress;\n        uint16 selectorPosition;\n    }\n\n    struct DiamondStorage {\n        // function selector => facet address and selector position in selectors array\n        mapping(bytes4 => FacetAddressAndSelectorPosition) facetAddressAndSelectorPosition;\n        bytes4[] selectors;\n        mapping(bytes4 => bool) supportedInterfaces;\n        // owner of the contract\n        address contractOwner;\n    }\n\n    function diamondStorage()\n        internal\n        pure\n        returns (DiamondStorage storage ds)\n    {\n        bytes32 position = DIAMOND_STORAGE_POSITION;\n        assembly {\n            ds.slot := position\n        }\n    }\n\n    event OwnershipTransferred(\n        address indexed previousOwner,\n        address indexed newOwner\n    );\n\n    function setContractOwner(address _newOwner) internal {\n        DiamondStorage storage ds = diamondStorage();\n        address previousOwner = ds.contractOwner;\n        ds.contractOwner = _newOwner;\n        emit OwnershipTransferred(previousOwner, _newOwner);\n    }\n\n    function contractOwner() internal view returns (address contractOwner_) {\n        contractOwner_ = diamondStorage().contractOwner;\n    }\n\n    function enforceIsContractOwner() internal view {\n        if (msg.sender != diamondStorage().contractOwner) {\n            revert NotContractOwner(msg.sender, diamondStorage().contractOwner);\n        }\n    }\n\n    event DiamondCut(\n        IDiamondCut.FacetCut[] _diamondCut,\n        address _init,\n        bytes _calldata\n    );\n\n    // Internal function version of diamondCut\n    function diamondCut(\n        IDiamondCut.FacetCut[] memory _diamondCut,\n        address _init,\n        bytes memory _calldata\n    ) internal {\n        for (\n            uint256 facetIndex;\n            facetIndex < _diamondCut.length;\n            facetIndex++\n        ) {\n            bytes4[] memory functionSelectors = _diamondCut[facetIndex]\n                .functionSelectors;\n            address facetAddress = _diamondCut[facetIndex].facetAddress;\n            if (functionSelectors.length == 0) {\n                revert NoSelectorsProvidedForFacetForCut(facetAddress);\n            }\n            IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n            if (action == IDiamond.FacetCutAction.Add) {\n                addFunctions(facetAddress, functionSelectors);\n            } else if (action == IDiamond.FacetCutAction.Replace) {\n                replaceFunctions(facetAddress, functionSelectors);\n            } else if (action == IDiamond.FacetCutAction.Remove) {\n                removeFunctions(facetAddress, functionSelectors);\n            } else {\n                revert IncorrectFacetCutAction(uint8(action));\n            }\n        }\n        emit DiamondCut(_diamondCut, _init, _calldata);\n        initializeDiamondCut(_init, _calldata);\n    }\n\n    function addFunctions(\n        address _facetAddress,\n        bytes4[] memory _functionSelectors\n    ) internal {\n        if (_facetAddress == address(0)) {\n            revert CannotAddSelectorsToZeroAddress(_functionSelectors);\n        }\n        DiamondStorage storage ds = diamondStorage();\n        uint16 selectorCount = uint16(ds.selectors.length);\n        enforceHasContractCode(\n            _facetAddress,\n            \"LibDiamondCut: Add facet has no code\"\n        );\n        for (\n            uint256 selectorIndex;\n            selectorIndex < _functionSelectors.length;\n            selectorIndex++\n        ) {\n            bytes4 selector = _functionSelectors[selectorIndex];\n            address oldFacetAddress = ds\n                .facetAddressAndSelectorPosition[selector]\n                .facetAddress;\n            if (oldFacetAddress != address(0)) {\n                revert CannotAddFunctionToDiamondThatAlreadyExists(selector);\n            }\n            ds.facetAddressAndSelectorPosition[\n                selector\n            ] = FacetAddressAndSelectorPosition(_facetAddress, selectorCount);\n            ds.selectors.push(selector);\n            selectorCount++;\n        }\n    }\n\n    function replaceFunctions(\n        address _facetAddress,\n        bytes4[] memory _functionSelectors\n    ) internal {\n        DiamondStorage storage ds = diamondStorage();\n        if (_facetAddress == address(0)) {\n            revert CannotReplaceFunctionsFromFacetWithZeroAddress(\n                _functionSelectors\n            );\n        }\n        enforceHasContractCode(\n            _facetAddress,\n            \"LibDiamondCut: Replace facet has no code\"\n        );\n        for (\n            uint256 selectorIndex;\n            selectorIndex < _functionSelectors.length;\n            selectorIndex++\n        ) {\n            bytes4 selector = _functionSelectors[selectorIndex];\n            address oldFacetAddress = ds\n                .facetAddressAndSelectorPosition[selector]\n                .facetAddress;\n            // can't replace immutable functions -- functions defined directly in the diamond in this case\n            if (oldFacetAddress == address(this)) {\n                revert CannotReplaceImmutableFunction(selector);\n            }\n            if (oldFacetAddress == _facetAddress) {\n                revert CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet(\n                    selector\n                );\n            }\n            if (oldFacetAddress == address(0)) {\n                revert CannotReplaceFunctionThatDoesNotExists(selector);\n            }\n            // replace old facet address\n            ds\n                .facetAddressAndSelectorPosition[selector]\n                .facetAddress = _facetAddress;\n        }\n    }\n\n    function removeFunctions(\n        address _facetAddress,\n        bytes4[] memory _functionSelectors\n    ) internal {\n        DiamondStorage storage ds = diamondStorage();\n        uint256 selectorCount = ds.selectors.length;\n        if (_facetAddress != address(0)) {\n            revert RemoveFacetAddressMustBeZeroAddress(_facetAddress);\n        }\n        for (\n            uint256 selectorIndex;\n            selectorIndex < _functionSelectors.length;\n            selectorIndex++\n        ) {\n            bytes4 selector = _functionSelectors[selectorIndex];\n            FacetAddressAndSelectorPosition\n                memory oldFacetAddressAndSelectorPosition = ds\n                    .facetAddressAndSelectorPosition[selector];\n            if (oldFacetAddressAndSelectorPosition.facetAddress == address(0)) {\n                revert CannotRemoveFunctionThatDoesNotExist(selector);\n            }\n\n            // can't remove immutable functions -- functions defined directly in the diamond\n            if (\n                oldFacetAddressAndSelectorPosition.facetAddress == address(this)\n            ) {\n                revert CannotRemoveImmutableFunction(selector);\n            }\n            // replace selector with last selector\n            selectorCount--;\n            if (\n                oldFacetAddressAndSelectorPosition.selectorPosition !=\n                selectorCount\n            ) {\n                bytes4 lastSelector = ds.selectors[selectorCount];\n                ds.selectors[\n                    oldFacetAddressAndSelectorPosition.selectorPosition\n                ] = lastSelector;\n                ds\n                    .facetAddressAndSelectorPosition[lastSelector]\n                    .selectorPosition = oldFacetAddressAndSelectorPosition\n                    .selectorPosition;\n            }\n            // delete last selector\n            ds.selectors.pop();\n            delete ds.facetAddressAndSelectorPosition[selector];\n        }\n    }\n\n    function initializeDiamondCut(\n        address _init,\n        bytes memory _calldata\n    ) internal {\n        if (_init == address(0)) {\n            return;\n        }\n        enforceHasContractCode(\n            _init,\n            \"LibDiamondCut: _init address has no code\"\n        );\n        (bool success, bytes memory error) = _init.delegatecall(_calldata);\n        if (!success) {\n            if (error.length > 0) {\n                // bubble up error\n                /// @solidity memory-safe-assembly\n                assembly {\n                    let returndata_size := mload(error)\n                    revert(add(32, error), returndata_size)\n                }\n            } else {\n                revert InitializationFunctionReverted(_init, _calldata);\n            }\n        }\n    }\n\n    function enforceHasContractCode(\n        address _contract,\n        string memory _errorMessage\n    ) internal view {\n        uint256 contractSize;\n        assembly {\n            contractSize := extcodesize(_contract)\n        }\n        if (contractSize == 0) {\n            revert NoBytecodeAtAddress(_contract, _errorMessage);\n        }\n    }\n}\n"},"lib/forge-std/src/console.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nlibrary console {\n    address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n    function _sendLogPayload(bytes memory payload) private view {\n        uint256 payloadLength = payload.length;\n        address consoleAddress = CONSOLE_ADDRESS;\n        /// @solidity memory-safe-assembly\n        assembly {\n            let payloadStart := add(payload, 32)\n            let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n        }\n    }\n\n    function log() internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n    }\n\n    function logInt(int p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(int)\", p0));\n    }\n\n    function logUint(uint p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n    }\n\n    function logString(string memory p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n    }\n\n    function logBool(bool p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n    }\n\n    function logAddress(address p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n    }\n\n    function logBytes(bytes memory p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n    }\n\n    function logBytes1(bytes1 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n    }\n\n    function logBytes2(bytes2 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n    }\n\n    function logBytes3(bytes3 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n    }\n\n    function logBytes4(bytes4 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n    }\n\n    function logBytes5(bytes5 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n    }\n\n    function logBytes6(bytes6 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n    }\n\n    function logBytes7(bytes7 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n    }\n\n    function logBytes8(bytes8 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n    }\n\n    function logBytes9(bytes9 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n    }\n\n    function logBytes10(bytes10 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n    }\n\n    function logBytes11(bytes11 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n    }\n\n    function logBytes12(bytes12 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n    }\n\n    function logBytes13(bytes13 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n    }\n\n    function logBytes14(bytes14 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n    }\n\n    function logBytes15(bytes15 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n    }\n\n    function logBytes16(bytes16 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n    }\n\n    function logBytes17(bytes17 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n    }\n\n    function logBytes18(bytes18 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n    }\n\n    function logBytes19(bytes19 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n    }\n\n    function logBytes20(bytes20 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n    }\n\n    function logBytes21(bytes21 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n    }\n\n    function logBytes22(bytes22 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n    }\n\n    function logBytes23(bytes23 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n    }\n\n    function logBytes24(bytes24 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n    }\n\n    function logBytes25(bytes25 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n    }\n\n    function logBytes26(bytes26 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n    }\n\n    function logBytes27(bytes27 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n    }\n\n    function logBytes28(bytes28 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n    }\n\n    function logBytes29(bytes29 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n    }\n\n    function logBytes30(bytes30 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n    }\n\n    function logBytes31(bytes31 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n    }\n\n    function logBytes32(bytes32 p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n    }\n\n    function log(uint p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n    }\n\n    function log(string memory p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n    }\n\n    function log(bool p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n    }\n\n    function log(address p0) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n    }\n\n    function log(uint p0, uint p1) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint)\", p0, p1));\n    }\n\n    function log(uint p0, string memory p1) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string)\", p0, p1));\n    }\n\n    function log(uint p0, bool p1) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool)\", p0, p1));\n    }\n\n    function log(uint p0, address p1) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address)\", p0, p1));\n    }\n\n    function log(string memory p0, uint p1) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint)\", p0, p1));\n    }\n\n    function log(string memory p0, string memory p1) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n    }\n\n    function log(string memory p0, bool p1) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n    }\n\n    function log(string memory p0, address p1) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n    }\n\n    function log(bool p0, uint p1) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint)\", p0, p1));\n    }\n\n    function log(bool p0, string memory p1) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n    }\n\n    function log(bool p0, bool p1) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n    }\n\n    function log(bool p0, address p1) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n    }\n\n    function log(address p0, uint p1) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint)\", p0, p1));\n    }\n\n    function log(address p0, string memory p1) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n    }\n\n    function log(address p0, bool p1) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n    }\n\n    function log(address p0, address p1) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n    }\n\n    function log(uint p0, uint p1, uint p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint)\", p0, p1, p2));\n    }\n\n    function log(uint p0, uint p1, string memory p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string)\", p0, p1, p2));\n    }\n\n    function log(uint p0, uint p1, bool p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool)\", p0, p1, p2));\n    }\n\n    function log(uint p0, uint p1, address p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address)\", p0, p1, p2));\n    }\n\n    function log(uint p0, string memory p1, uint p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint)\", p0, p1, p2));\n    }\n\n    function log(uint p0, string memory p1, string memory p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string)\", p0, p1, p2));\n    }\n\n    function log(uint p0, string memory p1, bool p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool)\", p0, p1, p2));\n    }\n\n    function log(uint p0, string memory p1, address p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address)\", p0, p1, p2));\n    }\n\n    function log(uint p0, bool p1, uint p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint)\", p0, p1, p2));\n    }\n\n    function log(uint p0, bool p1, string memory p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string)\", p0, p1, p2));\n    }\n\n    function log(uint p0, bool p1, bool p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool)\", p0, p1, p2));\n    }\n\n    function log(uint p0, bool p1, address p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address)\", p0, p1, p2));\n    }\n\n    function log(uint p0, address p1, uint p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint)\", p0, p1, p2));\n    }\n\n    function log(uint p0, address p1, string memory p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string)\", p0, p1, p2));\n    }\n\n    function log(uint p0, address p1, bool p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool)\", p0, p1, p2));\n    }\n\n    function log(uint p0, address p1, address p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address)\", p0, p1, p2));\n    }\n\n    function log(string memory p0, uint p1, uint p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint)\", p0, p1, p2));\n    }\n\n    function log(string memory p0, uint p1, string memory p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string)\", p0, p1, p2));\n    }\n\n    function log(string memory p0, uint p1, bool p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool)\", p0, p1, p2));\n    }\n\n    function log(string memory p0, uint p1, address p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address)\", p0, p1, p2));\n    }\n\n    function log(string memory p0, string memory p1, uint p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint)\", p0, p1, p2));\n    }\n\n    function log(string memory p0, string memory p1, string memory p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n    }\n\n    function log(string memory p0, string memory p1, bool p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n    }\n\n    function log(string memory p0, string memory p1, address p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n    }\n\n    function log(string memory p0, bool p1, uint p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint)\", p0, p1, p2));\n    }\n\n    function log(string memory p0, bool p1, string memory p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n    }\n\n    function log(string memory p0, bool p1, bool p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n    }\n\n    function log(string memory p0, bool p1, address p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n    }\n\n    function log(string memory p0, address p1, uint p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint)\", p0, p1, p2));\n    }\n\n    function log(string memory p0, address p1, string memory p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n    }\n\n    function log(string memory p0, address p1, bool p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n    }\n\n    function log(string memory p0, address p1, address p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n    }\n\n    function log(bool p0, uint p1, uint p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint)\", p0, p1, p2));\n    }\n\n    function log(bool p0, uint p1, string memory p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string)\", p0, p1, p2));\n    }\n\n    function log(bool p0, uint p1, bool p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool)\", p0, p1, p2));\n    }\n\n    function log(bool p0, uint p1, address p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address)\", p0, p1, p2));\n    }\n\n    function log(bool p0, string memory p1, uint p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint)\", p0, p1, p2));\n    }\n\n    function log(bool p0, string memory p1, string memory p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n    }\n\n    function log(bool p0, string memory p1, bool p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n    }\n\n    function log(bool p0, string memory p1, address p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n    }\n\n    function log(bool p0, bool p1, uint p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint)\", p0, p1, p2));\n    }\n\n    function log(bool p0, bool p1, string memory p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n    }\n\n    function log(bool p0, bool p1, bool p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n    }\n\n    function log(bool p0, bool p1, address p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n    }\n\n    function log(bool p0, address p1, uint p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint)\", p0, p1, p2));\n    }\n\n    function log(bool p0, address p1, string memory p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n    }\n\n    function log(bool p0, address p1, bool p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n    }\n\n    function log(bool p0, address p1, address p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n    }\n\n    function log(address p0, uint p1, uint p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint)\", p0, p1, p2));\n    }\n\n    function log(address p0, uint p1, string memory p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string)\", p0, p1, p2));\n    }\n\n    function log(address p0, uint p1, bool p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool)\", p0, p1, p2));\n    }\n\n    function log(address p0, uint p1, address p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address)\", p0, p1, p2));\n    }\n\n    function log(address p0, string memory p1, uint p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint)\", p0, p1, p2));\n    }\n\n    function log(address p0, string memory p1, string memory p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n    }\n\n    function log(address p0, string memory p1, bool p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n    }\n\n    function log(address p0, string memory p1, address p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n    }\n\n    function log(address p0, bool p1, uint p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint)\", p0, p1, p2));\n    }\n\n    function log(address p0, bool p1, string memory p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n    }\n\n    function log(address p0, bool p1, bool p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n    }\n\n    function log(address p0, bool p1, address p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n    }\n\n    function log(address p0, address p1, uint p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint)\", p0, p1, p2));\n    }\n\n    function log(address p0, address p1, string memory p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n    }\n\n    function log(address p0, address p1, bool p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n    }\n\n    function log(address p0, address p1, address p2) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n    }\n\n    function log(uint p0, uint p1, uint p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, uint p1, uint p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,string)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, uint p1, uint p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, uint p1, uint p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,address)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, uint p1, string memory p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, uint p1, string memory p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,string)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, uint p1, string memory p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, uint p1, string memory p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,address)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, uint p1, bool p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, uint p1, bool p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,string)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, uint p1, bool p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, uint p1, bool p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,address)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, uint p1, address p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, uint p1, address p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,string)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, uint p1, address p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, uint p1, address p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,address)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, string memory p1, uint p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, string memory p1, uint p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,string)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, string memory p1, uint p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, string memory p1, uint p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,address)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, string memory p1, string memory p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,string)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, string memory p1, string memory p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, string memory p1, string memory p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,address)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, string memory p1, bool p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, string memory p1, bool p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,string)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, string memory p1, bool p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, string memory p1, bool p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,address)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, string memory p1, address p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, string memory p1, address p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,string)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, string memory p1, address p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, string memory p1, address p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,address)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, bool p1, uint p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, bool p1, uint p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,string)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, bool p1, uint p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, bool p1, uint p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,address)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, bool p1, string memory p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, bool p1, string memory p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,string)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, bool p1, string memory p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, bool p1, string memory p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,address)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, bool p1, bool p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, bool p1, bool p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,string)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, bool p1, bool p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, bool p1, bool p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,address)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, bool p1, address p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, bool p1, address p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,string)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, bool p1, address p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, bool p1, address p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,address)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, address p1, uint p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, address p1, uint p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,string)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, address p1, uint p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, address p1, uint p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,address)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, address p1, string memory p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, address p1, string memory p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,string)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, address p1, string memory p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, address p1, string memory p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,address)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, address p1, bool p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, address p1, bool p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,string)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, address p1, bool p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, address p1, bool p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,address)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, address p1, address p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, address p1, address p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,string)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, address p1, address p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(uint p0, address p1, address p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,address)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, uint p1, uint p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, uint p1, uint p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,string)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, uint p1, uint p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, uint p1, uint p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,address)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, uint p1, string memory p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,string)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, uint p1, string memory p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, uint p1, string memory p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,address)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, uint p1, bool p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, uint p1, bool p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,string)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, uint p1, bool p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, uint p1, bool p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,address)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, uint p1, address p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, uint p1, address p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,string)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, uint p1, address p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, uint p1, address p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,address)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, string memory p1, uint p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,string)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, string memory p1, uint p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, string memory p1, uint p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,address)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, string memory p1, bool p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, string memory p1, bool p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, string memory p1, address p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, string memory p1, address p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, string memory p1, address p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, bool p1, uint p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, bool p1, uint p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,string)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, bool p1, uint p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, bool p1, uint p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,address)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, bool p1, string memory p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, bool p1, string memory p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, bool p1, bool p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, bool p1, bool p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, bool p1, bool p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, bool p1, address p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, bool p1, address p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, bool p1, address p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, bool p1, address p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, address p1, uint p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, address p1, uint p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,string)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, address p1, uint p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, address p1, uint p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,address)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, address p1, string memory p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, address p1, string memory p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, address p1, string memory p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, address p1, bool p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, address p1, bool p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, address p1, bool p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, address p1, bool p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, address p1, address p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, address p1, address p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, address p1, address p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(string memory p0, address p1, address p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, uint p1, uint p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, uint p1, uint p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,string)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, uint p1, uint p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, uint p1, uint p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,address)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, uint p1, string memory p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, uint p1, string memory p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,string)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, uint p1, string memory p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, uint p1, string memory p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,address)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, uint p1, bool p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, uint p1, bool p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,string)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, uint p1, bool p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, uint p1, bool p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,address)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, uint p1, address p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, uint p1, address p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,string)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, uint p1, address p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, uint p1, address p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,address)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, string memory p1, uint p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, string memory p1, uint p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,string)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, string memory p1, uint p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, string memory p1, uint p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,address)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, string memory p1, string memory p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, string memory p1, string memory p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, string memory p1, bool p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, string memory p1, bool p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, string memory p1, bool p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, string memory p1, address p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, string memory p1, address p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, string memory p1, address p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, string memory p1, address p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, bool p1, uint p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, bool p1, uint p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,string)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, bool p1, uint p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, bool p1, uint p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,address)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, bool p1, string memory p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, bool p1, string memory p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, bool p1, string memory p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, bool p1, bool p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, bool p1, bool p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, bool p1, bool p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, bool p1, bool p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, bool p1, address p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, bool p1, address p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, bool p1, address p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, bool p1, address p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, address p1, uint p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, address p1, uint p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,string)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, address p1, uint p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, address p1, uint p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,address)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, address p1, string memory p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, address p1, string memory p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, address p1, string memory p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, address p1, string memory p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, address p1, bool p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, address p1, bool p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, address p1, bool p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, address p1, bool p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, address p1, address p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, address p1, address p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, address p1, address p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(bool p0, address p1, address p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, uint p1, uint p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, uint p1, uint p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,string)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, uint p1, uint p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, uint p1, uint p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,address)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, uint p1, string memory p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, uint p1, string memory p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,string)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, uint p1, string memory p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, uint p1, string memory p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,address)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, uint p1, bool p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, uint p1, bool p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,string)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, uint p1, bool p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, uint p1, bool p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,address)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, uint p1, address p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, uint p1, address p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,string)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, uint p1, address p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, uint p1, address p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,address)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, string memory p1, uint p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, string memory p1, uint p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,string)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, string memory p1, uint p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, string memory p1, uint p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,address)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, string memory p1, string memory p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, string memory p1, string memory p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, string memory p1, string memory p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, string memory p1, bool p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, string memory p1, bool p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, string memory p1, bool p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, string memory p1, bool p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, string memory p1, address p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, string memory p1, address p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, string memory p1, address p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, string memory p1, address p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, bool p1, uint p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, bool p1, uint p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,string)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, bool p1, uint p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, bool p1, uint p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,address)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, bool p1, string memory p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, bool p1, string memory p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, bool p1, string memory p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, bool p1, string memory p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, bool p1, bool p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, bool p1, bool p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, bool p1, bool p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, bool p1, bool p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, bool p1, address p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, bool p1, address p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, bool p1, address p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, bool p1, address p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, address p1, uint p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, address p1, uint p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,string)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, address p1, uint p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, address p1, uint p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,address)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, address p1, string memory p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, address p1, string memory p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, address p1, string memory p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, address p1, string memory p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, address p1, bool p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, address p1, bool p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, address p1, bool p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, address p1, bool p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, address p1, address p2, uint p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, address p1, address p2, string memory p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, address p1, address p2, bool p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n    }\n\n    function log(address p0, address p1, address p2, address p3) internal view {\n        _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n    }\n\n}"},"src/interfaces/IDiamondCut.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\n/******************************************************************************\\\n* Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\nimport {IDiamond} from \"./IDiamond.sol\";\n\ninterface IDiamondCut is IDiamond {\n    /// @notice Add/replace/remove any number of functions and optionally execute\n    ///         a function with delegatecall\n    /// @param _diamondCut Contains the facet addresses and function selectors\n    /// @param _init The address of the contract or facet to execute _calldata\n    /// @param _calldata A function call, including function selector and arguments\n    ///                  _calldata is executed with delegatecall on _init\n    function diamondCut(\n        FacetCut[] calldata _diamondCut,\n        address _init,\n        bytes calldata _calldata\n    ) external;\n}\n"},"src/libraries/LibAppStorage.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\nimport {EnumerableMap} from \"openzeppelin/utils/structs/EnumerableMap.sol\";\nimport {IERC20Extended} from \"../interfaces/IERC20Extended.sol\";\nimport {IERC721Extended} from \"../interfaces/IERC721Extended.sol\";\n\n// using EnumerableMap for EnumerableMap.UintToAddressMap;\n\n// Declare a set state variable\n// EnumerableMap.UintToAddressMap private myMap;\n\nstruct AppStorage {\n    bool diamondInitialized;\n    IERC20Extended token;\n    IERC721Extended nft;\n    address DIAMOND_ADDRESS; // facet where getters are stored, need to add a setter too in game manager facet\n    // dutch auction\n    uint256 duration;\n    uint256 minPrice;\n    uint256 startingPrice;\n    uint256 startAt;\n    uint256 discountRate;\n    mapping(uint256 => uint256[]) petDna;\n    // shop and items\n    mapping(uint256 => uint256) itemPrice; //shop item id to price name this diff than items later\n    mapping(uint256 => uint256) itemPoints;\n    mapping(uint256 => string) itemName;\n    mapping(uint256 => uint256) itemTimeExtension;\n    mapping(uint256 => uint256) itemDelta; //item delta for pricing and selling\n    mapping(uint256 => uint256) itemEquipExpires; //when long after consumed it expires\n    mapping(uint256 => bool) itemIsSellable;\n    mapping(uint256 => mapping(uint256 => uint256)) petItemExpires; // pet=>item=>expires time\n    mapping(uint256 => uint256) itemSupply; //supply of items\n    mapping(uint256 => EnumerableMap.UintToUintMap) itemsOwned; // items pet currently owns\n    uint256 PRECISION;\n    uint256 _tokenIds;\n    uint256 _itemIds;\n    uint256 la;\n    uint256 lb;\n    // pet properties\n    mapping(uint256 => string) petName;\n    mapping(uint256 => uint256) timeUntilStarving;\n    mapping(uint256 => uint256) petScore;\n    mapping(uint256 => uint256) timePetBorn;\n    mapping(uint256 => uint256) lastAttackUsed;\n    mapping(uint256 => uint256) lastAttacked;\n    mapping(uint256 => uint256) stars;\n    // vritual staking\n    mapping(uint256 => uint256) ethOwed;\n    mapping(uint256 => uint256) petRewardDebt;\n    uint256 ethAccPerShare;\n    uint256 totalScores;\n    // migration\n    mapping(uint256 => bool) petMigrated; //if pet migrated from v1 to this v2\n    uint256 hasTheDiamond; //add this to the contractor instead\n    mapping(uint256 => uint256) itemBought; //total bought to keep track of supply\n}\n\nlibrary LibAppStorage {\n    bytes32 internal constant DIAMOND_APP_STORAGE_POSITION =\n        keccak256(\"diamond.app.storage\");\n\n    function appStorage() internal pure returns (AppStorage storage ds) {\n        bytes32 position = DIAMOND_APP_STORAGE_POSITION;\n        assembly {\n            ds.slot := position\n        }\n    }\n\n    // function diamondStorage() internal pure returns (AppStorage storage ds) {\n    //     assembly {\n    //         ds.slot := 0\n    //     }\n    // }\n\n    // function abs(int256 x) internal pure returns (uint256) {\n    //     return uint256(x >= 0 ? x : -x);\n    // }\n}\n\ncontract Modifiers {\n    modifier onlyOwner() {\n        LibDiamond.enforceIsContractOwner();\n        _;\n    }\n\n    modifier isApproved(uint256 id) {\n        AppStorage storage s = LibAppStorage.appStorage();\n\n        require(\n            s.nft.ownerOf(id) == msg.sender ||\n                s.nft.getApproved(id) == msg.sender,\n            \"Not approved\"\n        );\n        _;\n    }\n}\n"},"lib/solmate/src/tokens/ERC20.sol":{"content":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n    /*//////////////////////////////////////////////////////////////\n                                 EVENTS\n    //////////////////////////////////////////////////////////////*/\n\n    event Transfer(address indexed from, address indexed to, uint256 amount);\n\n    event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n    /*//////////////////////////////////////////////////////////////\n                            METADATA STORAGE\n    //////////////////////////////////////////////////////////////*/\n\n    string public name;\n\n    string public symbol;\n\n    uint8 public immutable decimals;\n\n    /*//////////////////////////////////////////////////////////////\n                              ERC20 STORAGE\n    //////////////////////////////////////////////////////////////*/\n\n    uint256 public totalSupply;\n\n    mapping(address => uint256) public balanceOf;\n\n    mapping(address => mapping(address => uint256)) public allowance;\n\n    /*//////////////////////////////////////////////////////////////\n                            EIP-2612 STORAGE\n    //////////////////////////////////////////////////////////////*/\n\n    uint256 internal immutable INITIAL_CHAIN_ID;\n\n    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n    mapping(address => uint256) public nonces;\n\n    /*//////////////////////////////////////////////////////////////\n                               CONSTRUCTOR\n    //////////////////////////////////////////////////////////////*/\n\n    constructor(\n        string memory _name,\n        string memory _symbol,\n        uint8 _decimals\n    ) {\n        name = _name;\n        symbol = _symbol;\n        decimals = _decimals;\n\n        INITIAL_CHAIN_ID = block.chainid;\n        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                               ERC20 LOGIC\n    //////////////////////////////////////////////////////////////*/\n\n    function approve(address spender, uint256 amount) public virtual returns (bool) {\n        allowance[msg.sender][spender] = amount;\n\n        emit Approval(msg.sender, spender, amount);\n\n        return true;\n    }\n\n    function transfer(address to, uint256 amount) public virtual returns (bool) {\n        balanceOf[msg.sender] -= amount;\n\n        // Cannot overflow because the sum of all user\n        // balances can't exceed the max uint256 value.\n        unchecked {\n            balanceOf[to] += amount;\n        }\n\n        emit Transfer(msg.sender, to, amount);\n\n        return true;\n    }\n\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) public virtual returns (bool) {\n        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n        balanceOf[from] -= amount;\n\n        // Cannot overflow because the sum of all user\n        // balances can't exceed the max uint256 value.\n        unchecked {\n            balanceOf[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        return true;\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                             EIP-2612 LOGIC\n    //////////////////////////////////////////////////////////////*/\n\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public virtual {\n        require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n        // Unchecked because the only math done is incrementing\n        // the owner's nonce which cannot realistically overflow.\n        unchecked {\n            address recoveredAddress = ecrecover(\n                keccak256(\n                    abi.encodePacked(\n                        \"\\x19\\x01\",\n                        DOMAIN_SEPARATOR(),\n                        keccak256(\n                            abi.encode(\n                                keccak256(\n                                    \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n                                ),\n                                owner,\n                                spender,\n                                value,\n                                nonces[owner]++,\n                                deadline\n                            )\n                        )\n                    )\n                ),\n                v,\n                r,\n                s\n            );\n\n            require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n            allowance[recoveredAddress][spender] = value;\n        }\n\n        emit Approval(owner, spender, value);\n    }\n\n    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n    }\n\n    function computeDomainSeparator() internal view virtual returns (bytes32) {\n        return\n            keccak256(\n                abi.encode(\n                    keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n                    keccak256(bytes(name)),\n                    keccak256(\"1\"),\n                    block.chainid,\n                    address(this)\n                )\n            );\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        INTERNAL MINT/BURN LOGIC\n    //////////////////////////////////////////////////////////////*/\n\n    function _mint(address to, uint256 amount) internal virtual {\n        totalSupply += amount;\n\n        // Cannot overflow because the sum of all user\n        // balances can't exceed the max uint256 value.\n        unchecked {\n            balanceOf[to] += amount;\n        }\n\n        emit Transfer(address(0), to, amount);\n    }\n\n    function _burn(address from, uint256 amount) internal virtual {\n        balanceOf[from] -= amount;\n\n        // Cannot underflow because a user's balance\n        // will never be larger than the total supply.\n        unchecked {\n            totalSupply -= amount;\n        }\n\n        emit Transfer(from, address(0), amount);\n    }\n}\n"},"src/libraries/LibDiceStorage.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nstruct DiceStorage {\n    address gameSigner;\n    uint256 gameAmt;\n    uint256 playerIndex;\n    mapping(uint256 => bytes32) gameIdToCommit;\n    mapping(uint256 => uint256[6]) gameIdToPlayers;\n    mapping(uint256 => uint256) gameIdToWinningNumber;\n    mapping(uint256 => uint256) gameIdToWinner;\n    uint256 currentGame;\n}\n\nlibrary LibDiceStorage {\n    bytes32 constant DICE_STORAGE_POSITION =\n        keccak256(\"diamond.standard.dice.storage\");\n\n    function diceStorage() internal pure returns (DiceStorage storage ds) {\n        bytes32 position = DICE_STORAGE_POSITION;\n        assembly {\n            ds.slot := position\n        }\n    }\n}\n"},"src/interfaces/IERC20Extended.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\ninterface IERC20Extended {\n    function balanceOf(\n        address tokenOwner\n    ) external view returns (uint256 balance);\n\n    function totalSupply() external view returns (uint256 supply);\n\n    function transfer(\n        address to,\n        uint256 tokens\n    ) external returns (bool success);\n\n    function transferFrom(\n        address from,\n        address to,\n        uint256 tokens\n    ) external returns (bool success);\n\n    function burn(uint256 amount) external;\n\n    function burnFrom(address account, uint256 amount) external;\n}\n"},"src/interfaces/IERC721Extended.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\ninterface IERC721Extended {\n    event Transfer(\n        address indexed from,\n        address indexed to,\n        uint256 indexed tokenId\n    );\n\n    event Approval(\n        address indexed owner,\n        address indexed approved,\n        uint256 indexed tokenId\n    );\n\n    event ApprovalForAll(\n        address indexed owner,\n        address indexed operator,\n        bool approved\n    );\n\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId,\n        bytes calldata data\n    ) external;\n\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId\n    ) external;\n\n    function transferFrom(address from, address to, uint256 tokenId) external;\n\n    function approve(address to, uint256 tokenId) external;\n\n    function setApprovalForAll(address operator, bool approved) external;\n\n    function getApproved(\n        uint256 tokenId\n    ) external view returns (address operator);\n\n    function isApprovedForAll(\n        address owner,\n        address operator\n    ) external view returns (bool);\n\n    function burn(uint256 id) external;\n\n    function burnInGame(uint256 id) external;\n\n    function mint(address to) external;\n}\n"},"src/libraries/LibReferralStorage.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nstruct ReferralStorage {\n    address lastJoined;\n    mapping(uint256 => address) petToRef;\n}\n\nlibrary LibReferralStorage {\n    bytes32 internal constant DIAMOND_REFERRAL_STORAGE_POSITION =\n        keccak256(\"diamond.referral.v1.storage\");\n\n    function referralStorage()\n        internal\n        pure\n        returns (ReferralStorage storage ds)\n    {\n        bytes32 position = DIAMOND_REFERRAL_STORAGE_POSITION;\n        assembly {\n            ds.slot := position\n        }\n    }\n}\n"},"lib/solmate/src/utils/SafeTransferLib.sol":{"content":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport {ERC20} from \"../tokens/ERC20.sol\";\n\n/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)\n/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.\n/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.\nlibrary SafeTransferLib {\n    /*//////////////////////////////////////////////////////////////\n                             ETH OPERATIONS\n    //////////////////////////////////////////////////////////////*/\n\n    function safeTransferETH(address to, uint256 amount) internal {\n        bool success;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Transfer the ETH and store if it succeeded or not.\n            success := call(gas(), to, amount, 0, 0, 0, 0)\n        }\n\n        require(success, \"ETH_TRANSFER_FAILED\");\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                            ERC20 OPERATIONS\n    //////////////////////////////////////////////////////////////*/\n\n    function safeTransferFrom(\n        ERC20 token,\n        address from,\n        address to,\n        uint256 amount\n    ) internal {\n        bool success;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Get a pointer to some free memory.\n            let freeMemoryPointer := mload(0x40)\n\n            // Write the abi-encoded calldata into memory, beginning with the function selector.\n            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)\n            mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \"from\" argument.\n            mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \"to\" argument.\n            mstore(add(freeMemoryPointer, 68), amount) // Append the \"amount\" argument. Masking not required as it's a full 32 byte type.\n\n            success := and(\n                // Set success to whether the call reverted, if not we check it either\n                // returned exactly 1 (can't just be non-zero data), or had no return data.\n                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.\n                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n                // Counterintuitively, this call must be positioned second to the or() call in the\n                // surrounding and() call or else returndatasize() will be zero during the computation.\n                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)\n            )\n        }\n\n        require(success, \"TRANSFER_FROM_FAILED\");\n    }\n\n    function safeTransfer(\n        ERC20 token,\n        address to,\n        uint256 amount\n    ) internal {\n        bool success;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Get a pointer to some free memory.\n            let freeMemoryPointer := mload(0x40)\n\n            // Write the abi-encoded calldata into memory, beginning with the function selector.\n            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)\n            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \"to\" argument.\n            mstore(add(freeMemoryPointer, 36), amount) // Append the \"amount\" argument. Masking not required as it's a full 32 byte type.\n\n            success := and(\n                // Set success to whether the call reverted, if not we check it either\n                // returned exactly 1 (can't just be non-zero data), or had no return data.\n                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.\n                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n                // Counterintuitively, this call must be positioned second to the or() call in the\n                // surrounding and() call or else returndatasize() will be zero during the computation.\n                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)\n            )\n        }\n\n        require(success, \"TRANSFER_FAILED\");\n    }\n\n    function safeApprove(\n        ERC20 token,\n        address to,\n        uint256 amount\n    ) internal {\n        bool success;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Get a pointer to some free memory.\n            let freeMemoryPointer := mload(0x40)\n\n            // Write the abi-encoded calldata into memory, beginning with the function selector.\n            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)\n            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \"to\" argument.\n            mstore(add(freeMemoryPointer, 36), amount) // Append the \"amount\" argument. Masking not required as it's a full 32 byte type.\n\n            success := and(\n                // Set success to whether the call reverted, if not we check it either\n                // returned exactly 1 (can't just be non-zero data), or had no return data.\n                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.\n                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n                // Counterintuitively, this call must be positioned second to the or() call in the\n                // surrounding and() call or else returndatasize() will be zero during the computation.\n                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)\n            )\n        }\n\n        require(success, \"APPROVE_FAILED\");\n    }\n}\n"},"lib/solmate/src/utils/FixedPointMathLib.sol":{"content":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Arithmetic library with operations for fixed-point numbers.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)\n/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)\nlibrary FixedPointMathLib {\n    /*//////////////////////////////////////////////////////////////\n                    SIMPLIFIED FIXED POINT OPERATIONS\n    //////////////////////////////////////////////////////////////*/\n\n    uint256 internal constant MAX_UINT256 = 2**256 - 1;\n\n    uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.\n\n    function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.\n    }\n\n    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.\n    }\n\n    function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.\n    }\n\n    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                    LOW LEVEL FIXED POINT OPERATIONS\n    //////////////////////////////////////////////////////////////*/\n\n    function mulDivDown(\n        uint256 x,\n        uint256 y,\n        uint256 denominator\n    ) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))\n            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {\n                revert(0, 0)\n            }\n\n            // Divide x * y by the denominator.\n            z := div(mul(x, y), denominator)\n        }\n    }\n\n    function mulDivUp(\n        uint256 x,\n        uint256 y,\n        uint256 denominator\n    ) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))\n            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {\n                revert(0, 0)\n            }\n\n            // If x * y modulo the denominator is strictly greater than 0,\n            // 1 is added to round up the division of x * y by the denominator.\n            z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator))\n        }\n    }\n\n    function rpow(\n        uint256 x,\n        uint256 n,\n        uint256 scalar\n    ) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            switch x\n            case 0 {\n                switch n\n                case 0 {\n                    // 0 ** 0 = 1\n                    z := scalar\n                }\n                default {\n                    // 0 ** n = 0\n                    z := 0\n                }\n            }\n            default {\n                switch mod(n, 2)\n                case 0 {\n                    // If n is even, store scalar in z for now.\n                    z := scalar\n                }\n                default {\n                    // If n is odd, store x in z for now.\n                    z := x\n                }\n\n                // Shifting right by 1 is like dividing by 2.\n                let half := shr(1, scalar)\n\n                for {\n                    // Shift n right by 1 before looping to halve it.\n                    n := shr(1, n)\n                } n {\n                    // Shift n right by 1 each iteration to halve it.\n                    n := shr(1, n)\n                } {\n                    // Revert immediately if x ** 2 would overflow.\n                    // Equivalent to iszero(eq(div(xx, x), x)) here.\n                    if shr(128, x) {\n                        revert(0, 0)\n                    }\n\n                    // Store x squared.\n                    let xx := mul(x, x)\n\n                    // Round to the nearest number.\n                    let xxRound := add(xx, half)\n\n                    // Revert if xx + half overflowed.\n                    if lt(xxRound, xx) {\n                        revert(0, 0)\n                    }\n\n                    // Set x to scaled xxRound.\n                    x := div(xxRound, scalar)\n\n                    // If n is even:\n                    if mod(n, 2) {\n                        // Compute z * x.\n                        let zx := mul(z, x)\n\n                        // If z * x overflowed:\n                        if iszero(eq(div(zx, x), z)) {\n                            // Revert if x is non-zero.\n                            if iszero(iszero(x)) {\n                                revert(0, 0)\n                            }\n                        }\n\n                        // Round to the nearest number.\n                        let zxRound := add(zx, half)\n\n                        // Revert if zx + half overflowed.\n                        if lt(zxRound, zx) {\n                            revert(0, 0)\n                        }\n\n                        // Return properly scaled zxRound.\n                        z := div(zxRound, scalar)\n                    }\n                }\n            }\n        }\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        GENERAL NUMBER UTILITIES\n    //////////////////////////////////////////////////////////////*/\n\n    function sqrt(uint256 x) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let y := x // We start y at x, which will help us make our initial estimate.\n\n            z := 181 // The \"correct\" value is 1, but this saves a multiplication later.\n\n            // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\n            // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\n\n            // We check y >= 2^(k + 8) but shift right by k bits\n            // each branch to ensure that if x >= 256, then y >= 256.\n            if iszero(lt(y, 0x10000000000000000000000000000000000)) {\n                y := shr(128, y)\n                z := shl(64, z)\n            }\n            if iszero(lt(y, 0x1000000000000000000)) {\n                y := shr(64, y)\n                z := shl(32, z)\n            }\n            if iszero(lt(y, 0x10000000000)) {\n                y := shr(32, y)\n                z := shl(16, z)\n            }\n            if iszero(lt(y, 0x1000000)) {\n                y := shr(16, y)\n                z := shl(8, z)\n            }\n\n            // Goal was to get z*z*y within a small factor of x. More iterations could\n            // get y in a tighter range. Currently, we will have y in [256, 256*2^16).\n            // We ensured y >= 256 so that the relative difference between y and y+1 is small.\n            // That's not possible if x < 256 but we can just verify those cases exhaustively.\n\n            // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.\n            // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.\n            // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.\n\n            // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range\n            // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.\n\n            // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate\n            // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.\n\n            // There is no overflow risk here since y < 2^136 after the first branch above.\n            z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.\n\n            // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n\n            // If x+1 is a perfect square, the Babylonian method cycles between\n            // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.\n            // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\n            // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.\n            // If you don't care whether the floor or ceil square root is returned, you can remove this statement.\n            z := sub(z, lt(div(x, z), z))\n        }\n    }\n\n    function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Mod x by y. Note this will return\n            // 0 instead of reverting if y is zero.\n            z := mod(x, y)\n        }\n    }\n\n    function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Divide x by y. Note this will return\n            // 0 instead of reverting if y is zero.\n            r := div(x, y)\n        }\n    }\n\n    function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Add 1 to x * y if x % y > 0. Note this will\n            // return 0 instead of reverting if y is zero.\n            z := add(gt(mod(x, y), 0), div(x, y))\n        }\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/Strings.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n    uint8 private constant _ADDRESS_LENGTH = 20;\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            uint256 length = Math.log10(value) + 1;\n            string memory buffer = new string(length);\n            uint256 ptr;\n            /// @solidity memory-safe-assembly\n            assembly {\n                ptr := add(buffer, add(32, length))\n            }\n            while (true) {\n                ptr--;\n                /// @solidity memory-safe-assembly\n                assembly {\n                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n                }\n                value /= 10;\n                if (value == 0) break;\n            }\n            return buffer;\n        }\n    }\n\n    /**\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\n     */\n    function toString(int256 value) internal pure returns (string memory) {\n        return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            return toHexString(value, Math.log256(value) + 1);\n        }\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n    }\n\n    /**\n     * @dev Returns true if the two strings are equal.\n     */\n    function equal(string memory a, string memory b) internal pure returns (bool) {\n        return keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n     * with further edits by Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod0 := mul(x, y)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            require(denominator > prod1, \"Math: mulDiv overflow\");\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n            // See https://cs.stackexchange.com/q/138556/92363.\n\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 twos = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/math/SafeMath.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            uint256 c = a + b;\n            if (c < a) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b > a) return (false, 0);\n            return (true, a - b);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n            // benefit is lost if 'b' is also tested.\n            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n            if (a == 0) return (true, 0);\n            uint256 c = a * b;\n            if (c / a != b) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a / b);\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a % b);\n        }\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a + b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a - b;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     *\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a * b;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator.\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a / b;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a % b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {trySub}.\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        unchecked {\n            require(b <= a, errorMessage);\n            return a - b;\n        }\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        unchecked {\n            require(b > 0, errorMessage);\n            return a / b;\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting with custom message when dividing by zero.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryMod}.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        unchecked {\n            require(b > 0, errorMessage);\n            return a % b;\n        }\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two signed numbers.\n     */\n    function min(int256 a, int256 b) internal pure returns (int256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two signed numbers without overflow.\n     * The result is rounded towards zero.\n     */\n    function average(int256 a, int256 b) internal pure returns (int256) {\n        // Formula from the book \"Hacker's Delight\"\n        int256 x = (a & b) + ((a ^ b) >> 1);\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\n    }\n\n    /**\n     * @dev Returns the absolute unsigned value of a signed value.\n     */\n    function abs(int256 n) internal pure returns (uint256) {\n        unchecked {\n            // must be unchecked in order to support `n = type(int256).min`\n            return uint256(n >= 0 ? n : -n);\n        }\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS,\n        InvalidSignatureV // Deprecated in v4.8\n    }\n\n    function _throwError(RecoverError error) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert(\"ECDSA: invalid signature\");\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert(\"ECDSA: invalid signature length\");\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert(\"ECDSA: invalid signature 's' value\");\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature` or error string. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     *\n     * Documentation for signature generation:\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n        if (signature.length == 65) {\n            bytes32 r;\n            bytes32 s;\n            uint8 v;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            /// @solidity memory-safe-assembly\n            assembly {\n                r := mload(add(signature, 0x20))\n                s := mload(add(signature, 0x40))\n                v := byte(0, mload(add(signature, 0x60)))\n            }\n            return tryRecover(hash, v, r, s);\n        } else {\n            return (address(0), RecoverError.InvalidSignatureLength);\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature`. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, signature);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n     *\n     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n        uint8 v = uint8((uint256(vs) >> 255) + 27);\n        return tryRecover(hash, v, r, s);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n     *\n     * _Available since v4.2._\n     */\n    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n            return (address(0), RecoverError.InvalidSignatureS);\n        }\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        if (signer == address(0)) {\n            return (address(0), RecoverError.InvalidSignature);\n        }\n\n        return (signer, RecoverError.NoError);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n            mstore(0x1c, hash)\n            message := keccak256(0x00, 0x3c)\n        }\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from `s`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Typed Data, created from a\n     * `domainSeparator` and a `structHash`. This produces hash corresponding\n     * to the one signed with the\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n     * JSON-RPC method as part of EIP-712.\n     *\n     * See {recover}.\n     */\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, \"\\x19\\x01\")\n            mstore(add(ptr, 0x02), domainSeparator)\n            mstore(add(ptr, 0x22), structHash)\n            data := keccak256(ptr, 0x42)\n        }\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Data with intended validator, created from a\n     * `validator` and `data` according to the version 0 of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableMap.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableMap.js.\n\npragma solidity ^0.8.0;\n\nimport \"./EnumerableSet.sol\";\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n *     // Declare a set state variable\n *     EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * The following map types are supported:\n *\n * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0\n * - `address -> uint256` (`AddressToUintMap`) since v4.6.0\n * - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0\n * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0\n * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableMap.\n * ====\n */\nlibrary EnumerableMap {\n    using EnumerableSet for EnumerableSet.Bytes32Set;\n\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Map type with\n    // bytes32 keys and values.\n    // The Map implementation uses private functions, and user-facing\n    // implementations (such as Uint256ToAddressMap) are just wrappers around\n    // the underlying Map.\n    // This means that we can only create new EnumerableMaps for types that fit\n    // in bytes32.\n\n    struct Bytes32ToBytes32Map {\n        // Storage of keys\n        EnumerableSet.Bytes32Set _keys;\n        mapping(bytes32 => bytes32) _values;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value) internal returns (bool) {\n        map._values[key] = value;\n        return map._keys.add(key);\n    }\n\n    /**\n     * @dev Removes a key-value pair from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) {\n        delete map._values[key];\n        return map._keys.remove(key);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) {\n        return map._keys.contains(key);\n    }\n\n    /**\n     * @dev Returns the number of key-value pairs in the map. O(1).\n     */\n    function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) {\n        return map._keys.length();\n    }\n\n    /**\n     * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n     *\n     * Note that there are no guarantees on the ordering of entries inside the\n     * array, and it may change when more entries are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) {\n        bytes32 key = map._keys.at(index);\n        return (key, map._values[key]);\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) {\n        bytes32 value = map._values[key];\n        if (value == bytes32(0)) {\n            return (contains(map, key), bytes32(0));\n        } else {\n            return (true, value);\n        }\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) {\n        bytes32 value = map._values[key];\n        require(value != 0 || contains(map, key), \"EnumerableMap: nonexistent key\");\n        return value;\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(\n        Bytes32ToBytes32Map storage map,\n        bytes32 key,\n        string memory errorMessage\n    ) internal view returns (bytes32) {\n        bytes32 value = map._values[key];\n        require(value != 0 || contains(map, key), errorMessage);\n        return value;\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) {\n        return map._keys.values();\n    }\n\n    // UintToUintMap\n\n    struct UintToUintMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(UintToUintMap storage map, uint256 key, uint256 value) internal returns (bool) {\n        return set(map._inner, bytes32(key), bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(UintToUintMap storage map, uint256 key) internal returns (bool) {\n        return remove(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) {\n        return contains(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(UintToUintMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) {\n        (bytes32 key, bytes32 value) = at(map._inner, index);\n        return (uint256(key), uint256(value));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) {\n        (bool success, bytes32 value) = tryGet(map._inner, bytes32(key));\n        return (success, uint256(value));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) {\n        return uint256(get(map._inner, bytes32(key)));\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(UintToUintMap storage map, uint256 key, string memory errorMessage) internal view returns (uint256) {\n        return uint256(get(map._inner, bytes32(key), errorMessage));\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(UintToUintMap storage map) internal view returns (uint256[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        uint256[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintToAddressMap\n\n    struct UintToAddressMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n        return set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n        return remove(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n        return contains(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(UintToAddressMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n        (bytes32 key, bytes32 value) = at(map._inner, index);\n        return (uint256(key), address(uint160(uint256(value))));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n        (bool success, bytes32 value) = tryGet(map._inner, bytes32(key));\n        return (success, address(uint160(uint256(value))));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n        return address(uint160(uint256(get(map._inner, bytes32(key)))));\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(\n        UintToAddressMap storage map,\n        uint256 key,\n        string memory errorMessage\n    ) internal view returns (address) {\n        return address(uint160(uint256(get(map._inner, bytes32(key), errorMessage))));\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(UintToAddressMap storage map) internal view returns (uint256[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        uint256[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressToUintMap\n\n    struct AddressToUintMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(AddressToUintMap storage map, address key, uint256 value) internal returns (bool) {\n        return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(AddressToUintMap storage map, address key) internal returns (bool) {\n        return remove(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(AddressToUintMap storage map, address key) internal view returns (bool) {\n        return contains(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(AddressToUintMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) {\n        (bytes32 key, bytes32 value) = at(map._inner, index);\n        return (address(uint160(uint256(key))), uint256(value));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) {\n        (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key))));\n        return (success, uint256(value));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(AddressToUintMap storage map, address key) internal view returns (uint256) {\n        return uint256(get(map._inner, bytes32(uint256(uint160(key)))));\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(\n        AddressToUintMap storage map,\n        address key,\n        string memory errorMessage\n    ) internal view returns (uint256) {\n        return uint256(get(map._inner, bytes32(uint256(uint160(key))), errorMessage));\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(AddressToUintMap storage map) internal view returns (address[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        address[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // Bytes32ToUintMap\n\n    struct Bytes32ToUintMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(Bytes32ToUintMap storage map, bytes32 key, uint256 value) internal returns (bool) {\n        return set(map._inner, key, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) {\n        return remove(map._inner, key);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) {\n        return contains(map._inner, key);\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(Bytes32ToUintMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) {\n        (bytes32 key, bytes32 value) = at(map._inner, index);\n        return (key, uint256(value));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) {\n        (bool success, bytes32 value) = tryGet(map._inner, key);\n        return (success, uint256(value));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) {\n        return uint256(get(map._inner, key));\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(\n        Bytes32ToUintMap storage map,\n        bytes32 key,\n        string memory errorMessage\n    ) internal view returns (uint256) {\n        return uint256(get(map._inner, key, errorMessage));\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(Bytes32ToUintMap storage map) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        bytes32[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using EnumerableSet for EnumerableSet.AddressSet;\n *\n *     // Declare a set state variable\n *     EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Set type with\n    // bytes32 values.\n    // The Set implementation uses private functions, and user-facing\n    // implementations (such as AddressSet) are just wrappers around the\n    // underlying Set.\n    // This means that we can only create new EnumerableSets for types that fit\n    // in bytes32.\n\n    struct Set {\n        // Storage of set values\n        bytes32[] _values;\n        // Position of the value in the `values` array, plus 1 because index 0\n        // means a value is not in the set.\n        mapping(bytes32 => uint256) _indexes;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function _add(Set storage set, bytes32 value) private returns (bool) {\n        if (!_contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._indexes[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\n        // We read and store the value's index to prevent multiple reads from the same storage slot\n        uint256 valueIndex = set._indexes[value];\n\n        if (valueIndex != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 toDeleteIndex = valueIndex - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (lastIndex != toDeleteIndex) {\n                bytes32 lastValue = set._values[lastIndex];\n\n                // Move the last value to the index where the value to delete is\n                set._values[toDeleteIndex] = lastValue;\n                // Update the index for the moved value\n                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the index for the deleted slot\n            delete set._indexes[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\n        return set._indexes[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function _length(Set storage set) private view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function _values(Set storage set) private view returns (bytes32[] memory) {\n        return set._values;\n    }\n\n    // Bytes32Set\n\n    struct Bytes32Set {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _add(set._inner, value);\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _remove(set._inner, value);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n        return _contains(set._inner, value);\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Bytes32Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n        return _at(set._inner, index);\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        bytes32[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressSet\n\n    struct AddressSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(AddressSet storage set, address value) internal returns (bool) {\n        return _add(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(AddressSet storage set, address value) internal returns (bool) {\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(AddressSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\n        return address(uint160(uint256(_at(set._inner, index))));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(AddressSet storage set) internal view returns (address[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        address[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintSet\n\n    struct UintSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(UintSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n        return uint256(_at(set._inner, index));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        uint256[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n}\n"}},"matchId":"2958860","creationMatch":"match","runtimeMatch":"match","verifiedAt":"2024-08-08T17:16:52Z","match":"match","chainId":"8453","address":"0x47f634e78B1Af81C0494763F18620E5cA3D7Ad0A"}