{"sources":{"Lynxeon.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: Lynxeon.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Lynxeon - 1881 Cyber lynx girl with glowing circuit freckles and chrome ear implants in a neon city for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 1504 free pool lasts (gas only).\n/// Every other mint costs 0.00005 BNB. Max 50 per wallet, 1881 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 Lynxeon is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 1881;\n    uint256 public constant FREE_SUPPLY = 1504;\n    uint256 public constant FREE_PER_WALLET = 1;\n    uint256 public constant MAX_PER_WALLET = 50;\n    uint256 public constant PRICE = 0.00005 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(\"Lynxeon\", \"LYNXEON\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"524946460c340000574542505650382000340000b01d019d012a900190013ec15aa44e27a5333528174b12a018094dd2b3e56a3976c8d2ac1a06bced05679b3e135db66dd122d19fd5f3dfeba768a4ebc30912dbcbd507f71f48af4d3ea47fea742d7a5cfea7ea01fd57d277d623fb97fe1f620f3a6f586fef7840ddc77aff8697654eed7f72e30f8d6fb2358f90cf1de91ae617cdbdf359db52577dbd0150edeb4fb4beba18b7f78eefc3ff2d636b6a06e25b0a610b38ab96bd4da5d785a15ae22279b9d96b5df2dc5d330e9cb0b7e3678b3e1854c1cb535dbad9c056532ac9dd6e4204a9a4ed99ac67b481d6c5b334feddc7f3716fbb2005e86950015d0daa0c07238eb2567c1e5efbfb4c9ad33dedfd6bf216bd9533c5ca05d48db680029cef0aac8287b9282dd3eb2c772ae2cd498b5d8fca1989eb050b2fe34c87550ce31dd07e9f1436f5fe6b023be56382adab600e2c22727e48aa8392b26e0806aae700a328bd0edb7685607bae124154b49a05a812ae2d7609696c5982ad8d17f98d8b4ed7171ea176046805634e255e7efa6d08c2c224d4723eca109f454d7568649976f8a1c3dcca722825eea50dcc06037252ed848b1277e5f76be93b8f5cb693579ef5f7bd81330ff5baad6807efdcaa9d7ada4682b214e7d7989b8df5c148fcccf6983ee0d5271a4c05f2c23672e98286c66cf1ff3b16caf53502074ae2b5712a1aac5be771452e8ecac584ae7093346d1e1254a59c2c16740923131b8310847321d9ea4be19398f6869db78ccd2a8d3baf6a5f1f24b0e85d5030d4982dafd54c4b477c5657e9f936ef60b8dfe31adf5d935652327c7ebe12222328d5728718ac95696e0ee049c1aa60b94499facf7d9c554349f236b066d1e432f3ad6a60394257393f5868c3f522d51ba20d9b3f396ccbeec63c843e70783cb9c7d7780bc627c290e34c07be85926dc13e8e44b7e23bd35744d36287fa7cd6328a3ba2d39de065d7cb58d3df4c0351d2e64d809bb44615d1ae56aaceeacb4a5d4b531741945f4988e37674d1215fa122ba93ce79c9ec5778f65bfe2a66c4152e62b61586f8df68e9608cb672c7ef459c32ae65a72cd3cf0f8d1d43d6ee2051607faeb552aebc2f867e8b271e70e156cbb5382857605ff8efe2656dd591521f3796d889d812b8703a6cc1f381d923bc38b10c9d5f78c27a4c5f0d1c4d5e3906d3e3f3e88e386eb3bbac846403371c1299bcb51dea9f5405d37e0f78a4d2ce7c73da786fafc51aea320ec9cbff446b357c1943dd0fbebafcd1be72040ead19d5e963765e7ea25e90a21123e10234a689e8aca026f8a82c7c1588055f45f73fc7c6d9b2cf2529e0203a3df05f8f1dff3d54201ff30febb19ab510239f165374ff8fb77a6fd1aebac92434546d4419980335c2887b661af3cfeb826d047d954af6da5fbaa0401f60b3d0eb35beae295fcb719ceabc4ecb9263e69fc88c5dd66dcb22c6ada8f9f1dc7c079533a5760dee98f6846a0f0d81365542d06d2a3cf69495a3ccc7025c2b9c3a9fc068dc671dc6d93ed6adcf61fad6a8f6c74e70227d4079d5330a85b74b74d472c2aeacfc455f1a414808a2c1166dfa2bff342cb9944550f40123343ac2810e66ae02d299b6d7ddf62c3d0a76980311926ecffefbed39af610beb78d5003c83e7b4c67e437e072a4cc09d7c18f3279793b58445121636cd29fa9d518d271abe5ab08955aa6ab2e6c06e44467a04591a4feb0383c2384a049aa57e8bd92fea2f2561f410edea33d3d49db9e7d8001f89ec896e3bf56318f8e750f3eab94c29ea47c68ab693ee38839d11b804c28c64b6cd5e72af8a6e8111dda6fd2da3eb6d103db35137e1f906de60ae5e23b7b2f2cbe1795693ff47273498820c457c79191bab153b54d04b03f3c3aa3a57c759f7d345d81e7c507e24da66590cc0713e6c4fffc64057c3d0dea165e3c24115f3b82c900d5a6b4052bb84bff1d42605ef4b748a26d415a5cce6e64cddd63c87e0662b87ebe56f70e998d483e86cf043f714bcebfa74c096f2b10854e3bdb9f6f0a6f425d513633ce770f22e32ad359994f1c2d163a2f14880f0bd70f74da826d0ac01d90eb7b2ad1f9a8123ccca9ebb3a2bb8180bf3948e9afb74740fbd1a5eed7df3decfcaad6d52e0b9bba14ef5064a0f217ae888e345fb6ea288b520a37d9e14a1480de11c666dc1e471d49e9424e452ef60bc55197bf7663388627e8e3c53b48f7f45ef06432887c0a36a2bbf5175755ce221463e63eac830f4b8530d1d7a2ba4495eef9f514b8a6d820701ebfb1753e8a359c21051bc4fdd8e665e4ac0c158bacde9ae6dc5bcc1ea36a95d08825c81e28c08670b0f65d35258a93018eb7879e7dcac2422e19d67f3c3eab1c48c67697f17fdb79ef3f48d817bad5b244383baf1080583960d6bff00b4f0c5c8b01a28b56cc728877e3cc50dbc214ca61da9da91ba276bf9034afe6d568963771e00218a193feb2e8ba73df6997c0ba7d979c8ca2f6d3cae57387cc1a29648c277e8a01b1355e11d15764938de76dedaf00b20ae4624945ad764d9eeba75d9c1da4423867622d9252cfa5c744edc3b51446d62c65317e697d6e42a52241ae65016cefb78f64774f81e1b47082d3a8dd2fede154b0bb40539b18db49be3125544bf60582360953ea509d850c5fb29a29a6a1f242a9879d090339b228683896687e275a80f71658df056e6ef8041a085075c2ec38f5ec1074616e0c0ec6893141576a61a762ad0dd1ca6da3293d8ef43c136b534853bc72314bcead653b23e83336b1d3ef68267f6ee9ba3ea430d5975bb82c065ad053d3cad04c3b07a4cd269254ed93927a3cf7f9ea266e8e403f57f29632acf3f407e8be3b2367af20870eb77d5b80d1cde83ba313856ae104b17c3149b75d8dc9af097229b645a98c80766d2f78d4abc3073b6838a0cc34cb38290a85a82210687d94044be4de977bc39c78439834a7508971c7f64cab87759f23366550515e32eaac57bb5039032fe52d024f6e3eaabdb874fc17c7dddb69805f32f2a83a412d08fb8080c8e7b08e5763c9568759ce7a729387a0ff75427a1d5cbe3ef0732e0e2dfdf9a1bb7135f362706fed703612ffa6e02bf2f697d82b0c2de61d9289805a582a8ad56f6fba695374f9f3a1c44d8440e72b8c1c48b01111fa4d24403e82a2116d9f3492c464cf74514687ecf35acd19d68af7697a090fcbba3305bcab1a0a0aacba414545b6a217b193575673d6f34ee36659c63c23800fefa7ce3eb9d4447497077265872b7ab8c39ad151a1571e0620b23e33868ec8db1ff67c98b3a24e9e82d5e5fee3c59ae7f6219ee014ebd18ac76a49ade0ee87a8675b377c9b93480b836eac5aef1490ab2499864a1cdb5a4f078b9514d534af2a293d2f752c1cac67625f551ed5410baba2e52594426759a48ee3c6d83fb689bc043fa4e0cfbe8bf6d6e511db6f1c48713a8eb735a2d429c7f8b5c7e06a1a0297fc5314d67b70dd6cd711b3fb7f6663df5f215afc46518a275040700536efe9866445c73a3fcd36bb76d70807862e7a9c907e25bdd33b8f23a9eb7c01e01d54ca1144d09faf817789aee47bd66342917068d22423cab944dcc0a52041a296d394e1253968a06206d72bf5c8fe00a74ce4f52c1c66594d085fa17d35a870d6ea21cc905073ca99e215a896c45cba2b147253e72def5c7d94dfcb861e3c92863d4a687ec6eab94c6862f81f61704d4c06ae4576fa44cbba225f7109b74dad76bebf2bc935840941e49193d0abaab2345ebb8f42f2e98fcbef418226d77ae05de66a9565d1ad83563ec6cabd2634a752d795321178585dfe09d1972166de0e250270caf49fc025f86debb1a2ad885f6afe08446633c3e71a9251b52bf085df0c588d93a5c19a7e633baf892bde14d5e269c2d0e0dfdba0e08566ad078e2de62f2ce8cc06595f1455e14bb277b38b71d849eabcb74044666500226a323d8d3b6d59fec00100f29a45fff0c869e1fe3d16ee1064dd4f22d47ec39b8bd26e49de806ac75f16918de3cbd65b2599ce2f30ad2deda9ee26971a954800103dcdb998b41415128746c4abba524e1159db360d4dc9110d9b8572b6e071cb90ed304dcf19572c20bd19de05097dd28b11a4ed138942a79d98b6d4e15f8d4bb27ba41e4945452723527a1984f2e028f1b5bc43164e1daefb8509597ab05564df15c3bbbd99ee0006ed7b24f7a865d37ab371e81b56e9262887a16a5beb3cf4e7953b575aaf67b6f05585f56ea3137b8915960fea639afc70e7f062cfd5af6d1c9895a5f9d9ef167f6df8233c8e76b2ef76bd66726b18cd885b3884031f21f00e59d735f0909d32e2a3ac8a47c1ba4d989535a2c1dd9b6d397d43fa5b88a043baa963eded87f2e91ec0d75470b46dcbd50245f4023d03bb781af235338d5553b942b379c6e1b92bf5d89e3388d08468a1bf00d8376e740ac815d3e34c54ee767935b3a49d2f0e2fabe848ad49d9f383d8ccc39fddec280e910940d99cdc23e507da917916b96848b74b806fc996b3e04f2284f041709e890c4f54537257653b0ade3be62e985be82b907d83d750d73935227f24afdfab826373b0c94376ad1163f38429183090ca799bb3aaebd81d96e14d1953734b4f031465c6d4281d408c7a0369e897c878c3900ad8e2514ab7d86c1a962356572da5a8279189f9dd875fb1157628d92ecd2c785008d1bfebf82ca911bc668477455e80268d23eb9b46444278874a3b54adcfd3e1c4acfeb760f904a6caee91872e1a7c0e94ce1b57a182ffa130bc981bb3baabcf419c18476bdbaead855c487f5793bdfa871ca8bc5195d3a3d590e5457cb4f63103b29b03bf83b217e8fe1635b32037a808b732f2aa97c69c6f4793c6065bc6a6867b1982f5e7623f3fe60b24d5f8d4446681594a7d7209ef04e5abf33ccb45c58e91452c8ff11d8d46052c5847b4b2dda3017f56ea0b80883873d45d7a61a41400df3cd8925f66ae7ad0f46b9000b3956e03fe9c3081b2d121c344b86533446a44ef9315cc750f7a7823dbabc2bc44b41f15fb19658dad8be6b9b6f52726231edd3f39c4d180e72135241dc5b28595b2ccb0d1ef1d360996495f8bff7a14650d20e19f66e3c98e3ad5913c4e0709f6759c3c0d36aa84d5c2f3ec95982b43161bd33271f5f8316d109df7ba077f4f125ce6d2877f9781c71f0da8632e317b318892021e5344a025fbea27a85a4bb067e9b57fcc0ff23856df035da3ab278ecd52d9859e6f0d95de216f5b45c8144820d8afcc8ad2a6b1b4d38d2d3e7bbd83bf059b506c5079e4036c562e05674a4cfff44765bb9db3f394d9a780842dc1410f7f3241abc7a6ccee6013af65596f556bce424b0ca6c9c7ad027c80ca92016a4c2736dae19ec900928f05bd4af8d47c358d827228f7ff61f98d24e032c10cd22144d2782b95832d20aa4183ca0eef56763260aa952841b81946ea6242d759399d9ad4c3e9f34855d3d3eb771b068d78c44dbf9d181342695ab13512d29a5353f29648ab46458b4af17b7ea486d8a66e96b687e9b44f217ce9b881767978e0f82698578b7befa80c1365124724ef9689779c9e5441861b427a00fb083c4da9478a7897561710e2c400281e606d6b1084d2b83ce84816d885a46d98a271be3f1df6d7e30261d13e097cd91ea0e81539c9546d86fecbeb3d5936983ad62750f040ea07ea87d8d6a7891f59da8dd86c7e2989d35fbec219b77c17ae4bd54b322c2f85182d0ff969352d535908a0b52257adc9af0fb0f3d31165a1d79a30111a0d4180fac8e222a59aa5f676845157ccebdf6b8df498e81c91fca919e0c104c56d29fbd9dbdfa705e30afbd2bd6418e6e80773a736c3182b554fa0b693fd2c69e268e256b70a129608b97bd776d90db11279c3cc76b26935e3ab7b1c9265a6f1dff6aab8b929f448ad43fa10430ef3d570504c49ad8bb6a060333e36e069355d0f35cf7f357bc29605b50f503b67b102f55dc1e8ba077ecbd961c23d837109060454bce619ec837364882f92788b74d0f773efdcf28568279adaa30d2f02879e0bb15879fcd9ed392f625115b975fc78c491baf15ddf1317ea3196d555c1ebee741a5cd2b37321b5f03adb17cff01f068efeb8d4b2b46218b7630cc8e73f35ffc69abaa2de0ba19a91776cb96aa4dd3d45e958ede4a4099dc1d8a8c2905b50619ce77ce0df9242fcd4f17750d2232b29312e0aa5c0ced8d14ebd9b38d0cbedebf570f7a2bcfa24434176c8d2c7480ee42a7cf02b0c127c97d848b4fdb21a37e937df3bc7dfb254a803d13de1e5f14ea6aed8aec48b26c922138529d17b069abdd9e58c87cae3b80003b99d7b6732b13b310e020078e242422afa4f06b4e1e5eea0de7539f4bc1c75aa9f0dab262116244146a11b69d41961a5e7b1fefb66b59a7a60d3e634d8b78a2cbc2692214a764addc4e18c7c60433fc885ac8fee1d9ec7d33adcc4b19f65cfe6aeecfd77220f945e7cace25e1f376fa61af9ce2ebde218d5a976a00f6b98b8c615fc3de4a2ac27eef4ed62a81fa58e6d1e82167c03010d044f5873cab19fc8149919015a44086009ab4d310abef0e5916ff8aa71f09c2952a7ab8a88cfe80858a3fbcfb3a62aca5f30d928025e4e84e8d732f40c224beabc7eec33cc73f48be6e644f27c184c455faec5e9ed99310858c581b90e5ec4d4e64a2765f11c438941699beb2664983a4bf423d0d78f3517c643d4b6e24a70c66212dd923e1ef52a807688678f0bf8a0d985d95346006781b3e38cb8e70f20520234d65785a3504d67c348206bb4f3361a81ed1b84b59a524fcdf2926e15e620198f2da2dc68b79245662b8cf026a6fa199ec4c7cfeed278b461e167219174ad54eda7feac9543e9efa4fc84eecfa5a0c27fb269edb56e89fbaa0de0b2497954bd5df8831cad74904fa6712b1ca8ed888462cd0dcb0227b63ae3d29bce8e79f7293f71963a09332e9b59cd821d0c41b4bd4f21f419ad1db337bfd1e9e16c0b44f0943228880763339d81e162ce930abcd70b06255b8404d88fa2eae041c87c66fcbc7dd5ae236556aec6dfc06417745b26d2c2cd75774bb18f73a336fec170bbe8f47eab6067ea43bc1f14c4feb93071276092f302e21bbaa6a1267f18ccb7a1c4d792d494c99a2160338119997c4fba8dfd6aa88e746ddd4102c3bdbbb48a0c641e68862f0bbdfa89ada7659ad712153bba3f5631df15200f90b725c2959659c379739424de3f87c81a7de2c978b39b4d1fecd94f68ad565b37de4a10724217f366d1d849a2b0a66b4d961d02b593281086c56815e1d48752f04744e6f154ca9c492f48d6d2a7156f7368e82bd11cf2a65df97528b6300dcf973a7d5ec53ff3b7aff3e20af34ace8add140234cbd13d191a67ce89381523b673403557ba06999fb171310760ee7859d7831a7f2dced1bdff81c7f7af78cb7861afb735dda5e5b337fa051eee063db22229c115b38ca0dd51c772d81992b7f7aa5bbd3d233efe66c68059dc651d81065a4524d4218b6cb041e1fef7bb0b68d004bd55e7787ea6c4a4a29fb32a932846068d86d5220057bcd3d179172dcf8d5280162d4ec8ba187099db7817af8c6e02e45dc838247a54c1970dabf6105764768fc8e349ee5c07800de08a8ddcc8f1ff18588a5d27f19d965ed7d48383623e5c5661e51b0daa80dbcb0e4b0352f0413dd32f7329d16d5a1728336e9d7a12d30a341dc0781fabec0f1ab2e9c3cb7384d382e8455f7f8a37f189736b8dc0e9c9631491526a4a61d5f73a335ff2ea200dbb4e7128c880bfc2f10f7e35b6de3b4b9a864d0527db88f36df623980f01954ea2d7704498ac43034eb3c2bcc1e4b124aea513a7e7a8b1ce74a19dfdd917c7a34f40e0593b34f15325b3d98b3087630108519a49815f53cb601c574d95f72c8451b43ce042391d8de5375d59f2c3163f2511167347b21353784095134b084a1377641c2dd03d6766d3d43c1894bda9378302c106bcbc46aad8442405b8731a45fcac7598854ce7f0c4dcb58f976ab571173efbefb66f8f2870be6bece2b85c9b0e3701074ab2335e8812cf7481e2df79e8a497d477c1f482274edafa8e44715e858c48916ad0c7c97e5204b08eb5a8edddc593fa27d6b6c9cc832edd40fd288b32e9dd447989705ab8b65e98f0a8303b31354ae07ff009c315f4d60462adc1f18fda379e1cc4f93ab50c5cc65bb9d792e49b99295508945b957bce4db9a3ea379cc1bfdb1132133a83463f40f0ea7f7eaa36f8ee7e8fb785eb0a574bd2c7ff14e17de84c3045207f2205f274ab53bbffb74bf5a55521c66f2ae3a2511a8bac8909939bfad99597a0461bedca6783201a0516bf4b902705678886bcb1cba3b359bd051318ea920ec58635d6c46b4f5d79f12f1592d8aecbc465ced5768072fec4628d002682adda75ad45d5026db2b648de70ea84e73f30b73734ff70bc3a202b3964a44b8ce2d120315ef9c9eabac9bda4176ff3428536ba6cd94ad3fab188c3ca1954bb060d2a1e869691e53080a6817cfec3095f3a4f094b929d1abb85884e012ee49629677c287b9a8510a88bad2b6fe784b7b244ca53806ed9e3292c896f3390d3d9be034950c0bccf6b8295077e4e3a8c3c5de51e731924854e2e6892ae7801b851d9e9e563be17c31bad377211a0ed888b9e11629090f2ab601ccfdd09c8bee5f10d752581073d1e3d975de2b5f436113c337798a02b46998cd07600817ec8ce79fea0e19bd8971b60f5085f5d808e68a67762eb5b411fb58043dae4f960f675f4ea732b23f2f5c22065dcc415846025e5adb40961dcc39a55ee35d464597c6af7cdceaa2a6a208ff9aac8c5e1e94063416273856dd620660b9c1eb9a11af61cf3bd8a9ba1a938b27913dae2a40b732aade6d724e28ab20a826d6bd6386e52655c175d060aa4684a928709d4be434283b0de45eb1c38ecf86746d7bdeca70792c75ea77c4e7fd258079841b2f2eae822f8de82c2a07c3ad07ea0ab0cde07e7a7c50c282c48414f41854dd38fbadac882e83e5299d3a5313cb0eee5d4571739d32941d3d71fa35e0eb312dbba438870451add9ee9320ff950ad5bdac464665eae1130ff9d865203679d15df5c90e75d753b39a184da3225108a77c135b2c36dede3585ed8631d206519b14da475e38665a9e726724283326e4b2f2d906ad5c824c13b55190b076b1c7483693dba1505e65e527f1ce9bdbfc583a38c3d36ce6ff987bbab881c8a84e8b61cdb09c773b95dd40db3fd61e3ff934865ab0566d5443542afb63e7e6ffa2317bb46dfb709a6493ed5ab60e2223d58590f9294604ec2265d200daa85154b18f60ea507f9f8a3a5acd21d8fcea321d5807a7f7f160f0e3f54aab52c16cfca0a46a11e30d3dedc10b1557bd5e11886c07747e1feb5a84872306d8ffe2f4ffce19a754c401d537c6f097a2804c98b84a0bb0ba4d32f46590112664cec3f8dc4f1fd805e9fcb7a5420b34a03d2f47b13bad56ce4926355caba50e38f910e948b87967c739dce16b33bdef9eb247256ee3e68d324dc90df46bbc10ba57a92d5de284d84cd01a95d83e4b5d4ae7cbac53f04f556a065e3fb21c72530c0b967d17ba8eb8c74b7c627de2afa48128954c5f0bc6b697261b5d6ed1b07bee31b8b05c34d1c79e2af8b35c081b2130a1e5f91796062acb68987c396ba2a0fc2e62651fb7bea4a7d9848a517f950f27f1a2d7559d9dedf32a5a9c30a9b43a1fe90e6673bd93271bf4926a1c1719c0d8e2c158b1c98551b19af07c80be4ccde36670b5e541e0d7e9a8fd6079559954b67a56c346f09f77a7bffaeff8ad4028bb7bb3468763b350afc1b2155656a06095d2a94f0abebcd1ca4ca40910ead8e2c816dfce114ad343314b5ed5ba389cc7a64c20f4afc78d889d6639fefab609392346d3f0549ce910a6b3936eb7bcf4ff96d1e771e71a8f6259cbfb8ff9ff830a675e40581f0a3519dfaf74a4416c2f9b644d59b67313367343021280097bea727c132409c682925abd6d4c82c37c8e9498651a0d2c79ebb894f1e987b6810ff7909e54ff4b3104dbfe0d7e818dcd157c7c921b8014ed70fcb4f1f2c3c961e1291eddd99fd0f2b10b9c61d968875e6940f439f51abd12079fcd20e059bdeb65d508cddc609a6f6474624122d95565d463523113d5e1d2622a7ca87b248f79ea02b33b1e6f00689f8ef3c3661a65ca2839013ca29b77d0ce05f64d65071ded601af6a1419b6c0277a3110a20c14957f278e562dfc84d64f87eb0eff47fb0b3d6f54e0cfec2294dff6b6012529999a79f46ab57e9189407ab2c5d3de71e8ff086f209adfaab894571e88f37351002da819c78627a4dc637913422bdc5b259f877d4aab33acd404e62ca116ef91bccde74137eac1320b6f2026d7e5c36a485f879617506c9193f620883f4005c58f373c6ddd90a7c9d680bad2c6ee56bbd05d94a55904d9017f1b4933589784be57c226eefbc808d8873ef6a269cea842469dc5d4c3e9f1b6a63113f9fea167519d3ada37f6f66c79457377859cbfc427e1c8c320990c85f7c42c541bac1e57a176ace3febde317cd8889b1c001af1b65b78ef2707f9ff4c090a505d8172b93360190140eb5063495fb8d59f7a812f681127ace9febe64b1a812b9b007a870bba238a7d4008895dcef0c149614bdc91eb070dbf6b7839cff0c998173d0b3818f0701560d2fbb236d2b39bae436ef0cf490970ec2a381f44d9128f88c9c4895fd0ceee26d068e604da2fefed951fb51f9a5d2459aaaadabb384ed40b1df50925a55118d69afca58c96dab57a7d6403d6a57ae908a1b5615455b01e2b9abd017622ae65c79cf11f8b8b5f9069ff7df235e9d160e1d1856d2b5253515157e2c8bbc8e661b5de7ad126b1b2c32717d7eb529130a15399b6f0560a4ce64f6c126174a212fc8034f2ba1a9eab794e9d9786abab068bc7929f6615429a2c4f2ef8eb6e0b05c57986e665998f73bb48fe9a87d914639c0584981c4b0c01593b3d6cee5327dca3fb8d8d97ebc45b7eea972fce4398c09913011b980e93e6ba9b99f8c0e2c76cc9ed838d3e6c636b74ce66cd6495bf9fbb4195bd8624c07dba61a496a2ee98d236917690221f9ebbb974828ece6b61e9e8030368819a2e68bda5b42d4a47517d9e0120f2180055619f381629befe9c2cdcfdbdb33a1e5e09833dd345ecd3883f6ddaf5153da992f1fee8e62e57d6be1843f86808e8d46c5e9f73c3a141050916fa94c40deb2b95aebc93c0f4a156784874bb91565e8ccf9191b204385247c61578664ce8900f19c9547f336b44e339d521acc696f6026ff2cf7dc235f3ac019d914fd61532e1c90cf0076eacfb4870982ea7f3ecb6fa623545ff81ede519641819bef2241daa91cfb18dc8ff67b7a6f62b97150969e20735c7b7f66a7447cc3c51be098cc1af893d42014bd21e078765a6d14b6f0f2cb1bdee414f1aeb765fa42fe58850f888319b7cf7c9c00ba754797545d4e3e5cd2dd87b721a8c4693d9081668e5eeab730afaa905510e5a8e968b7a9be577d3247111b1f17667263e0a5fa231dfdd4710908fea5adf5f8c70be05ee7170d1b8e8340665ab628950c19543c827423e57e8d44c4263e810103011ebf10c4573cd5da60e50ca93359b8649ce65fe56fac0c6b618020848309bb11d4528b1a6d5f0a43d0296722bc273ea51bdd63b9070f19061da2a1d060446aecb1d646feca209d2b6599c58d3e90db42dd703e758cb916c2b1dceea22d84c2c404687138455f1a414dafe776cd75e9a02eb4fd141e9f481402ad34c1ec4b92d6a8f42877cd28881881a2aa5c821e81f62d76cf1f12cee875c9ee7c7403e0fe136f645c093a4df2a7263146571f95a26d7479a51d7b5398c8ac997db85994764efb1ab95ae7925910589c736a29520d7e43d35fc05b969276655f29ffd5262fd2bcae17c22a27f54efb419344f508d63475aac58eee04b622315d6b9cc4e712ed934b7532ae20a2a2605cb87aacaa880f43bc2f769e70ed0f48005880ebf23a7d333c8a617e81012660160a0ddad04f5ab331216bdd20e35a76e3da888f3c7abef23497dd038ed8d9d083af876d6f7a564aedd89114be3f0ddc6aec23c844fd82d93b164fd014b73f5d20fe3264e9f264bbc06bd79a034f90ee96b0c147f5a59123e6d9dbfbbf02ef2ed02d789f4553da6fc3fa14b7bdedd55dda1140a70504b81d945672596d84f5e0f3d700fc9cac942f25de46301fbb523a8c48d47b5b53d496ec73ed03aea0c40132ad517a1f46ca44901454759cd8665380a3e68ab17e14e45871c21f8b7840b12b1c10b90e37d16ca7b0425559ef7bfe0061fa2e72e8cf64384d8c868ad2b23d22d367c571aa911682e16384048bb372c0591b253691889b47745315baf3df0c96f70975564195b06498e82d9b8f12b772702b0990a68e17b1c1eb85baf45607cb7df82743a292c2a1e1ed914048965cbe58b376a741dd16bf4509be1d4d287d96a316c0914128ae52d9bedbfabd5e66468c3bb652ae1bfd7acb384548b20f6318d2a99b3ded699fd598d0be09dcf64fdec00e5501d80f3f0c343133d58b2f804d922c6d6198a5847dc0624669d1c6b3046fcc0cb4368df0af67d1d71f9a42c99c01e497f4b79608df900b66a1abac062649643e7e8c15e8a8e2c463d0fe9d70eed8f7ce7f0850710a2728a27274f4af2825ea47561fa203777c3afbe597374fbfb052f2fdd0048c2b5e8c7fe2d628896e8aaaa9069128dc6a4828b20239d14e7501b1ff054a33bbdd980da824d238103487aee8845e4f8ec53cb59b96a97dd04316acde1d30bcb9acf16dda2a3daeb2c1cc0e46a279e36222ad0b052c96941ffa77db059763db2a54fd97db47601804d447a36f2ce2cfcf28c4e3112488923747d5c465d10298592d5f7cac3210be96c1fe41b15d3a66c23779a3365f8100ad915f503d44200f7c7a2d6588337473ba286fcbaf3c87788fde92949b1f7f9832f8c85b8032dc9f94ba0d9238cedb03407b2f698737d138dbc9b8ddc36693c3616f949cd28219656068e718ced2209f3bdda09fa29186368fdb401e13a4b7e10e35ccc96cfaf364b44ee5a46a9ea6bf806aefb8803c382d57c3824b90eb3de4ffe97bae2bcb3444878c061b33290935dc3159e86ae541c1cd696c7c5b0c46904f6983b31e9fe1c11c162f49cef0d1d25f76dda013c9fd19a3841d794ca9f721eadb4da0d31486f297d918239e6f8d3d539466eb1be28a2d0c7ea6e3631ce8488b6aebaa30aeb010a45eececbfeddafae030b0e11b6796bdcaa8978a9081d3e7a3a3c6239d38aebbbcc4ea4361b969f3b51ccb476d64a94b20b12628ac66a687101b3141a8c7c4a76fff1aa825a6cef8b1ff9853635ef89afa6897e5311a5c2857002f4120341c92a2c289c5b7bbe3e3e0381e8d10aeec8cdd105ee15ce30b5aa300dd53ebbf189bd6307ea841031a505109f457eacb9bacac8b591282558bc3c6327a397b65b5e9c9ed3c6ea0203ba1e5371d400a4e06b6aed654c3748ca1d16b0d64d314b40b34a7062e8aa08446addfbbeead2bf5cb039b750a850f80317b1fd343c2cb958938cb5a242ffaa336792a1e99e4d973ed574ef6ee2ac0e68821a17cb6cec8075bd57f402a8c847f4a684690d5892dd56a4dbad77c8abb83c0e3bfce9788ee91ea0397295fedaa4f786511384f0caa9e305fdf472a70da2bee6f787df57f39d29be68d7db1bd8160da8c876ba833636b47db7181916c4a59f0e28fb2f9334964b364ceca32ecae2eaf5998441fef4f0a083aa5d49d0483a0ca439c26f3c5929164d0ce9d9627656a2aa6bd7081d1dfac360c4d17b13ced0841771839777e9db6b0758a19e5196c252cb6aa12337f1ab2ff6a6e2b56a6fc4225efb4d0fb9ebe1ce0b32466880b2bf076738925875fdfb3392562b5658980266937dfd269673ebe0457cc5b1e0a17da3fbdecb88f705bf4fb15b9a2a3328d752b6bfef285a22c1c14fae65e2f5e2a1d05758d2f1dbef412833256fc978e387712cb3c1fe70cc3cc05c2e6f529eaddff045b35171c5c1a394f95494334c6f7a96cb53e6d548b29a715cb3f2e41f08885b5375bf601d7a7a0d6d3bc76a752164b9fa062264319cd301ce80625bd8d5ca0524fec1bc74153a4faf798cd81aeda8d50412fa62061b602e1be3051feff4fe8f3fa1c95446c8eae24886f9a8b2a4682e86667dd86f5db25eff4bde75ad96658567aa259bce945c95174219c7ff0e3d2058ce17cfca43ae6e4f90ebf7c1d1982d210d9fcf02422383bed7dad0002d9603caf822f3a7dce6fd413e9081efbf28780b63df34d86d1fc6b18fe2b7a2d7accde6e8549df3e9ef45660285ceb7867f440a12a2f554d71d304aeb2cb13a8f267b1ebf92c07e349714a9c98f85fb6c9ea2c9c57fd56fd9e474ed72e8bb356c9cd0dc5cd7c8e333aa9ea243eb28169f5aa5340e6a28797f33a64f352364359dec486f127b0f6a13418b2142ee8b61f836d3eb4b60a43d613b41633bfab9854b97eaf26b946ae658ffc39d255c5875b04ae330dc86153060b42946350ddd64c56ea59e5bae79a75eddd220c26cd316a621b12b89e445e89c87c95d129d04a6e09c75bf352f05a2f498641328d9581997df741ec5a3864befb8ca872f0973507981ce07dda4272d44d8ff4118523273f1f0723730fb9dd012fc13972d3459441b89abc01bad0c6ff439791f16bc5cbd083fb6443d9554a2f84d5c4a58dbe863c03db790d08c165dd1972612080995b7d0a996623afdad528a47e5dac7d8ed047f5769659de27797382cf762051dfef31b6bb197e5557c22cb251aac61b1cc9a2d535f35f529ac4e027a3f2493721dff0d929e07efef80dce071b5d1c2eda66309d9148e30c1bdab353285f2902f6323c80623c3d73dae3d58f56e48beab25f8db4ae563eeecc533a9f4bd5eba38189817ff2e0d68416b0ca21c14b2ddbf9c9876062b2bbf9a891fb409f4ac8b3d840e37369f68500131322d2fde1276b3574810e72b2298d880acc696f1bc29f259a6ed4a168d5fe05c9b3ec3d1230ebdda1effe7e745cb1e6e9ad940dc8d1ae0584a7157df595e3c66888c0f92a46f4e487d53718f83d7d730589bf1ab9af6cfdb36fc6632c3d499ac73d1110f0415aeb09537149ca6bd6f78157fd2cd96909771de29b9f2e7cb9f815a13327fbfcf017ac3a9e9797e0b4f4e75df17b4fc21dbd1fceb72cffc004026bd5f9e279999f04682364f409cd64852be8a48751b06d386ff5eb53badcb840b46f42278ee0972f615f45c3c37e2c9820890412164f3e240207f5be6b8321c27df9641d58062c1c5da96ddee15061f47e252c122151aae099535297390f67bfd642a2caa977c3730ae01a590319b8e8d006c72fc5f565fa7ffc4c15f017a44f548f0d2b86651c36e223d65b046c123fae4d17a145b35ccd0d380fcb368aca9e0ea8f3eb1f9e1aeea047669fd1f6b9d93dbb6ac6839599d472316be93850ab0ca3d97174333eabf67dd5fd10ca51c9d0dd36c809b4fd35c0dacfe1d3a5a189f4bab338e13b6890c54595686b1de6eeed2efbc3726626831d9fedbf3f6aa2d9f086f465c2cb3939421008789fcc329a6da11d1474710be9d41f05c5aa406cf9d55dce7ee083e2af6c429b4cb0a9bebcd472d1712bb5368d91f4cf4f8cfc5ad2843b82821bac823aec093a34d8d58d894c9d4c691d950fe64a7fb82d16698efb8d9f98c8d035c58d6760e2705bf04cb7bf1785bce7947dd49f4c5fff4f745c3e6968494e8d195dcd7905bc4cc86920afeb107da38834dacce9917590da724c04833db0352b88146056b10fe3667c389c4d1212ce29dd6d01e6ea7f38a1fdb1c6160fa6144a95cbec20b5e10f3b7f7aef84f0cc950936413412360656684eb96082ca258b76a6e66d61d1fd32cdd44eb45ecebfd891da76936b2e964fde0a4224e4d602dea647be376a9ac18bd5abb648261007ede40f5e48ee2ca3192e88db9a6f50723075af3b951b0e5d101da3d3c6b70ccab7201fdd84a4ca3b543496c4cb34ad71ef706a01b77f5e583eb561334b7c9bc673fe1a95d79b1f1b89bbb867f8b2c9020059a13e7715a983c06d819126f91a6cbac3f2ae92f20c6f3b4d99ec48ad3b0c20774f8f06a6d0344fe8e0e32190e8a26aba415b6a689bed41a8c97a6813db3988eea1ca5fb891e47f78122eca8e2c38b1851d353cecb9dfc2054013ded7ca3a5385a8d702a0061b2c0a4c68872bcdd31b0ff4cd4281e891a055182d421d5c97415c4283d3ea0313ea8c2c505000eef8102cb2a67ec4e75b62ff1cd1f5a63af1750202612dde9d2df9d755fbf31d9244d8c6b1ac7a68cc07649bed40738cdf5a2db0e00ea8849086f5f9e65f2ef209667d18b92d5d42f4a8a92b22430bd144c196fc35f8025c65db20a0f3c0ad8f110326a1046c6a148c34e360dabb121dc7d0a08e9efad5b4c07127716e32215b8a52a6ac8a59d60a6f3b96f1a7ab03174354baa8f51756070fa24b12dd04c6d577ec4f253653c9d110f04d3f52f06f35afe308782595f0ada35d2565891818ed9ac94d72ca9a964c45b43f28cb707a3d6d60f4bfcfb6a594f6f57ba3765e7bbab579d1ac3a9d2b97d7b2909e278469cdaa1e97af9bdcd3b5873921ec56567859c32617e9e2b6e20570544b4f9a463ff69a8e7d93c947ff96ff4cbaa00f600d481fb3e03145a397e8a0eef2ee7d845689e947cfeea0e1b401f7c515d54266e042022ddc4cff314b2bde86d44e3170520344b71f87ae63e4a64fc35fe134bf38604796749391cd422989063adb418424efba76aa82720310ac256ece1ae3e65236473ce2ae93c54dd6e91eb5218d3262a31ae24634f2319d7e5b8099704480c6b741fc7b7c56a3636c96b645910c2051a442b7828c80e62675bdd7920d8ec0f6692d749a8c4ac9b3c1fdd4c7a1905faf1bb922f626c10e9c2eb6b12dafa8e42cc2d7b79978d4965b7574e95afbdc359861a13658d3ab10a26ac50922ececa0f47486165eb0083b50e54e24d02503269deef2ee2a904b2965295fbad48f77b2c544e43f1ba00bae76a5167c9284963005dab2e2d694831a302669ad20ae64b533104cf6a21f8b139585f84f02912f8e8c2c9da0455a9c41f4bb0c7dde8aa63a3876b23077c207b582185bcfcac8988b9052a5d17a03b3c3f9f3071b08d10188ef30864a1844763cb8514ba8219a81d133e189c34304e37a0325c2660854c3bf0978ba3b34feac0eea5e24f86d00db318d4f2b32646c3b2da66e6a8bbb077d9228538e26655bd57a18ff45cffccf600a1eda2a4a4e71b5216cc92f48c99b0dd98212fca5df126d43844287c4f3a8cd63901fdaa01c6dcb30fbcea36379ce54c751033f8f2a9d11b6d0119bf2285464cb92a0003730bc01654a579ff81c768bf5c16de1803ec02f3795408a33a200ae5a8e309dbca9ce7653ef066f6be5145756a3c8e490a8487561174a251ef01af14870633956a647f624e94820f5927c2b40237e90038db28d004ceed15d738356181d83dea2aba3d3e2436e1f2e59c300024b1de6091b1c5653e6cbaffb1381ffd1fb0fb0253fc0b2c4d97bf4c87c42dcb58dda71895141f8b873103bb97e1efba3c0811d5af671fa7cc3f744236e15a260b11d0813b419cf81fdd5878a99bd062b91925b4c756318c7c18a2b0e39d332aa355cb2a881fae0d74f76ad2c0ada572f7a1195b53d3240b761af385377ae8c489e760fb7e52f6a40719b3d59e014ac2832a115fcc6232f3e0f62b3a47615f79311134a0a21f178b67ef443f401a5d845cd6fcd74ab4b517cadefe3dd207b94051fb3051bec62ac7d8e065d4ca36abfa3bafa8f8f0d4b5ba48b561b24f624d2bea93196d9e738bb1ab0f91d5445e528a1688d0c6b86dbe57e0154821d32792ab6c9f5b7f1f8aded83edbbc27d951483a92c3100994c32864b423e05494d90562631d030a562180d62abcf1d4645d08d2a1dd545a03ea84a52a9e0c719c3a8a69a8cdba69dbbcb7bd0b3c6b4d1b3ae9c806abdd88e586f0e4472c62358976c8ee70e9605de9cde393addf687a5d733ff620ff2a5ef81d5c57221c550b442797ce2bdca8f24e0e12c06ee0ab6162e3c9beda998d894c4d0f0631b8fd243c1349ab22d67d18466416c5e1c189fc8db255ad4e56f4205dfa3b99fce06325497b514f57adf43b1bb7aaa837d2a5d171ef15f922b0e5c980142e44855b21ac0bd7055559e171fac0a6232c83e46e8eb87ca479f13c934c72dbb767195f630c89a497c4100ae4802087190aec1236e4782eefd6224a540157574452d77e65050937f0e6feb4495f877d8535441d24c081eea7d8a0f73f1d56f55c10b8e288926bf2e0bf470df04a74b3265eb8e86c965ade80d6f958e752d92a814931212baf9d8d26893725f52691c1d4970c597843efe20ae33e329c1afc1051d2040d474f7352b82a8e5df30fd07dac8be2c952ac4c049ae44d56308c45d40d349dae07bd56965ddc608a973850b67ddb9d569957e05326cd16dfeec9100bb6524cf3747b405eece3760a7408027ff74206adda6b59c4f5c06fe8460d6960c6388a409659c71bd15e090f3a5074b3edc9c200dbca05e77f1a21697e78aa94a48244fb1f5367c75b6665c59e23a1cbda31cb1e508bc97fb5b328b451829789b326ab25cefb83aa3d435b3473e9ed374409184c0d6d182afa62f27819be2ee7f744ee2624f72236dff26af054f401a0a80c8d3bb6bfa916ca0a98a254b25a550d15c6d18f0e4585779f2a862e026ff2f69b87042d6591ca3899871f0039060297eef000000\";\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(\"Lynxeon\", 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 [\"Cyber lynx girl\", \"Cyber lynx girl\", \"Cyber lynx girl\", \"Cyber lynx girl\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Techwear collar\", \"Techwear collar\", \"Techwear collar\", \"Techwear collar\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Magenta cyan rim light\", \"Magenta cyan rim light\", \"Magenta cyan rim light\", \"Magenta cyan rim light\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Neon city\", \"Neon city\", \"Neon city\", \"Neon city\"];\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\":\"Lynxeon #', id.toString(),\n            '\",\"description\":\"Lynxeon is 1881 Cyber lynx girl with glowing circuit freckles and chrome ear implants in a neon city. 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\":\"Lynxeon\",\"description\":\"Lynxeon is 1881 Cyber lynx girl with glowing circuit freckles and chrome ear implants in a neon city. 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":"58069425","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-02T11:11:02Z","match":"exact_match","chainId":"56","address":"0x6f70Aca287f509b160caFD6BE9D8041b9d99d08a"}