{"sources":{"Pilotchrome.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: Pilotchrome.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Pilotchrome - 999 Cute cyberpunk pilot android with chrome flight helmet and cyan-magenta visor in a rainy teal-pink neon city for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 999 free pool lasts (gas only).\n/// Every other mint costs 0.00007 BNB. Max 50 per wallet, 999 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 Pilotchrome is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 999;\n    uint256 public constant FREE_SUPPLY = 999;\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(\"Pilotchrome\", \"PILOTCHROME\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"52494646ac4500005745425056503820a0450000f071019d012a900190013ec154a34d27a4a32ba8d2dda9701809666c61c0b7f946a7727c10b7b20297eb78871dc8787e57bc9be127d6b2c5e0b77079bdbe3ffd7fd98f7d3fd7fd19ba44f9b7f371f4f3fdb7d4abfb5f5517eeefb29f9cbfac4ff69ffd3c1ebce6f14bf22ec4ff29dac714d7a1dec9e64ef29fbdff9bf521c90df3affc5ec27e519e0e29f3d34b6b2ac64cee89257dfc128267b7bf40f1c49213f0a14d507e75260ac2e85ff2e486a7af12f224ca4ccc02dc6532771f325a4090498bb0eea7aad485bf7fea7d2f7ff28a0241df56f022aff0fd127501d7ac1a134df296298a917477334dd9d7e690febe7f4ee5e03011c345fd53b0d18f0d0526ba57ee3740f9dfea16d6883ce235a84a592b70775323b22fcdd4ca519c9597a06dc850c4dc46f51ea84e80dc1ed39ddd3c35ce8578913212675e3873a2d42de63fc700a407e066a5a68657e2c9e16a90c25e8088b519692fdf9f5e28f7cdffe891b5ed8b0e063e15e30df3d329d4adc806e764ba980bd3790db062a0d9480d7fe2e453c22051fbbd613e9c19db2fc5b0247621e46675c783737f2724c2a7c8ff598df22eab529ba18c8b5ba8c364ad38af241e40c9e73bba3728d6b5694c621b88dd2fd2a8c2929d9f6dc91ee8022c07929470e563511e95e5bf67895b855233a7c96d9d618eb4d4dd3110eedb3a9c67b1b7d77337e76661e69f311da54f3d8525fff7795c5ab910ff1bd4599a2fe9a54ad70c97f84a949606367c799d857bff3e099c5cf436c304e3f3f99a3687f428a9d899380df71e247caa8c430ee7a8828934559fdcc99ab6749cb23dead4ca2ca29051f64a5a0c0ccfb24823294ca147ba6e573f893118d671da4285a26143d89f51d3adecd882a8fae375ad795551224fe7d875539ab77f236130116f311416844852862c39bbe07c24af7ad98dc808a6d96dbfdcc6dea4c493fe6d0a56f1df7cf9bf2e4600baf2c8d5dab2b951ea225b0f39b12430036bd4501f435e390d60598b798bfb25f26052ec43853938e42f50627959574cdbfcb763147aa807e4224ea5fdbd542b73d0275e1bd2fc9f5202ec6aae3cef0a653d395511da89abcb4188245d1e9785548781fdf5ebb7996749f27b03391b3210afb113d4b7929370ec5542ec6804fb15571c064f8c0b3e31047e1a1b2666ce5dc205616576e4cc8c74ef55de3a67d4c929a72083f841c56b7d4b0d2b8eddf17752563a89a715fb4a9e38023c1afecfcd31bf75edf82c6828d00e269a687bf5ecf0280b7ae765b901a0975bb50b496ea8942267ee680da76453ab5501286ce8189e4236968e153cd1234b1b2fcf2c38739e1806e5288514879625b47351ce6e19782659dc2aff4fa7b36baf0ffffff27a2996ab170a3d5d4c100f04005cf9c6e1a50eb5995f6def0df6e7e63f21fc6317b717b71dd61bfac976ccf317a95c7d193169e96bcd7a367bdf4c5d0e9626c7f34eb5cb3cddfa41122c4c20840636ef72848ec0369faaf280d36f471db9fb50a712d5fd09a99275bd18f2b6dada0cf95d33aebdffaa651197b7511c9fdbdcd71fd696a0f4c4e8f17480c9832bda4dd20ebb2e32183de1ef031162428ee8a2b109e0520cade9f98339e11492d66fa0736221cc1bdfb9da946543b28fc2f1b2e45f42374c007b5386dd81d3b32619d09f57915b3a303e8e32e7a4684d49ccff5015b6739984a55964ba2820acbf6eee40ade76e06e067dc23b6eacfb0752edaa78d3dda65f90fba48dc35647c6c4820f30749697f735ab314e0aecfb3b0977e2a721cd234607176da665c718841850ed12f005f523559616ad3b2372f35621e9e63a5bec74e3a8f1ba678e6503add96dd164ac34a0e6fdc4b44e9e8395e716d3e4c40aaeb64029dce2458c7fc1d4dfa61050d3ead2d772ee97d769b45078baa38b81c843c57724239b5d237a7f1dce466e22c4d4157f0e0b1cbb737b1b3aa60a5bbc9002c601b79e6628ece8783d9f795121fc785098a812aed061a255820e8603f51b0200ed97a7e3d0f1f688176d42b690351eb1588eb818238cebd07300a4a5d3059ccfeb7809d808fd9bc8e78f9ed1af90237ae5fc85d48201c3b2fc05e828976e775dda297cc72d80c83f962f7284877aaac5b9dfc668ddd5adf97443533c27670592edb81ea1c2aa8d9551c4bccf7614a2074ab07a75bbbc4f226539619e18ac00c8883b86522c1eeab818dd8000d35de1cfaa60ce2c18cd666b04f00aaee8ed8edc247a822a719729c66ee196ab9819ac0e1e1825e5c6591441e2d3fb971a7dd4ea8362e1f6223219cfd721c3a083116efebe5c33a6baacb190fcfc5e003bd04021abe7cd71d5f8d0ac4f5052fe98afac5375dced7b4da90651ec43231e06a528029a9b922c3133257244c7882046b8367b4e099c2d77dc1952da32fe7d84cca93881904273fb6679699a64e2cd2d6f2e9a5694bf306cc3ae3876483c3496390fc36d849d70e6b4f6c8343af8cb606e38f5d88186d4c7f4090be152d7f4459f05753d724a6a96e04df0ee706cdaaff6e29232fc8f82325ae22ebb91eea2444f93c1f3b5a999df8289c8884c3046f587b05dc13940f8faea05b7087f0223dd4fd59affb9fb483b452ee2d12e1d19dd3048b0ba1dae8fe6370bac8ef75195b7b9ace885c956844c83efe13aeb255a45c809c896f92e237273831a3a5565ea51c1f448d76ba6ef067957d6ae4f3dce7b980fb5d977452e55f98e634cb8fa03ff4132d968d926fc7db253e5e16fa01fc809a946960040dcf43f0c98b0095364bad15b625c4c28c2a951d38b3c7406ec4c129a4257606d147ecb5f82420f9fb2b24a8258b593fd52f62fe16b5d2209055dfccb7c9aa465fd67376944f463a1ddcd34fac91c3db3553fdc92e9e81b293cc07ec62b067be4487b7b379dcc390fd9d1b95dfa077813411cc3f68f431e75dea3c36f7fcd9b359ea717ea0989cb87a55f53f648d2867a668d3d1b5fa433e1f2c3ec9c6889f0f179f27a88e4e339ec7f902abbf7cc5fe57b3fe4e37021e383d11d67a94a33de0da98d6dd9b39a2ecdf585a7a9d2eedeee427e90e73eec790fafeca7ee0754ffca1ceb09d69cf23d1df1654e4ea8e02c3d29aa4b10fb5a98bcc60fd14b5033a5f1b7709bdf3584b18bf1b3f180affc326edb6fa9b5952a2051cc2f35fecd75b470237d7f3f3ba8cef93d0984e63808d3f2aa8419cc0934c4228a954704a4c624623be93472cf320b21276753912d6dc67bd8e3875d1574fdb32d319b7ef3d8697ce5161e2fd2e4513d07b3ed4c96d5a9a5c765a21d39e2e917586c1a5b49b1c9774d38a3aeed8f8fe4c468415d406723a0dfaeb76e3b102b0e1059aecd59c09041f084ac5583fde4c234d992c33496fe98cee98f91664634a75e7232482739d9846086c75075f8e69be2bf868e8871552d5d1043bc89b304c7daba88202f454e196eb48ebccea51952bdaaf2eb8c9de2ef52d30f71425d57a816de615b41192913e6a2de842a756495173663420bb4051fea24ab9fddec79c5c914e90f3ff7d72502ef55e7e932ecc60547403a0a3184cb29636a9f184a7f3371f42eb66aaa89749f4d3f134245961325cba7efcc56c62f19af319623d96356569fda6e2cb9a3e9115214d47b95acc6d4a9954444924998d17630e34d69d058756d59d3d6dfa7c82203d21f1504164d12f73bbb764b512ccec8814c76a59f88de42aae7fb773f57b74fec638380c3cd564453c9fea97d94e91d857e9f950f0159a3eae5e5d032c1ad9c6c7dcc0ab649a4331b159ac23e11fe3d7d44603a7f46f20ae4af94b68d2f10faa48ef37c6c907df1c344938de855d0fc588c0d81006eba36756d6b7c882600508a60fbfdfcf524744b19e785231b359d40f67c43bf53b4149d49147d3ed26e870201585ca3d3d18a9e3861e190e5651011cd457e7b310157271c4f8ca99ba18908ec08e946ed3e3572b38907f89c5cee3b130880694f37b153f48c54aa526a9dc0e34ae4197fe1126ce1f42f53099c0ad5268678fa42c74eba2fe5e66b5bc980719649b25eb58d483930f782e562e79e698ebed2566ef893f837691ada8b871c32a76459883b5ae2737a0d5d30214841deb76b159c405d048764027c17293b1674905dae3e5e1b4d5eeff163f5e765f3e9062e22a7ca86050ca14b88e2bb6ce151833539de040dbc000fef5f53024c23a320b3fe1d83663effa465ba61ac72cd25f4f2592e08d68c16b07d2baf5f7cff97017d882c454159faf4195f0955b01be3f79f11ef123d2c3d5bf02884f36d632640250fab8044f62588f67652d2ce560b12bb45651cab449719f73f9e6bfc03e9709e3ed4b62526e1613c298b1436f96091ee7588d6a8b359534e4819f149f7ce8b1a456b85ce097e1782dd7fcac25c789ed1c0e1df3046fe1d93c7fd0f036005d7a15532f32081eaa9e44fb5ebb1eb47f7283f61f9c8cb9e27055b3baff9a1e046f2ad3e6c88ad40661e8ca9a90477655a9579608e5e478db3e9d5c40d63fd868100e5072e3b8c34752eb61af9fff1019f89bf69988d569df4327e2a0a92eab4544b5d2b68743013bd72c38428c848814ff341109f04bf83a6a8511c73a531d8029d1ee3d125a5fcfc2fe188c13d68d764d41cd59bcb4eabec5cd7b13e8ecc388c893bca991878fd9240bdefaa98416d540b1f720356302e93163514488e8a65e76ab767900b71ea9cda9b7b9b584b01784c61698ca9c07a2354ff40c14209d08b32fd164e33369b148748ec0419b4ae6ea14e42295bdb27ec0be1238fd8c6ac84be8a00220cefe60d11c30dcb5bd243bf69913d5b5218dabb74eb2de7298990703ff5328e41280af781d674fda0e1d7e8affa9e69d455597d097d7e04b31547c4f525d6117b3c01aff9c333a632fb983d7f412383258f0d699e776d8ce8f6f8303a1733f9f447c2ce85df3cd79c42a7bda24dd4639856b8fc46175cd87bb5859c6ea34d22b592579e91eeb08ce693444319101365b199d23cb6c92ee9e9b08da10436ab6133d6c94dfbb02c82a6350c3afb3b597f7256784db2788e7e01f3631cfa3066a3444fc0e9f6e200cf41661cfbd7e32739f1fc6487e183d8c0ddbedf0451e2484554e6c13b4d74a9d23fcd37918ec063ec5a4553ba24ba633bd01aad0b61f117334bd9e5d7d93ed4a0ab64fe57123c84c23e3121f909f4d0800ab25e707a484c46fed6110e2c1104939c0574eff237dadeaeb0b60a5256f1a6b9e363c3aa063293a5563e0bf74988837f52581e90eea38a6124e2f828c5e2c95c74548b4df8d2cd10c664a5ccf9ff6c190f6ec3d37827762fa9c83bfa83332a99da195ed9abd2c4185a32cc8616c9e5110b2e848086305066b14ec25a8b3a60564a1eadb03956213e7914d1c71c16a1edd3d96728381cf00df7ee3052b7d74072ea5a4e4715aaa520fa2a32f88584c376a9296ddcdf07a9180819703f28a484358bd908d7210257756acb2dcb7238a36e03addacb4b578e9c0e159e93cc79a18530eb24fa15a15a4da5bc01fa6167812ac847d71bc0f52ae8e012fa4312ab2c722fb844da536dc9bfddf846b493b2a30116d6348ead60e010ed83374dba84c411c1955252cc0c12801748bb23a9b1d71534675c39f21c19895d5a95beb657897cb36e7baab68c59a4d7542311299a8c2f23ba289ba9b80bb4e81ee09ae645c04650368ab7e57b32205619497eb332ebd4749f4de3b636f0693e49379ade1d15610c0a4cf3416723dbfaf733d3a784e3be4e1e3f23054fef5f7be0c18a83ee366480796187ec5a0836a9d70a8ac53ade7dda3b4c325f3c0df306e5fa6e29a6fa647c40382888d7fbd5e12e07726941db212709538791b38168611434200b6165d02de78fd5f1729df9e03c9182a7845b9092c04a621a60f5020e28e9e8483a7f6b287fc7bad0c3e03e569eaac00758e17ba81ffd40220aa5b32f5de9db398199510f8816b30d3f334dfbf6bee0a7ed18f7419f992b07164adc602d8e228496c25c457fcaefce061bfd8b0be4db4b04978af7ba76d04f97e3f38cdbbaf6afc98e42c313372439387a2925780c7e7bce6dbb60c61b688f6d36c3b5d1abad33436327d52ee399c89024b2dafd174b4d9abaa79d356f95d9d4ee1948ba3aba50d8c375da54adca077ff9076fda52b92d6ece4e4830f0f3de35a006ce0c365916e50bc87ca513d0a666ff82be153dbd388c9a585ce8409b04f5478d40bfe6fe83e2e643193b5497942d2aab6660fa8676b6a0b6d33aa6099b7092dac8ca697ddf28750115f09bb11ceca38d3e56f1d70e5d8fe707e0a3caefd8f407a7b89e8d6b61efc7dceb626465472032233fd22a2f2ca38719f54e8414583b4e3d6e110f1740b93d2f7e64d6b6da74e5173cad07f65cd6075b352cd7106fafc0783f8ce5410c30fd78dff15c91a15ff80c2da09e7aef5f8ebab0c9c7f919356fb8fff700770ed9e42e1220ac11dc677d4c15fc9ea6c537a49e47cd16ae017759dbb98e5cecc84ddc6ada53b3511eb9894da1eaf5e3f373f2d7bc85a23df8760b96c65eb2f283e3b56372737098420ac0a344b4671f972d562548f69c8ba11154c814ea1b5439221de24ccbd9d4fdb4282856d68828e7c66f6386f57e8cce8d8d3749ecc301b93e564606d2906480022f7a13d55692eee03e19e928370c2a7979a20b895b1af56164aa25f0c8390916e36b8e67bbdd9b306e9ab0b66f44b1535279b74bc75aa0e1edb3786c71b33be63e543f8f6437c391832b64a93631f74f0329e483e11d9c3a00e24cc6270c172569eead37066c092246b86ff06d349a4cab1317ac664716327a4ded309bfa72f35f7487fb3a71341890d2591940803abb1c900a6b6f1825a065e5adc2fccef458c790d6972bad9cb11f02225a86dc2a79ecf6e88747abe6c9c21b163af34d83445a19ce6ff4479683a4523bd0b793b730bcf34d75c8ac5261715b722c4d3485b9d96b10899efdb2353d48a503fcb5e6c014ddf3dbf8a1513ad7793f5fa26af34fd5ace03185de2ef073c52aa68d8c1c9c8a612d21563422e0954ab54834164d85218bad67483ba5634615ea89b73fc973eaf9ad8ebd3691965465a4bee6fa42ab1bec71f1bac88c138a4d6527d72ddf9415950ee5914f4247e8456ca4de1246961690b5f818afc9c11e3be3c215af31a3318cf85f1a1b0f0805e0936af98c0e267345992d8de17c303403cb84236d1516e81147493f25798381ff2c5ff6cad3d84bb38d088e330388591d7e4ccf587e14c52dbdda9a5ae57dfa2268a2bf5b13eb64048838f3fb1ed1a9072ff733ae678713912336d4ee070b9a047f0f76faa9fc9c5171a9d304be4446b887434f62ec342970d11780b6f41eabeaa2615b724f7551e02d639af4fa72e326d171d040424e5ed44c0ba7f76ed8962ba4ed7d5add34f7d81a0c9fb79974c4c6dfb908af186326b79d70ae87cbb3a2cb4d76f6a2c9d5d5f1569f10d559cd16e3d9867a17ad8abcc6edb0714422727ea4133f714fc81e533fbd50a75ebfe21e79929df9f98a6c8393b04fd06730c9e7bddb02b653ca85a02ee22a80a5b36887890374f9a0eb18b6fdace902ac7afe4201f52105724c3c869da12c4d198ee2daccc581d7cfc74861f9ce2246286e37dae7b807114b9013b663d880961527e98c87cbe86f8c6700c357bca172c3dcc5b55ae577688028b2d48d2c7640d64385d1889d9e8c449fd896e7a5a023d8b056237a774ae76ab7dfcee394f912f3060a238947e6ba8c32efb0be781c7ddc6c8240068ac1617d7a5e98ba33f56cccb88cd6b47480193b3f918b31df811538ba9c1014aec6fd39497a82ea9f2e41a82a443a2edd36a0ef6500c003b486a5c8560c760869fe40056e9687dca387c23f14b0a323ffe88e8c865370c819eebd3cb7aa39e0d4b89b8a7e2b07c42afdb86ee09c4747c1bc144295697ba85f0feadfd3b91b60054ae353530c3ca7e6742707a10cf718ba4cf3b6da2ea389a4d60d649f09bf15941fbf0523ee99c2fcdbea965b470aa6a62faa066376c26385bde7fbdd0ed51f1b48be2c0d6b1b50b66c0e6d169742e6479cae0a2a1fecc4f68763d84988e49fb9bbc9ad2aac986771edc9ba573826a1aa7d1aad688cb7189a3d982b4feba1b0ef221363ff833309ad7f3d3a5e52631167275415c90df66b86005d365b79255d94f5340d9f5c1de34b7b13299aaa31e281e8c559b5b741e5e74102a27f023bd583c5f1c3cfee1241b5532092a13e046ee99e8caad87f6779fa35bc793c3285973cf07b08a7a19ae1238bdb3612d66b3dc1b8414f3dd8376521bb1d12bcaf66468b6b695957fa394e553b84085420372664968c7c27e89c4b41e94a1e244081ed37776f4599a362540925c97a9419498a4a925c37d1fcc24d2849f82e98aa9f9d471fe5abf871ff13ed74c8f6978a05d299ff7b83e891757ac8df48c048a88d3358356c095d3d630315de1053509ca2a29604934b610e20c340a650a43468522c48bb979ee99b034c304abda01e8e38c1bd06619569efbcc0ae5d755dc66f4e52de1c796e10575226de08062ddca181a0162798645181a2c5a31047d47bd57c7c744c3090e8f1c735548ae0ef4750d70d3253297edec77107905ad8b534dcd899f5def225efeb24318427a7fe2222f295cc368894af808d1c7be9a98ff268f427bf8899e14f144aefeb423ccf95fdb1f00c108ba7d58d79148b3f359d412c4e3b0de7150149aea3a6da80c8ddbd3888197e2b005e9834504cd0496ebd5ac1197d724d514cafaca3cac77559d668b4e5516d50eb4893dc65bd33a522975f38d80b539ef6e76fb4a5593ce779f14c19122265447632b5c4528accd59159acaaada47e7b20bb8cfc9e067bb6ba1b79b27a2a289893e808626909c01a60c5752f88a5da1775649a5901d33a150ca4f98f583b539173178f3ae5fe01d342925e4cbddd6c39a62015d97a5f2df6ba912c1ec0bb3d7775e0e69830916fcec84f0352e4c34f2d586aeddbf5070f5c3ab8df44d7099e77388fbc3ad8d4a9de4eab72c61b07fa35bb20e6968eda96790008ff92f330f3345b1883cf4a6b679e80ef3029f434156f27530285a1dffc166277edea6704274df255c67ade165dcb42224ed9fa2a08f4a1913b3f22726789f75fb99fbecc60187f41f3c5ceb97360751e4116bc057efcec2605ec751a85b4d32cb2914732751ae4d9cefbdbcb54ef7e2fc7d1b769646ca1adb46115f922414d0458107437a981d0b4f8ff7bba8bc425ba0400f1dc2cdcc0add95e45f60b86c23ecdd6d81c42195a90ddfc4a3481157b6013b58094cf1bf33a204a52b0eb76c21cd158ed095d4ffefd3cab330235b5accd1e25833f4574a1882b7eeb8f984e020994654766955029d854344fecee71d3e1eeaa9c70a326cee882c5ed8247ddadb8b232bbcddd76915695f84b2f66dd925220128e404cef96b70785fd6ae29910282894f95aef39cb7b5852e3407ac828f20d98bfc5575c65b919183d63443793d2558d3912419a2d7cc93410fd708832cfd74c428c4476394d00239b78e4d7d572aaa4b65be5a5d65dd0449bb12c38cbf4d389a088dad035688cb0049cd51fe1da3906488ff61e9b8a567b0f5643be6aa3781257dd11f82f8eec456dfcc8c73146662cc1e5a1b6fa16bd0597a868e24f0b1bcdf6a04192443efb974e7e3adb6996fe998156243a0eb05027ba53d76bce96adc86ba305071ec307a550f7ae6d26da6661706ec38d7024a951eb1a704c298f07712cb6a01a605b069ecfb966117f4a7e99f2d9142a5f0f6f5eedd7a7b1f9774a5a83deb30a2f287018ad2868164f1cef837603ae53427d2c617408c67ce44d30df580dc1c6bc1b34408fe57b4487ff3157b672fc78cdcf28a760b08c36f48d308a6bf89b079f48ed3743d66832a3ba850e63fd781b28a247a13310295e5981dd4027a8b6fb5cad9f618f3df98c2b0798fd91a201c5898c50827726d3b674ac97b47e52a43495a58bd59dd619f50cca87712a7c17abc9c34e8484871d55a74927b436cd56594f1bce0c3ac278e3387b3220f1175bf5e9dea7d14ddc4ca4a677058861b330b19061798d14505dd05f9a24ffa634e70a6fc947264bb34bd99ee054673da4044b75d264724c73c456f2e1598880b514e4eba6fef449571dcb6b4cb968372c27fcc9f4368d318a0f636feecdc4b5e9bf5a770582f76920828df59f29b0b8deb2f9406a4ea6eb7eeb2c69ebddfec620703607cddfd756132059cdb46502eb69b4e3ab01acef3e0955a4322c4b63473e07b1551393a495cfe3131e06f62f4d203b9103e1fcdf7df15171f84f0fef9faf571ee2cf2ff5ab1ea5e2bed27554bb8f0a1dfd742cd304ec6c98aa7f57f29f4f57c28e4cb97c90c6f65965036de77e16ca6996b6304e10489b0d066b48c210c009e0d796f746ff657b6bd3f8b997d56a0e1061358d422228eac55198adc9a005bc3db7267e03c611636a08e6f7cbad6529b5ee1e1b4ff158c64e115bb0e9e851e090ffb6cec2ddaa80fefeb842045aa19cb919efa5c60cf34cac7c4bc911740078e34b95c35da07529fd5589c1dfef2baa6971c3d95979008648318d266966baf89d07e24b0a05a2125ed55dc736cf173fc004e3c272ebd24c3024c7396b0205cd3657db9707adf34a32ac30ad61604a6082330bcdb3e8a2638358d1c69926ca1930a4635cc5c490404fe9b833b0551aa533e4e2c9b030416abc5fa628143c326b5fb8b483770208a5c865185c8c27ed7c32d16516f35003e014326b36dc37c2e1cc3a3c9bd69b538cf145fb59d365b973355107cf60d62b33a643ba467efa73fa25a5fa43e5e0adec81a3909af58ff7c9469702f837e0dece649db8d3e0bf4d39cedcd2e118e28d487e287b3477bde13a50c38a992cee6169baec84318394ef4c69ed0e6161c761e1520ee1fa047576d1966bb1c273581d97357223d3759ea52a045fa653821c0511d4ea4bf55b58ee250586b31d592ecee84fab1570cb3a232d8ffb3a27ec7273ffd71121e37e554d87a31fd633c495fc957105d142a3d4575a1e855664d8d124ae078517301fa84cc8cf569f3fe72a60b48fbb2b6015fc658cfb0033fde569ffd9524eeaceebcbc558d0fe1e81d181678a7e7017043cf89c7639bc01eb3d1e28455584c7a1be86dbf13c1181d3392ece7fdf6e9b7e6b8f7b38f9f22ee0ac48b79513b6ae30c18dc2f8297a61d814fd30fd091fe3135b67b1fcc85fde48a6a5956067aa025b8505563801815dc3c3ecda9f11110bba837cf9cf8ad4148cc2b3c4195d3232a78289cd16302591a3a8886e4f3c56134ad0ca8d3dad33ccf91748356721e908d7d6b4cdeb32f299f60abcd8b2f9337835e42bebab9e724c4a06849b85452985882e573c89d5dd377bc794989a75f15923cb608efde80e88ff1ae7539662e023dfde109bee12f1de1232fcfa053ebc8dc8bf327873d52817a02aad006a2f6939672e0e967498d0514fb0394721b19e01cf7348a16cb584009cb3cdcf1b346fd922b8b2fa02044def797d38e289dccb92fc82ad25d5c0de8ca151b3d48abc78bed8cb434cc020d2dd565e0bb30f863183ed79896c222428e8ae40fb316ab01c27d7a30ba69df81b12d8e8cfea44b230724d731fff902a24882d7574465c82c61c7830c7c190d6ac071b3c13f1f4c3295f7549c41303a0e406209a923e202b6b4140a0d723d265497699b90e5e76d05e08bc260067905fbcb6dc60cc5fd3e895c46f0ebb923695b68dd8ee73e55253017d4f3663e7b3eb247f9a49c7b8a52b341ddeb9621ae3d14a56208a057f5c3b706283802b572fd9f53236e3616878cc6f7022a2f38f572d8e8bf89503ba54a45cbd29d0a3a8ebefcb635e4f0a4609642a999fddf49a075979fced1429b8b2e4c4a8c9d99a92e3d13d70239879f7a70956e750f8d2f4f92f5d3d21cf2b8797a9ec1b06e3dce019a82da47e61ba36585bd4c34e5250bf220bee12c48ee628d745633564459bac92f3df89ac9080f30518f724a8231137600bbc1789e224ef04896527f1e1077a7c0356ae2b552a874865997154e170262ec424c6b23ae8c5f1770f2487c981f13611ed425a843ae9b245be02741a8ce8296ba770a28b88460fd3ca01953d88e766878002d7264dacb1ea43af162bbbbed12646cdf55b9c3e94187a8e5663ef750cbc2145c23fefdcef8806779d21426098b9ebb81adf6bbaca591dd072c7c32e249c6498e9774fd6914db1166a5b4cbccbc65c178eb50a409bf6eecb5b5bcbd8d20bcb6c7fc35c43ca540a37b0453e9017062a4e0ca68a539320249ebe534e94d8c4d43c19562f524c830ecdf5db649cf93d82230538c28bcc8c3d823fe599b03ae03039ee76dcf4e039e9c4bc638ae84c63dec6e2d4dc0c36b25b4c9682e5e8de96e18b61aa05ed3b021c60b58750ceb5ab4258b3ef7e7df333baf55cf323f042f67b2c40e97486207c27b7e0871a4e5d39f667f97cf9dd19438ab39985b1a3bf799c50edda164cc02bc4b1528885c599d87449b41591ee20bee81cc992bd7e9cd48861c0230b83abd24c63c16ee7165f25f01cd0326378501edc594ee9358b0f4e78179d5e226afda5975c3b589d19752a75f228d165247ef6823356fd9577952e2e2d16b64318e24ab4d5df50d0d22bea468f70ae3133d1992d28ca9d81b5fa0c383003fff133738be354496afd813527ed1c298db20057708098705cae623672b975a801236f64cee065c402d86c5f261eec053bf21bff23ed307b87c41172cd4ecf26035a61a1a85a446c17e61787bff7485a23cf09c14060e937d256bcb993e576ddb5813a5a093497f3d4d71b7c792159fb6c3908e3666b0b2e46ee8956c9f1ea7e0a0a31c031bef5df89f569fb103ee2368e035e2c57feba80ba5aada25b2f619525e5afcb75d0d7fcee7f05d4296cc9d0630bb398003d6757ae4ea0e9bd6183554b8d46eeceabd8edf42c1dd74350d4eaf9502fc9b9c4858f9df9ee9a6c7dc3e9d443e0b2bde0a844d37d5a106c7c2acdf61911ee48cef90c5991e72b14c1761f3231de8bfc041874148d30cd6972fb9fa4f7b5ac665af85b53b280bd82d26b6c8b278293513f04f39e7825d326bfdff34b8fe59d32522dba7e9695191d09a0d5db0c39bcbacd2701712043fbab031ef57d0ed7fb63d3e0ba81f036738cab27b458b27c8593e886335c1bc2415952ca4a9e886f9f093ccfd5f334b61bd3771652a5e5a4c78447f8ec6f8669e138b6edaf68044465670a746da784cd32b788380f8a54a0777ecc39f6ebca4f60d2dd280c67d000ec5ce8b27cee5766dcaeadb38f8ecea215f116ba4344cd01b5045a62351ddb734eb0e0ebd0241051e8e1e305b8c2a9b5a3e8954b64a469df710f2fd93a3305b8248592d845348fd494871966257f489e9c6c49776483466f8c9d4c11b9bd58b76eec13fae321968bbe9e29b91db496ed82e5f98310bd63ff03c55648a698cd8147dc92183a6e0f18ce15f41fbec8973e9c5138b19abc09405f04edf1e931ee9ec2a5f9891f62fb30569098c9a797349f5e02b1e7b6d56be04b2332562d58a7ee6605d8b5a03b9afef0a1cd86a7d0bdfcc964d7b63606bfcfda60b3c22a1c919f7b5f683ce925255bd5ac3d2cc1ffdefc99ccc589fee82cc8053895eea2b4b8e05e42a7b4b3a181cda364fa809f771863b6a087acc4eedc12b69bbe284a081c0d85694049585752ca6d27bdce9f4c623619e732be525cffad5d444db6b2f119c60d7c2dcace76bc5eff77367d7ebd93dd7f90ae5e33ceee78e64e062cd8d09f342de4145be82d50570009e2da3fbc3f809a6ffaecc30c47c07b1acd506816d348124af5f2db7833c7a77ca427ba468881921eb047a9bcd70f47c1606c21717bb4bd98d7a4bb4981ea22471ed4e884298661fe12ffbb62c44383cbe3f7fbc6d0764e016babb5dc0a797e08441d80e6baea177d34d6e2e5c585442c3fb24331173fce7766971c45c11dd8f31ae677134a01cdd2044c343d24788e8bea16eb1d956bd146f7da819adfa72cfdd91e77f0289478181c1184df92d2fea5629aace84f1f70f1ddc3ad487bdb33c68a8c4e5c16ef49750fa3ed5e4070074b6fd9aea99db81bbd3a59f5ced275da533fc094e1b28675f0f2d7816ed3e085b08f1a98aa458673be3e72c507f36afeab47452c80bc720faa7e86ae931913be18cba2907eef6e0cc463fada39c203fac2f621fa52855400eeae2c19315cbe50bfc145aae1c915a4861feb505d64c9aea98a67610b9dfb9d5e7630faa159ebc0b5c240532741ab857a3b8df5e0c2c8d8eb4c392f7e9c94ce2d0721f3db9f4f8fd898e2d294d79389290123d9d3de7e2ea9c041efe269a33ec1b4bbd1b4de455b4ec3eb1e5d6bcef40a8378ea9260273fb4590c11132044c9ae3079693ea0eeb55647812ec7a5f7f3afe0291605626745aef9634180abf55d3e71acd2e8f894f7b1634f2dd1d35e3d09fa5cf494636bd6162ed74bfe381658e57c406d8dfc3cde1f42a35859258af8eed0b0d0d71e38242327a8d70c3c06f60048c86ff0932d81374e2720bb13ce5be3ee63a1671eb72cb02599b1c1ec066ea92e6cab1f348b91c825f9cb2af34071c383991ad54938096535f4b084c3d4cc35030230661bdb3a552c49cc7bf5bbdc8d2e311f6439b731f5cddbbec55b5b4629cce7c64b3f13d4bd9e8c9990218f710625682720507a303f5fa98a2a47d6ca2c007781a4f35259b5326b88692f7594e6fe276f0887fb74226c53da4948f512046d9086fd92aed3e31e10ce0328b3cbc04384ccea22c808ad900d445054fbc0abf5f7cec41562b0e87e6f99bb3a8ff7cae19237e12e06bdcdded29f948bc0511becf9b772a5ec434e117994a138773facb52f2f2a1d9570601098ddec46a160b377f9d33d8b72fed935e6e4c543a044802b5ffbfb143d30d45ffaef4d5b467e8d0582f57fe59e872570fdd5a87fb342fd6ac768689877ef0999d7a2dcc8a3187cad79567959c4de863122ea3f6cda61f39962b9456277c9794b349bd2ca6e9770b34ff5fecb0e5ebe8f14474a29330c3e290328b49f98590a8e679e628b785fa927f4a27697b5f4bf34954ca660c70bac5ba9ba213dd965c2eea8e0694d4c4ca0737f64fe03f1c71fcbde0bf85f68431391d7f32c053acb135a145a87245b48ff60810eea2f78ff45a7606395e21543196eede5dfe3c15c2a9cc33afebe20ffe4a2191eb72f8369e9e32cd7bf4b58cbf34ef089a2b4f7433a9c0879e8b93c787dbd54d1457d01b5a361cda9c9c69e87e287ec18b36f22f905d659c2d152228bb2c2bde916487aaeed5e0c1b4f0105267cfdcccbb15a323cbad703690320c5b9a099642a91eac1b96414b77b4acef39d56b93a1c4bbdc12f01602d06249f1c4551d3af4a4531081815a5bc797ffe864b1bb254657319c8294cff1d33a6c9049bf3dd47d28e22beaf5cf81b082d3ddd3cadc5ef31deba51bc5b87a047af6de64d878ae0878e8d0b5f95356aac77d2c37f5605c5207502d75f4fe8918f598087f98ac7a718899cf43d5afa42ce25d97bbe76b1c938951041e208cb0511e2fb65df9ba84007aceee35e466d2fa7a3b845f9357fba1e90af5b96dde004a3a209128e96f2520d8d781d268355896d28e17835d61b717bb1adb45e822ebeaec896ab3eeccbb5511cb3289322712692e17e35a06d7cbb603fd068e4adc443fa7798b241ef7d0dd8f4613857effe1e5418300dc0a3d2dbbcebd94a77ee1659036aae676c20cb5be8b3608e616ccfd87e51e5ff89d6b1c025deb7f7da80ecb0b46aad2af7912e17a67eaf083b6f7dcf8a0595f45d312bbb45052619721e4bbe4840694828a1d61aeb4f33da5955cde6cd621b8f29cc41ee21b540f336ac9c4f02141a02c36ae4d70ac06feff0265c382db4a0bb232939e3cc7f5f65dfc6011097e938d172159565b39f46597582ee25f97376665d6f4c49a7f420161d9daceb519cfe395dc307731540f5a1ade44f16ce3ec5e74003cb2bac263106aa612d739abaeef86d9d594e0868e47a11fdb4c1251108a40d5e250a2e2e9dccd41d89f8acd60c2e05b5f85c6b276d25057ae71f19936e745e9e5c0d03813b2ca555afe8f794f9e731c42d87c457579760b19963298e0798679143cfbdfd19938ebb00ccafbc5de1c76097965256ed6e5ef7fb7375f5db86d5a76aef37b2bfcac6c40373a4f8caa06bdb063bddd39c394f1de0b9471d2af972390dcb3b21e67e8d33f83f3b88aa80204d38a554a8f382d1bc95079cee62414866aecf8d7e2c37b47bb5cb29173e88ae633623c27fe468b50bd07a570d510ac930e683acceda6bd6567db4c66c76f9b4f31b18b08c7e4a900a5480aee2f77ccb28ea936b590a7d45d5cd28835ded50ded1e958e0a6ed545d4851c733d3f07c944a472c4d0b62a2f8264d034ea783d5e405445a246adfb86f6173a3bf7cf01fea152ecec8ab9de147d6d5e61eb9cc2b3c1e95276c96d181fa448deb0a96c4c50d11a69772dbb1ee2b687b2aa0b74d04e3197bad35bf59a1af60552e4975df12ae8fd53e0d5391a044c3b9d61a7b4ce9ec1abc2d9689918f162b4cc836a4673c8a4622247a64b6dac1f9b9781f344ce832670c3aff3e9a37dd132de96f0317232060936e8b15eb26d108356a18fd5db3ffb3ceb60c5b6109bf49bd4b7dbd391f7c79e9ce3ef75455afb4d2f13fa1e55002638a460532cff9728796ed868f07685cb43f7a156e883361b84414ff29c5591e25436213216090b3de090a2ee45fb9c4cff8842bd5a2aaf14cbbac1d9f550da24ba0a675397921fd1e1edcba950bf82e57136b4c6fd338ef886d66590106de217b9c3af726d2911731d01a21e1e8550dc63473fb6bc851ac0f8d6ed2a947c3d13693d8c22666508a3d07028f39b1cf10c37502816c9fecbd32a64859e1a2bc8ab35d38a19935c31fa49937654867ee8b409dbd8d1384efba6f10954e7c5b1af11a0764b4da52dbce6ef88754b5e1f8794764f12d0d878249cd797bb6dc358d193e242be7584b762e39fc893d67ec4e8e16501a662d0ccbc8df002ee1eb0ba0c187d5078a42dd77645dcbf6f4bea5d67cfdab03b023c1d4063097e2c3f2107173695d9929f7f11b3aa59deae81fe69616673e782a5d5c327cb61982d097b0ec98dbc638dc453f55c889dde55f88a6643ca67254268ee914d968b06d39fd698d35821a5e36f710f5e39004b8a2cfaecec82f0beef2a45dd54c0e93b943124eac992666c290158da8651d67b03edbf9aaeb4e3d682febd32aa577650a393d9c27a6d299872e3a50f59252bfb969c8b0063f68cfce27f015a8f100d0bc4c1015bba9194f01056c2298dab64e6bf6439e6ec08d7e34d419b611773f9ac5aabbfe93a65b572c29ee1146d987dd812839c5584857d8c567d9744ffb19d75c55fa86a5225dc7bbebc280a1f8482e3d8414b4b2766ee2a0927c09998151a91b626d75b8854f600e07ee81b533b58672e3c0c8ee1cbdd9840473610e7885d9674edb67f30dbade33df5e61de79fc0ae484c6646f85f34f8ca2cee7457cba6b3843188e9738ffc9bb19069cfab2d7f3d41ac53b1f35bafa1962346f6a8f4c361e01df20fd0283ac11fdd5f95e3a757964ce4deaa43658a0dac2a68ae9415b96812383d5b7f4f46c1dc508beb4e46909328b4efcfea55bd073e4f47d9e0d3394978aac723e780ac3f8c831cb0279e8f44f3f721c91c347a25c8743f92cd12993f1b60f5d73feb422d96eed8d2b4db3043b71da8d6049b63fa7cf526967a15d709cd346a3d06e38b7eec6e57e741bef75aea2c92d54b77fd97d85287b615e4f64acb3efc3613b2db9fda4fea2301d4aff5aada29757e0e35449a796bc48d80c9c111730a34645c1c6fb9dd90ca19165d92f3aa1f4b79eba509cc70d4d471b3585778c0089741ed17123b652964e4f49a62e645123f4a8d68749571c0a2e434cd333e276f5abe626c90485023f5757328a99d42b47c8f6f00b96912f9a9e8e0fed98a9afa620c465ef9ebacda9231176973da3e614a19fb7ea85dbd4cdd60011455273e4e0103d1d24ded13d30d23b095577f74dad9f5cdaf752ff51777e77d4ab0098e0bdc2924a1ab172f4806cec3e0e1f907de835c353cf5fe19c0c653f98c929ab7d65eea06cdd7e789dc78809e032d3a8d149dc0f500290b9c653e7c9c4078b558f656acd1d9b8152ac1779ecf3b68c0a47fae0256ede42d05e53f96555bc257e7c75c353f2bb6641104c00435fdb6ca5e1604b97bcb737d25b939b0d54e94652c2afde8cc6694328a99531ade066c9375ea93ff21537ea3820189d92f05aa7493beaa9f79b6a1dd37f3f7da1d666fae6708b6ac1758118669c2073af3fb8d8713fb22fe5513eb724479421e28da76ecde7084b03a858bbf1630add1a7cad81435efa495861b78ad246f61e3aca72f7f1a6afce8270ee9ac37a7fd985302dc8c26e553bbab27e1eccba79e2c5218a882780e6be59e7acc03dcdcc6a4dc627ecbf0eea938c3ecb0627d1252c1230917f8b28c2599ba74eb985e425178a548b45597a2425316e2f281c1ef5e01a0e67271e88f619899ce72eca31d81d8a47afe52fab91e0e331969ec575d253377a9b87c5f30761c6841e7eb56b97b923e670648517fb55313d45c5180b5d1363f694c0f62edd0f6a975c6b94d0400a8dab683921713b7731c0a89029b7202d90b643000d5355f94dc6891c76931e04a8e6e6a7d0c870b82f2c46118159f08552008e12cf591c3060a7e03d18d574d654d1b61f761bceaa3f63601e07c167be9b75bd6c9de19f17b88a75e25206513392c8d37b9e871370543b4bed9b9492911a687753002172897c4c51a032d3d1d2d9c0e81104c0c0e0e169f2f124b9ef68e4b5eb9a1be13bc80eae1dcedfe3a69336d9d46428a9442e558b12228f471a9a2ce4924e9888570beaa56111a0caa9e0ff86072b8fdee344baab5f8394beb33eb334032e6b9e73be8bd8d35106607ce3a93bef16c58560f3f35787eae034c7da16e0ce526d42d69218821e9521095589cc541b766ecc5fb85ef1f6580d6f44df8d7f34fa01ed014426f2719cc299ac993d42c385d8be00fa496dd3730796120a7fb5f927444da0288485ce19e541319d2c0e12a4f5a87376b45eba1305f26fbaf55004ae9724db66dc7511f0f3c8133dfce133393d527abb38c9b55e510345d004bd527efa7d98fb2177b2efefb68d3e2254d1fb3a763e0e2c3f3f4a9a66e6d959acf47a7f9dd439d01260ca796c30ded1222ad1b8b42780dda66eac4632eff70fea8ae2bfa65e46f0bde2dd1d6ca4775da492278210d5c6b8517390425129eddebe1cdcaf1293c742742f72068d1d1e690a6a09b6089269614eff4ab69849939dad2154ebc56d85c46f611b939c0581965505b5c2288fb679c0428b850029649d1cfd4e9f9bda2f765141ba033889acc8133cd149b2caa8734aef95e1846c675d5ff5587ac58e1e76454bbb69666f82e09427b6b1c4ba2041ce6838f48ecdd093960af8e82b94f3e7981cd34abd82a830bdde37f204bd0c8918b3d286c80864e461bc843dc2ddaece8cbaf3f439ebb0865ff98fda5251995721ba545d5210ef384494426fbac6b75d581b182936c4a9e1f7dabc4a5ff26642545779e51aa7aea4f1e6e221fbb4e2faa88302afd4d356e7f0608c6229235909ac62da0af9aa90876839f075a88ada2c385c6bcd48f3ed63dd6e77dbbc7f061eda76224ed8d3b33feb496c5c15fd1a082d1b90883a1c4f342c0af58d41c8254094bdd4e74e70e4a8e380fff0cf901704a5b7a65471f238943e22d3f8a447aa1ebd1cbf429bdff35c8ef0a179ce9319957a7aed1bfaf65332612bf8745d76c90d55571161692c9db6bfba4841dac4320677d24509d5aeb350c6ec432da1669040d5d98ec8dcd44d800973012ea912d8f78590f5cadec33af958eac52d0229f8c813e76faf12b16615868912b95c15510ddcef25feeef429fe10c0d940f043a9e2c26b2c0d157b4fb3f5c2103c8904198a6eea97f3f6bf6c7d79319d59264a45a2e7338e0f6b8bc395fbeb97faed6c6bd8265259184157655224d13238023f0c1c48be109cc8d06ece1d69073997f744d7cde6c77863444f28b87f22eec1dc4168bfbf07c8bce11bce75908de96ba762cd47947250dca8a9cdac6a5b8d95b2611754242eb8d6f0e9b722ab8185af4bfd10c23536a5211c4f37d482c1319d35913563615130f38126332c81ef1a1e9c52dd174109582bec4ce6367bf524e4ab6c6134f813e6acf806a7fa403c0f1e3afa43f92db6bbbeaeaaced7f9ccec5e27f1ef13fda59467db45b5fa751d28793f5e76535fc95a4552815f86712d75991aaa9f68454f75d1f75d772bef72d4329ee1672254b9f3cd68d0ccf05746a8cdf69010f1dfc479514f43b30d3b2103bad55bdbf89adeefd7c64e06eec5b77e94fb5d948f690812342cea008451533ff1d667baf278cb62740677f4a87d0939436b04131f7b6f89eee313113d68851a8c056a229906ef47f779e473feb6ebea45339021d82435cc72ac9358d7dea0e4507d9f108b3c4f6e1cd98917f39658e39fe6e994e648f0bf664136b860a37f41247416dc1b1fcd9f67bfcd380ce7f4a0d44e156a125d9b15dd7247831264ce2ee178a02d3c82a242811b552e303cffd99115aa4c806dcf47bd2b70e84c96e85bda6aa63e16adb46a08f380a6dc0493431b933ba82ab31c7f6b7ece257e746fcf9c69b6f05a7a17819d37b1f169c4c716b27c3e5d4b28ad304ae9a40d42637a8fec5e8d76bcf68da7a986cb5c618c74a747b5df67fa07d00df20ca8135fcc7adeae7c4f9b6306a6d82fbe66e328d18d47b38cf3c75fbfb56c4dc040514201732f1ab3652f7ff7a30103da12b2d4ad87dbf3ff14bdc349806db75df198018e89a1a6b9aca836d10101e5efee5bf3eac41c2a8980a4d9cde48290989b32083ff51309f5c6dbd4d146ac262da8d458830ebfdba8db4a5b83a1eb28c855d947bbc3bf1d1a97d35fe53154bfad6ff415d1ac7cc0d3947175b604848f26428fd4e1529ffcb0e4657af68e92a1b8f52282d053a66d862fd71a93ab3aa7c00cd8de97bbf8760e7ff26dfb5c1c3bbfd65957e15e258dca87577e97c2f0df103fc60075a7b6e7ee3bf084d915b0ea2b5686e1b58b89dcb8c8e22e1f278d771e90a64303c828de62aadf61e0277fd7705e0cf3acec21dd3fa9ef2a69af9f2ba93ad4c60669afcb534c03f62d1f04607f94de86fb34aefd6907a7b334723944c8bcf86ac25cdbcea5d3b71f06ed939dc459610616b742eca5c27b7f171f9d56f19a70c2896bc47315c222b6152a9526b3986e7050004d66f549532511aea0775a40c0f4160724a4701fa37fdb1bf195264e9807f949a0aaf96cb46a9892e592b44f98cab817212defd26557c286dcd4aee0deaa2e676bf2ea2b9666fd8a46a9a93dd6d7b156c9097a7d1fa5bcbb1c1b449d714858d1998e704cac06bc4d280d489e04f6a11ca19bcbe2a7219281c385225afe6a907091cff74f28792475f975b5a068fc1eca67c0e74446878dd9ea45177b9d2825ff6de8bb92c25ef54c47d2211bc5c87e758f31a80f2535bb08385f4c96d7c14c5fe894c6a2e21d6d26cc0916406beb6baa98806cbf9981ed5bd579e34ac34c87ede8110b1543a77e4804a795c3865c6438d4b2325439c1bff31c15dcbc6ecbd2ad617abc2ac76ae630337f1162a36dda5afacb2ac20ea4536b7ca138ee3dc24e085a7bf61a90c63243dd7a85c0b2392f03b3fad615c7be09d5405999dd17f3e70f55b1f264f7ec111eed5d6e378d6409d85da9794ec490250a28e2f985adb9a7dc0f6e4d22f345f2888d93d8da89e4aa719c1bca2ac6eeb76a5644186fcdad095fe5f6377b1cce418124fc1074a139cd5a09a3d88ec1fa51d91d91eff3cf74a1bbd16efe50ece0c97002103b0074dc4b0c2a0d2e6197014cbb22817ecd59f63e701f02a735d743963910077d9b014be3d090b6571050900a6a97a46c15690d326ca18d9ccdb5c7fc093f940880aa000eae8423e3e582f4f674a66b0c14d743b3e0a0a0860984e047b47a3ae725571d8b7a9b7d5cd4a5583adbe3f088ceb2e2b7fcb014d37addcf8475e3bde4dd57a0213cea95df558d2cce123a01fa5a319c622e39752bd731a5ff1121772c7ae1ac2e3910a0eb1b50d5e57275e8638a0cdec270f796df11b7566dd9986a7f2a757af4079f1784cc981e04d649a862b4fb513f139e5379ed616b49a44fdc096c89dc21b40a23f34b5313137188014316fe67b19d1ff0e6cc4e3edc48753cd3b8e4e2e4c228882d6a19430c45621ee1ee84e7db01351dc09f254b2ba919124047af5258ca7f4a3ccb6c84306a321a1633d56194cbebf8322bb1a6cae3877133e511b6adbb3b0cd86f1011fe0700f7c633e42cdb1669764913a214cd269fb5523df9b65e19140f06c82ec598633175bea12ffd19f4241ee70df1ec0a4660562517da9485e92eec75dedca580e06d64f4da2bf45c28676ed53d450456e4ca9e8d4f9389a54756e57f65b3949639964711543c6b63d2ba9e9154cf4f692517136c3bd5beec28effe15f5047c75b60d4ee0a1dbac15b536f871495f74f978ad3736bbdd35e14881c6d188490b0bc85b39b4243cf58636923a92f3ebdfb75c05c8fd84471335c9b83fb53467e87bb48802f835fa1f2d986e1f69967d23af63107c278bdf7fdb56b5f001b0b826d4a85905418b93b6ded5bfecb0eb5657e4042a74d60fb29614be19b303e38f70cb5d40acb133442eb539990d8e47669d5f1ed9e127079ea6f77684d6c44c62b001bab635c1a4ec2fcc6ca2b866e1faed9b86b3f936e1cb623dc91447aef5401b649a962c95f8f3826b9ca7b141ccf8b92dafcde0798fb96cdbc341ba6eb43231c9584443ac456234afdf63cfe0ebd21ff9e27102175a16217abe6c8a6d3d9b4e7cdc90502322c671da9f57862b58975e7b873c774d1a9463e7a9421d3802c52fc184fff13d1e7e8bbd737e3c157aa2cbdf787ada86b43b8058b104d64c6f67bd2301b00f8df8046d0a95f9be3a3cc42e9cd2982534f09cd2a3b66c527a1b7e5f7ae79c9e3f2523fc642343b4d114544acbcb30e644b7353d7774396031e571b9e6e167a8260c474922dadadfe8b260f5788412632e08bdea053affdab6e47d13c7f625ed7967ec855751e9bc66213f0df8c401fede496a8ec402cd9a4877e2f903aac453419c3403cff59fc036370da8c1b248f741cea7483a5d2196bcd4fe19680e843af05cdbc6f223a575021a9bfc1e8a0f19708af202f540b7b9b97912b110fa11445d9fd413ecaf3da4329c651f102ea46d4a005d25faa2a29e12361752bd509210b0f6ada51f2199fe651dd41adad87962bb0bdb424e34c8fb387f98f018db19d7b1cd5e6aefc2b1debd683d76b4789724d717918fab234ff6125027c96b082338d86acead9aca91162467886b1cfa2764908635cfb4028aad562e6eed0de66b1b1b16f99fad44c397fe1f8d358a2e23a9c0e1ccc101223f4de3d44392b716aff4a4f85b18879a1a8dc9be481b8e37280fb65d3e583d03d29f6747ef20a84dd8b7aa70683b41b4cecf89ab7e8593e757ca417f817464db6e9eb4e31224ddc9877ab31f7be13c6dbfeca18b22adc75bdda5a11f0952b9d2c9dfb44d17e4d338d46358e048375755ddfa0402c28c18f66d165b3f57a55845fa806be019c9718b0a0d6a4bef1eef6c975d03a484ad1fe042a90cdb97028d6d1281147b165345abead8ecd7645b4b47887e85ce9ea44950f1673e107df77b0040a4815ae61aa6e5706456e358406a11e029f4723b394037bd726ffa0ca54b436f828aa3a42e8381388bd5109b7f74c158169114004923e06b3b03aaf9197cb52325c60de7211e4f197c5507537d99f99a7ed7aecb66b2ee2052c3c2e4063269894cc5e3b6e1f291daf07320fa356ca11f62b751a15b4ee5a0f581a0425d3e51c673deb2e7b7f77456fb6652028c9a82dab2f53e7eb7916244afe1e7358f3b19987cae26a9b28b6051baef285047a6d18411e9cf89d456b2a7ac8579d0c2310a8ee02f55764c28532767ef96abccc4642b43b9fa5b14f21def9fd92a1228d74a95195977ea158ee09d557979b26bb3cf866aea8706e3fea27d149157361de32ac4a3b7749eb0e2a46a9e42757224f16d6616b5239fe502f7f8cf156d8a408bafbd48ffe1d0b0e4a01ccc9cbcd825745d1757851a41ca53bdc48f78793adfa167d84e62a663b0ee8c4ee94dfe86eabe3b1c411cba3771c85503853c0609e5b30c0ff8f961c6ebed5b2ba870ba34c6338044c4170edfeb9c3a1a25868838595e462d7fb4f266fd478ed262cc5ac83b5c3966c39bbd36c4d7325d249ae1ad2cd9aae12291e32c600d3adcbad069d00992b3a9cd346b667ce5fb87743521468302f1d00a196d2ead6c7ade6f6971c0dc5c8c8edea6ab0305285591941bc734316291c45bf19f3d56b5e6ea9e9dbe26c4c6b17f9851c8087455c8cb70010a6574b57057b22d803ff6d789e6bac926842cf14c45fd063dc5367d90c002f661876a37a4bdcfd6650682dbf2cb2159540acfcdda5b3ef4a21515bd3238f47afde2291187d1550045fb51d5683e9be0dd3a7bbfd38973ac9e4caf716dae7c889541916b9586d13096263d423c58ec18b5c8ec4870a7f7589fd2c451a71773ac446c95cc9d8462e3b0a7e591ad349b31fe84498d9e38eb962c2925af4954e1570df2fe38b49f3beeb95f6c2a8b38a72914e34cfda5c1cca400af18a8e8471bf0f326c69f9cfc776481c46cbc8685b1ed981a88450771cb2edd4ed2499f5780814dff5c3d1275d26ba9eb9d4de3c34879773c27bbe4e1793c1bdf9f0f943a1c04fdc93365f97247ea739f66daa146363a89309e7c75c256682642bc22544169f0adc6986ea7d0f6ec35072b2956a434d608a67eaec4c53e7096567b210b3c8b87830efe4670235c5ef4fce6d6e14f84dbc3126fc7351d87f1f1ba2e0bf71cfe92548ce95aa4b46a6adb405df0e13eb3ebc3baa93b0a442879de9e4b144e22ee9d25cab4792d4274742dae005206efa93cc02a86d2fa52b455dcaa2ac782040325da2e202a3950e2dc067c8360552441022becdf8ebef5158e9506238d0e56c000000\";\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(\"Pilotchrome\", 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 [\"Pilot android\", \"Pilot android\", \"Pilot android\", \"Pilot android\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Chrome helmet\", \"Chrome helmet\", \"Chrome helmet\", \"Chrome helmet\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Cyan rim light\", \"Cyan rim light\", \"Cyan rim light\", \"Cyan rim light\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Rainy neon city\", \"Rainy neon city\", \"Rainy neon city\", \"Rainy neon city\"];\n    }\n\n\n    /// @notice Raw artwork bytes read from the IMAGE data contract.\n    function _img() internal view returns (bytes memory b) {\n        address a = IMAGE;\n        uint256 n = a.code.length - 1;\n        b = new bytes(n);\n        assembly {\n            extcodecopy(a, add(b, 32), 1, n)\n        }\n    }\n\n    function _svg(uint256) internal view returns (string memory) {\n        return string.concat('<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 400 400\"><image width=\"400\" height=\"400\" href=\"data:image/webp;base64,', Base64.encode(_img()), '\"/></svg>');\n    }\n\n    function _attributes(uint256 s) internal pure returns (string memory) {\n        return string.concat(\n            '[{\"trait_type\":\"Character\",\"value\":\"', _pick(_T1(), s), '\"},',\n            '{\"trait_type\":\"Outfit\",\"value\":\"', _pick(_T2(), s >> 8), '\"},',\n            '{\"trait_type\":\"Light\",\"value\":\"', _pick(_T3(), s >> 16), '\"},',\n            '{\"trait_type\":\"Background\",\"value\":\"', _pick(_T4(), s >> 80), '\"}]'\n        );\n    }\n\n    /// @notice The token's SVG image.\n    function image(uint256 id) public view returns (string memory) {\n        _requireOwned(id);\n        return _svg(_seed(id));\n    }\n\n    function tokenURI(uint256 id) public view override returns (string memory) {\n        _requireOwned(id);\n        uint256 s = _seed(id);\n        string memory json = string.concat(\n            '{\"name\":\"Pilotchrome #', id.toString(),\n            '\",\"description\":\"Pilotchrome is 999 Cute cyberpunk pilot android with chrome flight helmet and cyan-magenta visor in a rainy teal-pink neon city. Art generated fully on-chain on BNB Chain. Minted by .ai Agent ID holders.\",',\n            '\"image\":\"data:image/svg+xml;base64,', Base64.encode(bytes(_svg(s))),\n            '\",\"attributes\":', _attributes(s), '}'\n        );\n        return string.concat(\"data:application/json;base64,\", Base64.encode(bytes(json)));\n    }\n\n    /// @notice Collection-level metadata for marketplaces.\n    function contractURI() external pure returns (string memory) {\n        string memory json = string.concat(\n            '{\"name\":\"Pilotchrome\",\"description\":\"Pilotchrome is 999 Cute cyberpunk pilot android with chrome flight helmet and cyan-magenta visor in a rainy teal-pink neon city. Art generated fully on-chain on BNB Chain. Mint is gated to .ai Agent ID holders.\",',\n            '\"seller_fee_basis_points\":500}'\n        );\n        return string.concat(\"data:application/json;base64,\", Base64.encode(bytes(json)));\n    }\n\n    // ---------------- owner ----------------\n\n    function setMintOpen(bool open) external onlyOwner {\n        mintOpen = open;\n    }\n\n    function setRoyalty(address receiver, uint96 feeBps) external onlyOwner {\n        _setDefaultRoyalty(receiver, feeBps);\n    }\n\n    function withdraw() external onlyOwner {\n        (bool ok,) = owner().call{value: address(this).balance}(\"\");\n        if (!ok) revert WithdrawFailed();\n    }\n\n    function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC2981) returns (bool) {\n        return super.supportsInterface(interfaceId);\n    }\n}"}},"abi":[{"type":"constructor","inputs":[{"name":"initialOwner","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"name":"BadQuantity","type":"error","inputs":[]},{"name":"ERC2981InvalidDefaultRoyalty","type":"error","inputs":[{"name":"numerator","type":"uint256","internalType":"uint256"},{"name":"denominator","type":"uint256","internalType":"uint256"}]},{"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error","inputs":[{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC2981InvalidTokenRoyalty","type":"error","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"numerator","type":"uint256","internalType":"uint256"},{"name":"denominator","type":"uint256","internalType":"uint256"}]},{"name":"ERC2981InvalidTokenRoyaltyReceiver","type":"error","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC721IncorrectOwner","type":"error","inputs":[{"name":"sender","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"owner","type":"address","internalType":"address"}]},{"name":"ERC721InsufficientApproval","type":"error","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}]},{"name":"ERC721InvalidApprover","type":"error","inputs":[{"name":"approver","type":"address","internalType":"address"}]},{"name":"ERC721InvalidOperator","type":"error","inputs":[{"name":"operator","type":"address","internalType":"address"}]},{"name":"ERC721InvalidOwner","type":"error","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"name":"ERC721InvalidReceiver","type":"error","inputs":[{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC721InvalidSender","type":"error","inputs":[{"name":"sender","type":"address","internalType":"address"}]},{"name":"ERC721NonexistentToken","type":"error","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}]},{"name":"MintClosed","type":"error","inputs":[]},{"name":"NoAgentId","type":"error","inputs":[]},{"name":"OnlyWallets","type":"error","inputs":[]},{"name":"OwnableInvalidOwner","type":"error","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"name":"OwnableUnauthorizedAccount","type":"error","inputs":[{"name":"account","type":"address","internalType":"address"}]},{"name":"SoldOut","type":"error","inputs":[]},{"name":"WalletLimit","type":"error","inputs":[]},{"name":"WithdrawFailed","type":"error","inputs":[]},{"name":"WrongPayment","type":"error","inputs":[]},{"name":"Approval","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"ApprovalForAll","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"Launched","type":"event","inputs":[{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"agent","type":"string","indexed":false,"internalType":"string"}],"anonymous":false},{"name":"OwnershipTransferred","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"Transfer","type":"event","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"AGENT_ID","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IAgentIdRegistry"}],"stateMutability":"view"},{"name":"FREE_PER_WALLET","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"FREE_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"IMAGE","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"MAX_PER_WALLET","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"PRICE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"approve","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"balanceOf","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"contractURI","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"pure"},{"name":"freeClaimed","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeFor","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"},{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"n","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeLeft","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeUsed","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getApproved","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"image","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"isApprovedForAll","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"mintOpen","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"mintedBy","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"name","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"ownerOf","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"quote","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"},{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"royaltyInfo","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"salePrice","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"safeTransferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"safeTransferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setApprovalForAll","type":"function","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"approved","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setMintOpen","type":"function","inputs":[{"name":"open","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setRoyalty","type":"function","inputs":[{"name":"receiver","type":"address","internalType":"address"},{"name":"feeBps","type":"uint96","internalType":"uint96"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"supportsInterface","type":"function","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"symbol","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"tokenURI","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"totalSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"withdraw","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"matchId":"58371201","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-04T13:48:49Z","match":"exact_match","chainId":"56","address":"0x3AD8738C82aDe72bc632eA58a51E2368847BBf44"}