{"sources":{"Swarmcentaur.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: Swarmcentaur.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Swarmcentaur - 777 Friendly young centaur with a shaggy chestnut mane circled by a glowing swarm of golden fireflies and tiny bees in a teal enchanted forest for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 777 free pool lasts (gas only).\n/// Every other mint costs 0.00007 BNB. Max 50 per wallet, 777 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 Swarmcentaur is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 777;\n    uint256 public constant FREE_SUPPLY = 777;\n    uint256 public constant FREE_PER_WALLET = 2;\n    uint256 public constant MAX_PER_WALLET = 50;\n    uint256 public constant PRICE = 0.00007 ether;\n\n    uint256 public totalSupply;\n    uint256 public freeClaimed;\n    bool public mintOpen = true;\n    mapping(address => uint256) public mintedBy;\n    mapping(address => uint256) public freeUsed;\n\n    error NoAgentId();\n    error OnlyWallets();\n    error MintClosed();\n    error BadQuantity();\n    error SoldOut();\n    error WalletLimit();\n    error WrongPayment();\n    error WithdrawFailed();\n\n    event Launched(address indexed to, uint256 indexed tokenId, string agent);\n\n    /// @notice Contract whose runtime code holds the artwork bytes (WebP), after a leading 0x00 STOP byte.\n    address public immutable IMAGE;\n\n    /// @dev The WebP artwork is embedded in this source and written, in this same deploy transaction,\n    /// into a small storage contract (runtime = 0x00 STOP byte + image bytes) owned by nobody.\n    constructor(address initialOwner) ERC721(\"Swarmcentaur\", \"SWARMCENTAUR\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"524946467641000057454250565038206a4100009055019d012a900190013ec154a24ca7a4aeadab13cd11d01809640dcf4ff58eb238fde59d0cfff7be8752de1cd6dfafb9cff57fa54463e6acdfec71ff93d77792c74adf3a1e6a7ea67fadefd57a0c74d0e3797c23c9a7c6bb11fc93117dadb814c18cc534f36823e4d3ff1798ad45105025311968670b4a23a758fa6c465a1a9051e6da524e12f03e72e26dea15b7efcbe9ee44d1e44f6c68aedcdc13d15f2bff68ae39b564819d698c42545febbc95a147c89b65661123c5efc492aa9832c5db1b8c4dfccb47a11f8c20c0e3c89693624bf482ec0b70bf3155f0ccf3be499a4293a9dab9dabc2a389518f32b44764310d20fc47d2d9817c26a1372f65310d3caed1fd17d3b4a33fdf947dfc7f64cbb33a24ffbd144f93a0ad1050355bcba6151921e591b4ce7a25f76b8f9e1bae86411526bb9fe06c1105c57ccc9944af02939a23da9d62cffaf35551a988d24997017424cdaf5075a1b4b6273c624691f30826a375577598a05cd399f7882cb5ca1bc362a48d992bb210995877c853e6bc4a0f965a6476b00149ffc88c2f440b20424ab1b743c71678da151f07e1f57e2c113ad00ece8234b295cb4a2df59dca047e7a2a5c1e58eaf64ca43081cb9c51b7d08c80bdb233ef3858f6ab60d878ebde53ee15077bd8cc69bb9a9179cb38da7d58c3fc874677fffc3987f7b55b11dc7cd9b5364b4f243b7ce992fb1fd337ddcfd42c7b8de8c1f9a8e585c5ce860ae0fb9e5d08bb20a8957fee9e043ccb8777e9e91035c7ed0786016c552df1d3549bc3b76689deaef74838492835ef5f8a46be88ae1bccf4250e5e202d772c07996a02fa960dbb268c97688e4d8329ab9629ab119ee4b5fabeba031a4ed9945fba512d972c9efbb82923547e2068825494a0cd701b586ae3de7464237bc3d6205596031056adf98816534b8f1486c09c2bc07890ece2ccfd6b03d6d6ed82565da08394716cba8d292330ff4d87e97759530aa94513bb5977777aa4166d6d9bcfb57806a8db9bd98b46119f7203a20b48393bdc23704b8a42d2a7077559a6aa6238ba7704c20c7a342cda3e6273d9ceb6e090a987cd497afff913e014c6e5c3983642d74cd21e876a5cfa3bf66c9f36dd1bf6c128104e3782f3f14d8fd7b4dd2cd3846dd27d79d9fb8c59b8aec9523f418e7ffe9abd5f9c7f3f205ed603f3c480368cf1b7037b89daf39af345fdc6676db261ad5cf08fd6717fa2f9a0acda98937f929a98112e6e6183c1038d8621ae1e762ede2257da0ef01a5f95b2fd101993005d034c8ea623281111fd9e4266c6fb93c7870ce2b31cb76e5d820b698c8a8dfa84295fb595e315a7eab5525d7d3429e26a1d2319c13e8256c7fd307039bc85ef6b484c30162682d224ec283fd606f0332441956901ed8eac5d99d5049c96bb847bad2b33fb767745139d0cafe25f31f491ff3568f18ce071be1978b5930a9cf38c9471aa14520edb73ea90e5d990e2cc6f3182490bdb2d9b87ce9216ee4cdb26b45c0f676bb5b3fc64b05f56f5fbbb103a093c31fc456f3f7cd1389827454ea5d0890fceee6206802198300f9d09b4f6cddbb4a1ead9e041847e491e722e10c62345c514a0c2015c3f04247069e34942096a0dafaf09993502fc8fc93075b1de8268124c6efb688a57e745398eb5282cc920cfc4ff5d42689c1c98b998b96c026b5fc3d0af3979edf86f0ea46fb70d3ce226eec698f6ed094b7e4a99f3ae31f07145cbd762cfc7ada75158d8f462037c3d77c6f7c9e0e6c2ee91f2cbe41f8c0ac67f779576068e233f2e3073939ff52fd1471fabb12e4a295767d969c7c54473bc5c20aaba07f240fc39fee401b15d76b4392d1d5be0ed5dbf0857d07f7c7fcd6405e2929928386b7f5c62d41f68adc33f292fc4027596521a5443412a3b2e299f3ab34a9591f805550e5001f3d01f8e650512a04489670fd970533a9857f4e9f2ad7b38da1f9415a8db86beb29228a6a8644319a8402d292de5676edc802f2aa0fdff170418b7c4ece230e5d398467fe35157ed49a646f379282b7acd385d45e8fdba46da87e4e71bddc922e217741d9425a2d13c2494f56fcabf3b07a3f4329a799ea0027a64ab5538c2d92922b10eb7de4f90176bd5e2ebd30f4d2b4dd78e451713d55ad8636c81177b84ccf7dce45723a7bddddcfb470740593014840c66538def2ce5267b49e0e0b04a569c42cc7a94ab6e820fa4548841ec259002b9a383549b18b34792045b800f61c20da80b5f1eff97c2513b8c9bd1a582e5bce5188edc1aa097eace7843ba2360ede7c065be33f452d7ae96194d3c629f9c72937a7fb26b18001abafa621f50834ba6751c7f1953ec9b36f3c513b1175342c7d30b67969e706b5474b8158cf3a4c95431ee94f22bc206f3317ac8e54cb737f244e439c0feb2412734f874ef1cb8243adc94ffe1bdde9442e6726509d35c4d39243a91bc363337c5eb4cb2ba0f85b8301e3f473813db054518440ee176bcbb8bd49ede565077b7a7852c52df26ee2b6d6fbdab9ddc8f062966511a82d5c98fef03653c3a60868a74b18e080f9c36942614129b7b03656ffcc9e9e66565aef63294fb4f7aa1c256a2663e0f3d73c37f357ece516b1c84009f7031cf7464455537715fd2ba4443973d2a457e8bb274713ca95eae0eb065bd60f2ba27968d32631e23f19ed24e0a2da298b6e3df60ed3f66be1c6ba63a3622458c6d6770fb919113ffdfc6b9e1f8dc8a43f294b915177e217cba244ce6e819f3b2201d3f7dcc1b0bf57aef0f698fe87b5b3d8a0524cbda91bbc72e34ce26110fabe56e45f2f49d8b0c3ec7658720af6408c73ae1afa0e374642feede2aa9acfcdb060b05d99c729c516b924e0bfc10c8220cf127ada359f14f61434aa441152933b1818d147d9384d6d1441962038d002aed57179638a49d42e89733dcee9a1dde1105e78bbf8d6741bf52cf9f276a74bb3fab2c3f7ad9a9b3a1d030c811cbfd8f82a73e7da4fa249026f8d25678ad288fe51b822f09430fa68e882ff99823ecc0a11b99a6be3e7f7a5e564866b7681501e0bbcf136749a1d9dcf5a7f131e922092e5adfbf56bbd29562fc6415ae356df65489ddd424100fe12b112b571610bd5df2610c94e444be3af8858c30e29f54258e812e94d63fec1dd2e174ea44da8a2ba2bb0edcdaedc6b8827c9510f4b0fefd87b1e42416ec24485e97f7a8f9dd737f620de328deac19fa6bfb9d832b85f4c95fce83b532de961061d05fb1962c2c22820176bc3eefbadb2ce071296ea2ce3f0cd124d7079771fdba3e6005ea7bc1bb2d3a0a90902adbf644bb6280e231d1c036efca7b66e878b84e07e25ac8caaaf16959f365adbc3a626cbd15269517279475b168cdf645fa969d1de32f9ed3c980b43437e18c4974e0c6fd416d06733d5690c344be4cae90ff8f50596d949abd04313a34719d5f40cea3a649f6b4f9a3cb06844dc6a37789a7302281cd72eca35e8a6315b9dc2a1864a708379eaa2690443729a67bc38e6c90fd6140e5aadbc792c85fb1222baa2afb8289e593c8f13187e98926e64f2a909a356b55087f3adc92d5513bbb81ce055abe5e45e73dab106acb0e1d84382710a8d7866f5ce0fdc30a51c480983ebfe7d2970ba8c248d8b89524a48de1464265e623fb094a0061be3331d75672e2ba7633a0ed7560c4be4e92839bede84306f3809417e8e762e874f47cf9e43412ee63664e5b7633966b4d2e6557a9ea2109885cbdef2922758d3bb573654ed7383d66f47af4442bfe965c06489447ab59e700b1c3ebe50f2f1999bc16fdda42bd6df042d94f8e1486df0a60f69fd3358a313f21abd30cd6b00af6ba68f12728b71ff6ab38a32f9a2bf1d000000fef6e1a4c6cd64bbe253235b14eaf81dd7a11522989d781278b044d4f73a67d5e7700ec5f0221780b78a3847c305f3dd952c4800fee492ef6b6b5207b6e1bd40bf1cb4e491d1d9e8e75005d1fc2f4ec6ed6281e12d09874cfd811b8c62f6fa0cd3bdfa64735696a131615c9b6df20041f155b4be227e142cf39066afcd9d32f30d74178d2600cd9f46dba6986e601b270a0f87b391c4d7dd2ba0bac9cf17d74b5af1f8c072ae90d7870a0073945f5edcc7e15fc6adba50f21e62ed99762366bb7f58b2b9dc458b97c4585ed40581c5a8d6273aa6937f13926c2f56e13c661410f854e43dd60fa4424a51f5186e823a1116b6a2d09edcaa838b6fda890bb74437188debd3fd6d2bc2efb7fc1e7969c7a3f7331e696aca875cabc6fc4ef858554f76821d266a3ddbf9fd71657058b8a020ce5699ec5a977927de0e6193c1be72afc404ba98e64b3f8722e223f03c7f40c70fbdf521f3fac6cc20a86134ba6b2df98132ed72172c9a8baea9ca4d47d8649c33e7c609c81bcba5641d65247b4fc46dd4cd852efc5fa3a2d1a4cf01a177fd59e91924a28c178ef6b6119ae6143f6627d3cd41605d5af4b798f86f0e8590aab30b984d2d70ed03ea2406a7565bc4dff886eb09d55096f85f480771264bf6206f1adb15d4c8927edb463a2cb348451e365325d9c6b9abd0c35fd78db8115e0a9e8dd883a486a675a09d98f213f01e541250dca65ebeb7eda701d33850974822f19c77228a47b41c3a83a4d4520c49f23309a88ce5e03f98227dc5b043256def50b312e4b0fbfd7e86ecb23c37bd5cf12d3fcf7b3c64a9e476e810e169ee42828dba5dbbb5b48f02c560a480e3f38172d208ac2562e2c0d34c2d7002ad017e6006833d4485cff0d2304f63cca45345e76743bbd21241c18425c6275ffee46b9ae2de5ef1f97f18a660874da3e076adf8c61b6397b10715951dcdd2f159f224b600100189fcd9eafcb402b9878112f9cce2b4223faf966fc2013be090e105bd03a44646d7453ab449c60f798b12fa1be5312472e672beb26ed236ebbf37b536df5612524ae9537e4165fb7559314f2764f7ba534865c0a7bc2d7ceb4cdc1b5ee03d11e39757d151be35be81825c0432044311f59df82e0e2cbd2c968789a2361b47cb41ee6b635e92521bd57fa48a2a008a83603e7574562ffa343f9bda69c52223976d6dc593a7c0dc85bcd68909ce45f226faa14ab125c0ea4914177fe3c65645e871c82eed507ff59dde63eb174c99b51e96e13a6846e78c0ea9342c997496a21ef9a7b976b9bddb379d923ba35cc1b08a13dfde74c2e426dfbb21d761883f0875ea3cb4102fddefadf5c16e17af4925b0212c1f231411c9cd08a07b59bf5eee950bae46715ebc0e39358f89ecb321aa3c38f6bee6c95aa6fcfe9ebf0ff0b4e9cba89864cdb41ea9fe50f1f2b6dcec7bc7912c27d6bf45620687d2a8821a565b2add664ad36558babbf56faeae1955867dfa512a162c4b288e916b868c3403e151b8ff21de593959b6442875edb87df4398b4d5b39e4117dae1161f9cf37d8cac898a6ca28fc39bf1450fccbe6b725afd9e954593b130368e89b942ff648a9293d8a2ae843d2cb451fb27cfd65564a282f4a4b838631e85058b1638bde064aabc79e5c7a629126498b185c36acb457ecdcc29e2a201371d488f361c14ecff0c672a55bb2710c0530f3a1950f22007711dbb7a5f71f74af3de43972e8bdba4708a27c74a67d2bb9aacdfe6231e02ff370d444b108ac60b3dd9998959284b93d46e6da53cf0cd47ba773c58edb3828273558b5ed2fe8b263aeedd4a5bc673e8c52df4db4b568c467ebc3db34004bd836d4d226bb0c7b772fc477d1de596b52620a5a4028c05a3a0aa1c1a7c54f6109b23c41c7b0faf03a28ffedbf7d89f8ace07867eea81142419df3b8b53beb850a2df99adc0896c6f9e3074bdcf8b945ff2551e8558bf2fcf07ae2532453edd1246233003a4643dd38739d2f8ef10678469d86ec4ac6b03f61197c043004d80593d31909f5407aa3c5e3c77a47b010821ce28fbe834f7d69e916261a0980689f03c7fe6b7be0ffa9cb5aea18aa50206630249c8905644b5b6ddfc21bad8d0b9d60ae9cab5c378d5f7831bf13122832d65deefa6cb91e06ef8d1bcc03b665cb1ec19636ed324ab90d9b98fe6f7e71a7d88c09ab00fce672e4f8e1ffbe3fee3cb3d2b0246bae30fecd36dd874910e70d5b22661c7ec5af8283ae29b1b80f6d97506c4ce2c9112018c8833543ad8711c56ec38e93fc38d52daa703db67e2b944750a9cbb9300ec45e60e139a6fe5e8a6aaebac442b7542456f346e13c7334143c1e3121498810a208be51d846de346cda9556874fdb5b7d1d6f52ca7154db219b78c1d80f81e3635a718b5c8503e9df4f210386826bb88b044d3b3e1eb8fcbc642b57acd271bf576b630f6f48f775adebda34949897f86ca84952409455f84fbc8a72a14a8d1ab98bce1e6541a106f7b296ae092f65754e776ba7668a8e054e795216b671cc4aa3f449a8bad1fd629bdbc37bcf0f0d961afb1d9b0557d79fb1d7809e2dcaa67ef9525ca1c0823835e959441a5ffd56ab13fa5177460a20fa058cc080482a46ce4732f9aaf1262000bdea9ecd57c08d4ba31653e54dab9eb6c088f2dbd6256b972b465b03678b63fa1ad54075d48823b59e2a79cfb9eb29d0237a8b1a2bd04bd3ddfc7ac716ac3ebfa14b33a3c4a7e8cf9d8cbe35df87436190db530d8359a92ad2316b10bd0b067989035470e6f123937c609e281cb5244e00d7c998658397749def4542976c2f071cf41f033b32e835e1cf816a472de15f0db91a23ac471c9bef12ded6fafa9f37675173e2925b456c8883c80a1d65baffc20580072a7e03bd49a9cd0dbf045ba35c2ff696c4fa5b29909629840f7dff70dc7f21ac555acd593a96074220439b014bcd2ecb98ea4a046d9a6fea313e1ab750aa4acc275d5961a98aef7262fd150d8c91f78e6fd27d484585abeddd284f579568d431130aeb1981417284374c64d33c7177fcc05fb0591e11705290a7dd01aaf772e68cbb7114baac61d078c368f77dd73d5009335595a7eb7392329ca11a8885fc08caf49a9db853d41a30e826e2d6ea5eed3d2c23d1314bfd847c4be93d8fbf5a090d4a2121c80945f13562eeeb1976c5cbc4afbb0e9d8455546700e6b4551e5a515d1d60ccaf86dfa8164edbb94af89fdc00d3ac87187777ab0ca4047b40d426f1fa467671cf032d2fc54d52ebd2664a006b971f3c5ba05d0b2b8c8b0cf02d77d5ca0df5e7293c36d61221c2a8b46174adcbed66e2640c25b844023704cee7299545ffb548bdb14809cda8f4af1804e172e5561df6306e0bdd7e12e31ea5002817742c6de01ba61198adb2f8104f6cd0078ad72dc2f522498deeb4b8fa555350eee2f7092817cc0ed960cec749ee89fd0747873980fd477a751f267b05f27e7b5c1ccbdcc5982ef7d1ff34d5e756b57b13c55f51b2cdade8f465033b174a112a669089bdd66b6ead60fac4cc1035c2a4a8d870797ea0503fc88c55eee4782768b8fa12bf1423ab09cb72023afdae7c242d639cc4947212a1cb11f78faf7e169e08be64036432932e9160c9537c053f6888813c4b99c8c945a2266b9f051388e6474a3b7f921d396e6b74a575b4b1613d2f8a8a4c5c841ca8a27a3036f8833ba347199347337b8d849984ff855dfc07dd4656a91171971f1b398b698a041a4037fbfda98797d78fc57d29e9f92c460f423d58411bbfad988697af0165d052a4495e91ff7af669434ec2c65cf1765a412d64500c848609782d41b8c1782430fd22d7568c1d3a38e3f5ffc488f943ea9ad7450915e359624483dd196dbd42c99d8eb2737db5ad6ff2596da4e206e58d9026b0f73145e8a453660f5b04d5e1b903be571b2eac52ccc24b17fb6a7b8c311779b3867b62cfe2492452b53b72ab3e494287f3244e7ee1864d3664023fa1a2ee42ba4ac6415cfc070b4854a882f573f4d7f8d1bc8a6870f34f336e1a24278ac33e4161c48de092c229bf89ef1ddf256811c4f666803c83afa5f7134d9d6082264dd10763134533f5b0db35e0380eea74be7913a6cabaa3b0ad171eaae269b90a457aab7b596db63f295d1eec9bdf3fbb00afc1173e8fb0ef89eedd26a1d58f57d2304af8061982be7470678ee709ee248c923b0a5ce67ab21f507face677e711c5972bc3aff28ebf07f60581f5b64737e8441d57da515b9e3e83b7b32ed87a6c27a240acf8928f6dee4033602db562b0dca55766d20172042230179efa748c9fbb0943b129d9338ff75ca0105e02dfd14a53fd4477328a776fdf6e9cdc99030c84080e530af2b541f2b41ceee32227ffd1cb2e596c7441e265bf2f999853a787d06f0b2e2b7f4436af2c669701d4cef2a5ba8240eec83ce6499e2b0f39f153149d3df48ebfea87070346bab956052f8e1af9135d569b6a3b5866411fb06c6501f7a7b7d59a9f40b63ed1f1d957398e309c46a363d2727f553f551eba0597b8d4a9bb30fa0e0669cb77d4eb246f28470c5c5d8659ec79372a042f5807120fc0f4f8b5a7bb77190d955a94abc82ebc97674a85e7db5e705c3b458219e5cf8f56e25c6a8871c1404721abd05cf3ac0afd7acc083a5d7834ce01d5d61ec7928b3210c9220a032b5e80e98ada3d19d8d41aae0ca32bdec47c59f2aac8c36f6a49ce7c84ba046f3014ca9882947659673d9b0cd8c726ecfc6dc2b8c02db482dbd45fce1240b0c9932dfbf0020282d5aea549be4594588a4eb6ff573c2eed8211e0ed6534d80848277e23c907ba7d1c985b2521ba11634d83676b2bfd7cccfd9dda4d3be7200af45b70e287766e1a3f090c7cdc72ac7fed52fff434ba6bce138a7f746147e0bab7689a86b665da866185d01f2589e34555e6d46b24cff7fe2efdcd26efdd840e20424f367841b9b608dd599f2c21ff5518804885bdf286bfce87b780bbaa3f21e3e9383635849e842f6c8afbfed13750027c258923a66f8251f447ae49e3dd5df6d6cf39ae5f7882e319404cf4d7bf950344327d884ac3d6610b0f47e29a3fe40690bc392817ecd4f80d4d7a46f51bbce973d1dd28b3fa524873a0b7bbeaf42a3076ca098e9ce484d9131601d0ef696add9dad41431b054d8b66a95c36ed01304f1fe1ca3156f9d7ac830a8d0ee1729621e007e0f383cf82a0dcd6800e7f27c7612c6a33c56aa1474bb36fdeee046a6cde358e2304531083c4a31f9a495a177c3808f6e1106f255dcce46267e1a83756936f2a7f99af0ff34a816e444ee9658a28803fc06be193dceb619a4d19e77ad569509c6244b97de3437c33de2cc7c092909ec51dfaef693c717b22a4344399543ec312b41c2b781e36bf4e8494628d561e905af45df890c3d8ee8aca0c984aa708a07b1c99eb31f968f6ffe8cf68ea426692a10a7fd417d9fdffe8b633cb200b502a9d8dd4621d370774875224dcec58ca9cf25fb3f7bf3478961d538683a1a145d777c4fdedd612946644740b83b3cafc85ca879df0d07f8b87dd51ea9b453cf5d2c70b46b9191f1b58b8ab49b8ec5e1a7348b16778b4110e9e8fb61b96e64abd1d85c2154e078e62d5c304e4383640b553e463fe2dc98051b1b7d3341cd487d8de5da5091f439d7dbeac3b4e0e25b449085517f6f10ffd392f2fb22c764f9cc6c3f6fd9358e23ca08d56f43bccaea8fd5538b8dab412fb76e3bf036ed05ddf0d2cd0237be73f889e73447759b368363a7a7717482a26bba11707335ce1f0c938d3e8569518c4872f10a33f8c673d4352b13ae8763520ceaf2229bf6312fb05e21d16f2ad98e22c1428e5373cd152778508f53b7fc2d7d65574a2d750cf44a953b72afe32cf41c1ccd28566d4c9df89bbf9e7a0d38780d79f248fde3a4fa345a259d052844aed88a65463853b59ae8819ad6713c2ffd863aa6379b8ff2473bbc177381215be4eba1d1a1f7dc89dd77beaefb2648acdb198f2ca8cc582dc116c9f8a4394ab13507ff40a45cd584101966cbffb2050f64f609f0e84b32664ac756c50af80c45b9c9256350af68dad9f47f516021563c1948b2d4fdd108872a80706e09d7e648b63d63ff7d871e384854adf8cefe12848537ca6ad779ccce5b093ad2453811c66fec41fe270d64ceb49905aaa415014018d36139cb4f7607d4097276ac82f9c85ffbbd6626ad22c97ae53ceba9f0078508b11928f5a6b1c04177a6322d494d209be15c5a6d77d5e153f39269989359580fbb7eb6ffa18165c5e3a13d2f88c0e9187c6eb5972e37af42b05aeca32d9089ed2c6d008786bd6794695195bcdc4dd214e8da8fc7a5b6adb83abcf895fc7e638702f2d6e15b03e870a157683b03b28919c3f470f326a431b9dffbb1c519f3cf90549831c272606f22100d6e12a3f56aa09cc108ddf6f9a765531a54d9c5aca117de43c1331d16deac1f258984c134d7dd31be35631fedc9ec9d46910e0e359dfed94f597db6d43a0c095a35e67fa5376fe1e8fdfd9d61fcae4df1c1bc20d4916f94619207f5bfde5dbd750e48173924b9e717be840e65acceecd47cc53fb71430281f55f069e2205a24e69af2b4097925d4752d2f45cff9cb7c3faf7cba13c3b32e77b270a658525b7d3056075346a574b07cfa21f906c4127fa9815332e507f2a6a60005dd9d3ee70a45ec777561818e2da77f4970c4833f61a0dd4f991fe8310d12ae55daed1239bbf3f1ab0d0564cf5a9861ae37276f2280358f84e9e8d85d9080d1af28880012947b90494dba6d6a2bf269bd7637e896aa5cc4ea848c9c205b348b3054553ae1626762242b857b2e338deb0c4178cfd12db0477efb9b70ee0457242168a30effd828cd355b398f03f3af4ee216ed95eeafb0c3aa0a293a9dafc2f0f23678595d01a2fe453491eca98b1af6e02e52039fba3d87a4aa8b925abeea1e7a4e42b58d6de090ff310ecd916e2ced50b6b7ebc735661cb386412c5271c1dd6be4954deb3e1403fa6c760bb1af9f2d05626b1fd66c23c0ccfc4b77dd1216bd4dd3334a506cf83f7e9328b4ab3b590c223ecf8d81b7cb7a005583f7f6ade05a88c15876f33fe3015a0437672381c4ef331400527bd78bb5f3d9fdf240743a19cba43c577b5b40721e424d5d135d8ec30aaf5f89162198d1e4776c586f183b53c76ff873f8b33926b4bee1623b03b7bcbc8b5eb5c96ff5d331e1dadd49e3e01f55752912a910d76468fe62d04f2143a6daedd858c14ba88708d65e14c8d0e5220b00a95592876e80751ce611877c10e88eac9e64f52dc817410260091b00296a366b59363a5518492c9f37790b61b9f3a5316ea67d2bdc77edd789d0fdf8b3ace5bb4ecba134dda72cf8ae530592c3528714c163a1deccb04fa889d90d2dfb237fa3edc36dafa130e31d7d70321443c5f8dced4d756a3d79ad816c21eb329307682ecef2bef66986529c4d33ed4af7640b2c90751e92303e43663fbb991453d899f0779d70f207f4dd98d58449020f1b9aca14afc4d77e7d558d37bdfb5def1759c298d8fd4762d69f10c16a9fdecf49fc50bff94e199aca3abcd129195d142b290e86906d843d43275937ae4594e77108aaabdbe287a6f72943affc8e1d74e99735bc034fbc6d4d71f510984df28bdad4d4b64f54940ffc6d94c084bd5965a69e88b997c556c3f5c906a9735932b75d79a79bcee1b4db2c507e5aee16f2c0d97717406fd34e5e21b6ab3f9a2eeae0dea6ef9ac1b474cf3835057f6f52fdf234574ace54792dad55acc83295fb2afff931bac763272d12c047745200e652352ce4ad347674b404f13f1927da29df7457fe440feaf7a4a1d5c711d9e04f95a58d38c422e581e98245558ac548515a5c0b1ed608ec4220cb0db5be46650824f951b3c10a36fce4d9433de0fab8f2e6fbd71a376cdd6575b177970b536fd33578079cf99b5a73f795cfe3ccc9af9de8115f28408cb3801cd2e43706e22f3ed913a0721b02e0bbdc7b7f1764a21e0e4f7675fed568bed536de578b17294c9c1ab15cc1d05c24904732f564a0c8e3caeab5a389a2f08b0199be84896209fc1cc4c8751e54b1268261379055b49acc2484790b42713b7dec38f6ef3edd09b253f740b21d09bc71971313cdd16163158f2ff8d33a0b9cf027130a2a40111edde5e4183eb10e22062bf9c17d2efbbdd5b61c7c80a720d0c59408cb59f0dc086e796e85b16946cb766082833763c0640d98f6e92f2d71e61a0a7314e7c70881f0a1c85a35938c7a0ee97210cfd5efaa042328b85645d340096b102ad19b9b330e6e61f73e9c21855673305a6c526d89c9c961665f1fae3c76c36462fa8c6f1cdb6fb3d2d4802f41f8628a161bdac56cf9ba758ba2dfd9a869d74539da6bbedf9edb6e0069e03acdd32bdbf01eb407177a355cec284c8835d80192718b507383559fce6158b1f15ae6bc00ad9ced5afdafb62060b5392d33b466124679ed6aa46db20296a717a741365bd3de15c259b4bbd1e42bca629b47761923fc8005479267314e854f1e652973227cf952baac1fac9ba1bd5abd980d2473fbfed6dbf6c603e5b6cb478eddbdbc37b1315c2090fbbe68435e086ae808c0f849c0038cac86a03adc1fd6d7294fe21e85b6ea6fd226744983bf40c3ad1d29e4462a43f6d2b03d8fa02835fa9ba9d4a76be5e613dc9e13fef4508bee32365281f04d22bc98605a39b29997984b9f815e9ee716c4c7adf472478ca49674d3615d001476af4e906e724314bc7a6cdc7ffdfe299acb8c816fbdb74220fae16fee63a4ecda1f435203dcbeab6cdf2fec2a4f74edc087ce20b3c7a5477d9f6a4dc6cb409561be6230a7d2eb3508c2d4b26eb3be7cea889f8857e36b37abc27d9ee2cc3f9eb84ddb419848fbd3784418f2f2d15d1fda1886c0a74a9f833980ec4dd112f48fae18cb2be3731fa65f657d8009a19b9d4e2a809db3a19c70dda40f3aed2bf18104060bbbef5e877815e72232c1238c213307130ff0bd6498b847758aba84cadf623474779add85a5611c8b3f98c275bd2cefb7d9b8784a032b3a10fc44333e8e4900da83622ce709097f0d3638e93940cfff5933a02fb346a818cb72325e5abb9e8cef46f59aa2be3705349769d1850016f125b45bead5716701a0317280f5d0f100021f95eec9471c414efb2c885000cf3f99e3618df7c4f4a6fd9ef255488a4e2433aef893692fa92795c5003359b20051f9210395345968b7f5693a741210672f819ce5b36f146d175f5b0e1380c3e09cada6a2d7dc594f2314b6bc2d9a6c95bd01338e375fca4b3db2802d93c0f0131f07dcf43bfe6368a21cf042cd35d65427d356692587eb35fea7caed29d4d0b009afbfb8400c88b38928ba2c843f25385f54c055f234ea38e991269a9b67c6441e389a17529e2f4fd8f07c510c07824b3e41765df9f0e8330d20b998f6800b2b9f7f12dc5d77934b8712abc0c5d6f330b3b935c702efa1b7193f121046bce535b4661321bc9e32f6a0aa54bb5df93b93cb02734e11d6f2fb40a8f7b16080b288a68ee6a6c9bd1075e60cd9373c8f5b1b61ea91631cdbb89f9bc8b68e3c947f1f2277dc142fb30bcca5045315c0bee125c95471794522f5819027f2c70482e40584148454078ff9212633d3e06f6cf8593fae75eeebe18d27d09f2d48e9b8fa6e0b6fb63de687a9b7650d0315ea8b94c939a5b1c982ea6d613f15a37379f49a3b3f63321be22a5d21262008c6c5a7ab9932d884f1520690d5e7bd3b9fc7da9a466d8503fd0b7917811cdeba056c1ae685948760be5037fdad1f453fb48988160f52942cc72ccd8ed74f05026c22ae8a94d5240e6b5b7ec24ce1a70610abeda1cf00bf0aa840e5d8a40adf47f293a9d57d251a19428b30de8912266260e1bb84d15651699f167d50d7d246f44cfed4c58f891ed8c6dcd1dab5a6885ddf4a33869016a3839273269c12280ce9f080c222f704c7d7e1e090748033ceda8ed0fa312061e457eacdf645b9e6e00b584cfc0d7d6af349f7030095b86d620e17f104dbbf77342db3af1cb1d74589ac03906b962a8e99e89d4e387526d0aab88048d3e563b01bda0411bef212f0ee61a2b1ef6d780c40b809419323e057cfb59f229bd6b35e33aafc8db49db20a975c04eefab4eff94860293d6c4a57705726d5a060421980aa5e2ad2346a242961f01e99001b48a899a2ee5a57e54de609f86ba4da839f8f26d4a3312590da1b5a56ff462a2e54d31cb21a85378b30bcd058fc24828e5f010727184cb843d665a20b0ca63e5de0973bbfaae1f98fb4ea9893bab433deb8d06b8145a58788802a9a16fd4fb31a310ba83767a7f463596677ad15243943777d7480d739e6da17b7843184634f6e1ff067795a4cd632dc1d9390e886813250bf4f873c85e8b61ee53f41a46240302b524c19bd504f5a3998a4e8be39f218681f31500f8e9e8ef7c159f296c30b5a70cab13890e9af1948d23bc5da95946395c7bb2086d97036053a5e5b45fe2394951979c2d10f2c6aef9ab5b70d453afb66930de0bf8001b0808b8c781553c3652c9368bf546cfbc0617a67b2e666d350d8eb421598ffb0b3ee3a8c5c5c0fe0f5568f36ae61c484e1b29a89ced021e6c7e1d23464b6e5bd609ce42cf17c4cf0eb9d489c590b69ec2df921fa8c381fd1d4e201d394af775ec4e201aadcb8dc2b73e441be004365a292f967f232cbdb7f66243253bc33a1bdb64a65e70e82ca9a30c48083cd9154dbde9ea50d0717ccc4e6c4e158a894abc77e8dad0086ba3275e73c85e11a4200010e799688ab48de361201777a08b1e7c20c40ad7ae73dbf165ccf89041b5c5881c7cdcb7879d9347a7e8e6ce7d2d30d33ee6846662d2c5ba0e256427f318d8257da8e645054d3f6e8cd7aecbf0628dce08ae9d8e1caee4086caed288da6fbf4844d6774fcfc68b938cb2b2f7d165c2fd43b1fef3b40b8279fa16ee89804c8b999c0da736e8fe4e32b349ddbc86364b3b10da54d08659caa3936935336a3d90f783fad4c92bf2d6405c6e5ae338d23f7fc738aae8163184dfd87f5b02865e4ac4dc64187b2421361b0109c43225582ee534c8663435fe1e00577f9c6afb052451d47917a6bdc677c7812dacbeb17ea7b854f7a3abce9176fc9d20984127b227eb864816e13194bd8610fbd36be2af180db20bf52788f2128d501ad83f1997b5406498b4ee5a9129466204fd721d695997c671ff24b13291104800d3c350d13ba77b06cfc8f663670005d49b9bdf85f0f97e753fe12b39fe571dfd8ce80c95845ea9822bf7e30f02e8ec8591137059325a077db61d6bab4426c994b7fdb6a4195910355cc43215b20c4613d0c57fe680d9cbf6473ab93b0805f77175e03954c3071fb3e101f804867ac3587144e07e0d1e1ef0fa2fb50042d2cdf3f695a52f46eeeee00c5eb5b193f9f84652eba1c74e91b0ea6fb4dc6dc6617b47d1d5d103733b10d47010ad7409d77561028a6ef5c7c5b950db6266c107b163593c90d6563dd055e27bdab685d5c4f6fd8f6840ab23c8de800c518e9adb54e072100329ee1e40532b9a7294c84f59299879d3bc41f3038bea6688db51363a49f813dc5bdf6ef66763c78d69f11e66bc42eea6b87f577749c3b7efdfe9b62d6cda02af88b1ebdd4ecbd878a5cef332871c14c323f8a96de8491744104df0f1d8c4c15556cf242928fee7b2eda5de61a8aa6e3492cf5296edd2e880d05352832c916b9b860e2fd39a5993fca4722f6c20edfc4de2ced6d998074e3e3f309cc5e543d6d6e7c220290d45d44b230d90f6092c4edfd7ba761698d9cb3893793d96754a15c38c64dfa52654e2185b70292a441e1ba256ab428d7f3fbbd2e7f480475afd0ec710d54399e6012fed34b2e3f06bd923e614c03a2ba0f0bf94369d0c6f78e94f7a929e0f182ba8b22538d971b32d13ce66bbfa42ea6cdccd5326a3bb324d00a02bb072ad020787e6926bd82c68fa10b75a042ab05ba3b497606361abcdec95deb3f404db5232d90773d37232368e71d37f18626aae67b518372d3c5b3f1751ca702345437b25217d7e1b15a5d9e98f8b6d0b391f199108bca9d073ecf43a95fb58f7e15776ee23595cc4ef987ee160efe0e51643f1eec8d058f8be181c00d1708eee15f49992928ea5bef649b3817f059561a08f5310ea9bbdb79e6f5bec09adc0165c93b0945b04ae519caf8dd5b4261f4d96f11f286f7a7f6492d41ea530d35b35465f8b625fb906e46d1370b4d9377cdad28d5d66d2e74cc8cd0a5f5f1b03c1e90f7e0c3f4cf9def59d945c343132ca2ef651de0510d1bd824e193d3380a140d4bb41e308694dd58552b5aae90b3ef760ca9b978c807ba052d4657e5073dae6316acb597bbeffd2db66e81f101bf6fe94c431fe6e043c39e94b2894dd5468d9808f42fc6133be0bd0d2929babc70986d0c69886d7dff8bc23b31a0bcb0314eb8d700cc587d5de600bcd7c90b1f292dfbf0c8940ce3d9e3b93cb6faa8142746c9f9d2007095ef306ad0f58789de3b822c6fa850a8036e58fb2f763b802d08b8bbb8bb121578bead47b6ac186fcfc4292858e09aa97581789d722df0a6f10cf34d1a93c5c0c79584a15f691f7a87fbde0dc868df3c709c1d05430433da393269e68dc86a3ca4c8e36304280001bcef377e855d426f89a35098dfa82d5b7f58418e34af2d4820dd95a82fb4153291bd4f301191807f8330b9c45976ce3689ee117b4412018611393f49853934a824bba1175bc8cc8dc8d8a00b91663ad03db19c7b42837ff3926b50d0caff8df09b910f92c9c5c6947304391ad18e7e838d329ef9979d8437e050e778a0b2134ac4f2d022dcbe40b366e670df96186d2cf268bc41702e1c2378fef02562e391d1e062c2b61c5c5f095343cdfe012442ca9e7b711eb88cef6987e0af0d79ea2a71004cdf16c57607326b5300d1c67ae841a8512d721910d808397ff4e868594c9244c4fec8e63265f396879b1d9fe6cdca420c87235b8636cbbfaf7710da596fd14c4957a6ae5b283f375da1a0d5d21aaa260c28bf694a1b9f6b9155e927d6438db41977edaf5d8a335d2bb9028afe5d517b0b5f4faa7639e3995acd0f2a1ce759531c72043f5bd8d3236b5f426c16e9df711b634adff019c55676b184e2a72ba438a3730570912cb1fef431ba40ab3ea5ec5d241e4b2c8c526a832e15ed7e84193d95bebf18a59b97045418039e4fac57e06d6e4a00e46ba2ae4fdb615da58270356548b0b2e34d431d9b4e40fe097377ad0ec8dc782fd779dade36189b2c7d6805fb00cec0e3cab16282a7388c34d9458855c710feff8287fbe5111c2b9aa71fd8db29669965ae13cd9a372004016d6ee5a3518f46ac22ba86bdde61bdeb7c312eeec1a044b67ed56491b05b61fbde8f979ea2658298b59ab4a501d839c7aa3014a51f0714e98233ed3b8fb2ce11809cfd7b0d2387f9522315d16abd5d26180619cb9094f9d106955d15126568cfa2f062b612979d3829a2c4ce9082a192500112cc4359158619943213ef6a6d6785cdbf31ad2507af4209d2833a8b0e45c6fb6b1cd6f070f446eab294085f73a4e91d33b35f007eb22773ff01516a390b78fc6b02c13cdbf6ef49681eca55bb823fe9125d5e1ae87dd98f553e4b3a1d32dbe7d4dab7820884dc16a3d60b2964a619b932d0714f8639943b0ccd3d67722a7214208ffc9e3f06ac8e568c2bee5e8c4ef0059cc7a06e7493ba0eccd6b80e398db82fafa0833c49bb9b9f5db569fd533e67bd72ce41072752c4d1b85ce599687640b8f3fd01e2e96d42da8d2390ae43610d58ac9a1ab276b3bead1fb3d2a0bfef2026b2bd2080fee8dad819a038f0a401313fb70bfc22fbf1a1934622650139d53de1ab2cbd13ea14f553212efa404384af01224b9eaa53441ed4f367d9daff0aed5a9b6087ec62d18cddcd6971a2425863a9fa4266f3a54ba36d3713224b90f2b237923cc47a746c1d1ed25891ff29b1300b3b82a6b170072e61b3820e3068aa2eab51db224f52085620704e2dd9e59e31251f97fe3fef9e562448c902fb0237ce511a122e32a5dad41120d90ee7630119869ff4dfaba1d76286e042cd1fa9b3ab0fc7d71209001e00b8d1de9d1bec1d6fec40045cebca030ba92c10bb3c5780c017adaf6543d9820e3c2859f73f851fc13f89bc5391e7768057c3fda0dc8154403d81dc3d94fe0b8ae5acf72af495be0971e8930e2ca50615c89bdd3be76f71e3a58cfec80a2350f5aa8e9e7b6aa9d50b8b99c3a7064b0e2550bba93497367553004fe038d16129b8e2cecf8f0d2e4448834291065f9d9a5d32e4e722b69a3b31453b311df3781ed589e1d7fa4bdc085b9fd80ebf0a115641a2508398d0d8ba6411ebc3b52647a08f81093126db538eb43c846775e612eb944604db738f00da3510252ab8596e5c2abe127daf017e734097176b4a4277eb0c6fef19067fa0840c572eb32d3d793a7f61d9dabab0ebbd66938cd1e1f2967ae985d85a456d4b8e2c3b0625c8ec06686280e9cc1689a82c516d50b189ce0034cd8a40edbb28e76b0fd085ed47fdbe6824a5d37bffb41323591b51dc177a46d6e4eb2e47f2f5460731a28e442df59b7bf761d731f7879b20898e5c1ac36aa23e364c6e8e712bcf9e74e3736d365261e0e50322903ffc4fbf9f8c78181c703e882ccdbf5e7d1da7d317797dbaaee4e884a319cda5e209bf379f6dd133c2d59818da0c3e282d7aa2349d4c69e8e35efd17d6bd9e0001401bb4d96907a878a990e523c50c008b7e97ccd10f74da0f456c034bd9bd8b2a5cd70192738dcf1dedab539f97d87576c8d426e89e0debe7f083ee892d177716ee11e563fa65ea33d24b8133c7c0dded4185cb8b71fccc174c977beeb1e6299a1e272ff090b492a49d3935db6a5b470bae5abf0fd2444885dcbd41e549e05a4dd7b1e06ef02694c5c38ab7c9df4d1260b9dc60d5418b6c946c804f56a34cba8804b76e5d0fb53c0c79cd72c8cd7d7306153e5635cccc6ab9da7e6ba3e742cfd764677f71fd5cb98e47f27179345b922f4b85d68f50322024edf388161cde64c8ef0f3dda9868e91e2f053388231f1c45110acf2e53774c2b8bdc9471c40e3dcdd70334f07799068dcd19ed92fa1438256f36f069957ca75920112ac4340a38d132ac8907eb4badd4a3e3039a9ddd1b31247614b44ca2c844f6a073980ed14ba27fcce646f38fdba844b7f24942766bee0147c9502b56b0d3b58d11189dbf2b4a8c7678096cea6499322fc408375ec2314c22b680dabd454838ca166e0875a7c65839c9c9769beaf55218a7f23b42c36fb38bb5023f53da63be39b726b4e3592ec5e483bda9d155303b98b93e918302e5e016cee34dc1fb50bee1fcc677c985ad479930c4786646f7e488487cdd7d4c7723bc362c4caf104e581c090754d438f88196a83c2df4e885f224edebd6d0a55bf721c76840f6778c7f7f6e489893dffcb11ce83962332b9c4b1106f584234d460b59709c4f52fd232cdfdcfd1d1661516731118c4aa7c3f3d13a97f0f04ef76cccefcf0c132042ac2b5b299d09495647a658e73e5f412ed09bf1194ae3654c8c77420d811b4f41453f29eaae615ece6d8bbff89f7e1dcc7ebbfbe4200c765dfe53bebdfcb8b3c62e750345b35943b6617c70562edad5f43fc4598cb628e0ebf197cae27b271a7c681403fbf75063716b11b6799378a1c3dd5dd28e16a646b4d363c7dc16ecbb4eb6270367f94c56e1a87aeaa5a064c376b19efaceecb9f49ee8196493245904d9d53c28a493b72305be59a92b819e6b3bd6019b22927c77fdcb058fe275d9ebf7e849cdfd783303cd8b3157f42a5f1e58f691cb9f26aeb4684abd61a5195c0fbd4fb702cbb7de22bfb80d0c1b1108d2bf1064849f4ecdc250bc602f3de106662f62756c8e9f085ec2ecfc2ab87a32a8d901b9822bac879e4610127ea7cc598bf5f0be9d0029782ea5d8198609703b82c8aa0a923cb1bac7c2ea43c9286e4246e647e4903d22467e466b0defe9af49e022b6677c7feaf2512d54ef7ccb5843c7b8ac0e02f723910003d7cd5bd3cf85c9ecb80b97fbed54dd8a9e06605c30647f25f2c1d5af11e8ca56ef4941cdb46ec448ac45a679c53bbb47dc3cce2a67b8a62faed8de55b2e149ab15a9668a3faa5235ebf67256b24d56bcdea3f7106027a7b41d222c116d9545f060ddf2e02c9631dfcdeb5e9716b6dfe9a6f0f3104ddfecad54cbac55674ce28a968814caa4d53a6a3ccc16e976ea6e25274712d2932f207734e7ccb97a6715aa8cb3b00b70599510b91b46063ecb153b53b92f665f52ef84486e187d563c7fb8196813040a9de292a1ca3863ab5bb7eb1695db1c1551d985601dd95769039b45ed89e342e055f0754f64934708374259288457a9f86698f49f60929e27c73f9744c2ef0ae9a975bbe3b41a44480bc914872da57a1ea1b2da70ce905a83f11dba2d728e7bf2924090c17de98a3329e5d16b2015802f654fa333e4dc772d05eedd6ff5c1ff405f9065a16e4484bd6e02ad1c0456e96dc18f959c9a895d61971b657b417e24e583dd93134cdc9d38df1ca6835ed63707be6fbece5d1ead8e37a34b9789d6daf2c84bec6f7c7b3115429e31c06cbb599c9d4d34650ab7b2572a95f2db137a13ee91b7c83374c54167e0596c8e45eceeb5cdcd9dff2dd83ea12edac3f92ab3406cf1a15903ca0b9b73af6b87cfa81cd5ea7a13f32b67382cb76fb22a03e8f711146745b2c590dabc7bca1f7ffb1b4f155bc7a40ce3f950544ab2513122ee43dc6f83d51a2eb1352db396bde831bf4807e03a92a43041485762cb643f354b676b7d69fd4cbc9aa93793add5724cfd69a695c9e0914fba8a6c36b1e520e4c14a69ea3f84e095459fa998b34eaa778cd9c152a572d42e422f8fd6c7ee239b7ce79215965118206c423de143471a43ff4540a11445601a4e533fc4abc11d899281088bc95fc129648ae80b352ba82b3777196389194bdffb52988a0e1e87df611600c06915489124a79957544d50b7adb7953866f3306ce5f01fce2a6e5df8a77ffeb0d942b0d29ad4310b878c533785177f2d8ef0a43aa913435c5bbf41b8fc2c4bb405bc6e491b819c909c1cd5980fcf4ce0dc46f55fc97f3e8cd8736220d832dbeb41346e22fc6d8a5fd9814c002c36669545b27e93959801227a78dfa7bb9187a5e521f9a4e83e92d2898af6328aec40e0c40da80ff262aaaefc9d9d6fae668e1475d32214cf575f12d57e26236f7cf6adefd42b3f20b5eeb77e3a2b9f28d79991e2405346548babe1bfe313aa5232a18059aaa09e094eac1efb3145c4c38791934f75cc45e1d41c0c1316230582c5f19f7db3520a0fbfea40a41b8608a3f181a263b17c2c97e676c6e1a22f88b3b36e8a5df3d5ef55b94f130332a763c9b435c586143c6729a08fc65f4310c32d866e470ecda254e389d484d4615503fe47491c551aca6803e9b9049cfb3af26d1bce1fbbb86b972de4a48b8f05e772838571521232969014bf26e54a8fcc182b7eba6cd06fd523a12b5b05841510fd6caa4a67b4fc3e73cf0546229629410c7edbb73fe7d5bb9fc32455f1904d8bf4cd17c518139156a70b0e9e14dd07047687e6f1f08d8a67ae3bbe96b33ea19ec786a6a3b9b9ceb028e86d2d7227962aec8301cf070a392f984d7c7a8039f8d71264c8b354a03a93adbf54976fbc4cdfa3e4316e0ff0746055388c8320bf5fa98bf2fd9bff6c9bc6bd442ba3bda33b8ced2bf2d07737418d6919249b2025aa8226cb6f4f8a00081de002c201a22ee89547292b32087db8bb2921a50f28a1b7b934f4ba18a0066ec79a9149b6a46d3d61daaa0512555099b5f9bb09598d88f4ab9123885397c83ea3c2ddc0b7852823763fe94f107ac7d983b4e21fa0044e9243c8e35eca91da5841d95bac4244685a982ac6b1f7abea93326b3d189dc344ac621b09698f1b5834fa8ab11d93597374d04561ec93faaf7c9e7a86d9911e32604365ceef04916babf3ccc6b4df87ddad6fbbbecc5646796519b471eddcb5df64c0193f52cfa93099396a5d4ce50d2b7fd9aac0f68fe2c09c3ca6bbb099106436c2a9bf1aa65b9850107e5c13a56fc504fa8458828440aa1165d380f0323b23aed656fb7a0c55eb681a1f06dbf77bb397adae1273f4ed29a38337387b868e20109fd9d180f9fe9aaaa1c0d04235a3b47aa8318f53944b981afaeebc72cbc9b1e0a167b092cc1946b30c868f5507b3a9487be17cb60c82445e56c9e283e98063edec61770b8130598417d59595668ce086586cef21c2f2389bb0ce1d00cbbf16cbdcebc78b182a58cdc4b31c99831a6914c7435d9673a9318141142a89945d526609ecdbb8c1a450b6994c5ae1a0eca8ad44bb00e4d783c623440f7733b5d0e56fa18b0887538fdff7a5b77470851be58f623b76117c4015a297a8c6e0d8dcde90f3bda59ee8a587ad9762ce46b12c84d17801d9c328e2503990f34aa5a57f5044540a4d5476c2ec0a663418e8ac6eab6ae7d7569e4a77bde663ea8d89ad2ce97f6c8f9052bab430db50f8556df978cfcd0571ea407a4bf2d811692dfd73e1974fde2fdc06b8641247bb18ddaa38c44e29dba502f5cffb21bb8e8e114cb12995bf4e7abd25d79ed862bb57eeb5f9f01ec592dfca43049692a346027c3c01176823d06f449e9aaa3d97e9afc14d4e7371329200653eaf2c25120169e3e4e702b63607ad6b07fb3acc80499a79105e80ed1a1444bae20d425ebfbb6ac0bf5a7270cc8b1dcb988c3255babb135e77120b41eb2c0db0d4243963a44f31575e045912134bdf239dd3cf2d7108239c3e2537babc0df993d63356f4c439e598be7a6f10f60df7b0f03313cf70ca7f479fdb01e2c37559ef41edc532cec08e46688630d40da6e9a5618aa4a0b1b625894e2246558dfa5293151b696a16c3045d901977297d75066ddfdae241bec33e08be3fdc1620d6d8febb8c72473ada3bf98c3c8c4b77e1c447c8ea1f26f78a54818c1024de3ec63d1c81f48b3f92b1a2745195c745387b70e2e93e669a8f7783351f06d72b1d96144ae1f3e16520f4fdb6dd7ebaaf93e6b65e5b1f812f7a9c93239d12eb55a40214abfc4689c5e27a7c02cbaebe8fa93b98f1ccc5c5d6ad597365239488edab9a5ee9bcb2ed024e08c2c90cfb9b063274e8339ed2f54b7cb11af7ad72c06fc6ba8abbe3ed2ba62b06805f75ddefed8e53b931d7353f675d71c3d1df2f4959fc8b5e1afc50e998ed57f909a48069a1482383d2a491285d024ce5d48062e0e52dba9b03028af150c981676faa87ca2879cbac5e68291be3e54d765920f9bb8a53237f3e60921793e2200782a485b829bf37f70e8d664674e9d97c52128ee4c2585f87dd12b081ca5e3606f7a36c16b7c1e3c3fdc9a4f575c474c462d4e7038a7614e5b0628bfeba377bd9c3e66e7beb4cbb838d7b1740352584abe8258ac18e28717db45a20ae9d4593e55f443f9e7daeb48daf47a271c99efa8339e2f6cbf63c043e1bb865e5f9462912bcf88a445ff50f6224f29b7b0457384e48f745b4d58fc7e464037e42816e408ce4d5a840dbe4b5274d560ec10209668226b03ddbc090673dabd5f3ca350384ad704da1482c6ffe53f09b729727c8d4e0b1e438cda3c512b4f6dfcf31373499807014e0aca6e6f18868d4a0d042b052aae4a73449970292de34060867d0f64db7d41d653cd66e49751f37158ee83499535371690ab2c37b9bc1018577c6bc57fb9e1b78015586bb7894be40f0cf7e0000000\";\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(\"Swarmcentaur\", 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 [\"Young centaur\", \"Young centaur\", \"Young centaur\", \"Young centaur\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Burlap tunic and bead necklace\", \"Burlap tunic and bead necklace\", \"Burlap tunic and bead necklace\", \"Burlap tunic and bead necklace\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Golden firefly glow\", \"Golden firefly glow\", \"Golden firefly glow\", \"Golden firefly glow\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Teal enchanted forest\", \"Teal enchanted forest\", \"Teal enchanted forest\", \"Teal enchanted forest\"];\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\":\"Swarmcentaur #', id.toString(),\n            '\",\"description\":\"Swarmcentaur is 777 Friendly young centaur with a shaggy chestnut mane circled by a glowing swarm of golden fireflies and tiny bees in a teal enchanted forest. 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\":\"Swarmcentaur\",\"description\":\"Swarmcentaur is 777 Friendly young centaur with a shaggy chestnut mane circled by a glowing swarm of golden fireflies and tiny bees in a teal enchanted forest. 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":"58267921","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-03T21:39:25Z","match":"exact_match","chainId":"56","address":"0x87B805eCDDaB0b376531cAf6d5aD9A52E641B100"}