creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@solidstate/contracts/access/access_control/AccessControlInternal.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { EnumerableSet } from '../../data/EnumerableSet.sol';\nimport { AddressUtils } from '../../utils/AddressUtils.sol';\nimport { UintUtils } from '../../utils/UintUtils.sol';\nimport { IAccessControlInternal } from './IAccessControlInternal.sol';\nimport { AccessControlStorage } from './AccessControlStorage.sol';\n\n/**\n * @title Role-based access control system\n * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license)\n */\nabstract contract AccessControlInternal is IAccessControlInternal {\n    using AddressUtils for address;\n    using EnumerableSet for EnumerableSet.AddressSet;\n    using UintUtils for uint256;\n\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    /*\n     * @notice query whether role is assigned to account\n     * @param role role to query\n     * @param account account to query\n     * @return whether role is assigned to account\n     */\n    function _hasRole(\n        bytes32 role,\n        address account\n    ) internal view virtual returns (bool) {\n        return\n            AccessControlStorage.layout().roles[role].members.contains(account);\n    }\n\n    /**\n     * @notice revert if sender does not have given role\n     * @param role role to query\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, msg.sender);\n    }\n\n    /**\n     * @notice revert if given account does not have given role\n     * @param role role to query\n     * @param account to query\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!_hasRole(role, account)) {\n            revert(\n                string(\n                    abi.encodePacked(\n                        'AccessControl: account ',\n                        account.toString(),\n                        ' is missing role ',\n                        uint256(role).toHexString(32)\n                    )\n                )\n            );\n        }\n    }\n\n    /*\n     * @notice query admin role for given role\n     * @param role role to query\n     * @return admin role\n     */\n    function _getRoleAdmin(\n        bytes32 role\n    ) internal view virtual returns (bytes32) {\n        return AccessControlStorage.layout().roles[role].adminRole;\n    }\n\n    /**\n     * @notice set role as admin role\n     * @param role role to set\n     * @param adminRole admin role to set\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        bytes32 previousAdminRole = _getRoleAdmin(role);\n        AccessControlStorage.layout().roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /*\n     * @notice assign role to given account\n     * @param role role to assign\n     * @param account recipient of role assignment\n     */\n    function _grantRole(bytes32 role, address account) internal virtual {\n        AccessControlStorage.layout().roles[role].members.add(account);\n        emit RoleGranted(role, account, msg.sender);\n    }\n\n    /*\n     * @notice unassign role from given account\n     * @param role role to unassign\n     * @parm account\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual {\n        AccessControlStorage.layout().roles[role].members.remove(account);\n        emit RoleRevoked(role, account, msg.sender);\n    }\n\n    /**\n     * @notice relinquish role\n     * @param role role to relinquish\n     */\n    function _renounceRole(bytes32 role) internal virtual {\n        _revokeRole(role, msg.sender);\n    }\n\n    /**\n     * @notice query role for member at given index\n     * @param role role to query\n     * @param index index to query\n     */\n    function _getRoleMember(\n        bytes32 role,\n        uint256 index\n    ) internal view virtual returns (address) {\n        return AccessControlStorage.layout().roles[role].members.at(index);\n    }\n\n    /**\n     * @notice query role for member count\n     * @param role role to query\n     */\n    function _getRoleMemberCount(\n        bytes32 role\n    ) internal view virtual returns (uint256) {\n        return AccessControlStorage.layout().roles[role].members.length();\n    }\n}\n"
      },
      "@solidstate/contracts/access/access_control/AccessControlStorage.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { EnumerableSet } from '../../data/EnumerableSet.sol';\n\nlibrary AccessControlStorage {\n    struct RoleData {\n        EnumerableSet.AddressSet members;\n        bytes32 adminRole;\n    }\n\n    struct Layout {\n        mapping(bytes32 => RoleData) roles;\n    }\n\n    bytes32 internal constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    bytes32 internal constant STORAGE_SLOT =\n        keccak256('solidstate.contracts.storage.AccessControl');\n\n    function layout() internal pure returns (Layout storage l) {\n        bytes32 slot = STORAGE_SLOT;\n        assembly {\n            l.slot := slot\n        }\n    }\n}\n"
      },
      "@solidstate/contracts/access/access_control/IAccessControlInternal.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title Partial AccessControl interface needed by internal functions\n */\ninterface IAccessControlInternal {\n    event RoleAdminChanged(\n        bytes32 indexed role,\n        bytes32 indexed previousAdminRole,\n        bytes32 indexed newAdminRole\n    );\n\n    event RoleGranted(\n        bytes32 indexed role,\n        address indexed account,\n        address indexed sender\n    );\n\n    event RoleRevoked(\n        bytes32 indexed role,\n        address indexed account,\n        address indexed sender\n    );\n}\n"
      },
      "@solidstate/contracts/data/EnumerableMap.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\n/**\n * @title Map implementation with enumeration functions\n * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license)\n */\nlibrary EnumerableMap {\n    error EnumerableMap__IndexOutOfBounds();\n    error EnumerableMap__NonExistentKey();\n\n    struct MapEntry {\n        bytes32 _key;\n        bytes32 _value;\n    }\n\n    struct Map {\n        MapEntry[] _entries;\n        // 1-indexed to allow 0 to signify nonexistence\n        mapping(bytes32 => uint256) _indexes;\n    }\n\n    struct AddressToAddressMap {\n        Map _inner;\n    }\n\n    struct UintToAddressMap {\n        Map _inner;\n    }\n\n    function at(\n        AddressToAddressMap storage map,\n        uint256 index\n    ) internal view returns (address, address) {\n        (bytes32 key, bytes32 value) = _at(map._inner, index);\n\n        return (\n            address(uint160(uint256(key))),\n            address(uint160(uint256(value)))\n        );\n    }\n\n    function at(\n        UintToAddressMap storage map,\n        uint256 index\n    ) 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    function contains(\n        AddressToAddressMap storage map,\n        address key\n    ) internal view returns (bool) {\n        return _contains(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    function contains(\n        UintToAddressMap storage map,\n        uint256 key\n    ) internal view returns (bool) {\n        return _contains(map._inner, bytes32(key));\n    }\n\n    function length(\n        AddressToAddressMap storage map\n    ) internal view returns (uint256) {\n        return _length(map._inner);\n    }\n\n    function length(\n        UintToAddressMap storage map\n    ) internal view returns (uint256) {\n        return _length(map._inner);\n    }\n\n    function get(\n        AddressToAddressMap storage map,\n        address key\n    ) internal view returns (address) {\n        return\n            address(\n                uint160(\n                    uint256(_get(map._inner, bytes32(uint256(uint160(key)))))\n                )\n            );\n    }\n\n    function get(\n        UintToAddressMap storage map,\n        uint256 key\n    ) internal view returns (address) {\n        return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n    }\n\n    function set(\n        AddressToAddressMap storage map,\n        address key,\n        address value\n    ) internal returns (bool) {\n        return\n            _set(\n                map._inner,\n                bytes32(uint256(uint160(key))),\n                bytes32(uint256(uint160(value)))\n            );\n    }\n\n    function set(\n        UintToAddressMap storage map,\n        uint256 key,\n        address value\n    ) internal returns (bool) {\n        return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n    }\n\n    function remove(\n        AddressToAddressMap storage map,\n        address key\n    ) internal returns (bool) {\n        return _remove(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    function remove(\n        UintToAddressMap storage map,\n        uint256 key\n    ) internal returns (bool) {\n        return _remove(map._inner, bytes32(key));\n    }\n\n    function toArray(\n        AddressToAddressMap storage map\n    )\n        internal\n        view\n        returns (address[] memory keysOut, address[] memory valuesOut)\n    {\n        uint256 len = map._inner._entries.length;\n\n        keysOut = new address[](len);\n        valuesOut = new address[](len);\n\n        unchecked {\n            for (uint256 i; i < len; ++i) {\n                keysOut[i] = address(\n                    uint160(uint256(map._inner._entries[i]._key))\n                );\n                valuesOut[i] = address(\n                    uint160(uint256(map._inner._entries[i]._value))\n                );\n            }\n        }\n    }\n\n    function toArray(\n        UintToAddressMap storage map\n    )\n        internal\n        view\n        returns (uint256[] memory keysOut, address[] memory valuesOut)\n    {\n        uint256 len = map._inner._entries.length;\n\n        keysOut = new uint256[](len);\n        valuesOut = new address[](len);\n\n        unchecked {\n            for (uint256 i; i < len; ++i) {\n                keysOut[i] = uint256(map._inner._entries[i]._key);\n                valuesOut[i] = address(\n                    uint160(uint256(map._inner._entries[i]._value))\n                );\n            }\n        }\n    }\n\n    function keys(\n        AddressToAddressMap storage map\n    ) internal view returns (address[] memory keysOut) {\n        uint256 len = map._inner._entries.length;\n\n        keysOut = new address[](len);\n\n        unchecked {\n            for (uint256 i; i < len; ++i) {\n                keysOut[i] = address(\n                    uint160(uint256(map._inner._entries[i]._key))\n                );\n            }\n        }\n    }\n\n    function keys(\n        UintToAddressMap storage map\n    ) internal view returns (uint256[] memory keysOut) {\n        uint256 len = map._inner._entries.length;\n\n        keysOut = new uint256[](len);\n\n        unchecked {\n            for (uint256 i; i < len; ++i) {\n                keysOut[i] = uint256(map._inner._entries[i]._key);\n            }\n        }\n    }\n\n    function values(\n        AddressToAddressMap storage map\n    ) internal view returns (address[] memory valuesOut) {\n        uint256 len = map._inner._entries.length;\n\n        valuesOut = new address[](len);\n\n        unchecked {\n            for (uint256 i; i < len; ++i) {\n                valuesOut[i] = address(\n                    uint160(uint256(map._inner._entries[i]._value))\n                );\n            }\n        }\n    }\n\n    function values(\n        UintToAddressMap storage map\n    ) internal view returns (address[] memory valuesOut) {\n        uint256 len = map._inner._entries.length;\n\n        valuesOut = new address[](len);\n\n        unchecked {\n            for (uint256 i; i < len; ++i) {\n                valuesOut[i] = address(\n                    uint160(uint256(map._inner._entries[i]._value))\n                );\n            }\n        }\n    }\n\n    function _at(\n        Map storage map,\n        uint256 index\n    ) private view returns (bytes32, bytes32) {\n        if (index >= map._entries.length)\n            revert EnumerableMap__IndexOutOfBounds();\n\n        MapEntry storage entry = map._entries[index];\n        return (entry._key, entry._value);\n    }\n\n    function _contains(\n        Map storage map,\n        bytes32 key\n    ) private view returns (bool) {\n        return map._indexes[key] != 0;\n    }\n\n    function _length(Map storage map) private view returns (uint256) {\n        return map._entries.length;\n    }\n\n    function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n        uint256 keyIndex = map._indexes[key];\n        if (keyIndex == 0) revert EnumerableMap__NonExistentKey();\n        unchecked {\n            return map._entries[keyIndex - 1]._value;\n        }\n    }\n\n    function _set(\n        Map storage map,\n        bytes32 key,\n        bytes32 value\n    ) private returns (bool) {\n        uint256 keyIndex = map._indexes[key];\n\n        if (keyIndex == 0) {\n            map._entries.push(MapEntry({ _key: key, _value: value }));\n            map._indexes[key] = map._entries.length;\n            return true;\n        } else {\n            unchecked {\n                map._entries[keyIndex - 1]._value = value;\n            }\n            return false;\n        }\n    }\n\n    function _remove(Map storage map, bytes32 key) private returns (bool) {\n        uint256 keyIndex = map._indexes[key];\n\n        if (keyIndex != 0) {\n            unchecked {\n                MapEntry storage last = map._entries[map._entries.length - 1];\n\n                // move last entry to now-vacant index\n                map._entries[keyIndex - 1] = last;\n                map._indexes[last._key] = keyIndex;\n            }\n\n            // clear last index\n            map._entries.pop();\n            delete map._indexes[key];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n}\n"
      },
      "@solidstate/contracts/data/EnumerableSet.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\n/**\n * @title Set implementation with enumeration functions\n * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license)\n */\nlibrary EnumerableSet {\n    error EnumerableSet__IndexOutOfBounds();\n\n    struct Set {\n        bytes32[] _values;\n        // 1-indexed to allow 0 to signify nonexistence\n        mapping(bytes32 => uint256) _indexes;\n    }\n\n    struct Bytes32Set {\n        Set _inner;\n    }\n\n    struct AddressSet {\n        Set _inner;\n    }\n\n    struct UintSet {\n        Set _inner;\n    }\n\n    function at(\n        Bytes32Set storage set,\n        uint256 index\n    ) internal view returns (bytes32) {\n        return _at(set._inner, index);\n    }\n\n    function at(\n        AddressSet storage set,\n        uint256 index\n    ) internal view returns (address) {\n        return address(uint160(uint256(_at(set._inner, index))));\n    }\n\n    function at(\n        UintSet storage set,\n        uint256 index\n    ) internal view returns (uint256) {\n        return uint256(_at(set._inner, index));\n    }\n\n    function contains(\n        Bytes32Set storage set,\n        bytes32 value\n    ) internal view returns (bool) {\n        return _contains(set._inner, value);\n    }\n\n    function contains(\n        AddressSet storage set,\n        address value\n    ) internal view returns (bool) {\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    function contains(\n        UintSet storage set,\n        uint256 value\n    ) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    function indexOf(\n        Bytes32Set storage set,\n        bytes32 value\n    ) internal view returns (uint256) {\n        return _indexOf(set._inner, value);\n    }\n\n    function indexOf(\n        AddressSet storage set,\n        address value\n    ) internal view returns (uint256) {\n        return _indexOf(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    function indexOf(\n        UintSet storage set,\n        uint256 value\n    ) internal view returns (uint256) {\n        return _indexOf(set._inner, bytes32(value));\n    }\n\n    function length(Bytes32Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    function length(AddressSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    function length(UintSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    function add(\n        Bytes32Set storage set,\n        bytes32 value\n    ) internal returns (bool) {\n        return _add(set._inner, value);\n    }\n\n    function add(\n        AddressSet storage set,\n        address value\n    ) internal returns (bool) {\n        return _add(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    function remove(\n        Bytes32Set storage set,\n        bytes32 value\n    ) internal returns (bool) {\n        return _remove(set._inner, value);\n    }\n\n    function remove(\n        AddressSet storage set,\n        address value\n    ) internal returns (bool) {\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    function remove(\n        UintSet storage set,\n        uint256 value\n    ) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    function toArray(\n        Bytes32Set storage set\n    ) internal view returns (bytes32[] memory) {\n        return set._inner._values;\n    }\n\n    function toArray(\n        AddressSet storage set\n    ) internal view returns (address[] memory) {\n        bytes32[] storage values = set._inner._values;\n        address[] storage array;\n\n        assembly {\n            array.slot := values.slot\n        }\n\n        return array;\n    }\n\n    function toArray(\n        UintSet storage set\n    ) internal view returns (uint256[] memory) {\n        bytes32[] storage values = set._inner._values;\n        uint256[] storage array;\n\n        assembly {\n            array.slot := values.slot\n        }\n\n        return array;\n    }\n\n    function _at(\n        Set storage set,\n        uint256 index\n    ) private view returns (bytes32) {\n        if (index >= set._values.length)\n            revert EnumerableSet__IndexOutOfBounds();\n        return set._values[index];\n    }\n\n    function _contains(\n        Set storage set,\n        bytes32 value\n    ) private view returns (bool) {\n        return set._indexes[value] != 0;\n    }\n\n    function _indexOf(\n        Set storage set,\n        bytes32 value\n    ) private view returns (uint256) {\n        unchecked {\n            return set._indexes[value] - 1;\n        }\n    }\n\n    function _length(Set storage set) private view returns (uint256) {\n        return set._values.length;\n    }\n\n    function _add(\n        Set storage set,\n        bytes32 value\n    ) private returns (bool status) {\n        if (!_contains(set, value)) {\n            set._values.push(value);\n            set._indexes[value] = set._values.length;\n            status = true;\n        }\n    }\n\n    function _remove(\n        Set storage set,\n        bytes32 value\n    ) private returns (bool status) {\n        uint256 valueIndex = set._indexes[value];\n\n        if (valueIndex != 0) {\n            unchecked {\n                bytes32 last = set._values[set._values.length - 1];\n\n                // move last value to now-vacant index\n\n                set._values[valueIndex - 1] = last;\n                set._indexes[last] = valueIndex;\n            }\n            // clear last index\n\n            set._values.pop();\n            delete set._indexes[value];\n\n            status = true;\n        }\n    }\n}\n"
      },
      "@solidstate/contracts/interfaces/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { IERC165Internal } from './IERC165Internal.sol';\n\n/**\n * @title ERC165 interface registration interface\n * @dev see https://eips.ethereum.org/EIPS/eip-165\n */\ninterface IERC165 is IERC165Internal {\n    /**\n     * @notice query whether contract has registered support for given interface\n     * @param interfaceId interface id\n     * @return bool whether interface is supported\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "@solidstate/contracts/interfaces/IERC165Internal.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\n/**\n * @title ERC165 interface registration interface\n */\ninterface IERC165Internal {\n\n}\n"
      },
      "@solidstate/contracts/interfaces/IERC721.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { IERC165 } from './IERC165.sol';\nimport { IERC721Internal } from './IERC721Internal.sol';\n\n/**\n * @title ERC721 interface\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721 is IERC721Internal, IERC165 {\n    /**\n     * @notice query the balance of given address\n     * @return balance quantity of tokens held\n     */\n    function balanceOf(address account) external view returns (uint256 balance);\n\n    /**\n     * @notice query the owner of given token\n     * @param tokenId token to query\n     * @return owner token owner\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @notice transfer token between given addresses, checking for ERC721Receiver implementation if applicable\n     * @param from sender of token\n     * @param to receiver of token\n     * @param tokenId token id\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId\n    ) external payable;\n\n    /**\n     * @notice transfer token between given addresses, checking for ERC721Receiver implementation if applicable\n     * @param from sender of token\n     * @param to receiver of token\n     * @param tokenId token id\n     * @param data data payload\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId,\n        bytes calldata data\n    ) external payable;\n\n    /**\n     * @notice transfer token between given addresses, without checking for ERC721Receiver implementation if applicable\n     * @param from sender of token\n     * @param to receiver of token\n     * @param tokenId token id\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 tokenId\n    ) external payable;\n\n    /**\n     * @notice grant approval to given account to spend token\n     * @param operator address to be approved\n     * @param tokenId token to approve\n     */\n    function approve(address operator, uint256 tokenId) external payable;\n\n    /**\n     * @notice get approval status for given token\n     * @param tokenId token to query\n     * @return operator address approved to spend token\n     */\n    function getApproved(\n        uint256 tokenId\n    ) external view returns (address operator);\n\n    /**\n     * @notice grant approval to or revoke approval from given account to spend all tokens held by sender\n     * @param operator address to be approved\n     * @param status approval status\n     */\n    function setApprovalForAll(address operator, bool status) external;\n\n    /**\n     * @notice query approval status of given operator with respect to given address\n     * @param account address to query for approval granted\n     * @param operator address to query for approval received\n     * @return status whether operator is approved to spend tokens held by account\n     */\n    function isApprovedForAll(\n        address account,\n        address operator\n    ) external view returns (bool status);\n}\n"
      },
      "@solidstate/contracts/interfaces/IERC721Internal.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\n/**\n * @title Partial ERC721 interface needed by internal functions\n */\ninterface IERC721Internal {\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 operator,\n        uint256 indexed tokenId\n    );\n\n    event ApprovalForAll(\n        address indexed owner,\n        address indexed operator,\n        bool approved\n    );\n}\n"
      },
      "@solidstate/contracts/interfaces/IERC721Receiver.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\ninterface IERC721Receiver {\n    function onERC721Received(\n        address operator,\n        address from,\n        uint256 tokenId,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n"
      },
      "@solidstate/contracts/introspection/ERC165/base/ERC165BaseInternal.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { IERC165BaseInternal } from './IERC165BaseInternal.sol';\nimport { ERC165BaseStorage } from './ERC165BaseStorage.sol';\n\n/**\n * @title ERC165 implementation\n */\nabstract contract ERC165BaseInternal is IERC165BaseInternal {\n    /**\n     * @notice indicates whether an interface is already supported based on the interfaceId\n     * @param interfaceId id of interface to check\n     * @return bool indicating whether interface is supported\n     */\n    function _supportsInterface(\n        bytes4 interfaceId\n    ) internal view virtual returns (bool) {\n        return ERC165BaseStorage.layout().supportedInterfaces[interfaceId];\n    }\n\n    /**\n     * @notice sets status of interface support\n     * @param interfaceId id of interface to set status for\n     * @param status boolean indicating whether interface will be set as supported\n     */\n    function _setSupportsInterface(\n        bytes4 interfaceId,\n        bool status\n    ) internal virtual {\n        if (interfaceId == 0xffffffff) revert ERC165Base__InvalidInterfaceId();\n        ERC165BaseStorage.layout().supportedInterfaces[interfaceId] = status;\n    }\n}\n"
      },
      "@solidstate/contracts/introspection/ERC165/base/ERC165BaseStorage.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nlibrary ERC165BaseStorage {\n    struct Layout {\n        mapping(bytes4 => bool) supportedInterfaces;\n    }\n\n    bytes32 internal constant STORAGE_SLOT =\n        keccak256('solidstate.contracts.storage.ERC165Base');\n\n    function layout() internal pure returns (Layout storage l) {\n        bytes32 slot = STORAGE_SLOT;\n        assembly {\n            l.slot := slot\n        }\n    }\n}\n"
      },
      "@solidstate/contracts/introspection/ERC165/base/IERC165BaseInternal.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IERC165Internal } from '../../../interfaces/IERC165Internal.sol';\n\ninterface IERC165BaseInternal is IERC165Internal {\n    error ERC165Base__InvalidInterfaceId();\n}\n"
      },
      "@solidstate/contracts/security/partially_pausable/IPartiallyPausableInternal.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\ninterface IPartiallyPausableInternal {\n    error PartiallyPausable__PartiallyPaused();\n    error PartiallyPausable__NotPartiallyPaused();\n\n    event PartiallyPaused(address account, bytes32 key);\n    event PartiallyUnpaused(address account, bytes32 key);\n}\n"
      },
      "@solidstate/contracts/security/partially_pausable/PartiallyPausableInternal.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { IPartiallyPausableInternal } from './IPartiallyPausableInternal.sol';\nimport { PartiallyPausableStorage } from './PartiallyPausableStorage.sol';\n\n/**\n * @title Internal functions for PartiallyPausable security control module.\n */\nabstract contract PartiallyPausableInternal is IPartiallyPausableInternal {\n    modifier whenNotPartiallyPaused(bytes32 key) {\n        if (_partiallyPaused(key)) revert PartiallyPausable__PartiallyPaused();\n        _;\n    }\n\n    modifier whenPartiallyPaused(bytes32 key) {\n        if (!_partiallyPaused(key))\n            revert PartiallyPausable__NotPartiallyPaused();\n        _;\n    }\n\n    /**\n     * @notice query whether contract is paused in the scope of the given key\n     * @return status whether contract is paused in the scope of the given key\n     */\n    function _partiallyPaused(\n        bytes32 key\n    ) internal view virtual returns (bool status) {\n        status = PartiallyPausableStorage.layout().partiallyPaused[key];\n    }\n\n    /**\n     * @notice pause contract in the scope of given key\n     * @param key key whose scope to pause\n     */\n    function _partiallyPause(\n        bytes32 key\n    ) internal virtual whenNotPartiallyPaused(key) {\n        PartiallyPausableStorage.layout().partiallyPaused[key] = true;\n        emit PartiallyPaused(msg.sender, key);\n    }\n\n    /**\n     * @notice unpause contract in the scope of given key\n     * @param key key whose scope to unpause\n     */\n    function _partiallyUnpause(\n        bytes32 key\n    ) internal virtual whenPartiallyPaused(key) {\n        delete PartiallyPausableStorage.layout().partiallyPaused[key];\n        emit PartiallyUnpaused(msg.sender, key);\n    }\n}\n"
      },
      "@solidstate/contracts/security/partially_pausable/PartiallyPausableStorage.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nlibrary PartiallyPausableStorage {\n    struct Layout {\n        mapping(bytes32 => bool) partiallyPaused;\n    }\n\n    bytes32 internal constant STORAGE_SLOT =\n        keccak256('solidstate.contracts.storage.PartiallyPausable');\n\n    function layout() internal pure returns (Layout storage l) {\n        bytes32 slot = STORAGE_SLOT;\n        assembly {\n            l.slot := slot\n        }\n    }\n}\n"
      },
      "@solidstate/contracts/security/pausable/IPausableInternal.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\ninterface IPausableInternal {\n    error Pausable__Paused();\n    error Pausable__NotPaused();\n\n    event Paused(address account);\n    event Unpaused(address account);\n}\n"
      },
      "@solidstate/contracts/security/pausable/PausableInternal.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { IPausableInternal } from './IPausableInternal.sol';\nimport { PausableStorage } from './PausableStorage.sol';\n\n/**\n * @title Internal functions for Pausable security control module.\n */\nabstract contract PausableInternal is IPausableInternal {\n    modifier whenNotPaused() {\n        if (_paused()) revert Pausable__Paused();\n        _;\n    }\n\n    modifier whenPaused() {\n        if (!_paused()) revert Pausable__NotPaused();\n        _;\n    }\n\n    /**\n     * @notice query whether contract is paused\n     * @return status whether contract is paused\n     */\n    function _paused() internal view virtual returns (bool status) {\n        status = PausableStorage.layout().paused;\n    }\n\n    /**\n     * @notice Triggers paused state, when contract is unpaused.\n     */\n    function _pause() internal virtual whenNotPaused {\n        PausableStorage.layout().paused = true;\n        emit Paused(msg.sender);\n    }\n\n    /**\n     * @notice Triggers unpaused state, when contract is paused.\n     */\n    function _unpause() internal virtual whenPaused {\n        delete PausableStorage.layout().paused;\n        emit Unpaused(msg.sender);\n    }\n}\n"
      },
      "@solidstate/contracts/security/pausable/PausableStorage.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nlibrary PausableStorage {\n    struct Layout {\n        bool paused;\n    }\n\n    bytes32 internal constant STORAGE_SLOT =\n        keccak256('solidstate.contracts.storage.Pausable');\n\n    function layout() internal pure returns (Layout storage l) {\n        bytes32 slot = STORAGE_SLOT;\n        assembly {\n            l.slot := slot\n        }\n    }\n}\n"
      },
      "@solidstate/contracts/token/ERC721/base/ERC721Base.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { IERC721 } from '../../../interfaces/IERC721.sol';\nimport { IERC721Base } from './IERC721Base.sol';\nimport { ERC721BaseInternal } from './ERC721BaseInternal.sol';\n\n/**\n * @title Base ERC721 implementation, excluding optional extensions\n * @dev inheritor must either implement ERC165 supportsInterface or inherit ERC165Base\n */\nabstract contract ERC721Base is IERC721Base, ERC721BaseInternal {\n    /**\n     * @inheritdoc IERC721\n     */\n    function balanceOf(address account) external view returns (uint256) {\n        return _balanceOf(account);\n    }\n\n    /**\n     * @inheritdoc IERC721\n     */\n    function ownerOf(uint256 tokenId) external view returns (address) {\n        return _ownerOf(tokenId);\n    }\n\n    /**\n     * @inheritdoc IERC721\n     */\n    function getApproved(uint256 tokenId) external view returns (address) {\n        return _getApproved(tokenId);\n    }\n\n    /**\n     * @inheritdoc IERC721\n     */\n    function isApprovedForAll(\n        address account,\n        address operator\n    ) external view returns (bool) {\n        return _isApprovedForAll(account, operator);\n    }\n\n    /**\n     * @inheritdoc IERC721\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 tokenId\n    ) external payable {\n        _transferFrom(from, to, tokenId);\n    }\n\n    /**\n     * @inheritdoc IERC721\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId\n    ) external payable {\n        _safeTransferFrom(from, to, tokenId);\n    }\n\n    /**\n     * @inheritdoc IERC721\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId,\n        bytes memory data\n    ) external payable {\n        _safeTransferFrom(from, to, tokenId, data);\n    }\n\n    /**\n     * @inheritdoc IERC721\n     */\n    function approve(address operator, uint256 tokenId) external payable {\n        _approve(operator, tokenId);\n    }\n\n    /**\n     * @inheritdoc IERC721\n     */\n    function setApprovalForAll(address operator, bool status) external {\n        _setApprovalForAll(operator, status);\n    }\n}\n"
      },
      "@solidstate/contracts/token/ERC721/base/ERC721BaseInternal.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { IERC721Receiver } from '../../../interfaces/IERC721Receiver.sol';\nimport { EnumerableMap } from '../../../data/EnumerableMap.sol';\nimport { EnumerableSet } from '../../../data/EnumerableSet.sol';\nimport { AddressUtils } from '../../../utils/AddressUtils.sol';\nimport { IERC721BaseInternal } from './IERC721BaseInternal.sol';\nimport { ERC721BaseStorage } from './ERC721BaseStorage.sol';\n\n/**\n * @title Base ERC721 internal functions\n */\nabstract contract ERC721BaseInternal is IERC721BaseInternal {\n    using AddressUtils for address;\n    using EnumerableMap for EnumerableMap.UintToAddressMap;\n    using EnumerableSet for EnumerableSet.UintSet;\n\n    function _balanceOf(\n        address account\n    ) internal view virtual returns (uint256) {\n        if (account == address(0)) revert ERC721Base__BalanceQueryZeroAddress();\n        return ERC721BaseStorage.layout().holderTokens[account].length();\n    }\n\n    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n        address owner = ERC721BaseStorage.layout().tokenOwners.get(tokenId);\n        if (owner == address(0)) revert ERC721Base__InvalidOwner();\n        return owner;\n    }\n\n    function _exists(uint256 tokenId) internal view virtual returns (bool) {\n        return ERC721BaseStorage.layout().tokenOwners.contains(tokenId);\n    }\n\n    function _getApproved(\n        uint256 tokenId\n    ) internal view virtual returns (address) {\n        if (!_exists(tokenId)) revert ERC721Base__NonExistentToken();\n\n        return ERC721BaseStorage.layout().tokenApprovals[tokenId];\n    }\n\n    function _isApprovedForAll(\n        address account,\n        address operator\n    ) internal view virtual returns (bool) {\n        return ERC721BaseStorage.layout().operatorApprovals[account][operator];\n    }\n\n    function _isApprovedOrOwner(\n        address spender,\n        uint256 tokenId\n    ) internal view virtual returns (bool) {\n        if (!_exists(tokenId)) revert ERC721Base__NonExistentToken();\n\n        address owner = _ownerOf(tokenId);\n\n        return (spender == owner ||\n            _getApproved(tokenId) == spender ||\n            _isApprovedForAll(owner, spender));\n    }\n\n    function _mint(address to, uint256 tokenId) internal virtual {\n        if (to == address(0)) revert ERC721Base__MintToZeroAddress();\n        if (_exists(tokenId)) revert ERC721Base__TokenAlreadyMinted();\n\n        _beforeTokenTransfer(address(0), to, tokenId);\n\n        ERC721BaseStorage.Layout storage l = ERC721BaseStorage.layout();\n\n        l.holderTokens[to].add(tokenId);\n        l.tokenOwners.set(tokenId, to);\n\n        emit Transfer(address(0), to, tokenId);\n    }\n\n    function _safeMint(address to, uint256 tokenId) internal virtual {\n        _safeMint(to, tokenId, '');\n    }\n\n    function _safeMint(\n        address to,\n        uint256 tokenId,\n        bytes memory data\n    ) internal virtual {\n        _mint(to, tokenId);\n        if (!_checkOnERC721Received(address(0), to, tokenId, data))\n            revert ERC721Base__ERC721ReceiverNotImplemented();\n    }\n\n    function _burn(uint256 tokenId) internal virtual {\n        address owner = _ownerOf(tokenId);\n\n        _beforeTokenTransfer(owner, address(0), tokenId);\n\n        ERC721BaseStorage.Layout storage l = ERC721BaseStorage.layout();\n\n        l.holderTokens[owner].remove(tokenId);\n        l.tokenOwners.remove(tokenId);\n\n        l.tokenApprovals[tokenId] = address(0);\n\n        emit Approval(owner, address(0), tokenId);\n        emit Transfer(owner, address(0), tokenId);\n    }\n\n    function _transfer(\n        address from,\n        address to,\n        uint256 tokenId\n    ) internal virtual {\n        address owner = _ownerOf(tokenId);\n\n        if (owner != from) revert ERC721Base__NotTokenOwner();\n        if (to == address(0)) revert ERC721Base__TransferToZeroAddress();\n\n        _beforeTokenTransfer(from, to, tokenId);\n\n        ERC721BaseStorage.Layout storage l = ERC721BaseStorage.layout();\n\n        l.holderTokens[from].remove(tokenId);\n        l.holderTokens[to].add(tokenId);\n        l.tokenOwners.set(tokenId, to);\n        l.tokenApprovals[tokenId] = address(0);\n\n        emit Approval(owner, address(0), tokenId);\n        emit Transfer(from, to, tokenId);\n    }\n\n    function _transferFrom(\n        address from,\n        address to,\n        uint256 tokenId\n    ) internal virtual {\n        _handleTransferMessageValue(from, to, tokenId, msg.value);\n        if (!_isApprovedOrOwner(msg.sender, tokenId))\n            revert ERC721Base__NotOwnerOrApproved();\n        _transfer(from, to, tokenId);\n    }\n\n    function _safeTransfer(\n        address from,\n        address to,\n        uint256 tokenId,\n        bytes memory data\n    ) internal virtual {\n        _transfer(from, to, tokenId);\n        if (!_checkOnERC721Received(from, to, tokenId, data))\n            revert ERC721Base__ERC721ReceiverNotImplemented();\n    }\n\n    function _safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId\n    ) internal virtual {\n        _safeTransferFrom(from, to, tokenId, '');\n    }\n\n    function _safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId,\n        bytes memory data\n    ) internal virtual {\n        _handleTransferMessageValue(from, to, tokenId, msg.value);\n        if (!_isApprovedOrOwner(msg.sender, tokenId))\n            revert ERC721Base__NotOwnerOrApproved();\n        _safeTransfer(from, to, tokenId, data);\n    }\n\n    function _approve(address operator, uint256 tokenId) internal virtual {\n        _handleApproveMessageValue(operator, tokenId, msg.value);\n\n        address owner = _ownerOf(tokenId);\n\n        if (operator == owner) revert ERC721Base__SelfApproval();\n        if (msg.sender != owner && !_isApprovedForAll(owner, msg.sender))\n            revert ERC721Base__NotOwnerOrApproved();\n\n        ERC721BaseStorage.layout().tokenApprovals[tokenId] = operator;\n        emit Approval(owner, operator, tokenId);\n    }\n\n    function _setApprovalForAll(\n        address operator,\n        bool status\n    ) internal virtual {\n        if (operator == msg.sender) revert ERC721Base__SelfApproval();\n        ERC721BaseStorage.layout().operatorApprovals[msg.sender][\n            operator\n        ] = status;\n        emit ApprovalForAll(msg.sender, operator, status);\n    }\n\n    function _checkOnERC721Received(\n        address from,\n        address to,\n        uint256 tokenId,\n        bytes memory data\n    ) internal virtual returns (bool) {\n        if (!to.isContract()) {\n            return true;\n        }\n\n        bytes memory returnData = to.functionCall(\n            abi.encodeWithSelector(\n                IERC721Receiver(to).onERC721Received.selector,\n                msg.sender,\n                from,\n                tokenId,\n                data\n            ),\n            'ERC721: transfer to non ERC721Receiver implementer'\n        );\n\n        bytes4 returnValue = abi.decode(returnData, (bytes4));\n        return returnValue == type(IERC721Receiver).interfaceId;\n    }\n\n    /**\n     * @notice ERC721 hook, called before externally called approvals for processing of included message value\n     * @param operator beneficiary of approval\n     * @param tokenId id of transferred token\n     * @param value message value\n     */\n    function _handleApproveMessageValue(\n        address operator,\n        uint256 tokenId,\n        uint256 value\n    ) internal virtual {}\n\n    /**\n     * @notice ERC721 hook, called before externally called transfers for processing of included message value\n     * @param from sender of token\n     * @param to receiver of token\n     * @param tokenId id of transferred token\n     * @param value message value\n     */\n    function _handleTransferMessageValue(\n        address from,\n        address to,\n        uint256 tokenId,\n        uint256 value\n    ) internal virtual {}\n\n    /**\n     * @notice ERC721 hook, called before all transfers including mint and burn\n     * @dev function should be overridden and new implementation must call super\n     * @param from sender of token\n     * @param to receiver of token\n     * @param tokenId id of transferred token\n     */\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 tokenId\n    ) internal virtual {}\n}\n"
      },
      "@solidstate/contracts/token/ERC721/base/ERC721BaseStorage.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { EnumerableMap } from '../../../data/EnumerableMap.sol';\nimport { EnumerableSet } from '../../../data/EnumerableSet.sol';\n\nlibrary ERC721BaseStorage {\n    using EnumerableSet for EnumerableSet.UintSet;\n    using EnumerableMap for EnumerableMap.UintToAddressMap;\n\n    bytes32 internal constant STORAGE_SLOT =\n        keccak256('solidstate.contracts.storage.ERC721Base');\n\n    struct Layout {\n        EnumerableMap.UintToAddressMap tokenOwners;\n        mapping(address => EnumerableSet.UintSet) holderTokens;\n        mapping(uint256 => address) tokenApprovals;\n        mapping(address => mapping(address => bool)) operatorApprovals;\n    }\n\n    function layout() internal pure returns (Layout storage l) {\n        bytes32 slot = STORAGE_SLOT;\n        assembly {\n            l.slot := slot\n        }\n    }\n}\n"
      },
      "@solidstate/contracts/token/ERC721/base/IERC721Base.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { IERC721 } from '../../../interfaces/IERC721.sol';\nimport { IERC721BaseInternal } from './IERC721BaseInternal.sol';\n\n/**\n * @title ERC721 base interface\n */\ninterface IERC721Base is IERC721BaseInternal, IERC721 {\n\n}\n"
      },
      "@solidstate/contracts/token/ERC721/base/IERC721BaseInternal.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { IERC721Internal } from '../../../interfaces/IERC721Internal.sol';\n\n/**\n * @title ERC721 base interface\n */\ninterface IERC721BaseInternal is IERC721Internal {\n    error ERC721Base__NotOwnerOrApproved();\n    error ERC721Base__SelfApproval();\n    error ERC721Base__BalanceQueryZeroAddress();\n    error ERC721Base__ERC721ReceiverNotImplemented();\n    error ERC721Base__InvalidOwner();\n    error ERC721Base__MintToZeroAddress();\n    error ERC721Base__NonExistentToken();\n    error ERC721Base__NotTokenOwner();\n    error ERC721Base__TokenAlreadyMinted();\n    error ERC721Base__TransferToZeroAddress();\n}\n"
      },
      "@solidstate/contracts/token/ERC721/enumerable/ERC721Enumerable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { EnumerableMap } from '../../../data/EnumerableMap.sol';\nimport { EnumerableSet } from '../../../data/EnumerableSet.sol';\nimport { ERC721BaseStorage } from '../base/ERC721BaseStorage.sol';\nimport { IERC721Enumerable } from './IERC721Enumerable.sol';\nimport { ERC721EnumerableInternal } from './ERC721EnumerableInternal.sol';\n\nabstract contract ERC721Enumerable is\n    IERC721Enumerable,\n    ERC721EnumerableInternal\n{\n    using EnumerableMap for EnumerableMap.UintToAddressMap;\n    using EnumerableSet for EnumerableSet.UintSet;\n\n    /**\n     * @inheritdoc IERC721Enumerable\n     */\n    function totalSupply() public view returns (uint256) {\n        return _totalSupply();\n    }\n\n    /**\n     * @inheritdoc IERC721Enumerable\n     */\n    function tokenOfOwnerByIndex(\n        address owner,\n        uint256 index\n    ) public view returns (uint256) {\n        return _tokenOfOwnerByIndex(owner, index);\n    }\n\n    /**\n     * @inheritdoc IERC721Enumerable\n     */\n    function tokenByIndex(uint256 index) public view returns (uint256) {\n        return _tokenByIndex(index);\n    }\n}\n"
      },
      "@solidstate/contracts/token/ERC721/enumerable/ERC721EnumerableInternal.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { EnumerableMap } from '../../../data/EnumerableMap.sol';\nimport { EnumerableSet } from '../../../data/EnumerableSet.sol';\nimport { ERC721BaseStorage } from '../base/ERC721BaseStorage.sol';\n\nabstract contract ERC721EnumerableInternal {\n    using EnumerableMap for EnumerableMap.UintToAddressMap;\n    using EnumerableSet for EnumerableSet.UintSet;\n\n    /**\n     * @notice TODO\n     */\n    function _totalSupply() internal view returns (uint256) {\n        return ERC721BaseStorage.layout().tokenOwners.length();\n    }\n\n    /**\n     * @notice TODO\n     */\n    function _tokenOfOwnerByIndex(\n        address owner,\n        uint256 index\n    ) internal view returns (uint256) {\n        return ERC721BaseStorage.layout().holderTokens[owner].at(index);\n    }\n\n    /**\n     * @notice TODO\n     */\n    function _tokenByIndex(\n        uint256 index\n    ) internal view returns (uint256 tokenId) {\n        (tokenId, ) = ERC721BaseStorage.layout().tokenOwners.at(index);\n    }\n}\n"
      },
      "@solidstate/contracts/token/ERC721/enumerable/IERC721Enumerable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\ninterface IERC721Enumerable {\n    /**\n     * @notice get total token supply\n     * @return total supply\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @notice get token of given owner at given internal storage index\n     * @param owner token holder to query\n     * @param index position in owner's token list to query\n     * @return tokenId id of retrieved token\n     */\n    function tokenOfOwnerByIndex(\n        address owner,\n        uint256 index\n    ) external view returns (uint256 tokenId);\n\n    /**\n     * @notice get token at given internal storage index\n     * @param index position in global token list to query\n     * @return tokenId id of retrieved token\n     */\n    function tokenByIndex(\n        uint256 index\n    ) external view returns (uint256 tokenId);\n}\n"
      },
      "@solidstate/contracts/token/ERC721/metadata/ERC721Metadata.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { ERC721MetadataInternal } from './ERC721MetadataInternal.sol';\nimport { IERC721Metadata } from './IERC721Metadata.sol';\n\n/**\n * @title ERC721 metadata extensions\n */\nabstract contract ERC721Metadata is IERC721Metadata, ERC721MetadataInternal {\n    /**\n     * @notice inheritdoc IERC721Metadata\n     */\n    function name() external view virtual returns (string memory) {\n        return _name();\n    }\n\n    /**\n     * @notice inheritdoc IERC721Metadata\n     */\n    function symbol() external view virtual returns (string memory) {\n        return _symbol();\n    }\n\n    /**\n     * @notice inheritdoc IERC721Metadata\n     */\n    function tokenURI(\n        uint256 tokenId\n    ) external view virtual returns (string memory) {\n        return _tokenURI(tokenId);\n    }\n\n    /**\n     * @inheritdoc ERC721MetadataInternal\n     */\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 tokenId\n    ) internal virtual override {\n        super._beforeTokenTransfer(from, to, tokenId);\n    }\n}\n"
      },
      "@solidstate/contracts/token/ERC721/metadata/ERC721MetadataInternal.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { UintUtils } from '../../../utils/UintUtils.sol';\nimport { ERC721BaseStorage } from '../base/ERC721BaseStorage.sol';\nimport { ERC721BaseInternal } from '../base/ERC721Base.sol';\nimport { IERC721MetadataInternal } from './IERC721MetadataInternal.sol';\nimport { ERC721MetadataStorage } from './ERC721MetadataStorage.sol';\n\n/**\n * @title ERC721Metadata internal functions\n */\nabstract contract ERC721MetadataInternal is\n    IERC721MetadataInternal,\n    ERC721BaseInternal\n{\n    using UintUtils for uint256;\n\n    /**\n     * @notice get token name\n     * @return token name\n     */\n    function _name() internal view virtual returns (string memory) {\n        return ERC721MetadataStorage.layout().name;\n    }\n\n    /**\n     * @notice get token symbol\n     * @return token symbol\n     */\n    function _symbol() internal view virtual returns (string memory) {\n        return ERC721MetadataStorage.layout().symbol;\n    }\n\n    /**\n     * @notice get generated URI for given token\n     * @return token URI\n     */\n    function _tokenURI(\n        uint256 tokenId\n    ) internal view virtual returns (string memory) {\n        if (!_exists(tokenId)) revert ERC721Metadata__NonExistentToken();\n\n        ERC721MetadataStorage.Layout storage l = ERC721MetadataStorage.layout();\n\n        string memory tokenIdURI = l.tokenURIs[tokenId];\n        string memory baseURI = l.baseURI;\n\n        if (bytes(baseURI).length == 0) {\n            return tokenIdURI;\n        } else if (bytes(tokenIdURI).length > 0) {\n            return string(abi.encodePacked(baseURI, tokenIdURI));\n        } else {\n            return string(abi.encodePacked(baseURI, tokenId.toString()));\n        }\n    }\n\n    /**\n     * @notice ERC721 hook: clear per-token URI data on burn\n     * @inheritdoc ERC721BaseInternal\n     */\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 tokenId\n    ) internal virtual override {\n        super._beforeTokenTransfer(from, to, tokenId);\n\n        if (to == address(0)) {\n            delete ERC721MetadataStorage.layout().tokenURIs[tokenId];\n        }\n    }\n}\n"
      },
      "@solidstate/contracts/token/ERC721/metadata/ERC721MetadataStorage.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nlibrary ERC721MetadataStorage {\n    bytes32 internal constant STORAGE_SLOT =\n        keccak256('solidstate.contracts.storage.ERC721Metadata');\n\n    struct Layout {\n        string name;\n        string symbol;\n        string baseURI;\n        mapping(uint256 => string) tokenURIs;\n    }\n\n    function layout() internal pure returns (Layout storage l) {\n        bytes32 slot = STORAGE_SLOT;\n        assembly {\n            l.slot := slot\n        }\n    }\n}\n"
      },
      "@solidstate/contracts/token/ERC721/metadata/IERC721Metadata.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { IERC721MetadataInternal } from './IERC721MetadataInternal.sol';\n\n/**\n * @title ERC721Metadata interface\n */\ninterface IERC721Metadata is IERC721MetadataInternal {\n    /**\n     * @notice get token name\n     * @return token name\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @notice get token symbol\n     * @return token symbol\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @notice get generated URI for given token\n     * @return token URI\n     */\n    function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
      },
      "@solidstate/contracts/token/ERC721/metadata/IERC721MetadataInternal.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { IERC721BaseInternal } from '../base/IERC721BaseInternal.sol';\n\n/**\n * @title ERC721Metadata internal interface\n */\ninterface IERC721MetadataInternal is IERC721BaseInternal {\n    error ERC721Metadata__NonExistentToken();\n}\n"
      },
      "@solidstate/contracts/utils/AddressUtils.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport { UintUtils } from './UintUtils.sol';\n\nlibrary AddressUtils {\n    using UintUtils for uint256;\n\n    error AddressUtils__InsufficientBalance();\n    error AddressUtils__NotContract();\n    error AddressUtils__SendValueFailed();\n\n    function toString(address account) internal pure returns (string memory) {\n        return uint256(uint160(account)).toHexString(20);\n    }\n\n    function isContract(address account) internal view returns (bool) {\n        uint256 size;\n        assembly {\n            size := extcodesize(account)\n        }\n        return size > 0;\n    }\n\n    function sendValue(address payable account, uint256 amount) internal {\n        (bool success, ) = account.call{ value: amount }('');\n        if (!success) revert AddressUtils__SendValueFailed();\n    }\n\n    function functionCall(\n        address target,\n        bytes memory data\n    ) internal returns (bytes memory) {\n        return\n            functionCall(target, data, 'AddressUtils: failed low-level call');\n    }\n\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory error\n    ) internal returns (bytes memory) {\n        return _functionCallWithValue(target, data, 0, error);\n    }\n\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return\n            functionCallWithValue(\n                target,\n                data,\n                value,\n                'AddressUtils: failed low-level call with value'\n            );\n    }\n\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory error\n    ) internal returns (bytes memory) {\n        if (value > address(this).balance)\n            revert AddressUtils__InsufficientBalance();\n        return _functionCallWithValue(target, data, value, error);\n    }\n\n    /**\n     * @notice execute arbitrary external call with limited gas usage and amount of copied return data\n     * @dev derived from https://github.com/nomad-xyz/ExcessivelySafeCall (MIT License)\n     * @param target recipient of call\n     * @param gasAmount gas allowance for call\n     * @param value native token value to include in call\n     * @param maxCopy maximum number of bytes to copy from return data\n     * @param data encoded call data\n     * @return success whether call is successful\n     * @return returnData copied return data\n     */\n    function excessivelySafeCall(\n        address target,\n        uint256 gasAmount,\n        uint256 value,\n        uint16 maxCopy,\n        bytes memory data\n    ) internal returns (bool success, bytes memory returnData) {\n        returnData = new bytes(maxCopy);\n\n        assembly {\n            // execute external call via assembly to avoid automatic copying of return data\n            success := call(\n                gasAmount,\n                target,\n                value,\n                add(data, 0x20),\n                mload(data),\n                0,\n                0\n            )\n\n            // determine whether to limit amount of data to copy\n            let toCopy := returndatasize()\n\n            if gt(toCopy, maxCopy) {\n                toCopy := maxCopy\n            }\n\n            // store the length of the copied bytes\n            mstore(returnData, toCopy)\n\n            // copy the bytes from returndata[0:toCopy]\n            returndatacopy(add(returnData, 0x20), 0, toCopy)\n        }\n    }\n\n    function _functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory error\n    ) private returns (bytes memory) {\n        if (!isContract(target)) revert AddressUtils__NotContract();\n\n        (bool success, bytes memory returnData) = target.call{ value: value }(\n            data\n        );\n\n        if (success) {\n            return returnData;\n        } else if (returnData.length > 0) {\n            assembly {\n                let returnData_size := mload(returnData)\n                revert(add(32, returnData), returnData_size)\n            }\n        } else {\n            revert(error);\n        }\n    }\n}\n"
      },
      "@solidstate/contracts/utils/UintUtils.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\n/**\n * @title utility functions for uint256 operations\n * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)\n */\nlibrary UintUtils {\n    error UintUtils__InsufficientHexLength();\n\n    bytes16 private constant HEX_SYMBOLS = '0123456789abcdef';\n\n    function add(uint256 a, int256 b) internal pure returns (uint256) {\n        return b < 0 ? sub(a, -b) : a + uint256(b);\n    }\n\n    function sub(uint256 a, int256 b) internal pure returns (uint256) {\n        return b < 0 ? add(a, -b) : a - uint256(b);\n    }\n\n    function toString(uint256 value) internal pure returns (string memory) {\n        if (value == 0) {\n            return '0';\n        }\n\n        uint256 temp = value;\n        uint256 digits;\n\n        while (temp != 0) {\n            digits++;\n            temp /= 10;\n        }\n\n        bytes memory buffer = new bytes(digits);\n\n        while (value != 0) {\n            digits -= 1;\n            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n            value /= 10;\n        }\n\n        return string(buffer);\n    }\n\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        if (value == 0) {\n            return '0x00';\n        }\n\n        uint256 length = 0;\n\n        for (uint256 temp = value; temp != 0; temp >>= 8) {\n            unchecked {\n                length++;\n            }\n        }\n\n        return toHexString(value, length);\n    }\n\n    function toHexString(\n        uint256 value,\n        uint256 length\n    ) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = '0';\n        buffer[1] = 'x';\n\n        unchecked {\n            for (uint256 i = 2 * length + 1; i > 1; --i) {\n                buffer[i] = HEX_SYMBOLS[value & 0xf];\n                value >>= 4;\n            }\n        }\n\n        if (value != 0) revert UintUtils__InsufficientHexLength();\n\n        return string(buffer);\n    }\n}\n"
      },
      "contracts/facets/ERC721Facet.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.9;\n\n// Import necessary libraries and contracts\nimport { AccessControlInternal } from \"@solidstate/contracts/access/access_control/AccessControlInternal.sol\";\nimport { ERC165BaseInternal } from \"@solidstate/contracts/introspection/ERC165/base/ERC165BaseInternal.sol\";\nimport { ERC721Base } from \"@solidstate/contracts/token/ERC721/base/ERC721Base.sol\";\nimport { ERC721BaseInternal } from \"@solidstate/contracts/token/ERC721/base/ERC721BaseInternal.sol\";\nimport { ERC721Enumerable } from \"@solidstate/contracts/token/ERC721/enumerable/ERC721Enumerable.sol\";\nimport { ERC721Metadata } from \"@solidstate/contracts/token/ERC721/metadata/ERC721Metadata.sol\";\nimport { PartiallyPausableInternal } from \"@solidstate/contracts/security/partially_pausable/PartiallyPausableInternal.sol\";\nimport { PausableInternal } from \"@solidstate/contracts/security/pausable/PausableInternal.sol\";\nimport \"../libraries/LibSilksHorseDiamond.sol\";\n\n/**\n * @title ERC721Facet\n * @dev A Solidity smart contract representing the ERC721 facet of the SilksHorseDiamond contract.\n * This facet provides functionality for purchasing and airdropping NFTs (horses) and handles pausing functionality.\n */\ncontract ERC721Facet is\n    AccessControlInternal,\n    ERC165BaseInternal,\n    ERC721Base,\n    ERC721Enumerable,\n    ERC721Metadata,\n    PartiallyPausableInternal,\n    PausableInternal\n{\n    using EnumerableSet for EnumerableSet.UintSet;\n    \n    event HorseMinted(\n        MintMethod indexed method,\n        uint256 indexed seasonId,\n        uint256 indexed payoutTier,\n        address to,\n        uint256 tokenId\n    );\n    \n    /**\n     * @dev Purchase horses by providing season, payout tier, and quantity.\n     * @param _seasonId The ID of the season from which to purchase horses.\n     * @param _payoutTier The ID of the payout tier for the purchase.\n     * @param _quantity The quantity of horses to purchase.\n     */\n    function purchase(\n        uint256 _seasonId,\n        uint256 _payoutTier,\n        uint256 _quantity\n    )\n    public\n    payable\n    whenNotPaused\n    whenNotPartiallyPaused(HORSE_PURCHASING_PAUSED)\n    {\n        LibSilksHorseDiamond.Layout storage lsh = LibSilksHorseDiamond.layout();\n        // Check if the sent Ether amount is valid\n        PayoutTier storage payoutTier = lsh.payoutTiers[_payoutTier];\n        if ((payoutTier.price * _quantity) != msg.value){\n            revert InvalidIntValue(\n                \"INV_ETH_TOTAL\",\n                msg.value,\n                (payoutTier.price * _quantity)\n            );\n        }\n        \n        // Check if the purchase quantity is within the allowed limit per transaction\n        if (payoutTier.maxPerTx != 0 && _quantity > payoutTier.maxPerTx){\n            revert InvalidIntValue(\n                \"PER_TX_ERROR\",\n                _quantity,\n                payoutTier.maxPerTx\n            );\n        }\n        \n        // Mint the specified quantity of horses to the sender\n        _mintHorses(_seasonId, _payoutTier, _quantity, MintMethod.PURCHASE, msg.sender);\n    }\n    \n    /**\n     * @dev Airdrop horses by providing season, payout tier, quantity, and the recipient address.\n     * @param _seasonId The ID of the season for the airdrop.\n     * @param _payoutTier The ID of the payout tier for the airdrop.\n     * @param _quantity The quantity of horses to airdrop.\n     * @param _to The address to receive the airdropped horses.\n     */\n    function airdrop(\n        uint256 _seasonId,\n        uint256 _payoutTier,\n        uint256 _quantity,\n        address _to\n    )\n    public\n    onlyRole(MINT_ADMIN_ROLE)\n    {\n        // Mint the specified quantity of horses and send them to the specified recipient\n        _mintHorses(_seasonId, _payoutTier, _quantity, MintMethod.AIRDROP, _to);\n    }\n    \n    /**\n    * @dev Allows an external address to mint horses by providing season, payout tier, quantity, and the recipient address.\n    * Checks if the calling address is in the allowed list of external mint addresses before minting.\n    * @param _seasonId The ID of the season for the minted horses.\n    * @param _payoutTier The ID of the payout tier for the minted horses.\n    * @param _quantity The quantity of horses to mint.\n    * @param _to The address to receive the minted horses.\n    */\n    function externalMint(\n        uint256 _seasonId,\n        uint256 _payoutTier,\n        uint256 _quantity,\n        address _to\n    ) external\n    {\n        // Check if the calling address is in the list of allowed external mint addresses\n        bool inAllowedList = LibSilksHorseDiamond.layout().allowedExternalMintAddresses[msg.sender];\n        if (!inAllowedList){\n            revert InvalidExternalMintAddress(\n                msg.sender\n            );\n        }\n        \n        // Call the internal function to mint the horses\n        _mintHorses(_seasonId, _payoutTier, _quantity, MintMethod.EXTERNAL_MINT, _to);\n    }\n    \n    /**\n     * @dev Mint horses based on season, payout tier, quantity, minting method, and recipient address.\n     * @param _seasonId The ID of the season for minting horses.\n     * @param _payoutTier The ID of the payout tier for minting horses.\n     * @param _quantity The quantity of horses to mint.\n     * @param _method The minting method used for the horses.\n     * @param _to The address to receive the minted horses.\n     * @dev This function is used to mint a specified quantity of horse tokens and associate them with a season and payout tier.\n     * The minted horse tokens are then assigned to the provided recipient address. The function performs various checks\n     * to ensure the specified season and payout tier are valid and not paused. It also checks for successful association of\n     * horse tokens with the season and logs minting events.\n     * @dev Emits a HorseMinted event upon successful minting.\n     * @dev Reverts with specific error messages in case of invalid or paused season, invalid or paused payout tier,\n     * failed association of tokens with the season, or any other minting failure.\n     */\n    function _mintHorses(\n        uint256 _seasonId,\n        uint256 _payoutTier,\n        uint256 _quantity,\n        MintMethod _method,\n        address _to\n    )\n    private\n    {\n        LibSilksHorseDiamond.Layout storage lsh = LibSilksHorseDiamond.layout();\n        // Check if the _quantity being minted will cause the maximum number of assets in wallet to be exceeded\n        uint256 maxHorsesPerWallet = lsh.maxHorsesPerWallet;\n        if (maxHorsesPerWallet > 0 &&( _balanceOf(_to) + _quantity) > maxHorsesPerWallet){\n            revert MaxHorsesPerWalletExceeded(\n                _to\n            );\n        }\n        \n        // Check if the specified season and payout tier are valid and not paused\n        SeasonInfo storage seasonInfo = lsh.seasonInfos[_seasonId];\n        if (seasonInfo.paused || !seasonInfo.valid){\n            revert InvalidSeason(\n                _seasonId\n            );\n        }\n        \n        PayoutTier storage payoutTier = lsh.payoutTiers[_payoutTier];\n        if (payoutTier.paused || !payoutTier.valid){\n            revert InvalidPayoutTier(\n                _payoutTier\n            );\n        }\n        \n        uint256 payoutTierHorseCount = lsh.payoutTierHorseCount[_payoutTier];\n        if (payoutTier.maxSupply > 0 && (payoutTierHorseCount + _quantity) > payoutTier.maxSupply){\n            revert PayoutTierMaxSupplyExceeded(\n                _payoutTier\n            );\n        }\n    \n        uint256 nextAvailableTokenId = lsh.nextAvailableTokenId;\n        uint256 i = 0;\n        // Mint the specified quantity of horses, associate them with the season, and set payout percentages\n        for (; i < _quantity;) {\n            uint256 _newTokenId = nextAvailableTokenId + i;\n            lsh.horseSeasonInfo[_newTokenId] = _seasonId;\n            lsh.horsePayoutTier[_newTokenId] = _payoutTier;\n            _safeMint(_to, _newTokenId);\n            emit HorseMinted(_method, _seasonId, _payoutTier, _to, _newTokenId);\n            unchecked {\n                i++;\n            }\n        }\n        lsh.payoutTierHorseCount[_payoutTier] = lsh.payoutTierHorseCount[_payoutTier] + i;\n        lsh.nextAvailableTokenId = nextAvailableTokenId + i;\n    }\n    \n    /**\n     * @dev Hook function called before token transfer, inherited from ERC721Metadata.\n     * @param from The sender of the tokens.\n     * @param to The recipient of the tokens.\n     * @param tokenId The ID of the token being transferred.\n     */\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 tokenId\n    )\n    internal\n    virtual\n    override(\n        ERC721Metadata,\n        ERC721BaseInternal\n    )\n    {\n        super._beforeTokenTransfer(from, to, tokenId);\n    }\n    \n    /**\n     * @notice query whether contract has registered support for given interface\n     * @param interfaceId interface id\n     * @return bool whether interface is supported\n     */\n    function supportsInterface(\n        bytes4 interfaceId\n    )\n    external\n    view\n    returns (\n        bool\n    )\n    {\n        return super._supportsInterface(interfaceId);\n    }\n}\n"
      },
      "contracts/libraries/LibSilksHorseDiamond.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.9;\n\nimport {EnumerableSet} from \"@solidstate/contracts/data/EnumerableSet.sol\";\n\nstruct SeasonInfo {\n    uint256 seasonId;\n    string description;\n    bool paused;\n    bool valid;\n}\n\nstruct PayoutTier {\n    uint256 tierId;\n    string description;\n    uint256 price;\n    uint256 maxPerTx;\n    uint256 payoutPct;\n    uint256 maxSupply;\n    bool paused;\n    bool valid;\n}\n\nenum MintMethod {\n    PURCHASE,\n    AIRDROP,\n    EXTERNAL_MINT\n}\n\nbytes32 constant CONTRACT_ADMIN_ROLE = keccak256(\"silks.contracts.roles.ContractAdminRole\");\nbytes32 constant MINT_ADMIN_ROLE = keccak256(\"silks.contracts.roles.MintAdminRole\");\n\nbytes32 constant HORSE_PURCHASING_PAUSED = keccak256('silks.contracts.paused.HorsePurchasing');\n\nerror InvalidAddress(address _address);\nerror InvalidSeason(uint256 _sent);\nerror InvalidPayoutTier(uint256 _sent);\nerror InvalidTokenId(uint256 _sent);\nerror InvalidIntValue(string _reason, uint256 _sent, uint256 _expected);\nerror InvalidStringValue(string _reason, string _sent, string _expected);\nerror InvalidExternalMintAddress(address _sender);\nerror MaxHorsesPerWalletExceeded(address _walletAddress);\nerror PayoutTierMaxSupplyExceeded(uint256 _payoutTier);\nerror MintFailed(string _reason, uint256 _seasonId, uint256 _payoutTier, uint256 _quantity, MintMethod _method, address _to);\n\nlibrary LibSilksHorseDiamond {\n    bytes32 internal constant STORAGE_SLOT = keccak256('silks.contracts.storage.SilksHorseDiamond');\n    \n    struct Layout {\n        mapping(uint256 => EnumerableSet.UintSet) seasonHorses;\n        mapping(uint256 => SeasonInfo) seasonInfos;\n        mapping(uint256 => PayoutTier) payoutTiers;\n        mapping(uint256 => PayoutTier) deprecated_horsePayoutTier; // deprecated\n        mapping(uint256 => EnumerableSet.UintSet) deprecated_payoutTierHorses;\n        mapping(uint256 => SeasonInfo) deprecated_horseSeasonInfo;\n        mapping(address => bool) allowedExternalMintAddresses;\n        uint256 maxHorsesPerWallet;\n        uint256 nextAvailableTokenId;\n        uint256 defaultPayoutTierId;\n        uint256 defaultSeasonId;\n        mapping(uint256 => uint256) horsePayoutTier;\n        mapping(uint256 => uint256) payoutTierHorseCount;\n        mapping(uint256 => uint256) horseSeasonInfo;\n    }\n    \n    function layout()\n    internal\n    pure\n    returns (\n        Layout storage l\n    ) {\n        bytes32 slot = STORAGE_SLOT;\n        assembly {\n            l.slot := slot\n        }\n    }\n}"
      }
    },
    "settings": {
      "evmVersion": "paris",
      "optimizer": {
        "enabled": false,
        "runs": 200
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {}
    }
  }}