{"sources":{"Swarmdrake.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: Swarmdrake.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Swarmdrake - 666 Baby jade dragon with golden horns surrounded by a swarm of glowing fireflies on a purple-teal gradient for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 666 free pool lasts (gas only).\n/// Every other mint costs 0.00007 BNB. Max 50 per wallet, 666 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 Swarmdrake is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 666;\n    uint256 public constant FREE_SUPPLY = 666;\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(\"Swarmdrake\", \"SWARMDRAKE\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"524946469e3f00005745425056503820923f0000d02b019d012a900190013ec158a34d27a52b39a9d50b63301809646ed900a110c7d416656a1a5db0f5781513221db97ad3cb72407927c2b8cbe263ced9cdfb2f7c3ffc3eb7370679a5f379f535fdc3d1dbaa33d0c3a68ffbbe101f95ef8cff41ff1fc53fc8bec9fe1f9aebe5ff3bfcb79306633ce2d42ff2ef1e38b075ae81ff58ef42d72fc79ae05407f264ff83cc9ea2269062962427d2ebd15da37ca59c4bd83c4e29601b62e9ff4536e5b5b2139c1152f81a7fa7216e83e60d53e42fb6e9aad11f95c04261becf4d817a39f426909048916fed010fc9287c233b658fc1f7c99413707848056c1b59da11fbbb968ffa1d7a211e4a6fcdac85a5febe14672382020c6fa23bf08845f67d272492f37426e3dcf79e9c2ee8bbdeae8d68428bf03909ed0d8ca15c0ba8bbeb0b54c7b6469c6fc7df6d6a3b494459ffdbce019504c720220bf8f32a824db9d485cbaeae61c286e7e5e42438fcdd6cb6b99b0b3bab1a3ce6cf28874fc8637c2a855c96c33256304c1ebf32cfc95035f8a33855bfc08c4804a4a52f3799ceed2b4a8e2ec2d36fd6539a45e48b1cd42d2ce43c276d38d1d275450505fa490218f2ba49de560841b2e45ba67240d7e53b1e89bc70f73d524a4021d61944629eca075dd85c7d961449078ef59aec3fdf5a3bb4aafe0b3dacb17f07f2abebe6f5469bd7756e154cc5e969e0247f7590641e6d1fb43c69d4a74f6791ed646af6d5df4cb2279a38b5604e97cfe00562bffc4b38e528bed1955bb6581bb6669c151a7e2837d2d69d9fc5b43378dacea1a5ed16e062f968334a52d3005e3482dfd7a5cd3d29b8c10b12eb45d17ab745ae7a58a45e7de6ff0514432a80e3e83d7d871c7691d9d6dd9c495fd2f71b063e12ac2f25c05c7bf7e45c312fdf9cab33aa449c93dbfd43d433e73d371c309c46de1007b5ac24abde63332f075dc592e3beb15997531dd37adc76c31c11d448c5c426112c1d28fb74ef5682005d2e462ec8ab7fe8934a90aa2061662d9784e6c7f4e5a90678f80057065713d76d74937454bad5d311cc4e21cf2893b6d190c12cfbe16b28f8f11b738d283eb5caec8f9985593f7824419f8cb41664ac652957b4dcfc5e938e6fc72691a8b83266b0c2fdabd0498d8ec427f0ab8cda85264b60403510f7db55a7cccb47faa98ff4284b3e944a0e98bddd8ef08b5b766902e4b9d8c099b9dbb651ccad9fa4bb8db456ceae56e97e9c4b1ea89de3d2c31651cf2e5055a04016cc5ba0e0480c330ea5d287aff5536eaba079259a017f01ba6ac7f7667acb989c5e331d5af0b7d834b6b2c45fd963deadf5c23ac6e1cacb1069bdf4fd4a55ca37f6ecd72d44cff012c72f1477321cf4321888918f457a933da1aca6456eb845ba1d4bbe0183d89ff212edce2997f3fe5de925e821e281b342a33437d5921b67ee7ba7330d26a10a8723787dd50ec271d98b646bbf864910e810d428f75e829647d7ebf1866447d15ad6329f00b0fc090e862114876f08bdc1920aba03b878d0fdbe6fcc1ed468c0d7610057ae87bdefeac0cb7f72af32d80c0e91b5e2b192df1fe1c1dfa645ba63f4535101cfa3c3ebf354e17c1b2ce76e5d45349efa88d98b399ba060b76da488e60d54763474a0c59b52109f6487d0783ac46f7c5fe8225d5cc94f49d3d96a342a9061ece52fba5321e096d5ca34aa521f24f21b1cd261cb8490e717c86655f61d70a6fe1de3914102264f46d2d1310b4ddc71f082f5584fbe3acec73432ac129dc9003fd2dc31cc74e6720187b7659d15e33b2f4803db1a3eca5a40dd491a035d3a05b8aaa1e2261f6f94e4800314862552b95dfb0c8084bb0449484a924e824cf381828de97743d680c4c6419a9dc36ce3db4ae8b55c25d828fc07cdefeb1fc12f5aaf088dfcd3412c35e1b1ac01302550a060622791c13f2fc4de15d506f3ceed9e50eb58a985836f71d36595b00ea1f5e22a9c259e0eb1852aacc657e1c040ae11cb6638ba3d8f0da9e8594d2a6913c32dbfa48e7f9a7cff760d3adc9f5f16adb3dc89c8a63c3ca7f53e0ff288df8cc635189706640a1a52824259e999b60719d6560a412c5f183c831bcaaf6a8498640b117fad3132722efe3ad57bc30f9002c92dc81e6da303c8d855dfbdb9aebdccf837bd581fde589714fc5cfbae852cfe3372046ebd113f843f9e853e9daad8095b5d14e67188f7f2608d9ad812be1ceb07d43483b51640d1887da6649c30ecda8412eed0010eef8238a8cd6651b407f6e4957f0785064fdb5cd8509698ca545166f5cffe2fff68850b2aa980042c307444c2e7b2bfb3a80aec6c7ea693ff3788b0d3cf62dd9e5af2630ace19b8d19ad94d4837d3bcbe8dc38e4bd061a871fcaf4cf9b4c5ade84336717260b18dafd9dd30a670bd4a6e617cd7556173f60a927bc2f8807dbc880b2de448045f924c464fbae2500c2621802b963e8618cccf2b5211dc3354ee95073a44a1d32592589f7caa283e48a999f02eb22902ed8eaa3f66e911e0781395777001c9964653f3931ad07b96c6d274a47e9587ec6ad79e49116ac5679efc118db1e7a1c8132762888b5fd00b3f681adea6f97a485902d562652fb56b0371181f718cf63e6845698c4df7b30e1ccc8de10a388faa7c331eed468264577465b9a3345100cb630f2884acbfca0fff144e613767b5b3af98093c50e6bfa30b51b218d852c86130834bbf4eccac7c7959b50b766037bbd643bdd3fcda33b0b48e2359c361d99e41c0b92acc3bb1eb4f8ebb5b70ac47e9916a9a140456224cad88224b5d2cba157df1e02b05fea56b06a110692036e935ddf66e3e34a989a7bb66a44f0e03e282188da6d9b8e1862f1be80731de42588b8e4ae5d80dffb2cdfe73b9419d8a76effdbcecdf0dcc6d31bf1af21071c144ce6a63f4e1cb0e1b4da2f193df76965330092cc253e7fd2accbc9bc49fa52e2e2b1b261742939398d239e4e56df659bfa67133626d200f21f4b48e3e6d5914dea258136e145142ca2570460739bea6a5b0e45b30790a6ff026860350ec0fda73d1c0d8d1995086e342246e03d77286cab67b712712687aad0305a4eea7c30ada9b89932ff771f392a0c3c81cbafbc009352a8003c6a692a5f7eacdd10570b9350c4d313387af12dedf2bc4f3b46cc5424fb4d8e026885d1f9f2115ec62d80557b1b2c5d7990c21003646a1ef7fa50e37b4a549007f42e0b824af6432bbb549aa5978b5d8a7d14fe222354ce21f64e7671ac9c835d158aab70937def9f14210f8413aee749c415b4aad6f7f7c926cc8e367c9b7d59a208f86b62d6972d852651594d334881b613edf67fcadf88ea4313113740e92eff597ac7597aded40bba7db04061618740e050e007ca2bb977974954e7d428cd801820ca5e000fef5e19fdba9a4dd0876dd7065710158981859c2bddaf3084d68e6246021a6e609c977082abc7250485146d3bac4dfda8de65378bf1e8a4df5987aa08f11bed86bc415f60eec8809a70970c00e958c98eec866d3ab74f38e1b87b516cbc18dc4bafc2954eb4441c461dceb97a702cfe4c1627305bdabc3552952acc62453dcc7872ca86d1f067b6b30c8a5a041d31acc9d87c06f207fefce597643e117e73b13342111def8957407e731ff7619f020433233b98dbdb8c0cca72f59d7c6c31f48f704cbfdd2f97942eb3af168024b7d7dd1d8e253cfe8e04e8bce6de44316714c2fcac25a865913b554456094266102f7a52827e31665f77afb8bfd7304c34ed9835e72d9e96b7ed745e780ac0a5ee5be43dc361faa33d04c649f9f57d8df3a6b85de16f0285ae41ce8d7c9d59a5eebc0862bbd40fef0504ffd00ed47905d613889444cd4d5b9082256a7322f6780a244c3bc6a96e65e4a7ee312b5ce3fc53404f2fe884bbcf5446c0728ef31544b302c1b4ae169983ff8583ffe5018f0f2535cc8454fcf78b52246ea4be4e51f1e19dbc35c1eefcd40cb81bfc79aa7b6cf77f12539f0d4b115d1f1a5e1c2786bde44f9d5b45cc45ac8ec42d665f932bf162fb40459e5dd40fc018365169dfaeb21d94f470420a4b1d6b4bb839212759231b19cca1e84e15702e9d5f8ef3d935ec91bdfe5d3b56c250522787a93963d4286ca0b4209b7a29c11c0b458738d82bc6f71a8c2a0402b3f1b80f157d60f2a3006806fcc722fe5c7f12a65f0e28abd7553ae87b4c79af0e35cc5ef6766891dc1ac1fcfda284d2f177ec466feaa4ba0a8d946b5aa6e18dcd1695b47abf19df2650ed4033260001ddc57ac5d2c7206e32f7bd90f1efd8fe5b9039f4b05d890a15a77c0cd9486ca8fe7ea949d6f6c51095eea936ece5c40dcd75517d96bda6fac85bc5709d3eb9b23d3b0e141e1ef73779da20eebf8c29a06a004db0b922195b18f9b3991063d2ce0b669100c3019f7df594ff98daa69cd8e808114f193957564b74381dad1be17caf218e6fd9f670b7fba447fba4bb8f1e876f8ecb8593d91db7628909e5469e9dbc921f9c7e9de9f67717877986842f377f87dbeb939c0d2d2592ddf997cf5b5e4b3ae773a61194afd1c9093dfdb4941debd5fe71bd776f8b845f0ff7bebd1a765700fff77ddd7367b4bcd068b0c12cc6b0cbe629ac62edfa525fee5d06c6f9548d66980e5081f4d04080e2d80c20f79ebf208deffbf8103a604fcae32e72752fc4d553a1527aef47fca2c2fd7e2d244bee2f7d67ab580c9f867ca909bdff03372829f12a4f086ea967c0e9b6dfd88e00786748fcf1f06271e8a23b8155245aefae0d4b5786b41dc7535de3971f241a6fdcfed0b65c4f6a4eeeef367f4a39cb9bd738e1eade63db50be3906e7103f1b77ffc9f4f63f671c5ff7682b295b35c0cc5e3541ba317d5b3f13431b873613cbf341d1f98ca5fee54ab005199e36382650193665cadff93bccd7cb4a7470cb2f90a1f04d0a5ca609178bb8879e91fd2f1894e0e26ba49c6d7da83feb9f996aa430c8345a3b865a2218b8e22f89183d4db131cd3bf7846e85c30739be49ec82bbf140f26ec5b6e3e666422492b7f29d0892bd7ddea9dc2f202f01e12b9f02d4ab4df5666dc27ebd8982a2f2caeff66b09e74d233431366ff11af6f7281d95a43156ebf2a947f625557cec6b4ba3c7b0a838a5155b856458132fd014fa47d8a5b7f12dbfe9bd3d16ff74bca9a6fe3083c0ab21c82756a0e7bd1f2e0a8d2fdf7b4961a75830ad04eef2eb82efb974fbd5b6339a70fee267f86d8b722a5ffc2330cd30ae41d5fdea88d94b0a9e9f140da0e9d395714de14d05c21839d55fb99e39c500cb6df37d45bb825101376ec502122ecbbfa8ce5adb4b8422b24b273e6665b5ae389177ba174f7dcdd775c3ee2a5d127ecd2c54a4a6608afa35defdc32fa4339168473041e4a61d6032f478775f5f3ebcaa76a0c3dd5b9513399b6b4474b416a5309f0dd289e57401da1e737c91bf9e7a354c80c5fabc01851bd39207c7acab190f3832e2460f864a232e9129bcc620e0a09b991212bef4c3b2305734ec480ec30f8a9aad4f00750b39d20ff7ef90d6747aaa7c46a89f42e823aeca1fe76de8414cab4def4f443b4572d40d8c95f0c9e2b8c7640d257a2e3c09def3e9e5f3eb99fe33d5700af9a43fb60644181cbc61a746fae0ac0ddab2730014f7b59c4d85d3694650c5000d477799c2e282f9021792e801438e3ac4d90c2f65e74dad97cb689c0673f1542efb4798e484314a52db1f80f44653b2d956587e0c9c54a06ef4f1147c3a86ae1558db118dea232c9aaf74180bae5cb4643ccc981ad6596c3dc91140b65d88de0e95b4695209b8339ffa21b68a8e57bb42e4cfbd1f8ee86ceba1a31ab0bf28b323ddf982d41d314fa85b60439749730ecaf83fb9c8d872b89f6ed3aca2a10ab9fcf02988974a9f65e6a33b9450858c3c07bd2ec4525e0f0ebf8bab2efefa8a67f984cbd30ef1a7b38491e49cfcb64c68bab90e06371bd7457f2255630aecf2b370308b121898781a60d9a3e561a17b038cf0b18f0e46ecf2065f84ff001bd1031d10fe444d83d8275482b67665f1aff6497c84dbd9bd67282f34751488a84872e8574afbaa2417107659b5ad7e12a804743336e86ddffc9d74e8272f225b17eb58b06949925c94ca4c9ef2a6bbbea9b83c68eec7e2bf50b46d1d4baa6218c0a0b4411e49063ef9b7f3934c9215444be620b474e1f49f2f8340ff19db255c1637631fbc9767e16654a517097478bf87ff4bafaadcbaf13a22ecf02fb9de0b72e08ead5d6e37d8f4c47fb1653d65ac5aa7f728d7b128265b48444d4e10dd901f99ba435e85381fcedf7968cff9d444b72753132c3af43cd7c54ef189f57ead1005b44e8ed0450f40191e0131ee7cc1eb29f0a70095db1a95925e9cabf2accd6a832698234b4817a65f2f7158f629ca6a22a7ec8ce9682508dbaf3db83672f047918e001efe3bc85e2766bcaf4c391a7a42a9eb7eaf8e6c37ebf1c59f10a77812bba09120f78e1c4c9689fd5eed93fc0f8cce3a97880679b7549306957995c43327023c5488a8b300344dfa83e9ee13eb7193cbd117182f4d1abf0854e58256f026a11918471a20598a84163b86149f25bdf927b2c1883d2e41a4d1488eb61b036002d2c6bcd2776201e466d693bedb6d0021cd4363d0ac21f545d80c3393c86b7d24b96b96f674409c7a962151674d8961ffd6d4bab70d79528253e88eb3f87bdaaf3fe3bf5a21c8d38c2523cd3cf8da4cd3d47877c9715b0a1615d5860a29d1631a2e3c050455f8449abca8af9039711eaeed730ff181ecd6b8e54358522daff1b6a03d7b43b9951b06a79f5712ad854eb87021adb28261e25f37e6aeb942fa2505be980cd375bef0675c1462cbf7de3aedd1710dc927af52e25ff5b4ae387cc0a5bb68906a7a7f55ff913c6b8228740d79e7bc7145eb8afad29c60f6870829a9a81edce737264df6243b84ec06e88f00e5d4a43287acc88e40fe4b8a997aa71187d3ddf9a71fd63821e381cc432846e2142d01d3b014b7a12118f6938a10aa53f138be8a295e957e182930e4d4b2b5f86d35074b2349e3ab69619ccddccad63ac2c9dc287898088425f00fe0b4e61f0d3944447f84c02a6c1325b7c3edd8afde967f672043b0e3b7e575ec2b9fda52860fd1864988346645a71a391914339043c2feb3103a9b4b766c106b6cd9d4befce5e6af0e4ea51f181c87269963afd2270106ee8b29363c5cd029e0dc62eddd2cba5e92bb31c7f3ab37a0a4d704d22b1d9b0829bc5c2eadf32f2af884ccd2711f3448f9435b99e7b8e9ffd5d5a94e3b38503d25617456ea72ad107b890ce3f128c7cfbeedc2278b7045425432230d08403b2736be76d3a0bde40c832d2f0819fe34cc54862083bd2fb401f9f44197684a078c1f204222409cdc37e6daae4bc7bf0203ec9628f2fad2413c1117fe11a461ce2e65fbcda25ca2a987e5115907f07551d498bb5bfbe0b0b0c5cd4fcf38c478e83f9a7f6ace08d670edd6e66c03031721e08a5712c4027ce7549df9e00e0e44a8b99b504b2d11c0767b9dc4da33eca205fbe4044df22dc2ef31da2893126c06e11e92ed4ca7cd7a747cc80788b4f648cf26a1a8218b06bf283af30c90035a679cda57e18a5fdb5eae121fac3a22e3cd02daa88dd79726a97d4bd2044f3f7ed5a08cad96eea67adbdf7bce04096076a74ca89401842741b4d46132aaec3016b7199ea11ebc86f0a2d55049c53ee60cd43a977ec168a4ab847c49c4fc64912632dc5460ad33106cd6cfe1dd2445366770bd394da9cde4573b6e44fe19b16e75d27b080955e817282ac748ed3af0aee8ea55146f38e9c536b47bec76f5a80440d7a654a667b2c8397e18094b4a83ceff455e3f47b255702649d7fb1c9c664464689741e3291e7d35277f82ddab77cfe41400904575b0d62a5c55c338a0d22708235fa89bdde4a5220018c5884f936dc4c9c0346455f2e368c8c72cd5ee17d6955ce6555380cfa178ebc11fa3f804d7dcaa3f2bb9fb3c79a4877fb27d0dc151b75f6545e939e87700d56b1c85b0742865977b0ec44d6e6dfc4987e073cd15e6a3736e29187e8a68aea2bfe0b6d41bb0de46d621d7d50a4555d88ad9dabcb5462d22ea04087e9747dd154b6631797725be2a90f1208a58e7ea6108e4077265b55d74b69ed897e938278b77afc82d14ae5e0b5b6199d70e436243aca903e411c60ebefd76d0771fd168333d84ea3990c1353b5c45918d9ae034f9c0c62ef26bcc24306e0f185a3866469fee7858d4fe46b0a213b4451309e03ae93c7ce4e4dbbde3ddf94ba3ed4c8ba56a3ba0cac606c3c2639ee934d0e6e9718370ec7203fcffe53df70c5148eda1ec47ce259e69a8876bf0fac0709ffd3904d4f1ba5ae1470199b257fc26edbdfe0f5f2ae1c872e0d3c0e57f8544b452245fb5569fcbe899200e17473de9ee601a5f134dd7b07abb036e77da849a3a922dca1caae1f093470c12357207b0b6bc5031eb3e5fd1d5b24d4d4418a8aed0243eb659ed93de7bd81e1361533553ab5354f201ce6da690fb129387cb49bdfd02c0e1128fcb9bb567e14fcaa9492357f955ade8eb22811647c45d5a9a34844cb6863b4f33b26bb3f11b6a72cd6eef2260b390a113fd9de7e9fddcf84a6107f28d9532c464133b21d7e36d6a07969d407cc4f682ecff533b5adcab5417d558b0af4eb31ad5997c2274f1243a90ec48e87e36ca6bcacdffd9bf6d17a4e36de533bb48df3ffe8175a8882be37f09ece599c64d503c1bebc48403da43952e839ea625fc25efe70f499f9240d1fc187b5bc035a39f88e2ff95a11272af16f1dcfb797717ba424544c7ba3ec67bc7bfc82ce80f969a9f1bf2a07af24762396a036c80613475415000b180baaebb15516054599595c2de2493f2004a57280e160776bebe83ff34514d46f80b06c035993e41a1db06beb566b3ddfc8008ae67051cd88f2c6f77999ffca75b23f18d9a25380194bf6f24df353a721514a5a42ed7c431643ee6d1ebfa5b61bf2357e961d9caf3acebdeb44b6a3c775855be7e8825790a6655b4c90abb619cfac98e67d2dddc903b2ca3a97f4f7816d6a5851af9df002def0fe5eb8e17d894489d69913bbff52604ec60f7af63b629fa409700b480d236f03a67d2cba676bdc69a0a8e37145c7147139ba9d6226900fc244be7ea9e65b8afca47d2fcc576c9649734c179c37e902728177876b2e95107a4db1f177187fecf89369411ad06cdb51d433e7e707ee64d4b28307114f88038ffa6c185645e74fa63fc65a5256db5a771fe9ba4537a315a87f59513052d8acee59868e4f0ac37a6e70f16f8b4dc1162fd432a84a9efa634d6d75f1e71a103179de6f6dc76d2fed67c519735c1f8c832e0ad23ae199440f1e7389cc4c880e97f730cb6e92dcb340dbc6ed344694eb3acc824d9355ff464e28e422ede535e076ad40710d268c91e815bc6f555c12ffc970a48f1bc66b795f1e729dd10c98a8b2a669d17b618a1a065eb1478490414a027c69d6cb1b631feee5927e7bd8fe6549de644bfe677f682ddcbafc5400f91992f4b3c5315f7aa213aeb14f06962ce1d0558f3f51b8f0644cedaf8743996e26a1e2380c3c998413e6ffd9a7c9901f7f96f383c0f56d290579e541667d3fb4239f2b097d18ebd82711043c5d0ddeb333edc7d9c073a56db16e1c203dd86190f35ca5a3f452aea7d03cd3cf021b66f0f4f37c5ef469bb3339386a74384859e435b945d2e3122fd4a6bab7b319e46de60c09d2225f9ab7a52e29650d12247458d3c0d448342f0c564880405c95f1411992fc3fcc2158c7e0782b84587c470258afaccd32116d08f307690ba4d0c83c67de1e445b29d3dcb0ee1645141bece3f8c96c6a54d4f816f658489272533c5ee2f98b41737db5583001f27f265699db821df54017e44d1a058f038d4f1539fc26e69a1c72be109820027de836df901aad46203a87142da2122d67f4a0ce7ea4279246d62e3c123d3f8aaba012d612a35465e9987fb65082cc1a02ada8382dc3772312e8d004525a7dc5bbaf56775199651ccaa3eab51654203c8180eb64b0e8c5a38bc74097e97777dc629a152c5da215bc0d64e4d44faf4e8fe8b94e0a5d3b0174e260316fc7d76d0c6449c859215ee66dc232c0f6a24c4f33b4cb41c4f24db3decb528b71aba920e70eb4bcbd532a6d77879b4bfeb723695aecd59a586ae203718b07ae0a791f5e62a6924fe20de2bcbb27ecb1cdebdbe6692d2d016aff89c82438d90379a51243a44b4542efa4bf7e208fc80f8d9e7d113b9fd401f07c366546abbf234b256bbff55a6fd84a3690ca88fb1c2dd7b3108a8ceab336af948492fa3c6a8c07435043e99e7704063b08f821da057bc6dcc4a06375028c94e79d4b20476b3c39f80974c0263c0c0e2c62621778be492a5c257973b175df1818e25867e4c4e2306f54322ce09a7ef9bfde640c2d0c6e73462f9b8b8da1595ae505c4667125a8517dda8c6fefda1e48d6091846557c6a7c7f20978b6e99533ef1d1a0aec185dcbc76747e3abff119a6d60521f5ba29dbcaa28765e3b11948e25ca9119eb976187ac44166b8ad9250cbfda27418a7251923a631275fbf4b19bef39087575b04cb7d2fec0db1c76a0c75ba7bf87ee140fef4923f1ab1d78235a4c4cc794a58840d9e71b8b44b31694cf43e0816b3600a05b03f0f32cf86ef8bf90086f3168bc2fea92910f7542036d8e5751a299b8fc0c5378a21ec29d4368497897b38e578732863d0fcfd64526d6d8faeee1c828fadddafb6e4e381b01109c1ecb25c8ff4dd9ad65dbe10c103f5e6a7d3e65576f11687b6307b47bdb51f93b8793254e0763ee0869f2d67a2e989a5a2d46c19525b1ee6f86f533b71712fd8311d957a61ef1c147dac3cd7b546ec5de61224561b512eb4b1184cbe5ab4e377fdb961e362e7ce018997b7dcc06a5347fa24f930dee76d8e0e6581392fd791a9f3c60b07925b17aac04dfae836aa353343779075a665aebb2939431837a403c7a1da992c1341d0c64d566182b9743287183f62558842ac921c41b6012b917e427c04a49324dc9161418eef3588688f190cac64317c4caea15b012eaa4a91c725ddf88d85c5ad727f14c195b44297c9bc46a1f1bbdb1aa61974eb7168e4e1d1dc3043e22e1539a4fed61ffe23608b3dc6ccc742243a7c02871709642ebb898a7e5c0c7bccbced5321e770b3ebef8287f4cf2e17dd97ceb640f8455a055aa6dbc8f00e09e1046901a7f6862d7404fabe999bd0cb84954fdb7b41aab05c0899a4d348f7aee6e967e06cdc6eec34a20b1164bfcee9246c0b5299e15735ac21ad35c2e96d322de06b0e6ee56a72be97802a25f2dc9f2e3a48cc92af743803a253b7c437b3e6257b61a88a30575bd5609471881c4f42c09ba1a4572dfd61d0b35c911f1ac6a3434d5b6c716ca5f18b6f29ff23060b47529070dffe4e1e293e95fd912cd4b4dc8838c6e41c81ad06aae9a520e129941221a17998c3d350431d8a3d12f6f39d1617782b7559ec4cc1dea0e8345dca9693270900c60d6629f9f72fca63b1c9ffcdff445c41730be46c338ada8991ee8e681fc61fc34c5f941df52a20bf725992b7763183fb402d843f30f70ebe2d98640476ec4fe726a0e6a037c505ce69219118540339467edb24848bda9cf9fe418c00d24434e45bbec696951fd7ae47ca1ad69b84810b77eb703363be476df1b841a17801c30324fa1ac510569998a58c58b2540ecabb931ca3baf7649001210cca15ba0fc5e6b2174d9037ec7a9a98956c91c54e58bfd018351c18fb8a9b364284b264fe8a1420e01ab0444842db995d22ab5749d75ba2f382639b0801e5be3511c9cd8b4bf0383070942dfb89fd6dd9940bae615f2bf3261b887e4bceca3cf55476301eb97303cff319cb2fa2d9b324f79d0b952913317a7b11f86a85aca440fce4f0b77c3cad14fe7ed8a91574c215aefbb3338a1c8c7aafce782db00d2fcdbd91c27c1ca00d9aed783a74fb6826178a6de9c1cd3b6b73bc6cc912d80676708b55ecf693c0f502d6985d39b44ca85d882e9c7363faaef8e424e3378a1aee7b108e7ca8632885c2116a626cd4d962f60a1bccd412cbb21bde0d1508865509080acbc61b3281cbb5285ef54e5e584daa2bd1c39cf8e86d9ec5e322e8af95676bf25d6faa36b0288bbe01dc8f53a08a0b2663b5dd7154eec4f8ae2f56f88ef0d7c2f91444d04fa94d01d44b9f25263eca9ac0efc5f5189f5b497eaff3b478160cfcdf515bb5212a31cbc0a1dcbbfbebcb9cc6fe846811c91a74c8ad91d32a0cb522640b5cd2325e725df288e437fd8795b45f22000f8b3543cd23ff5cbb1b708e23d1daca75635a9b8ce092d26da48688b135c187f9e72fe98e282864d380a6a5902bea376f048d3f62f5445fb8dd78482d56fc1315e385e8a9d3f25f2f9e9ded1f7df0a92e758c7569594b4a3dc14aa83d83625a2419f417518801374db0854bb91317f385efff705df131fefe030796806d7a9285265b6b31d772230e712bbd77cef054536d79a9fa9671e46e20d384252a4adef2565ef63bc6e636485d660e2cf5ebc01eedad8075d9d6b5688f3b3ddf0733901960cdd48a809730354f885d2c49061cd51ab286ae016b2ae8ad23cd81d207fcc0aa1bdf5b6166f94b4a3e1afd4529fd0fea54be64e98bd6160d74e348c0cfb61a358e68b7d8d6af1946d920b41226379130ead11c4a8b224c3919d1928ce3b15da7bbcf39e0fa701f3ebef5e654685dca71013f388dd19a23e351f7b170631cc9bc764dc8476ea57f39cc3ef90227b29a7337429af9f92d51d2de846c42c0e61fb72df5a9011f3dc2b40fada238e07da1665b8818f5a5a619259b55f58c02d456dc788f87ba0d522f1971f94481828bee87604fe91aa088d99380cc2502bf70845fb8e77b7197b6dea35c228c35b5c283f9c9714aa140315329956d1f4506b39afbd080d44b4d95cebedb637691f1c0aa2ff3498ae233b29ca6909b11736f9a703889fb78904a812d00be8e2520a5eb31ac9f1ce62b43b2a3c0a0bdf5a8be211ec958d814606bede1e1646a0d878c760b4566c2611aebee35da786d41ef95f99ce123664f94477e304a8616baeda6904775381219d120b3f2854d1d12f4cb3e7f342c019a40ab74dd0c44c7d5a7fad8ede686a696257e0f506deb9c71c5ad1a3e99450cfdad151b97616da6a5110fb2a7712d0af07e5fa66b26b90a808ffa212e13ec689d00f727b5c24e812025cba49490d04768ecab9e89f3d8abe09965a8ba03848b31bdfd6273515fa32394568f9d054287a49555c3a4f2dd9ef37df9627e2b3db25d935a0b5b36d20a6d2aa687aa86517d2c1b18871f35d89e59f26cc2cbbd18c714aed5c58a2cd10c93a4783e61ca3939b0308701d2208c698aa5e1d2f04bd329aa932547fcd27e5739fb45264561e0289d55bbc098566dc8014f3dc0440329ce83f8cdc862dbb70c7c37d61081c21f9469769a6bffa486844ad105c025bbb75f6dd9f6a02b7725f00d2be0942b3006d6d320913f5035bff6b2cb845dd5e509ff48a96c40dbb3ed129f90b5cb7e132daea7823b72755b876f5cf70b8b083929620ef1d384819838bb53399f8cf34c18600b5ff97f6974b3e777df34843c08935007df3a09e82d5cb3a324a8cc17542b8fe4537eb3a9b82b8fbae45ab0a978ad688c1c21db768ffb8e679fb938ebe8cf61761b23fde04ed0b8bf401266127adf47bdac22063c8d2f05404ce09cfad58054d2d184cddff0846b9d3f84a4b7c0c773b6202641424cf927786ac0c83b6da2a15272c3865d1b56e47152b83021b3f3609c331f19dbf1f879fa24424b7528db95ed1783ebd478541e2d3b463ff0b6bcb63284f11d1b02e8b2a3efba0a0fa41b68f76ef2463ccb894155cac0dd7e4351083a4bafcdae2eb2971fe593821c22c9d276dc5f845297c5133ccbb42ff93582119b8962a81d39d4f1a193ddcabc8700c8a7bdecf9385b43f96a2257302711316db1b6487a6ff04c2fe2a78151e831455c3a3f23a920354bf118a8d9b4f1f480f7fa68331984e29df69552ca9f5a66258bca5160b49ea17cd79ca6d71ce8530a6eef968fa525ce49d24e2acfff76f3eb876cb423062b8d29f822a1ce859d9fe614e7c0984d398cb9e3a4da5476008bbfe813e9bd9d947c3217a236e69432847b184575d498eaaa2b2875e8669e8751e91c9bebffc7cb99e719c590c82fe57cac009159f57261e7029f455dd9b219ca9ce3ac78a76d4db0dfa7a7a3d8febf199b356f5c31f33ac7a8089cf1a72dc1dccca2f77edeecd4a66d98172c765f3d2756fc0991055e77f41d5437230b34ac71393f3486982af6fe58c43fa84b3ccc6feb49a896fd21a71b06a6d37dc1843febbc1dbf6152a96a17faf3cdaf80e3f3a66d47e6c6620f2162b75562a091fc5edf06d7968b9a7aa6138b39ae87509af4164bf9daba47194543b847eae7261773abaf0ceb47182979ea053cb065fd4bc7994581da3f1d8ba98577cb176e0e68e3aa110f0aa14a82865ec12be0ce096947c81855c7d67a11ca6c84618391ff69a088c99325cef71594f23165c21bb23214d8e7069c6c3ac529fdc570cac42bb7dc88990750336d58a161276e08022a76ea9d0eaf0782e65f9ebb39644aceca3e6072df29ac293071b4f6c256f89f3b813d80482f2f4ab3a7f562ce937b448962ab93968fb8e80476c24d6fb44acef01ef662413b350d30e03768e2a2a39e373d437fb9d54f4f52d30832c963fd5fc73bba2aaac524723a353bf35ae4a10e051c8a2c02aba2e9d288e815280da82009514f447e8de9cc89325048338eee768a718f78d81e2028af008e7642317ba0e4104bcfb69e859f8e73fb9d8e71e18888fff50da6eaa960247c9eae467f8fe95b8fadefa9b9bda6940a81a1a7064317c10af889fcee948f2fe00faf956caa4abaeb9ac7442f8aa36bcb28cd88720429a981ca4acea739f8ee14b12e4b796f0a9c483cafa369c6a828328fd64eb4238c6894366dc14f2f2047ce4bce35618ebfcf202ff30700407cb8ce25ddf16f2af74e750432ea3abfbf04c197326dc22dfeb2530062e1bcf035571d6af78baf91307709619e2058549aa85d96b2b45c649e541a8d9c6f780a4d41dc07d0fc058b58f1ad455e311fcea3af2660861ee8ebbffc16266546aec9e5fb0df12cc67dd960fc073d8a26e741580e7b230dd46fa17d034536382abc2d92a33aaea7ab771675d1c6c134c04a8871e32b171b1d9b7207a9e76274b982a9e9d39886d00e01d08fc0288a66c27e9e2916882d6dec33312e2637e627a731578e1b8e48187f9ca9cd37759ea48e844120c2e8383173d578d3492496a2f65efb9baddbdc0996428bf7a84ca363b0f1606f6a281cf842dba36d34e780efdc6c2686c3d2a0aafcdc41e86e4c95d22ee482c5e2e6bd463ae4e5cfc5e679c321647da671bdac84028d342e0e514c02a495bd45c90afb24e5626cf077abc954f6859a2340fb84505c57b4653e739d6b7d49b41265f13e1d51a1ec07c653e554d590ce5b218b7e7cbdc6e569a9a4a58bfd424afdf2c8125f74f9c3a1325d78654bfb0f03a1663949c46529ea5698ce3e53d0c995a10cebf8cd2d5d2548154a8e2cff92abc01bdc0a9af790724cf8962d00032f04f7de4c48e235709fe161808390991503ff9ec24693208d8857aa56407c684fa263f208d8ee5fde17652d108cf9a19042304cf21fc3003fca4d9d87d4c13d19d1e0cf0a407216637ae2d148e0ac0e79f01e7a7dccb698900976aa41308500b71294934a76c7d5c36e8b8ef9e24583123bc1382b0d228b6bce21072c82c4b5866f977a5800813f6e576df0182716f723d357b5bce99dcf6810f8b90cbeceab17eb410af73bd672b0b7e4605a5f81f0acaf1a4f27248a2b84ba47048cec0093fe26755f06416ba9feb4229f4f37efb7d66a170e5d8ab9cc870fa644c5458589158e5e28715f51a7a474d88ed92f607300c5a60a1bb3c52fcdb9d72039077168b367f9297b1fca0c60f9244546082a1c65eee1680593d6fa14c6dccbe3e0b6dca7d4c11a4d5b206a1ccba7f708220c1af215b9abbf8c1b824199fb66deb52af63dee61ff0c49c095934ff4bcb13c4147ee783dde44e75f07654a2c1e1dde103eb921d809cc48eef503e0f61e8769a1c90c385164ad9e418f03f6fad7d56437ee49f26a285991f9ab014fff5927a2006204402b82c6c56d230098bb55985a7fbc0b45badfee2136e7a5bca72f5be26934af4e2513cfe69d85cf7a41ad6c1c1768eb17eeb6744d1ea4add400044503e18a24b9dccf3373ac8382d22d9ae13eac38e0e97745542f1324b1e8eb93451365307b8a5f22599422991cbb65ccdb73b38994e8fddd579a0c0297cd0f45bf6c5641889432b12ee73d76ea33ef746ebee4c90c299845f9f1e5e5a68e85a09176b7684cbe5a2333af7cf82c104172571e6367d4a4ebc3de31e2200bf765b123c755bc769208f8a3e2d9e4b5fe272612ddc01e970b86438617d89a3b956ce184da67ec36c2f20072fb03b32ea80e91a4fbefbae8d72307135febe9efc565b0327d1b4a2cef98ed3d8f2c1579187919462f6cb02087275839303c74057e57318ca28d7eb448a17f8d1ba89e330e61a35e4477c6543b0d1c7175fe9b5e1225c2abfa54aef7f408df3e51302448ac9a18648e860709178d01f0f86bd2d8ecddf788546fe173b4d5f472e14b6dfa26cacaec4a6fc160be22337c4440fb66377ffe4645f086640f9e6d173bf2016c5ed01939b22f8cac1f4d5e13cb0cafb6ee2960ec13bfef40f2da38f5ead2cde704e341dbeeac834557a4c064da1d1f544a94ae121362caea7866cde50d9c3ecf14014c87f9ee419525dccbcbc6f0f0e2678c6df38f594da7075f1c1dc1a309d5d59d90338ba936e6b710b54459dbb406956f22ed1da6719d37b33c669ec9b3f1fba18c9f0b0b115fc93bbe97b7e1d5c4093d4c924d0b75b2faccd3c7a9a0b8ca0fa67359d7f664da124160e732c4c44341a49d40ed3a6bbe4e82b110ad4980f08785b5e03b3c130f9327f511856ea6163f9e342a2f0762da4512840627345e9ab69e7fcb130f019c3535f84e4a59bc73c3d790c113a4e4df3ed87bd39fb58a47d89cdf8fc7e73c65ed01e84a72fad38b2ebe806a9ff2dd55712ce657e03206dfe66f481f80cd6b3663386d8950686793c674147653e4f0be37eebbfd5bcdc557646284d60026c3f2bbcd3ed75200a6b6e7d624daf706e75cba489aa6cf79ce1a047af6d2aa6ce02e4de558a3c0710280b3038ca997ffd169507d2fa36009f77f68c89f69dee542808e36931f45dbf04698b315ba8f3b935bce7897c12062206861ab8b74dd1a6b21a1c985fd662ac82b590cb605e8f8c08eb70de3df21d046b29b8d83e80b164a6e2790b28ff838fee45a75687443656ed87a0ff415eee2be363ef5ec0942cf57ded0ce812b5d910d5384099265afb679461c6f30d8b23aaa4fddece32e9895545e3f6884afafb0a1deb0e159392122298f2f456733478c3f98ac5bebefb9cfd7036aea651db568a7c97bcdb4958a9b389bbde7ee0984dbede7cfbc5874bff4d33c93f19fb61e89993987cbcc1add772565010a273aae8bc8fa657f2ec4bfd10004442e36a939cc45b85f4eb83ba5181160e749dbee35373da77f0d6fd7eb7609038b82d00dc51fb63b620aabbd15207ad9eb44464ada23946b6c5197a371d86aeef6b05cf227c7380c1228e063a37b784c8c60b1c73d1e9984d32cc7f1b7e5ac85451770a523b9eed3e8c19e0c22fe064501c322ed2b89deba2ad247b1aa91800802cecc9ea19b677b5e32b21a27e47144293e7eb2d58974537d316382811e238f4899adb27558e3a2003445f81ef261eae26dba213e9593c37ab314fcb24c66c1065bfdc788557a6036cba7292167a2368741357ed651d17f8010d4ffdf511109dacc4a1eccb49e67f55af514683dc7278c5701d8c359085cecb8878d9258247d5954050e3314ac7d86406bfa91935a9f39a7586bd1b5e16c2378ac3d2ef7ddef76d2938603f866e8c3beb9ed9350461c2b74b4b9b2af216f3d5a709d4a04dffa91dfca55de57a15be09d3178325b7df5915a8784049226bea20df0a36eed129ab5d07203d298bc4c04454a7e271360f5de6805414885ae0dec1aa8d240e7200a9662e8d5971ccb5f9e0c3cfc9d8f5bbca287690e4efe22c3908cbde9edd050f968d3230c327fc4ad7675b8e7c94c642ea96877bfe52e67f1357323979545cd41c0e0bb8029f75744c7f614265e2c63ce3ab5f234a1a4c3627f19c0bdc7487e24b9129c45c1b67d25115651b909da9b9657a922976b9105b307d3a14fb115a927113949f03d71239a140684986913edc8ca980420c12f271c4122d8bc5237b11fed6bb0f4eac52c5a142075674fcc6e85b767f1e6a04ab5f2b14fa4b68eaf6dcf051f6bc49be6da221dd6c62cb166c79cb81c12a7051e78f04d2e64ece66d0d8ecc2b6e7d8e498442031a6bc5c75807dc50cebe0e611a796b66b4b52f183757f9864961780ccb32e9880ded179cfb05919db73ae98983bf73c16651cabf9e3393f113946fc0b91166df9abd7d55a8ff36b0b777bf131b100c928ee303e20afaa79989a0859d4a21500ae2ef5c10aa36fc46b24aff49213b9d0e0afa406245dc8e906055de202b78a4c91572ffbfc191b853689ec630b6d02511fe89de2ca325c351e4e2d8c3bba1229b0228220bd89489b008af56469f437612c89c947a0a528c9961ee99f3818371d5ac0b244cd4d997da26dc0c2fd65901ecdef9444702720bb04cae18a0905366766e9a4261516e932e73cdcc51edfb95d7f86708c6fa1f613d451b42a3db34b8a96245c0fc1f990517a4f7431c9309df87d89bf79bde2733b13335ee102b29407388cae79718527fff99725f02c16e28f6c155d487838ed7ec859ecb29633d010e265cd7f60a6ced392546096efd24c8cca6f1faf4061383260151613f6df226343f9290cc20fb883aadb0c0ea92728b647bf30e7f64fbf162f9c31088a579fdd5425e614aa80815caef63f11a7788c041e2224c1e77b44f4a475523bc1c4271ca6a539cb97f8d4dc128ff3c9fe5ef912e3bbb6d1bba687e97bbae03824aaf0975f6c067be1a30a420bc9490eefc876696c97704bf5d2aa8bddd27c54c7df291650debb44d18a1db5ef4415456afa8c24a194b3d50f2f18660909e8e351ae662c65f3e61e62377552c9e3fc52aa83a9eb1941fb608f744b22ef4cb90412bf4567a7b3b7eb2147aa972139bc59cc7e137f7fec3ad07bced321e177ed564dcea5b8a7230ade955eec2dff1acc3869b23666ed8690432ac1cac2a542cbc059670425bc3d3b04e049d443ea6c87594a0ee24c5fdd7a776c3139dd5c22753f88f411b726c9330e48c192a88bf38f0400c90e57b4ee905ccfc0101db1d36bfbece6837d2c1dcbbf5b9806b693d58002cbebfc577f1a68eee27998605f6e2e1779a92a64b8d14332c1a1ba87aa8c9474d2aca921eb691e30162e3a5daa9417a6ee2aaba317931e89a3cf54b65f5c97e586da080b9356c655edc7c18aa068cb653e6c2bca47547eb1ee73b688ccbf8475b978b96eba777eb1229d51d6569522217f1363a8fdeb3942770677da10c819f4decd86543a2f0233ac0898531f5be979ca17397ddc2248ea2d21e81d2e4789f1f772fb9b9fda26818b7d27f22a0d5f3bab274e4676a0f8133049e55e56d5606a1a822e4709255c2a644cae35ede5deb8a727957a55d17236b1861cd897d6cd4f4d5dda0b80686cbcfd1fc696cb5df15b2755bf542a0c0d2ffce0b47ad888ccc59b231338c4f0a058ef948f0bc08e88f4204df70e0111d866eeb4ed2b34b9236aa983df1fa5a98b6ff2fccc3c0ed8c0f53ff1bf2ae022b2502cd56196f5ab8ec92f960b9be5e4964c3f4170a1df8cc8fedf48cfc33bc817b2f7bfed45b394d6629680c7870deee0f52d9ae074c3fa35568083c22a6fa341b477c14737a59922a26f88eada230b01d727cc318f1f6201718ef23056075edca57bb1512029979b799554b30efe8a708d042b11682479af69d91be874d2c89d2cee79b18f3fd35c248bb89e1128b969be0fa27e5f3df21a10ff1d767802149553d3fd870494eb8433916caed9b7b65c8d65fc701395c89edbadbfedae8902dd8bbe8cf407c119c8133ab6270f48e0f6a8f3283fcf58fc5792ff2d6bcd7cd2f723dce00c619e942d75818c762498562ae6ff3100df3b78cc3f1c53ee4a7415435510ba89bbf96ec44a3000c06cdc2c9c19c8af99bf71d1cad2b996102a8bdbd37ecbe304d16a215842dcaa0c9c37c28c4e0cd996759098b117f2cb89dacb17b16653401f59af37a4c0dab331b2de97b168e7b7f36462454546bd07e0f3e376a4eb25a30e546c29d443b866e599a507d3693d5ea9be4393c31eead45f639a312e001769afd2bab0648587e2f43d380abdb1bc61cc31c7665e921d75a9a715f40d47528b116dc31c85a4e7542355823e781df804d75c5c868d4762271795b7762950f64231ad58f40b213835758532ce758b4fe406145e1db3216a194b26e36aa327a084267c48b7a97e43aeb7bcba88caf7763d7ee69f50c8108935b48b931f7dea1292c82c251bea7cafad56e1ec56ae1cb4d000561200b6bebe26d58215c88cba4a95d1c1204409fbf8a13431509d6f249c76b36def7bd5abdac1545d907211d4d69c215dc0b0c46a33a81f4203e484e85136ff3b59eccda04de61cf0b07db1435b813f1b26483cb6c6506b7df778afda7c5cfe485ab5eeff8021cc3d7fded5b538eafdedf4fe01a5ef2cf97336e82eedee3e7ca01ff040f541cc3f4d7d9f580bc0827dcde7bbeff9b961902fd65c76312987870d73dd124398525e355bd7841dbcf64d378ba90877037e8e5b8d21f6bbbb510e71f6b39c44393d46888d9be072ab3202e85079394d451979171bb73fe5141ab9e51ac2946de99db192a722b890544cf63b65486305aa93bb65d9bff6aac5958093c203dd12a2e2c44dc15b4ca4d9c2bee9dc94ef44ab9f9171266dd4433552af0fc35be3e1c1b89143d4df9567ec1704298fd8fcc359d324f0632520b8eaed8fc6b4a522e95298f0cd11f29c5a49c1ecba3930e617c0612aac7c84d5fd246fd725b15bb127f5d0ad2268579658ebb010d0c19c4c75b5c0ae6d5c9be1e2ed6f335a425bf809821d704d83b4aadfe563db9a5237f27e8e3ef988f5c721767ed71b3fd778db201f8d01bc1ab9d39dd38b2787555ef8123b716265a619e0dc169299bf7a474278bb2a963d79557066559f54551605d5eb86d1d063a3192fe86467aa2e51d02df4dd1b814b6305c6f039c3661115e638c1a74d1a3e19cf6ea852d21d465b8e5157859a2d0c6aabdc15dc961d9764bc9a961992b7ef309bb676766dec7329fa70974d3e5726f1d7aa9ba04949c2e4df72d1e886629b405f9513f6867dd224b669e21325aefdddf4fc726277db55f9aeb4e7facbab6a3cc00683841f192bd5eb5f91e9da2648f3fa5eea5e04356be812c23abdb95151d5eef3f436fd5e19b4ddf27dd95a0c6600c1cb350c96c8e154651e9b62cea17c4da5d47e3905c402faff347b8627298dacb0f706127903d87fe217d8bc6532fadbefd451a372c75c070f461a11a7b69db9311928eaab559042574d5514f7be4646a631fce0ac734a916dad5ea118d7d3cb866e2b46f771c61ad44604c4db3cad42ad2b6c38ac07ab3752c9cf3d8ad90d06555131eb8ca397e968319ee5206e3c5f8e2023f5945a50380007d31df307222fc2f80dd3d436070061c8b3dc73ba5c0a22a1c5c523da03b3a0035b704a501c67a6f8ca17c95907b6f5b6da102ff723ff5c1e5935d0dbfd70aa46b76f99bb7a7f47de89fa1a9769b2969aa3c7a0ba36112a058ef359f645f002b85fbfc9dfcf4664e07b9f2ba3eb4f5d1636886d986e02e7acb9a910a54217bbb9f6b770bfdad5e28862c85a014ee3b8ea88f1be704cbca2382a77c09126710fba87d15bcbfc969e3200ac2f230a404bf5ccf29d2fae646237f2b63d50ca78c38d70a9231051d2ec8749901250704f69229b6089f35e3618e808e72b2bf8a9f0c6c82699e47e96b90e947a6e916d0d9526bf77981d66c627c6e17264415764b600e7f8698d07ef22f650729279da119399075ccba8ccdb6a47594ff4381c6efded2a54969e03268488035d0a81e7cbbeac8ba0e96d8c70a0fde8ae5ddc41d97d1bbc4d28b92738827ff6bf7f4b6e19bc2bd03c10991159867d0b46fb07008d196f2d965daebf7cb3872f6d3933afdd10418fd23dbaa08e831e223d5fcee123816509bb104c4f9106a077f6bd3736feb96baeebf6c8a76f9f3dfc7ff4ce09dd19bdd2d95528103de0d606181471ef4b21cea34638683df2f1d125f6166c7c53039b9fc4de3f1203f22864e3ade6367e122907f69593e07e8501f95ed074ae3a0ed7e8da02e956ba441b46521f2f519fe881f2324d0a996548344c37bcfd554b66581fde69c3c9ea77ed4b9874f2aee7045d628efc17fb0c3f9b6f071ff04900c5636d2c4ce7620ea186635c7968c06da9f49717870bc6701952d76dd1d26a5735e5080f4dbbc4a68f476105875ea75680ba97e6a5fcc83e6a608b903285d2bb42dadbab7b8148ce63ae7b7daecec642cfd83688415a6efea57ba20bb2d0f7acb728fbaccedc282a12c8776692d57db2e226c3df334d79d6e85fff452daae208c57af2c58c6120aecd8ce798108137c5ebbd0123e536e9b782ed32de700452b9aa25e10b8d495e810b6b9050d7e134bcda96b6ee8e225a7f453c8601a333e76623dfaef67bdbce0c2189b7294d7820c2531cb7d5c243ba818c45c8fa3c1fd1aa02bfde30c3e368b3d33f1aaa2cb214f9da6b371fb3fd9a37f0340f8f1c0bf5463193b09eb2295bd196c5e9c1487e88d43aa03155900b6a239e6e5518686a0041569f88412fbf91350c74020e3c8cca000\";\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(\"Swarmdrake\", 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 [\"Baby jade dragon\", \"Baby jade dragon\", \"Baby jade dragon\", \"Baby jade dragon\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Firefly swarm\", \"Firefly swarm\", \"Firefly swarm\", \"Firefly swarm\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Warm rim light\", \"Warm rim light\", \"Warm rim light\", \"Warm rim light\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Purple-teal gradient\", \"Purple-teal gradient\", \"Purple-teal gradient\", \"Purple-teal gradient\"];\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\":\"Accent\",\"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\":\"Swarmdrake #', id.toString(),\n            '\",\"description\":\"Swarmdrake is 666 Baby jade dragon with golden horns surrounded by a swarm of glowing fireflies on a purple-teal gradient. 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\":\"Swarmdrake\",\"description\":\"Swarmdrake is 666 Baby jade dragon with golden horns surrounded by a swarm of glowing fireflies on a purple-teal gradient. 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":"58241891","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-03T17:10:27Z","match":"exact_match","chainId":"56","address":"0x3807470b75f332461D8aae40501E83A7E1Fe1819"}