{"sources":{"Neonpanda.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: Neonpanda.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Neonpanda - 8800 Cyber panda hacker with green visor and neon cables in a rainy neon city for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 302 free pool lasts (gas only).\n/// Every other mint costs 0.00005 BNB. Max 50 per wallet, 8800 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 Neonpanda is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 8800;\n    uint256 public constant FREE_SUPPLY = 302;\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(\"Neonpanda\", \"NEONPANDA\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"52494646224d00005745425056503820164d0000107d019d012a900190013edd5ca74ea8a4a329ac156d69301b896a6b6cbd90ed9f81715fbcc0bc1852ab72ba4fb5d14b26fbf73a3ebd755e39fbcbedcf3627f7f4fdfdefd4a3fb8fa6af4dfff4bd11f99c7fe5fdc5f7e7e577eafdeb61fdcfd573ce87d68ffbee39e4aa1b3f8cde9d983ff44f057e3a7aceef7febde68bffd7b25c7ebdd932de1b7416f6b6839c617fe9fa2cf57ff02a00e17f870f2bacacb5fb9ef9f3ab8139a1019677ae9b994729529db1b99eaebb691308cd3c3d5f9e358b3957e7ff8c0c8889c362086ddc7137bd2509c11871f190355b8df6138afb7a782f72541aa736a001dd933252a28c6089842ee900895363486888c8fd2566bb8edd7b1666eb40a37a028161c0f4f244b60ca4cf555cea54ee9edf278db10f0e9b1ccfeb556ab629bd76f2255c8edc68fbaa2bfbe0c14fc8ed992d3ed519a75612f4feb4f1305c3937c756ea58eed5d2673362e058a8271459f86b31f16ca69da2f14b560ed5468960e564af1c5aeaa96d29234dea610db52afd4fcc05b0ddc218e17b515d76ca7d2083c0e410a767fccb57708df8aa51b12e16f1a2295e05c8ad3ccd61a571e6b7ae6a3a3ad099a82d4a5fd58258161a84e8811c91dfc0f13db63295dc692221ff84702d784a037e6253fb8bff1cad946409e4c21107f2597be12161cf2fb899039065446cda68d7b7f23b3e969da31cf878ab94cc7382c3dd7cf5970462dd58bee462e1eb2297f1ef0470f9d88cb456bbfa020ee9abcd6e9518e732d59550d193c7147f81e4efaa3ba2b70d55c356f051fa5a14331f73ae9f6ffa07e05bc66300421f459669000ea3fb20dcf523e95c7f43e60cdf186984074383be4d2d31426bdbe60ca061e574b2b45d090577c01c2bfb49d8d00e6da02aa781d48a1b16da9c2453a9cedc66f3ec7ee1ed0c5f2416824ebcfab10285256c9233c0c9f50a2efc906d049df536911a0f28e4e9ef170a595653af50938d407eb006deac65c758e73e822015648c6d285242c8ce95c5f96174eb1344818d6ba52f08b9591d511a7935259f6ba41062a3559570faf2be09f9c6b9d32468bef948e700be59ab14bab1037080283cac16a23a5ae781f291ba4b8b0a44d5ad22766a70e06db3b3adfa15c51279d937037fdf2683df90fea4ed9ad0eef0bdee63a4abd4f13f5e695d22184215103e55e30869dda269e00eab903e2fbecde4385ffae0aac2a986a8c1c3274c271398fd09341f18e944394f39c2673da0159c7459d512b587ef8f83e3f2604e24358d39e4f94da502970505a447618f808d5c04ddddf9c1ab09c7cbb0b5d0d708a089ef961190ecdd37ef59d7e3ee90b8ac2c9e9eae7a1246e344f73911fe9e766f18186ce575206bd1fbda34e20c16b08303557dc5924978934ff2a524790b5b3ff4d56bb5f66fe8bd42e8ede127069bcd149788047922227e16e34cea587954077d0dace03c8dd10ceae41471d6303584593c7f6d775171a409343824694bbcf0e627bb2f5582798d1ad6be2e036dce9776ed1309fa3b138851af1f3f3af02b48d597029a5a2a1b1fdd55613c8ab53364e1f1ef0e9c14d7ecac847c05b4ee94925aa3a4c4f05894237e75ba54231f84c3aa3eff0e25e4827fec9fa1355ed4be393e2280a21bee021ff3a0727c25b2d51b905b1a52d18555af7d9eef6899f0b32f5b44e735fedfa9c41e5958c0902c7da91c20447bd6e2167c5656ffe834f9afe6e4d086195472726786df45d584f2bee43883955c9e6a4c3b4186e6c82caa5b065f7f6be4967ae9d5800d2a52f10ac9e0fda8b6fefb58d454a1c3d0d601eff38a3a0662ea90bf43cd9cf17cbf6cfd08e52163221eafb8d46f067606ca1077a2b4360c71088408806a19d0a7efa44dc234482da68e25a1fe880f9b467cfa8b0d7e9c4353114323d5121991cfbc651c7ae0507683e2d664cdde2c98250eb4998958c2234d9f7ad91d7127f51e4866d583fcb51897b4c059a9dd16554e1cb50a6a2eba274d4332ac0abdf1af308659455663c6aef1dd9ba688eecc91c18570307a6a66e0f266fbde3223785c38b52dcc897e967d4ce18026856696d6323ebbd89b8a1f5b7d6d2e6c5c092ba7a7f068d5644d0ed90b28b576d9f8b4b5580a17bc3a6dc2326389a26fef1e34b07d61ac733a8bf373971f2d1f566294a1ec2aacb53d0a2449a8cbfba4c21a298daeb14ac5b865cebe4e23ac3ee6f2b58576138535497ef6cdf4bf4c69a463f3b78840ba2742743156cdb511aa1b66b2bed61253c1f953f57786d058175d0399e73fb78e28ce57e6ba4910ba416392499e5c1c12832d1782300958836605cab1a61cd024aa88abf042587e596bce277a97fb7ae3c6f736a005afab31e1da3a2db0ebb2f0980cb9560d27908ae63f3d26aa259ae172e01cd74a7070507ca6c3531c662cb611d960f4ed23cf89c1ae7838110d305a152c868dcb99a8354eedee47b15537cf8d30a2e64c098ff764cad05d9826e33c59fac1e82e7ab8d1dcbf50631074607f0f46e386d54699019e48a93bd415aa4031cf2d2d3370113ea07a5a8c1074dff03677974385a835a5d71a350c00a1ff42c07929fdcb4ed22f2592bb49e3f3a2f326241d6b3f35ae8f1044c4b2397502bcc34883192e02c573581c4f0298d0508c12325118191795181db4137568be72bf595deb38b60a782135c9fa0ee14a4d60e62e3d2a0fb18bce196d7b28129340dc0c46343ddc71af2ea57759e26f4adf7db5a46511e1278020eec374ff3d2d107cf552c5913fcc569b926361665b9bb256e5ee5dbf40dbad6a8422c423cdbb824d2f0121181808e3fc3f4b8f5a47a232c987d9d3d57dfc40d833c4cd9598d3224a68dbf1a4edeb004cba77c8ff7217faad4bd8e9970c552ff0764df2d5214a60d8c82745bbbaf1ecc20fa7c1612c4b9d63cbd70e05edd520d08d01bf23f0bf73a851ecce3e64c8f3ff8c451036b1a6b9ebac4181ea41cd267e4dbc59c4aea18cca3e2d27550b8d3cc35d145ffb3df8e986f8bf9b76f7876f92d11b2273f2e3ee6cc27f887d76ea93f492f4317dd0deab2eab155cef7bb76581faf62a074397bd2356408ecb09b06eb59083862fff60873db6222f855e39a01fca565db30d1178ca37d37ef7d6f5ad7be1da306bf1970978d39760ce90ddae464d20beddb9305c5ea6af57eb71f8a6cd920a0b7d788c4cc98f97e7e08d621a2f0a1a149388c1163d0701c5027c05c919adc5e04808edcd6df061c464fd0e2591abf1922ea0e770bc6296b3a5e48cb41b689f785ee3c21d9b924ca77d1b9706b5c085b17ed3481eb4e96147a847c617d4a31fd412cce18e2f0ff84fdc8d4c4fb1e18533da137f468f6c6ca47bc336698ee3a2214115e86e4775f17a644f0eb14bf733bd48607ad27a5f6f4aa15e4ed65ebe81899f5bb1a8aee58e776a701097622b15e974059c3f98febc6bd79f8e990734b50d390a072c9fcd135ea7f54f429c9ce27b7d12b438b94a53991a343c03a7e7ef14c8ddd9a58ba324b490fc2657ae71558893c5e768fd69850bd80376f98fc9f013f96daefa77786395a6bba4e5da8d14ecc375d7cc9738eb97478a2f7590daab64e9de723ca7e96317526868cfce71c3b355683af63abcc94e0d1cdc668580ec67f2e36cab51d95eeedd0a135e855d979905947c732967d932aa8c2b2eafeef9a72c4eb97ef0367ffb97e3c42bd57a452c3c3f552f70d5c8575df2d78fb7387d86bedcb0f84b22d33c55e0acdb46184cbc1a3d07c2aa7f0e38c99bfc31ad004419c09c28f08173da1e7fd4fc5909ed661f7645f3e217fce56cbf68c0eefa767cd05cc1e20e7554415d449ca4c5951d03135c51166f86033004ed5eaa0b2b99f4181c56edead1a86aef31679b50db3ce4a6f8843dc9f9404269e86ba7074a6f8f93dbaf892f3ee60c9d7b2406436d7f6600d4c4abb31461a46fdf3f9fdd1a68720b2600455f89afe4a009a280a3fddad43e760a5a61cefba463c4058946c07fcf7c2a797826ea422633a021d0cb1efab37b3a678f718e601e1d10cb56aefd753156a8032b8e0fbbe9a7c0a24124e2c2f208f2687bc20d350bc015d105ba2348cfed3fa98b5d1496dafb453a5eccbe752bf5cfe2212eb2b1a8ab31e607f0a2b5af170f4f292b0a2b462fae334600129e273d9f8095c27bb9fea646fe3ea05d82f5a18b939616e3be0950134f601f9d2bcca4754b3007a90d7414c96930d1a74f896710dbad744c5c84491f85171cd9e78395986f8fdea246adc2d1fa5d025ee9ea7c1d68d4db52fbe6308726fdae2df7e0a59fa383c4483174829161d1e7e164000fee4f51f7210bbd23a03ef7315e8f7f238e917d6ba2ceaec540e1b906358b388ecf9c60f27c25831bbea8e286452360bd40e75cad423acc2a5e9f85a962d1829b6c021eacc626dd699e49322b71303e4e6c5545649328b9e1d4517bd8528b57d73c9eaf9ef2a938c924ca9ec9a79e00fe96fb24d0a0fb1f15dea01821063376954e3144c06308af8ebef9150c076409f837c9b7ac6244b26d6cdc48319d18aceb2ad8e4628410dc4e746cd2729e22ff3390164b92401d6b396f557498c5a065c86ecf05704d70786f2474365fe2cbc3da4eeb0bbcc2ccf7a7ca7e066cec923ab84d8c027d6c928bd3d6eb55575ed8164af5faa209341093ed40675b2fbfdf99eb9e0188651a513b5df623fb12c4ab257cc134d252a58ae9613b092409faa23f2c34344c873a3bae9161f2b74d0a266bab38df68e6744285685d35fa443eb94cc31262a27ae031279182a9f8f05f7a1e51fec393eb9dd177e8222ca90ba900b65a58df1a35f6e3f1b053a4647de38fd2c89f0f8eac976a65b01f118cc4c1898383308d11d29b901a7f22110ad85eed90bc61b95449c3cbd6f88c43ce3f42f767cdd72ba94528a39cf71c183675400008d1a02860fc4612519d619b6ca574bdebc7be1f3b945c0e53d081fdb2bdfa58eb110abc43203a5e77de0db312c228e6a10499049d56b865cf1bb0696dbb7b9a00f64282199545ee210fa6c1773400432bc7bca04e484f8378c9547ffeea223f8047ab6bdbd63158b833861a0256f35af3ee57e00d44e28a343a1a4b08851ffe96359258a219847a5c8b17400468d6116bcf1c087c311a5bd8aefb2d0d80222e6dee33a93a4a2fe675bf3221c1d9a98c5a921829525bcc1905c90e9dd8e47d4aa955de48aedc4ad0e520cf734902f8c3aa5f09f0ab3c4c3d9e5316c6902d2ae44a0f89867b605c25926b53a0f0fa69928a311a2a25f94ccb09869a4e2c0464c58dbd5ac78573fdb51603e7b1d59ff9a15ebb83015f2a01b229a36fb264d39c1c14614d7b98728ea32fce9342693ad5c7d283c073ea2082071c18bd38e087b54ac0e0810770ef8da789bab3e3040f960009b2f5d9e0f362116055349e15a7528470bd857d1aa842e14534d6593cb00ff23c711cf916ed2b17a5ec5bfa1b0cb2867e091dfe1406b8ff4fb24b60838610afab1b65a5c22cee536af54e7e2c8172f6a732a834301d57dac5088977a5885d28117d15985a3ee8b8e7cc258c0b8f9707caf7766caa842862076d8585b499e51240bf31a1405bb72b282de2491b73c0da9db11affa1be8a1b17239417ffe3e3486c460c5c73d33ce3a08df1a00c268b1e689162b0e6ab810102b2f4dcb126bb4dff2c3b982d7d87ab24a13a4995cc47c7d17ec9fb5d6870c6c2434cc00d33d454ef5c5a4947cede320ac3e8c748f81aa2c9b27f3df4dd6365abf7fddc1178422db969d5ea2bfe532168ea9a3616bd91cfb33f07f64b0fd2db759a10ddda1b4cc6ec36f4ad79b1b4fa4808eda481ce4972e175d38d93ea7b280d8f87f0de4429f1c9bb4219971483633b61b79f2343a9acd67c9fef0c37986b84dceeaee697aa76d081d6a548721e9b27db1fb216d5b0a7522effda50bf0685cc52f97847b6e3df57350e580d5c5c052a668f9c642fafb4c322cb990e722e2a9449efa9044f30df4c97e9ae09de1cad7f6c23548d32533d7a7005fbabbfb50d70595eecca6fc9af26dbe3fa0731100e811613b776cf83e2aae90d6a78c48ffc9a03417fd457112308154482ffd4324c68f7e20b9d78c873289ae448b99a60a38bd8f1a3a7343add3f7da9b891644a841666838ba77d3d232700fd24b0f0af3985a4a3accefbdde98cb180d294b890878b3d7f008f53969147252cfcb9c2d3281faf06c56a68624b1c75a800d7c6af9b0bab2f4c60bb84c9db608b491a78e21c980fe75b2e9d92b22aad2b63e8110b36cb759ae7308d338664ef8746820712e39b4d8e1fd59545f0c4ad3142d245cf2a0c805899f9e67e1060af8310de351d482d4f64ce06041742119ee532837d6f06312accfc610c3096bac3827d55e7845217ba2e3ee45037074b1bb910ea168a2b004ca73136658973df8ba9c0b729a54d429f38a4607d92aab80a5179007b108681c2eb68b231f038cd25c30d6be93a8d2eeb156c7339b26432decdae4db73f105868814fa3c9ebbb74a2b2ff6d0061ab8866a557defff5be2969ff5cff2255f8f0421c24cebade2e26d3f5227aa7812e8f058ff03e85477ddca01075dace4c5411a36f52a1dd19c50e8417bba91323a5479c9c857b42b60742b3362497bac3afe863429f6472f627a329e9d58d533de57a5d1048a53f67f77c7fe81f4813972b339dd0b480ec69d01be7f2c8989f9f090efb98d930e92d5c0aca798de48efe3517d8d05b396b6fc42c47ceb20252bbc3807c95a73f4bd8c2bf29a3efa4056fe7d74cb08395b3a6105ef4326d97d4535c47d81e3cef19d7ce31c71c82c4118d8082702eb1007bf3b4bd2833573d711266327dc6f7c09c1c7f48e5279b8a23108d9408676f26825ea92f81c3289c0c0ee0c884630da215d8dd77fcadadcbae3cc0a1d6836c875a38fae9eec292c83bf34fda2fa9e231e0ddd144dfa8f0b2904aef821728bad1b5f00514c74a10f28486c100921f05350bc84425a2707631a016944eec07b2b4b26f76e86017443906edd3a8b5128ceb7e614ed2439774a37525e3c9a3506ccecc0be4abbbd4169188799935495e7028fbf80af80589f0e90e4163ec5919c06a4806a32405dffee3960f9630b2311b3e2ac3ecf4b4f337cf0882959814cf5889207a42314dca94421c0b0a5d1589537a9523d6a70a70eeb6cef805226a9f90e08a80550eb5d0b52cd779d9d0ca32a92cad48a530e8ce1bf6ac9334ca9ce745a8c1f1df6be8321f18a91e8cb3839b313af472738290126ca3bc5a8957910d09ea221b09b989b2137cf8dbaf07f9b5a37d1a29ae6cae1e931652a3b8e5122fdd190f1c4a10a43ae8c38e3a182555617d5befed24a25c21ccbc033404430e91bbefcb02141d3819d313716b8945349afdfc158ccd302a5e7ebf48c1153f30063d7c27ab2d63e4dcbbe3731c1f3e0c8e71f2367b212c84af4480aa29deda567947a9665230234a7bf03e9871b87c7dfd45ba056f273fbec3e7cad8dc36fa158ac6e83bd40fcfcf2a8d836c30d6897efb6090198927449ad8e65b47b6f13328aa8c2cabdb78886c7bc68d75efce73e43bc7477a263143ae477b2ca15a345e62e7548d5f107720e64c35733fabbaab12a7ca7f667020a9890a7a7f0ef1b7040c571bab54082eb987636444493e1f01c064af97698b1ba085378bb027984012e3eabc902882fa80cc1e03e7c1d1d661df49213477aeec0ce766eff3bdbd4ecb78dfaea95b600d09c09d5378448690bae864fccbf500a8f29f6e7ff5243acae92c6b33443093d590898299b5af914df08f7e08cecdd47584da9fc22e23bf730e75a5260122675b98ced932ede4ef00d3121a7fa9a8b7a4253a66dfc165a744b7cf82e3f7ebd9b986cc2841e0df1d3db14808e3ab4822737f91a1363514ff52c07e1afd9323b88f8af877e0fd301bbf524901a6dfb944c0bac0387df4fded9f116b6f8210dd636c480b58dd4de92894e45345d1ea61e0739495b0c91d74889e8ba4a3fac3619b74e7e1bfe3712333c33678a6e1e84f950232a5e61f069333350e497d9925242362c328449503051778faf8e171a3b386e4080b3dcbf462acfadb045fd0e11a19e3e055e58a227703ad62e5acb00b0b4c493c048557512191f75f6aa0c18f3989cfb00081a95a7e4b42455111f030168792600b9270fa75ce58e02ad5bc45f976cdb7a0c5a3063f49562e55e8c3dbad49ecae5e8d64d75d8651d5b756981547cbe5726608d20ece20f7f2217e015113d8ebf0c998475acd4e2533c525be032735afbbed56dffcbe6f66bb4336986c10d2b1de39c75686ab69cf370e526096f53006aa2a50f4e5002da5981e7df0b4283616c7106e2e34f1892cb5c241a6135b69ef55d2e8627dc37987ebc968ca14a18c70120f4176f0273aafb644b7bbe160d252537dbf776d0fc73b56aed8585b2567ec4c505634b85e6c22264436157f95f325abc3a901a1b2c5bad06ce82a2a4028162a0728f4a1bd4fee8f67f751d8edd353ef274b9eca810d5d7e64abe78503605a723f810497bd08e574de2c0e5e3a4d70a7296750641751f5fcb28543562d1d9a77548553a2c1a9fab38d40f08b69e542d617aa2c3ef789a47ba48366588a22343dfd8fb7bc6c27bf562f81cbc18b2f6f65777404e62c42114ac9fc8b0d81bd108dc9db27969f13db0f4e1421b175273d406382e27a9a5f459fa94f7aceb05cf598c9c94934e0425750a32e046dfc6efbf380e3ace13960ee00e140cfb3d7faa076a68c3fd15594e390a96f39da3f0c464a14e0b3595300cb69abd15e976889b70504d379c036eb2c15f6c315c02b417f726d6f953eaf6d6d5a2bd5f02f6061eed4cd91954f1113df2b5e8ad2eb21163a0af2c2a60d12ddaf8dcf3be11cb1e479e15d5b5988de9cbca2bf56a857fd50ebd852a67de23ced5a8f3163b8f94f353a5824397b7fb8158b326aa2d17b530ac73d6f2c6d1249b3c058b7569cc80baf98ffc6df2c3e112366d04db13402d85ff14944c6fdf258a43712ec279edd5fbd194e9bd948f6d2c5143dbe5d3b05e2bf2f24e9ab83c39278be607fb250c974552aad6bb2b3d0c31a429ad52110f0793869fee0e93615b8fa26414a593da42ca7f9181db64e970244a7fae4f6a588f3b5b64b9293a7ca3df9b65a315672d22430bc8b14e578af186a49c6e598a1008ed120b9400af513d42b2eff5940f9f62d5cf87dd5f26ed026b0470240b3db1e979ccaf95135e6bfc872d48f73bef0835f36a7c7c02ac6398d1604f0f2bf8ef47c00193d6b785d39574f99c3268bf6abbf119f09d124756f8b1e3cf15eea48c6bf56a9d0069bb516d72f2b2f527f4622568be7d4151793aa952429ba411ab35f4a2c1b708da0bc673290d8404f2418c24f4d0b979f9bfd70e364167225563ea3065dd817e02b6ed7e6c168f0357f79549f0b4754c222dcde5bfe26986ef622cf330d62dbff8de8d0c7606df1c025749c8198b8ec9a5e61ca462992926ac6610c4dbecde609fb91bb485ee19f3f6dc134c855f29170e29ec053a536b093fa9867dae19b651a64bef0a78c71701ad9c734a21a70c8b161806754b63f10e38e196232ae34678d0fea6b069af39972db85adfcf9a225758c5d78cf0e22ac7e6631452441e5e6407b866264f905ae033ee8ab31448af4b3b61ce0f48bb7e889830bfcd5cb5c6b473b9fc312640856b64ecfec3664acae0d3c2d40259e21071b5e1905163a06a73ebe62932be221b5b8436a252f209f9381820be5cfceeb6f61d09356137426ef6fb1cbaaacb0285c4b0b4abef5ba7caa5bd5712f095f547630ee6a2bc422db796a768d36e6c22b8481db80cd584b240218c4116fa9362b5296e12a31f6fd4dd3e7d28ff73b138753bf2592593d0252d3ca17a35357920cc9ad5632f3ddc40f7c818576a88d53683ee8345d37d0eb732da497a221621d9ab15ab22ac6b89cca91cfc44fd5487445278bdec6e19c5aece8fa2c6bde66e79b6a7f46bd57f3c5546138b16eea873b2d50087a92063310908f382b784fc0ed0973f0027be5cd5ad126837a275b1c9f6d9daab25985c7d5b849aaabc498d2d83a6539fa57646e80be0893dbfbb13e214b84af3f8aa7f9a5f33e0acaf2b7892d8cba6c32eb88c7e0469eaafd45bd97dd294f40d3bcf6870bdc32a651210e1dd884c650710e519938a7e387699c005777b4be60ac6f498151f2726caee12a44860a5978d33b3064396130dc2e70c63f2c16bbae9f8a2efa32c555a565dd488278c08a581b7811d57a4d0199f6e0db3add9345321d904ac55aceb290fcb6369c5eaba05db15de4fd5abfa96e807f1a8e9e40960db7672dfe10a085d3ba45d808ec4a19802026cabcd820a589e4a2b21441c4d945edc5d48e49731341e2d52092d3f5ba85bbe5c9e57cc1d6a9a2ac5f25327877869343270d65ce1fc08837b85910d787e5e510aea130c35a2ceed124d3eda96f84c29d34fc5883191739f1ad8e3e8cb93b867df51a7a4801652cd57b080686e022e5c43e8282b6d070f97a219a42822e550c683158c9462fb4cc5acc6108ad6d7996d1d93b4f29233fc4de25c3828897d04fad8ae65938b2675851ff7070fff9c160a7323ab401cde855f93c9a249c019a4315310a833669cd050776ee042ef0a21dd4d87d131e13bee7d40b06c1cf581a023da3c0c4e569b602fb101afb0f2e621d3cd6daa84cc480623ba7fc6a34d7f1cf3997eed3b45e4501477843b02b3168b9e1fc1d05f39fd1c61ce16a3f7b39f8b9b0d0af29f0bcff74239a5dafdf4c589aca41c756b01a889e9e07d86c19b8566d0b82c4e98656becaa3d0f42cabe422718992542019ff5d98103b2ca3f95d301e5509b858e39508707e764cb807c0286788ccf8939295215eeadfe4e1b69aa097e40d8e5fa9484c5f58c8fe3efff44b8007d7f8af29dc2795f2426df1c7d13076ed20b5f55d4c9700ae56e43bb24cea30975923fcc71d6fcea0b358cf8f5992adbb7d3c824eb3bfb59421839b62edeac22c56fdf512d6daecc8aaff1f88d3e24082b9b43382978ceee8332d676591e66d4b56f6b95c0908de65f5862d79e2800c436c930aad6a2418e7c9ef3ec31058a91264574294d0dc5df418d59e8185165e9f7ac92707986b881866e5a3506786d9dfad62c3713b03fad822b5def32b49520abfdcb9e011dd8f944c4062a623b4b76211608325bec06ac021281a7bf71404a410b43dd150e392bb2b1c53e0c5c4ecec7ab084fdbb0866341cc772402620e941b1c9184cf2c70bd11e3d597215ba6863c4fff049c8d1c695992ece23c830b37e8e33dfe06b3ce76bea1ab6d01ab2eda26793c1603619c4a76c77d8bb7c1a240b29461ff1a4d7cdda3c3a4c3e825a136bdbb4abcbc565d2c6f28448edb7fed407b5d7aed050af392286b97b5a65a601dfd511e87218a98f392aee1acb6f2be56c560a9ba78f5a4a24c74636b29beecce887b2e148777c83bc5e6ca01d701147777434cee15ce0573d891438f53364ed1b423b9e591335bc137b8f7b7339dbf72c8cb5d46422d9d1abcdcaeaa03fd5ce984994d945250e7ac3afda9d787358135a67df8329ece4b9cdfbf4362c1288ae025ec996257ffa876083b5f16eeba2cd24a590d99c7396b17080d2e76f09620e1cb596956d2406921a11a8538cafa4b634e7ee7940cbf0f4499d3cfdc3a0163f8debfefbe193156d517e495eb44f74a718c1226b46e7cd56594036d2bb1ad23777ac17fe3b5b6c8a804daf6077a538908ddf1b19a2861aa2c2bf88efcdec36c216a2d4a15f7877fa4a6abaebb7ad19b0cf735e45bb03bd41db59f72663c84032aa92ff9b1a3403b08cc8ae35fc9f3d7cb6e41ff7669accb85cad78b3579be2cbdca55eb54f58a6b4c41cafe51ea97147c63d9206c1f39eecf5bdf13226cd8d2a0a0c9c0607dba78f1476fb67ef46c2ececc4b1d4a3155ded5b5bc921746011f7827b626b57978a3fb32dee92eecad0ffa7aaaab8be5b12737e73e41fd59e32b67091a3044647edb5e1d688467b130eea8bd9095d17c6ef43c6e1ff154027321dbcc5181c38944545492e05a4beaf91bc680ec2b8c58b8c632d6566a0fadb6e9bf0c72cf0f1041dcde69105a53720f8ed934aad35fd8e9bac7fc1f5a0b127a0f0e65948b53f2166a23026dfe5e607278402de04125007292e37659bee49003d3a93cef4a0674cd4be2a060f7e929053608f4b9ea6dca5a5b37331537396a324b6b949eff61a4038fdfa100c2267f3d5138a5c890ee55ba972e091d28ab46859ff795b5c8f4a9a198561444df891a8b1b420dd0f4a973bd88b29c396a644135f34a635501d0225b2d09bd6f614f7143af5110c548a8abf31e948cd939b840fffbfddd70586eea139687b4543f96ca4bb1044867261c5d255823a6743305891c570160dffdb5df174e883c6c0163b7700be1fd7825ad6dec6b3a3e954917ee7d1935dfdce53c562d0d413498dc30ba6f52fe646a26cf55a9def29f604e4aab1081bff8558d0bbddd0c79ed5e559078c2074f19a5f60095d6b306b66cfc490959965376f61e49bedd397c4e871cf3916aa2e86f80a11500e2eacdc6489845ca998a63484197badcd719c14936bf366489efac968a4f9e1536784ad56b4536932d298e924bbba08093526b1c4d657a5cb84018cc67dba8a771e418bac6c67f51b4163efbfd13a489ce62938bfffbafdeb499123ad589ed014fc4f4d92ce73365550ecc4e28815f6149b4c57e13d4db5a37af66199d5f7973693a4444a8fb09666644ede136bb0b40b778f2aa114b1364379beabb7b785c404d8bfaa89970b24a20dccebe524d24e266c51f3379042925a1c983149d3acd0bfacf522a34a00be5c1a21e6f8c39fe5bfad7ad3bcfe9c6ed9cdff3d92de1d8f464991ae16fd5cfb8b787a573af99065c15c3ae1b5ef19ba17d12414af7af1fd7166e4342d7961bbc606b70712b4ed5bfda98c30b46f471561c987864f802cdc321611afa58eed93270de07e8824ebae8eaa8d125ba1844cd26b199cb7ee384cb638496c9bd9dc62fd43751359351920aae7c4e3e91b349999912ddd51f71d6957bfd1d5eabe132c3efc4692e3a9b3edb736fa169efe776810c8ae8d2af46abd1dbb8cf98260de631dfbedf33c3a14efb2c83144b5d30099bc2c4cbcc04ce2c0ae31e51b1d14a6f27248e85815f4cbff90258a85f3a882e98776bb43fc702cf0722582a4955df7e90635d837c919dc6817cc46b32f007920b66b4a7ebad455ac0fae775a4e532cd7235977f46da9a5777a188f4eac2c98106a05e9210ad2ad80176a8d99ba1b49f5fef438de53ce099a44eb76949087649ef5d1dd54da654f36a1f7ceed6c3ec1f8f40ff500a8b5b5a288d3a126977e2c6d8dc337a56c4179b648e5d1f761878f523eb1eeeae8fccf40d5fd95c9593ea89bc407c29615979b0f57cb563ee6d2970ac48befe82d73f5904920bd4a82ac1ebb85c8d76e1293151bae96c1959f21884516e85056aa1f11bafbaaec6c9d6fe1f2a32909d8a56097d96ceeabec3d3681355aeb0650c8e152acc213ef54540b61b0aeeb4acb56031f4b6aad41d461f9b0497fc05579c06fbcbc90fc0401bc81785f1dfb9e8c2a33e18c2c4c64f130bce127c732be77a0c516c316f535a19e763aa823f780e2cfbe6a09b3c6b0b82531ee8e99d79ea98b29af22ede68510a555638f8485b9a2b362a97aac25eeb9651ae70eca106551f63a3bce27a00c5637d7a912cd65602ce521404cc7b79e0f9188934caebb5356d8b2f7d81633d7f56cbe6e0bbff4c0267e0e762e145e75b1831754f74d4c65da9a6dd0f6e917b1c921da1cb3c55707d1e6ece2d58b97167bfcca18ba7fef752e1388b1e5c068d6a334da91cae046d8be1890ce6bab29219998a4fef084734f2fd12d3107ea06b810de00301c5f047fecb03fe837799ba1db392d348aaede1f87edc9b9764bcac58155b3f477b77448817ab715a4aff9b82274cf423a1dbbf54bc8a65ab8ecfe7581774b62d285d1124ebfbc2278a0d313c28cd3a23d02e1302aca9a5d4dba5784338a8f26c8764a2ce3797ecfc20ea73ecba76266b04a80f9da913e4aef9311c6cb6c232f215e0b7eecbed646d8156d4168ea987cfb6561e0d5ed286bea0e1372c5a9d04b60aece653f77d8e97d9f0e4f41e266aadc0cccf67a3f372865a3d5f1ba1f7bdfc435dcbc431ec463d98ce60e727255e6077fa679eef5a95f6f17eb3264ded770c9a65dd7a1bf7dd59f115af57c2cac72a070072cfc66526d0de56fbac2a9424ef116bc8c74bc388af3f8d76ebee6ec1ff36fc42868c54935decfd5d1c6259a3ecc80c8358b0496af9717eb5dabdb46e6884919ba14a6b924b3ec63fee57c5a15c4fed608411c5c00a73d1eb41e0a9c110eaf7b2be60a3aab715c610372d17c0357a062b643eb6583821853ee46b44bab4ff111fa036bd058ad6e7095e3f0cfa5946f756da4a70353b7621f956c46d39eb38f6d379cc7b17fa88754502ab0e0f0abbb8896f0a1d83373185d9ba32e5582f761be23305ebdd78895ee94eaf70fe3bc354f2d19d67c2190ea819725bff845a77771db55cbcb95f471ca04f0e9c49c69be9efa1f99d56efae4c51654d95abcea6536e503c72a8d27868a59b5914f5aa60d8e82b629e5ac72d5b823d96738725d7ab68f989fc6a2ecdffeb148ad64e257edb74d8e7319aad1f44da6551b89dbc5286b9f22efb979de8ad655c509bdabefd86df878ff3abc06dcd71de018e4891f2abb494e902b3cca401fb69ff6c22cc586fd43cadb75a9ebf603d4c6ea1eb2c5ae7639435767cdedf9a82961da975f4207a4bfb823bc11d21a3d06b209a32b3b8f3ea0b129b4071acf979bb9fce85bc49acbc62560203688c34158b183505f8970520d619e7c686badfd289479b7909c40b1fd0c1e464173c4b1581059a90252f7db35475ad9b162ddbcd0b44b03a48228aad7e7510e9bca93a4dd27af72aa409a09e58e9b0ecd946c027464463ac42877816d305a8e055e37de0b6128e53d863b58c91cad79406141409ca1f562c986483db52e15a853297a6d8a3112f378a56fcd84cc98e19025af79c2ff7bedb452d0443b883a2a1748071d59ba581d98289d252b0398ebf28e8c3af8590a74c12ad09f87a591c36c2d586b552f0a1895bdeabfe344223dbca0b0ca638d0eac3d0468e26302b6c4d215fe599728e6de3750fe7ff7391ff348cd6438cbfacdc8fc0eef506279b7d22bdfc033411d4719625de1b147ff654b47fe8104b280dbe3134b0dc85735224497bd686ef26ba10a0da974406117ae8a2d5b9ea9c4aa62ac9a190c05bc7cbdc7d0db475f633c3bae9fe9c346ba2394cf7e17eaf6a5c4c7b920d65921222a3ae7e06624ab933fce0a37660426a5112c615843d9b064eb5707fafec35858fa6f023885be256198a35b0535c2545ddf076d749774a2bda79872894b652a074faee14fe45aca79de8f3f096b802cfd975d4f9cffd5340da92dbcff304db774fcafde81d2ef21cf1fc4a110bcfad37719e7ba4b972a29cc5361be6f4ee60eba2414bfa2b58af8a501c889e05feb08fd7e5e8cf2480dc118e5038b8dfc1d84a2b358bc82fa74458762635f45be13553cc2e2d22b1d0db55f085a268db89e5391be6006be56edbdad745bcf6e942cad28485df8b82824bac96ab06a68ef2a17be59339a9e8d8db8e31836a78cae9011157d82298b45ef548220b4817e07ce301510aaeb7e111cbe2f74f30062f873341705f48c6dd51149b677abf97be08ccc1f74789be8ae1934d04b63464697860bca89051003bce91abe5c9228a8cd27bb7913f59d21ee3e36fbc4a5fddf80c2ce09077b3fb94a3874fc6830f7b4583a93b9d33a195e4944a259b5bea3ac8d128ccd6bb67d5f3143e72d2fed7ae78a0826bfadbca1c1608dfbec7068f1b0b5b37ceff832aa49997ab2f5cbd855decf88186eb419c41e2480a3c842263216b0ba83ec62c1d693f46618fdf952cd5d6bb9df27a6cfbf778b4d7bac188ad9fed2f0bc40df28e682951776ec1614945fa2ce22b694372a5c56037cd9379e606c50bbb199fbaa2cdb794ab7f5c1bcbdee573ee1c809d43df20aa636b94bdca1bc24e8a562054d7f0da537eeab79d22a3ddfb0dd89a394bde5821099448c32d08362c6a8458da1297c83e48f9743ff18b2363d28b41d3301bf0535211298b23179e7ba02890fc31bfa86e8c2602f290632646cf975962c634b6d31b3ad81acdef85a8f3ab201112dea6e2b52e852be4b240c7d8368896f6f7d0c48c935733c68bc908ad0ea2eaf56f4ff362d114526f7bacc183a98427baa79cf29971a917f2e5efe1f44551b96e50287663bebaa5c8c92889797374baa3841b374a6eddafe6af99ee78ba3ad884c45426493a916f4c9e0fcc699c75ae42c9a35dfae05386f2199fce7ce4e71f0391847445efc24fa4dbdea8b19f0ad048ab1fa92283e1b8fed8790a650748cdf3c232dfde9d42a7da389cf3ac06a8a35f6dea48522aa2660c32faaf74fd90ee73b348f2036741e88212ba7670494aae7a87cc36c41967d2769d1d23865a027922c78405de4ef95fffe8fd2138ba1347a54e09ec44a80b147e6d7b4c42acf732703f9c7bece3bc5ee4401516a6a2187967037eeed9cd7b8002bfeef730faa2e1380bb527f9dd4399c7770d4335d8412c32a626bf6c5008f19dc862782742514eb7255161cd450e58dd6da8f95d38ce1a33ead60969b42997e904a3f5c9f4865110dc1744050d371f9f7a97e8e84a56ca7aebe95db9a2bd88cd4ed158a453c42e11647b14d6158e96e62ee7cf830f794305813a2031b3e9eb9621c5a03aa7b9226eb567d768c26eaf022247f4d3210ba2578029286fba25a58e110030bb7ce79ea52ec45173943389965218f1a3cc184ab1d208b7fe649b6dfe2331f3b97bb285274a7aae6f615a9314af7dca8e2d357627df5e02588d56c6cb7be5979abe45dd00e4009be5c02319a14aa27e79c88948911a6100aebb4dea9ed6e460c6aaaa5c93f9c643952dfa4634e8df8f9ef73cbb8f95c2aeb6a967097daa2a863fc3599fa24fa2a54d67e0bc3ec9f4287662dc16b5e66dd21c3f4abef7199b58e97e9b8076e8c44ad9c70f1a4493536cbded09e3a0e2491e711e34276e55cbd45ee2edc5c93848cd216b7a45c5ce26f2d367da4f9aebdac21e2aaef6b25f21cbcfaeb7104edf5d64e54523de9cbf4a5e6b4ba07b2dae7747adf2b0ed5d76d6b09690c1c7f4831a500437081923f4c6b9c26df096c459fff446beedc8115b19e628848620805e4ec274ce91c9726f4bf543b5f877707d2f1ce0e5a3736326e77a790faf28eea9d21b79322b6f6afd91521ab4651e5745afcd6d56383318a7071e0ff1a09934489d4d6bffa934b436d946f33c3900ffcefb0e8bc44fb5b55cd56061d0ad3090edd530a48c08926cee8d3376b7df220fb35323f8a76df56c788b11eb67ee7961527a7738174203f54761f3353b5c913867cc254facd6861ade4da4777e8eae085b7a2d667bb7d89985a8eddf70969f6ebcf5bdd84893c8e20a731d5af560c6056df4be4c526be89914445fc585b04b53df7bdf5cba699dc57ece44683653915799262c5f67d100114e711a73a6fdea4a900bef6a8277e3a8888ce3ddad45bed04e098110d02ea98b8f457eecd771d726b563a46c6acbec57a0be7c5d93e54bba52e71d4ff130a682cf3364dc1fd2b5e0eb8edd447b6f893abedd6cfd22c7fdd05b732e630bc50264d26c148931f1cb61331274b325f01d60baa2288688c883895df6cc5df464fb23c86fa74e4d483f44f24cb4ae4ebc9ad4cc71e2e9eaa743f88cf4ecb73fa1149664e957b1c815966fa54d852fd1f2cc123c3f85b6c53e8efea53d4a581d81bc01261fbae8d7eadb6eac52811e3dd7443f6925077b133df577762e90f89e75c7d76a1db315f3f6a7ec4444452a0db856d6a1dc156f2ac35e6a7a61b8d33b0705ee6d981917f2a1439263e7a12c7e80eb24c2b7a8c071d70d58550d00bde4651b67983cf6e16b4ebc3d7cd21354105f9940f5b9f03a27e1e0137d5394620f01e7d5e4947e7f8f8922a67b6f6989367c75ec9aa79721d820714b7a19eb4bc0f67dc06615b9c0391a90235d07fcd626b13b75245d20aa099a58b3067a1d364b2055a87f7d5906e9b9b153996d5a19f68ac9db9bbb1cc743294e18d6392d0d26c37e3e2d755a57160ea01f705ef30c7f7b7b072924a84ff40bd80dc790a5f79a3865a85feb7007b11b7ea0da6599e35e5d703e9622f0de4586801f918d72ba8ccad22368a6914b3b6ddb8185b56482004a725f0cb03ec5f79d702a6060fc8e2945e367f06c11c917890d7b567e3b16fb874e17b1257d79be5095c4323e0026f51e90782100b67411027ca4e1cf9bb7dd18beba9ee18e77f03939a7db326e4a654a8f1d2880ae0c44ed1517bfc07750b5073047e5512d68b940be401094f19d5cd0f70f37a630ed8063312c2c73bd6ae052f37037ad6a174cbe6f8f60099fef002a6ba3d71c2f830400e9c10f939194a18623b86d2e665d62f5f7868c431a0690e6eadb660ac4b6c48941316d1c3ad224393904d6df341a5b7b6131d759f44a6402e8bfbcdd3a28d221e3054fe32c65ccf2207213e6bb24bf44aca570c76fbd8fce5eaa0ff991c140d03f79d4b37aabf930172b8c203a904f277eb1c384ff3f61507fa131997665d5e8e21fbc0c690017dbac528e670a6eb67267460ae4b0af60eca2a7bd69b0ca0489ce344c879934732ffdb208af0d4a5e0121de60dbf52e525a36d5058b7d9b306052d442ef633a1d8b6862a212697bdac3c7ad3041f9e69cba5749e63b1582deb53143f6978d2feffd88b2b2f8d4babd4af33fcbf788dbc90937c0cb3d9df813b34fd4fc6e1a199345a630f50ae639995b6a9f80e5adfa6d1e9729b2d38f2b06e43b618a67a59189f10300a125901899b9a86b116dc3ad5dee7520ee88cba9ce8fb652115e40a88f9a6fc6abe81dd17636f9a1caefd76cd4c10a372906e8a85d682240ce8ce25a8718141b7d7eb93fd9820fa0165d1d9ad6cc88b0c0feb4217353664705c5d3bbcc26f9be7a1f283c05619c1f83a3ecd0692b03982e202642d58b46eef8709198854cb6334c87a2df54220e9dc1c98cab2553840f9b4992748715cf8ece36bb6ed864077237fd05108157ebb03b55212d93ebb1eed0ee12997d5b1b6cc7d434216ac79fe4a17949b37a1db9e19b39e7fb45519e5acbb970e4a70f5a8c3422fb52cf911b3546307357c5b1d55c1af638853927bb51b0d81e75e4de7fc9fe3a4dae7479703f04c55047b512483de1aae0e28b467e6827b9991772386e256643b750ee4fa180cbc8f7060e4407734f0604d3784fd13912361145ff0b613a737b77567812772806ccedf7f14f2a938d0df89b84ce59c369d159a1665b0f18c325bd0cd7eefdfc0e30790f397f6c7e8e04399e2aad3848eed16e0169ba797ba844371bf59a21afbd3c846fee3759ce6755b3274c842fe4a52db8afd2888d815aaaa5975586b0ad767b5e12c9797e10e373ddc73a7c5d8dd07cc8eae9f4a250bcd02157dbdd44b5635562ecea9e9b6fb0d594e97dbeeb2c993aadffd1bf6388653bddf91c51a843f811861c953e30a095a3a80673c4b21df456ccfa5691533972e6ee99da21a67b36bd37ea20e762974b7dbc1bb730e9a017a4453eaa64b02aa0bb9876b8a7085c9a714e4a2e1b7a679625039be12cd5bbe4fbf82b9817dc3b180e15f07c7d18494ba11dad2bea1e52061ec0236b6c69c196269397670e0681bba9f5a751979ecaa2f47c47d68df49e1609c536d9032e358a506406b35760705c1040daeb242e96af235c7c90a9c5e800b56c3fdbf743cd337b85d9804824c66321cd3faeb2f373da93320559eede6e63ec760e2044933b62fc03e6243a64a05b5c8140ffa45b1b0ceced20e67e9f6622e8e89f82f5cf09e8dca6be41f002de65f113bb4493c02a2f30a7805e9d7274be3f776fac6645ee552911c6bdf117f2a201d56a06d23dfc2230a03e642d65f9cd061c49a36df01d65e9043345ff440d73ea95e17aed924b47b135a640465f029ee72038c0e0f5e56d4e7c5918f1f7bceb41d2a76fc91a48573f869d264ed56d8d0f376c0db6808961ea3f60a76bd726a99a244fd09b55796c460d32361fe286f2e05034a66b894be42d624bf56e0afb68aa0b11918aa79bd5a578a28aa80d5dfd491c4c8e18f144f0e877a2ce17c2fef770acfed97c64094b78266471195c4ab205bba400c836822b8524cd4b9eebcde692a1f76fb2f95dd4758864be1606e3da15ea14a4d810b7b4cdbe835c4fb5bf59c237ae96f6fc8226d1daa096b12d1137318a7841dd9c189a3661910a85a2343b71c78a5c875ef528bd899381167415b0ec6b69f02e39c8e6069990cadceb68024a11548d87fe1b91913af6e6560bbcff51a4b9699e5df9653bd9e95122441b2b5aa56c6979f4b0b39a989b11bf75a50d335b636c8732c5855584ccbdd0e131585b3425d167192e927c6d2656032f424b12cac2b734e713810b9a2385a67bcdd2c8c9e4cd0a8d36b1b8bab2e7f677e4770d0b08e6354e99eec32f85dec4108cedb3569e8067d8f356afd140cd5eebb0b83641e5a1d24db2f175f71f8a389da4503ed02acdd8e4214f9e0807ec5d4e9ae76d28312b1dddf31b4d8a09715636ef0768613d85f81a4e6b53cfaa91b1564b5ca04f916275e5048a159b9420049ca93022ca43de9df21fc00000cfd1c6deea15c43baf3a0a3f7dc9d2ca17c634d4f5020fb3b349f8c8c172933530f41b4a1f4971b335d17c7a11e628ad426d2e78eb798c6509a3eb04913db5173508d6998eeb1f73095543ae8ce6881b5b0246e2523bab6e24ad301531a8059cfb996d40b926c0084a9b5559ef3f8a7c831b3518241fa6e6aaba6552689a3b0e8e31b9ee7957ecd92bf605598089d480b045a70a315fb44a0e893880a6e326eb8555bb6fdf73b6ab68af905a2d62fd42c8876ae633dc28495ff16ae10c05b26fe6d81621258aca57ef0f35ef02dcd7e1a2d5cf1092ac36123c73c26eb5ebc1c071f99736b0e723fd96d702531447567cf61d50c932740124d99da40b8714bb13459e4c06b28bb300aa6e77436cf27c7c662eedf094ae3cd00a47a5216325f78e472eb2c31a39fcdfa61ed69855677a8a3e0c913381a9b79414ce407d6ee7f45f682de5018fd014357aae0ddf4756d989fb5ff80385ae37568f632a7d94fab9e0ec4a02a0963228c9c85b78ea871fcce498e9e88ad843edd27377f0187befdfd34dc7fa1888536a21d2667d11f74c60f3be1ac14cefeb816aeb586a9f999a38406de6e6dbc0d4ad14c28efd8fa3ae3cd11d669968d43ae55ae92c0d3d77cc183583748427a965bb112a6a198d8d61d2b055ebda979fca32bcc050fdba53425f2e3f5d2c1a7944bc011ad49a1dd6023a363a28007a49f307e0d19122cda4da8845eaac9ae1d20f41c685253881dbfb4c52513024b7a31a3b9811b593c63c05f316e60088e70fdfb1d5473548081f290ba2d18ff10f597252a70302ff5b50ef08d98e66ff82bf1b271c94adcf9578b9eaf8e23f348abc71a918dbe6fad8f9669a499c9667a02aafa28d75fcaea58cb2125e72d0e473a2e7d088cc53e20453490efee91695beb9b1c6dcc2c24264c9d05791185d463cc66b541019df6d1ffffdfbf18f3aa19f69d012001b68b18e9770c49d9b06487618a1b2a8629c1bf8ad84735f4ef1ded521c9fda7c3e9f002f653c2041f314f4f5b84267f1a72f779fc6f715f3524abeacbf2e8a6a1970ed8d7a7697f14280f051558969ef01625c2654574638b747ae1734bb7dce6295e0411ecab15730efea7beae8c404702ffcc1a24e6a1b8d0145ded00fd8a5c58fcf3508a9f200c6fef3f16ca1fef653679cfbcf6ad8c708761a94527135aa56edc4072cdf6003505cc89681f28fad863b597998241075df02966de644b9a8b7981210e5b411a414b5a7ac1ee0e451e29d9038b71abe2b8a509401733c4a98eae5d7b2bb38cf286277fd00bf5d3833de11bfaddd57ee2065268e752c0e450b047c3dd59c68ea217ed28c99e3565a5391a90da9dcbfa34d6dc7be05046763761fc8d4464d95e8456d0f324386b44e27ed5ae07d8c03f2fd261da670b6e869392bd9dd636adffdc9766ed1a9ddb14e514fae5d9c94a413bdfdcef1b84f2f42698e73c6e1e4f362d1b893da242512738c7700e546030c4dbaea7c23777562ecb0740e7acdb3bb0bf288f01ca518e65d5d89309b13a186994d3ab496c6b0e0a9f6eae8e4c5fde8b36eaafddb4a26483c79dee325d36e09b22a9ab147268f536c0e3d8ef7d03b05fd7b328f5d3dea3c0d73ca8aef51e2f227a2b394158146dd18fa5ec6528359412696447ae03230b17f635543480c69c6641a89f9e74e674cc031b514dcdc55fa039e7169321d2fe454f929aea06882db841441de0aec2941bac35f684d6376fb4c1cee12ae9934dd4fd2f7f8373cb3190af29927e4c807e75ad8cb357231c54a58b070ba2bdbbcbd329f40e0eb4aa84cb1695f6bf275a72f8e0cab41f666215fc665e9fba55da15284948cfef4b1f6b6cb0eb6c517dd2abc168a27791656fd78066d9bd6f42907827efc2725c00ae842c5868cd06dfea1ee6fa27663ffbc2f792c197ee1e8b2718afa178ace506c19fd784936e709ce048b13f23aea1be711c2a27af4a4a30355947d7dd700c0cd1c3de341f4059d5f89501193bc3270160ad54b1f1faaac78cffcae2bdb01a5a38da2d1122e7b146dac8ea3ad69c47b4d6f2fa52fb1c56ed87be971dc1a4c68f7feca5dd69c487d775dd1395b161d0dca81a554188f57334ea420c98b9f764d13ec1f4e8e3f2a1c5c8d58acc9a5f7add5197b17729f5917b0aa8f5b854bca37f389a68f4433a78ca64416ea10a773b99cf03755c3d3ad165bbfe68bd9d9fb41c2051d08df30306f5165da1e8f2c8713ff5b3ae6b5f4c35b5104d3876c81058d8324ec147dce314625625ca707ea982a83bc90097e8c286abe56cec1972f8589dedb15ae874918e04ff4b8866b8e06e71d43c9a1e0935baff8ad39064e2c74e9a57a6e0f6448d5555bdbf50c7518dded8122f10d26f2d54cefbc171282e23fd812ced07f8c2ce5e4e205f26037206d32a9f93e8194cf18ef19f7126966a990718f5455fe22452ba3e7042b738c6a27188032a992c88728e2252c877d3fe98e456d2036347d0e0d1ee542ff1b3294c953aa2d989bb4fd18af2e4eb3839fc7bfe7b061d81f8da4cd9a8ebb51b4fd15c2b19603e1eb3f566b6d23ad2c4d0a1f394b6a9aa3e2f1ea4f6d558204e29430420dfd4e405624e1ac7da2a58dce47db0ca6efd9408f5827b8ac543d5dd59316e72b8af86e3ee7c9bf008cfd47c8cd526d690509342ef5594dc7a2cd86daa6e851a20b48d074fac277835afdeaca35801478978d2995b41c392768bf5ca181ab3728e439af11407203736ef518a0a514a89a6efd22a9325cbb1e66bd1090112c400dede551966a25a2c8a853a1d09cf83336db0b8b28fde6755f2fffda14b8ceb4c94f2bab71fc8fb0eaf3ac029f1c606b977981ee75c6802bff103be44d233e8b3d7b318fc3a55d7d1ae1d75d491196d7ef77b5170174283433ce3e929a6b6c1c6b415aea9d23daec484771579767e4132c09eb3f259d9864bb9d4bb81a60d8012c5e4550902ada6177bf70d46084fe93658b321fe3b79b13d2368eaee4494af677030f3092fd8c19b5796e278ea717992504f0662d78a84a5866276d96c202aebbdad83f77e8760fcf4e3c445b4abd4d87d35b4d851482fac9a9ef805378456aa14f5bf2acaabd6ae4c21b692553ebe6e3f7487e84219478f613d776049e8908d65410b72748450334cbd556a637df7deb6d948ddc9ef63bab9b71dcf0145754345acbdb89c5ca0e8354ddb5a809d625ad7ce520373e1c8605e462ae11f7e5058dc8b05234e11e668a8ec8d824025c17a4269cc24fe73a556458812fb1ff5ae1663b62f6caf2f5c86fbc714b31f819173bdf7b1b9b1f1bbf236ea367827e61ad73a72bebb622e4011e2300d7f2b88db8c61fcb38d3e408f62b65943cf5a7d989c1f5c29781081cd745d3dfe7b868e6d87d5806ce300fdc0acf90f7c871d844e8e45adb1e3ddb07684312c5742df98b12f1b550673dafe80f0cc5370c4d3d765f5b82ba42116f1080fbc13e710d7a6244fb991e6a64c73ae9818be84090c476ebec24ec90ca6f97dcb922e3e74229e6efbc3fbf5e734013d053a2f7e3394536f661feaa483f19c718cd3516ef9e9676d0cc7a3e6a6e20a82f421e1f0a47fa161ab081d603b994e94a178c5f6b308d9e6d2011816af75afd26743c05c5fe2f621bf3ec0c06a6609044780ee8e904cf45b3964be3b17f914dac4a5b288d76678d9142a0216e21bf13171aa73c4f091d03c4cee87c409d307131c8fef7205854c760580823c2d19520edff440d4b236a15d34706ea4db414e9bc343deb52e8b1ccd2a5d245c639822b076fb06c51dc5d4d95d5f0f092a54b28f9a7c03470bf566d3a2ca0e1cad9360761b5c2ea74b95c8b8579199acd183955e668082312f10072f4673fc4be4095735628967d53035fe1435974bcddef8fde946818971447dd58c7aa04d8ba4e122319ca3a2b7a2b76cbe5ff9a05e96a13c30d5084ce241e5b332685ac47b3657b21b646df996dd99ba7f62e1cd094325b389042f48de39f996f21d9758c4b2e9cb30367b82ba1b7c91c08ef8d11b35457b59b7d800391846f52c099507bf8e2f4b17b182b07c9715c869a2e1d480252b03bb3b0fcd54e578ca0d52bb08836ac6b0b82b6570d310aeffe2fa50ac02461fb826bfb08154c514631d4e87f7570c6731e87a76172504b4ba4daa26c7386a3336f1e7c2da7bcec9a423b194dd4d676d7ad392f8473e84cd8676eb7fa64fbd196d0be19a58ab6fca9954fe6cc416ecad21da88fac493f24eb79ef100bae77479dbe15939e709dd1a21b0998a02af94c0d8ccecd258caf113129731d7ad74307245208e1ceedc16bb4c0d0b4327958656325a5734cbeb9e21cea35752ab1dd9d154c0aa4ebc726bd87f8baf21b3333504628747559f3e1be79edcb728ae6ce45268e5ac1c59ce98ce25da3ae5b347ebbee2cf287c18cbbc9bb0d1c01b3af4ab7a32a29118c0a4d2a31c567289b789be242570cdb166dbb2f8df86781484b7c1a680bf65599e5fa53234bf189cbd25782118f879f16152bf36f46585875e36ce33983ed297f9eaee1d67e603ce8e03aa463a6d6ef91201c7c236a79c005c7050f137a97fc3900ff80aa4c550f71042383908012fbef59154f738b44bc4dc38c9042a645821390f710eaa54226f4cdc1f6fcc6b2a4bf5611b782dfbe4305ef5af6662b12bcf05ff1d65197d1ac1d61026245a526e7ff7f08d585248af9806208dc7c8be12739781e76199c88893e3316dbcba64f841b75a89fdbef0ec422e21b52d280bc4df5aa0adbf91abef1e9ef71ad455ee1d0c250d94151c316460ad18dc77c4bab706ceeb6de83dd42a25b21b4113f829598e1cc3af35420e80b0ea5a51e08c0c3bb720b4425f8bd2d634cb4163754921d31ab1514fc96e2a50b9dbe11a74ac3762595649cdc2d2a205da40cdc863c81592f6f5bf80384a2be76571d7fe19a0eceb98fced3661991f2a6ffb59d23c832935e671e7dc6022c31597ef7838d681d19dd0dc575fcc5b9ab692175b22299ebc96f74803a689df95dedb4d727912b234e02bbf8188b77d3b71b258df951ddcfde031b3eda2725a232d8c6aded716a0341630eb2a317d010ef70d65898df207e25c19be85ee38901b65ae0b60b26d03f671cbe0fc12959d06360c7bfbfda46cfcda9db441a64a40510182cbc7bf44ae075ff4fee84139e6ee8edf33d0610b80afbdc8802841e853df09f1dfc924fc09e9c0a8d9423f59bc638d1adb25c69f0dda2b70b9c2317653521140dd326182585033e15a5a0c966c7f6886de1d227c985fd25682ea0934d355788fc96747661d32302feb33837db14d72c9b4a559d22cc52c123c32317b12fc713080fbcb6a01aae38d7aa2a4537ea22e8830cd02d3a1bd8029f7c33aad365bf3d179fb7cc3ff7d9586d5de1e8caa766afda2c8e4ab969822d4e3ae7ed6dc418b09dd3b9483678e8a103ed83c955a51b6434ad674247354ca20839903fc553e2b9f9ebbcb4a50a54146e8a89cb7497d4aaa81a3d04af678eba47367b3fbbc070fdde3ceb324110a1e1a83ab565dca43ebbd6847815e013088358d97c41f5a99b1d498d84816441dad82c5c33210a1e6a6c133d81aa372aec52a8c653c2c1f060a72e3f9ef2fe87d393eda3b3e4532158279f9e3bc43f91c745860934230f8966801bc92f5c1883eb45f993ad188b52df5f07db6b10a10ab4e574554666941194fb180416d47f403c66034c3d576cb5534f5c5d0f5665211e07b13147e6553ac32831278f71a787959c4a601c5bc1ed9ee1ed69b987fbbeef6a7725afac49d37cfcddc987936e5e6648a5b3127409631aa5d8f3158eed82dafa612db7981554d982429e488f77ab9ab68b5b2e182648a360c0b1be7756acdb40233e36eb41bd20e4f951c6f980ba35c3353e65045bffb2dbd0fb2d1ca71232b6a44f8885d9e9a384c97938312899f6dc7bd1c4112a2dbea61812160e524d5ef5791366f3c2c640737e21ecb7ef347e2a0ec5b18b84c7cde7a3519901818a1401130fc77172fa55f63b2fa9535ff80f5214a630fc5957291db1e3a647ffc95401612d8763e00d60c67d761fca9e279a2896b9485b6a394a48e8f6bc96d6620a1f0870bb876b5ff6f017ebef68179c3305fb9b3f762928f4fbd52299e1f0a53c190323f873f7be9d17c9c0101923aa1e6571dfc4031d4ac3c04d832ea4d30eb2b48356966017bbaecdf9e1a2e69948b5f63840e9bb87dfc19e9acd0fcc12251d84f78707aaf22670c33a5d29e6abf7756b4af760a3956239ccd802ced2e91a2d9db54bbe199d9ffdca17b961072110ed8adc06870c85fa3cf1c303a5c5d22d3e4d73d7b2a01099defd5a63d123a244bfaa62d9df26204e588cb9943f775ad740f5b3d9bbe547808ff41c3bf48e0cf96c314c012613014074d1ca80914014ed627a9b69509c7445c617d34d7d7a3071ef1e6cf3603ff30e3986597aaceb5f70afd08bd91589b7277d35881e970c1144586181fbe9731d19a668e552ef20791e6af1fedb79f014c3ccfd5d305cd17dc1b0b8097c51adc94c0664ced9bee516ab21e4a99749502fc4b0ba72d9b7019a08df701beb466531a835f54895dfb045f689607d69686ebcf10d68bd2b05211668315dff7d6d3c05f44d73b7146efea7a7b29c8393112d077e687912ec9df2acea2d32889f868e45a27c45fc8134182d596b5ecd4d7e6b63aad36ee487ddaf99bb6cce9eee8f0c9260c70fb7c0c4ff204f4d82922026c69a621fdf5c222b20c0bd0972a2c2fc3d88cc785ce14c467b894399c1dba00dd7b1c1212055ae1e34481e253dc8e73233947d92ec090926fa5d1eb04690617f71afacd05c82364cd0603f92be8a6ca7a70216a50d91555131963ecccb10ffb5625c32e99939f98de2388d504fd066c87bd01f9e92893ce14a41f5b5b3c949fab588bc363a4f949f2797f1f8f6763de46b3334f2a301f7cc3953759de54e47e331ec0eefffd734aafedeb54e17a93f73e989eb219a847c60fc969feb827e874b169ee71a22990373a27da0b72ce985042c310d3707e93009dbd7c797c679483bf42aa8ee0588b34a407413ce3414c24f97c9fdc4602ba3ef7e572b14231674de80f4b449c479218ff12dce1b7f90fb0ef12a601f25000\";\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(\"Neonpanda\", id)));\n    }\n\n    function _r(uint256 s, uint256 i) internal pure returns (uint256) {\n        return uint256(keccak256(abi.encodePacked(s, i)));\n    }\n\n    /// @dev HSL (h 0-359, s and l 0-100) to an rgb() string, which every SVG renderer reads.\n    function _hsl(uint256 h, uint256 s, uint256 l) internal pure returns (string memory) {\n        h %= 360;\n        int256 c = (100 - _abs(int256(2 * l) - 100)) * int256(s) * 255 / 10000;\n        int256 x = c * (60 - _abs(int256(h % 120) - 60)) / 60;\n        int256 m = int256(l) * 255 / 100 - c / 2;\n        int256 r; int256 g; int256 b;\n        if (h < 60) (r, g, b) = (c, x, 0);\n        else if (h < 120) (r, g, b) = (x, c, 0);\n        else if (h < 180) (r, g, b) = (0, c, x);\n        else if (h < 240) (r, g, b) = (0, x, c);\n        else if (h < 300) (r, g, b) = (x, 0, c);\n        else (r, g, b) = (c, 0, x);\n        return string.concat(\"rgb(\", _u(r + m), \",\", _u(g + m), \",\", _u(b + m), \")\");\n    }\n\n    function _abs(int256 v) internal pure returns (int256) {\n        return v < 0 ? -v : v;\n    }\n\n    function _u(int256 v) internal pure returns (string memory) {\n        if (v < 0) v = 0;\n        if (v > 255) v = 255;\n        return uint256(v).toString();\n    }\n\n    function _pick(string[4] memory names, uint256 r) internal pure returns (string memory) {\n        return names[r % 4];\n    }\n\n    function _T1() internal pure returns (string[4] memory) {\n        return [\"Cyber panda\", \"Cyber panda\", \"Cyber panda\", \"Cyber panda\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Chrome hoodie\", \"Chrome hoodie\", \"Chrome hoodie\", \"Chrome hoodie\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Magenta cyan rim light\", \"Magenta cyan rim light\", \"Magenta cyan rim light\", \"Magenta cyan rim light\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Rainy neon city\", \"Rainy neon city\", \"Rainy neon city\", \"Rainy neon city\"];\n    }\n\n\n    /// @notice Raw artwork bytes read from the IMAGE data contract.\n    function _img() internal view returns (bytes memory b) {\n        address a = IMAGE;\n        uint256 n = a.code.length - 1;\n        b = new bytes(n);\n        assembly {\n            extcodecopy(a, add(b, 32), 1, n)\n        }\n    }\n\n    function _svg(uint256) internal view returns (string memory) {\n        return string.concat('<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 400 400\"><image width=\"400\" height=\"400\" href=\"data:image/webp;base64,', Base64.encode(_img()), '\"/></svg>');\n    }\n\n    function _attributes(uint256 s) internal pure returns (string memory) {\n        return string.concat(\n            '[{\"trait_type\":\"Character\",\"value\":\"', _pick(_T1(), s), '\"},',\n            '{\"trait_type\":\"Outfit\",\"value\":\"', _pick(_T2(), s >> 8), '\"},',\n            '{\"trait_type\":\"Light\",\"value\":\"', _pick(_T3(), s >> 16), '\"},',\n            '{\"trait_type\":\"Background\",\"value\":\"', _pick(_T4(), s >> 80), '\"}]'\n        );\n    }\n\n    /// @notice The token's SVG image.\n    function image(uint256 id) public view returns (string memory) {\n        _requireOwned(id);\n        return _svg(_seed(id));\n    }\n\n    function tokenURI(uint256 id) public view override returns (string memory) {\n        _requireOwned(id);\n        uint256 s = _seed(id);\n        string memory json = string.concat(\n            '{\"name\":\"Neonpanda #', id.toString(),\n            '\",\"description\":\"Neonpanda is 8800 Cyber panda hacker with green visor and neon cables in a rainy neon city. Art generated fully on-chain on BNB Chain. Minted by .ai Agent ID holders.\",',\n            '\"image\":\"data:image/svg+xml;base64,', Base64.encode(bytes(_svg(s))),\n            '\",\"attributes\":', _attributes(s), '}'\n        );\n        return string.concat(\"data:application/json;base64,\", Base64.encode(bytes(json)));\n    }\n\n    /// @notice Collection-level metadata for marketplaces.\n    function contractURI() external pure returns (string memory) {\n        string memory json = string.concat(\n            '{\"name\":\"Neonpanda\",\"description\":\"Neonpanda is 8800 Cyber panda hacker with green visor and neon cables in a rainy neon city. Art generated fully on-chain on BNB Chain. Mint is gated to .ai Agent ID holders.\",',\n            '\"seller_fee_basis_points\":500}'\n        );\n        return string.concat(\"data:application/json;base64,\", Base64.encode(bytes(json)));\n    }\n\n    // ---------------- owner ----------------\n\n    function setMintOpen(bool open) external onlyOwner {\n        mintOpen = open;\n    }\n\n    function setRoyalty(address receiver, uint96 feeBps) external onlyOwner {\n        _setDefaultRoyalty(receiver, feeBps);\n    }\n\n    function withdraw() external onlyOwner {\n        (bool ok,) = owner().call{value: address(this).balance}(\"\");\n        if (!ok) revert WithdrawFailed();\n    }\n\n    function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC2981) returns (bool) {\n        return super.supportsInterface(interfaceId);\n    }\n}"}},"abi":[{"type":"constructor","inputs":[{"name":"initialOwner","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"name":"BadQuantity","type":"error","inputs":[]},{"name":"ERC2981InvalidDefaultRoyalty","type":"error","inputs":[{"name":"numerator","type":"uint256","internalType":"uint256"},{"name":"denominator","type":"uint256","internalType":"uint256"}]},{"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error","inputs":[{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC2981InvalidTokenRoyalty","type":"error","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"numerator","type":"uint256","internalType":"uint256"},{"name":"denominator","type":"uint256","internalType":"uint256"}]},{"name":"ERC2981InvalidTokenRoyaltyReceiver","type":"error","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC721IncorrectOwner","type":"error","inputs":[{"name":"sender","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"owner","type":"address","internalType":"address"}]},{"name":"ERC721InsufficientApproval","type":"error","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}]},{"name":"ERC721InvalidApprover","type":"error","inputs":[{"name":"approver","type":"address","internalType":"address"}]},{"name":"ERC721InvalidOperator","type":"error","inputs":[{"name":"operator","type":"address","internalType":"address"}]},{"name":"ERC721InvalidOwner","type":"error","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"name":"ERC721InvalidReceiver","type":"error","inputs":[{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC721InvalidSender","type":"error","inputs":[{"name":"sender","type":"address","internalType":"address"}]},{"name":"ERC721NonexistentToken","type":"error","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}]},{"name":"MintClosed","type":"error","inputs":[]},{"name":"NoAgentId","type":"error","inputs":[]},{"name":"OnlyWallets","type":"error","inputs":[]},{"name":"OwnableInvalidOwner","type":"error","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"name":"OwnableUnauthorizedAccount","type":"error","inputs":[{"name":"account","type":"address","internalType":"address"}]},{"name":"SoldOut","type":"error","inputs":[]},{"name":"WalletLimit","type":"error","inputs":[]},{"name":"WithdrawFailed","type":"error","inputs":[]},{"name":"WrongPayment","type":"error","inputs":[]},{"name":"Approval","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"ApprovalForAll","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"Launched","type":"event","inputs":[{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"agent","type":"string","indexed":false,"internalType":"string"}],"anonymous":false},{"name":"OwnershipTransferred","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"Transfer","type":"event","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"AGENT_ID","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IAgentIdRegistry"}],"stateMutability":"view"},{"name":"FREE_PER_WALLET","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"FREE_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"IMAGE","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"MAX_PER_WALLET","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"PRICE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"approve","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"balanceOf","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"contractURI","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"pure"},{"name":"freeClaimed","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeFor","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"},{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"n","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeLeft","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeUsed","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getApproved","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"image","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"isApprovedForAll","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"mintOpen","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"mintedBy","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"name","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"ownerOf","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"quote","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"},{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"royaltyInfo","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"salePrice","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"safeTransferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"safeTransferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setApprovalForAll","type":"function","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"approved","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setMintOpen","type":"function","inputs":[{"name":"open","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setRoyalty","type":"function","inputs":[{"name":"receiver","type":"address","internalType":"address"},{"name":"feeBps","type":"uint96","internalType":"uint96"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"supportsInterface","type":"function","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"symbol","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"tokenURI","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"totalSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"withdraw","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"matchId":"58047552","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-02T06:57:32Z","match":"exact_match","chainId":"56","address":"0xDc50866B4b76AE375344Ba730C8C7C324797D38e"}