{"sources":{"Swarmwraith.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.24;\n\n// File: @openzeppelin/contracts/utils/introspection/IERC165.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\n\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n\n// File: @openzeppelin/contracts/token/ERC721/IERC721.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)\n\n\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n    /**\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n     */\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n     */\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of tokens in ``owner``'s account.\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\n     *   a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or\n     *   {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\n     *   a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n     * understand this adds an external call which potentially creates a reentrancy vulnerability.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the address zero.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool approved) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n\n// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol)\n\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n    /**\n     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n     * by `operator` from `from`, this function is called.\n     *\n     * It must return its Solidity selector to confirm the token transfer.\n     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be\n     * reverted.\n     *\n     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n     */\n    function onERC721Received(\n        address operator,\n        address from,\n        uint256 tokenId,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n\n// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)\n\n\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n    /**\n     * @dev Returns the token collection name.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the token collection symbol.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n     */\n    function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n\n// File: @openzeppelin/contracts/utils/Context.sol\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n\n// File: @openzeppelin/contracts/utils/math/Math.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)\n\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    /**\n     * @dev Muldiv operation overflow.\n     */\n    error MathOverflowedMulDiv();\n\n    enum Rounding {\n        Floor, // Toward negative infinity\n        Ceil, // Toward positive infinity\n        Trunc, // Toward zero\n        Expand // Away from zero\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with an overflow flag.\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    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    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    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    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 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 towards infinity instead\n     * of rounding towards zero.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (b == 0) {\n            // Guarantee the same behavior as in a regular Solidity division.\n            return a / b;\n        }\n\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\n     * denominator == 0.\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\n     * Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^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 = x * y; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            if (denominator <= prod1) {\n                revert MathOverflowedMulDiv();\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\n            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\n\n            uint256 twos = denominator & (0 - denominator);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^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\n            // works 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 (unsignedRoundsUp(rounding) && 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\n     * towards zero.\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 + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        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 + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        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 + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\n     */\n    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\n        return uint8(rounding) % 2 == 1;\n    }\n}\n\n// File: @openzeppelin/contracts/utils/math/SignedMath.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)\n\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\n// File: @openzeppelin/contracts/utils/Strings.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)\n\n\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant HEX_DIGITS = \"0123456789abcdef\";\n    uint8 private constant ADDRESS_LENGTH = 20;\n\n    /**\n     * @dev The `value` string doesn't fit in the specified `length`.\n     */\n    error StringsInsufficientHexLength(uint256 value, uint256 length);\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), HEX_DIGITS))\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 toStringSigned(int256 value) internal pure returns (string memory) {\n        return string.concat(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        uint256 localValue = value;\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] = HEX_DIGITS[localValue & 0xf];\n            localValue >>= 4;\n        }\n        if (localValue != 0) {\n            revert StringsInsufficientHexLength(value, length);\n        }\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\n     * 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 bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n\n// File: @openzeppelin/contracts/utils/introspection/ERC165.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)\n\n\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165 is IERC165 {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n\n// File: @openzeppelin/contracts/interfaces/draft-IERC6093.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\n\n/**\n * @dev Standard ERC20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\n */\ninterface IERC20Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC20InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC20InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     * @param allowance Amount of tokens a `spender` is allowed to operate with.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC20InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\n */\ninterface IERC721Errors {\n    /**\n     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\n     * Used in balance queries.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721InvalidOwner(address owner);\n\n    /**\n     * @dev Indicates a `tokenId` whose `owner` is the zero address.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721NonexistentToken(uint256 tokenId);\n\n    /**\n     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param tokenId Identifier number of a token.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC721InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC721InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC721InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\n */\ninterface IERC1155Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC1155InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC1155InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC1155MissingApprovalForAll(address operator, address owner);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC1155InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC1155InvalidOperator(address operator);\n\n    /**\n     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n     * Used in batch transfers.\n     * @param idsLength Length of the array of token identifiers\n     * @param valuesLength Length of the array of token amounts\n     */\n    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n\n// File: @openzeppelin/contracts/token/ERC721/ERC721.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/ERC721.sol)\n\n\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\nabstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors {\n    using Strings for uint256;\n\n    // Token name\n    string private _name;\n\n    // Token symbol\n    string private _symbol;\n\n    mapping(uint256 tokenId => address) private _owners;\n\n    mapping(address owner => uint256) private _balances;\n\n    mapping(uint256 tokenId => address) private _tokenApprovals;\n\n    mapping(address owner => mapping(address operator => bool)) private _operatorApprovals;\n\n    /**\n     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n        return\n            interfaceId == type(IERC721).interfaceId ||\n            interfaceId == type(IERC721Metadata).interfaceId ||\n            super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev See {IERC721-balanceOf}.\n     */\n    function balanceOf(address owner) public view virtual returns (uint256) {\n        if (owner == address(0)) {\n            revert ERC721InvalidOwner(address(0));\n        }\n        return _balances[owner];\n    }\n\n    /**\n     * @dev See {IERC721-ownerOf}.\n     */\n    function ownerOf(uint256 tokenId) public view virtual returns (address) {\n        return _requireOwned(tokenId);\n    }\n\n    /**\n     * @dev See {IERC721Metadata-name}.\n     */\n    function name() public view virtual returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-symbol}.\n     */\n    function symbol() public view virtual returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-tokenURI}.\n     */\n    function tokenURI(uint256 tokenId) public view virtual returns (string memory) {\n        _requireOwned(tokenId);\n\n        string memory baseURI = _baseURI();\n        return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : \"\";\n    }\n\n    /**\n     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n     * by default, can be overridden in child contracts.\n     */\n    function _baseURI() internal view virtual returns (string memory) {\n        return \"\";\n    }\n\n    /**\n     * @dev See {IERC721-approve}.\n     */\n    function approve(address to, uint256 tokenId) public virtual {\n        _approve(to, tokenId, _msgSender());\n    }\n\n    /**\n     * @dev See {IERC721-getApproved}.\n     */\n    function getApproved(uint256 tokenId) public view virtual returns (address) {\n        _requireOwned(tokenId);\n\n        return _getApproved(tokenId);\n    }\n\n    /**\n     * @dev See {IERC721-setApprovalForAll}.\n     */\n    function setApprovalForAll(address operator, bool approved) public virtual {\n        _setApprovalForAll(_msgSender(), operator, approved);\n    }\n\n    /**\n     * @dev See {IERC721-isApprovedForAll}.\n     */\n    function isApprovedForAll(address owner, address operator) public view virtual returns (bool) {\n        return _operatorApprovals[owner][operator];\n    }\n\n    /**\n     * @dev See {IERC721-transferFrom}.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) public virtual {\n        if (to == address(0)) {\n            revert ERC721InvalidReceiver(address(0));\n        }\n        // Setting an \"auth\" arguments enables the `_isAuthorized` check which verifies that the token exists\n        // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here.\n        address previousOwner = _update(to, tokenId, _msgSender());\n        if (previousOwner != from) {\n            revert ERC721IncorrectOwner(from, tokenId, previousOwner);\n        }\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) public {\n        safeTransferFrom(from, to, tokenId, \"\");\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual {\n        transferFrom(from, to, tokenId);\n        _checkOnERC721Received(from, to, tokenId, data);\n    }\n\n    /**\n     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n     *\n     * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the\n     * core ERC721 logic MUST be matched with the use of {_increaseBalance} to keep balances\n     * consistent with ownership. The invariant to preserve is that for any address `a` the value returned by\n     * `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`.\n     */\n    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n        return _owners[tokenId];\n    }\n\n    /**\n     * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted.\n     */\n    function _getApproved(uint256 tokenId) internal view virtual returns (address) {\n        return _tokenApprovals[tokenId];\n    }\n\n    /**\n     * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in\n     * particular (ignoring whether it is owned by `owner`).\n     *\n     * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this\n     * assumption.\n     */\n    function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) {\n        return\n            spender != address(0) &&\n            (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender);\n    }\n\n    /**\n     * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner.\n     * Reverts if `spender` does not have approval from the provided `owner` for the given token or for all its assets\n     * the `spender` for the specific `tokenId`.\n     *\n     * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this\n     * assumption.\n     */\n    function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual {\n        if (!_isAuthorized(owner, spender, tokenId)) {\n            if (owner == address(0)) {\n                revert ERC721NonexistentToken(tokenId);\n            } else {\n                revert ERC721InsufficientApproval(spender, tokenId);\n            }\n        }\n    }\n\n    /**\n     * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n     *\n     * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that\n     * a uint256 would ever overflow from increments when these increments are bounded to uint128 values.\n     *\n     * WARNING: Increasing an account's balance using this function tends to be paired with an override of the\n     * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership\n     * remain consistent with one another.\n     */\n    function _increaseBalance(address account, uint128 value) internal virtual {\n        unchecked {\n            _balances[account] += value;\n        }\n    }\n\n    /**\n     * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner\n     * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update.\n     *\n     * The `auth` argument is optional. If the value passed is non 0, then this function will check that\n     * `auth` is either the owner of the token, or approved to operate on the token (by the owner).\n     *\n     * Emits a {Transfer} event.\n     *\n     * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}.\n     */\n    function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) {\n        address from = _ownerOf(tokenId);\n\n        // Perform (optional) operator check\n        if (auth != address(0)) {\n            _checkAuthorized(from, auth, tokenId);\n        }\n\n        // Execute the update\n        if (from != address(0)) {\n            // Clear approval. No need to re-authorize or emit the Approval event\n            _approve(address(0), tokenId, address(0), false);\n\n            unchecked {\n                _balances[from] -= 1;\n            }\n        }\n\n        if (to != address(0)) {\n            unchecked {\n                _balances[to] += 1;\n            }\n        }\n\n        _owners[tokenId] = to;\n\n        emit Transfer(from, to, tokenId);\n\n        return from;\n    }\n\n    /**\n     * @dev Mints `tokenId` and transfers it to `to`.\n     *\n     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n     *\n     * Requirements:\n     *\n     * - `tokenId` must not exist.\n     * - `to` cannot be the zero address.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _mint(address to, uint256 tokenId) internal {\n        if (to == address(0)) {\n            revert ERC721InvalidReceiver(address(0));\n        }\n        address previousOwner = _update(to, tokenId, address(0));\n        if (previousOwner != address(0)) {\n            revert ERC721InvalidSender(address(0));\n        }\n    }\n\n    /**\n     * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must not exist.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _safeMint(address to, uint256 tokenId) internal {\n        _safeMint(to, tokenId, \"\");\n    }\n\n    /**\n     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n     */\n    function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n        _mint(to, tokenId);\n        _checkOnERC721Received(address(0), to, tokenId, data);\n    }\n\n    /**\n     * @dev Destroys `tokenId`.\n     * The approval is cleared when the token is burned.\n     * This is an internal function that does not check if the sender is authorized to operate on the token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _burn(uint256 tokenId) internal {\n        address previousOwner = _update(address(0), tokenId, address(0));\n        if (previousOwner == address(0)) {\n            revert ERC721NonexistentToken(tokenId);\n        }\n    }\n\n    /**\n     * @dev Transfers `tokenId` from `from` to `to`.\n     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _transfer(address from, address to, uint256 tokenId) internal {\n        if (to == address(0)) {\n            revert ERC721InvalidReceiver(address(0));\n        }\n        address previousOwner = _update(to, tokenId, address(0));\n        if (previousOwner == address(0)) {\n            revert ERC721NonexistentToken(tokenId);\n        } else if (previousOwner != from) {\n            revert ERC721IncorrectOwner(from, tokenId, previousOwner);\n        }\n    }\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients\n     * are aware of the ERC721 standard to prevent tokens from being forever locked.\n     *\n     * `data` is additional data, it has no specified format and it is sent in call to `to`.\n     *\n     * This internal function is like {safeTransferFrom} in the sense that it invokes\n     * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g.\n     * implement alternative mechanisms to perform token transfer, such as signature-based.\n     *\n     * Requirements:\n     *\n     * - `tokenId` token must exist and be owned by `from`.\n     * - `to` cannot be the zero address.\n     * - `from` cannot be the zero address.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _safeTransfer(address from, address to, uint256 tokenId) internal {\n        _safeTransfer(from, to, tokenId, \"\");\n    }\n\n    /**\n     * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is\n     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n     */\n    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n        _transfer(from, to, tokenId);\n        _checkOnERC721Received(from, to, tokenId, data);\n    }\n\n    /**\n     * @dev Approve `to` to operate on `tokenId`\n     *\n     * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is\n     * either the owner of the token, or approved to operate on all tokens held by this owner.\n     *\n     * Emits an {Approval} event.\n     *\n     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n     */\n    function _approve(address to, uint256 tokenId, address auth) internal {\n        _approve(to, tokenId, auth, true);\n    }\n\n    /**\n     * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not\n     * emitted in the context of transfers.\n     */\n    function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual {\n        // Avoid reading the owner unless necessary\n        if (emitEvent || auth != address(0)) {\n            address owner = _requireOwned(tokenId);\n\n            // We do not use _isAuthorized because single-token approvals should not be able to call approve\n            if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) {\n                revert ERC721InvalidApprover(auth);\n            }\n\n            if (emitEvent) {\n                emit Approval(owner, to, tokenId);\n            }\n        }\n\n        _tokenApprovals[tokenId] = to;\n    }\n\n    /**\n     * @dev Approve `operator` to operate on all of `owner` tokens\n     *\n     * Requirements:\n     * - operator can't be the address zero.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n        if (operator == address(0)) {\n            revert ERC721InvalidOperator(operator);\n        }\n        _operatorApprovals[owner][operator] = approved;\n        emit ApprovalForAll(owner, operator, approved);\n    }\n\n    /**\n     * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned).\n     * Returns the owner.\n     *\n     * Overrides to ownership logic should be done to {_ownerOf}.\n     */\n    function _requireOwned(uint256 tokenId) internal view returns (address) {\n        address owner = _ownerOf(tokenId);\n        if (owner == address(0)) {\n            revert ERC721NonexistentToken(tokenId);\n        }\n        return owner;\n    }\n\n    /**\n     * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. This will revert if the\n     * recipient doesn't accept the token transfer. The call is not executed if the target address is not a contract.\n     *\n     * @param from address representing the previous owner of the given token ID\n     * @param to target address that will receive the tokens\n     * @param tokenId uint256 ID of the token to be transferred\n     * @param data bytes optional data to send along with the call\n     */\n    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private {\n        if (to.code.length > 0) {\n            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n                if (retval != IERC721Receiver.onERC721Received.selector) {\n                    revert ERC721InvalidReceiver(to);\n                }\n            } catch (bytes memory reason) {\n                if (reason.length == 0) {\n                    revert ERC721InvalidReceiver(to);\n                } else {\n                    /// @solidity memory-safe-assembly\n                    assembly {\n                        revert(add(32, reason), mload(reason))\n                    }\n                }\n            }\n        }\n    }\n}\n\n// File: @openzeppelin/contracts/interfaces/IERC2981.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC2981.sol)\n\n\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n */\ninterface IERC2981 is IERC165 {\n    /**\n     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\n     */\n    function royaltyInfo(\n        uint256 tokenId,\n        uint256 salePrice\n    ) external view returns (address receiver, uint256 royaltyAmount);\n}\n\n// File: @openzeppelin/contracts/token/common/ERC2981.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (token/common/ERC2981.sol)\n\n\n\n/**\n * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.\n *\n * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for\n * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.\n *\n * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the\n * fee is specified in basis points by default.\n *\n * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See\n * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to\n * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.\n */\nabstract contract ERC2981 is IERC2981, ERC165 {\n    struct RoyaltyInfo {\n        address receiver;\n        uint96 royaltyFraction;\n    }\n\n    RoyaltyInfo private _defaultRoyaltyInfo;\n    mapping(uint256 tokenId => RoyaltyInfo) private _tokenRoyaltyInfo;\n\n    /**\n     * @dev The default royalty set is invalid (eg. (numerator / denominator) >= 1).\n     */\n    error ERC2981InvalidDefaultRoyalty(uint256 numerator, uint256 denominator);\n\n    /**\n     * @dev The default royalty receiver is invalid.\n     */\n    error ERC2981InvalidDefaultRoyaltyReceiver(address receiver);\n\n    /**\n     * @dev The royalty set for an specific `tokenId` is invalid (eg. (numerator / denominator) >= 1).\n     */\n    error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator);\n\n    /**\n     * @dev The royalty receiver for `tokenId` is invalid.\n     */\n    error ERC2981InvalidTokenRoyaltyReceiver(uint256 tokenId, address receiver);\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\n        return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @inheritdoc IERC2981\n     */\n    function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual returns (address, uint256) {\n        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];\n\n        if (royalty.receiver == address(0)) {\n            royalty = _defaultRoyaltyInfo;\n        }\n\n        uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();\n\n        return (royalty.receiver, royaltyAmount);\n    }\n\n    /**\n     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a\n     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an\n     * override.\n     */\n    function _feeDenominator() internal pure virtual returns (uint96) {\n        return 10000;\n    }\n\n    /**\n     * @dev Sets the royalty information that all ids in this contract will default to.\n     *\n     * Requirements:\n     *\n     * - `receiver` cannot be the zero address.\n     * - `feeNumerator` cannot be greater than the fee denominator.\n     */\n    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {\n        uint256 denominator = _feeDenominator();\n        if (feeNumerator > denominator) {\n            // Royalty fee will exceed the sale price\n            revert ERC2981InvalidDefaultRoyalty(feeNumerator, denominator);\n        }\n        if (receiver == address(0)) {\n            revert ERC2981InvalidDefaultRoyaltyReceiver(address(0));\n        }\n\n        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);\n    }\n\n    /**\n     * @dev Removes default royalty information.\n     */\n    function _deleteDefaultRoyalty() internal virtual {\n        delete _defaultRoyaltyInfo;\n    }\n\n    /**\n     * @dev Sets the royalty information for a specific token id, overriding the global default.\n     *\n     * Requirements:\n     *\n     * - `receiver` cannot be the zero address.\n     * - `feeNumerator` cannot be greater than the fee denominator.\n     */\n    function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {\n        uint256 denominator = _feeDenominator();\n        if (feeNumerator > denominator) {\n            // Royalty fee will exceed the sale price\n            revert ERC2981InvalidTokenRoyalty(tokenId, feeNumerator, denominator);\n        }\n        if (receiver == address(0)) {\n            revert ERC2981InvalidTokenRoyaltyReceiver(tokenId, address(0));\n        }\n\n        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);\n    }\n\n    /**\n     * @dev Resets royalty information for the token id back to the global default.\n     */\n    function _resetTokenRoyalty(uint256 tokenId) internal virtual {\n        delete _tokenRoyaltyInfo[tokenId];\n    }\n}\n\n// File: @openzeppelin/contracts/access/Ownable.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\n\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    constructor(address initialOwner) {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n\n// File: @openzeppelin/contracts/utils/Base64.sol\n// OpenZeppelin Contracts (last updated v5.0.2) (utils/Base64.sol)\n\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n */\nlibrary Base64 {\n    /**\n     * @dev Base64 Encoding/Decoding Table\n     */\n    string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n    /**\n     * @dev Converts a `bytes` to its Bytes64 `string` representation.\n     */\n    function encode(bytes memory data) internal pure returns (string memory) {\n        /**\n         * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n         * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n         */\n        if (data.length == 0) return \"\";\n\n        // Loads the table into memory\n        string memory table = _TABLE;\n\n        // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n        // and split into 4 numbers of 6 bits.\n        // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n        // - `data.length + 2`  -> Round up\n        // - `/ 3`              -> Number of 3-bytes chunks\n        // - `4 *`              -> 4 characters for each chunk\n        string memory result = new string(4 * ((data.length + 2) / 3));\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Prepare the lookup table (skip the first \"length\" byte)\n            let tablePtr := add(table, 1)\n\n            // Prepare result pointer, jump over length\n            let resultPtr := add(result, 0x20)\n            let dataPtr := data\n            let endPtr := add(data, mload(data))\n\n            // In some cases, the last iteration will read bytes after the end of the data. We cache the value, and\n            // set it to zero to make sure no dirty bytes are read in that section.\n            let afterPtr := add(endPtr, 0x20)\n            let afterCache := mload(afterPtr)\n            mstore(afterPtr, 0x00)\n\n            // Run over the input, 3 bytes at a time\n            for {\n\n            } lt(dataPtr, endPtr) {\n\n            } {\n                // Advance 3 bytes\n                dataPtr := add(dataPtr, 3)\n                let input := mload(dataPtr)\n\n                // To write each character, shift the 3 byte (24 bits) chunk\n                // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n                // and apply logical AND with 0x3F to bitmask the least significant 6 bits.\n                // Use this as an index into the lookup table, mload an entire word\n                // so the desired character is in the least significant byte, and\n                // mstore8 this least significant byte into the result and continue.\n\n                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n                resultPtr := add(resultPtr, 1) // Advance\n\n                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n                resultPtr := add(resultPtr, 1) // Advance\n\n                mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n                resultPtr := add(resultPtr, 1) // Advance\n\n                mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n                resultPtr := add(resultPtr, 1) // Advance\n            }\n\n            // Reset the value that was cached\n            mstore(afterPtr, afterCache)\n\n            // When data `bytes` is not exactly 3 bytes long\n            // it is padded with `=` characters at the end\n            switch mod(mload(data), 3)\n            case 1 {\n                mstore8(sub(resultPtr, 1), 0x3d)\n                mstore8(sub(resultPtr, 2), 0x3d)\n            }\n            case 2 {\n                mstore8(sub(resultPtr, 1), 0x3d)\n            }\n        }\n\n        return result;\n    }\n}\n\n// File: Swarmwraith.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Swarmwraith - 500 Friendly little ghost made of a swarm of glowing orange wisps with a tiny witch hat in a misty purple Halloween night with candles for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 500 free pool lasts (gas only).\n/// Every other mint costs 0.00007 BNB. Max 50 per wallet, 500 total. Collectible only, not an investment.\n/// @dev Art and metadata are generated fully on-chain from each token id. No IPFS, no reveal, nothing to set after deploy.\ncontract Swarmwraith is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 500;\n    uint256 public constant FREE_SUPPLY = 500;\n    uint256 public constant FREE_PER_WALLET = 2;\n    uint256 public constant MAX_PER_WALLET = 50;\n    uint256 public constant PRICE = 0.00007 ether;\n\n    uint256 public totalSupply;\n    uint256 public freeClaimed;\n    bool public mintOpen = true;\n    mapping(address => uint256) public mintedBy;\n    mapping(address => uint256) public freeUsed;\n\n    error NoAgentId();\n    error OnlyWallets();\n    error MintClosed();\n    error BadQuantity();\n    error SoldOut();\n    error WalletLimit();\n    error WrongPayment();\n    error WithdrawFailed();\n\n    event Launched(address indexed to, uint256 indexed tokenId, string agent);\n\n    /// @notice Contract whose runtime code holds the artwork bytes (WebP), after a leading 0x00 STOP byte.\n    address public immutable IMAGE;\n\n    /// @dev The WebP artwork is embedded in this source and written, in this same deploy transaction,\n    /// into a small storage contract (runtime = 0x00 STOP byte + image bytes) owned by nobody.\n    constructor(address initialOwner) ERC721(\"Swarmwraith\", \"SWARMWRAITH\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"52494646ce2f00005745425056503820c22f0000901b019d012a900190013ec15aa44ea7a53b3627d41acb6018094dd25e5a2b63d361fb1bf4d44d2c503f8daa963596d8c725e9c7fe46893bbb9ed3d476e2de75bd3e0a65bf857fe9f3c3f1aff0fc29b7599f5c61f01ac42f05c3bc5960ec5dfcbee32b9b0ae8fdb54b2abcccf8abb47231f130e0db72a6d010dbaa2f3f2bcab3abd5a49e2978d9eb2d63018180777fa1bf54ceb1f43e3f4d75ff7ce3c05e6a7935b29440e95725f9fca25121d140f83dea29bf866eef08dcb2759090c91d09a339c5ef41395887ce271cdd0178e094ae900026d4dc9225d5507b8cb9dfd16c7c7f60732cc411b732add5df218c8e23f9f9acc8f41c15eeb8c1f2cee4725f397d637612639b3bcd77e3133769453580ee59b1f1073120f082e502f353ad7f7f82dd951f754ebb2dcfb668009bb7d7a3436442523eee99fc2c098e2548c0269a3ab24a4aea043a6472f45262282b96f67aa1a26a64cccafd97ef56008da4c43a0bb6827c79fc34554f8916b579ff1c32b1561277c71bc8cad2de1de98d7a81716bc7480fe9b3f2fcb957596c1b6d6220efc1d3dffde87a6d20b7e0e4d29baff30b9afd28afaee340eace37470d30a1bd207d979a54f3da5db441cc35fde643676bf929c7881adb03e0f426c7059c8b952b3d883ed18a1f57ef26a31ae3a76226dfe179d60230225700c095fd941c9859f1753b46213c0c8c3fafbe279782c951b415b29eb197fc090f29fc1f6c2022fe1d9babf3a9b9406f81b685ac28f317a8eeeaa3bd620eb939b7b724b5a02e7cc1a8def8c4663f81638b28712d94896636dd0458a0c424281646d03728dbe771219414bab54d7acce46ab41384bd3e1a3adae3dcd1ee25ec76e3f532d04cfc341c5ebf2465029c96d68534a6817f6668d9831f6266778280b044417303b5eda635abed1ea5f6a2b83d7bc726e7b0badf9f52686301df30060d10221083aacf821141a5972716b24ae95bd849dc3baef100081a61d9f00b4ea0f496adf3dd11c8e1a2f47cb34c6d476c1ffdd539019aed3a3aea7916b18b9d43ee6e728145ccb3612458765ab6c79f035bd42e36a3e281c40683a20f1457179e5db7114933feb5fb706f2e9014c2bc692ee2de9206a600a55464b79d06be5494ddb4057fc67edfabfd8d685ef89fb5dfa9fe21b0647b66657d8c9ea5d5d2248732d7b116578bf8862992348701870dbe921e015b91923e427f95ae8d1060a61662a2f4a38fa921b279408ca217e19fdbfa49aea0cf41189a410caca6c74f4875d8d9cf04e24ec00274f8d7369c2a1559ae98038e26233714c65672f8660932ff425cff98a3e002af381458a4050de09cc8e0c8b9b997c73a25a23c72bd600e4cb3f8752190c1fbd893b25c9df59853cc69b7b3243aa2153ad2f69ab02ea5d3f46bf539b6841bf50e94e945b5f859e1913ba49eb5330a16835308f473b3c6dd1eeaaa32f3d44861e68bf4464da0d665c49112ca984564c15a80e97ad0835a24b1e6a265db8de8a4beaa9b1c9dc58c67eb67fd05bcd0af23b2b97597b4864521afddbc3383714aa0ac2cc4c938f67d9645ea2dda85adbdba9309691eb1085d5359f4599379bfa9951e54fa5484e621815cdda66e63141fc0e34efd039c5fe7b684a21c31199a7418051648e714bcda48430acb7d8cc2b7e4f5e22fa4b413a5bcd4b9dafddb7d891ff0468b9fbb8f5be3632342040fa017b5795b6f2a8ca50a2d36dd09274e60ee2ce832bc43952d12fd353ced11b3b505e5a883b41379290ae64f8ce253db807524bf00f92f0fd24325073a388e8695f146e3e3be81b7365c36e2bd1d614a89fcaa81241a26c62c9d5e86bb2daeb02facedceff1210f05fa121870013026116b94bd815e370203816f9f9980dafb70de59b53a5d9e4f77d976546912fdf4ec3c96535a0ae9e73c20b153fecee90b0424edf9bf06a190bb4407543f890d7dd58f20bca1ec09adf8344209fa85c201ece79329c1caef57777b18ed459477ae0e83c6caec75b05d7aa19504010130210f188ea23ec9363eb788196f72e219ee028c5094028220dc680e945f3e62b58690adfe81820698f8bd472716099a0dd68176faeef05b44d6ba630cc270da58e71102949cdeee3c99b3e7faf35e10221a6eb8de1f9cdc019c3f3a63bfb8850f2c4a91ce382c6ac3488390d1032d4b33299c83f1b1214f7c5cdca051a55f82f388b7da292d3f3de058a049d5ba3ea49ea04af96e9abde8afe0cd790a8e40e0721e32752f6bd32492549b75540ce301c493b3758450549f52083232077a1ec805f7447c3b66bd043545f9211e87b0dfaff8998d6de6d12c541cef00581d29d340107ff55a01b8913013cb585dd2766f85700119f597c6f2870ea9256a4525ffa71adca57f2a034bdb08df1208fd0ef068d4cbf2a8c58268b2627f743ca72b075f33ecbcab68dca502ac56d96946667c9c7bde6e7402b34f5164d5b3277a8cc91561ac00f0e61bed78192eae88cc99027a368343e99a9bb3dcaf4899cee15c504fd9d4acd3f5d3c6cdef3f24b35316fe2df916c4ecf948a593381dbe481a9fe3fe8b3f623158a0327d884fc96dbcc4a03fe92713cd3d1930d3c7c879a430de63745e09b163c6937a00a29288eef5e399b8467b0f3bef66ae93bee6f31e1e69ead3208bf00ba866fd772a5f232f97bfd17b053584bb4514bbff21e268ff4fdd9d91d095562ed0c849e980352528bd3f4684ebe0f318089a36a4b580d617a8019198f8ae3ac393c3c9f873b354878c8d9836a7ce018245560e7dd64c4f7390490ba971e75beab8fa5fb1b0fc6710c7bea6c03186f48045cef2764c79d288c6e18e134327df6fa78346286b26c5a58febe89c26f389132fc34c13a10b2826fa2efcc63f0f01f63f400c6c5d991acac2cc9ccec1300ccd555c8df72f5d680d2c632169da181aff87b0e65a7d88dfa924ce853f3f68563f40acaa622b676eebfac3c1f36a8091753a9cd27be9f8e9bef4e8314dd81ccb2082beb91ba8cf64fa7f3aa7996c1fa753f2e84a36dd2d198e2c09e9137aa6e4aa6d508fdd8c96da298dc7e52438b8b15fd7e3c0b827943f6d149e2906a2843a0b4cc7f0fb2d35570de62737a6587bf613d55f049bd414fa6fedd89a7891326d3a5cf1487164c8cefdec47f0beae60e02a291b48435a639af40b9255eec697455624eff4b25328a24ecd1e8d4648a345ae3cc7235d7c3300000fef534254290350ca5eda093506ff0f695848d6eb91adadc7afee366f74c95511aa203beaeb324fc9b6ed1c12e71e24548ba74d4465524d257d20a79141f42577f168f4f53d7557ad1630f7a943f79004a11e54b435ee2592c9ac5840fd508b6ea465011cf923f28c1ae36d7e0b182ae20aebb3cbfa72d0c22617e514fcc23383f50f1df410a76afd2e01452a2e208639ac4359f63ba043ff622bd2c12ef7f21163c7cbc2dc547452d6dc04bbb1c1b8e4378dbf53fc527053eaa90fa36dd5f2052d2c3605b4b64526228bb18285b95a6db134a8350842de9df917d24268908cb0a158faf8888ad835128c3e4c91a1833b25f9637757951daaaabb20c5e9f1fb1e7e403ed103b46826561fb6a093e789e3c1b06d8eb8412d62d0d4014a227e11d2804db8fd0bc0742b1f646c927036006e6375674e3beb4a0079f8b70a098141d6c0a260f60504b8ce114cef13f8a7c268d97ea1823277968dfd58ffc924bd7eee9bf0d65b81bf12599a7e14eed1866a37710c2c128ec39b88d10f328a51968ad4a6f6cbbc0be22cd87e1e79df95607b4e49db58570f49138d4df2814b823faa13ff79fa9cf840059bf33a3b534f06a285040d82b878ea72d2b8aad31ad1bc5dcf61e4d8e3f5b5c187670e7e8064fd243aad95fadc18b4b6ad20656a91d131ee3e3a419d41fb02acd5168527e1f042f4dbf694293b336a08457ea944fb9f0df4944d05b962f98530238c40291723a1349bc83457e5c93babf2d39d3696a15aacf9f3ff1e5d806580b3fdde1cea363f9953d097e0abcdb0b19eaccc9f31e8abb832b21b06b093b01587bad6d1cd50e35169fac2f79980ee4d6116984d92ec13a1c298200020791fa6a1f643410af31c97deb5eecdc67d92f9b1aee242e8e48607d8a261c77d3f899ba783af2d1228ea04f96f9cc8066dcc5ebcae2b26849e0f9c67c1aa76ed742375a5db9d322a492d9983d75b8b6f3f63c2c44a9e82e30803eed2efdf6bf2a31f6197d3192090421040204c606fa7700af3ab62294d8f80328d9535dc3dc2f674741a546338f3d6ef05e6c5ce521c1765fdd7b38539fb1b517cd386f27d248d077647f1d8d9ed934d9408ac5fcf1453bf756448e7b045723d29532d4ed087c21009a959648f5ade7a3c3c625bf8d3837cfb36680e5e0fbf1ba7cd9d1bdc5f19bc0641545f43aa6f591c488fb7a058dce063a375612714bdb83a1a4e47e92116e93f1e5a470a6df88a1939035f9e904015daabb4e90b7a5c35d356ada763567530463915f4efc1fb7b6b7ce8ac7c7bb3c911d6908c27a445ab044e8927be66b92f66d8dcf238d9d64b9fdfbf6ac9374bee990d60179eec7db067fd20b3c11a6298b94b0beef362966e3236506dce31cb5e4be9cdd012439ba9e9cf079d67d7659743c8f425caedc18ae481ba6b7e85b08bf7408741ac296bf6a8260820d37036de1c20a2487bbc99e9356d3f4b9cebe8650bd7d7cf3805c138e769b9f3f9985827edbbe3aaaf90f547526cfae64851554b803a6c4f800b8f17b78b5bdf6081ea031cac75698935dff010a3c68c59e7e22f8a3dc18e4b571e374f25000c84bf846c5d07a574ba862e163c2cd2a44a48a0a8b3614f6d66d98de9c87bf759f6b71287d24401e86384a1d91479870b85107510a943d1a43ca5dbc96b11434d8c368fa3a4d3f4683b25eb3c056b01e4dce94afc7d97584a48d969a385415e74cfc1e3caeffb0fccfc17aea69f6f063857e2e2340caba893218b1afd3652123d9ee1cbe98e2975f3c9cb1468d051652c1c44d96231f21fbf0b1385cffe472310a11b938aa976b699830a7341e830e3682015d1ece8ee96a78ad9934642ef3fbe2ee4db9f1482fdb6dc31bed292aeeae494bc7c0b71e52b9fcae52ef5370cf3aa04779fe30a0b3d2770eae8f44a9f43eb15ef4f44f19379972883bf0bc0acd3fb157c41d5b6dbe58e7d5a0a7a687f30885b726deef2156493e4d984e8fce280358da0176ed98ac75c76a18b7c72a54c3ac20d2b377cab6a7254e33857c041cfa628487acdf52b2542c06412164d9e931a3a384d3ad778f8c3834f953342426e3bbbed635065944de820d2601d679d0f7da894217313fbb98673617a22336da4f592e3c3f3d245ff40aedbdd5cec5335028c97ba068aaf3df4e2fec93175e1adfbee8c008cf6c07b51366adfe85a4284ae288c0e25307499e3cf46335a64c137d9ced411b687946ec41067ff0026764e0a14da668c1fd9080c9a67923f298174748ec4128a6cbbddaebc32e0e43c8e0ad90ca5144e386e1378ec6b8d60f5220545258563bea4dcc24c8b880b853068edf1adf82987724f47f9b46f5fae70f5549818aa93e3856f8150f56bf8ad1b79cc3d858d1b3de1f7f152107b53bf3d49c2e15ead016b6ef3c4f662bc58f8b4377168a6bbd05e9f265bbe7cac9f557df3a7505873ba630d4732947f04a5fce26ab21b769ea1e2e992a4157cdfe53d7766d0d6da2fcf5756c9406ee878507e699f5a60eb8fa9adf6a9ea2b1a4303026c2a0eecd026083530761282f8ce93160f130ef77721ac03f142701acd69bb079398adc9b4513930c2eb010d41bb32c59ed579c4cc318a18101a0089ac27602610318392982cd194bd1ea35842b8d6a24369cc9ac7601e26177bfb0b4dcdc6155d1c57ae861b5af0e66d9fa3fdfa47ba282a0ab15c327151a5e7c8742b38f32e84031d5787dcfe3d7341489d7c3c2c89b80bbec3a2020afc268adb895e2898aafa6519cc16ed878a83f8b7ac982d634afc02fcf7f009932d8402c09adc281b36769cd78dd42c75e95697f4cf55192317774d7310c80b8ba8fb121d5f44e1c2d0cf344caf4d8722d49c53ba9ad5273aad9347d0cba8ed47bb0eeda00d3db74ce4e20ac42b07668c63feb94671c8404e516d3e4faa7018c02cf38985b4af7bc93ef03a47a28ae9263917994a51bd488da6a0ae440146958b8a5e7ce4bf2014c7c8dc2e250ce195dfa2dbd4d84f04ff75ac9a11af4384ea33a892140fc28094efc0fd6f09853829607699eaa83effe513c00e0c081db56586eaa00f11577e6bea0b99bd3d466151ddf42c519eae27c2c97ecc1f2c90852edd26a1c61e7bef94c55adc6b1b0a6f2a578f505d0f06aa9596e2b17455b2d5b6ec9bc345179ac273a936a9d0f7251d4237aa9efe45d676e9e5c6283c383a0268f73bc19fcfc07c055a355f18a1b46f321fbc3036f5b85f7b382adfebde689851cb6439418a7f06fdc092daf16a7cab69ec4e9e9277e8e30315f343d1a59202c02928ad8355d76f24ed8f83ef8d0e5fa1d693a52c9f288146d27c8a91510e9a756ad0a09b7d9ffd54ebd652fb69ba94734fcad0a3384662d8cd584974d90b8e05e0a974bbd989ba04f94789bf53108a83554c42bfb5bd43ef6df155f0df95f599f3bce288c7126f9f5642dcdaeea36a27f0c99de998cbba2b8f27fe5538738aac3779ec8acd85c2889d11fef7ae3dfd34babfc5798e4a23d21bda5619261d32abbbc99196ca48ff90d1ffd0f908f2e37b1ef9c77da399c706cada6bbf5b2af8b6d7e628e3914784a378318a223489227fab91b625f18430903705c82dc42dadb513ffe1e938389438d8b766691907f608ffe647d0628565d06e5fcc6bf26349bc3663756ccc3c2d66b4eb9fba93cda712ca89741475808e9f0483f3841c3b10160653eb24454756a56c99615894178bf57cf72aa454d85e5d26c5959aa51e9bf1aa1fa18b0a14d63519566335ae463b362049b9b69d91d16d8771ed81b3042e963ac4df07a7f2af857459f6c2d3878df0f0090db847f0b4af3d652fd88efb5b07cefd04167088eb36eb99a36ad1ffdebb535b41bbd9cc2b009c776577c5406bf3f989f02745541e5cedb67982a37d6cb0a9eb5d64c42a9b159836f1faaf43188487f91afa95707635a85110dcb0e5da559004a9ce7ee174dc3c12a439731caae7c908ef5197a9ab263ffbb3ed82f6c83e6c5abce2aecb69466833a75c2613bc0d889449f90fb64b01d8405f45cea75c622c10d8ce68c4cbf41a2d8c52316bf231ddcd21785406831cdf9e76ba2907c9e97469631975c383d532b2cae58598864903a12589264b3d984459c5a9774e58ee8745c42d107502213722b8b73b259d9acaf42f638c092a2030deceaae170efe7d49124048094c7d4ac422aee457b50f98e627585364a622a212f463336cddf576c264a8cdc1564bdf96dd80a7e394ed5078bdbbff3f31d57df61765b8c380698af37a9c8737f011ba17155f6be0f480f959cb7c93a28281625157cd1a497a6613019118532054222de5f6e88f9f7a43243537976b8835d6af22bb76febe8a17a0a1697e948a943d7a479bb8b418384e12a988ce3048c181c4b615bfcf1534774b72b5e4a5d5abdb70ba886f6f6832e61ceb13ff782b86ec1d898770065ae3f34b5e0e8e310a5ecb453b6ff10c54b5bfe425ec3ce32e1753a80344a592212351f3a1e451a9496b329fde2e5159e4d1157acd6a64efe82d29196304ed936180a298d0ab3ec2250dbd6d971ffb385729f39bc9abf29812b16f24903d24e0f441106e4c7a14a1f4fd80eca1cc208cc83ab22b943c320eea776f88d73400b4d66b30c834cdc55dec60fe20811ae8a528d8bfed32d4fbfaaa4be25eb87a15b9ea154eff4bbcc70814b3e05708b7347965661be84dffd6f15995a684ac04b11dba36fc0a052dc8d48adbdc557b1b209abecb28f933f8f3de2000512e508e5701b40c86d367a519014045edc0d54a0f214cc4f06f534a1833de85237d556ad956eed413c8e977b62fb55d70db5e8cb5cefb7eea2e51957578effe010545fb71183cfdb7cba8472c1d51f9fa4797b11c2196d44ac65c5ab82353ab56201459d3455d568de966c216b8ef125adcf97b0b0a28ce48da3ecf5091864754133bba09d30f3b32ccd2a3b891b8e25872a933ceb8fd27aa4b1243e45898c2e7917796e993babaa033d7d1b42f978e0a8b4b19f33a856b9eb891413f45ae9db1e0a3fd5c420b5a25721e9da2c7f2f675c18d591af4b82358ad02eb565b825c59336c124bb19a7f698b944fa040f5a29d0cd7eb8b681e262e8dc5f44877a8922ba815f11d03abda390208cde96185300a88ff6b9a024418d6d729e38f7acb3a95db8c28d5ddaaee30c75300a8c4db6d499ee549b633255a03a6389ed1b3a89498a2462b0421bc55b240358962fd4e8d366524859bd8a1c20e67b99b724025ec769a2b6d198d37e907d39bd6983f2168f00680a004bb4158b19bef23b7ce4165393618ecbf273e70977d4609c7da4ea3568f64bf380663bd962bcdb68eb0e4a2fe395c8b988f1c60cdb28bd4c656526a75fb8fb59af07a1f918b61a7ce66af79bf0eb6a44a1daf03769530bb3a94925f2865bfe5c9e81d74f9588265e0d3e2f84f8544045b807fc176c04683a7b74fba937502a99645595e9b4ea857808405d510d0d93dbe3e71d6bf19dfbb4631de81eab040d10ab1cb73416b5e357004e2228251f29bc76ae050e0786f861b6d130efae75ec50b36f9f8c12c779d18ea47cb8a90d95f1abfd0a87c2827b2c53ad38a3699bc7d0efe54c7d6250733d524993a9fafec9c5f81f85ad62143fd5376068dc64906f74129cbcdcc0878f72180e9ead85f680b6ec208490ac5ea1092a1153e5de65ba297da2649b0dfc9852bed945a4e88624e4b195b811e48e9efeedfc5fd9082b3cf68ea26c2279bf95dddab45c775978d7a052b99296c1105db8b0f286ccdc79ac3f4f21ee07d545ecf51bbddcf880dda4ae2b9da03019951cd93e9e04a86022e9e5e35af2c2374c26d24e656525a698139531a5a4c51770733ef4feb30fce2c31f0ae143a07f78ecfc6691d913d4ba8d19a8f45abbb9d446a1e5381db266171e442e04f9b51ca06798aa60a6011e37b4debc4e4b99fad7f4f2607ea7c81f1e682592395a0ef42e393637b57d8c7cdd208979dcbb82210c80e0cd5ff5f488ed592239b37f6f4128fcd579f5ea010ed97b307d191cd756fd2a2afc5140477e5a1ccfec6722b6b7f349302c6840a3ce0933a189ccaee22da8d43b9f32de9e6911fbdac06fccff72b267d7d776b58a7a92e1b9419ae1a758c4cee6f880ec1d3a9aaf9804580beac406cd5749f9a0eb7d1d878bf82fd13ef7be589c209b5a49e4f06d2fb7df676412ea0c8431f136c09c405b8a843a5ae96a266340190f87528e3baff027617c9cc6fbdb2fcf8a2cec33c5853697d421423d07b7a92d6dc3ed2acb371a3385a03575189a9bcfb8ace519c342b52744cd8bb61b0d855eecc562c661dadd61a0d0aa06fd36dc868265fe7f3025ed792b506e842b3146b7281be245d7a1b027366a387a7dca2dfcd526df910b86ee0edcc157702274f69213536434e1f2dbf490fe9a641222a94e9eb572785e90712070eaf4694cefb9502bd7cf8830c003be1eeab267bf00eb8dcc294885e097e0e95ac9197a3426d7b25a922d5a67a0bdd7a53ddf3444e2f6c3aeadab2348f5b56f1c5c35d907365c8bf91f34d8a164d9497f6b085fb49c84943748d34579ebe0fa2320fa01eac544c2e4221b47bd02b178f159436e12c73b85640c9ae63f4b40862e321d832d2d1762de803402156495ff5a744daf2c70aed67facde49ef34291b24354b09e9fd85d4f2ddd0bce418b695fbff2b7ee463e747188a71251a41de4be3ee0ac669657df6d62a1ff0d170004ca2966ebd7c786ea7d370e315b4938029f97ba642f6dc655903c630de217e88eb926a6e21421e837925b07c5f650c5f0665a012c1db6297b3d9cb26e093a878bd2bf7140334f6d69694a9b85109a9d898ea2ab57f2994da3823e0b07a499c505a6887de30708d320867612d862ff7afa152d622d9beea8c5ec54382f11b56f6f57893299c27173b35a8cb1640ac5a72a5c354cb5ba6f32b0f1267eae1534585ac3c44867e349944373f04afaa3cc1a886f7758cfe60efc76fefae35fd3cb572aa573649581490b083e29f3fc54314a56a7871ac0680ff43248648a02d172f55eff96eee229c6f96930a4b34a1ffa9b040ce933df25b9f6b357a982bdcb17373cc4e2b8de60099caac9ee18795ac8d9c76023c287be149e9ce406a4a2931eb71873c0d114d8b800fd1cf567a1ce1ece93ee37f4556510278adeeae346ec70ccfa75bbf4c6cb65238035777312fb392816aa9baec33c0a76879da853f4a411befa58eaae3e6746b4ce8094bbd5af9b8f4c53e11853228151f636650f15563fa28463443a9f738431998aba42e2c90de80b2efa075421a477d564f4a88a1e0e6e133bf7808e6824be963c46036511a2841f83efa0eedcd2362da85e9f8f33088b146088ce7f940a3deda47e2fc232484a1f4aa541d8e6a0f573f81832cfaebf79091653f6773e2180b8ec3dd7238fc225d3069c9bdc174ee8fafad976084d9b5fa404a3d76f0234ef8fbcfd51707044ecd56c1eaa876f315d0c2d2dd5fc3fccd6a85cb8cd237ffea0925e3aabe14858fde4709c68ab8b024ada6a05db2788277e98ff5dd0916621bb32e4942dfc987220458f4f10a27875ee80628a419bffa3dd7ee2f733592d6b50d01865eaa8bafeede029a3bab33ccc24a9a2166148569930e517d63821139ef81d04ad489ab1a722d9033ce6608f9dc7de8c66f1b2cb80a9d8d297f0b70f18c52f12456754993a10e4fd85769bdf7cd04fca618b09609d469ad523e04cb8110a923ce17e112d06f69e73bd1319e0a79caf07a51d7bb82b0efc0b1df75ba6fb161e6011954de89935c439ebd909b584bd66879cda69d6d179090d7da35786900eed9f01cf1ad39104a7cedd9c8d446bd45af2b1f49a18bd3773e7603d8deb4d7075d47cdb42475ad5d2ac2dba741b5dac9c1fb0da08d82da1accf79854195e099c760a0ff44ffbb19787e5910dd4043b93f25a3076f30fdb0baf57853ae5c75f963df01ef67f588eaea2247776b095e1a68fe61144ca97588b21ef938d873a7b86f1c4547cb4e92fe3cc7776d87f208d9711dee0274557edfe3fb3f8dc283dfdada5081c706a455be647680bc84e3fca1a8d249de4022be33e9785dfbc4fae9856dff964b324e2fea2e18ee0e7d7ae092873b83ca2dbd3a62dd9d5f2dc185f557e67c957123ded8cf82483fa9f73f0c59d92a0e2031f4e8e6607065061ad13488d49bb035e9cb3d362b5f4e882d526e6f49f82862a916dba638a1e5b95090c6389390fab95c1324800f5080a458e275d843e4941cc9e4a062b43d08ca4e4894ab0321ab4f6b725ae31b274c31d92637335090b70820807ca7280d291c676a59f834ecb630d8f3fab797c19856f27c3424660101fd59586d528d5c2ead4fe0dbb1b8e48a2e9442ccc4ae15f343d9ae099117d1a4703e55af3ce8ca0aebf1970b6d105419e16f4ca7c650532d4baad23c59e09140374d967932230b988107133b0c392d4b9e426fff36ce1dcac70ad14bcb1495ae88ab2eecc521ed751cc1cdc94952ff1ee50ffab9ac42fcc3408a0fbd7f03054ec402cd4587d04e92c112615372523e16c28263c18bc1a8c60d4cb7ec1de510ab842663466dec8b8aba6c16df763d2a31f68a09fff1fff35a7bb1c0f32ce3efc74e59a5e1d96f8b5bd37631f957d099a5a02a62209a1c374c5f38c08e03dd1f3576687ca723b9a8bdcf2d73e879c3033435d141a5d1c912d48675014085214bce062718a3b95320f167a28e8168093ee513e5c076c03e254dd8541c6eddd3654820a8ce22ff3daa550218d31bdcea092c56424805fc421d177773f76a6541c4862f2546db75d8aee1c97d76e9fd7100c2299fb0e9025225004d59d7b23004e511438bd3a596c89f1892c3445028059eab261675daf9f320ba9569ca2e7d4b9f6fba6131516f06cf4e5b469146fb2901f57fd68850a9b8680ae74a5c1c8f8c0077d33b6514d37d0f975088186fdc5e5c2175c63f45ca4a5bb2a811a6753c13fb5ecf2ae239c0436a41103fd83d71540350715d5e2bbddeeea708725576313253116f63afcadc3fde836f93e98d6f77ef15ba95e174b64f7c1f9b521c8e54c2c1e6b2aa48fad7374a39c648d0c8b93f100265afe82086d3d87d82d2df3e4a43570988a298dbe8e888413cda30cfc6c3df1b8837ae237f71480502f3ce13908d110fdc1620321dac0f73d38a716335f4d07e19886bd168a12401f2e03b8e175d3b2dd2cb21a5d48e42d5bd63773e301e3edacd6d597744318359c9f68b048cfef26f7246914b0aeadeaeb54acdbc1f667f0963b52708a226623564694bf5b81ea9c14e4fdb6a550fd08e9b7ab6a52dfb9798f8faa9a0cb57cb220a0b2e67f7f160514e57112c59b85a157c651af8da86e136d21b258a1d9e364162aec72927f41a96812a4ed0ae743766a9e3a660b9af418b6e045879a034da9930e755993d93ab7dc00b9c81486581f58c6f59bab9feb766971f1a85b2194a527bdf4bf561ae5bfa3df4d7f73676745e9549b289012746aa0f29e67c721722a15c68976589b14a33804542f1ec61e3cf241edf8ed669099626cc3566ac2d9eeefa57ad0a331b89ed022caa3acb6742971941cd801407b4d91d50d93c67f84b1a0248a5dde6c50ec8508341e1f59abc3ef3797a19247a746216a79d50d3c9d3690b9277d26d5632d35ccdb3b786a07ed30b32e8b9a141ac8b9fd9877c432ba9ac210db680b0278d4a02fd201e7dc160184640584d7cee686ebb9a797a91a62733bbeb2a662f7e0f8ae060b5274868e95cc47ca639c55110c69d657dac2434bfb5baef249fa277db313ceff594f218995d984ccdf9a7aabeb778df2e48331e7f5afc2a648e0c6aae5d7799351a96970c8f66478751b86658c089c35138ababbd4874f5ea1fa301e67360c2ed0eeb557b85c6cf63e39e5f7d15fb2f387e4a4f49c67e31a97169e143c7a474eeee68cad76e1b3d8240fac1c0fdcc01f971e00577f33717ebe8d260168120ce44e0f929878fd94e2a840171307820d474cb0213f6887cdc375b7e55326d7347c7e479a251bb833e1681f5396e1f064c1d253010fab7dbaf5bf02775d15d0b6744ac77367285d98dcd1a2a510fcd8c9fc136ac8a8829577dd58e0f74da10875f260fe4aa4a50d2dba9bd4ff1bd240806999bb4af50c744f4495532904f63d3194a0c371893d155f92df1c71e09cb061d4a75d84839eac5304e343dc3a1e645168e060540300b7986e901aabfb950c106175692bdb069b396c5f89e24d865a593a95ea239d372cf63475e57d892b16e2127ec0731661ee916e6605a3fedf49b785c789b5060197f7c81a8df0b6e8edc4689d3201514339c94fb85d525bc05a2f10fe7bf525a419df88b6ef448602a790d3dc1aad30e96a39eb8b85febaf1ce9e6e6a876e3eb7cf6a983e241b15ca3831d118eb0331508ad20ed17f73e638451f7e739ab91c680a0a5b491706cfaef707c915997321562359917c4cd97727600a854ae4c26a5aaa3569febba0c51a5cfc179ccb79803fa06dad9d075ee3c9ac5f9734fe067b6d4bd163effcc3194c3ee91d15cee6fb7147957798a33ad30e7f7d76829ca3af233f86515fbf03d1ef1e1bf47777fe736ed8305c4d7735d7054ff1d132ca9941b6ee9e813bd21c9816c1aa080fce23527780fc8d30ee046156e362c9886f3fa11fdcdbad16dbbe574a9375f0c06db4c91e52b2a92ca830ce285f247cfc4d92f2896c4f5c4b39b57210de0a59fc1cbdef1944584ad2e411a2bf35a7b33c15c335011a874bab045503ba756535f90fafd929c2c8b9c8a02fc62f1e5c9c3d6cd016b5dbfd52ad1c4046bb23685055bda3f6d83a0661270218ec48998d72365b4b73e17d235d6314cb1240c114238424d5d3d21fd1c8ac7325ff168d17b3647b20cca89e035a99654c1eea3e420f5733f936f1365cc33f8ea1e1e84d40ea854cfc98fba435529c5825e6cb81c67353e17ac976bcd8bc7a3175147463a60ee3365474963e3ec92dc64727a9d7d0ace7a0b10b010abf726b702ad2e5a7e9707c5bd6a2f86383958e8ed1b9d2ec9ffa37525cb82b296a292bb76e4ad77f3a4d429a62bdefa3e2daa3e135251429b22d0827b7a1b04b755460488be79d479bc3a4c7c49ad4de0d1667f6dfd30e2789c7de6733ec2678f777353fbd37da20a7adbb12480c260526ab26cc39b88dd878b85ecae700cc9730a18bfd2d09430106b417e9fedcb25a138e836e212b98412866d80f3a2f21a8a7baa45278bc0cb56d697d5fb635c4d5a2fe32e29b4b6f481c6eac6e1cb0b51775603e74b8c443840edea4c3ce80bf65b3684eff6d0c77a271f4b39bd3f39f2b25be920de52f6aee95ceeeb69d3ae92eaf8f16e4c95291aaaa000135b5440a2ec27728cd88f78f02bd683a1fd03b13eecd62807f34790daafd6dd1766a4af72c2653873f16bc9fa50b4dda057c00d03fe8c6757ec6566e309a00e928bc15b4dfd338a3f5618a60e72e8cb340fef18e5f8ef67dc21a0b2ed4caa25be3ffde6a3eb56c6a7324d54a3f81fac83366b682ae4a09cc87ea4443cf01c411248a3885d40666e74be7ec4f02c364e70820583090428b5e7439d36dd3965b3edc079313d311c047eeff3b273976a7f1851bcbc20fa9ea06d3cf671ce8c84f4708a367c42a8802b07551ead7bae585b8a7f0a01ec3a327911480faf792fc02b159cd6bb366ed19509fe6712548fc7eaf7984844860c4b4e2b3f6bd2bdec95f1adb87af4a81c74b660b2b58f5aee55699d1e788c9ecf1ab73af9ed1c1d4041ed1913206d6bc2f9be050720ba2cbb2247c5871528968b49c02dc1d1e0a75018dd9e09a660e74395f183811cf9b9c455bab87dc9f9407d3023c168dea8380bce7724008dda76e2c9c78aa6718cef1f3de40fef59282ab539abf9f96759d778809c60e0feb971f0f04d1c770d4d14b8e60f9b00e065a2e98e3053685b598b0ae1181cf62e0ec019fdc0013f2abd396735384fe50647ec8661d75af65b9461154e94e9e148fee61842e866146676c749f8003622e85d3814760783842fff407b66491c9c417aa498a261b666a65b5a67b309635f17490612ac28c9c00f4c83094cac0e9fd69f62bc9f3a41f11f825ea56d809ea65af2140de3eb35fb075237cc3405c2635542b074e115371740f6305ca84af2413776a61b6bb1bb1a464cadd9fcf4fde061c731961c641c0454dfa87927eb188602b80f6ba29c221c720b13b6816364250cf8776228ee8f0cb2e09e474f4b6e2fd839bf68de048c9712ff347cbbd0796fc8a3e6d4da35d66565ba3e7c268da7ace701b54d4347ab034a28787339fdf8f6a1cba6a778cb5af104dbef9c87a1792b8f4cbf906b56ade719891e5433d103a36b7fb808c838b302ca3327e897cc842c8859703748f0917669f03321e814adae3af643d7ebaebd5ead3c3a58d300c1fe4a57c9b9a62597a701e96642550c80aec159c5e04b916ebd4e0f79f0627b52a8b23e5c2a2fbbf37b8143eacec069cb6a319e8d61dd3e35b81103fe2e599628166a661225f0b34cb1e21a51d7d81db6c97e162b6520a702aa5adb4604628d787757cd71599f20044a3e01b20b960210dedb72a7e494c61bdb4b9a972ee02961370a5de3484f76bf706ff8e1a56b6d0a663b6b7a44a42041039e657c5b5784e58a4002dc26ab973f1fc792c7062b6f940ad9d863cc58dab657c40cb3c2fa340648959ee3ebcb5e80232ec4048bfe7ba3a600d43547806b8b714c1ca4ef6b58dfb288421320dcdace9ff09f839d678b5d8ff2dc881e0f9030fddef33f1504d0344d9091174b324cbbb5101ee838e70b6a827231b1a92fd0e64f849d973f11d019e20aaee90ba5a00d52de19e87a5c24eb5cf3aaef59f54afcef2620c5e5a1773a4a28842fe67ce1e2ef0fe08c26d16a5c947ee58d485688488f00db7c234cfbbbb68229f7f4d471e1eb4cddb73de9c245f86968bcfb5b1606d4b38b6f80abf4b5a4de8075c78d2fa8f760e348681b7d9a25a7e2dfbe936768afc022f236fd87cfac43e455e6341b29fbba36eb6de657d1712ba5a4a08458593687272918f92a25a8173130a8028ace09956e0b687f289c8f7a948364112c3cc2c6650b2368ff42ec02ba4b7ee1516f1fc613786c9e9d2c57854dfd36900c1bf104dd2222f29a604924aa9b4859e0171678b73ea8d2a0f93aaa194663b980fa65ef04b46dd081c9ce8ac9273ffe7808926a0f159afbf1389390c2ae0ce7b13b631c5aea6e93e91fe7ffc92aa46dfc28ec10ee90635d93d93296019247f418e663422a6dcaac820374911487a7b57cf35e272076dc41eb4aefd3b2900803274de0412c2a0bf25da61a43745c1ecc5580bdcbb34042eccd59a2ce0c63204ddcbb78b6cd284877485c8203e26c229ba71cbe848c83762c6b793ba325294282706054af0d65dbae4fa4ad97fd323e0f6dd8d1f9aa78e9b6ca0c5489aa9af2c340e3535023cb4ea9ac1dcac9c3f043af025c697a2575a817577fef3d8529c04ee3de587fa681beddb6f820de8467a52dc2836d2c0d78b1c340e33db87de50c8ae92f22c34e98509b774bd82679a99f821380225c99aac9a42ba998452c751a02505d15a8ef89f5c1d6361007e9f0c93e13e3956a6162a9528bd0e31ab7dfa1c30a50525ed6907fadeaa16c760cd21b4b0ef3a92ff7f42775e1b430b64bbdeacf2475b19b719203140a23a2a22c039fc507a40a547fd003f88a8c5b5f16d13883b1b8e8b656b7f340bae61bae06d139b21dfe8bc4cd67d2e5e29e9cbb7c2ecf1aa251ae44ecc75eaadca6e5d48474406d60d3902e0beb1ecd1a304c8446d940bb62f337caaa74de66bcd3014baeba99d84a325868702d16feea240b5bcdea5088c8743919cfe84de735e244d70c4fe07467d401ce780402e5593e37507ad2e6df1cdcf42f3c608c76b5473b9af28543425492aafca407072dcd128ba0b3ce0e6e75568650d26d51bd17085880b3ddaaaf6e99c1a8f89c136686cd1d8def63ff5bca6e0b67b576da8e82aa85ad68f585293f5a32e1dc1109094a5ccb23f9c11a802027ed4596e96185ed5c4e7d3693bad8276ca119980000000\";\n        uint256 len = image_.length + 1;\n        require(len <= 24576, \"image too big\");\n        bytes memory code = abi.encodePacked(hex\"61\", uint16(len), hex\"80600c6000396000f300\", image_);\n        address a;\n        assembly {\n            a := create(0, add(code, 32), mload(code))\n        }\n        require(a != address(0), \"image store failed\");\n        IMAGE = a;\n        _setDefaultRoyalty(initialOwner, 500); // 5%\n    }\n\n    /// @notice How many of `qty` mints would be free for this wallet right now.\n    function freeFor(address wallet, uint256 qty) public view returns (uint256 n) {\n        uint256 w = FREE_PER_WALLET - freeUsed[wallet];\n        uint256 p = FREE_SUPPLY - freeClaimed;\n        n = w < p ? w : p;\n        if (qty < n) n = qty;\n    }\n\n    /// @notice Free mints this wallet still has (limited by the remaining free pool).\n    function freeLeft(address wallet) external view returns (uint256) {\n        return freeFor(wallet, FREE_PER_WALLET);\n    }\n\n    /// @notice Exact BNB (wei) a wallet must send to mint qty.\n    function quote(address wallet, uint256 qty) public view returns (uint256) {\n        return (qty - freeFor(wallet, qty)) * PRICE;\n    }\n\n    function mint(uint256 qty) external payable {\n        if (msg.sender != tx.origin) revert OnlyWallets();\n        if (!mintOpen) revert MintClosed();\n        if (qty == 0) revert BadQuantity();\n        if (totalSupply + qty > MAX_SUPPLY) revert SoldOut();\n        if (mintedBy[msg.sender] + qty > MAX_PER_WALLET) revert WalletLimit();\n        string memory handle;\n        try AGENT_ID.handleOf(msg.sender) returns (string memory h) {\n            handle = h;\n        } catch {\n            revert NoAgentId();\n        }\n        if (bytes(handle).length == 0) revert NoAgentId();\n        uint256 free = freeFor(msg.sender, qty);\n        if (msg.value != (qty - free) * PRICE) revert WrongPayment();\n\n        if (free > 0) {\n            freeUsed[msg.sender] += free;\n            freeClaimed += free;\n        }\n        mintedBy[msg.sender] += qty;\n        for (uint256 i; i < qty; ++i) {\n            uint256 id = ++totalSupply;\n            _mint(msg.sender, id);\n            emit Launched(msg.sender, id, handle);\n        }\n    }\n\n    // ---------------- on-chain art ----------------\n\n    function _seed(uint256 id) internal pure returns (uint256) {\n        return uint256(keccak256(abi.encodePacked(\"Swarmwraith\", id)));\n    }\n\n    function _r(uint256 s, uint256 i) internal pure returns (uint256) {\n        return uint256(keccak256(abi.encodePacked(s, i)));\n    }\n\n    /// @dev HSL (h 0-359, s and l 0-100) to an rgb() string, which every SVG renderer reads.\n    function _hsl(uint256 h, uint256 s, uint256 l) internal pure returns (string memory) {\n        h %= 360;\n        int256 c = (100 - _abs(int256(2 * l) - 100)) * int256(s) * 255 / 10000;\n        int256 x = c * (60 - _abs(int256(h % 120) - 60)) / 60;\n        int256 m = int256(l) * 255 / 100 - c / 2;\n        int256 r; int256 g; int256 b;\n        if (h < 60) (r, g, b) = (c, x, 0);\n        else if (h < 120) (r, g, b) = (x, c, 0);\n        else if (h < 180) (r, g, b) = (0, c, x);\n        else if (h < 240) (r, g, b) = (0, x, c);\n        else if (h < 300) (r, g, b) = (x, 0, c);\n        else (r, g, b) = (c, 0, x);\n        return string.concat(\"rgb(\", _u(r + m), \",\", _u(g + m), \",\", _u(b + m), \")\");\n    }\n\n    function _abs(int256 v) internal pure returns (int256) {\n        return v < 0 ? -v : v;\n    }\n\n    function _u(int256 v) internal pure returns (string memory) {\n        if (v < 0) v = 0;\n        if (v > 255) v = 255;\n        return uint256(v).toString();\n    }\n\n    function _pick(string[4] memory names, uint256 r) internal pure returns (string memory) {\n        return names[r % 4];\n    }\n\n    function _T1() internal pure returns (string[4] memory) {\n        return [\"Wisp swarm ghost\", \"Wisp swarm ghost\", \"Wisp swarm ghost\", \"Wisp swarm ghost\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Tiny witch hat\", \"Tiny witch hat\", \"Tiny witch hat\", \"Tiny witch hat\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Orange rim light\", \"Orange rim light\", \"Orange rim light\", \"Orange rim light\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Misty purple night\", \"Misty purple night\", \"Misty purple night\", \"Misty purple night\"];\n    }\n\n\n    /// @notice Raw artwork bytes read from the IMAGE data contract.\n    function _img() internal view returns (bytes memory b) {\n        address a = IMAGE;\n        uint256 n = a.code.length - 1;\n        b = new bytes(n);\n        assembly {\n            extcodecopy(a, add(b, 32), 1, n)\n        }\n    }\n\n    function _svg(uint256) internal view returns (string memory) {\n        return string.concat('<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 400 400\"><image width=\"400\" height=\"400\" href=\"data:image/webp;base64,', Base64.encode(_img()), '\"/></svg>');\n    }\n\n    function _attributes(uint256 s) internal pure returns (string memory) {\n        return string.concat(\n            '[{\"trait_type\":\"Character\",\"value\":\"', _pick(_T1(), s), '\"},',\n            '{\"trait_type\":\"Outfit\",\"value\":\"', _pick(_T2(), s >> 8), '\"},',\n            '{\"trait_type\":\"Light\",\"value\":\"', _pick(_T3(), s >> 16), '\"},',\n            '{\"trait_type\":\"Background\",\"value\":\"', _pick(_T4(), s >> 80), '\"}]'\n        );\n    }\n\n    /// @notice The token's SVG image.\n    function image(uint256 id) public view returns (string memory) {\n        _requireOwned(id);\n        return _svg(_seed(id));\n    }\n\n    function tokenURI(uint256 id) public view override returns (string memory) {\n        _requireOwned(id);\n        uint256 s = _seed(id);\n        string memory json = string.concat(\n            '{\"name\":\"Swarmwraith #', id.toString(),\n            '\",\"description\":\"Swarmwraith is 500 Friendly little ghost made of a swarm of glowing orange wisps with a tiny witch hat in a misty purple Halloween night with candles. Art generated fully on-chain on BNB Chain. Minted by .ai Agent ID holders.\",',\n            '\"image\":\"data:image/svg+xml;base64,', Base64.encode(bytes(_svg(s))),\n            '\",\"attributes\":', _attributes(s), '}'\n        );\n        return string.concat(\"data:application/json;base64,\", Base64.encode(bytes(json)));\n    }\n\n    /// @notice Collection-level metadata for marketplaces.\n    function contractURI() external pure returns (string memory) {\n        string memory json = string.concat(\n            '{\"name\":\"Swarmwraith\",\"description\":\"Swarmwraith is 500 Friendly little ghost made of a swarm of glowing orange wisps with a tiny witch hat in a misty purple Halloween night with candles. Art generated fully on-chain on BNB Chain. Mint is gated to .ai Agent ID holders.\",',\n            '\"seller_fee_basis_points\":500}'\n        );\n        return string.concat(\"data:application/json;base64,\", Base64.encode(bytes(json)));\n    }\n\n    // ---------------- owner ----------------\n\n    function setMintOpen(bool open) external onlyOwner {\n        mintOpen = open;\n    }\n\n    function setRoyalty(address receiver, uint96 feeBps) external onlyOwner {\n        _setDefaultRoyalty(receiver, feeBps);\n    }\n\n    function withdraw() external onlyOwner {\n        (bool ok,) = owner().call{value: address(this).balance}(\"\");\n        if (!ok) revert WithdrawFailed();\n    }\n\n    function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC2981) returns (bool) {\n        return super.supportsInterface(interfaceId);\n    }\n}"}},"abi":[{"type":"constructor","inputs":[{"name":"initialOwner","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"name":"BadQuantity","type":"error","inputs":[]},{"name":"ERC2981InvalidDefaultRoyalty","type":"error","inputs":[{"name":"numerator","type":"uint256","internalType":"uint256"},{"name":"denominator","type":"uint256","internalType":"uint256"}]},{"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error","inputs":[{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC2981InvalidTokenRoyalty","type":"error","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"numerator","type":"uint256","internalType":"uint256"},{"name":"denominator","type":"uint256","internalType":"uint256"}]},{"name":"ERC2981InvalidTokenRoyaltyReceiver","type":"error","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC721IncorrectOwner","type":"error","inputs":[{"name":"sender","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"owner","type":"address","internalType":"address"}]},{"name":"ERC721InsufficientApproval","type":"error","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}]},{"name":"ERC721InvalidApprover","type":"error","inputs":[{"name":"approver","type":"address","internalType":"address"}]},{"name":"ERC721InvalidOperator","type":"error","inputs":[{"name":"operator","type":"address","internalType":"address"}]},{"name":"ERC721InvalidOwner","type":"error","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"name":"ERC721InvalidReceiver","type":"error","inputs":[{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC721InvalidSender","type":"error","inputs":[{"name":"sender","type":"address","internalType":"address"}]},{"name":"ERC721NonexistentToken","type":"error","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}]},{"name":"MintClosed","type":"error","inputs":[]},{"name":"NoAgentId","type":"error","inputs":[]},{"name":"OnlyWallets","type":"error","inputs":[]},{"name":"OwnableInvalidOwner","type":"error","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"name":"OwnableUnauthorizedAccount","type":"error","inputs":[{"name":"account","type":"address","internalType":"address"}]},{"name":"SoldOut","type":"error","inputs":[]},{"name":"WalletLimit","type":"error","inputs":[]},{"name":"WithdrawFailed","type":"error","inputs":[]},{"name":"WrongPayment","type":"error","inputs":[]},{"name":"Approval","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"ApprovalForAll","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"Launched","type":"event","inputs":[{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"agent","type":"string","indexed":false,"internalType":"string"}],"anonymous":false},{"name":"OwnershipTransferred","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"Transfer","type":"event","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"AGENT_ID","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IAgentIdRegistry"}],"stateMutability":"view"},{"name":"FREE_PER_WALLET","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"FREE_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"IMAGE","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"MAX_PER_WALLET","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"PRICE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"approve","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"balanceOf","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"contractURI","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"pure"},{"name":"freeClaimed","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeFor","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"},{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"n","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeLeft","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeUsed","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getApproved","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"image","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"isApprovedForAll","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"mintOpen","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"mintedBy","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"name","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"ownerOf","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"quote","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"},{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"royaltyInfo","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"salePrice","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"safeTransferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"safeTransferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setApprovalForAll","type":"function","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"approved","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setMintOpen","type":"function","inputs":[{"name":"open","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setRoyalty","type":"function","inputs":[{"name":"receiver","type":"address","internalType":"address"},{"name":"feeBps","type":"uint96","internalType":"uint96"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"supportsInterface","type":"function","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"symbol","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"tokenURI","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"totalSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"withdraw","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"matchId":"58371191","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-04T13:48:43Z","match":"exact_match","chainId":"56","address":"0xB56c1B63D2b51573Cd1A2ad1BDE096526f89632F"}