Source Code
Overview
ETH Balance
0.01 ETH
More Info
ContractCreator
TokenTracker
Multichain Info
N/A
Latest 5 from a total of 5 transactions
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
RoyaltyContract
Compiler Version
v0.8.26+commit.8a97fa7a
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-10-29 */ // SPDX-License-Identifier: MIT // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.20; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or * {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the address zero. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.20; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be * reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.20; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } } // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Muldiv operation overflow. */ error MathOverflowedMulDiv(); enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an overflow flag. */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. return a / b; } // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by * Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (denominator <= prod1) { revert MathOverflowedMulDiv(); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also // works in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } } // File: @openzeppelin/contracts/utils/math/SignedMath.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol) pragma solidity ^0.8.20; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { uint256 localValue = value; bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal * representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } } // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/interfaces/draft-IERC6093.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); } // File: @openzeppelin/contracts/token/ERC721/ERC721.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.20; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors { using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; mapping(uint256 tokenId => address) private _owners; mapping(address owner => uint256) private _balances; mapping(uint256 tokenId => address) private _tokenApprovals; mapping(address owner => mapping(address operator => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual returns (uint256) { if (owner == address(0)) { revert ERC721InvalidOwner(address(0)); } return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual returns (address) { return _requireOwned(tokenId); } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual returns (string memory) { _requireOwned(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual { _approve(to, tokenId, _msgSender()); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual returns (address) { _requireOwned(tokenId); return _getApproved(tokenId); } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here. address previousOwner = _update(to, tokenId, _msgSender()); if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual { transferFrom(from, to, tokenId); _checkOnERC721Received(from, to, tokenId, data); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist * * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the * core ERC721 logic MUST be matched with the use of {_increaseBalance} to keep balances * consistent with ownership. The invariant to preserve is that for any address `a` the value returned by * `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`. */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted. */ function _getApproved(uint256 tokenId) internal view virtual returns (address) { return _tokenApprovals[tokenId]; } /** * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in * particular (ignoring whether it is owned by `owner`). * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) { return spender != address(0) && (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender); } /** * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner. * Reverts if `spender` does not have approval from the provided `owner` for the given token or for all its assets * the `spender` for the specific `tokenId`. * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual { if (!_isAuthorized(owner, spender, tokenId)) { if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } else { revert ERC721InsufficientApproval(spender, tokenId); } } } /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that * a uint256 would ever overflow from increments when these increments are bounded to uint128 values. * * WARNING: Increasing an account's balance using this function tends to be paired with an override of the * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership * remain consistent with one another. */ function _increaseBalance(address account, uint128 value) internal virtual { unchecked { _balances[account] += value; } } /** * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update. * * The `auth` argument is optional. If the value passed is non 0, then this function will check that * `auth` is either the owner of the token, or approved to operate on the token (by the owner). * * Emits a {Transfer} event. * * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}. */ function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) { address from = _ownerOf(tokenId); // Perform (optional) operator check if (auth != address(0)) { _checkAuthorized(from, auth, tokenId); } // Execute the update if (from != address(0)) { // Clear approval. No need to re-authorize or emit the Approval event _approve(address(0), tokenId, address(0), false); unchecked { _balances[from] -= 1; } } if (to != address(0)) { unchecked { _balances[to] += 1; } } _owners[tokenId] = to; emit Transfer(from, to, tokenId); return from; } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner != address(0)) { revert ERC721InvalidSender(address(0)); } } /** * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { _mint(to, tokenId); _checkOnERC721Received(address(0), to, tokenId, data); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal { address previousOwner = _update(address(0), tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } else if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients * are aware of the ERC721 standard to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is like {safeTransferFrom} in the sense that it invokes * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `tokenId` token must exist and be owned by `from`. * - `to` cannot be the zero address. * - `from` cannot be the zero address. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId) internal { _safeTransfer(from, to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); _checkOnERC721Received(from, to, tokenId, data); } /** * @dev Approve `to` to operate on `tokenId` * * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is * either the owner of the token, or approved to operate on all tokens held by this owner. * * Emits an {Approval} event. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address to, uint256 tokenId, address auth) internal { _approve(to, tokenId, auth, true); } /** * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not * emitted in the context of transfers. */ function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual { // Avoid reading the owner unless necessary if (emitEvent || auth != address(0)) { address owner = _requireOwned(tokenId); // We do not use _isAuthorized because single-token approvals should not be able to call approve if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) { revert ERC721InvalidApprover(auth); } if (emitEvent) { emit Approval(owner, to, tokenId); } } _tokenApprovals[tokenId] = to; } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Requirements: * - operator can't be the address zero. * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { if (operator == address(0)) { revert ERC721InvalidOperator(operator); } _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned). * Returns the owner. * * Overrides to ownership logic should be done to {_ownerOf}. */ function _requireOwned(uint256 tokenId) internal view returns (address) { address owner = _ownerOf(tokenId); if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } return owner; } /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. This will revert if the * recipient doesn't accept the token transfer. The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call */ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private { if (to.code.length > 0) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { if (retval != IERC721Receiver.onERC721Received.selector) { revert ERC721InvalidReceiver(to); } } catch (bytes memory reason) { if (reason.length == 0) { revert ERC721InvalidReceiver(to); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: @openzeppelin/contracts/access/IAccessControl.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol) pragma solidity ^0.8.20; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev The `account` is missing a role. */ error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); /** * @dev The caller of a function is not the expected one. * * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}. */ error AccessControlBadConfirmation(); /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `callerConfirmation`. */ function renounceRole(bytes32 role, address callerConfirmation) external; } // File: @openzeppelin/contracts/access/AccessControl.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol) pragma solidity ^0.8.20; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ```solidity * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address account => bool) hasRole; bytes32 adminRole; } mapping(bytes32 role => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with an {AccessControlUnauthorizedAccount} error including the required role. */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual returns (bool) { return _roles[role].hasRole[account]; } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()` * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier. */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account` * is missing `role`. */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert AccessControlUnauthorizedAccount(account, role); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `callerConfirmation`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address callerConfirmation) public virtual { if (callerConfirmation != _msgSender()) { revert AccessControlBadConfirmation(); } _revokeRole(role, callerConfirmation); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual returns (bool) { if (!hasRole(role, account)) { _roles[role].hasRole[account] = true; emit RoleGranted(role, account, _msgSender()); return true; } else { return false; } } /** * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual returns (bool) { if (hasRole(role, account)) { _roles[role].hasRole[account] = false; emit RoleRevoked(role, account, _msgSender()); return true; } else { return false; } } } // File: @openzeppelin/contracts/utils/Counters.sol // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } // File: @openzeppelin/contracts/interfaces/IERC2981.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.20; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) external view returns (address receiver, uint256 royaltyAmount); } // File: Fight4HopeNFT.sol pragma solidity ^0.8.20; contract RoyaltyContract is ERC721, Ownable, AccessControl, IERC2981 { using Counters for Counters.Counter; // State variables Counters.Counter private _tokenIds; bool public whitelistActive = true; uint256 public mintPrice; string public baseURI; address public feeWallet; uint256 public maxSupply; address payable public royaltyRecipient; uint256 public royaltyPercentage; // Percentage in basis points (e.g., 500 = 5%) // Whitelist mapping mapping(address => bool) public whitelist; // Track minted status for each address mapping(address => bool) public hasMinted; // Owner role identifier bytes32 public constant OWNER_ROLE = keccak256("OWNER_ROLE"); // Events event WhitelistToggled(bool active); event PriceChanged(uint256 newPrice); event FeeWalletChanged(address newFeeWallet); event WhitelistAdded(address indexed account); event WhitelistRemoved(address indexed account); event BaseURISet(string newBaseURI); constructor( string memory name, string memory symbol, address _secondOwner, address _feeWallet, uint256 _maxSupply, string memory _baseUri, address payable _royaltyRecipient, uint256 _royaltyPercentage ) ERC721(name, symbol) Ownable(msg.sender) { require(_royaltyPercentage <= 10000, "Fee exceeds 100%"); maxSupply = _maxSupply; feeWallet = _feeWallet; baseURI = _baseUri; _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); _grantRole(OWNER_ROLE, msg.sender); _grantRole(OWNER_ROLE, _secondOwner); royaltyRecipient = _royaltyRecipient; royaltyPercentage = _royaltyPercentage; } // Modifier to check if the caller is one of the owners modifier onlyOwners() { require(hasRole(OWNER_ROLE, msg.sender), "Not an owner"); _; } // Function to set the base URI function setBaseURI(string memory newBaseURI) external onlyOwners { baseURI = newBaseURI; emit BaseURISet(newBaseURI); } // Function to set the fee wallet function setFeeWallet(address newFeeWallet) external onlyOwners { require(newFeeWallet != address(0), "Invalid address"); feeWallet = newFeeWallet; emit FeeWalletChanged(newFeeWallet); } // Toggle whitelist on/off and adjust mint price function toggleWhitelist(bool status) external onlyOwners { whitelistActive = status; emit WhitelistToggled(status); } // Set minting price (only when whitelist is active) function setMintPrice(uint256 newPrice) external onlyOwners { mintPrice = newPrice; emit PriceChanged(newPrice); } // Add address to whitelist function addWhitelist(address _address) external onlyOwners { whitelist[_address] = true; emit WhitelistAdded(_address); } // Remove address from whitelist function removeWhitelist(address _address) external onlyOwners { whitelist[_address] = false; emit WhitelistRemoved(_address); } // Internal function to return the base URI function _baseURI() internal view virtual override returns (string memory) { return baseURI; } // Mint function function mint() external payable { require(_tokenIds.current() < maxSupply, "Max supply reached"); require(!hasMinted[msg.sender], "You have already minted an NFT"); // Ensure the address hasn't minted before require(msg.value >= mintPrice, "Insufficient payment"); // Check whitelist if active if (whitelistActive) { require(whitelist[msg.sender], "Not whitelisted"); } // Mint the NFT _tokenIds.increment(); uint256 newItemId = _tokenIds.current(); // Mark the address as having minted hasMinted[msg.sender] = true; if (mintPrice > 0) { payable(feeWallet).transfer(msg.value); } _safeMint(msg.sender, newItemId); } // Override tokenURI to concatenate base URI with token ID function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require( ownerOf(tokenId) != address(0), "ERC721Metadata: URI query for nonexistent token" ); string memory base = _baseURI(); return bytes(base).length > 0 ? string( abi.encodePacked(base, Strings.toString(tokenId), ".json") ) : ""; } // Override supportsInterface function for ERC721, AccessControl, and IERC2981 function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721,IERC165, AccessControl) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } // Implement royaltyInfo function as per ERC-2981 standard function royaltyInfo( uint256, // tokenId (not used here, same royalty for all tokens) uint256 salePrice ) external view override returns (address receiver, uint256 royaltyAmount) { uint256 amount = (salePrice * royaltyPercentage) / 10000; return (royaltyRecipient, amount); } // Function to update royalty info function setRoyaltyInfo(address payable newRecipient, uint256 newPercentage) external onlyOwners { require(newPercentage <= 10000, "Royalty exceeds 100%"); royaltyRecipient = newRecipient; royaltyPercentage = newPercentage; } }
[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"_secondOwner","type":"address"},{"internalType":"address","name":"_feeWallet","type":"address"},{"internalType":"uint256","name":"_maxSupply","type":"uint256"},{"internalType":"string","name":"_baseUri","type":"string"},{"internalType":"address payable","name":"_royaltyRecipient","type":"address"},{"internalType":"uint256","name":"_royaltyPercentage","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"newBaseURI","type":"string"}],"name":"BaseURISet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newFeeWallet","type":"address"}],"name":"FeeWalletChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"PriceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"WhitelistAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"WhitelistRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"active","type":"bool"}],"name":"WhitelistToggled","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OWNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"addWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasMinted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"removeWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyRecipient","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newFeeWallet","type":"address"}],"name":"setFeeWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newRecipient","type":"address"},{"internalType":"uint256","name":"newPercentage","type":"uint256"}],"name":"setRoyaltyInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"status","type":"bool"}],"name":"toggleWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040526001600960006101000a81548160ff02191690831515021790555034801561002b57600080fd5b50604051614c91380380614c91833981810160405281019061004d91906106da565b338888816000908161005f91906109fb565b50806001908161006f91906109fb565b505050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100e45760006040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016100db9190610adc565b60405180910390fd5b6100f38161025c60201b60201c565b50612710811115610139576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161013090610b54565b60405180910390fd5b83600d8190555084600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600b908161019091906109fb565b506101a46000801b3361032260201b60201c565b506101d57fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e3361032260201b60201c565b506102067fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e8761032260201b60201c565b5081600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600f819055505050505050505050610b74565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000610334838361042060201b60201c565b6104155760016007600085815260200190815260200160002060000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506103b261048b60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a46001905061041a565b600090505b92915050565b60006007600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6104fa826104b1565b810181811067ffffffffffffffff82111715610519576105186104c2565b5b80604052505050565b600061052c610493565b905061053882826104f1565b919050565b600067ffffffffffffffff821115610558576105576104c2565b5b610561826104b1565b9050602081019050919050565b60005b8381101561058c578082015181840152602081019050610571565b60008484015250505050565b60006105ab6105a68461053d565b610522565b9050828152602081018484840111156105c7576105c66104ac565b5b6105d284828561056e565b509392505050565b600082601f8301126105ef576105ee6104a7565b5b81516105ff848260208601610598565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061063382610608565b9050919050565b61064381610628565b811461064e57600080fd5b50565b6000815190506106608161063a565b92915050565b6000819050919050565b61067981610666565b811461068457600080fd5b50565b60008151905061069681610670565b92915050565b60006106a782610608565b9050919050565b6106b78161069c565b81146106c257600080fd5b50565b6000815190506106d4816106ae565b92915050565b600080600080600080600080610100898b0312156106fb576106fa61049d565b5b600089015167ffffffffffffffff811115610719576107186104a2565b5b6107258b828c016105da565b985050602089015167ffffffffffffffff811115610746576107456104a2565b5b6107528b828c016105da565b97505060406107638b828c01610651565b96505060606107748b828c01610651565b95505060806107858b828c01610687565b94505060a089015167ffffffffffffffff8111156107a6576107a56104a2565b5b6107b28b828c016105da565b93505060c06107c38b828c016106c5565b92505060e06107d48b828c01610687565b9150509295985092959890939650565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061083657607f821691505b602082108103610849576108486107ef565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026108b17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610874565b6108bb8683610874565b95508019841693508086168417925050509392505050565b6000819050919050565b60006108f86108f36108ee84610666565b6108d3565b610666565b9050919050565b6000819050919050565b610912836108dd565b61092661091e826108ff565b848454610881565b825550505050565b600090565b61093b61092e565b610946818484610909565b505050565b5b8181101561096a5761095f600082610933565b60018101905061094c565b5050565b601f8211156109af576109808161084f565b61098984610864565b81016020851015610998578190505b6109ac6109a485610864565b83018261094b565b50505b505050565b600082821c905092915050565b60006109d2600019846008026109b4565b1980831691505092915050565b60006109eb83836109c1565b9150826002028217905092915050565b610a04826107e4565b67ffffffffffffffff811115610a1d57610a1c6104c2565b5b610a27825461081e565b610a3282828561096e565b600060209050601f831160018114610a655760008415610a53578287015190505b610a5d85826109df565b865550610ac5565b601f198416610a738661084f565b60005b82811015610a9b57848901518255600182019150602085019450602081019050610a76565b86831015610ab85784890151610ab4601f8916826109c1565b8355505b6001600288020188555050505b505050505050565b610ad681610628565b82525050565b6000602082019050610af16000830184610acd565b92915050565b600082825260208201905092915050565b7f4665652065786365656473203130302500000000000000000000000000000000600082015250565b6000610b3e601083610af7565b9150610b4982610b08565b602082019050919050565b60006020820190508181036000830152610b6d81610b31565b9050919050565b61410e80610b836000396000f3fe6080604052600436106102465760003560e01c806378c8cda711610139578063b88d4fde116100b6578063e58378bb1161007a578063e58378bb14610892578063e985e9c5146108bd578063f25f4b56146108fa578063f2fde38b14610925578063f4a0a5281461094e578063f80f5dd51461097757610246565b8063b88d4fde146107af578063c87b56dd146107d8578063d547741f14610815578063d5abeb011461083e578063e2e784d51461086957610246565b806391d14854116100fd57806391d14854146106b657806395d89b41146106f35780639b19251a1461071e578063a217fddf1461075b578063a22cb4651461078657610246565b806378c8cda7146105e557806380e3f1ad1461060e5780638a71bb2d146106375780638da5cb5b1461066257806390d49b9d1461068d57610246565b806336568abe116101c75780636352211e1161018b5780636352211e146104fe5780636817c76c1461053b5780636c0360eb1461056657806370a0823114610591578063715018a6146105ce57610246565b806336568abe1461041b57806338e21cce1461044457806342842e0e146104815780634c00de82146104aa57806355f804b3146104d557610246565b80631249c58b1161020e5780631249c58b1461034457806323b872dd1461034e578063248a9ca3146103775780632a55205a146103b45780632f2ff15d146103f257610246565b806301ffc9a71461024b57806302ce58131461028857806306fdde03146102b3578063081812fc146102de578063095ea7b31461031b575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d9190612f66565b6109a0565b60405161027f9190612fae565b60405180910390f35b34801561029457600080fd5b5061029d610a1a565b6040516102aa9190612fae565b60405180910390f35b3480156102bf57600080fd5b506102c8610a2d565b6040516102d59190613059565b60405180910390f35b3480156102ea57600080fd5b50610305600480360381019061030091906130b1565b610abf565b604051610312919061311f565b60405180910390f35b34801561032757600080fd5b50610342600480360381019061033d9190613166565b610adb565b005b61034c610af1565b005b34801561035a57600080fd5b50610375600480360381019061037091906131a6565b610da4565b005b34801561038357600080fd5b5061039e6004803603810190610399919061322f565b610ea6565b6040516103ab919061326b565b60405180910390f35b3480156103c057600080fd5b506103db60048036038101906103d69190613286565b610ec6565b6040516103e99291906132d5565b60405180910390f35b3480156103fe57600080fd5b50610419600480360381019061041491906132fe565b610f18565b005b34801561042757600080fd5b50610442600480360381019061043d91906132fe565b610f3a565b005b34801561045057600080fd5b5061046b6004803603810190610466919061333e565b610fb5565b6040516104789190612fae565b60405180910390f35b34801561048d57600080fd5b506104a860048036038101906104a391906131a6565b610fd5565b005b3480156104b657600080fd5b506104bf610ff5565b6040516104cc919061338c565b60405180910390f35b3480156104e157600080fd5b506104fc60048036038101906104f791906134dc565b61101b565b005b34801561050a57600080fd5b50610525600480360381019061052091906130b1565b6110ce565b604051610532919061311f565b60405180910390f35b34801561054757600080fd5b506105506110e0565b60405161055d9190613525565b60405180910390f35b34801561057257600080fd5b5061057b6110e6565b6040516105889190613059565b60405180910390f35b34801561059d57600080fd5b506105b860048036038101906105b3919061333e565b611174565b6040516105c59190613525565b60405180910390f35b3480156105da57600080fd5b506105e361122e565b005b3480156105f157600080fd5b5061060c6004803603810190610607919061333e565b611242565b005b34801561061a57600080fd5b506106356004803603810190610630919061356c565b611349565b005b34801561064357600080fd5b5061064c611406565b6040516106599190613525565b60405180910390f35b34801561066e57600080fd5b5061067761140c565b604051610684919061311f565b60405180910390f35b34801561069957600080fd5b506106b460048036038101906106af919061333e565b611436565b005b3480156106c257600080fd5b506106dd60048036038101906106d891906132fe565b611589565b6040516106ea9190612fae565b60405180910390f35b3480156106ff57600080fd5b506107086115f4565b6040516107159190613059565b60405180910390f35b34801561072a57600080fd5b506107456004803603810190610740919061333e565b611686565b6040516107529190612fae565b60405180910390f35b34801561076757600080fd5b506107706116a6565b60405161077d919061326b565b60405180910390f35b34801561079257600080fd5b506107ad60048036038101906107a89190613599565b6116ad565b005b3480156107bb57600080fd5b506107d660048036038101906107d1919061367a565b6116c3565b005b3480156107e457600080fd5b506107ff60048036038101906107fa91906130b1565b6116e0565b60405161080c9190613059565b60405180910390f35b34801561082157600080fd5b5061083c600480360381019061083791906132fe565b6117b6565b005b34801561084a57600080fd5b506108536117d8565b6040516108609190613525565b60405180910390f35b34801561087557600080fd5b50610890600480360381019061088b9190613729565b6117de565b005b34801561089e57600080fd5b506108a76118d8565b6040516108b4919061326b565b60405180910390f35b3480156108c957600080fd5b506108e460048036038101906108df9190613769565b6118fc565b6040516108f19190612fae565b60405180910390f35b34801561090657600080fd5b5061090f611990565b60405161091c919061311f565b60405180910390f35b34801561093157600080fd5b5061094c6004803603810190610947919061333e565b6119b6565b005b34801561095a57600080fd5b50610975600480360381019061097091906130b1565b611a3c565b005b34801561098357600080fd5b5061099e6004803603810190610999919061333e565b611ae6565b005b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a135750610a1282611bed565b5b9050919050565b600960009054906101000a900460ff1681565b606060008054610a3c906137d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610a68906137d8565b8015610ab55780601f10610a8a57610100808354040283529160200191610ab5565b820191906000526020600020905b815481529060010190602001808311610a9857829003601f168201915b5050505050905090565b6000610aca82611c67565b50610ad482611cef565b9050919050565b610aed8282610ae8611d2c565b611d34565b5050565b600d54610afe6008611d46565b10610b3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3590613855565b60405180910390fd5b601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615610bcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc2906138c1565b60405180910390fd5b600a54341015610c10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c079061392d565b60405180910390fd5b600960009054906101000a900460ff1615610cb257601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610cb1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca890613999565b60405180910390fd5b5b610cbc6008611d54565b6000610cc86008611d46565b90506001601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506000600a541115610d9757600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f19350505050158015610d95573d6000803e3d6000fd5b505b610da13382611d6a565b50565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610e165760006040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610e0d919061311f565b60405180910390fd5b6000610e2a8383610e25611d2c565b611d88565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ea0578382826040517f64283d7b000000000000000000000000000000000000000000000000000000008152600401610e97939291906139b9565b60405180910390fd5b50505050565b600060076000838152602001908152602001600020600101549050919050565b6000806000612710600f5485610edc9190613a1f565b610ee69190613a90565b9050600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168192509250509250929050565b610f2182610ea6565b610f2a81611fa2565b610f348383611fb6565b50505050565b610f42611d2c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610fa6576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610fb082826120a8565b505050565b60116020528060005260406000206000915054906101000a900460ff1681565b610ff0838383604051806020016040528060008152506116c3565b505050565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6110457fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e33611589565b611084576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107b90613b0d565b60405180910390fd5b80600b90816110939190613cd9565b507ff9c7803e94e0d3c02900d8a90893a6d5e90dd04d32a4cfe825520f82bf9f32f6816040516110c39190613059565b60405180910390a150565b60006110d982611c67565b9050919050565b600a5481565b600b80546110f3906137d8565b80601f016020809104026020016040519081016040528092919081815260200182805461111f906137d8565b801561116c5780601f106111415761010080835404028352916020019161116c565b820191906000526020600020905b81548152906001019060200180831161114f57829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036111e75760006040517f89c62b640000000000000000000000000000000000000000000000000000000081526004016111de919061311f565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61123661219b565b6112406000612222565b565b61126c7fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e33611589565b6112ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112a290613b0d565b60405180910390fd5b6000601060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167fde8cf212af7ce38b2840785a2768d97ff2dbf3c21b516961cec0061e134c2a1e60405160405180910390a250565b6113737fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e33611589565b6113b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a990613b0d565b60405180910390fd5b80600960006101000a81548160ff0219169083151502179055507fc816dd38770d8cbe6a8fb169cb4961c28b697d528ebfd3c353ab8f74e82f1f9a816040516113fb9190612fae565b60405180910390a150565b600f5481565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6114607fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e33611589565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149690613b0d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361150e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161150590613df7565b60405180910390fd5b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fe805ffc02a12d27b142431551e2cd3f766203c54a9a4ab0d1cf01ce7366a796f8160405161157e919061311f565b60405180910390a150565b60006007600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060018054611603906137d8565b80601f016020809104026020016040519081016040528092919081815260200182805461162f906137d8565b801561167c5780601f106116515761010080835404028352916020019161167c565b820191906000526020600020905b81548152906001019060200180831161165f57829003601f168201915b5050505050905090565b60106020528060005260406000206000915054906101000a900460ff1681565b6000801b81565b6116bf6116b8611d2c565b83836122e8565b5050565b6116ce848484610da4565b6116da84848484612457565b50505050565b6060600073ffffffffffffffffffffffffffffffffffffffff16611703836110ce565b73ffffffffffffffffffffffffffffffffffffffff1603611759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161175090613e89565b60405180910390fd5b600061176361260e565b9050600081511161178357604051806020016040528060008152506117ae565b8061178d846126a0565b60405160200161179e929190613f31565b6040516020818303038152906040525b915050919050565b6117bf82610ea6565b6117c881611fa2565b6117d283836120a8565b50505050565b600d5481565b6118087fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e33611589565b611847576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183e90613b0d565b60405180910390fd5b61271081111561188c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188390613fac565b60405180910390fd5b81600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600f819055505050565b7fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e81565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6119be61219b565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611a305760006040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401611a27919061311f565b60405180910390fd5b611a3981612222565b50565b611a667fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e33611589565b611aa5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9c90613b0d565b60405180910390fd5b80600a819055507fa6dc15bdb68da224c66db4b3838d9a2b205138e8cff6774e57d0af91e196d62281604051611adb9190613525565b60405180910390a150565b611b107fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e33611589565b611b4f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4690613b0d565b60405180910390fd5b6001601060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f4790a4adb426ca2345bb5108f6e454eae852a7bf687544cd66a7270dff3a41d660405160405180910390a250565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611c605750611c5f8261276e565b5b9050919050565b600080611c7383612850565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ce657826040517f7e273289000000000000000000000000000000000000000000000000000000008152600401611cdd9190613525565b60405180910390fd5b80915050919050565b60006004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600033905090565b611d41838383600161288d565b505050565b600081600001549050919050565b6001816000016000828254019250508190555050565b611d84828260405180602001604052806000815250612a52565b5050565b600080611d9484612850565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611dd657611dd5818486612a6e565b5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611e6757611e1860008560008061288d565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611eea576001600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b846002600086815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b611fb381611fae611d2c565b612b32565b50565b6000611fc28383611589565b61209d5760016007600085815260200190815260200160002060000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061203a611d2c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4600190506120a2565b600090505b92915050565b60006120b48383611589565b156121905760006007600085815260200190815260200160002060000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061212d611d2c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019050612195565b600090505b92915050565b6121a3611d2c565b73ffffffffffffffffffffffffffffffffffffffff166121c161140c565b73ffffffffffffffffffffffffffffffffffffffff1614612220576121e4611d2c565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401612217919061311f565b60405180910390fd5b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361235957816040517f5b08ba18000000000000000000000000000000000000000000000000000000008152600401612350919061311f565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161244a9190612fae565b60405180910390a3505050565b60008373ffffffffffffffffffffffffffffffffffffffff163b1115612608578273ffffffffffffffffffffffffffffffffffffffff1663150b7a0261249b611d2c565b8685856040518563ffffffff1660e01b81526004016124bd9493929190614021565b6020604051808303816000875af19250505080156124f957506040513d601f19601f820116820180604052508101906124f69190614082565b60015b61257d573d8060008114612529576040519150601f19603f3d011682016040523d82523d6000602084013e61252e565b606091505b50600081510361257557836040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161256c919061311f565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461260657836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016125fd919061311f565b60405180910390fd5b505b50505050565b6060600b805461261d906137d8565b80601f0160208091040260200160405190810160405280929190818152602001828054612649906137d8565b80156126965780601f1061266b57610100808354040283529160200191612696565b820191906000526020600020905b81548152906001019060200180831161267957829003601f168201915b5050505050905090565b6060600060016126af84612b83565b01905060008167ffffffffffffffff8111156126ce576126cd6133b1565b5b6040519080825280601f01601f1916602001820160405280156127005781602001600182028036833780820191505090505b509050600082602001820190505b600115612763578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161275757612756613a61565b5b0494506000850361270e575b819350505050919050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061283957507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80612849575061284882612cd6565b5b9050919050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b80806128c65750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156129fa5760006128d684611c67565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561294157508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015612954575061295281846118fc565b155b1561299657826040517fa9fbf51f00000000000000000000000000000000000000000000000000000000815260040161298d919061311f565b60405180910390fd5b81156129f857838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b836004600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b612a5c8383612d40565b612a696000848484612457565b505050565b612a79838383612e39565b612b2d57600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612aee57806040517f7e273289000000000000000000000000000000000000000000000000000000008152600401612ae59190613525565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401612b249291906132d5565b60405180910390fd5b505050565b612b3c8282611589565b612b7f5780826040517fe2517d3f000000000000000000000000000000000000000000000000000000008152600401612b769291906140af565b60405180910390fd5b5050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612be1577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612bd757612bd6613a61565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612c1e576d04ee2d6d415b85acef81000000008381612c1457612c13613a61565b5b0492506020810190505b662386f26fc100008310612c4d57662386f26fc100008381612c4357612c42613a61565b5b0492506010810190505b6305f5e1008310612c76576305f5e1008381612c6c57612c6b613a61565b5b0492506008810190505b6127108310612c9b576127108381612c9157612c90613a61565b5b0492506004810190505b60648310612cbe5760648381612cb457612cb3613a61565b5b0492506002810190505b600a8310612ccd576001810190505b80915050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612db25760006040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401612da9919061311f565b60405180910390fd5b6000612dc083836000611d88565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612e345760006040517f73c6ac6e000000000000000000000000000000000000000000000000000000008152600401612e2b919061311f565b60405180910390fd5b505050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015612ef157508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612eb25750612eb184846118fc565b5b80612ef057508273ffffffffffffffffffffffffffffffffffffffff16612ed883611cef565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612f4381612f0e565b8114612f4e57600080fd5b50565b600081359050612f6081612f3a565b92915050565b600060208284031215612f7c57612f7b612f04565b5b6000612f8a84828501612f51565b91505092915050565b60008115159050919050565b612fa881612f93565b82525050565b6000602082019050612fc36000830184612f9f565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613003578082015181840152602081019050612fe8565b60008484015250505050565b6000601f19601f8301169050919050565b600061302b82612fc9565b6130358185612fd4565b9350613045818560208601612fe5565b61304e8161300f565b840191505092915050565b600060208201905081810360008301526130738184613020565b905092915050565b6000819050919050565b61308e8161307b565b811461309957600080fd5b50565b6000813590506130ab81613085565b92915050565b6000602082840312156130c7576130c6612f04565b5b60006130d58482850161309c565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613109826130de565b9050919050565b613119816130fe565b82525050565b60006020820190506131346000830184613110565b92915050565b613143816130fe565b811461314e57600080fd5b50565b6000813590506131608161313a565b92915050565b6000806040838503121561317d5761317c612f04565b5b600061318b85828601613151565b925050602061319c8582860161309c565b9150509250929050565b6000806000606084860312156131bf576131be612f04565b5b60006131cd86828701613151565b93505060206131de86828701613151565b92505060406131ef8682870161309c565b9150509250925092565b6000819050919050565b61320c816131f9565b811461321757600080fd5b50565b60008135905061322981613203565b92915050565b60006020828403121561324557613244612f04565b5b60006132538482850161321a565b91505092915050565b613265816131f9565b82525050565b6000602082019050613280600083018461325c565b92915050565b6000806040838503121561329d5761329c612f04565b5b60006132ab8582860161309c565b92505060206132bc8582860161309c565b9150509250929050565b6132cf8161307b565b82525050565b60006040820190506132ea6000830185613110565b6132f760208301846132c6565b9392505050565b6000806040838503121561331557613314612f04565b5b60006133238582860161321a565b925050602061333485828601613151565b9150509250929050565b60006020828403121561335457613353612f04565b5b600061336284828501613151565b91505092915050565b6000613376826130de565b9050919050565b6133868161336b565b82525050565b60006020820190506133a1600083018461337d565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6133e98261300f565b810181811067ffffffffffffffff82111715613408576134076133b1565b5b80604052505050565b600061341b612efa565b905061342782826133e0565b919050565b600067ffffffffffffffff821115613447576134466133b1565b5b6134508261300f565b9050602081019050919050565b82818337600083830152505050565b600061347f61347a8461342c565b613411565b90508281526020810184848401111561349b5761349a6133ac565b5b6134a684828561345d565b509392505050565b600082601f8301126134c3576134c26133a7565b5b81356134d384826020860161346c565b91505092915050565b6000602082840312156134f2576134f1612f04565b5b600082013567ffffffffffffffff8111156135105761350f612f09565b5b61351c848285016134ae565b91505092915050565b600060208201905061353a60008301846132c6565b92915050565b61354981612f93565b811461355457600080fd5b50565b60008135905061356681613540565b92915050565b60006020828403121561358257613581612f04565b5b600061359084828501613557565b91505092915050565b600080604083850312156135b0576135af612f04565b5b60006135be85828601613151565b92505060206135cf85828601613557565b9150509250929050565b600067ffffffffffffffff8211156135f4576135f36133b1565b5b6135fd8261300f565b9050602081019050919050565b600061361d613618846135d9565b613411565b905082815260208101848484011115613639576136386133ac565b5b61364484828561345d565b509392505050565b600082601f830112613661576136606133a7565b5b813561367184826020860161360a565b91505092915050565b6000806000806080858703121561369457613693612f04565b5b60006136a287828801613151565b94505060206136b387828801613151565b93505060406136c48782880161309c565b925050606085013567ffffffffffffffff8111156136e5576136e4612f09565b5b6136f18782880161364c565b91505092959194509250565b6137068161336b565b811461371157600080fd5b50565b600081359050613723816136fd565b92915050565b600080604083850312156137405761373f612f04565b5b600061374e85828601613714565b925050602061375f8582860161309c565b9150509250929050565b600080604083850312156137805761377f612f04565b5b600061378e85828601613151565b925050602061379f85828601613151565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806137f057607f821691505b602082108103613803576138026137a9565b5b50919050565b7f4d617820737570706c7920726561636865640000000000000000000000000000600082015250565b600061383f601283612fd4565b915061384a82613809565b602082019050919050565b6000602082019050818103600083015261386e81613832565b9050919050565b7f596f75206861766520616c7265616479206d696e74656420616e204e46540000600082015250565b60006138ab601e83612fd4565b91506138b682613875565b602082019050919050565b600060208201905081810360008301526138da8161389e565b9050919050565b7f496e73756666696369656e74207061796d656e74000000000000000000000000600082015250565b6000613917601483612fd4565b9150613922826138e1565b602082019050919050565b600060208201905081810360008301526139468161390a565b9050919050565b7f4e6f742077686974656c69737465640000000000000000000000000000000000600082015250565b6000613983600f83612fd4565b915061398e8261394d565b602082019050919050565b600060208201905081810360008301526139b281613976565b9050919050565b60006060820190506139ce6000830186613110565b6139db60208301856132c6565b6139e86040830184613110565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613a2a8261307b565b9150613a358361307b565b9250828202613a438161307b565b91508282048414831517613a5a57613a596139f0565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613a9b8261307b565b9150613aa68361307b565b925082613ab657613ab5613a61565b5b828204905092915050565b7f4e6f7420616e206f776e65720000000000000000000000000000000000000000600082015250565b6000613af7600c83612fd4565b9150613b0282613ac1565b602082019050919050565b60006020820190508181036000830152613b2681613aea565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613b8f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613b52565b613b998683613b52565b95508019841693508086168417925050509392505050565b6000819050919050565b6000613bd6613bd1613bcc8461307b565b613bb1565b61307b565b9050919050565b6000819050919050565b613bf083613bbb565b613c04613bfc82613bdd565b848454613b5f565b825550505050565b600090565b613c19613c0c565b613c24818484613be7565b505050565b5b81811015613c4857613c3d600082613c11565b600181019050613c2a565b5050565b601f821115613c8d57613c5e81613b2d565b613c6784613b42565b81016020851015613c76578190505b613c8a613c8285613b42565b830182613c29565b50505b505050565b600082821c905092915050565b6000613cb060001984600802613c92565b1980831691505092915050565b6000613cc98383613c9f565b9150826002028217905092915050565b613ce282612fc9565b67ffffffffffffffff811115613cfb57613cfa6133b1565b5b613d0582546137d8565b613d10828285613c4c565b600060209050601f831160018114613d435760008415613d31578287015190505b613d3b8582613cbd565b865550613da3565b601f198416613d5186613b2d565b60005b82811015613d7957848901518255600182019150602085019450602081019050613d54565b86831015613d965784890151613d92601f891682613c9f565b8355505b6001600288020188555050505b505050505050565b7f496e76616c696420616464726573730000000000000000000000000000000000600082015250565b6000613de1600f83612fd4565b9150613dec82613dab565b602082019050919050565b60006020820190508181036000830152613e1081613dd4565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000613e73602f83612fd4565b9150613e7e82613e17565b604082019050919050565b60006020820190508181036000830152613ea281613e66565b9050919050565b600081905092915050565b6000613ebf82612fc9565b613ec98185613ea9565b9350613ed9818560208601612fe5565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000613f1b600583613ea9565b9150613f2682613ee5565b600582019050919050565b6000613f3d8285613eb4565b9150613f498284613eb4565b9150613f5482613f0e565b91508190509392505050565b7f526f79616c747920657863656564732031303025000000000000000000000000600082015250565b6000613f96601483612fd4565b9150613fa182613f60565b602082019050919050565b60006020820190508181036000830152613fc581613f89565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000613ff382613fcc565b613ffd8185613fd7565b935061400d818560208601612fe5565b6140168161300f565b840191505092915050565b60006080820190506140366000830187613110565b6140436020830186613110565b61405060408301856132c6565b81810360608301526140628184613fe8565b905095945050505050565b60008151905061407c81612f3a565b92915050565b60006020828403121561409857614097612f04565b5b60006140a68482850161406d565b91505092915050565b60006040820190506140c46000830185613110565b6140d1602083018461325c565b939250505056fea2646970667358221220552f6ac2ff539f540c6619e53d3fb02c3086f2f016d68b0be440973618904f9764736f6c634300081a003300000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000d302f9aa2a57ea2516835a6e36cc168ae0365b37000000000000000000000000c91541d3cd68cd0bb6749f0874a61e41e399f5f500000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000000180000000000000000000000000c9289e3167313abe2628de5b509d66e0ef7ee2a30000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000f526f79616c7479436f6e7472616374000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025243000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002768747470733a2f2f697066732e6172626f726e66742e696f2f666967687434686f70652f66346800000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106102465760003560e01c806378c8cda711610139578063b88d4fde116100b6578063e58378bb1161007a578063e58378bb14610892578063e985e9c5146108bd578063f25f4b56146108fa578063f2fde38b14610925578063f4a0a5281461094e578063f80f5dd51461097757610246565b8063b88d4fde146107af578063c87b56dd146107d8578063d547741f14610815578063d5abeb011461083e578063e2e784d51461086957610246565b806391d14854116100fd57806391d14854146106b657806395d89b41146106f35780639b19251a1461071e578063a217fddf1461075b578063a22cb4651461078657610246565b806378c8cda7146105e557806380e3f1ad1461060e5780638a71bb2d146106375780638da5cb5b1461066257806390d49b9d1461068d57610246565b806336568abe116101c75780636352211e1161018b5780636352211e146104fe5780636817c76c1461053b5780636c0360eb1461056657806370a0823114610591578063715018a6146105ce57610246565b806336568abe1461041b57806338e21cce1461044457806342842e0e146104815780634c00de82146104aa57806355f804b3146104d557610246565b80631249c58b1161020e5780631249c58b1461034457806323b872dd1461034e578063248a9ca3146103775780632a55205a146103b45780632f2ff15d146103f257610246565b806301ffc9a71461024b57806302ce58131461028857806306fdde03146102b3578063081812fc146102de578063095ea7b31461031b575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d9190612f66565b6109a0565b60405161027f9190612fae565b60405180910390f35b34801561029457600080fd5b5061029d610a1a565b6040516102aa9190612fae565b60405180910390f35b3480156102bf57600080fd5b506102c8610a2d565b6040516102d59190613059565b60405180910390f35b3480156102ea57600080fd5b50610305600480360381019061030091906130b1565b610abf565b604051610312919061311f565b60405180910390f35b34801561032757600080fd5b50610342600480360381019061033d9190613166565b610adb565b005b61034c610af1565b005b34801561035a57600080fd5b50610375600480360381019061037091906131a6565b610da4565b005b34801561038357600080fd5b5061039e6004803603810190610399919061322f565b610ea6565b6040516103ab919061326b565b60405180910390f35b3480156103c057600080fd5b506103db60048036038101906103d69190613286565b610ec6565b6040516103e99291906132d5565b60405180910390f35b3480156103fe57600080fd5b50610419600480360381019061041491906132fe565b610f18565b005b34801561042757600080fd5b50610442600480360381019061043d91906132fe565b610f3a565b005b34801561045057600080fd5b5061046b6004803603810190610466919061333e565b610fb5565b6040516104789190612fae565b60405180910390f35b34801561048d57600080fd5b506104a860048036038101906104a391906131a6565b610fd5565b005b3480156104b657600080fd5b506104bf610ff5565b6040516104cc919061338c565b60405180910390f35b3480156104e157600080fd5b506104fc60048036038101906104f791906134dc565b61101b565b005b34801561050a57600080fd5b50610525600480360381019061052091906130b1565b6110ce565b604051610532919061311f565b60405180910390f35b34801561054757600080fd5b506105506110e0565b60405161055d9190613525565b60405180910390f35b34801561057257600080fd5b5061057b6110e6565b6040516105889190613059565b60405180910390f35b34801561059d57600080fd5b506105b860048036038101906105b3919061333e565b611174565b6040516105c59190613525565b60405180910390f35b3480156105da57600080fd5b506105e361122e565b005b3480156105f157600080fd5b5061060c6004803603810190610607919061333e565b611242565b005b34801561061a57600080fd5b506106356004803603810190610630919061356c565b611349565b005b34801561064357600080fd5b5061064c611406565b6040516106599190613525565b60405180910390f35b34801561066e57600080fd5b5061067761140c565b604051610684919061311f565b60405180910390f35b34801561069957600080fd5b506106b460048036038101906106af919061333e565b611436565b005b3480156106c257600080fd5b506106dd60048036038101906106d891906132fe565b611589565b6040516106ea9190612fae565b60405180910390f35b3480156106ff57600080fd5b506107086115f4565b6040516107159190613059565b60405180910390f35b34801561072a57600080fd5b506107456004803603810190610740919061333e565b611686565b6040516107529190612fae565b60405180910390f35b34801561076757600080fd5b506107706116a6565b60405161077d919061326b565b60405180910390f35b34801561079257600080fd5b506107ad60048036038101906107a89190613599565b6116ad565b005b3480156107bb57600080fd5b506107d660048036038101906107d1919061367a565b6116c3565b005b3480156107e457600080fd5b506107ff60048036038101906107fa91906130b1565b6116e0565b60405161080c9190613059565b60405180910390f35b34801561082157600080fd5b5061083c600480360381019061083791906132fe565b6117b6565b005b34801561084a57600080fd5b506108536117d8565b6040516108609190613525565b60405180910390f35b34801561087557600080fd5b50610890600480360381019061088b9190613729565b6117de565b005b34801561089e57600080fd5b506108a76118d8565b6040516108b4919061326b565b60405180910390f35b3480156108c957600080fd5b506108e460048036038101906108df9190613769565b6118fc565b6040516108f19190612fae565b60405180910390f35b34801561090657600080fd5b5061090f611990565b60405161091c919061311f565b60405180910390f35b34801561093157600080fd5b5061094c6004803603810190610947919061333e565b6119b6565b005b34801561095a57600080fd5b50610975600480360381019061097091906130b1565b611a3c565b005b34801561098357600080fd5b5061099e6004803603810190610999919061333e565b611ae6565b005b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a135750610a1282611bed565b5b9050919050565b600960009054906101000a900460ff1681565b606060008054610a3c906137d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610a68906137d8565b8015610ab55780601f10610a8a57610100808354040283529160200191610ab5565b820191906000526020600020905b815481529060010190602001808311610a9857829003601f168201915b5050505050905090565b6000610aca82611c67565b50610ad482611cef565b9050919050565b610aed8282610ae8611d2c565b611d34565b5050565b600d54610afe6008611d46565b10610b3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3590613855565b60405180910390fd5b601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615610bcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc2906138c1565b60405180910390fd5b600a54341015610c10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c079061392d565b60405180910390fd5b600960009054906101000a900460ff1615610cb257601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610cb1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca890613999565b60405180910390fd5b5b610cbc6008611d54565b6000610cc86008611d46565b90506001601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506000600a541115610d9757600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f19350505050158015610d95573d6000803e3d6000fd5b505b610da13382611d6a565b50565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610e165760006040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610e0d919061311f565b60405180910390fd5b6000610e2a8383610e25611d2c565b611d88565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ea0578382826040517f64283d7b000000000000000000000000000000000000000000000000000000008152600401610e97939291906139b9565b60405180910390fd5b50505050565b600060076000838152602001908152602001600020600101549050919050565b6000806000612710600f5485610edc9190613a1f565b610ee69190613a90565b9050600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168192509250509250929050565b610f2182610ea6565b610f2a81611fa2565b610f348383611fb6565b50505050565b610f42611d2c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610fa6576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610fb082826120a8565b505050565b60116020528060005260406000206000915054906101000a900460ff1681565b610ff0838383604051806020016040528060008152506116c3565b505050565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6110457fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e33611589565b611084576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107b90613b0d565b60405180910390fd5b80600b90816110939190613cd9565b507ff9c7803e94e0d3c02900d8a90893a6d5e90dd04d32a4cfe825520f82bf9f32f6816040516110c39190613059565b60405180910390a150565b60006110d982611c67565b9050919050565b600a5481565b600b80546110f3906137d8565b80601f016020809104026020016040519081016040528092919081815260200182805461111f906137d8565b801561116c5780601f106111415761010080835404028352916020019161116c565b820191906000526020600020905b81548152906001019060200180831161114f57829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036111e75760006040517f89c62b640000000000000000000000000000000000000000000000000000000081526004016111de919061311f565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61123661219b565b6112406000612222565b565b61126c7fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e33611589565b6112ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112a290613b0d565b60405180910390fd5b6000601060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167fde8cf212af7ce38b2840785a2768d97ff2dbf3c21b516961cec0061e134c2a1e60405160405180910390a250565b6113737fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e33611589565b6113b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a990613b0d565b60405180910390fd5b80600960006101000a81548160ff0219169083151502179055507fc816dd38770d8cbe6a8fb169cb4961c28b697d528ebfd3c353ab8f74e82f1f9a816040516113fb9190612fae565b60405180910390a150565b600f5481565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6114607fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e33611589565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149690613b0d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361150e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161150590613df7565b60405180910390fd5b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fe805ffc02a12d27b142431551e2cd3f766203c54a9a4ab0d1cf01ce7366a796f8160405161157e919061311f565b60405180910390a150565b60006007600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060018054611603906137d8565b80601f016020809104026020016040519081016040528092919081815260200182805461162f906137d8565b801561167c5780601f106116515761010080835404028352916020019161167c565b820191906000526020600020905b81548152906001019060200180831161165f57829003601f168201915b5050505050905090565b60106020528060005260406000206000915054906101000a900460ff1681565b6000801b81565b6116bf6116b8611d2c565b83836122e8565b5050565b6116ce848484610da4565b6116da84848484612457565b50505050565b6060600073ffffffffffffffffffffffffffffffffffffffff16611703836110ce565b73ffffffffffffffffffffffffffffffffffffffff1603611759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161175090613e89565b60405180910390fd5b600061176361260e565b9050600081511161178357604051806020016040528060008152506117ae565b8061178d846126a0565b60405160200161179e929190613f31565b6040516020818303038152906040525b915050919050565b6117bf82610ea6565b6117c881611fa2565b6117d283836120a8565b50505050565b600d5481565b6118087fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e33611589565b611847576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183e90613b0d565b60405180910390fd5b61271081111561188c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188390613fac565b60405180910390fd5b81600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600f819055505050565b7fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e81565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6119be61219b565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611a305760006040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401611a27919061311f565b60405180910390fd5b611a3981612222565b50565b611a667fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e33611589565b611aa5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9c90613b0d565b60405180910390fd5b80600a819055507fa6dc15bdb68da224c66db4b3838d9a2b205138e8cff6774e57d0af91e196d62281604051611adb9190613525565b60405180910390a150565b611b107fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e33611589565b611b4f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4690613b0d565b60405180910390fd5b6001601060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f4790a4adb426ca2345bb5108f6e454eae852a7bf687544cd66a7270dff3a41d660405160405180910390a250565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611c605750611c5f8261276e565b5b9050919050565b600080611c7383612850565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ce657826040517f7e273289000000000000000000000000000000000000000000000000000000008152600401611cdd9190613525565b60405180910390fd5b80915050919050565b60006004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600033905090565b611d41838383600161288d565b505050565b600081600001549050919050565b6001816000016000828254019250508190555050565b611d84828260405180602001604052806000815250612a52565b5050565b600080611d9484612850565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611dd657611dd5818486612a6e565b5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611e6757611e1860008560008061288d565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611eea576001600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b846002600086815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b611fb381611fae611d2c565b612b32565b50565b6000611fc28383611589565b61209d5760016007600085815260200190815260200160002060000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061203a611d2c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4600190506120a2565b600090505b92915050565b60006120b48383611589565b156121905760006007600085815260200190815260200160002060000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061212d611d2c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019050612195565b600090505b92915050565b6121a3611d2c565b73ffffffffffffffffffffffffffffffffffffffff166121c161140c565b73ffffffffffffffffffffffffffffffffffffffff1614612220576121e4611d2c565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401612217919061311f565b60405180910390fd5b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361235957816040517f5b08ba18000000000000000000000000000000000000000000000000000000008152600401612350919061311f565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161244a9190612fae565b60405180910390a3505050565b60008373ffffffffffffffffffffffffffffffffffffffff163b1115612608578273ffffffffffffffffffffffffffffffffffffffff1663150b7a0261249b611d2c565b8685856040518563ffffffff1660e01b81526004016124bd9493929190614021565b6020604051808303816000875af19250505080156124f957506040513d601f19601f820116820180604052508101906124f69190614082565b60015b61257d573d8060008114612529576040519150601f19603f3d011682016040523d82523d6000602084013e61252e565b606091505b50600081510361257557836040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161256c919061311f565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461260657836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016125fd919061311f565b60405180910390fd5b505b50505050565b6060600b805461261d906137d8565b80601f0160208091040260200160405190810160405280929190818152602001828054612649906137d8565b80156126965780601f1061266b57610100808354040283529160200191612696565b820191906000526020600020905b81548152906001019060200180831161267957829003601f168201915b5050505050905090565b6060600060016126af84612b83565b01905060008167ffffffffffffffff8111156126ce576126cd6133b1565b5b6040519080825280601f01601f1916602001820160405280156127005781602001600182028036833780820191505090505b509050600082602001820190505b600115612763578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161275757612756613a61565b5b0494506000850361270e575b819350505050919050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061283957507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80612849575061284882612cd6565b5b9050919050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b80806128c65750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156129fa5760006128d684611c67565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561294157508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015612954575061295281846118fc565b155b1561299657826040517fa9fbf51f00000000000000000000000000000000000000000000000000000000815260040161298d919061311f565b60405180910390fd5b81156129f857838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b836004600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b612a5c8383612d40565b612a696000848484612457565b505050565b612a79838383612e39565b612b2d57600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612aee57806040517f7e273289000000000000000000000000000000000000000000000000000000008152600401612ae59190613525565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401612b249291906132d5565b60405180910390fd5b505050565b612b3c8282611589565b612b7f5780826040517fe2517d3f000000000000000000000000000000000000000000000000000000008152600401612b769291906140af565b60405180910390fd5b5050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612be1577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612bd757612bd6613a61565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612c1e576d04ee2d6d415b85acef81000000008381612c1457612c13613a61565b5b0492506020810190505b662386f26fc100008310612c4d57662386f26fc100008381612c4357612c42613a61565b5b0492506010810190505b6305f5e1008310612c76576305f5e1008381612c6c57612c6b613a61565b5b0492506008810190505b6127108310612c9b576127108381612c9157612c90613a61565b5b0492506004810190505b60648310612cbe5760648381612cb457612cb3613a61565b5b0492506002810190505b600a8310612ccd576001810190505b80915050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612db25760006040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401612da9919061311f565b60405180910390fd5b6000612dc083836000611d88565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612e345760006040517f73c6ac6e000000000000000000000000000000000000000000000000000000008152600401612e2b919061311f565b60405180910390fd5b505050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015612ef157508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612eb25750612eb184846118fc565b5b80612ef057508273ffffffffffffffffffffffffffffffffffffffff16612ed883611cef565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612f4381612f0e565b8114612f4e57600080fd5b50565b600081359050612f6081612f3a565b92915050565b600060208284031215612f7c57612f7b612f04565b5b6000612f8a84828501612f51565b91505092915050565b60008115159050919050565b612fa881612f93565b82525050565b6000602082019050612fc36000830184612f9f565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613003578082015181840152602081019050612fe8565b60008484015250505050565b6000601f19601f8301169050919050565b600061302b82612fc9565b6130358185612fd4565b9350613045818560208601612fe5565b61304e8161300f565b840191505092915050565b600060208201905081810360008301526130738184613020565b905092915050565b6000819050919050565b61308e8161307b565b811461309957600080fd5b50565b6000813590506130ab81613085565b92915050565b6000602082840312156130c7576130c6612f04565b5b60006130d58482850161309c565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613109826130de565b9050919050565b613119816130fe565b82525050565b60006020820190506131346000830184613110565b92915050565b613143816130fe565b811461314e57600080fd5b50565b6000813590506131608161313a565b92915050565b6000806040838503121561317d5761317c612f04565b5b600061318b85828601613151565b925050602061319c8582860161309c565b9150509250929050565b6000806000606084860312156131bf576131be612f04565b5b60006131cd86828701613151565b93505060206131de86828701613151565b92505060406131ef8682870161309c565b9150509250925092565b6000819050919050565b61320c816131f9565b811461321757600080fd5b50565b60008135905061322981613203565b92915050565b60006020828403121561324557613244612f04565b5b60006132538482850161321a565b91505092915050565b613265816131f9565b82525050565b6000602082019050613280600083018461325c565b92915050565b6000806040838503121561329d5761329c612f04565b5b60006132ab8582860161309c565b92505060206132bc8582860161309c565b9150509250929050565b6132cf8161307b565b82525050565b60006040820190506132ea6000830185613110565b6132f760208301846132c6565b9392505050565b6000806040838503121561331557613314612f04565b5b60006133238582860161321a565b925050602061333485828601613151565b9150509250929050565b60006020828403121561335457613353612f04565b5b600061336284828501613151565b91505092915050565b6000613376826130de565b9050919050565b6133868161336b565b82525050565b60006020820190506133a1600083018461337d565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6133e98261300f565b810181811067ffffffffffffffff82111715613408576134076133b1565b5b80604052505050565b600061341b612efa565b905061342782826133e0565b919050565b600067ffffffffffffffff821115613447576134466133b1565b5b6134508261300f565b9050602081019050919050565b82818337600083830152505050565b600061347f61347a8461342c565b613411565b90508281526020810184848401111561349b5761349a6133ac565b5b6134a684828561345d565b509392505050565b600082601f8301126134c3576134c26133a7565b5b81356134d384826020860161346c565b91505092915050565b6000602082840312156134f2576134f1612f04565b5b600082013567ffffffffffffffff8111156135105761350f612f09565b5b61351c848285016134ae565b91505092915050565b600060208201905061353a60008301846132c6565b92915050565b61354981612f93565b811461355457600080fd5b50565b60008135905061356681613540565b92915050565b60006020828403121561358257613581612f04565b5b600061359084828501613557565b91505092915050565b600080604083850312156135b0576135af612f04565b5b60006135be85828601613151565b92505060206135cf85828601613557565b9150509250929050565b600067ffffffffffffffff8211156135f4576135f36133b1565b5b6135fd8261300f565b9050602081019050919050565b600061361d613618846135d9565b613411565b905082815260208101848484011115613639576136386133ac565b5b61364484828561345d565b509392505050565b600082601f830112613661576136606133a7565b5b813561367184826020860161360a565b91505092915050565b6000806000806080858703121561369457613693612f04565b5b60006136a287828801613151565b94505060206136b387828801613151565b93505060406136c48782880161309c565b925050606085013567ffffffffffffffff8111156136e5576136e4612f09565b5b6136f18782880161364c565b91505092959194509250565b6137068161336b565b811461371157600080fd5b50565b600081359050613723816136fd565b92915050565b600080604083850312156137405761373f612f04565b5b600061374e85828601613714565b925050602061375f8582860161309c565b9150509250929050565b600080604083850312156137805761377f612f04565b5b600061378e85828601613151565b925050602061379f85828601613151565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806137f057607f821691505b602082108103613803576138026137a9565b5b50919050565b7f4d617820737570706c7920726561636865640000000000000000000000000000600082015250565b600061383f601283612fd4565b915061384a82613809565b602082019050919050565b6000602082019050818103600083015261386e81613832565b9050919050565b7f596f75206861766520616c7265616479206d696e74656420616e204e46540000600082015250565b60006138ab601e83612fd4565b91506138b682613875565b602082019050919050565b600060208201905081810360008301526138da8161389e565b9050919050565b7f496e73756666696369656e74207061796d656e74000000000000000000000000600082015250565b6000613917601483612fd4565b9150613922826138e1565b602082019050919050565b600060208201905081810360008301526139468161390a565b9050919050565b7f4e6f742077686974656c69737465640000000000000000000000000000000000600082015250565b6000613983600f83612fd4565b915061398e8261394d565b602082019050919050565b600060208201905081810360008301526139b281613976565b9050919050565b60006060820190506139ce6000830186613110565b6139db60208301856132c6565b6139e86040830184613110565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613a2a8261307b565b9150613a358361307b565b9250828202613a438161307b565b91508282048414831517613a5a57613a596139f0565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613a9b8261307b565b9150613aa68361307b565b925082613ab657613ab5613a61565b5b828204905092915050565b7f4e6f7420616e206f776e65720000000000000000000000000000000000000000600082015250565b6000613af7600c83612fd4565b9150613b0282613ac1565b602082019050919050565b60006020820190508181036000830152613b2681613aea565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613b8f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613b52565b613b998683613b52565b95508019841693508086168417925050509392505050565b6000819050919050565b6000613bd6613bd1613bcc8461307b565b613bb1565b61307b565b9050919050565b6000819050919050565b613bf083613bbb565b613c04613bfc82613bdd565b848454613b5f565b825550505050565b600090565b613c19613c0c565b613c24818484613be7565b505050565b5b81811015613c4857613c3d600082613c11565b600181019050613c2a565b5050565b601f821115613c8d57613c5e81613b2d565b613c6784613b42565b81016020851015613c76578190505b613c8a613c8285613b42565b830182613c29565b50505b505050565b600082821c905092915050565b6000613cb060001984600802613c92565b1980831691505092915050565b6000613cc98383613c9f565b9150826002028217905092915050565b613ce282612fc9565b67ffffffffffffffff811115613cfb57613cfa6133b1565b5b613d0582546137d8565b613d10828285613c4c565b600060209050601f831160018114613d435760008415613d31578287015190505b613d3b8582613cbd565b865550613da3565b601f198416613d5186613b2d565b60005b82811015613d7957848901518255600182019150602085019450602081019050613d54565b86831015613d965784890151613d92601f891682613c9f565b8355505b6001600288020188555050505b505050505050565b7f496e76616c696420616464726573730000000000000000000000000000000000600082015250565b6000613de1600f83612fd4565b9150613dec82613dab565b602082019050919050565b60006020820190508181036000830152613e1081613dd4565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000613e73602f83612fd4565b9150613e7e82613e17565b604082019050919050565b60006020820190508181036000830152613ea281613e66565b9050919050565b600081905092915050565b6000613ebf82612fc9565b613ec98185613ea9565b9350613ed9818560208601612fe5565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000613f1b600583613ea9565b9150613f2682613ee5565b600582019050919050565b6000613f3d8285613eb4565b9150613f498284613eb4565b9150613f5482613f0e565b91508190509392505050565b7f526f79616c747920657863656564732031303025000000000000000000000000600082015250565b6000613f96601483612fd4565b9150613fa182613f60565b602082019050919050565b60006020820190508181036000830152613fc581613f89565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000613ff382613fcc565b613ffd8185613fd7565b935061400d818560208601612fe5565b6140168161300f565b840191505092915050565b60006080820190506140366000830187613110565b6140436020830186613110565b61405060408301856132c6565b81810360608301526140628184613fe8565b905095945050505050565b60008151905061407c81612f3a565b92915050565b60006020828403121561409857614097612f04565b5b60006140a68482850161406d565b91505092915050565b60006040820190506140c46000830185613110565b6140d1602083018461325c565b939250505056fea2646970667358221220552f6ac2ff539f540c6619e53d3fb02c3086f2f016d68b0be440973618904f9764736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000d302f9aa2a57ea2516835a6e36cc168ae0365b37000000000000000000000000c91541d3cd68cd0bb6749f0874a61e41e399f5f500000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000000180000000000000000000000000c9289e3167313abe2628de5b509d66e0ef7ee2a30000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000f526f79616c7479436f6e7472616374000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025243000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002768747470733a2f2f697066732e6172626f726e66742e696f2f666967687434686f70652f66346800000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : name (string): RoyaltyContract
Arg [1] : symbol (string): RC
Arg [2] : _secondOwner (address): 0xd302f9AA2a57eA2516835A6e36CC168ae0365B37
Arg [3] : _feeWallet (address): 0xc91541d3Cd68cd0bB6749F0874a61e41E399f5F5
Arg [4] : _maxSupply (uint256): 10000
Arg [5] : _baseUri (string): https://ipfs.arbornft.io/fight4hope/f4h
Arg [6] : _royaltyRecipient (address): 0xc9289e3167313ABe2628DE5B509d66e0eF7eE2a3
Arg [7] : _royaltyPercentage (uint256): 3
-----Encoded View---------------
15 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [2] : 000000000000000000000000d302f9aa2a57ea2516835a6e36cc168ae0365b37
Arg [3] : 000000000000000000000000c91541d3cd68cd0bb6749f0874a61e41e399f5f5
Arg [4] : 0000000000000000000000000000000000000000000000000000000000002710
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000180
Arg [6] : 000000000000000000000000c9289e3167313abe2628de5b509d66e0ef7ee2a3
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [8] : 000000000000000000000000000000000000000000000000000000000000000f
Arg [9] : 526f79616c7479436f6e74726163740000000000000000000000000000000000
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [11] : 5243000000000000000000000000000000000000000000000000000000000000
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000027
Arg [13] : 68747470733a2f2f697066732e6172626f726e66742e696f2f66696768743468
Arg [14] : 6f70652f66346800000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
70534:5813:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75411:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70719:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38678:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39850:158;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39669:115;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73935:783;;;:::i;:::-;;40519:588;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64788:122;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75717:322;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;65220:138;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;66357:251;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71136:41;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41178:134;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70881:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72543:143;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;38491:120;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70760:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70791:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38216:213;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56773:103;;;;;;;;;;;;;:::i;:::-;;73589:151;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73013:141;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70927:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56098:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72733:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63804:138;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38838:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71041:41;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63116:49;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40080:146;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;41383:211;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74790:529;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65651:140;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70850:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76087:257;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71216:60;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40297:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70819:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57031:220;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73220:137;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73398:145;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75411:234;75527:4;75571:26;75556:41;;;:11;:41;;;;:81;;;;75601:36;75625:11;75601:23;:36::i;:::-;75556:81;75549:88;;75411:234;;;:::o;70719:34::-;;;;;;;;;;;;;:::o;38678:91::-;38723:13;38756:5;38749:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38678:91;:::o;39850:158::-;39917:7;39937:22;39951:7;39937:13;:22::i;:::-;;39979:21;39992:7;39979:12;:21::i;:::-;39972:28;;39850:158;;;:::o;39669:115::-;39741:35;39750:2;39754:7;39763:12;:10;:12::i;:::-;39741:8;:35::i;:::-;39669:115;;:::o;73935:783::-;74009:9;;73987:19;:9;:17;:19::i;:::-;:31;73979:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;74061:9;:21;74071:10;74061:21;;;;;;;;;;;;;;;;;;;;;;;;;74060:22;74052:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;74192:9;;74179;:22;;74171:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;74281:15;;;;;;;;;;;74277:97;;;74321:9;:21;74331:10;74321:21;;;;;;;;;;;;;;;;;;;;;;;;;74313:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;74277:97;74411:21;:9;:19;:21::i;:::-;74443:17;74463:19;:9;:17;:19::i;:::-;74443:39;;74565:4;74541:9;:21;74551:10;74541:21;;;;;;;;;;;;;;;;:28;;;;;;;;;;;;;;;;;;74598:1;74586:9;;:13;74582:84;;;74624:9;;;;;;;;;;;74616:27;;:38;74644:9;74616:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74582:84;74678:32;74688:10;74700:9;74678;:32::i;:::-;73968:750;73935:783::o;40519:588::-;40628:1;40614:16;;:2;:16;;;40610:89;;40684:1;40654:33;;;;;;;;;;;:::i;:::-;;;;;;;;40610:89;40920:21;40944:34;40952:2;40956:7;40965:12;:10;:12::i;:::-;40944:7;:34::i;:::-;40920:58;;41010:4;40993:21;;:13;:21;;;40989:111;;41059:4;41065:7;41074:13;41038:50;;;;;;;;;;;;;:::i;:::-;;;;;;;;40989:111;40599:508;40519:588;;;:::o;64788:122::-;64853:7;64880:6;:12;64887:4;64880:12;;;;;;;;;;;:22;;;64873:29;;64788:122;;;:::o;75717:322::-;75879:16;75897:21;75931:14;75982:5;75961:17;;75949:9;:29;;;;:::i;:::-;75948:39;;;;:::i;:::-;75931:56;;76006:16;;;;;;;;;;;76024:6;75998:33;;;;;75717:322;;;;;:::o;65220:138::-;65294:18;65307:4;65294:12;:18::i;:::-;63400:16;63411:4;63400:10;:16::i;:::-;65325:25:::1;65336:4;65342:7;65325:10;:25::i;:::-;;65220:138:::0;;;:::o;66357:251::-;66473:12;:10;:12::i;:::-;66451:34;;:18;:34;;;66447:104;;66509:30;;;;;;;;;;;;;;66447:104;66563:37;66575:4;66581:18;66563:11;:37::i;:::-;;66357:251;;:::o;71136:41::-;;;;;;;;;;;;;;;;;;;;;;:::o;41178:134::-;41265:39;41282:4;41288:2;41292:7;41265:39;;;;;;;;;;;;:16;:39::i;:::-;41178:134;;;:::o;70881:39::-;;;;;;;;;;;;;:::o;72543:143::-;72430:31;71253:23;72450:10;72430:7;:31::i;:::-;72422:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;72630:10:::1;72620:7;:20;;;;;;:::i;:::-;;72656:22;72667:10;72656:22;;;;;;:::i;:::-;;;;;;;;72543:143:::0;:::o;38491:120::-;38554:7;38581:22;38595:7;38581:13;:22::i;:::-;38574:29;;38491:120;;;:::o;70760:24::-;;;;:::o;70791:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;38216:213::-;38279:7;38320:1;38303:19;;:5;:19;;;38299:89;;38373:1;38346:30;;;;;;;;;;;:::i;:::-;;;;;;;;38299:89;38405:9;:16;38415:5;38405:16;;;;;;;;;;;;;;;;38398:23;;38216:213;;;:::o;56773:103::-;55984:13;:11;:13::i;:::-;56838:30:::1;56865:1;56838:18;:30::i;:::-;56773:103::o:0;73589:151::-;72430:31;71253:23;72450:10;72430:7;:31::i;:::-;72422:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;73685:5:::1;73663:9;:19;73673:8;73663:19;;;;;;;;;;;;;;;;:27;;;;;;;;;;;;;;;;;;73723:8;73706:26;;;;;;;;;;;;73589:151:::0;:::o;73013:141::-;72430:31;71253:23;72450:10;72430:7;:31::i;:::-;72422:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;73100:6:::1;73082:15;;:24;;;;;;;;;;;;;;;;;;73122;73139:6;73122:24;;;;;;:::i;:::-;;;;;;;;73013:141:::0;:::o;70927:32::-;;;;:::o;56098:87::-;56144:7;56171:6;;;;;;;;;;;56164:13;;56098:87;:::o;72733:218::-;72430:31;71253:23;72450:10;72430:7;:31::i;:::-;72422:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;72840:1:::1;72816:26;;:12;:26;;::::0;72808:54:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;72885:12;72873:9;;:24;;;;;;;;;;;;;;;;;;72913:30;72930:12;72913:30;;;;;;:::i;:::-;;;;;;;;72733:218:::0;:::o;63804:138::-;63881:4;63905:6;:12;63912:4;63905:12;;;;;;;;;;;:20;;:29;63926:7;63905:29;;;;;;;;;;;;;;;;;;;;;;;;;63898:36;;63804:138;;;;:::o;38838:95::-;38885:13;38918:7;38911:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38838:95;:::o;71041:41::-;;;;;;;;;;;;;;;;;;;;;;:::o;63116:49::-;63161:4;63116:49;;;:::o;40080:146::-;40166:52;40185:12;:10;:12::i;:::-;40199:8;40209;40166:18;:52::i;:::-;40080:146;;:::o;41383:211::-;41497:31;41510:4;41516:2;41520:7;41497:12;:31::i;:::-;41539:47;41562:4;41568:2;41572:7;41581:4;41539:22;:47::i;:::-;41383:211;;;;:::o;74790:529::-;74908:13;74989:1;74961:30;;:16;74969:7;74961;:16::i;:::-;:30;;;74939:127;;;;;;;;;;;;:::i;:::-;;;;;;;;;75079:18;75100:10;:8;:10::i;:::-;75079:31;;75162:1;75147:4;75141:18;:22;:170;;;;;;;;;;;;;;;;;75229:4;75235:25;75252:7;75235:16;:25::i;:::-;75212:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;75141:170;75121:190;;;74790:529;;;:::o;65651:140::-;65726:18;65739:4;65726:12;:18::i;:::-;63400:16;63411:4;63400:10;:16::i;:::-;65757:26:::1;65769:4;65775:7;65757:11;:26::i;:::-;;65651:140:::0;;;:::o;70850:24::-;;;;:::o;76087:257::-;72430:31;71253:23;72450:10;72430:7;:31::i;:::-;72422:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;76220:5:::1;76203:13;:22;;76195:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;76280:12;76261:16;;:31;;;;;;;;;;;;;;;;;;76323:13;76303:17;:33;;;;76087:257:::0;;:::o;71216:60::-;71253:23;71216:60;:::o;40297:155::-;40385:4;40409:18;:25;40428:5;40409:25;;;;;;;;;;;;;;;:35;40435:8;40409:35;;;;;;;;;;;;;;;;;;;;;;;;;40402:42;;40297:155;;;;:::o;70819:24::-;;;;;;;;;;;;;:::o;57031:220::-;55984:13;:11;:13::i;:::-;57136:1:::1;57116:22;;:8;:22;;::::0;57112:93:::1;;57190:1;57162:31;;;;;;;;;;;:::i;:::-;;;;;;;;57112:93;57215:28;57234:8;57215:18;:28::i;:::-;57031:220:::0;:::o;73220:137::-;72430:31;71253:23;72450:10;72430:7;:31::i;:::-;72422:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;73303:8:::1;73291:9;:20;;;;73327:22;73340:8;73327:22;;;;;;:::i;:::-;;;;;;;;73220:137:::0;:::o;73398:145::-;72430:31;71253:23;72450:10;72430:7;:31::i;:::-;72422:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;73491:4:::1;73469:9;:19;73479:8;73469:19;;;;;;;;;;;;;;;;:26;;;;;;;;;;;;;;;;;;73526:8;73511:24;;;;;;;;;;;;73398:145:::0;:::o;63508:204::-;63593:4;63632:32;63617:47;;;:11;:47;;;;:87;;;;63668:36;63692:11;63668:23;:36::i;:::-;63617:87;63610:94;;63508:204;;;:::o;52825:247::-;52888:7;52908:13;52924:17;52933:7;52924:8;:17::i;:::-;52908:33;;52973:1;52956:19;;:5;:19;;;52952:90;;53022:7;52999:31;;;;;;;;;;;:::i;:::-;;;;;;;;52952:90;53059:5;53052:12;;;52825:247;;;:::o;42356:129::-;42426:7;42453:15;:24;42469:7;42453:24;;;;;;;;;;;;;;;;;;;;;42446:31;;42356:129;;;:::o;8584:98::-;8637:7;8664:10;8657:17;;8584:98;:::o;51057:122::-;51138:33;51147:2;51151:7;51160:4;51166;51138:8;:33::i;:::-;51057:122;;;:::o;69006:114::-;69071:7;69098;:14;;;69091:21;;69006:114;;;:::o;69128:127::-;69235:1;69217:7;:14;;;:19;;;;;;;;;;;69128:127;:::o;47176:102::-;47244:26;47254:2;47258:7;47244:26;;;;;;;;;;;;:9;:26::i;:::-;47176:102;;:::o;45318:824::-;45404:7;45424:12;45439:17;45448:7;45439:8;:17::i;:::-;45424:32;;45535:1;45519:18;;:4;:18;;;45515:88;;45554:37;45571:4;45577;45583:7;45554:16;:37::i;:::-;45515:88;45666:1;45650:18;;:4;:18;;;45646:263;;45768:48;45785:1;45789:7;45806:1;45810:5;45768:8;:48::i;:::-;45881:1;45862:9;:15;45872:4;45862:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;45646:263;45939:1;45925:16;;:2;:16;;;45921:111;;46004:1;45987:9;:13;45997:2;45987:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;45921:111;46063:2;46044:7;:16;46052:7;46044:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;46102:7;46098:2;46083:27;;46092:4;46083:27;;;;;;;;;;;;46130:4;46123:11;;;45318:824;;;;;:::o;64157:105::-;64224:30;64235:4;64241:12;:10;:12::i;:::-;64224:10;:30::i;:::-;64157:105;:::o;67234:324::-;67311:4;67333:22;67341:4;67347:7;67333;:22::i;:::-;67328:223;;67404:4;67372:6;:12;67379:4;67372:12;;;;;;;;;;;:20;;:29;67393:7;67372:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;67455:12;:10;:12::i;:::-;67428:40;;67446:7;67428:40;;67440:4;67428:40;;;;;;;;;;67490:4;67483:11;;;;67328:223;67534:5;67527:12;;67234:324;;;;;:::o;67802:325::-;67880:4;67901:22;67909:4;67915:7;67901;:22::i;:::-;67897:223;;;67972:5;67940:6;:12;67947:4;67940:12;;;;;;;;;;;:20;;:29;67961:7;67940:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;68024:12;:10;:12::i;:::-;67997:40;;68015:7;67997:40;;68009:4;67997:40;;;;;;;;;;68059:4;68052:11;;;;67897:223;68103:5;68096:12;;67802:325;;;;;:::o;56263:166::-;56334:12;:10;:12::i;:::-;56323:23;;:7;:5;:7::i;:::-;:23;;;56319:103;;56397:12;:10;:12::i;:::-;56370:40;;;;;;;;;;;:::i;:::-;;;;;;;;56319:103;56263:166::o;57411:191::-;57485:16;57504:6;;;;;;;;;;;57485:25;;57530:8;57521:6;;:17;;;;;;;;;;;;;;;;;;57585:8;57554:40;;57575:8;57554:40;;;;;;;;;;;;57474:128;57411:191;:::o;52264:318::-;52392:1;52372:22;;:8;:22;;;52368:93;;52440:8;52418:31;;;;;;;;;;;:::i;:::-;;;;;;;;52368:93;52509:8;52471:18;:25;52490:5;52471:25;;;;;;;;;;;;;;;:35;52497:8;52471:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;52555:8;52533:41;;52548:5;52533:41;;;52565:8;52533:41;;;;;;:::i;:::-;;;;;;;;52264:318;;;:::o;53622:799::-;53756:1;53739:2;:14;;;:18;53735:679;;;53794:2;53778:36;;;53815:12;:10;:12::i;:::-;53829:4;53835:7;53844:4;53778:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;53774:629;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54109:1;54092:6;:13;:18;54088:300;;54164:2;54142:25;;;;;;;;;;;:::i;:::-;;;;;;;;54088:300;54338:6;54332:13;54323:6;54319:2;54315:15;54308:38;53774:629;53907:41;;;53897:51;;;:6;:51;;;;53893:132;;54002:2;53980:25;;;;;;;;;;;:::i;:::-;;;;;;;;53893:132;53850:190;53735:679;53622:799;;;;:::o;73797:108::-;73857:13;73890:7;73883:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73797:108;:::o;26400:718::-;26456:13;26507:14;26544:1;26524:17;26535:5;26524:10;:17::i;:::-;:21;26507:38;;26560:20;26594:6;26583:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26560:41;;26616:11;26745:6;26741:2;26737:15;26729:6;26725:28;26718:35;;26782:290;26789:4;26782:290;;;26814:5;;;;;;;;26956:10;26951:2;26944:5;26940:14;26935:32;26930:3;26922:46;27014:2;27005:11;;;;;;:::i;:::-;;;;;27048:1;27039:5;:10;26782:290;27035:21;26782:290;27093:6;27086:13;;;;;26400:718;;;:::o;37847:305::-;37949:4;38001:25;37986:40;;;:11;:40;;;;:105;;;;38058:33;38043:48;;;:11;:48;;;;37986:105;:158;;;;38108:36;38132:11;38108:23;:36::i;:::-;37986:158;37966:178;;37847:305;;;:::o;42118:117::-;42184:7;42211;:16;42219:7;42211:16;;;;;;;;;;;;;;;;;;;;;42204:23;;42118:117;;;:::o;51367:678::-;51529:9;:31;;;;51558:1;51542:18;;:4;:18;;;;51529:31;51525:471;;;51577:13;51593:22;51607:7;51593:13;:22::i;:::-;51577:38;;51762:1;51746:18;;:4;:18;;;;:35;;;;;51777:4;51768:13;;:5;:13;;;;51746:35;:69;;;;;51786:29;51803:5;51810:4;51786:16;:29::i;:::-;51785:30;51746:69;51742:144;;;51865:4;51843:27;;;;;;;;;;;:::i;:::-;;;;;;;;51742:144;51906:9;51902:83;;;51961:7;51957:2;51941:28;;51950:5;51941:28;;;;;;;;;;;;51902:83;51562:434;51525:471;52035:2;52008:15;:24;52024:7;52008:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;51367:678;;;;:::o;47505:185::-;47600:18;47606:2;47610:7;47600:5;:18::i;:::-;47629:53;47660:1;47664:2;47668:7;47677:4;47629:22;:53::i;:::-;47505:185;;;:::o;43525:376::-;43638:38;43652:5;43659:7;43668;43638:13;:38::i;:::-;43633:261;;43714:1;43697:19;;:5;:19;;;43693:190;;43767:7;43744:31;;;;;;;;;;;:::i;:::-;;;;;;;;43693:190;43850:7;43859;43823:44;;;;;;;;;;;;:::i;:::-;;;;;;;;43633:261;43525:376;;;:::o;64398:201::-;64487:22;64495:4;64501:7;64487;:22::i;:::-;64482:110;;64566:7;64575:4;64533:47;;;;;;;;;;;;:::i;:::-;;;;;;;;64482:110;64398:201;;:::o;21464:948::-;21517:7;21537:14;21554:1;21537:18;;21604:8;21595:5;:17;21591:106;;21642:8;21633:17;;;;;;:::i;:::-;;;;;21679:2;21669:12;;;;21591:106;21724:8;21715:5;:17;21711:106;;21762:8;21753:17;;;;;;:::i;:::-;;;;;21799:2;21789:12;;;;21711:106;21844:8;21835:5;:17;21831:106;;21882:8;21873:17;;;;;;:::i;:::-;;;;;21919:2;21909:12;;;;21831:106;21964:7;21955:5;:16;21951:103;;22001:7;21992:16;;;;;;:::i;:::-;;;;;22037:1;22027:11;;;;21951:103;22081:7;22072:5;:16;22068:103;;22118:7;22109:16;;;;;;:::i;:::-;;;;;22154:1;22144:11;;;;22068:103;22198:7;22189:5;:16;22185:103;;22235:7;22226:16;;;;;;:::i;:::-;;;;;22271:1;22261:11;;;;22185:103;22315:7;22306:5;:16;22302:68;;22353:1;22343:11;;;;22302:68;22398:6;22391:13;;;21464:948;;;:::o;29716:148::-;29792:4;29831:25;29816:40;;;:11;:40;;;;29809:47;;29716:148;;;:::o;46478:335::-;46560:1;46546:16;;:2;:16;;;46542:89;;46616:1;46586:33;;;;;;;;;;;:::i;:::-;;;;;;;;46542:89;46641:21;46665:32;46673:2;46677:7;46694:1;46665:7;:32::i;:::-;46641:56;;46737:1;46712:27;;:13;:27;;;46708:98;;46791:1;46763:31;;;;;;;;;;;:::i;:::-;;;;;;;;46708:98;46531:282;46478:335;;:::o;42805:276::-;42908:4;42964:1;42945:21;;:7;:21;;;;:128;;;;;42993:7;42984:16;;:5;:16;;;:52;;;;43004:32;43021:5;43028:7;43004:16;:32::i;:::-;42984:52;:88;;;;43065:7;43040:32;;:21;43053:7;43040:12;:21::i;:::-;:32;;;42984:88;42945:128;42925:148;;42805:276;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:248::-;1880:1;1890:113;1904:6;1901:1;1898:13;1890:113;;;1989:1;1984:3;1980:11;1974:18;1970:1;1965:3;1961:11;1954:39;1926:2;1923:1;1919:10;1914:15;;1890:113;;;2037:1;2028:6;2023:3;2019:16;2012:27;1860:186;1798:248;;;:::o;2052:102::-;2093:6;2144:2;2140:7;2135:2;2128:5;2124:14;2120:28;2110:38;;2052:102;;;:::o;2160:377::-;2248:3;2276:39;2309:5;2276:39;:::i;:::-;2331:71;2395:6;2390:3;2331:71;:::i;:::-;2324:78;;2411:65;2469:6;2464:3;2457:4;2450:5;2446:16;2411:65;:::i;:::-;2501:29;2523:6;2501:29;:::i;:::-;2496:3;2492:39;2485:46;;2252:285;2160:377;;;;:::o;2543:313::-;2656:4;2694:2;2683:9;2679:18;2671:26;;2743:9;2737:4;2733:20;2729:1;2718:9;2714:17;2707:47;2771:78;2844:4;2835:6;2771:78;:::i;:::-;2763:86;;2543:313;;;;:::o;2862:77::-;2899:7;2928:5;2917:16;;2862:77;;;:::o;2945:122::-;3018:24;3036:5;3018:24;:::i;:::-;3011:5;3008:35;2998:63;;3057:1;3054;3047:12;2998:63;2945:122;:::o;3073:139::-;3119:5;3157:6;3144:20;3135:29;;3173:33;3200:5;3173:33;:::i;:::-;3073:139;;;;:::o;3218:329::-;3277:6;3326:2;3314:9;3305:7;3301:23;3297:32;3294:119;;;3332:79;;:::i;:::-;3294:119;3452:1;3477:53;3522:7;3513:6;3502:9;3498:22;3477:53;:::i;:::-;3467:63;;3423:117;3218:329;;;;:::o;3553:126::-;3590:7;3630:42;3623:5;3619:54;3608:65;;3553:126;;;:::o;3685:96::-;3722:7;3751:24;3769:5;3751:24;:::i;:::-;3740:35;;3685:96;;;:::o;3787:118::-;3874:24;3892:5;3874:24;:::i;:::-;3869:3;3862:37;3787:118;;:::o;3911:222::-;4004:4;4042:2;4031:9;4027:18;4019:26;;4055:71;4123:1;4112:9;4108:17;4099:6;4055:71;:::i;:::-;3911:222;;;;:::o;4139:122::-;4212:24;4230:5;4212:24;:::i;:::-;4205:5;4202:35;4192:63;;4251:1;4248;4241:12;4192:63;4139:122;:::o;4267:139::-;4313:5;4351:6;4338:20;4329:29;;4367:33;4394:5;4367:33;:::i;:::-;4267:139;;;;:::o;4412:474::-;4480:6;4488;4537:2;4525:9;4516:7;4512:23;4508:32;4505:119;;;4543:79;;:::i;:::-;4505:119;4663:1;4688:53;4733:7;4724:6;4713:9;4709:22;4688:53;:::i;:::-;4678:63;;4634:117;4790:2;4816:53;4861:7;4852:6;4841:9;4837:22;4816:53;:::i;:::-;4806:63;;4761:118;4412:474;;;;;:::o;4892:619::-;4969:6;4977;4985;5034:2;5022:9;5013:7;5009:23;5005:32;5002:119;;;5040:79;;:::i;:::-;5002:119;5160:1;5185:53;5230:7;5221:6;5210:9;5206:22;5185:53;:::i;:::-;5175:63;;5131:117;5287:2;5313:53;5358:7;5349:6;5338:9;5334:22;5313:53;:::i;:::-;5303:63;;5258:118;5415:2;5441:53;5486:7;5477:6;5466:9;5462:22;5441:53;:::i;:::-;5431:63;;5386:118;4892:619;;;;;:::o;5517:77::-;5554:7;5583:5;5572:16;;5517:77;;;:::o;5600:122::-;5673:24;5691:5;5673:24;:::i;:::-;5666:5;5663:35;5653:63;;5712:1;5709;5702:12;5653:63;5600:122;:::o;5728:139::-;5774:5;5812:6;5799:20;5790:29;;5828:33;5855:5;5828:33;:::i;:::-;5728:139;;;;:::o;5873:329::-;5932:6;5981:2;5969:9;5960:7;5956:23;5952:32;5949:119;;;5987:79;;:::i;:::-;5949:119;6107:1;6132:53;6177:7;6168:6;6157:9;6153:22;6132:53;:::i;:::-;6122:63;;6078:117;5873:329;;;;:::o;6208:118::-;6295:24;6313:5;6295:24;:::i;:::-;6290:3;6283:37;6208:118;;:::o;6332:222::-;6425:4;6463:2;6452:9;6448:18;6440:26;;6476:71;6544:1;6533:9;6529:17;6520:6;6476:71;:::i;:::-;6332:222;;;;:::o;6560:474::-;6628:6;6636;6685:2;6673:9;6664:7;6660:23;6656:32;6653:119;;;6691:79;;:::i;:::-;6653:119;6811:1;6836:53;6881:7;6872:6;6861:9;6857:22;6836:53;:::i;:::-;6826:63;;6782:117;6938:2;6964:53;7009:7;7000:6;6989:9;6985:22;6964:53;:::i;:::-;6954:63;;6909:118;6560:474;;;;;:::o;7040:118::-;7127:24;7145:5;7127:24;:::i;:::-;7122:3;7115:37;7040:118;;:::o;7164:332::-;7285:4;7323:2;7312:9;7308:18;7300:26;;7336:71;7404:1;7393:9;7389:17;7380:6;7336:71;:::i;:::-;7417:72;7485:2;7474:9;7470:18;7461:6;7417:72;:::i;:::-;7164:332;;;;;:::o;7502:474::-;7570:6;7578;7627:2;7615:9;7606:7;7602:23;7598:32;7595:119;;;7633:79;;:::i;:::-;7595:119;7753:1;7778:53;7823:7;7814:6;7803:9;7799:22;7778:53;:::i;:::-;7768:63;;7724:117;7880:2;7906:53;7951:7;7942:6;7931:9;7927:22;7906:53;:::i;:::-;7896:63;;7851:118;7502:474;;;;;:::o;7982:329::-;8041:6;8090:2;8078:9;8069:7;8065:23;8061:32;8058:119;;;8096:79;;:::i;:::-;8058:119;8216:1;8241:53;8286:7;8277:6;8266:9;8262:22;8241:53;:::i;:::-;8231:63;;8187:117;7982:329;;;;:::o;8317:104::-;8362:7;8391:24;8409:5;8391:24;:::i;:::-;8380:35;;8317:104;;;:::o;8427:142::-;8530:32;8556:5;8530:32;:::i;:::-;8525:3;8518:45;8427:142;;:::o;8575:254::-;8684:4;8722:2;8711:9;8707:18;8699:26;;8735:87;8819:1;8808:9;8804:17;8795:6;8735:87;:::i;:::-;8575:254;;;;:::o;8835:117::-;8944:1;8941;8934:12;8958:117;9067:1;9064;9057:12;9081:180;9129:77;9126:1;9119:88;9226:4;9223:1;9216:15;9250:4;9247:1;9240:15;9267:281;9350:27;9372:4;9350:27;:::i;:::-;9342:6;9338:40;9480:6;9468:10;9465:22;9444:18;9432:10;9429:34;9426:62;9423:88;;;9491:18;;:::i;:::-;9423:88;9531:10;9527:2;9520:22;9310:238;9267:281;;:::o;9554:129::-;9588:6;9615:20;;:::i;:::-;9605:30;;9644:33;9672:4;9664:6;9644:33;:::i;:::-;9554:129;;;:::o;9689:308::-;9751:4;9841:18;9833:6;9830:30;9827:56;;;9863:18;;:::i;:::-;9827:56;9901:29;9923:6;9901:29;:::i;:::-;9893:37;;9985:4;9979;9975:15;9967:23;;9689:308;;;:::o;10003:148::-;10101:6;10096:3;10091;10078:30;10142:1;10133:6;10128:3;10124:16;10117:27;10003:148;;;:::o;10157:425::-;10235:5;10260:66;10276:49;10318:6;10276:49;:::i;:::-;10260:66;:::i;:::-;10251:75;;10349:6;10342:5;10335:21;10387:4;10380:5;10376:16;10425:3;10416:6;10411:3;10407:16;10404:25;10401:112;;;10432:79;;:::i;:::-;10401:112;10522:54;10569:6;10564:3;10559;10522:54;:::i;:::-;10241:341;10157:425;;;;;:::o;10602:340::-;10658:5;10707:3;10700:4;10692:6;10688:17;10684:27;10674:122;;10715:79;;:::i;:::-;10674:122;10832:6;10819:20;10857:79;10932:3;10924:6;10917:4;10909:6;10905:17;10857:79;:::i;:::-;10848:88;;10664:278;10602:340;;;;:::o;10948:509::-;11017:6;11066:2;11054:9;11045:7;11041:23;11037:32;11034:119;;;11072:79;;:::i;:::-;11034:119;11220:1;11209:9;11205:17;11192:31;11250:18;11242:6;11239:30;11236:117;;;11272:79;;:::i;:::-;11236:117;11377:63;11432:7;11423:6;11412:9;11408:22;11377:63;:::i;:::-;11367:73;;11163:287;10948:509;;;;:::o;11463:222::-;11556:4;11594:2;11583:9;11579:18;11571:26;;11607:71;11675:1;11664:9;11660:17;11651:6;11607:71;:::i;:::-;11463:222;;;;:::o;11691:116::-;11761:21;11776:5;11761:21;:::i;:::-;11754:5;11751:32;11741:60;;11797:1;11794;11787:12;11741:60;11691:116;:::o;11813:133::-;11856:5;11894:6;11881:20;11872:29;;11910:30;11934:5;11910:30;:::i;:::-;11813:133;;;;:::o;11952:323::-;12008:6;12057:2;12045:9;12036:7;12032:23;12028:32;12025:119;;;12063:79;;:::i;:::-;12025:119;12183:1;12208:50;12250:7;12241:6;12230:9;12226:22;12208:50;:::i;:::-;12198:60;;12154:114;11952:323;;;;:::o;12281:468::-;12346:6;12354;12403:2;12391:9;12382:7;12378:23;12374:32;12371:119;;;12409:79;;:::i;:::-;12371:119;12529:1;12554:53;12599:7;12590:6;12579:9;12575:22;12554:53;:::i;:::-;12544:63;;12500:117;12656:2;12682:50;12724:7;12715:6;12704:9;12700:22;12682:50;:::i;:::-;12672:60;;12627:115;12281:468;;;;;:::o;12755:307::-;12816:4;12906:18;12898:6;12895:30;12892:56;;;12928:18;;:::i;:::-;12892:56;12966:29;12988:6;12966:29;:::i;:::-;12958:37;;13050:4;13044;13040:15;13032:23;;12755:307;;;:::o;13068:423::-;13145:5;13170:65;13186:48;13227:6;13186:48;:::i;:::-;13170:65;:::i;:::-;13161:74;;13258:6;13251:5;13244:21;13296:4;13289:5;13285:16;13334:3;13325:6;13320:3;13316:16;13313:25;13310:112;;;13341:79;;:::i;:::-;13310:112;13431:54;13478:6;13473:3;13468;13431:54;:::i;:::-;13151:340;13068:423;;;;;:::o;13510:338::-;13565:5;13614:3;13607:4;13599:6;13595:17;13591:27;13581:122;;13622:79;;:::i;:::-;13581:122;13739:6;13726:20;13764:78;13838:3;13830:6;13823:4;13815:6;13811:17;13764:78;:::i;:::-;13755:87;;13571:277;13510:338;;;;:::o;13854:943::-;13949:6;13957;13965;13973;14022:3;14010:9;14001:7;13997:23;13993:33;13990:120;;;14029:79;;:::i;:::-;13990:120;14149:1;14174:53;14219:7;14210:6;14199:9;14195:22;14174:53;:::i;:::-;14164:63;;14120:117;14276:2;14302:53;14347:7;14338:6;14327:9;14323:22;14302:53;:::i;:::-;14292:63;;14247:118;14404:2;14430:53;14475:7;14466:6;14455:9;14451:22;14430:53;:::i;:::-;14420:63;;14375:118;14560:2;14549:9;14545:18;14532:32;14591:18;14583:6;14580:30;14577:117;;;14613:79;;:::i;:::-;14577:117;14718:62;14772:7;14763:6;14752:9;14748:22;14718:62;:::i;:::-;14708:72;;14503:287;13854:943;;;;;;;:::o;14803:138::-;14884:32;14910:5;14884:32;:::i;:::-;14877:5;14874:43;14864:71;;14931:1;14928;14921:12;14864:71;14803:138;:::o;14947:155::-;15001:5;15039:6;15026:20;15017:29;;15055:41;15090:5;15055:41;:::i;:::-;14947:155;;;;:::o;15108:490::-;15184:6;15192;15241:2;15229:9;15220:7;15216:23;15212:32;15209:119;;;15247:79;;:::i;:::-;15209:119;15367:1;15392:61;15445:7;15436:6;15425:9;15421:22;15392:61;:::i;:::-;15382:71;;15338:125;15502:2;15528:53;15573:7;15564:6;15553:9;15549:22;15528:53;:::i;:::-;15518:63;;15473:118;15108:490;;;;;:::o;15604:474::-;15672:6;15680;15729:2;15717:9;15708:7;15704:23;15700:32;15697:119;;;15735:79;;:::i;:::-;15697:119;15855:1;15880:53;15925:7;15916:6;15905:9;15901:22;15880:53;:::i;:::-;15870:63;;15826:117;15982:2;16008:53;16053:7;16044:6;16033:9;16029:22;16008:53;:::i;:::-;15998:63;;15953:118;15604:474;;;;;:::o;16084:180::-;16132:77;16129:1;16122:88;16229:4;16226:1;16219:15;16253:4;16250:1;16243:15;16270:320;16314:6;16351:1;16345:4;16341:12;16331:22;;16398:1;16392:4;16388:12;16419:18;16409:81;;16475:4;16467:6;16463:17;16453:27;;16409:81;16537:2;16529:6;16526:14;16506:18;16503:38;16500:84;;16556:18;;:::i;:::-;16500:84;16321:269;16270:320;;;:::o;16596:168::-;16736:20;16732:1;16724:6;16720:14;16713:44;16596:168;:::o;16770:366::-;16912:3;16933:67;16997:2;16992:3;16933:67;:::i;:::-;16926:74;;17009:93;17098:3;17009:93;:::i;:::-;17127:2;17122:3;17118:12;17111:19;;16770:366;;;:::o;17142:419::-;17308:4;17346:2;17335:9;17331:18;17323:26;;17395:9;17389:4;17385:20;17381:1;17370:9;17366:17;17359:47;17423:131;17549:4;17423:131;:::i;:::-;17415:139;;17142:419;;;:::o;17567:180::-;17707:32;17703:1;17695:6;17691:14;17684:56;17567:180;:::o;17753:366::-;17895:3;17916:67;17980:2;17975:3;17916:67;:::i;:::-;17909:74;;17992:93;18081:3;17992:93;:::i;:::-;18110:2;18105:3;18101:12;18094:19;;17753:366;;;:::o;18125:419::-;18291:4;18329:2;18318:9;18314:18;18306:26;;18378:9;18372:4;18368:20;18364:1;18353:9;18349:17;18342:47;18406:131;18532:4;18406:131;:::i;:::-;18398:139;;18125:419;;;:::o;18550:170::-;18690:22;18686:1;18678:6;18674:14;18667:46;18550:170;:::o;18726:366::-;18868:3;18889:67;18953:2;18948:3;18889:67;:::i;:::-;18882:74;;18965:93;19054:3;18965:93;:::i;:::-;19083:2;19078:3;19074:12;19067:19;;18726:366;;;:::o;19098:419::-;19264:4;19302:2;19291:9;19287:18;19279:26;;19351:9;19345:4;19341:20;19337:1;19326:9;19322:17;19315:47;19379:131;19505:4;19379:131;:::i;:::-;19371:139;;19098:419;;;:::o;19523:165::-;19663:17;19659:1;19651:6;19647:14;19640:41;19523:165;:::o;19694:366::-;19836:3;19857:67;19921:2;19916:3;19857:67;:::i;:::-;19850:74;;19933:93;20022:3;19933:93;:::i;:::-;20051:2;20046:3;20042:12;20035:19;;19694:366;;;:::o;20066:419::-;20232:4;20270:2;20259:9;20255:18;20247:26;;20319:9;20313:4;20309:20;20305:1;20294:9;20290:17;20283:47;20347:131;20473:4;20347:131;:::i;:::-;20339:139;;20066:419;;;:::o;20491:442::-;20640:4;20678:2;20667:9;20663:18;20655:26;;20691:71;20759:1;20748:9;20744:17;20735:6;20691:71;:::i;:::-;20772:72;20840:2;20829:9;20825:18;20816:6;20772:72;:::i;:::-;20854;20922:2;20911:9;20907:18;20898:6;20854:72;:::i;:::-;20491:442;;;;;;:::o;20939:180::-;20987:77;20984:1;20977:88;21084:4;21081:1;21074:15;21108:4;21105:1;21098:15;21125:410;21165:7;21188:20;21206:1;21188:20;:::i;:::-;21183:25;;21222:20;21240:1;21222:20;:::i;:::-;21217:25;;21277:1;21274;21270:9;21299:30;21317:11;21299:30;:::i;:::-;21288:41;;21478:1;21469:7;21465:15;21462:1;21459:22;21439:1;21432:9;21412:83;21389:139;;21508:18;;:::i;:::-;21389:139;21173:362;21125:410;;;;:::o;21541:180::-;21589:77;21586:1;21579:88;21686:4;21683:1;21676:15;21710:4;21707:1;21700:15;21727:185;21767:1;21784:20;21802:1;21784:20;:::i;:::-;21779:25;;21818:20;21836:1;21818:20;:::i;:::-;21813:25;;21857:1;21847:35;;21862:18;;:::i;:::-;21847:35;21904:1;21901;21897:9;21892:14;;21727:185;;;;:::o;21918:162::-;22058:14;22054:1;22046:6;22042:14;22035:38;21918:162;:::o;22086:366::-;22228:3;22249:67;22313:2;22308:3;22249:67;:::i;:::-;22242:74;;22325:93;22414:3;22325:93;:::i;:::-;22443:2;22438:3;22434:12;22427:19;;22086:366;;;:::o;22458:419::-;22624:4;22662:2;22651:9;22647:18;22639:26;;22711:9;22705:4;22701:20;22697:1;22686:9;22682:17;22675:47;22739:131;22865:4;22739:131;:::i;:::-;22731:139;;22458:419;;;:::o;22883:141::-;22932:4;22955:3;22947:11;;22978:3;22975:1;22968:14;23012:4;23009:1;22999:18;22991:26;;22883:141;;;:::o;23030:93::-;23067:6;23114:2;23109;23102:5;23098:14;23094:23;23084:33;;23030:93;;;:::o;23129:107::-;23173:8;23223:5;23217:4;23213:16;23192:37;;23129:107;;;;:::o;23242:393::-;23311:6;23361:1;23349:10;23345:18;23384:97;23414:66;23403:9;23384:97;:::i;:::-;23502:39;23532:8;23521:9;23502:39;:::i;:::-;23490:51;;23574:4;23570:9;23563:5;23559:21;23550:30;;23623:4;23613:8;23609:19;23602:5;23599:30;23589:40;;23318:317;;23242:393;;;;;:::o;23641:60::-;23669:3;23690:5;23683:12;;23641:60;;;:::o;23707:142::-;23757:9;23790:53;23808:34;23817:24;23835:5;23817:24;:::i;:::-;23808:34;:::i;:::-;23790:53;:::i;:::-;23777:66;;23707:142;;;:::o;23855:75::-;23898:3;23919:5;23912:12;;23855:75;;;:::o;23936:269::-;24046:39;24077:7;24046:39;:::i;:::-;24107:91;24156:41;24180:16;24156:41;:::i;:::-;24148:6;24141:4;24135:11;24107:91;:::i;:::-;24101:4;24094:105;24012:193;23936:269;;;:::o;24211:73::-;24256:3;24211:73;:::o;24290:189::-;24367:32;;:::i;:::-;24408:65;24466:6;24458;24452:4;24408:65;:::i;:::-;24343:136;24290:189;;:::o;24485:186::-;24545:120;24562:3;24555:5;24552:14;24545:120;;;24616:39;24653:1;24646:5;24616:39;:::i;:::-;24589:1;24582:5;24578:13;24569:22;;24545:120;;;24485:186;;:::o;24677:543::-;24778:2;24773:3;24770:11;24767:446;;;24812:38;24844:5;24812:38;:::i;:::-;24896:29;24914:10;24896:29;:::i;:::-;24886:8;24882:44;25079:2;25067:10;25064:18;25061:49;;;25100:8;25085:23;;25061:49;25123:80;25179:22;25197:3;25179:22;:::i;:::-;25169:8;25165:37;25152:11;25123:80;:::i;:::-;24782:431;;24767:446;24677:543;;;:::o;25226:117::-;25280:8;25330:5;25324:4;25320:16;25299:37;;25226:117;;;;:::o;25349:169::-;25393:6;25426:51;25474:1;25470:6;25462:5;25459:1;25455:13;25426:51;:::i;:::-;25422:56;25507:4;25501;25497:15;25487:25;;25400:118;25349:169;;;;:::o;25523:295::-;25599:4;25745:29;25770:3;25764:4;25745:29;:::i;:::-;25737:37;;25807:3;25804:1;25800:11;25794:4;25791:21;25783:29;;25523:295;;;;:::o;25823:1395::-;25940:37;25973:3;25940:37;:::i;:::-;26042:18;26034:6;26031:30;26028:56;;;26064:18;;:::i;:::-;26028:56;26108:38;26140:4;26134:11;26108:38;:::i;:::-;26193:67;26253:6;26245;26239:4;26193:67;:::i;:::-;26287:1;26311:4;26298:17;;26343:2;26335:6;26332:14;26360:1;26355:618;;;;27017:1;27034:6;27031:77;;;27083:9;27078:3;27074:19;27068:26;27059:35;;27031:77;27134:67;27194:6;27187:5;27134:67;:::i;:::-;27128:4;27121:81;26990:222;26325:887;;26355:618;26407:4;26403:9;26395:6;26391:22;26441:37;26473:4;26441:37;:::i;:::-;26500:1;26514:208;26528:7;26525:1;26522:14;26514:208;;;26607:9;26602:3;26598:19;26592:26;26584:6;26577:42;26658:1;26650:6;26646:14;26636:24;;26705:2;26694:9;26690:18;26677:31;;26551:4;26548:1;26544:12;26539:17;;26514:208;;;26750:6;26741:7;26738:19;26735:179;;;26808:9;26803:3;26799:19;26793:26;26851:48;26893:4;26885:6;26881:17;26870:9;26851:48;:::i;:::-;26843:6;26836:64;26758:156;26735:179;26960:1;26956;26948:6;26944:14;26940:22;26934:4;26927:36;26362:611;;;26325:887;;25915:1303;;;25823:1395;;:::o;27224:165::-;27364:17;27360:1;27352:6;27348:14;27341:41;27224:165;:::o;27395:366::-;27537:3;27558:67;27622:2;27617:3;27558:67;:::i;:::-;27551:74;;27634:93;27723:3;27634:93;:::i;:::-;27752:2;27747:3;27743:12;27736:19;;27395:366;;;:::o;27767:419::-;27933:4;27971:2;27960:9;27956:18;27948:26;;28020:9;28014:4;28010:20;28006:1;27995:9;27991:17;27984:47;28048:131;28174:4;28048:131;:::i;:::-;28040:139;;27767:419;;;:::o;28192:234::-;28332:34;28328:1;28320:6;28316:14;28309:58;28401:17;28396:2;28388:6;28384:15;28377:42;28192:234;:::o;28432:366::-;28574:3;28595:67;28659:2;28654:3;28595:67;:::i;:::-;28588:74;;28671:93;28760:3;28671:93;:::i;:::-;28789:2;28784:3;28780:12;28773:19;;28432:366;;;:::o;28804:419::-;28970:4;29008:2;28997:9;28993:18;28985:26;;29057:9;29051:4;29047:20;29043:1;29032:9;29028:17;29021:47;29085:131;29211:4;29085:131;:::i;:::-;29077:139;;28804:419;;;:::o;29229:148::-;29331:11;29368:3;29353:18;;29229:148;;;;:::o;29383:390::-;29489:3;29517:39;29550:5;29517:39;:::i;:::-;29572:89;29654:6;29649:3;29572:89;:::i;:::-;29565:96;;29670:65;29728:6;29723:3;29716:4;29709:5;29705:16;29670:65;:::i;:::-;29760:6;29755:3;29751:16;29744:23;;29493:280;29383:390;;;;:::o;29779:155::-;29919:7;29915:1;29907:6;29903:14;29896:31;29779:155;:::o;29940:400::-;30100:3;30121:84;30203:1;30198:3;30121:84;:::i;:::-;30114:91;;30214:93;30303:3;30214:93;:::i;:::-;30332:1;30327:3;30323:11;30316:18;;29940:400;;;:::o;30346:701::-;30627:3;30649:95;30740:3;30731:6;30649:95;:::i;:::-;30642:102;;30761:95;30852:3;30843:6;30761:95;:::i;:::-;30754:102;;30873:148;31017:3;30873:148;:::i;:::-;30866:155;;31038:3;31031:10;;30346:701;;;;;:::o;31053:170::-;31193:22;31189:1;31181:6;31177:14;31170:46;31053:170;:::o;31229:366::-;31371:3;31392:67;31456:2;31451:3;31392:67;:::i;:::-;31385:74;;31468:93;31557:3;31468:93;:::i;:::-;31586:2;31581:3;31577:12;31570:19;;31229:366;;;:::o;31601:419::-;31767:4;31805:2;31794:9;31790:18;31782:26;;31854:9;31848:4;31844:20;31840:1;31829:9;31825:17;31818:47;31882:131;32008:4;31882:131;:::i;:::-;31874:139;;31601:419;;;:::o;32026:98::-;32077:6;32111:5;32105:12;32095:22;;32026:98;;;:::o;32130:168::-;32213:11;32247:6;32242:3;32235:19;32287:4;32282:3;32278:14;32263:29;;32130:168;;;;:::o;32304:373::-;32390:3;32418:38;32450:5;32418:38;:::i;:::-;32472:70;32535:6;32530:3;32472:70;:::i;:::-;32465:77;;32551:65;32609:6;32604:3;32597:4;32590:5;32586:16;32551:65;:::i;:::-;32641:29;32663:6;32641:29;:::i;:::-;32636:3;32632:39;32625:46;;32394:283;32304:373;;;;:::o;32683:640::-;32878:4;32916:3;32905:9;32901:19;32893:27;;32930:71;32998:1;32987:9;32983:17;32974:6;32930:71;:::i;:::-;33011:72;33079:2;33068:9;33064:18;33055:6;33011:72;:::i;:::-;33093;33161:2;33150:9;33146:18;33137:6;33093:72;:::i;:::-;33212:9;33206:4;33202:20;33197:2;33186:9;33182:18;33175:48;33240:76;33311:4;33302:6;33240:76;:::i;:::-;33232:84;;32683:640;;;;;;;:::o;33329:141::-;33385:5;33416:6;33410:13;33401:22;;33432:32;33458:5;33432:32;:::i;:::-;33329:141;;;;:::o;33476:349::-;33545:6;33594:2;33582:9;33573:7;33569:23;33565:32;33562:119;;;33600:79;;:::i;:::-;33562:119;33720:1;33745:63;33800:7;33791:6;33780:9;33776:22;33745:63;:::i;:::-;33735:73;;33691:127;33476:349;;;;:::o;33831:332::-;33952:4;33990:2;33979:9;33975:18;33967:26;;34003:71;34071:1;34060:9;34056:17;34047:6;34003:71;:::i;:::-;34084:72;34152:2;34141:9;34137:18;34128:6;34084:72;:::i;:::-;33831:332;;;;;:::o
Swarm Source
ipfs://552f6ac2ff539f540c6619e53d3fb02c3086f2f016d68b0be440973618904f97
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.