{"sources":{"Jiayoutigo.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: Jiayoutigo.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Jiayoutigo - 9988 Jiayou tiger cub cheering in a red silk jacket at a lantern festival for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 316 free pool lasts (gas only).\n/// Every other mint costs 0.00005 BNB. Max 50 per wallet, 9988 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 Jiayoutigo is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 9988;\n    uint256 public constant FREE_SUPPLY = 316;\n    uint256 public constant FREE_PER_WALLET = 1;\n    uint256 public constant MAX_PER_WALLET = 50;\n    uint256 public constant PRICE = 0.00005 ether;\n\n    uint256 public totalSupply;\n    uint256 public freeClaimed;\n    bool public mintOpen = true;\n    mapping(address => uint256) public mintedBy;\n    mapping(address => uint256) public freeUsed;\n\n    error NoAgentId();\n    error OnlyWallets();\n    error MintClosed();\n    error BadQuantity();\n    error SoldOut();\n    error WalletLimit();\n    error WrongPayment();\n    error WithdrawFailed();\n\n    event Launched(address indexed to, uint256 indexed tokenId, string agent);\n\n    /// @notice Contract whose runtime code holds the artwork bytes (WebP), after a leading 0x00 STOP byte.\n    address public immutable IMAGE;\n\n    /// @dev The WebP artwork is embedded in this source and written, in this same deploy transaction,\n    /// into a small storage contract (runtime = 0x00 STOP byte + image bytes) owned by nobody.\n    constructor(address initialOwner) ERC721(\"Jiayoutigo\", \"JIAYOUTIGO\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"52494646084b00005745425056503820fc4a0000d07e019d012a900190013ec154a24d27a4aaaba7d5de11701809686d82c80edc5f5ccff1afb07fa7e717c8bdf67dbff1be76bb53edcf3947d3f4f1fdbbd177d35fa95ffbde94bfe7fa1b7a8ae89ff5d9ff19eb07e73de8f18f2f2d5f1fec474f1e30fd23c17dbf3eb4ea35925e183d8690ffaa7fbae5d5f363fca7a8aff4dff65eaebe007515dd8d3fdf4f8ff3d5ed0bf03c471295731571d74a97ef41843b1aca5dde5cd7f0c0073b9916895cb58b4c7f54144676d7f0bef5b5ac253bc261c494068732f3a35ebd5ce078a4168c7b269b60be4df4dea3b27a91e992672a25a8bd6a540264037ab53b7698d99ed5bb7425053968869202417605b3aaa195728c3990417307b401cc77e02a164b70108957ac8e4c13a24b20428b9532988cc023fb6c1ca498dad5bec13d259468cd083f831d35b55b5c22ceec81746a201814706a57470f1178ba7cb495a4adce55193aec449602686bfaf829bdfc250354b27b5eaf96e7abd28096e65a6488405d7ee1523a78b5955024dce389e6df5113694070743eda3cd4c3de91a300d92ec2466828d7afb2ea268b0f4607ae521ff26cacd3a209f68213ac832d7aa80a68bfa21b4c7440ddad98d7b15beabf298720bc2a1ad2e6fbbdc14917454c0f4c1c37f4324eb0e3be8d2f9aec01e850ccecb2ad77e8de4bb1684817cd6b90c6aa1a256cf99b5dbd19266ee2eaac504c80c1948614253deafe3d2e87800439c72bb04d7f86629724dcad9db727a7b0db7c7f531d87b8162ea21c89065efb573a76eb00a16d39ead15d62c3d979bdbb8ef186b0207c2b87fdf51fc7171febcce0b055037243bbaf3df78e4fd2db422e8712ea0c5970fe3f0662195f5a0e5d0c8ce12ea56c1d86bb2b573986d7dbdf21e02fab9d4f340e72b405af3a60d9fee8b60d41696dfea8d10fb7342c6175cbff34850fb3caf0cb8a983f73c1874e02a20c6b5f732dee6216947f5dd25bdaa64513e36e10690fdd61289268c90f6366cf98d24e67b5a1488026fd071d8a7e914da49cf18b14cd373af90e1bf5e09165bf5db59f91ea51ba88d072d01edaf901cbebe0d258b96c4e6b1e8c79f1fedbb1078c29e8ad5bd6a5ecd9201aebbe47e31ac997d4dce84e3fbe749d1bea0d7099f4a05712a8124132e0540b558b5467a6e1bbd35af30a104adde029cd8f993129bfc40e8b44e90eae8f5b73d074169d17771535efa650caf55dd37f354a66ed2a1c6be2607ccc625d288f4f89293db288c3c5fff584dd7baf30e31cce5bee57b6b7767aed0818ec0c81997a4240fe105f75f15763f4fcb89366e2f050b4a83724cb468406597f6ca1e137ed5198bb0c966b228d5a27154cd4719293ae5061570284c57cb54bacaf07b8d556f83a1c8079cc97c1ff1cc978cda7842706bba8eea9d29d66937b96f0100373cf82fdaaa781dd6d9b012c2657bab3374dd987bd7cc38be556607030b672b6cf7c6f4df617aa09007f45cec66a066b40a579c206f3746d486bd0e322cf69e6c58e6c88e172edd08e8dc742486ceb89d4494790475702f4921effd9e7b7beb632770aa65d1a93781803485f4ad321db6056f0fe1833c2638806559aa5190aea11f564e093f6cf90e0e3e391ccd268c0893c94711ec00d4000554e50d356c5cdce317c6b192da5951b95dd9cf5c775d330ae8b64908a37f0ea44dc1be002cc6c69241b60e4ba3112ddb83e0434631cf3af97f7b3fc3a857d125d0443497b21e60d1d8e802afa1ee0d5895cb16783c893a8b5fffb7933a9dde4bfb94bfea441f6da411fef75116eb80877409171cd9fd1329e35b3c0444c223f38289625c374a84fd56b4b35f2469c4472f996507fce1548c29c358af047c1f0540324e448c0361132abdc0d1b06285b2aa6ec5cec581d9034229a8d9cbd6e986ded32cc22bb35d548ddbae4702eca06d9c2fb1f02754040a1ca7771a5d3e5fd8d8a5590be6f061449a4ec6770364b675d57d20d7d1c55d968f72a1eaa3dc4bad498590bc25aca4391f762f10100f0a2f6ab8bf6c0831ef2d840819c952f505dfa095ba4ad7c2d74233ce9cb3c53b5e7f2f52ad0ea9ffd73059681343484dd1663a31e9668028c6c6118aaeeaccef9a2bae30961f171a08bdcd501f7381b90da319c56a9f5844ec7ab71fe47631b96b28c82edfc37e76293b9a6a26087489c6e7f4155756728b80568dc5550fcddb9d69cb37918094fda739c0631d45c685e28cf8eeb602cabcde0043ab2ff94bc5f415e9e68dc7b9fcaa2f3f7e98cabd45a428c204d38a1475906457ff720cb2a50b9c6c008fc2097bf24e6d7726f4e72af28f3ac02164777c77d3ef96236b98a337bb68f32f32b8a679e6660d6db8be7623aa97dc4d0236f2b7513226f41a12c155b7fae79110200620888ba7918c8bd9d27c26fa81167756568666b36d78f401b2fa1a70fe7828a5d6bcb8c7720a6d17d65bb46f0cf4551e91a3e94dc7b128a374c3421012442547def0daa78eb5aafaf6305c0cefc6ce62b84b5eacb8b2a1f9a801918a0d18b5cd2320d1708164afe002ac884591215f9e448d55f3db0bcade1284d6fa8e8af3e71d183ddf5a5c5407c3a84294395f2deac573b5cfb720492a256d1a64565a7e304bba31960c90d0c2f42e11713cb9838184ccb0257bb188eb8b2740f34c39a3d61bb3bd25789dde1651ba7dabb206652c7a224069ce8bb0f40df77941f5006a5b909beb8c8141a180821dea311cf379fc4fb83b9a9b5bc5b3b5e1b20f04a3732e4d7accc60923d879fe4e8727640bd3f13fff3e1ab411308954ff39962f6d1e5c2d0222fcbdb0cde0a3dbef0bd378d48d95bfc0fb144743dd16e957e5263232edbda301419c6ef77c08ea0767d3f0282e266cfe468a20396c2a0691fb478833298f9713f09e82363826df89948e26933df0cc3af8babcb8f848bc41e7e8105eb8ef0f78c24435d9ad2faf096946fa6c857cc87025905747d993d85cbc327728f5037150d4c38c1349eb811df0a550a1ba4aa7bf24f5aa9a5fe843aa69e3121e925a074ac5423a6fcaaf1c092c79bdce44e30b4270f025a158724e06716a07ed9b9c81b0148bb8c9405009665de24f662638a772a77ed42fdff2afd7ca1878b685c7ca54b923fce8756f64a3c50e7d5c41edf89d04c59e74e8ed266fc46cb0acb7f0534c3616128715efad26fa9dd9774cb3a490e0cfbd8bb1530c38d0517045609622dcbf678438335a79f1b9ea8f0eb26e4fd8da8525bbe496a4251c8020f52e545e5ff32bfdf4774cd00556e2aac815f2bfa408df4a76af4864e491ae386a0fb874a97630626ff07792a4cd65e6b01e0046498e06ea88b6b4d0c451cf1701eed6c67c0c772fcf66df0d9adfb730dc6567a36b2cf76742c2e04faceffd00bfc936e5acbafe8fa01b49c0d279230b61577c911eb161e7c903ca1b6dbb16e4f8862a436c36c44cdbfc4b2743a3c7e7c441e313dbc8dae79dec6776232646034739fd95a903a3c269c5d906ea8c3ae1077c63cedc76e51db777c7c9b4feb9a5c75ea5e844fb80546c812804c643789291a2384ff24784d12d438339ba646b3028120616f59e4bc1466b012fe182cac7a3b61de07c5fa561d9ac94aa9574a8790a07f8d491cd487fd2b285dce240253ba38eedcfe9a9615fe484d4c5c9438fd1d9401cc43e3bf0eb6452ccccd5992466c25eb5ec88de4eb730e54c783afe6994339a8580aa9f1ccbd3195197e53b61e0743a43427ff4dcabcb2b05811f43c45d53971e863f0b2e83998d092832f61da5e0a67e86bb3ef214674efe6ff970b7e578ef16d20d8ece7a6ec60ae23194f9825120959ce99254a5f505a7fc0c8038628099aea3815fe53b36baceecf17addb6fbbc96ebb60dd0fd10883fe4118608e1b400eebfb4edef68b28ddf6b05f3dc3c77c7dd6669d7a4961d99e42deb9f3fd2f792cea4c8d13d74cd598f773bb261ff7865073474aa2b93d4ce264365c9cdfd08c8cc3647767a926df6a81849828b11a2bd845c944e92722616f3a767bcdbba328e24d7c3d820c45d5056fc297a7bad97b8f735c278b12a1ac37a1ad8a67ec5eeac2b6ab959701e55160306a2b69e2ea3fac85e833dba1e58ffbfef06feca0391a2d736c7b7ca7f6b08ccbeb980c0358d79fcbe2329147b7cfded7d51bf9176c78e1ceec679521323140be12054e1f86e2f5085e8d0ed94bba566c69e4a5324674f23db653fe4092fda57db4846faf635041da7aab0fb4edb828b9cb8798e6d207aa20d207ac20df33a2dd3cdb8bf3b86a8b3b34ebc54b44b8583d47e6fd1562dcd63e75e576a86cc2f3a131488a3cc469b1678b7df5539ebacb0cb7f0aec800fef8497e7469f217c38718665a3957d2a772eb74948f396f80f893695e6777e32adae3663768f7af9faa9469d4e9572b90cc6d12612f74d740c556073f183902fa80446c92c45657774cedefe2ed5f4175d521570a363630fb34093ce22bdcb7c69ce66de9dd8322be2bd579891b4be6bdf061432f979bc29adb34f2137197983ffde68be83076c34e72407026369e55478c9251c5b0396fa391d985d366af36528d87ed49343fb75352ea52884a4398ee489863a8fb6080885e9d6ce7711bad45736f45e2c949e046d9e3863a04e6866230390d70b27958626180838ec1bbb0792f42b5baa07e0af30660fce652cec320ba6e780c54de8ea80bac85ac635ec4994194a12aab3576e29401c37dcee0cbc6fc3407eec3c92a211545a90d513fdadccf0fe1bbbff99d395d8a9fec8d61aa2ef2898dca3f2e8183096ceffbd956f43d0d6e571183434b973226f4fd04fb1d648328a382e3e7c2261bf4a136a233c357e4d8e2ec7965ad373a25c32698beb019beae1079cd4d1af9260b8eac90fa51ea0504427dab55186aeac7125c16af9b42f9c803859cdc728b1e91e8e833aaa9414fafc34b90ff2a8645aad99ba2046d6cbd1b1180b1705c5523eccd906ad32a302c12cfe2e14c495d66ae313985356061b6ba85e7a102175b257113ae40a7fdec2b21d2a4d06a38da2a2dc55985b51456029b78597d1300e6d7c50763689012af28abf6db18753feb6be51b4bd2b1d0f20c8d174d10d16d004aaa37941b7c8ba04a62e198cb469b38937a9e2c3f9f1dc191e98ff6831f5253dd77bf07836ee0f957a51ae92d221731b56b64c62a7580b55b4159a39dac1d330059d2d5029f7819a0a44871c6ac9e5ee68361e7979ff42cabd931e7b80b45e32aaa34deb453b575a7ac2c7aa554e841a5cc1b73049ca3861287abdc0154c04dd206b599958c681f47175513ea1558fc036b770d8b73545500c0cafb2c15bb335ae80215b39eb507646e4b43a25a53a6317c107f390e50192403aa01427369ca12f1ae4b9e30c38c710e1a08703697667fc8c15acc761c564094208cd9c9bd939a919496ebfd3a13890d805e7935f6f2423ef26c89aa65e393d1a04b43e895958de8bdb80be6430221be503a983888ad35a717d100d209acb872394d916f0d822f39cde1659b3b9d000409408e90cd8a375184aa644dcfbffdd3e2694d34bc3fa08d01c3a66d360ddabd231069d652d6524c0c31bb4d029e7280a7aa26ee255498b38d5a036ce5ccc4544aa0b4727a2eaa9c6e842af760228738503de3ddfc74daa85d580b06a233f57d56a438ad00012f90f6a3eaee858d3d85ff8c832bc423d84c5a0dc043087ab56bf1c8d0ff7f0e9d66959a3126dbf2efbd6d28b2d048ad66e37990a896b924150ca0f0991d7b8031f4701eff1e645ddc04b6fec3eb26b2770434d1f0d1b37e0dd79470fe5c86e111ae47166f6ea88dff409ab113775888b7dba2fe4d22404cc80146b27edf872675264d6cba4692343fdf89596543fd94cd1cdb653ca0ec17b6c68887cff8a877988ac05f9c9284d802c99329e93dd13fdaea5cde52a347c00341b378d5dc92162cea5b2c802c25d5ab0143c6567ead04e1bd2dbdc081b4f786b284d7ec312906a2310c1d8d7fdcca013960946c8bd3b018e1a358c5407afebc9718b2a0751f79cdb608fedeb1c03add93ecb93e6a9db8435b5161e77483c42b9825597ca36072f65bb0d4d64c135bbdb8eda6f02a8e8fd75c38f5735c56af7f77e719fe71699809ccfba7a58d1595310e8cfea950e90cb647ddec6494c61e2e3cc451f838696ccdee57ad54505bf0c5d21b4a9cae5dd20b3b5000d5211ada63c6e248172953d28f6b2861dc71e63a577fde48367155b7b41e87588e376f070f814e20dc704a3d49c636a68523bcb7c16f575a8ef41ed00cad5f4f080fe56d79f292af97088fc8aaf2273521d903c9519499a3d9cae5a3823e6a389095e415d4c9bfdd5088cb367c481a886da00005a2d6500a1e8f46508b3b59208c4c57f5674d25d3396898d7e4919235c1fc7dcaade8abed4e15122e588ae921c5e91769bd997c2517c7cdda6db2bb45d67f8e84f90e21b0780c5a5cd5df3df6f2ae939c4d7ba5d3d010b012c3040ae45b01e91f8154bc9dc6d853947983b34afebf8c47be05fc7f9f9bd636150b6ce78dba414d7666f94638671253a855b9b994479ac5bd82e3c736eb8d13fa4a3400b572d21ec48762733805f9d7a389afa6caedbc34e6c7cdade21a474ad18fa349593731c1770c3f9e7652c874bba0e6a6f303ab125af3e37d6875983d6c9811c643a44e5d46d9e01fc7ab3ebaeb0fdf9c98c61b1fd3efe4ed1b7c47d67aa81352871957ec5ccfae1d3fff1a8e9bf7966adb61c4bbb519eaa2ce0c97ee2e04309caa571d0518553b48ec279608551d526cf591e20a4f07fba65ca0c6117d0c5b6afd332d4864e06c640888b6661b9fff3a7d873dc2396b7a3c4aa252b10e7a73baa7331cdcdb2c353ebbcbc35bd6892ef953d1c57eeeb361ae2fb53aa19394a3f97102c496e9c598ab795dd33df3027769efc1d8f931e7002cd809f509fb36ebf90258f7c07e8a4ca326076c7723b9fef75536e465fbbdb3058268a66687440222f20cf6ef6ec007d17d7ad60e6301fcad47197fef0b31813dff2b8020fce490106fa07678a0d972e61a0436df542ae92d127761ca5965c761be3debe4af0b3501f1d5e6d553f5e654650043ab50404a1140b16b722312d29dfa5e65d9d6fc5616be7e2cbb635ba9285669fbfa5400424492846fb804757a215b376e66486ec9253fbadd80adcff00266a31e7f0cb51b9c748c966711f74bb77534d96fd53ddd261339f743392673065836faee8cdafb9820ca62c2a5519a6d6e523aa428ab0b3691ac4d51c5d2e7f45a146afb51b62c04e6fa6ba6514c89f38fc39b86c2a0bd07e490ff9801bc841717d660cb7c0be1a22940c2774e6d5d56fcbfd9c6ddb2ed2f84d0d7d921a24a5820c84fd366d6fa8f4a87c6ca9984766894b043dfb9f9a0c4512843c989aa9e7e10d8c16fb5f59aaabb4f9a8399ad0e60473e1f41f4c67ea60554bccccda9d78d375f67e6978bbcccdbe7a9af42a294bcdf31917750f7e3e9a4d13dee9846e24461eccfec4a797d4ec2340b72124f00e2b4ba3c65cba66d833bcdbe2779321ce24c94f42151278b35c1468af4a1174c4d8caddfe4f5fa9f9e2d51c44b80c3c7dc08bb927b94d1850e85a30301559d409d2c21c92ef1b998c1fcff2a65545e9fa6eced87367146dd7682bb2bcb2f678d71f4125777ac4ee11165037178e369392e8b6306ed1cefcef3c322a3fdf0458be90d9f5fdd5f00fac2d5d520a1087a0d24581db7321e35ef948e1257cdcacc6433000363a65936a57d6e69ddc84c7d3f4fc76705aae2059dfbc845ede304eedaac02e08fa30606ba4c6eeaa78a1a573a6f6e6835743ec3df09988cc8c808872534020a68dd7c7623d4553140edeac1eccad965d2f00eb84d755cb67892efde349b821f2517bd401e0dcdf905ae6af48b50f0643be7a5964a71ccce9fad3abc19acf75f82d4d8b35807d1f0c9d7984a86ac7453dfe8625d591e2bf5a4953bfab692f744fa5b48611b30d3722a9efe6ea61c218cc865afd4a7e289e8a57cfb90fad36c2fbf004f1cd7978cc4cd208d9222628367f2f1d2c2f834050c7d6d830ca98d8614f771327346227eb2eaa73b181776d9b4170529b0702a0d0d673947160f6f54d0e307b7eae34c9caf1c6027b6491d370fbf0c753c1d4cb70085b5b090967c25a60b583aa5b3090e3bc0036e5ebf6fec89d9cf7cfb4d19c5a1f39d5247945a51404a59feeacf9a38777bb7d2d0b48ef524b948463d48e9919b7b608f0106b011e976770a23d1a0df0d0fcf68212c4664c7d757258c104c606f5d1f563440cd0e7af599e98b86fe138f35cd0a13ed32cb2f5866ad497433b4c72c3ba97e4c12d524613d4d83d5ba99f4526d6c0a1cc7b7241f927ee2612c97768ea989d16c9620029b92df26e2430feafeccdc20c5cebd5b4e9b6adec565e3363eefc5f3098db5ab9960b9a4285c687d472eee2a31393f657777a363239719353d48abd9b88f305582db231d2991242a4da4ec2f00d3a9b68550e3ac9853adc56cf25113eceea2823b5fa4ee5455352769eea6062c2b7503eac13319e3a0d948678c09ddd1d7c7dd2800a4c524a4b0d3aa29089f5c31da31fba2d0637b7849538ad1cdea25f70dd43a9e57fc279ae6b840c981eda3fc9f7b9fb87f1d755d4a1a7a669e0e1fd7009eef0d76aa23cb943001a2e5d396fe62fef65f4d276f3669b8d5a8da584e619bccdd7ba9334ff51bbf3feb779b2544aa26060e61fabf63105ecf98d1f3d8bc46aff3e1fbdfe75556e63722fe3c818075d80fd7b7b47e299ba67925023a4a98afcba089190a909eb77fe2d58e45033657501777df66bb9d430496cbda78301aa942d265e8e435b213ecd5e984fc3a70395f125e33b8bc13c548b8104643596b96fb2fca89d304c553949020f2c8dd83b29ad1be77acbe7e11ebcd837cf6b241cc83f8d21fa5fbacd35a8932b7c32ab7b0a827cb1fbd406f5b20aa831981bf181bda4fcf68aea955a63f5cd6245c29abc287652df8b8b9b7ce337703af0de3ba60c13f6108b225faf3e873d6d9dd03ba2cc244c9e3246bd803929fe8e6169a8c058c3f76e9a81dae49b4bf6364fb3c52d5b767c48700f8c74811f7a64ebf850f6cb45ac5e6e954bd084f79342d6cb752d9b1c84ddff20c72169a5ac5038fb4d51650f53a9769d269d1bb10e4a774ad6d6c0e0ed51e1d9e551f430776412443eb05a9492afbbb26d4807682ae5fdaa64f7a82e7f1b723d7614b5ef631a2c34b3be2f0df36d72e0845d0c0636200efea5d76edf8fb154f0a4d6d9aecb9a24416110b408af2c51521a4105b7622bc6f2d3d9e83436e1a70ada920be50d91ce37a6efc0f0af4a4fe50788e8593a8f5452c56f53b0340c94b03e31cf113cf39203efb9d066267e8f06aa9174cebd885e3175a20b8cba0aec79026dffd74d70f657a3f8347938efe21925ce79f06c2cb33f9bb814c31164ea30fae1e93b6cda477b5a2b9d259af6c81730b1e08d1a5bc65d87e7b554322f66084c0812af495153cb72e4640505b04214f8b4dfd7d52f9f1b3d39f5613c89363690d2d4e1906fc4341c9b02f01633ea69d2e4c67508be91246392fd43515068f762da29054e616f3f96084f0e94009085d3078d61a60f2d7ff9f6236499ba8f001dc3e4a9dce362fb4aca91b4c0a900272f740e6be2be62d8745be6fcf03ac3534e72ddd54033f56d5958a960a04f78c43b3f65efd2728b3ab47f323bc4b9ae8eab1f04e1849209d72ca15feba4ce97774e7b6b06b511489666f3e6ac174ea38a74bfb8b85cb8ed36f881e6c9b75efc8e3086f8c41015009c928b380a4c824411ae35dc93b3bba34390d3c8d9ea8ad00533d0f7ce67ce04068d3cfa0c1d4a83b56828c87c8d0d5d11e7237a497e4836e503f97547373db73fd6cf0e303f9411636d4c3442fa1778675e2bd0a89e13845fb04a2a5e769481523fc988d43dcb652852b43d8bb0e5371cae41b83308b9699d6ab1bf9e333c2280284225c7a4e528057acac80499c9f92446f6b1304341fcd7920e1b649bad1b09c002dfd0d12fb2b4c4008c302419a727c966f5acfea5cf30fe5715deb6c92943eea7cb7ba886ee951c0fc6df7b3c85e89bbfefd7c251c3081d71bcde330cc4a31cbc228098cd55e714500f16bdb09197080c52df973b57bc95bda0fc4f08114cab04eae5a266f90cdc57b988bb48d523cb0ff7c1ace96cccc2365c924f0758003d158fca2e8f72f49d5bc46ab0b9658ddcec56e80fcf8fd49320cb2a7cfe5cd37547d1136a5098ee4b1860e7ea1d4c806e87fbedabc1d3318acee786898c09ac6d59a02a6202a689aa187fb36de4d80fbd0241c372cadb883b98145423332fda49f42bb7f8e90eb694d4d915321e40206cb0607f6d87a6e09b6bd9a2363caf96b6611a33880385bb23a02146fc5c1efb50ef2c298217ef0747494b48a5194f217c05236f89242914e980bad183960f6f76da161a3ae74b56eb36005ad311d3b2eaf96ca15c27261364734bae01bca927e0d34cc876d5d68bc05693149ed763b69bb3db91359f84ead702bb3a2c8fde01de4a1f2aae320022c5919be324936dfcc45d61ba2775bac2dfe57ab04667a5f0d3ff1a00654f7947f681caf46134860ee9b25ac92354043ce900b0f12194272f641033c244a7bd105a224a8d0db1a0c5eaa5b6c2d6c70111d09a12ebf299644842f7fedc1551f490001a34bda0c6192c095e5309e1cd72125f6ef765b08ac06f021f3d2433203486e78787cc396f7c443b8e5da12d66990d1e5f5a4df6b0d769795845a38b511893a5cada8ae265e5145e70157dbbc094303f3dfa44bbb27847f90fa53d0db9c14e187ec167cab28ad437f0ea546da1b33f2e2ce40552fb8f31ad91970799bacef25bd61fcd836655f04834f5b3f6f39fbdd23db29af8db22c8c31033e3273e39c01ba69020e5d814ec16ab5f43e6f9fded6f0b1d5f4a99afad2e462701d348b03dd562b69b453c0f759c139eaa32da71087d6d5b7d34b836d88f1c2f82d388c9b2773e4e26b719703fd54c7a13ebe42a394b3fa79fc84d4d182ebd529be06dc549205083018964d00c5d30d02a29c35f9885b9a780a87ea031d990c48df72d11cdcc4e6ab49958a06e99222a6f46c40dd556df3b7c3939ad188d61c1c0c4e3936c2bea68740717b5ee634ceb9386ae186c5a7a16c56d8fcd9df2abefb8cdbd1e20bd2fdb7c67cba08b0d43b4a1180b10be5254f418995fa57dbcdb41b95bc4863903dc024f8db2502e79e22e77acb900fb262bca32837cff94229adf58fdf9f90df958cf0fc21b25d654cacbc6a1ab986768ec3cfd573a0877d8ef4458f3ddb761712f1f16351d1971ed865b0766676bf608ec13eecc4d6ae2457d5788ecbc42c9a68b00904fdb8093ae2f0d801c622f8655f99d4220120230773a077dead2c5ca5a3a50fc0b48e948647856e3c481d60621c5c285830679fe73242a5a3cc5c07d1276c12abc054d45d6936ef51062ec65cb42e0d91bd443ead5ee60763f7c32fd7378efe364fbe6e1921b57dfec8cb93774a9958ae2e0d032d1de349c06a69636ceee42fee6f4482e625af24e76eccbc06f8f25f3f863e5d2e66b60a614fa54026bffc1d6a91b608da0eb8423109051b4066b27ef3bfdc3b91b0d70ae31ec3d12bd5dbb569c2e16864bfd33587de8b4a997728c24bbab643b360906925c24c079d2ab69527312e7b25903b5f3b895ebc3e2eaa2ec7d0cbc202b027a44e8621c030c9f440ea2f9e4acf9cb88eec6f2289c475aea930c9d3bd2dfb49d754bcca54fee273703dc170533c2e7759a89d9f4f00eb697a5dfc91b86cd2c7d56c5c41172df1970c8c0f978138cb0713a52eedb8abdddc06a3d45240354615dc4ff6fc8637c4128a4f1eaeea21bbbf57359d27977905d7069e295080986fb4e388bb0c498dd5d1d44761e5cefd6c09034a94e2a622e1be1c871dce8ea7195b62219143068281769e7dcb35a70df55969f61ea90f31dda91221366164cd630b7f18c98fd9ed5cd83f6dc79093fd0e2dac3cccfd25149ae096b1e76226056cfa8dd5e112598c7c86ff88657d96807ec0771fa4e46a1ec646cef0c55a3c234bf2af0f5204dc85fa9b1ee8c3627e26ab2807a6ad284df2c9a398ac1bd7e84d8da9151f529223a8934fb8384ea08f913ecaf5bae4edbf64941d96c6a3efa0e271cdfbb77af34e881e9074d52a32fc5950eceb4e1b7a9be09b3d0ad37816d2be65b34359cade43d576bf1a84f6f151d8b3b676018614cf5301a689b1816679a9a121930c1f1f334b53e223bc4ff91d456c95727568c71bd7518310452370dad6925bb60b3e39e8cacfbde519a0126dea1c1068bf78a808b439b543efab4f1abdbc4dc459a0188563f452e34d89e6c7d576e245ef9d4a984f146cef22fe8772d14a5b56d87ebb11516580457a9017ef5ac38b9673a526532f82467c9bbd96c158d6577d52088d3018cc713176a6a8a3db15f1d7d337a1cd832e55ed60a4df5a93828b61a6c79307c350683c287db90151df8e4b7a0cf1a13c523cc85844ca7d83b62a9b62c8c14f4c68353e3a83ee8c9559e6b536aa448e603de68d092525c28ff27ebabe2da2e14019cebf2436d45a137b4a05631bb27afdc5dee38c0dbe1d0abbfc2be8d7898721b6dbb20f731bd610f465d9507be02212ebafa2a88a3e4d345fddf962c85400efe8004ec4e55afc595e8346064d3095f272d22a72fb4ae3144e9312a4a42e6b32ed3de0ca243bfb9b57a793428491ad69371a5347c4f9e2589ae1e22db018d3da9b893ef2798d572370b081327bffb721897d8408fb9c2bb983bd3b3ff0aa4b3efadf65990103f76d286a89cd2642efcd133c2a03595d1173a7e53901a668a1e220272126ab2898de2cf7365e4f2cfa0876319a56c16250e41ed474bc7ef698208bac97be70e6dcc0302ade3c37b32d0a4eb493d72f54bdd6f558c3c74289371eaed3e56c16d716440b69011f8d1d8e5ff32e4ad8c22fdaa52df59c08822e47e93b0afbadd78c9c74dbb5134b153555f097a3dc857aadf1c4dc6f73cd2a703d52fb591648d1a374dca8d569f56e99d5825f2fbc4684160660ccaf44042fdc6cc7261529548c3c4d11711cb23d1dd2a9f87fd4c64f030eea7dd4f46ea33c657c39ab374172df5c63a2ebb665081e2aa7c2d6d60c1057ac7083bc7566f370c9a5a6f3dfe1425d822f034d59fe29daa08a8b3c0d7435930141b6044bfe56222d13c5537f8e4822030e66f8c241bed33627343884a21dae82e30cea55284fa3febaf1885ca2e95f78821d175df908bbe5c715cf84a03ed897eaf739376d42b43a2beda9c0a68520361dfb99f0153416c1de017d2815908c67c7f7804178b9e40bde08bbc28c70349eb56bdf93b667929357e995005235f6cb7781823424fd107f6f6db557b9332f336795c472744de709ab4455f5d49c4c96e5589670a74c4ca112224b904794f2148b8cc9dad5c4796be0f529f56b941691fdd6c07b4fab21494387383878d465e3c8ff1e30a4f7e9c75a5734543ee2fff7ecbc689cf6ba5cfae4a3b43dbb27c9692e305f796c4745ad944b989c49e1433aa1d3ba267567c3f6e47b580bdb4e0222a03ff319cec2b1c6c4b365a3c57d8ae6029ced026fe9e246f9aef276886981489f1f4abb180a8a114a08718d8065195c050bf8c25e0e41d244cbb5dd7a02b16224ccdd88d123825d6314d119e2ed5c96b006e6e1fb1c620b225a47bc4545deb98c2d176f7377261e2b7509b1ef1bda16c00ce911ac6cd080b5b8c5e090f2a6afae799f0a03f1e3375e6c976b5b8171851a04b3ed5ca73ec9262cbace72ab1ab4d15dc7fa70ab6431816fb25da0e1a54bfd0cce2c87057d75ea4f8ab193560b6654c78a6cc59102d16ff3b00013d6500876b52de38e0a7d865d504ed572803073772ebba3ce80e837e59a4c1f656dfeb8703643b379d884ddbb8f616c6ab2b4206e673d26d4649944fa35e48f45530fe6c2c78c070b531061daa8b60bab7cc6695459892611d4837a2846be3a7f84fea94cdc1fbe7ac8c2ab10f380ad5f62f8865432e8b19a36338256f4bde9c779bc44e9fec4728fac658ecb76494cdee3485bade48d673bb3415bdd7867f5a0c6048a1f9e93e5a4cebc715249f85f39f8af0456d2908dbcc8a3ae969321241378ebca3ac7650caba68e4036a95260e401477d4905b4d5100dd97b9be247ff633598c545ea341f8a6deac8855b2ff987a5405e17a5f1aa13c7207586ab8659ed0937fa5dd20aa643ef71234ae29eca54b15a2dc5e687195cd19c849aab15c6fd6e18299b711ea7195b397c6985ccb735a6fc771813dcede298add4294263887d75d36192ec44b95a82f215f4245f3d714e78c05589dbc64788f03799a2d1dc99bcb0e773eb732cd763913f3a1b2eae40d07e338ce9cde3c0939d441c0ecd583dd0812f00e9d19131823892e8612044bc5f24a0e1557d0d52e33f835863e6adceef24583d88df59cb9963beb93a1c7e0c6ddf2ddeb19587443addc37a7b046994ba5ec6e53f98f106de85a057f0c7c26e376581ca30042a294ca2989e479bb79edb0d33cf1c3dbfab40049407c3a4c592f74267839df9034eb8534548a3a57bda27d442325c158efaa223f1125f69146e6f3694c7a34314abffcb09251b3d0165815a000a6d4147d3ceece346fc99521724ec17c52f8cdfe9e0c4c7f1dd811689f4771819f7013f67fcc830849f8f2b0df05ffe330981c46e7a6c6246ac2bee7ed8d362654d1477919b43f412c1c8c16a4c810a8a5c422d324996693154c7394a5e6a028a54bbc0da093f6bd42f44eec742a760dd2c62545d613b247715b044ea368a11abff832ab8dd6d58eb6838648fa59f6cc6ed6e0bb75c575a31da6bcd09fd21e2b619434a120a68fba3acd0e72c371d953d095d0690c268cdd6ed1c4bc8ed1ffc04329fa8ffc5dec8b4c9f17001474724f771987a55f98953d79708037c31c5cd226a73749035b0aaf35376ba344b677ab44b40b72f0f9160c518c4611c7c3d4ab45f573345f2fe41259001cd9e7a32f988f0695b7a860c78eafadafa0c191fe7a37949f7e1537593b20f8b6bc484e4d5e8f7bddc9cf4bb0126b53e714acb27116133457ba6885d93496f7f4ca4a3bc6b9c7e029c3707e513d0e9dfe59571c19db0c987b75ab8ade4eb2a1928e084368bfbe47dc87e09f3c14d51c537a5879ae7c70c42d7d5b224b264f2e16155c1d0a570dada267067827e076815249bd4432734625325e27ce268c97cc13c84353270f559dddb4c57969acc51a0eeabfcd6c8575062329c6e368cfa02021a14a50b1b34daf9e74fd2ef202ad0a30b070aafc334d4601c7a4016647419567b0440844690e9ede929d439613b607237ab333d86519db877c8ec07c4b46be3f10d3d518b1f2b6413d35d462dc1e78660990f0c121852f8fb0a5064dc8a4dcc420c2ba8141d8d9867a29f4556006a6f23239a1967deadb110a68e22b3c292af514c9cbc4a9fe957c27dd89a5465d97ec4fca3d408fa237ed079ef8589903470160c620020af8092eb29eb58893140e91bcf43bc183ee70a698afc4f6604f228dfcf7c151d31cc34b30bcb72246cca96c14b6dd6d74a9a2e10b30576cb3bdc70cfb13671cd2d329e885ad2e108589c1eef215dccd8decdc3e4a76c116f8a9af4533acfd6611aef5ce323ed4a97c313481f3feb01368a82455201eeb1456c61cc0e1646e1096bf75f71cbbb973a3168ed5afadce0887a271c6dfca7ca44e5c031d3efcb34c8f3f05375166e0057e3d44814691aeb6f20fa4480705672d40019bc99f3c365d8755e83c48a91d7737001daba49b61d032867d45bcf7194a40040428170dc0b7810c7706d803f4262a3b917613fad6fda8845bd8fbdeadcac5a0445fedab847ca4be5ce7a837e0ee2460a14da9c3dd15e91d4a477482429671fc79eb63f9aa7634ec4588efa346eb9952b3e69fccae729121f27c783c37ae00d6711b21de5933a2969949abdea5d98896dbba4b5e6994641bde3b6e574bdaf65212a510e18a9a6161ad0b6062c8f6fb4f877099a3667549d796d8b83e886487420d8fbe2b50cad72d0396cfeedf35af06ee1313f4546f04373d4119ad438a7f62243055771ce250d2820891afec6c5a1af381c998a92eebf46606b1ebf1f88a1549aa83839fefc500153c1247938d90b316282acd37f4677bf6a71f837aeea6d5dfc8a9b47d88b9844ca6317cd78949c03a99ed7accee4c48edaaa686f4fce202f32d2d93c06076e25161c0374ebd292d373bca37e556ddcdece9677c147c7f688a4e61b3ef114bb130c843c9a512687ed3140161711e6622d81c93194137efa82a55f8abf6d2c1a816a23df16a68e5b8fff3b6983c347fb2f308e1b8b8b1c3c228a7170e05749b51188c44cb5f1c7cf71879a2d7fca2de9a7d43de964bfc0cfe771fad1a3d92f6694ac40b7cc5dfe422cb99376259d59d138bd8836bac38a1cebc7bbabb5515347da8412455b14cf3235c53e92fb5d59f15c3be3c5833204cf4eb8c41e2dc3897f766e89261ab40d6dd799223f5e75654bff69d18926360576a62435c7fb0fecd0f8988ed9a20518bdac12dd8023ed2be4753967161655a1248dea66a171698ca7ab16c59e1f11f22135b7b4ce6892ff1c043a3150d5cab476651f987c6f065b316d7a8c9026b8996043bce2ded5ece01b257c46e79d70413ef77498e2addc5a9bfa258c32eed4fd289166d9072c42d85e77125830bd118f56e292d7ff5bedabb6328a9da1c542daae2b7d47529b7565216bcc1ba4e6aee6b018715c3dec87fae3c4c1c31a3375d1988e584c33ee28c66c289f9418b5083b6ee711649f3a0d1e069b604a2e59d8d9d876315256eee093af0e525cac7abf330e532a39bc0fae983750c3030a33489b1f725ec5db453c4f553651f1949bfa8d2cdd18a6f82153f1833cdcc0df9259e3fb1174c1b7fa528c5a0d24aba49c991aae138dbd5faff2f0b977fa827cf3050de916bab4b6724d6ccb9ad89e78fd6469ac0ec17ef53eb0f480d45bc5bdeeeb3b3e47fa453a92c72aaeb79c5db1e00b2f6e7c3831d49fd5dff9ec731c17f7c84c29d502d4f142db8c1f1ac77ddc72354e1c52baa2c1c2fe9732cacccfe6ee1f289a9bba13b73d7162016477baa8acad68cd015bf98b4901857f4a665f342612586b80d639e443f62b5a197ff37818515c67ecbe98382c0e7b49e39f78a7a1fc0ff896defed4e9d66b4acc5511508fe2e01a1f25cbf43b165f74b409d8f7817696091007a925465b1903477d6d61a2882cfed8e37919785bc477f145497b1d118f7f551e975ffd73dd031090e6c45c69a7b8e2af6bfc5f0b47864437c3cb08700c92f6690f01fdc6d8068123971a5a67e2380af8a2e81386231239892db54bb7adf870cfae1fe11ce268a44324aefa28f2469ef904051d4c9f650744189a81305f28f4979faff29ab141e70cf70ae751a089df3c78ac0bf22c6d1d375239a33bb9a4e5a8d729b42d136eb91cb1cc9f52a16ba5e3c405be6c5bddcb85428d8c4ea3849067ed911d7d1a331e0fecceedafad7a2db628b800289fe09e4de982f6120e75d18c523e56fe15b0fb831a4bc40d330aac5ebcec6040a89d69dc27dd5a5eb16fff3567b0ee010f4f989298ced24ea2823b43733c88b8ae122997cdb4ff18b85779e8314c68a25f9b0a4fc4322adc36c94053da8852f264f90ca0010bf3e228d7b6fbdfa5cf301f243a0e6f53c31d18baed44e36324323957f94d93da33d24c48c438e47103cc124157b2d6aa1d182e063250d6ae531df8bbf2cf843ccaae98b598e34c286b0615c7a449065ed26c94661aba2e1490c460ec64e59e4dfe8fb62905b4e7513b24960b91de1b013a36d9578d02c5801a2a23c5d189f008f56d7a84b586f886b1df2222a7c6d0f514d0e3a1b8a2f0246267047044c612c66db3a1a94bb8eabddbde6249469ea4bb6c0f95d79eb01ade9dbbb065c427ef7098dc132a4e3e06fea366c927040c3a866cb87aa2bd801a15241c2e07356f0cd0bee87a0ddc156654382eb057215e521090e2f570e5eadb18e2387ae56c4ca57a2037ec73e835496c9eb6d68098f8b2e32c368ab5560f1ea0f395e883954f7ad47e69a1d48dabbd6a42a482476e2271277f9eff1995652e2ae62ad4f9a7324265e25ba1f88d5db2f28f4850c173704fb253c816059f026101f2c15de4ba947ec4c2abedb29ceaa942d9536561c950dad2008eb44199c32d75af2a7b41fb25faae0a283ebc1cf94a8107fc9e6feca341759aec83896b56fc41bef8b391ee49c6e339fec6784ad9fc80db78638cb874ccbd4002bf828d78fc71b5db00cb2287be0c0fbd548f75b3596341cbc211518a761ff072bdd8ae585cc029daea93aac95103f9c05ccb7d28d8ec82c8ac9234d4c739adbfcfef387e16e15b5e615c1e0d08d04a13a9a18bc2b6c9fd08915bfd1cc37f6628636f07791139143b8d11364eb408950222c7224dad4dfbdaf2f61984cbec86c3a57b88885b22cfb19ac17a236caa190675cd74f20837b5549f008303ac1b522447ea92d24fb26fe51b32d12823a01620d876cdd75bccd1633470e1395a3355449d1578a5697751fc4b6cbdbfe4ad4ff4887d12ea37bb1a74ce018b6bd734cd02b577462338f02c12dee835cee83ba51e92fa6d35e49d5fbb0d4865f03889914299c38c16012571ad828aec48cd9692fefe68c416a70b097905e6c14899fc834966fa9ac6fdf5f368fdb13642506376803a30bcbfa1ded16cc2bfcfa5fe22e8e4133383e43faf32c2962b42d483e629d731f6baaae8d4c98265ef6991b1faaaa4580177b41090848abd939cbfbfe8060800eeef56c697b8c21ff3eff59c43314313ace257e0f79ad1180d85bf9231db0f20573c4a7c1e2eebb97fa5cb34f68b137ed048bd422bbf32b55a7f5dd220471ca2df08c9cf0b768a39a6b3ec1c82130effe499f128d31b8e904e09ea5659050ade72447f24d83e08bd8913f11417cae86aae09aa40bf27f99101bbc6074a39146868a5375593a355fa33a8b4c7b5d7ce1d4c7491d59cc679545f0f85aebd098fc7ae6a57aee771a4181bbf1db54182236e581faf394a11ceea69b822061400433468836c949d5fe4c985bb44a3b404900f79d18f717a5e1f811cc859907cdcdd32e93894981e3b3b50853779cdc8f4aebb80db4a502d566d68bf58fa8c9e0d8def66a512848bb19e3465be241ed88a3d31d460ca9e9409f0eb7f8bd969eae3231b45acb06d000166a229250260d394f9d4b59fd216eafb6a617bb9b75c052316c0aa92f757da2546fd380f47ee2d9fa3f8b201c8eedc43e3f9ea36f13d6cd6bc734ddbff27aabc877660d2114063b201ede746d05be0b66c3ac456b5342f176b3dede9b0b444e1fd7fe3fd70fa940e206b757ebab3220b0e73955668dc8332d8e9cbe49883318f3eaf0844c794ae6583a57736620c2c571f700a4f4c407e2aa611ec07ef3ad63dabdb42e368784b4f5d3e83b691a0b8371ddb7b5b43959419736686d1499a2c9ab17a01abd9623428141930d7b6705d908f7493c16dc895ace96ca308de696f38e8f079cef5942d535699a4e5d188ff1603856962bc444f8f6d22cfbf77f37d007e825beded4fd1531e04c1400c096edbba332150b890d88279ccae5cb25b046c427bc9808517a81d8be4c315df883c081aebc3adcb26ba384eef853483bd64f584cac34ca586a9bc7666ae8c3b12724a038384d0534b60b828195da50ec7c4dc27ee050c500e091f48640c170f00037d7fa2dd91ec1c976ecfb767767178fbc5ac47d0d5d2d0d9e812475080fd35d80cb9b44b4d12f4dba281584b646f18570dcdd6b8395aa720267e3796057b02d8d54c08e3429cb756f4eb398c965f21c97e4137b04a3c9960c506e73d318373dc5337e04e96e17ec6ff8409e829404a924ec2546f6427c1262fa713c56fac2777c242fe6320fa51baf4170ffbec3a5f114b3f4331d64b891ddc7db603c53130a66c31b1e1babcaeaad418e9dea3d5952e36829993c0da8c15fbc8d60d0e02939b299d07b9c0033a50701fbb0e60cd30d4a2a1a0b280655c15856a7dd2fa1230abfa7d703a35fbe6f2563d2ecc157650e5cfd06f813adb5ea9164059634423da884f17fadd74405ea0c558facc4f671270ed5ac6c3401a30751d49d6a248566bffd321ab96e21a06c27018e6fc5687d89b3c456f406910633127437fc9363d4c348020daff0ff1c2bf750ccc78b90574cbb3105becba36b2e0722efe5e23b5b2a16720753abfabf46719050fee2c2529a89b3f4b5cdbae8c7b94eeeacb99745dec238419cdf42fee3d380d193d1782aed5962ef98ac83d5222de5083c922558daf36e267b9e716457cc0d9f0907b19105656b8dcc9bae602790008c81ff79e34b885489b6a459a1ecba36e13613c3933cd18ff4a61bd04296a8ac86a1db179176dcf2eccdcee7a95a6284d80a14af3fe326cae5024167028ca8433e01b36dbec705de908b37fa0ba6d5fdffe74e8d4b61aa8afbc05c803b066a18f55d557d584babb196e45717ce10af6797586362b8fe99af464871bd5e0d3189c89689b1265d15bc6425cdc270d6da755056212f2f8c4f84488eaae7265b3b4a02621aca1e37b5fecaeed2d36bafb7fd4579f987470ff41271d15064b307f6b27549158fb3de0eda40c24c1e6ea961414b7df6c65c5cdaa777464a997fb7559ba82397210a0c004f84972089691ab46dec06ff1c0d57644c54bda79c2f4477cba627dbfb03041cde3ac0f0f7ad60d1e4f7a3df064a7a73469590a5620034e8b5abbcd2637f1204eeda1dfa54325a451e70496bf13204f94ed93496941b642bd3ddecbf0aa1633d5847ebbdde0aa37a1d3d55fd8961119cf390cf57f243f3c9008f72aecbafc9838ab7f6455d2dbf1242bad4d85fb28d263eaeb70819c17e45d8d9d9f1a87c9b32f1aa6d38b66e02829af5e3d144572db4af2d49e752cbf5667d0d96471eb9caf11d12df77df0a5ae83b13043a92a62f58b85fddd044df51512d8908fe1cc64eafc4e1c08c1bb7a9c1590e34b50e9d66373ef6ad341d0be5937d9e099f8cb646f2868a583c5b21a70810b03fc664dda78068e623bc05c74f2201dc5471fe475102ee580db679e0523c3a5ed4f3a1f4c0283d6eccabc086d5d1ae1fde55e6d2e7735a8fc19572ccd587289821916ecddacac430d1e3f849b7c5767c0d04f16512951b7775313540afa396d48d50089b70ae450475ea76924504272a32622e195abd484aa9f4c93e310d507c714d78d380a0877107ab44ede9a64119a6ae8e7db9f7d2f39eefe91579b034a74eed5470ba5618acb5ac9de47241b82e4e967bc8d2dd9b6f69d3b03c7ecca2c0082ad2c11c8717c3b56c2de2709885c95efa106db0555ce8984cc6f58a3826457bac98e9cac852030b02fe41f545a9b7de8055fbec18204ae3f70c441bee0444569c3d8fd810e52e16592661923ec988e24328ba86d2a6fca1be0439db70d957821a44a28a3213637b148884370f1d0a60b9592b2aaee0c63b0db90ca598cbf7591f8a6767d7741aab4577c34c9d0d5bd123409faefcf5359e95bfe5e9059e9d264405b4b6dabc91eb4eb5d890fd7b6a14c12b621a0910f3967443e95160b8a8474fd771a9798a00cedac1ab80515e5a0e6bab234e48bfe92d764ae233aa978a776efdd6ae1cec740c8e1b8db39179cb9bae255626fad8127a10c824881865e6f6eefeaab2649a63af132075e3952ccf8f5aa1064d54ac4db89fe7af57f262415fab7e63259481ac95274f77d66dc776d6edeb51d80354a0cfaf6391342fd00115cfc9c49301c3c8702e09ae4fbfa3ea3cab1ce629c0d39d76aad41f7cabbfe753e990279ff98866b297dd046d49e0fce6470e3e874d717386be0ef820212313bb1d5e609901bf690177c3f663e6aaf017ad47e25df9276042212902b4c73e8b1f27bed3845dfc10f375f566298c0029cd0dda41d22f0706a060872ff4ca4917e7f0fdde3cc642f9b537018af9cfe2471aa212ebba22a21bc3127314dee3379538e4885b85a94fb7b177747510c0b3f82f915c1a27c912263c7b3215fe6c3c12af47d8856617bea23e594d2f8683e64dad2f2cbdfefb72f8cd18ef0ec000bfaad5075117dd2425fe018c2866354fb234fae469554451da401812e5fc80af6d15c3b259dfcc2cd88acf2dd595180c30e6989037fd0ee25ef049d54335507d2f3437ac14b5cba18d7aa5bcb832dc640933fa48f5c18fe8c9f26084eba38df33f83fa2c215ac84dd3fb6ccff03d9fe6abc414ef4d4dcd09d2bfae6bf9857611e1ea9e085f63004dda89a7c072ede01edbe2b8a8837d48a1f52b25513506d66ea63847dcaaffba6fefb36c3c004e91af9064bdd1b8d1515ced586f934467d9cd5647adee29dc67c4c2960cdc0abffae2217f85619aeae1b0cae6c908ac63a67a2bf48853bf73f8ca8069c7baf6c237dfd075644e3b5caa044b6a09463b4c43aa70439163f0c5c9e720d9e3a7bb6b2eaa2cfc42c201e59ee5984b6cc7933ce1ade0d44edea6e155f34a1c885615e657545de7aec3dfb6edb530d48f6eded9f7dc4e7312e064dcbafacb90838ec1a39ce2b951d48b5af28a4fecf42bd9ecd5ce4233a59818eb9c17c525f4e7389515a3f94a1d095b8dea5245e814a17a0041db58af1c8e8b6fafa60aa6c3a5174b95bbd437822ab0c5a1e437cb2d361c204adf0c63732a2ea20cecf8fd2f2680da6b37e9d52baa48de683c014109304df368673ba7e2f797bf9fa1fd68efa3998e3a7a358a91a3a27ca641c63bc4254d1389fbbb5649afda8f8161d365d9ce793ec8555ad68bffd8dd6ad4f1966cb90075b572260ac97c5e88b145becc8e038d7bca3ecaa33186e2a2eef8f5db6baa23173ce9863c1629d5a98772d5ad4d2c7db0da39aa1b5959b5594bc0e64e5eae257ae1fda844581a922f5ab2c24cbd7c8110f2343a363b12f0789be575bf477ddf3f7add4b5458665e8a6d16a73915ad5dee3fcde075ffe70d0c3429f9b1201a04b60b8144a0494121b0cee5097dfd9a42143f5a00dedff6a00b0cfdffed27b7cb9127bdf5347edb0bda9d25058c851c79190a5379d914dfb4b1402546ce263dd870a4a0f0b3c1260c7921821730fa836ba2e474e1848e365be2d9b5c8c61a1ce06a0e035c16a25d5054c1484f3e1abc4b52de8035c8f237b795bebb397a264f0982d934f6603604b3685c054ef55deb9b9943f9cb6a69d978ae7001b3935f30bc117e3b63dce7f5be3751ffb236574d31da48fb9f9289fe31c0b1c9f9114a7eac6dc5c980de367f49264d7ba56d7af6876a5383d5f51e2b8bf405b08028b354fcdbd59caeb292c5255b64c620b06f11d87deaaaaa70be42d6df7126b47cdaaa826b8508666e6d9c988acecf20557b7ad0f33aea9455f6c131556d0faa781a88cc0b1b51d63a2886d01380ad43e709244989c8f5a69b5fa842d50d77b9e91d3847655890837bafbbf213fb7edec4e3fa6e87814dc42eb7b419dad04f1919bebc0783449786091201160df3fe1fc76f23a26e5dd882ab0f5c8a57b4c60c049db4a6befbbf5fa949788f6d4cdc0ffa1977a613b66f87e1e720a49835e32a5a0a7e3d0efe332ffaef169866ca86c025a12df1ec085e5599b6ed9c77e0323c5a56ed5de3a5e51d7384fcf2428ca1d1bcc5649b54c3e5d6d2d3a4f292eac7eb63c69377f78d694daf32dfc95f828090daf3aa389718cfb7ce7a1cc2d94df3db3a7d29fbb87218a9460a28b988399700c91460614d9af5a6f9e6cbdac8a310aac9e284609d4441cb2b6924b937eeeea4ce645548fe30357ed04c5aa4dceab3bddadd857a0180f9271c9db3cc71e2238654e4b4173d4bd823de20c53885788e4a6e5252a16f8fcb3ca602975f1bd7c7e521c30dbf12bd536fdf99a3090fbba066844349e2363898cc29ff9319dc4f3a528d8ab30d06fbc22eb114360a1ce2fc69bc6c646c1483187344ecd809e0330c9b8aece6831d02a2b1192bc95b95913ec36f509bb9ef2b0aa989ef77f461d80df01213b0a39eabccbba2ff90e723cbf8743736d0c25cf17ce13ed3636c7d9adf2248cebbb3eaab0477ac2fcd798d58e7461e344b954883b1bcb6d9e4af2b268975a6a9889150308151cb772cd318653a5da0b968d3d6ce542a9d301dffb0ae96ef9f76e0b98630c7627b5ff150af2d7dc435aa5c3d900c82f5e5bcc246a382fdd77285fd9d1fe2a2f8bb6f2806b46101c86504744d9bbbf298679d8499b7198b40e0f1ac1dfe4871bae53bf9425622e2a7120e28ac15f6da6f73ab75673c8111884f78c3cefdeac940e81c5280547e65adaa3e7f078d202c1b0b6a90d531eeca20313143a36192385d7073c3abd98c0e0cd99d463dbc9340f1bf0f5c05d23abda0ec76227ee819a5d29576cda49fd2d9e69a2c32bb781c80e1bfe67c16d007c5fbab5463c936468e0fcbd9d74997515d469a53adfa0b226313523aa37b100893242bc1b4296b9e8f482ae41a274aa53f7cbb6aaba90bfe938d84ee969467244693c5092acd2c3811ecb46b204ea2fb00528b010aa295662debdb496a015fd58c5ec12dc9aa08f63e68c31d7f140f85e7822dcc5418e54fe2b90a6e9b2aee48a29e55ecd694dee953f0b371d7f210587f4ace2b9140c80b90b50616b81635f17a7402550d8aea76bf0602ee842bf422092be262f68afa6b5ad020ecdd0f44426f97409ad4958c4571a5a0a3a24fd6f65dc9cea8194a2ec3ae5b06ea76394563eaabc9eecb53c98c9b562e0bb0e89030e1d3d273cd1c6ffa6ef91a6358823d626e838d38cbfe17a9f80e2973a9266b4847002c6bc79f5eb6a1ef31b04fb9e83576de6fff56c31bf4bbdfea9ebdd3ccba6b00fa98aeb7a657bc18ea1052037d171e93b54147acf0a4c8ddbe24c97ea0d5841a3eb372fd79ab4b10c287e1e696e39e0e53e31e1f84b7774f169bd4457cbdf6f6e0dd2e41d184d8c49fdbbb933fd1371a1c4589274c563a4f40e73a683899b441e496660c87c386c6dd29d28213047932a8420a29d303ccc84f886cd7e045e69693e3a8015fc603343ac2dd8b694a69d12121cb025b0e1fec889273bb218f019bb8b88086ede232d996a9b8a6d2b6449d209820e2bb2c6d97a4d5f498c1f4b7aff61736502ca2a291948d2c7f6fb490da1f4d78a42d447693fab671fa75dae55662accb02429b5d8cdd9dc85ad210fbed0547874a07cb6bb83e59965f8f0cab17776a93c5e73d6042c79013202767c058ed802bc1a96ff5db1aa717d0ded2337f201067e782d763dde674214b82e8418c2a6af27dd0835e527819e323637b13bc1394c45039b09c925bf77bf214e30b1ddedd1c12670816f5bf8ed1cd350d6536d37d1a30850ede0d34de7b5f7ec662e47a971ddec587901cea1976fd9bd130bc040cb7f85f6bd576a1bc4b91c2e7d892a612e5ac74d7ea80caf7c5aaeecb24a6f9a41c31b592a185c406896510dd3211a543dd7f8497aa8bf4d2d85af7ac5ddfba0d8e3f363097212eb66a7ad99974ff667dbe4aebde47c84ff33c75c1201952a6e0041a412c961d24dbca94ce17e8ffa306c1f925176892bc54cc6f40abe1bb1ea32afa7ffd2b66584a6b9b76649141dbc455b735140d4f63fbe38d9997d342964cb6e1f0b24dabac33b2cb88490c67704403b6ed126b15aab78bff29e75299d3cdd9e9a3800f6874102283225f853b09db76e4de0fe657ad696d240793cd2647f4e06703f8a1a6944b21ccf2379c52d7c213e17e6f30d70db2c9f5a60acc7d985631ea301bf8960e679a0ad253b2dc15d5d7c48b261d2893dda10795524976332060e9824cda3a0f1dcc53c68ab74648c5447535a1aec7b093a59d2a4c3a8ab5ddae8ef5d5c355272577748236f8e2969a4ebdf689790018fcde1fe1df9ed43f32363dcafec45d93f2c3260892e67df6d9d24e4b892701f494ecbf16116e87cbcbf10836368454f260407fefc270dfad43b16a33ef3119a17ee0c97d39a61ca7c7d6a88d3b393aca31ab5d618b155b3888d1131be70f607280f12b48e775cdc84da11388166b92c51106e8bd1360efbde06d77b972a4c273feeb3fd7b3af3fc6ead81cb086d01d1aa7a8e7114268c01d52f156c9c0ebd77618b72bba358e99ae08d54040432346f7977fc54ebc99a0318e315361a9f695800596eb0f8ba754e763f3c0698698557e2206a271944c0404131a2a2f87d45ee7cafe3aed41c310818f8b6c6c3a80709ab3b2f4d3688dae8d9f6c47f3098c88ce54455dc39e2958c373d9e734aa0f71d6ee66e7d1db5ee8fe85b429ecad154bdb1f97a78d1f4ffe708ed9097f242cba1698e2334a22b2fce6b9b7aa14708290f8616952ad6b865e4bfb0454bdbbe68a1be5680988da26847868216ea531ffbe7c9a26dd555064172e73e46788dcb808c24220f5363e52dc19f60d740364b80db338558808b6089dbe37bf01d16e175f639eacdccd46bd80f617215b257d45aa31a3a180715b773e414040c340108d38eaa70ef754fc19d42fe323cbe0c11fb4040ec8bd98a44538877aa9fecc8622851882bc4ef3d26e35a6931e18239b16e72033beccbd1d00f2ae10fca4e3d6fc3ed674e2804fbdeaa383d8a4819c33fac05437817ea66d41199385056236cc8ad5620f680e86f357ad40024bf95d8eb0c9d9de6d06025f6406d747f183ab281c5cc261ec2a0a1b2b757f083f805d825f6408d38c51242bdb17d835151fca4b099d3a4ddc4f7bb40b8a02a2cd42e0e3e41b0fa0ac3145d10b331e536fcebe1decbc1412afea6bbc00a464a2e75ccc5a650b9cc995e06e7dc4787483f911be8c848ff25eee87e0cea42221698fcb1ecb840ff68879514a6460c046d5edd8fd05d0b23c25a8cfc5a9c08072aa12d727c132bef0e7588922eb90e6f0a06424a13aec5513c4a479a4dcddc4808cdb93ad3e8f9772d55c7a692785028da8bd214eddcc572a50275a93afec8010d8a4b64ef178e2aa3f9f58888c12b56fd5b45b29b07f34a5db05b2ec0128be8643808f22f147f8018c069f71becb380f5a61736200dbc66791230a72f501682ace3e8e37e9fd27fac0774081baa4d0604ba584f072e697b43568000\";\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(\"Jiayoutigo\", 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 [\"Tiger cub\", \"Tiger cub\", \"Tiger cub\", \"Tiger cub\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Red silk jacket\", \"Red silk jacket\", \"Red silk jacket\", \"Red silk jacket\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Gold rim light\", \"Gold rim light\", \"Gold rim light\", \"Gold rim light\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Lantern festival\", \"Lantern festival\", \"Lantern festival\", \"Lantern festival\"];\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\":\"Jiayoutigo #', id.toString(),\n            '\",\"description\":\"Jiayoutigo is 9988 Jiayou tiger cub cheering in a red silk jacket at a lantern festival. 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\":\"Jiayoutigo\",\"description\":\"Jiayoutigo is 9988 Jiayou tiger cub cheering in a red silk jacket at a lantern festival. 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":"58047548","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-02T06:57:27Z","match":"exact_match","chainId":"56","address":"0xc2De0C87765685f88b9Af69c288473411675a02c"}