ERC-721
Overview
Max Total Supply
2,333 MORTI
Holders
978
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
2 MORTILoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Mortiverse
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-10-14 */ // SPDX-License-Identifier: MIT pragma solidity 0.8.17; // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) /** * @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; } } /** * @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. * * By default, the owner account will be the one that deploys the contract. 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; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @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 { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing 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 { require(newOwner != address(0), "Ownable: new owner is the zero address"); _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); } } // OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol) // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @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. * * _Available since v3.1._ */ 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 `account`. */ function renounceRole(bytes32 role, address account) external; } // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) // OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol) /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @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 up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (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; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 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. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); 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 (rounding == Rounding.Up && 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 down. * * 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 + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * 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 + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * 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 + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * 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 10, 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 + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } } library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { 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_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); 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); } } // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) /** * @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); } /** * @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); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } /** * @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: * * ``` * 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}: * * ``` * 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. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ 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 override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(account), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @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 override 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 override 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 override 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 `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @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 Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } } interface IBatchERC721 { error InvalidApprovalZeroAddress(); error CallerNotOwnerOrApprovedOperator(); error TransferToNonERC721ReceiverImplementer(); error InvalidTransferToZeroAddress(); error MintZeroTokenId(); error TokenNotOwnedByFromAddress(); error QueryNonExistentToken(); error QueryBalanceOfZeroAddress(); error QueryBurnedToken(); } // https://eips.ethereum.org/EIPS/eip-721, http://erc721.org/ /// @title ERC-721 Non-Fungible Token Standard /// @dev See https://eips.ethereum.org/EIPS/eip-721 /// Note: the ERC-165 identifier for this interface is 0x80ac58cd. interface IERC721 /* is ERC165 */ { /// @dev This emits when ownership of any NFT changes by any mechanism. /// This event emits when NFTs are created (`from` == 0) and destroyed /// (`to` == 0). Exception: during contract creation, any number of NFTs /// may be created and assigned without emitting Transfer. At the time of /// any transfer, the approved address for that NFT (if any) is reset to none. event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); /// @dev This emits when the approved address for an NFT is changed or /// reaffirmed. The zero address indicates there is no approved address. /// When a Transfer event emits, this also indicates that the approved /// address for that NFT (if any) is reset to none. event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); /// @dev This emits when an operator is enabled or disabled for an owner. /// The operator can manage all NFTs of the owner. event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); /// @notice Transfers the ownership of an NFT from one address to another address /// @dev Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if /// `_tokenId` is not a valid NFT. When transfer is complete, this function /// checks if `_to` is a smart contract (code size > 0). If so, it calls /// `onERC721Received` on `_to` and throws if the return value is not /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer /// @param data Additional data with no specified format, sent in call to `_to` function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes memory data) external; /// @notice Transfers the ownership of an NFT from one address to another address /// @dev This works identically to the other function with an extra data parameter, /// except this function just sets data to "". /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function safeTransferFrom(address _from, address _to, uint256 _tokenId) external; /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE /// THEY MAY BE PERMANENTLY LOST /// @dev Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if /// `_tokenId` is not a valid NFT. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function transferFrom(address _from, address _to, uint256 _tokenId) external; /// @notice Change or reaffirm the approved address for an NFT /// @dev The zero address indicates there is no approved address. /// Throws unless `msg.sender` is the current NFT owner, or an authorized /// operator of the current owner. /// @param _approved The new approved NFT controller /// @param _tokenId The NFT to approve function approve(address _approved, uint256 _tokenId) external; /// @notice Enable or disable approval for a third party ("operator") to manage /// all of `msg.sender`'s assets /// @dev Emits the ApprovalForAll event. The contract MUST allow /// multiple operators per owner. /// @param _operator Address to add to the set of authorized operators /// @param _approved True if the operator is approved, false to revoke approval function setApprovalForAll(address _operator, bool _approved) external; /// @notice Count all NFTs assigned to an owner /// @dev NFTs assigned to the zero address are considered invalid, and this /// function throws for queries about the zero address. /// @param _owner An address for whom to query the balance /// @return The number of NFTs owned by `_owner`, possibly zero function balanceOf(address _owner) external view returns (uint256); /// @notice Find the owner of an NFT /// @dev NFTs assigned to zero address are considered invalid, and queries /// about them do throw. /// @param _tokenId The identifier for an NFT /// @return The address of the owner of the NFT function ownerOf(uint256 _tokenId) external view returns (address); /// @notice Get the approved address for a single NFT /// @dev Throws if `_tokenId` is not a valid NFT. /// @param _tokenId The NFT to find the approved address for /// @return The approved address for this NFT, or the zero address if there is none function getApproved(uint256 _tokenId) external view returns (address); /// @notice Query if an address is an authorized operator for another address /// @param _owner The address that owns the NFTs /// @param _operator The address that acts on behalf of the owner /// @return True if `_operator` is an approved operator for `_owner`, false otherwise function isApprovedForAll(address _owner, address _operator) external view returns (bool); } interface IERC2309 { event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed fromAddress, address indexed toAddress); } /// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02. interface IERC721Receiver { /// @notice Handle the receipt of an NFT /// @dev The ERC721 smart contract calls this function on the recipient /// after a `transfer`. This function MAY throw to revert and reject the /// transfer. Return of other than the magic value MUST result in the /// transaction being reverted. /// Note: the contract address is always the message sender. /// @param _operator The address which called `safeTransferFrom` function /// @param _from The address which previously owned the token /// @param _tokenId The NFT identifier which is being transferred /// @param _data Additional data with no specified format /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` /// unless throwing function onERC721Received( address _operator, address _from, uint256 _tokenId, bytes calldata _data ) external returns (bytes4); } contract BatchERC721 is IERC165, IERC721, IERC2309, IBatchERC721 { bytes4 private constant ERC165_INTERFACE_ID = 0x01ffc9a7; bytes4 private constant ERC721_INTERFACE_ID = 0x80ac58cd; bytes4 private constant ERC721_RECEIVER_INTERFACE_ID = 0x150b7a02; bytes4 private constant ERC721_METADATA_INTERFACE_ID = 0x5b5e139f; string public baseURI; string internal uriExtension; string private _name; string private _symbol; uint256 private nextTokenId; uint256 private startingTokenId; uint256 private burnCounter; mapping(uint256 => address) private tokenOwnersOrdered; mapping(uint256 => bool) private unorderedOwner; mapping(uint256 => address) private tokenOwners; mapping(uint256 => address) private tokenOperators; mapping(uint256 => bool) private burnedTokens; mapping(address => uint256) private balances; mapping(address => mapping(address => bool)) private operators; constructor( string memory name_, string memory symbol_, uint256 startingTokenId_ ) { _name = name_; _symbol = symbol_; nextTokenId = startingTokenId = startingTokenId_; } /// @notice Change or reaffirm the approved address for an NFT /// @dev The zero address indicates there is no approved address. /// Throws unless `msg.sender` is the current NFT owner, or an authorized /// operator of the current owner. /// @param _approved The new approved NFT controller /// @param _tokenId The NFT to approve function approve(address _approved, uint256 _tokenId) external { _beforeSetApproval(_approved, true); if (_approved == address(0)) revert InvalidApprovalZeroAddress(); address owner = ownerOf(_tokenId); if ( owner != msg.sender && !operators[msg.sender][_approved] && tokenOperators[_tokenId] != msg.sender ) revert CallerNotOwnerOrApprovedOperator(); if (!unorderedOwner[_tokenId]) { tokenOwners[_tokenId] = owner; unorderedOwner[_tokenId] = true; } tokenOperators[_tokenId] = _approved; emit Approval(msg.sender, _approved, _tokenId); _afterSetApproval(_approved, true); } /// @notice Enable or disable approval for a third party ("operator") to manage /// all of `msg.sender`'s assets /// @dev Emits the ApprovalForAll event. The contract MUST allow /// multiple operators per owner. /// @param _operator Address to add to the set of authorized operators /// @param _approved True if the operator is approved, false to revoke approval function setApprovalForAll(address _operator, bool _approved) external { _beforeSetApproval(_operator, _approved); operators[msg.sender][_operator] = _approved; emit ApprovalForAll(msg.sender, _operator, _approved); _afterSetApproval(_operator, _approved); } /// @notice Get the approved address for a single NFT /// @dev Throws if `_tokenId` is not a valid NFT. /// @param _tokenId The NFT to find the approved address for /// @return The approved address for this NFT, or the zero address if there is none function getApproved(uint256 _tokenId) external view returns (address) { return ownerOf(_tokenId); } /// @notice Query if an address is an authorized operator for another address /// @param _owner The address that owns the NFTs /// @param _operator The address that acts on behalf of the owner /// @return True if `_operator` is an approved operator for `_owner`, false otherwise function isApprovedForAll(address _owner, address _operator) external view returns (bool) { return operators[_owner][_operator]; } /// @notice Name for NFTs in this contract function name() external view returns (string memory) { return _name; } /// @notice An abbreviated name for NFTs in this contract function symbol() external view returns (string memory) { return _symbol; } /// @notice A distinct Uniform Resource Identifier (URI) for a given asset. /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC /// 3986. The URI may point to a JSON file that conforms to the "ERC721 /// Metadata JSON Schema". function tokenURI(uint256 _tokenId) external view virtual returns (string memory) { if (_tokenId < startingTokenId || _tokenId > nextTokenId - 1) revert QueryNonExistentToken(); return bytes(baseURI).length > 0 ? string.concat( baseURI, Strings.toString(_tokenId), uriExtension ) : ""; } /// @notice Count NFTs tracked by this contract /// @return A count of valid NFTs tracked by this contract, where each one of /// them has an assigned and queryable owner not equal to the zero address function totalSupply() external view returns (uint256) { return nextTokenId - startingTokenId - burnCounter; } /// @notice Count all NFTs assigned to an owner /// @dev NFTs assigned to the zero address are considered invalid, and this /// function throws for queries about the zero address. /// @param _owner An address for whom to query the balance /// @return The number of NFTs owned by `_owner`, possibly zero function balanceOf(address _owner) external view returns (uint256) { if (_owner == address(0)) revert QueryBalanceOfZeroAddress(); return balances[_owner]; } /// @notice Verify whether a token exists and has not been burned /// @param _tokenId The token id /// @return bool function exists(uint256 _tokenId) external view returns (bool) { return _tokenId >= startingTokenId && _tokenId < nextTokenId && !burnedTokens[_tokenId]; } /// @notice Transfers the ownership of an NFT from one address to another address /// @dev This works identically to the other function with an extra data parameter, /// except this function just sets data to "". /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function safeTransferFrom( address _from, address _to, uint256 _tokenId ) public { safeTransferFrom(_from, _to, _tokenId, ""); } /// @notice Transfers the ownership of an NFT from one address to another address /// @dev Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if /// `_tokenId` is not a valid NFT. When transfer is complete, this function /// checks if `_to` is a smart contract (code size > 0). If so, it calls /// `onERC721Received` on `_to` and throws if the return value is not /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer /// @param data Additional data with no specified format, sent in call to `_to` function safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes memory data ) public { transferFrom(_from, _to, _tokenId); if (_to.code.length > 0) { _checkERC721Received(_from, _to, _tokenId, data); } } /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE /// THEY MAY BE PERMANENTLY LOST /// @dev Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if /// `_tokenId` is not a valid NFT. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function transferFrom( address _from, address _to, uint256 _tokenId ) public { if (_tokenId < startingTokenId || _tokenId > nextTokenId - 1) revert QueryNonExistentToken(); address owner = ownerOf(_tokenId); if (owner != _from) revert TokenNotOwnedByFromAddress(); if ( owner != msg.sender && !operators[_from][msg.sender] && tokenOperators[_tokenId] != msg.sender ) revert CallerNotOwnerOrApprovedOperator(); if (_to == address(0)) revert InvalidTransferToZeroAddress(); _beforeTokenTransfer(_from, _to, _tokenId); balances[_from] -= 1; balances[_to] += 1; tokenOperators[_tokenId] = address(0); tokenOwners[_tokenId] = _to; unorderedOwner[_tokenId] = true; emit Transfer(_from, _to, _tokenId); _afterTokenTransfer(_from, _to, _tokenId); } /// @notice Find the owner of an NFT /// @dev NFTs assigned to zero address are considered invalid, and queries /// about them do throw. /// @param _tokenId The identifier for an NFT /// @return The address of the owner of the NFT function ownerOf(uint256 _tokenId) public view returns (address) { if (_tokenId < startingTokenId || _tokenId > nextTokenId) revert QueryNonExistentToken(); if (burnedTokens[_tokenId]) revert QueryBurnedToken(); return unorderedOwner[_tokenId] ? tokenOwners[_tokenId] : _ownerOf(_tokenId); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == ERC165_INTERFACE_ID || interfaceId == ERC721_INTERFACE_ID || interfaceId == ERC721_RECEIVER_INTERFACE_ID || interfaceId == ERC721_METADATA_INTERFACE_ID; } /// @notice Find the owner of an NFT /// @dev Does not revert if token is burned, this is used to query via multi-call /// @param _tokenId The identifier for an NFT /// @return The address of the owner of the NFT function unsafeOwnerOf(uint256 _tokenId) public view returns (address) { if (burnedTokens[_tokenId]) return address(0); return unorderedOwner[_tokenId] ? tokenOwners[_tokenId] : _ownerOf(_tokenId); } function _mint2309(address _to, uint256 _quantity) internal { if (_to == address(0)) revert InvalidTransferToZeroAddress(); if (_quantity == 0) revert MintZeroTokenId(); unchecked { balances[_to] += _quantity; uint256 newTotal = nextTokenId + _quantity; tokenOwnersOrdered[nextTokenId] = _to; nextTokenId = newTotal; } emit ConsecutiveTransfer( startingTokenId, nextTokenId - 1, address(0), _to ); } /// @notice Same as calling {_mint} and then checking for IERC721Receiver function safeMint(address _to, uint256 _quantity) internal { safeMint(_to, _quantity, ""); } /// @notice Same as calling {_mint} and then checking for IERC721Receiver function safeMint( address _to, uint256 _quantity, bytes memory _data ) internal { _mint(_to, _quantity); uint256 currentTokenId = nextTokenId - 1; unchecked { if (_to.code.length != 0) { uint256 tokenId = nextTokenId - _quantity - 1; do { if ( !_checkERC721Received(address(0), _to, ++tokenId, _data) ) { revert TransferToNonERC721ReceiverImplementer(); } } while (tokenId < currentTokenId); } } } /// @notice Mint a quantity of NFTs to an address /// @dev Saves the first token id minted by the address to a map of /// used to verify ownership initially. /// {tokenOwnersOrdered} will be used to find the owner unless the token /// has been transfered. In that case, it will be available in {tokenOwners} instead. /// This is done to reduce gas requirements of minting while keeping on-chain lookups /// cheaper as tokens are transfered around. It helps with the burning of tokens. /// @param _to Receiver address /// @param _quantity The quantity to be minted function _mint(address _to, uint256 _quantity) internal { if (_to == address(0)) revert InvalidTransferToZeroAddress(); if (_quantity == 0) revert MintZeroTokenId(); unchecked { balances[_to] += _quantity; uint256 newTotal = nextTokenId + _quantity; for (uint256 i = nextTokenId; i < newTotal; i++) { emit Transfer(address(0), _to, i); } tokenOwnersOrdered[nextTokenId] = _to; nextTokenId = newTotal; } } /// @notice Same as calling {_burn} without a from address or approval check function _burn(uint256 _tokenId) internal { _burn(_tokenId, msg.sender); } /// @notice Same as calling {_burn} without approval check function _burn(uint256 _tokenId, address _from) internal { _burn(_tokenId, _from, false); } /// @notice Burn an NFT /// @dev Checks ownership of the token /// @param _tokenId The token id /// @param _from The owner address /// @param _approvalCheck Check if the caller is owner or an approved operator function _burn( uint256 _tokenId, address _from, bool _approvalCheck ) internal { if (_tokenId < startingTokenId || _tokenId > nextTokenId - 1) revert QueryNonExistentToken(); address owner = ownerOf(_tokenId); if (owner != _from) revert TokenNotOwnedByFromAddress(); if (_approvalCheck) { if ( owner != msg.sender && !operators[_from][msg.sender] && tokenOperators[_tokenId] != msg.sender ) revert CallerNotOwnerOrApprovedOperator(); } balances[_from]--; burnCounter++; burnedTokens[_tokenId] = true; tokenOperators[_tokenId] = address(0); emit Transfer(_from, address(0), _tokenId); } /// @notice Before Approval Hook /// @param _operator Operator /// @param _approved Approved /* solhint-disable no-empty-blocks */ function _beforeSetApproval(address _operator, bool _approved) internal virtual {} /* solhint-disable no-empty-blocks */ /// @notice Before Approval Hook /// @param _operator Operator /// @param _approved Approved /* solhint-disable no-empty-blocks */ function _afterSetApproval(address _operator, bool _approved) internal virtual {} /* solhint-disable no-empty-blocks */ /// @notice Before Token Transfer Hook /// @param from Token owner /// @param to Receiver /// @param tokenId The token id /* solhint-disable no-empty-blocks */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} /* solhint-disable no-empty-blocks */ /// @notice After Token Transfer Hook /// @param from Token owner /// @param to Receiver /// @param tokenId The token id /* solhint-disable no-empty-blocks */ function _afterTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} /* solhint-disable no-empty-blocks */ /// @notice Checking if the receiving contract implements IERC721Receiver /// @param from Token owner /// @param to Receiver /// @param tokenId The token id /// @param _data Extra data function _checkERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) internal returns (bool) { try IERC721Receiver(to).onERC721Received( msg.sender, from, tokenId, _data ) returns (bytes4 retval) { return retval == IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } /// @notice Count NFTs minted by this contract /// @dev Includes burned tokens /// @return A count of valid NFTs tracked by this contract, where each one of /// them has an assigned and queryable owner not equal to the zero address function _totalMinted() internal view returns (uint256) { return nextTokenId - startingTokenId; } /// @notice Find the owner of an NFT /// @dev This function should only be called from {ownerOf(_tokenId)} /// This iterates through the original minters since they are ordered /// If an owner is address(0), it keeps looking for the owner by checking the /// previous tokens. If minter A minted 10, then the first token will have the address /// and the rest will have address(0) /// @param _tokenId The identifier for an NFT /// @return The address of the owner of the NFT function _ownerOf(uint256 _tokenId) internal view virtual returns (address) { uint256 curr = _tokenId; unchecked { address owner; // Invariant: // There will always be an ownership that has an address and is not burned // before an ownership that does not have an address and is not burned. // Hence, curr will not underflow. while (owner == address(0)) { if (!unorderedOwner[curr]) { owner = tokenOwnersOrdered[curr]; } curr--; } return owner; } } } interface IOperatorFilter { function mayTransfer(address operator) external view returns (bool); } abstract contract ERC721OperatorFilter is BatchERC721, Ownable, AccessControl { IOperatorFilter private operatorFilter_; constructor( string memory name_, string memory symbol_, uint256 startingTokenId_, address filter ) Ownable() BatchERC721(name_, symbol_, startingTokenId_) AccessControl() { operatorFilter_ = IOperatorFilter(filter); } function setOperatorFilter(IOperatorFilter filter) public onlyRole(DEFAULT_ADMIN_ROLE) { operatorFilter_ = filter; } function operatorFilter() public view returns (IOperatorFilter) { return operatorFilter_; } function supportsInterface(bytes4 interfaceId) public view virtual override(BatchERC721, AccessControl) returns (bool) { return interfaceId == type(AccessControl).interfaceId || BatchERC721.supportsInterface(interfaceId); } function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual override(BatchERC721) { if ( from != address(0) && to != address(0) && !_mayTransfer(msg.sender, tokenId) ) { revert("ERC721OperatorFilter: illegal operator"); } super._beforeTokenTransfer(from, to, tokenId); } function _beforeSetApproval(address _operator, bool _approved) internal virtual override { if(_approved && !_mayOperate(_operator)) revert("ERC721OperatorFilter: illegal operator"); super._beforeSetApproval(_operator, _approved); } function _mayOperate(address operator) private view returns (bool) { IOperatorFilter filter = operatorFilter_; return filter.mayTransfer(operator); } function _mayTransfer(address operator, uint256 tokenId) private view returns (bool) { IOperatorFilter filter = operatorFilter_; if (address(filter) == address(0)) return true; if (operator == ownerOf(tokenId)) return true; return filter.mayTransfer(msg.sender); } } // OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol) // OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol) /** * @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. * * _Available since v4.5._ */ 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); } /** * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the * fee is specified in basis points by default. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. * * _Available since v4.5._ */ abstract contract ERC2981 is IERC2981, ERC165 { struct RoyaltyInfo { address receiver; uint96 royaltyFraction; } RoyaltyInfo private _defaultRoyaltyInfo; mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } /** * @inheritdoc IERC2981 */ function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) { RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId]; if (royalty.receiver == address(0)) { royalty = _defaultRoyaltyInfo; } uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator(); return (royalty.receiver, royaltyAmount); } /** * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an * override. */ function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /** * @dev Sets the royalty information that all ids in this contract will default to. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); require(receiver != address(0), "ERC2981: invalid receiver"); _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Removes default royalty information. */ function _deleteDefaultRoyalty() internal virtual { delete _defaultRoyaltyInfo; } /** * @dev Sets the royalty information for a specific token id, overriding the global default. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setTokenRoyalty( uint256 tokenId, address receiver, uint96 feeNumerator ) internal virtual { require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); require(receiver != address(0), "ERC2981: Invalid parameters"); _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Resets royalty information for the token id back to the global default. */ function _resetTokenRoyalty(uint256 tokenId) internal virtual { delete _tokenRoyaltyInfo[tokenId]; } } // OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol) /** * @dev These functions deal with verification of Merkle Tree proofs. * * The proofs can be generated using the JavaScript library * https://github.com/miguelmota/merkletreejs[merkletreejs]. * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled. * * See `test/utils/cryptography/MerkleProof.test.js` for some examples. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} * * _Available since v4.7._ */ function verifyCalldata( bytes32[] calldata proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} * * _Available since v4.7._ */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * _Available since v4.7._ */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } } interface IMortiverse { error InvalidETHQuantity(); error MaxSupply(); error NonExistentTokenURI(); error WithdrawTransfer(); error NotInAllowlist(); error ExceedsMintAllowance(); error InvalidURI(); error LengthsMismatch(); error NotAllowlistPhase(); error NotPublicPhase(); error PublicSaleMustStartAfterAllowlist(); error NewAllowanceLowerThanActual(); error IllegalOperator(); } contract Mortiverse is ERC721OperatorFilter, ERC2981, IMortiverse { struct SaleConfig { uint128 allowlist; uint128 publicSale; } enum Phase { CLOSED, ALLOWLIST, PUBLIC, OVER } uint256 public constant TOTAL_SUPPLY = 5555; bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE"); string public contractURI = "ipfs://QmR2y7P2m9cbmtc31LskvVcbn2qxJPWNE4EvrioJJjPukJ"; uint256 public price = 0.029 ether; uint256 public mintAllowance = 2; bytes32 public allowlistMerkleRoot; mapping(address => uint256) private mints; SaleConfig public saleConfig; modifier isMintable(uint256 quantity) { if (price * quantity != msg.value) { revert InvalidETHQuantity(); } if (_totalMinted() + quantity > TOTAL_SUPPLY) { revert MaxSupply(); } if (mints[msg.sender] + quantity > mintAllowance) { revert ExceedsMintAllowance(); } _; } constructor( address owner_, address manager_, uint256 initialQty_, address filter_ ) ERC721OperatorFilter("Mortiverse", "MORTI", 1, filter_) { baseURI = "ipfs://QmWpxg6xzYgZhdzoejrp8HFxUppr8sPQaV6kE5XasfuZeX/"; uriExtension = ".json"; _grantRole(DEFAULT_ADMIN_ROLE, owner_); _grantRole(DEFAULT_ADMIN_ROLE, manager_); _grantRole(MANAGER_ROLE, owner_); _grantRole(MANAGER_ROLE, manager_); _setDefaultRoyalty(owner_, 750); saleConfig = SaleConfig(1665763200, 1665777600); if(initialQty_ > 0) { _mint2309(owner_, initialQty_); } _transferOwnership(manager_); } function allowlistMint(bytes32[] calldata merkleProof, uint256 quantity) external payable isMintable(quantity) { if (currentPhase() != Phase.ALLOWLIST) revert NotAllowlistPhase(); bytes32 leaf = keccak256(abi.encodePacked(msg.sender)); if (!MerkleProof.verify(merkleProof, allowlistMerkleRoot, leaf)) { revert NotInAllowlist(); } mints[msg.sender] += quantity; safeMint(msg.sender, quantity); } function mint(uint256 quantity) external payable isMintable(quantity) { if (currentPhase() != Phase.PUBLIC) revert NotPublicPhase(); mints[msg.sender] += quantity; safeMint(msg.sender, quantity); } function ownerMint(address recipient, uint256 quantity) external onlyRole(DEFAULT_ADMIN_ROLE) { safeMint(recipient, quantity); } function airdrop( address[] calldata receivers, uint256[] calldata quantities ) external onlyRole(DEFAULT_ADMIN_ROLE) { if (receivers.length != quantities.length) revert LengthsMismatch(); uint256 total; for (uint256 i = 0; i < quantities.length; i++) { total += quantities[i]; } if (_totalMinted() + total > TOTAL_SUPPLY) revert MaxSupply(); for (uint256 i = 0; i < receivers.length; i++) { safeMint(receivers[i], quantities[i]); } } function setContractURI(string calldata _contractURI) external onlyRole(MANAGER_ROLE) { if (bytes(_contractURI).length == 0) { revert InvalidURI(); } contractURI = _contractURI; } function setBaseURI(string calldata _baseURI) external onlyRole(MANAGER_ROLE) { if (bytes(_baseURI).length == 0) { revert InvalidURI(); } baseURI = _baseURI; } function setURIExtension(string calldata _extension) external onlyRole(MANAGER_ROLE) { if (bytes(_extension).length == 0) { uriExtension = ""; } uriExtension = _extension; } function setSaleConfig(uint128 allowlistTimestamp, uint128 publicTimestamp) external onlyRole(MANAGER_ROLE) { if (allowlistTimestamp >= publicTimestamp) revert PublicSaleMustStartAfterAllowlist(); saleConfig = SaleConfig(allowlistTimestamp, publicTimestamp); } function setAllowlistRoot(bytes32 merkleRoot) external onlyRole(MANAGER_ROLE) { allowlistMerkleRoot = merkleRoot; } function setDefaultAdmin() external onlyOwner { _grantRole(DEFAULT_ADMIN_ROLE, owner()); } function withdrawPayments(address payable payee) external onlyRole(DEFAULT_ADMIN_ROLE) { uint256 balance = address(this).balance; (bool transferTx, ) = payee.call{value: balance}(""); // solhint-disable-line avoid-low-level-calls if (!transferTx) { revert WithdrawTransfer(); } } /// @notice Sets the royalty information that all ids in this contract will default to. /// @dev Explain to a developer any extra details /// @param receiver cannot be the zero address. /// @param feeNumerator cannot be greater than the fee denominator. function setDefaultRoyalty(address receiver, uint96 feeNumerator) external onlyRole(DEFAULT_ADMIN_ROLE) { _setDefaultRoyalty(receiver, feeNumerator); } // @notice Sets the royalty information that token ids. /// @dev to Resets royalty information set _feeNumerator to 0 /// @param tokenId the specific token id to Sets the royalty information for /// @param receiver the address that will receive the royalty /// @param feeNumerator cannot be greater than the fee denominator other case revert with InvalidFeeNumerator function setTokenRoyalty( uint256 tokenId, address receiver, uint96 feeNumerator ) external onlyRole(DEFAULT_ADMIN_ROLE) { _setTokenRoyalty(tokenId, receiver, feeNumerator); } function setMintAllowance(uint256 allowance) external onlyRole(MANAGER_ROLE) { if(allowance <= mintAllowance) revert NewAllowanceLowerThanActual(); mintAllowance = allowance; } function setPrice(uint256 newPrice) external onlyRole(MANAGER_ROLE) { price = newPrice; } // solhint-disable not-rely-on-time function currentPhase() public view returns (Phase) { if (_totalMinted() == TOTAL_SUPPLY) { return Phase.OVER; } else if (block.timestamp > saleConfig.publicSale) { return Phase.PUBLIC; } else if (block.timestamp > saleConfig.allowlist) { return Phase.ALLOWLIST; } else { return Phase.CLOSED; } } // solhint-enable function userAllowance(address user) public view returns (uint256) { return mintAllowance - mints[user]; } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721OperatorFilter, ERC2981) returns (bool) { return interfaceId == 0x2a55205a || // ERC165 Interface ID for ERC2981 ERC721OperatorFilter.supportsInterface(interfaceId); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"manager_","type":"address"},{"internalType":"uint256","name":"initialQty_","type":"uint256"},{"internalType":"address","name":"filter_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CallerNotOwnerOrApprovedOperator","type":"error"},{"inputs":[],"name":"ExceedsMintAllowance","type":"error"},{"inputs":[],"name":"IllegalOperator","type":"error"},{"inputs":[],"name":"InvalidApprovalZeroAddress","type":"error"},{"inputs":[],"name":"InvalidETHQuantity","type":"error"},{"inputs":[],"name":"InvalidTransferToZeroAddress","type":"error"},{"inputs":[],"name":"InvalidURI","type":"error"},{"inputs":[],"name":"LengthsMismatch","type":"error"},{"inputs":[],"name":"MaxSupply","type":"error"},{"inputs":[],"name":"MintZeroTokenId","type":"error"},{"inputs":[],"name":"NewAllowanceLowerThanActual","type":"error"},{"inputs":[],"name":"NonExistentTokenURI","type":"error"},{"inputs":[],"name":"NotAllowlistPhase","type":"error"},{"inputs":[],"name":"NotInAllowlist","type":"error"},{"inputs":[],"name":"NotPublicPhase","type":"error"},{"inputs":[],"name":"PublicSaleMustStartAfterAllowlist","type":"error"},{"inputs":[],"name":"QueryBalanceOfZeroAddress","type":"error"},{"inputs":[],"name":"QueryBurnedToken","type":"error"},{"inputs":[],"name":"QueryNonExistentToken","type":"error"},{"inputs":[],"name":"TokenNotOwnedByFromAddress","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"WithdrawTransfer","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":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":true,"internalType":"address","name":"toAddress","type":"address"}],"name":"ConsecutiveTransfer","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":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"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOTAL_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"receivers","type":"address[]"},{"internalType":"uint256[]","name":"quantities","type":"uint256[]"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"allowlistMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"allowlistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_approved","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":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentPhase","outputs":[{"internalType":"enum Mortiverse.Phase","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"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":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintAllowance","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":"operatorFilter","outputs":[{"internalType":"contract IOperatorFilter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","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":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"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":[],"name":"saleConfig","outputs":[{"internalType":"uint128","name":"allowlist","type":"uint128"},{"internalType":"uint128","name":"publicSale","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"setAllowlistRoot","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":"_baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_contractURI","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setDefaultAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"allowance","type":"uint256"}],"name":"setMintAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IOperatorFilter","name":"filter","type":"address"}],"name":"setOperatorFilter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"allowlistTimestamp","type":"uint128"},{"internalType":"uint128","name":"publicTimestamp","type":"uint128"}],"name":"setSaleConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setTokenRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_extension","type":"string"}],"name":"setURIExtension","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":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"uint256","name":"_tokenId","type":"uint256"}],"name":"unsafeOwnerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"userAllowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"payee","type":"address"}],"name":"withdrawPayments","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60e060405260356080818152906200388960a039601390620000229082620005a3565b5066670758aa7c800060145560026015553480156200004057600080fd5b50604051620039143803806200391483398101604081905262000063916200068c565b6040518060400160405280600a8152602001694d6f727469766572736560b01b815250604051806040016040528060058152602001644d4f52544960d81b8152506001838383838260029081620000bb9190620005a3565b506003620000ca8382620005a3565b50600581905560045550620000e190503362000215565b601080546001600160a01b0319166001600160a01b0392909216919091179055505060408051606081019091526036808252909150620038de60208301396000906200012e9082620005a3565b50604080518082019091526005815264173539b7b760d91b60208201526001906200015a9082620005a3565b506200016860008562000267565b6200017560008462000267565b62000190600080516020620038be8339815191528562000267565b620001ab600080516020620038be8339815191528462000267565b620001b9846102ee620002f2565b6040805180820190915263634987808152636349bfc0602090910152736349bfc00000000000000000000000006349878060185581156200020057620002008483620003f7565b6200020b8362000215565b5050505062000702565b600e80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b620002738282620004d1565b620002ee576000828152600f602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620002ad3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6127106001600160601b0382161115620003665760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084015b60405180910390fd5b6001600160a01b038216620003be5760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c69642072656365697665720000000000000060448201526064016200035d565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217601155565b6001600160a01b0382166200041f5760405163163ae22d60e11b815260040160405180910390fd5b80600003620004415760405163eb1d0cf560e01b815260040160405180910390fd5b6001600160a01b0382166000818152600c6020908152604080832080548601905560048054808552600790935290832080546001600160a01b0319168517905590840190819055600554907fdeaa91b6123d068f5821d0fb0678463d1a8a6079fe8af5de3ce5e896dcf9133d90620004bc90600190620006e0565b60405190815260200160405180910390a45050565b6000828152600f602090815260408083206001600160a01b038516845290915290205460ff165b92915050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200052957607f821691505b6020821081036200054a57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200059e57600081815260208120601f850160051c81016020861015620005795750805b601f850160051c820191505b818110156200059a5782815560010162000585565b5050505b505050565b81516001600160401b03811115620005bf57620005bf620004fe565b620005d781620005d0845462000514565b8462000550565b602080601f8311600181146200060f5760008415620005f65750858301515b600019600386901b1c1916600185901b1785556200059a565b600085815260208120601f198616915b8281101562000640578886015182559484019460019091019084016200061f565b50858210156200065f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b80516001600160a01b03811681146200068757600080fd5b919050565b60008060008060808587031215620006a357600080fd5b620006ae856200066f565b9350620006be602086016200066f565b925060408501519150620006d5606086016200066f565b905092959194509250565b81810381811115620004f857634e487b7160e01b600052601160045260246000fd5b61317780620007126000396000f3fe60806040526004361061031a5760003560e01c806367243482116101ab57806395d89b41116100f7578063c87b56dd11610095578063e8a3d4851161006f578063e8a3d48514610952578063e985e9c514610967578063ec87621c146109b0578063f2fde38b146109d257600080fd5b8063c87b56dd146108f2578063d547741f14610912578063d783925b1461093257600080fd5b8063a217fddf116100d1578063a217fddf1461087d578063a22cb46514610892578063acf080d1146108b2578063b88d4fde146108d257600080fd5b806395d89b411461083f578063a035b1fe14610854578063a0712d681461086a57600080fd5b80638e0acd121161016457806390aa0b0f1161013e57806390aa0b0f1461079457806391b7f5ed146107df57806391d14854146107ff578063938e3d7b1461081f57600080fd5b80638e0acd121461073e578063902d55a51461075e578063907097511461077457600080fd5b80636724348214610698578063689843e0146106b85780636c0360eb146106d657806370a08231146106eb578063715018a61461070b5780638da5cb5b1461072057600080fd5b80632a55205a1161026a57806342842e0e116102235780634f558e79116101fd5780634f558e791461061857806355f804b3146106385780635944c753146106585780636352211e1461067857600080fd5b806342842e0e146105b85780634777a597146105d8578063484b973c146105f857600080fd5b80632a55205a146104ee5780632f2ff15d1461052d57806331b3eb941461054d57806336568abe1461056d57806338a59d971461058d578063396876bd146105a257600080fd5b8063095ea7b3116102d757806318160ddd116102b157806318160ddd1461047357806323b872dd14610488578063248a9ca3146104a8578063293108e0146104d857600080fd5b8063095ea7b3146104125780630c6b2cbf146104325780631338a83f1461046057600080fd5b806301ffc9a71461031f57806304392a4c1461035457806304634d8d14610376578063055ad42e1461039657806306fdde03146103b8578063081812fc146103da575b600080fd5b34801561032b57600080fd5b5061033f61033a3660046126b9565b6109f2565b60405190151581526020015b60405180910390f35b34801561036057600080fd5b5061037461036f3660046126f2565b610a1d565b005b34801561038257600080fd5b50610374610391366004612751565b610a9a565b3480156103a257600080fd5b506103ab610ab4565b60405161034b9190612793565b3480156103c457600080fd5b506103cd610b0b565b60405161034b919061280b565b3480156103e657600080fd5b506103fa6103f536600461281e565b610b9d565b6040516001600160a01b03909116815260200161034b565b34801561041e57600080fd5b5061037461042d366004612837565b610ba8565b34801561043e57600080fd5b5061045261044d366004612863565b610d12565b60405190815260200161034b565b61037461046e3660046128c5565b610d38565b34801561047f57600080fd5b50610452610ede565b34801561049457600080fd5b506103746104a3366004612911565b610f02565b3480156104b457600080fd5b506104526104c336600461281e565b6000908152600f602052604090206001015490565b3480156104e457600080fd5b5061045260165481565b3480156104fa57600080fd5b5061050e610509366004612952565b61110c565b604080516001600160a01b03909316835260208301919091520161034b565b34801561053957600080fd5b50610374610548366004612974565b6111ba565b34801561055957600080fd5b50610374610568366004612863565b6111df565b34801561057957600080fd5b50610374610588366004612974565b61125e565b34801561059957600080fd5b506103746112e1565b3480156105ae57600080fd5b5061045260155481565b3480156105c457600080fd5b506103746105d3366004612911565b611307565b3480156105e457600080fd5b506103fa6105f336600461281e565b611322565b34801561060457600080fd5b50610374610613366004612837565b611381565b34801561062457600080fd5b5061033f61063336600461281e565b611396565b34801561064457600080fd5b506103746106533660046129a4565b6113c9565b34801561066457600080fd5b50610374610673366004612a16565b611410565b34801561068457600080fd5b506103fa61069336600461281e565b611426565b3480156106a457600080fd5b506103746106b3366004612a54565b611486565b3480156106c457600080fd5b506010546001600160a01b03166103fa565b3480156106e257600080fd5b506103cd611599565b3480156106f757600080fd5b50610452610706366004612863565b611627565b34801561071757600080fd5b5061037461166b565b34801561072c57600080fd5b50600e546001600160a01b03166103fa565b34801561074a57600080fd5b5061037461075936600461281e565b61167d565b34801561076a57600080fd5b506104526115b381565b34801561078057600080fd5b5061037461078f3660046129a4565b61169b565b3480156107a057600080fd5b506018546107bf906001600160801b0380821691600160801b90041682565b604080516001600160801b0393841681529290911660208301520161034b565b3480156107eb57600080fd5b506103746107fa36600461281e565b6116e7565b34801561080b57600080fd5b5061033f61081a366004612974565b611705565b34801561082b57600080fd5b5061037461083a3660046129a4565b611730565b34801561084b57600080fd5b506103cd611777565b34801561086057600080fd5b5061045260145481565b61037461087836600461281e565b611786565b34801561088957600080fd5b50610452600081565b34801561089e57600080fd5b506103746108ad366004612ace565b61188e565b3480156108be57600080fd5b506103746108cd36600461281e565b611904565b3480156108de57600080fd5b506103746108ed366004612b12565b611944565b3480156108fe57600080fd5b506103cd61090d36600461281e565b61196b565b34801561091e57600080fd5b5061037461092d366004612974565b611a06565b34801561093e57600080fd5b5061037461094d366004612863565b611a2b565b34801561095e57600080fd5b506103cd611a59565b34801561097357600080fd5b5061033f610982366004612bf2565b6001600160a01b039182166000908152600d6020908152604080832093909416825291909152205460ff1690565b3480156109bc57600080fd5b5061045260008051602061312283398151915281565b3480156109de57600080fd5b506103746109ed366004612863565b611a66565b600063152a902d60e11b6001600160e01b031983161480610a175750610a1782611adf565b92915050565b600080516020613122833981519152610a3581611b04565b816001600160801b0316836001600160801b031610610a6757604051636de2dbdf60e01b815260040160405180910390fd5b50604080518082019091526001600160801b03928316808252919092166020909201829052600160801b90910217601855565b6000610aa581611b04565b610aaf8383611b0e565b505050565b60006115b3610ac1611bc8565b03610acc5750600390565b601854600160801b90046001600160801b0316421115610aec5750600290565b6018546001600160801b0316421115610b055750600190565b50600090565b606060028054610b1a90612c20565b80601f0160208091040260200160405190810160405280929190818152602001828054610b4690612c20565b8015610b935780601f10610b6857610100808354040283529160200191610b93565b820191906000526020600020905b815481529060010190602001808311610b7657829003601f168201915b5050505050905090565b6000610a1782611426565b610bb3826001611bda565b6001600160a01b038216610bda576040516306c8ec8f60e31b815260040160405180910390fd5b6000610be582611426565b90506001600160a01b0381163314801590610c245750336000908152600d602090815260408083206001600160a01b038716845290915290205460ff16155b8015610c4757506000828152600a60205260409020546001600160a01b03163314155b15610c655760405163449de15f60e11b815260040160405180910390fd5b60008281526008602052604090205460ff16610cb857600082815260096020908152604080832080546001600160a01b0319166001600160a01b03861617905560089091529020805460ff191660011790555b6000828152600a602052604080822080546001600160a01b0319166001600160a01b0387169081179091559051849233917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a4505050565b6001600160a01b038116600090815260176020526040812054601554610a179190612c70565b803481601454610d489190612c83565b14610d66576040516303b59b0160e61b815260040160405180910390fd5b6115b381610d72611bc8565b610d7c9190612c9a565b1115610d9b57604051632cdb04a160e21b815260040160405180910390fd5b60155433600090815260176020526040902054610db9908390612c9a565b1115610dd857604051637335356360e01b815260040160405180910390fd5b6001610de2610ab4565b6003811115610df357610df361277d565b14610e115760405163bb8f723160e01b815260040160405180910390fd5b6040516bffffffffffffffffffffffff193360601b166020820152600090603401604051602081830303815290604052805190602001209050610e8b858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506016549150849050611c0a565b610ea8576040516315ebf2b560e21b815260040160405180910390fd5b3360009081526017602052604081208054859290610ec7908490612c9a565b90915550610ed790503384611c20565b5050505050565b6000600654600554600454610ef39190612c70565b610efd9190612c70565b905090565b600554811080610f1f57506001600454610f1c9190612c70565b81115b15610f3d57604051635f22452f60e01b815260040160405180910390fd5b6000610f4882611426565b9050836001600160a01b0316816001600160a01b031614610f7c576040516311f1e70d60e11b815260040160405180910390fd5b6001600160a01b0381163314801590610fb957506001600160a01b0384166000908152600d6020908152604080832033845290915290205460ff16155b8015610fdc57506000828152600a60205260409020546001600160a01b03163314155b15610ffa5760405163449de15f60e11b815260040160405180910390fd5b6001600160a01b0383166110215760405163163ae22d60e11b815260040160405180910390fd5b61102c848484611c3a565b6001600160a01b0384166000908152600c60205260408120805460019290611055908490612c70565b90915550506001600160a01b0383166000908152600c60205260408120805460019290611083908490612c9a565b90915550506000828152600a6020908152604080832080546001600160a01b03199081169091556009835281842080546001600160a01b038981169190931681179091556008909352818420805460ff1916600117905590518593918816917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a45b50505050565b60008281526012602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925282916111815750604080518082019091526011546001600160a01b0381168252600160a01b90046001600160601b031660208201525b6020810151600090612710906111a0906001600160601b031687612c83565b6111aa9190612cc3565b91519350909150505b9250929050565b6000828152600f60205260409020600101546111d581611b04565b610aaf8383611c8a565b60006111ea81611b04565b60405147906000906001600160a01b0385169083908381818185875af1925050503d8060008114611237576040519150601f19603f3d011682016040523d82523d6000602084013e61123c565b606091505b50509050806111065760405163d23a9e8960e01b815260040160405180910390fd5b6001600160a01b03811633146112d35760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6112dd8282611d10565b5050565b6112e9611d77565b6113056000611300600e546001600160a01b031690565b611c8a565b565b610aaf83838360405180602001604052806000815250611944565b6000818152600b602052604081205460ff161561134157506000919050565b60008281526008602052604090205460ff166113655761136082611dd1565b610a17565b506000908152600960205260409020546001600160a01b031690565b600061138c81611b04565b610aaf8383611c20565b600060055482101580156113ab575060045482105b8015610a175750506000908152600b602052604090205460ff161590565b6000805160206131228339815191526113e181611b04565b600082900361140357604051633ba0191160e01b815260040160405180910390fd5b6000611106838583612d25565b600061141b81611b04565b611106848484611e27565b6000600554821080611439575060045482115b1561145757604051635f22452f60e01b815260040160405180910390fd5b6000828152600b602052604090205460ff16156113415760405162846fdf60e41b815260040160405180910390fd5b600061149181611b04565b8382146114b15760405163586cb9e160e01b815260040160405180910390fd5b6000805b838110156114f5578484828181106114cf576114cf612de5565b90506020020135826114e19190612c9a565b9150806114ed81612dfb565b9150506114b5565b506115b381611502611bc8565b61150c9190612c9a565b111561152b57604051632cdb04a160e21b815260040160405180910390fd5b60005b858110156115905761157e87878381811061154b5761154b612de5565b90506020020160208101906115609190612863565b86868481811061157257611572612de5565b90506020020135611c20565b8061158881612dfb565b91505061152e565b50505050505050565b600080546115a690612c20565b80601f01602080910402602001604051908101604052809291908181526020018280546115d290612c20565b801561161f5780601f106115f45761010080835404028352916020019161161f565b820191906000526020600020905b81548152906001019060200180831161160257829003601f168201915b505050505081565b60006001600160a01b03821661164f576040516280526360e51b815260040160405180910390fd5b506001600160a01b03166000908152600c602052604090205490565b611673611d77565b6113056000611ef2565b60008051602061312283398151915261169581611b04565b50601655565b6000805160206131228339815191526116b381611b04565b60008290036116da576040805160208101909152600081526001906116d89082612e14565b505b6001611106838583612d25565b6000805160206131228339815191526116ff81611b04565b50601455565b6000918252600f602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60008051602061312283398151915261174881611b04565b600082900361176a57604051633ba0191160e01b815260040160405180910390fd5b6013611106838583612d25565b606060038054610b1a90612c20565b8034816014546117969190612c83565b146117b4576040516303b59b0160e61b815260040160405180910390fd5b6115b3816117c0611bc8565b6117ca9190612c9a565b11156117e957604051632cdb04a160e21b815260040160405180910390fd5b60155433600090815260176020526040902054611807908390612c9a565b111561182657604051637335356360e01b815260040160405180910390fd5b6002611830610ab4565b60038111156118415761184161277d565b1461185f5760405163275b660b60e01b815260040160405180910390fd5b336000908152601760205260408120805484929061187e908490612c9a565b909155506112dd90503383611c20565b6118988282611bda565b336000818152600d602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60008051602061312283398151915261191c81611b04565b601554821161193e57604051634a000f7b60e11b815260040160405180910390fd5b50601555565b61194f848484610f02565b6001600160a01b0383163b1561110657610ed784848484611f44565b606060055482108061198a575060016004546119879190612c70565b82115b156119a857604051635f22452f60e01b815260040160405180910390fd5b60008080546119b690612c20565b9050116119d25760405180602001604052806000815250610a17565b60006119dd83612030565b60016040516020016119f193929190612f47565b60405160208183030381529060405292915050565b6000828152600f6020526040902060010154611a2181611b04565b610aaf8383611d10565b6000611a3681611b04565b50601080546001600160a01b0319166001600160a01b0392909216919091179055565b601380546115a690612c20565b611a6e611d77565b6001600160a01b038116611ad35760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016112ca565b611adc81611ef2565b50565b60006001600160e01b0319821663da8def7360e01b1480610a175750610a1782612131565b611adc813361219d565b6127106001600160601b0382161115611b395760405162461bcd60e51b81526004016112ca90612f7a565b6001600160a01b038216611b8f5760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c69642072656365697665720000000000000060448201526064016112ca565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217601155565b6000600554600454610efd9190612c70565b808015611bed5750611beb826121f6565b155b156112dd5760405162461bcd60e51b81526004016112ca90612fc4565b600082611c178584612267565b14949350505050565b6112dd8282604051806020016040528060008152506122b4565b6001600160a01b03831615801590611c5a57506001600160a01b03821615155b8015611c6d5750611c6b3382612327565b155b15610aaf5760405162461bcd60e51b81526004016112ca90612fc4565b611c948282611705565b6112dd576000828152600f602090815260408083206001600160a01b03851684529091529020805460ff19166001179055611ccc3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b611d1a8282611705565b156112dd576000828152600f602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600e546001600160a01b031633146113055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016112ca565b600081815b6001600160a01b038116611e205760008281526008602052604090205460ff16611e1457506000818152600760205260409020546001600160a01b03165b60001990910190611dd6565b9392505050565b6127106001600160601b0382161115611e525760405162461bcd60e51b81526004016112ca90612f7a565b6001600160a01b038216611ea85760405162461bcd60e51b815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d6574657273000000000060448201526064016112ca565b6040805180820182526001600160a01b0393841681526001600160601b0392831660208083019182526000968752601290529190942093519051909116600160a01b029116179055565b600e80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611f7990339089908890889060040161300a565b6020604051808303816000875af1925050508015611fb4575060408051601f3d908101601f19168201909252611fb191810190613047565b60015b612012573d808015611fe2576040519150601f19603f3d011682016040523d82523d6000602084013e611fe7565b606091505b50805160000361200a576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6060816000036120575750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612081578061206b81612dfb565b915061207a9050600a83612cc3565b915061205b565b60008167ffffffffffffffff81111561209c5761209c612afc565b6040519080825280601f01601f1916602001820160405280156120c6576020820181803683370190505b5090505b8415612028576120db600183612c70565b91506120e8600a86613064565b6120f3906030612c9a565b60f81b81838151811061210857612108612de5565b60200101906001600160f81b031916908160001a90535061212a600a86612cc3565b94506120ca565b60006001600160e01b031982166301ffc9a760e01b148061216257506001600160e01b031982166380ac58cd60e01b145b8061217d57506001600160e01b03198216630a85bd0160e11b145b80610a1757506001600160e01b03198216635b5e139f60e01b1492915050565b6121a78282611705565b6112dd576121b4816123d8565b6121bf8360206123ea565b6040516020016121d0929190613078565b60408051601f198184030181529082905262461bcd60e51b82526112ca9160040161280b565b601054604051630c962cb760e11b81526001600160a01b0383811660048301526000921690819063192c596e90602401602060405180830381865afa158015612243573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e2091906130ed565b600081815b84518110156122ac576122988286838151811061228b5761228b612de5565b6020026020010151612586565b9150806122a481612dfb565b91505061226c565b509392505050565b6122be83836125b5565b600060016004546122cf9190612c70565b90506001600160a01b0384163b1561110657600454839003600019015b6001016122fc6000868386611f44565b612319576040516368d2bf6b60e11b815260040160405180910390fd5b8181106122ec575050505050565b6010546000906001600160a01b031680612345576001915050610a17565b61234e83611426565b6001600160a01b0316846001600160a01b031603612370576001915050610a17565b604051630c962cb760e11b81523360048201526001600160a01b0382169063192c596e90602401602060405180830381865afa1580156123b4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202891906130ed565b6060610a176001600160a01b03831660145b606060006123f9836002612c83565b612404906002612c9a565b67ffffffffffffffff81111561241c5761241c612afc565b6040519080825280601f01601f191660200182016040528015612446576020820181803683370190505b509050600360fc1b8160008151811061246157612461612de5565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061249057612490612de5565b60200101906001600160f81b031916908160001a90535060006124b4846002612c83565b6124bf906001612c9a565b90505b6001811115612537576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106124f3576124f3612de5565b1a60f81b82828151811061250957612509612de5565b60200101906001600160f81b031916908160001a90535060049490941c936125308161310a565b90506124c2565b508315611e205760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016112ca565b60008183106125a2576000828152602084905260409020611e20565b6000838152602083905260409020611e20565b6001600160a01b0382166125dc5760405163163ae22d60e11b815260040160405180910390fd5b806000036125fd5760405163eb1d0cf560e01b815260040160405180910390fd5b6001600160a01b0382166000908152600c60205260409020805482019055600454808201905b8181101561266b5760405181906001600160a01b038616906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4600101612623565b5060048054600090815260076020526040902080546001600160a01b0319166001600160a01b03959095169490941790935590915550565b6001600160e01b031981168114611adc57600080fd5b6000602082840312156126cb57600080fd5b8135611e20816126a3565b80356001600160801b03811681146126ed57600080fd5b919050565b6000806040838503121561270557600080fd5b61270e836126d6565b915061271c602084016126d6565b90509250929050565b6001600160a01b0381168114611adc57600080fd5b80356001600160601b03811681146126ed57600080fd5b6000806040838503121561276457600080fd5b823561276f81612725565b915061271c6020840161273a565b634e487b7160e01b600052602160045260246000fd5b60208101600483106127b557634e487b7160e01b600052602160045260246000fd5b91905290565b60005b838110156127d65781810151838201526020016127be565b50506000910152565b600081518084526127f78160208601602086016127bb565b601f01601f19169290920160200192915050565b602081526000611e2060208301846127df565b60006020828403121561283057600080fd5b5035919050565b6000806040838503121561284a57600080fd5b823561285581612725565b946020939093013593505050565b60006020828403121561287557600080fd5b8135611e2081612725565b60008083601f84011261289257600080fd5b50813567ffffffffffffffff8111156128aa57600080fd5b6020830191508360208260051b85010111156111b357600080fd5b6000806000604084860312156128da57600080fd5b833567ffffffffffffffff8111156128f157600080fd5b6128fd86828701612880565b909790965060209590950135949350505050565b60008060006060848603121561292657600080fd5b833561293181612725565b9250602084013561294181612725565b929592945050506040919091013590565b6000806040838503121561296557600080fd5b50508035926020909101359150565b6000806040838503121561298757600080fd5b82359150602083013561299981612725565b809150509250929050565b600080602083850312156129b757600080fd5b823567ffffffffffffffff808211156129cf57600080fd5b818501915085601f8301126129e357600080fd5b8135818111156129f257600080fd5b866020828501011115612a0457600080fd5b60209290920196919550909350505050565b600080600060608486031215612a2b57600080fd5b833592506020840135612a3d81612725565b9150612a4b6040850161273a565b90509250925092565b60008060008060408587031215612a6a57600080fd5b843567ffffffffffffffff80821115612a8257600080fd5b612a8e88838901612880565b90965094506020870135915080821115612aa757600080fd5b50612ab487828801612880565b95989497509550505050565b8015158114611adc57600080fd5b60008060408385031215612ae157600080fd5b8235612aec81612725565b9150602083013561299981612ac0565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215612b2857600080fd5b8435612b3381612725565b93506020850135612b4381612725565b925060408501359150606085013567ffffffffffffffff80821115612b6757600080fd5b818701915087601f830112612b7b57600080fd5b813581811115612b8d57612b8d612afc565b604051601f8201601f19908116603f01168101908382118183101715612bb557612bb5612afc565b816040528281528a6020848701011115612bce57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215612c0557600080fd5b8235612c1081612725565b9150602083013561299981612725565b600181811c90821680612c3457607f821691505b602082108103612c5457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610a1757610a17612c5a565b8082028115828204841417610a1757610a17612c5a565b80820180821115610a1757610a17612c5a565b634e487b7160e01b600052601260045260246000fd5b600082612cd257612cd2612cad565b500490565b601f821115610aaf57600081815260208120601f850160051c81016020861015612cfe5750805b601f850160051c820191505b81811015612d1d57828155600101612d0a565b505050505050565b67ffffffffffffffff831115612d3d57612d3d612afc565b612d5183612d4b8354612c20565b83612cd7565b6000601f841160018114612d855760008515612d6d5750838201355b600019600387901b1c1916600186901b178355610ed7565b600083815260209020601f19861690835b82811015612db65786850135825560209485019460019092019101612d96565b5086821015612dd35760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b634e487b7160e01b600052603260045260246000fd5b600060018201612e0d57612e0d612c5a565b5060010190565b815167ffffffffffffffff811115612e2e57612e2e612afc565b612e4281612e3c8454612c20565b84612cd7565b602080601f831160018114612e775760008415612e5f5750858301515b600019600386901b1c1916600185901b178555612d1d565b600085815260208120601f198616915b82811015612ea657888601518255948401946001909101908401612e87565b5085821015612ec45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008154612ee181612c20565b60018281168015612ef95760018114612f0e57612f3d565b60ff1984168752821515830287019450612f3d565b8560005260208060002060005b85811015612f345781548a820152908401908201612f1b565b50505082870194505b5050505092915050565b6000612f538286612ed4565b8451612f638183602089016127bb565b612f6f81830186612ed4565b979650505050505050565b6020808252602a908201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646040820152692073616c65507269636560b01b606082015260800190565b60208082526026908201527f4552433732314f70657261746f7246696c7465723a20696c6c6567616c206f7060408201526532b930ba37b960d11b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061303d908301846127df565b9695505050505050565b60006020828403121561305957600080fd5b8151611e20816126a3565b60008261307357613073612cad565b500690565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516130b08160178501602088016127bb565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516130e18160288401602088016127bb565b01602801949350505050565b6000602082840312156130ff57600080fd5b8151611e2081612ac0565b60008161311957613119612c5a565b50600019019056fe241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08a2646970667358221220a53af23e2b1925c6a3a7b52e02f5af2ac1c122618fdbf083126e77b7ff2b6de164736f6c63430008110033697066733a2f2f516d5232793750326d3963626d746333314c736b765663626e3271784a50574e4534457672696f4a4a6a50756b4a241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08697066733a2f2f516d5770786736787a59675a68647a6f656a72703848467855707072387350516156366b453558617366755a65582f000000000000000000000000d4746f083df2d2e06734466d863e170881897e7100000000000000000000000098a3fba3036c9ed0ad4b28eacd9d939d7e3e1366000000000000000000000000000000000000000000000000000000000000022b00000000000000000000000046db79ad52f4ab71a7176c011ec9c79172873fe8
Deployed Bytecode
0x60806040526004361061031a5760003560e01c806367243482116101ab57806395d89b41116100f7578063c87b56dd11610095578063e8a3d4851161006f578063e8a3d48514610952578063e985e9c514610967578063ec87621c146109b0578063f2fde38b146109d257600080fd5b8063c87b56dd146108f2578063d547741f14610912578063d783925b1461093257600080fd5b8063a217fddf116100d1578063a217fddf1461087d578063a22cb46514610892578063acf080d1146108b2578063b88d4fde146108d257600080fd5b806395d89b411461083f578063a035b1fe14610854578063a0712d681461086a57600080fd5b80638e0acd121161016457806390aa0b0f1161013e57806390aa0b0f1461079457806391b7f5ed146107df57806391d14854146107ff578063938e3d7b1461081f57600080fd5b80638e0acd121461073e578063902d55a51461075e578063907097511461077457600080fd5b80636724348214610698578063689843e0146106b85780636c0360eb146106d657806370a08231146106eb578063715018a61461070b5780638da5cb5b1461072057600080fd5b80632a55205a1161026a57806342842e0e116102235780634f558e79116101fd5780634f558e791461061857806355f804b3146106385780635944c753146106585780636352211e1461067857600080fd5b806342842e0e146105b85780634777a597146105d8578063484b973c146105f857600080fd5b80632a55205a146104ee5780632f2ff15d1461052d57806331b3eb941461054d57806336568abe1461056d57806338a59d971461058d578063396876bd146105a257600080fd5b8063095ea7b3116102d757806318160ddd116102b157806318160ddd1461047357806323b872dd14610488578063248a9ca3146104a8578063293108e0146104d857600080fd5b8063095ea7b3146104125780630c6b2cbf146104325780631338a83f1461046057600080fd5b806301ffc9a71461031f57806304392a4c1461035457806304634d8d14610376578063055ad42e1461039657806306fdde03146103b8578063081812fc146103da575b600080fd5b34801561032b57600080fd5b5061033f61033a3660046126b9565b6109f2565b60405190151581526020015b60405180910390f35b34801561036057600080fd5b5061037461036f3660046126f2565b610a1d565b005b34801561038257600080fd5b50610374610391366004612751565b610a9a565b3480156103a257600080fd5b506103ab610ab4565b60405161034b9190612793565b3480156103c457600080fd5b506103cd610b0b565b60405161034b919061280b565b3480156103e657600080fd5b506103fa6103f536600461281e565b610b9d565b6040516001600160a01b03909116815260200161034b565b34801561041e57600080fd5b5061037461042d366004612837565b610ba8565b34801561043e57600080fd5b5061045261044d366004612863565b610d12565b60405190815260200161034b565b61037461046e3660046128c5565b610d38565b34801561047f57600080fd5b50610452610ede565b34801561049457600080fd5b506103746104a3366004612911565b610f02565b3480156104b457600080fd5b506104526104c336600461281e565b6000908152600f602052604090206001015490565b3480156104e457600080fd5b5061045260165481565b3480156104fa57600080fd5b5061050e610509366004612952565b61110c565b604080516001600160a01b03909316835260208301919091520161034b565b34801561053957600080fd5b50610374610548366004612974565b6111ba565b34801561055957600080fd5b50610374610568366004612863565b6111df565b34801561057957600080fd5b50610374610588366004612974565b61125e565b34801561059957600080fd5b506103746112e1565b3480156105ae57600080fd5b5061045260155481565b3480156105c457600080fd5b506103746105d3366004612911565b611307565b3480156105e457600080fd5b506103fa6105f336600461281e565b611322565b34801561060457600080fd5b50610374610613366004612837565b611381565b34801561062457600080fd5b5061033f61063336600461281e565b611396565b34801561064457600080fd5b506103746106533660046129a4565b6113c9565b34801561066457600080fd5b50610374610673366004612a16565b611410565b34801561068457600080fd5b506103fa61069336600461281e565b611426565b3480156106a457600080fd5b506103746106b3366004612a54565b611486565b3480156106c457600080fd5b506010546001600160a01b03166103fa565b3480156106e257600080fd5b506103cd611599565b3480156106f757600080fd5b50610452610706366004612863565b611627565b34801561071757600080fd5b5061037461166b565b34801561072c57600080fd5b50600e546001600160a01b03166103fa565b34801561074a57600080fd5b5061037461075936600461281e565b61167d565b34801561076a57600080fd5b506104526115b381565b34801561078057600080fd5b5061037461078f3660046129a4565b61169b565b3480156107a057600080fd5b506018546107bf906001600160801b0380821691600160801b90041682565b604080516001600160801b0393841681529290911660208301520161034b565b3480156107eb57600080fd5b506103746107fa36600461281e565b6116e7565b34801561080b57600080fd5b5061033f61081a366004612974565b611705565b34801561082b57600080fd5b5061037461083a3660046129a4565b611730565b34801561084b57600080fd5b506103cd611777565b34801561086057600080fd5b5061045260145481565b61037461087836600461281e565b611786565b34801561088957600080fd5b50610452600081565b34801561089e57600080fd5b506103746108ad366004612ace565b61188e565b3480156108be57600080fd5b506103746108cd36600461281e565b611904565b3480156108de57600080fd5b506103746108ed366004612b12565b611944565b3480156108fe57600080fd5b506103cd61090d36600461281e565b61196b565b34801561091e57600080fd5b5061037461092d366004612974565b611a06565b34801561093e57600080fd5b5061037461094d366004612863565b611a2b565b34801561095e57600080fd5b506103cd611a59565b34801561097357600080fd5b5061033f610982366004612bf2565b6001600160a01b039182166000908152600d6020908152604080832093909416825291909152205460ff1690565b3480156109bc57600080fd5b5061045260008051602061312283398151915281565b3480156109de57600080fd5b506103746109ed366004612863565b611a66565b600063152a902d60e11b6001600160e01b031983161480610a175750610a1782611adf565b92915050565b600080516020613122833981519152610a3581611b04565b816001600160801b0316836001600160801b031610610a6757604051636de2dbdf60e01b815260040160405180910390fd5b50604080518082019091526001600160801b03928316808252919092166020909201829052600160801b90910217601855565b6000610aa581611b04565b610aaf8383611b0e565b505050565b60006115b3610ac1611bc8565b03610acc5750600390565b601854600160801b90046001600160801b0316421115610aec5750600290565b6018546001600160801b0316421115610b055750600190565b50600090565b606060028054610b1a90612c20565b80601f0160208091040260200160405190810160405280929190818152602001828054610b4690612c20565b8015610b935780601f10610b6857610100808354040283529160200191610b93565b820191906000526020600020905b815481529060010190602001808311610b7657829003601f168201915b5050505050905090565b6000610a1782611426565b610bb3826001611bda565b6001600160a01b038216610bda576040516306c8ec8f60e31b815260040160405180910390fd5b6000610be582611426565b90506001600160a01b0381163314801590610c245750336000908152600d602090815260408083206001600160a01b038716845290915290205460ff16155b8015610c4757506000828152600a60205260409020546001600160a01b03163314155b15610c655760405163449de15f60e11b815260040160405180910390fd5b60008281526008602052604090205460ff16610cb857600082815260096020908152604080832080546001600160a01b0319166001600160a01b03861617905560089091529020805460ff191660011790555b6000828152600a602052604080822080546001600160a01b0319166001600160a01b0387169081179091559051849233917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a4505050565b6001600160a01b038116600090815260176020526040812054601554610a179190612c70565b803481601454610d489190612c83565b14610d66576040516303b59b0160e61b815260040160405180910390fd5b6115b381610d72611bc8565b610d7c9190612c9a565b1115610d9b57604051632cdb04a160e21b815260040160405180910390fd5b60155433600090815260176020526040902054610db9908390612c9a565b1115610dd857604051637335356360e01b815260040160405180910390fd5b6001610de2610ab4565b6003811115610df357610df361277d565b14610e115760405163bb8f723160e01b815260040160405180910390fd5b6040516bffffffffffffffffffffffff193360601b166020820152600090603401604051602081830303815290604052805190602001209050610e8b858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506016549150849050611c0a565b610ea8576040516315ebf2b560e21b815260040160405180910390fd5b3360009081526017602052604081208054859290610ec7908490612c9a565b90915550610ed790503384611c20565b5050505050565b6000600654600554600454610ef39190612c70565b610efd9190612c70565b905090565b600554811080610f1f57506001600454610f1c9190612c70565b81115b15610f3d57604051635f22452f60e01b815260040160405180910390fd5b6000610f4882611426565b9050836001600160a01b0316816001600160a01b031614610f7c576040516311f1e70d60e11b815260040160405180910390fd5b6001600160a01b0381163314801590610fb957506001600160a01b0384166000908152600d6020908152604080832033845290915290205460ff16155b8015610fdc57506000828152600a60205260409020546001600160a01b03163314155b15610ffa5760405163449de15f60e11b815260040160405180910390fd5b6001600160a01b0383166110215760405163163ae22d60e11b815260040160405180910390fd5b61102c848484611c3a565b6001600160a01b0384166000908152600c60205260408120805460019290611055908490612c70565b90915550506001600160a01b0383166000908152600c60205260408120805460019290611083908490612c9a565b90915550506000828152600a6020908152604080832080546001600160a01b03199081169091556009835281842080546001600160a01b038981169190931681179091556008909352818420805460ff1916600117905590518593918816917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a45b50505050565b60008281526012602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925282916111815750604080518082019091526011546001600160a01b0381168252600160a01b90046001600160601b031660208201525b6020810151600090612710906111a0906001600160601b031687612c83565b6111aa9190612cc3565b91519350909150505b9250929050565b6000828152600f60205260409020600101546111d581611b04565b610aaf8383611c8a565b60006111ea81611b04565b60405147906000906001600160a01b0385169083908381818185875af1925050503d8060008114611237576040519150601f19603f3d011682016040523d82523d6000602084013e61123c565b606091505b50509050806111065760405163d23a9e8960e01b815260040160405180910390fd5b6001600160a01b03811633146112d35760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6112dd8282611d10565b5050565b6112e9611d77565b6113056000611300600e546001600160a01b031690565b611c8a565b565b610aaf83838360405180602001604052806000815250611944565b6000818152600b602052604081205460ff161561134157506000919050565b60008281526008602052604090205460ff166113655761136082611dd1565b610a17565b506000908152600960205260409020546001600160a01b031690565b600061138c81611b04565b610aaf8383611c20565b600060055482101580156113ab575060045482105b8015610a175750506000908152600b602052604090205460ff161590565b6000805160206131228339815191526113e181611b04565b600082900361140357604051633ba0191160e01b815260040160405180910390fd5b6000611106838583612d25565b600061141b81611b04565b611106848484611e27565b6000600554821080611439575060045482115b1561145757604051635f22452f60e01b815260040160405180910390fd5b6000828152600b602052604090205460ff16156113415760405162846fdf60e41b815260040160405180910390fd5b600061149181611b04565b8382146114b15760405163586cb9e160e01b815260040160405180910390fd5b6000805b838110156114f5578484828181106114cf576114cf612de5565b90506020020135826114e19190612c9a565b9150806114ed81612dfb565b9150506114b5565b506115b381611502611bc8565b61150c9190612c9a565b111561152b57604051632cdb04a160e21b815260040160405180910390fd5b60005b858110156115905761157e87878381811061154b5761154b612de5565b90506020020160208101906115609190612863565b86868481811061157257611572612de5565b90506020020135611c20565b8061158881612dfb565b91505061152e565b50505050505050565b600080546115a690612c20565b80601f01602080910402602001604051908101604052809291908181526020018280546115d290612c20565b801561161f5780601f106115f45761010080835404028352916020019161161f565b820191906000526020600020905b81548152906001019060200180831161160257829003601f168201915b505050505081565b60006001600160a01b03821661164f576040516280526360e51b815260040160405180910390fd5b506001600160a01b03166000908152600c602052604090205490565b611673611d77565b6113056000611ef2565b60008051602061312283398151915261169581611b04565b50601655565b6000805160206131228339815191526116b381611b04565b60008290036116da576040805160208101909152600081526001906116d89082612e14565b505b6001611106838583612d25565b6000805160206131228339815191526116ff81611b04565b50601455565b6000918252600f602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60008051602061312283398151915261174881611b04565b600082900361176a57604051633ba0191160e01b815260040160405180910390fd5b6013611106838583612d25565b606060038054610b1a90612c20565b8034816014546117969190612c83565b146117b4576040516303b59b0160e61b815260040160405180910390fd5b6115b3816117c0611bc8565b6117ca9190612c9a565b11156117e957604051632cdb04a160e21b815260040160405180910390fd5b60155433600090815260176020526040902054611807908390612c9a565b111561182657604051637335356360e01b815260040160405180910390fd5b6002611830610ab4565b60038111156118415761184161277d565b1461185f5760405163275b660b60e01b815260040160405180910390fd5b336000908152601760205260408120805484929061187e908490612c9a565b909155506112dd90503383611c20565b6118988282611bda565b336000818152600d602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60008051602061312283398151915261191c81611b04565b601554821161193e57604051634a000f7b60e11b815260040160405180910390fd5b50601555565b61194f848484610f02565b6001600160a01b0383163b1561110657610ed784848484611f44565b606060055482108061198a575060016004546119879190612c70565b82115b156119a857604051635f22452f60e01b815260040160405180910390fd5b60008080546119b690612c20565b9050116119d25760405180602001604052806000815250610a17565b60006119dd83612030565b60016040516020016119f193929190612f47565b60405160208183030381529060405292915050565b6000828152600f6020526040902060010154611a2181611b04565b610aaf8383611d10565b6000611a3681611b04565b50601080546001600160a01b0319166001600160a01b0392909216919091179055565b601380546115a690612c20565b611a6e611d77565b6001600160a01b038116611ad35760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016112ca565b611adc81611ef2565b50565b60006001600160e01b0319821663da8def7360e01b1480610a175750610a1782612131565b611adc813361219d565b6127106001600160601b0382161115611b395760405162461bcd60e51b81526004016112ca90612f7a565b6001600160a01b038216611b8f5760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c69642072656365697665720000000000000060448201526064016112ca565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217601155565b6000600554600454610efd9190612c70565b808015611bed5750611beb826121f6565b155b156112dd5760405162461bcd60e51b81526004016112ca90612fc4565b600082611c178584612267565b14949350505050565b6112dd8282604051806020016040528060008152506122b4565b6001600160a01b03831615801590611c5a57506001600160a01b03821615155b8015611c6d5750611c6b3382612327565b155b15610aaf5760405162461bcd60e51b81526004016112ca90612fc4565b611c948282611705565b6112dd576000828152600f602090815260408083206001600160a01b03851684529091529020805460ff19166001179055611ccc3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b611d1a8282611705565b156112dd576000828152600f602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600e546001600160a01b031633146113055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016112ca565b600081815b6001600160a01b038116611e205760008281526008602052604090205460ff16611e1457506000818152600760205260409020546001600160a01b03165b60001990910190611dd6565b9392505050565b6127106001600160601b0382161115611e525760405162461bcd60e51b81526004016112ca90612f7a565b6001600160a01b038216611ea85760405162461bcd60e51b815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d6574657273000000000060448201526064016112ca565b6040805180820182526001600160a01b0393841681526001600160601b0392831660208083019182526000968752601290529190942093519051909116600160a01b029116179055565b600e80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611f7990339089908890889060040161300a565b6020604051808303816000875af1925050508015611fb4575060408051601f3d908101601f19168201909252611fb191810190613047565b60015b612012573d808015611fe2576040519150601f19603f3d011682016040523d82523d6000602084013e611fe7565b606091505b50805160000361200a576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6060816000036120575750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612081578061206b81612dfb565b915061207a9050600a83612cc3565b915061205b565b60008167ffffffffffffffff81111561209c5761209c612afc565b6040519080825280601f01601f1916602001820160405280156120c6576020820181803683370190505b5090505b8415612028576120db600183612c70565b91506120e8600a86613064565b6120f3906030612c9a565b60f81b81838151811061210857612108612de5565b60200101906001600160f81b031916908160001a90535061212a600a86612cc3565b94506120ca565b60006001600160e01b031982166301ffc9a760e01b148061216257506001600160e01b031982166380ac58cd60e01b145b8061217d57506001600160e01b03198216630a85bd0160e11b145b80610a1757506001600160e01b03198216635b5e139f60e01b1492915050565b6121a78282611705565b6112dd576121b4816123d8565b6121bf8360206123ea565b6040516020016121d0929190613078565b60408051601f198184030181529082905262461bcd60e51b82526112ca9160040161280b565b601054604051630c962cb760e11b81526001600160a01b0383811660048301526000921690819063192c596e90602401602060405180830381865afa158015612243573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e2091906130ed565b600081815b84518110156122ac576122988286838151811061228b5761228b612de5565b6020026020010151612586565b9150806122a481612dfb565b91505061226c565b509392505050565b6122be83836125b5565b600060016004546122cf9190612c70565b90506001600160a01b0384163b1561110657600454839003600019015b6001016122fc6000868386611f44565b612319576040516368d2bf6b60e11b815260040160405180910390fd5b8181106122ec575050505050565b6010546000906001600160a01b031680612345576001915050610a17565b61234e83611426565b6001600160a01b0316846001600160a01b031603612370576001915050610a17565b604051630c962cb760e11b81523360048201526001600160a01b0382169063192c596e90602401602060405180830381865afa1580156123b4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202891906130ed565b6060610a176001600160a01b03831660145b606060006123f9836002612c83565b612404906002612c9a565b67ffffffffffffffff81111561241c5761241c612afc565b6040519080825280601f01601f191660200182016040528015612446576020820181803683370190505b509050600360fc1b8160008151811061246157612461612de5565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061249057612490612de5565b60200101906001600160f81b031916908160001a90535060006124b4846002612c83565b6124bf906001612c9a565b90505b6001811115612537576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106124f3576124f3612de5565b1a60f81b82828151811061250957612509612de5565b60200101906001600160f81b031916908160001a90535060049490941c936125308161310a565b90506124c2565b508315611e205760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016112ca565b60008183106125a2576000828152602084905260409020611e20565b6000838152602083905260409020611e20565b6001600160a01b0382166125dc5760405163163ae22d60e11b815260040160405180910390fd5b806000036125fd5760405163eb1d0cf560e01b815260040160405180910390fd5b6001600160a01b0382166000908152600c60205260409020805482019055600454808201905b8181101561266b5760405181906001600160a01b038616906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4600101612623565b5060048054600090815260076020526040902080546001600160a01b0319166001600160a01b03959095169490941790935590915550565b6001600160e01b031981168114611adc57600080fd5b6000602082840312156126cb57600080fd5b8135611e20816126a3565b80356001600160801b03811681146126ed57600080fd5b919050565b6000806040838503121561270557600080fd5b61270e836126d6565b915061271c602084016126d6565b90509250929050565b6001600160a01b0381168114611adc57600080fd5b80356001600160601b03811681146126ed57600080fd5b6000806040838503121561276457600080fd5b823561276f81612725565b915061271c6020840161273a565b634e487b7160e01b600052602160045260246000fd5b60208101600483106127b557634e487b7160e01b600052602160045260246000fd5b91905290565b60005b838110156127d65781810151838201526020016127be565b50506000910152565b600081518084526127f78160208601602086016127bb565b601f01601f19169290920160200192915050565b602081526000611e2060208301846127df565b60006020828403121561283057600080fd5b5035919050565b6000806040838503121561284a57600080fd5b823561285581612725565b946020939093013593505050565b60006020828403121561287557600080fd5b8135611e2081612725565b60008083601f84011261289257600080fd5b50813567ffffffffffffffff8111156128aa57600080fd5b6020830191508360208260051b85010111156111b357600080fd5b6000806000604084860312156128da57600080fd5b833567ffffffffffffffff8111156128f157600080fd5b6128fd86828701612880565b909790965060209590950135949350505050565b60008060006060848603121561292657600080fd5b833561293181612725565b9250602084013561294181612725565b929592945050506040919091013590565b6000806040838503121561296557600080fd5b50508035926020909101359150565b6000806040838503121561298757600080fd5b82359150602083013561299981612725565b809150509250929050565b600080602083850312156129b757600080fd5b823567ffffffffffffffff808211156129cf57600080fd5b818501915085601f8301126129e357600080fd5b8135818111156129f257600080fd5b866020828501011115612a0457600080fd5b60209290920196919550909350505050565b600080600060608486031215612a2b57600080fd5b833592506020840135612a3d81612725565b9150612a4b6040850161273a565b90509250925092565b60008060008060408587031215612a6a57600080fd5b843567ffffffffffffffff80821115612a8257600080fd5b612a8e88838901612880565b90965094506020870135915080821115612aa757600080fd5b50612ab487828801612880565b95989497509550505050565b8015158114611adc57600080fd5b60008060408385031215612ae157600080fd5b8235612aec81612725565b9150602083013561299981612ac0565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215612b2857600080fd5b8435612b3381612725565b93506020850135612b4381612725565b925060408501359150606085013567ffffffffffffffff80821115612b6757600080fd5b818701915087601f830112612b7b57600080fd5b813581811115612b8d57612b8d612afc565b604051601f8201601f19908116603f01168101908382118183101715612bb557612bb5612afc565b816040528281528a6020848701011115612bce57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215612c0557600080fd5b8235612c1081612725565b9150602083013561299981612725565b600181811c90821680612c3457607f821691505b602082108103612c5457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610a1757610a17612c5a565b8082028115828204841417610a1757610a17612c5a565b80820180821115610a1757610a17612c5a565b634e487b7160e01b600052601260045260246000fd5b600082612cd257612cd2612cad565b500490565b601f821115610aaf57600081815260208120601f850160051c81016020861015612cfe5750805b601f850160051c820191505b81811015612d1d57828155600101612d0a565b505050505050565b67ffffffffffffffff831115612d3d57612d3d612afc565b612d5183612d4b8354612c20565b83612cd7565b6000601f841160018114612d855760008515612d6d5750838201355b600019600387901b1c1916600186901b178355610ed7565b600083815260209020601f19861690835b82811015612db65786850135825560209485019460019092019101612d96565b5086821015612dd35760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b634e487b7160e01b600052603260045260246000fd5b600060018201612e0d57612e0d612c5a565b5060010190565b815167ffffffffffffffff811115612e2e57612e2e612afc565b612e4281612e3c8454612c20565b84612cd7565b602080601f831160018114612e775760008415612e5f5750858301515b600019600386901b1c1916600185901b178555612d1d565b600085815260208120601f198616915b82811015612ea657888601518255948401946001909101908401612e87565b5085821015612ec45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008154612ee181612c20565b60018281168015612ef95760018114612f0e57612f3d565b60ff1984168752821515830287019450612f3d565b8560005260208060002060005b85811015612f345781548a820152908401908201612f1b565b50505082870194505b5050505092915050565b6000612f538286612ed4565b8451612f638183602089016127bb565b612f6f81830186612ed4565b979650505050505050565b6020808252602a908201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646040820152692073616c65507269636560b01b606082015260800190565b60208082526026908201527f4552433732314f70657261746f7246696c7465723a20696c6c6567616c206f7060408201526532b930ba37b960d11b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061303d908301846127df565b9695505050505050565b60006020828403121561305957600080fd5b8151611e20816126a3565b60008261307357613073612cad565b500690565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516130b08160178501602088016127bb565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516130e18160288401602088016127bb565b01602801949350505050565b6000602082840312156130ff57600080fd5b8151611e2081612ac0565b60008161311957613119612c5a565b50600019019056fe241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08a2646970667358221220a53af23e2b1925c6a3a7b52e02f5af2ac1c122618fdbf083126e77b7ff2b6de164736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d4746f083df2d2e06734466d863e170881897e7100000000000000000000000098a3fba3036c9ed0ad4b28eacd9d939d7e3e1366000000000000000000000000000000000000000000000000000000000000022b00000000000000000000000046db79ad52f4ab71a7176c011ec9c79172873fe8
-----Decoded View---------------
Arg [0] : owner_ (address): 0xd4746f083DF2D2e06734466D863E170881897E71
Arg [1] : manager_ (address): 0x98A3fbA3036C9ed0Ad4b28EacD9d939D7e3e1366
Arg [2] : initialQty_ (uint256): 555
Arg [3] : filter_ (address): 0x46Db79ad52f4AB71A7176C011Ec9C79172873fE8
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000d4746f083df2d2e06734466d863e170881897e71
Arg [1] : 00000000000000000000000098a3fba3036c9ed0ad4b28eacd9d939d7e3e1366
Arg [2] : 000000000000000000000000000000000000000000000000000000000000022b
Arg [3] : 00000000000000000000000046db79ad52f4ab71a7176c011ec9c79172873fe8
Deployed Bytecode Sourcemap
75254:7333:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82245:339;;;;;;;;;;-1:-1:-1;82245:339:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;82245:339:0;;;;;;;;79275:319;;;;;;;;;;-1:-1:-1;79275:319:0;;;;;:::i;:::-;;:::i;:::-;;80512:188;;;;;;;;;;-1:-1:-1;80512:188:0;;;;;:::i;:::-;;:::i;81688:398::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;42983:85::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;42330:114::-;;;;;;;;;;-1:-1:-1;42330:114:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3274:32:1;;;3256:51;;3244:2;3229:18;42330:114:0;3110:203:1;40611:738:0;;;;;;;;;;-1:-1:-1;40611:738:0;;;;;:::i;:::-;;:::i;82117:120::-;;;;;;;;;;-1:-1:-1;82117:120:0;;;;;:::i;:::-;;:::i;:::-;;;4036:25:1;;;4024:2;4009:18;82117:120:0;3890:177:1;77061:498:0;;;;;;:::i;:::-;;:::i;44223:124::-;;;;;;;;;;;;;:::i;47519:967::-;;;;;;;;;;-1:-1:-1;47519:967:0;;;;;:::i;:::-;;:::i;27688:131::-;;;;;;;;;;-1:-1:-1;27688:131:0;;;;;:::i;:::-;27762:7;27789:12;;;:6;:12;;;;;:22;;;;27688:131;75826:34;;;;;;;;;;;;;;;;62847:442;;;;;;;;;;-1:-1:-1;62847:442:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;6227:32:1;;;6209:51;;6291:2;6276:18;;6269:34;;;;6182:18;62847:442:0;6035:274:1;28129:147:0;;;;;;;;;;-1:-1:-1;28129:147:0;;;;;:::i;:::-;;:::i;79874:356::-;;;;;;;;;;-1:-1:-1;79874:356:0;;;;;:::i;:::-;;:::i;29273:218::-;;;;;;;;;;-1:-1:-1;29273:218:0;;;;;:::i;:::-;;:::i;79762:104::-;;;;;;;;;;;;;:::i;75785:32::-;;;;;;;;;;;;;;;;45578:174;;;;;;;;;;-1:-1:-1;45578:174:0;;;;;:::i;:::-;;:::i;49814:269::-;;;;;;;;;;-1:-1:-1;49814:269:0;;;;;:::i;:::-;;:::i;77804:165::-;;;;;;;;;;-1:-1:-1;77804:165:0;;;;;:::i;:::-;;:::i;45003:208::-;;;;;;;;;;-1:-1:-1;45003:208:0;;;;;:::i;:::-;;:::i;78791:227::-;;;;;;;;;;-1:-1:-1;78791:227:0;;;;;:::i;:::-;;:::i;81100:221::-;;;;;;;;;;-1:-1:-1;81100:221:0;;;;;:::i;:::-;;:::i;48751:383::-;;;;;;;;;;-1:-1:-1;48751:383:0;;;;;:::i;:::-;;:::i;77977:551::-;;;;;;;;;;-1:-1:-1;77977:551:0;;;;;:::i;:::-;;:::i;58791:105::-;;;;;;;;;;-1:-1:-1;58873:15:0;;-1:-1:-1;;;;;58873:15:0;58791:105;;39377:21;;;;;;;;;;;;;:::i;44684:180::-;;;;;;;;;;-1:-1:-1;44684:180:0;;;;;:::i;:::-;;:::i;2667:103::-;;;;;;;;;;;;;:::i;2019:87::-;;;;;;;;;;-1:-1:-1;2092:6:0;;-1:-1:-1;;;;;2092:6:0;2019:87;;79602:152;;;;;;;;;;-1:-1:-1;79602:152:0;;;;;:::i;:::-;;:::i;75529:43::-;;;;;;;;;;;;75568:4;75529:43;;79026:241;;;;;;;;;;-1:-1:-1;79026:241:0;;;;;:::i;:::-;;:::i;75919:28::-;;;;;;;;;;-1:-1:-1;75919:28:0;;;;-1:-1:-1;;;;;75919:28:0;;;;-1:-1:-1;;;75919:28:0;;;;;;;;;-1:-1:-1;;;;;9138:15:1;;;9120:34;;9190:15;;;;9185:2;9170:18;;9163:43;9040:18;75919:28:0;8893:319:1;81536:103:0;;;;;;;;;;-1:-1:-1;81536:103:0;;;;;:::i;:::-;;:::i;26161:147::-;;;;;;;;;;-1:-1:-1;26161:147:0;;;;;:::i;:::-;;:::i;78536:247::-;;;;;;;;;;-1:-1:-1;78536:247:0;;;;;:::i;:::-;;:::i;43139:89::-;;;;;;;;;;;;;:::i;75744:34::-;;;;;;;;;;;;;;;;77567:229;;;;;;:::i;:::-;;:::i;25266:49::-;;;;;;;;;;-1:-1:-1;25266:49:0;25311:4;25266:49;;41752:301;;;;;;;;;;-1:-1:-1;41752:301:0;;;;;:::i;:::-;;:::i;81329:199::-;;;;;;;;;;-1:-1:-1;81329:199:0;;;;;:::i;:::-;;:::i;46617:304::-;;;;;;;;;;-1:-1:-1;46617:304:0;;;;;:::i;:::-;;:::i;43507:491::-;;;;;;;;;;-1:-1:-1;43507:491:0;;;;;:::i;:::-;;:::i;28569:149::-;;;;;;;;;;-1:-1:-1;28569:149:0;;;;;:::i;:::-;;:::i;58653:130::-;;;;;;;;;;-1:-1:-1;58653:130:0;;;;;:::i;:::-;;:::i;75652:83::-;;;;;;;;;;;;;:::i;42751:176::-;;;;;;;;;;-1:-1:-1;42751:176:0;;;;;:::i;:::-;-1:-1:-1;;;;;42891:17:0;;;42862:4;42891:17;;;:9;:17;;;;;;;;:28;;;;;;;;;;;;;;;42751:176;75579:64;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;75579:64:0;;2925:201;;;;;;;;;;-1:-1:-1;2925:201:0;;;;;:::i;:::-;;:::i;82245:339::-;82406:4;-1:-1:-1;;;;;;;;;82448:25:0;;;;:128;;;82525:51;82564:11;82525:38;:51::i;:::-;82428:148;82245:339;-1:-1:-1;;82245:339:0:o;79275:319::-;-1:-1:-1;;;;;;;;;;;25757:16:0;25768:4;25757:10;:16::i;:::-;79443:15:::1;-1:-1:-1::0;;;;;79421:37:0::1;:18;-1:-1:-1::0;;;;;79421:37:0::1;;79417:98;;79480:35;;-1:-1:-1::0;;;79480:35:0::1;;;;;;;;;;;79417:98;-1:-1:-1::0;79539:47:0::1;::::0;;;;::::1;::::0;;;-1:-1:-1;;;;;79539:47:0;;::::1;::::0;;;;;;::::1;;::::0;;::::1;::::0;;;-1:-1:-1;;;79526:60:0;;::::1;;:10;:60:::0;79275:319::o;80512:188::-;25311:4;25757:16;25311:4;25757:10;:16::i;:::-;80650:42:::1;80669:8;80679:12;80650:18;:42::i;:::-;80512:188:::0;;;:::o;81688:398::-;81733:5;75568:4;81755:14;:12;:14::i;:::-;:30;81751:328;;-1:-1:-1;81809:10:0;;81688:398::o;81751:328::-;81859:10;:21;-1:-1:-1;;;81859:21:0;;-1:-1:-1;;;;;81859:21:0;81841:15;:39;81837:242;;;-1:-1:-1;81904:12:0;;81688:398::o;81837:242::-;81956:10;:20;-1:-1:-1;;;;;81956:20:0;81938:15;:38;81934:145;;;-1:-1:-1;82000:15:0;;81688:398::o;81934:145::-;-1:-1:-1;82055:12:0;;81688:398::o;42983:85::-;43022:13;43055:5;43048:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42983:85;:::o;42330:114::-;42392:7;42419:17;42427:8;42419:7;:17::i;40611:738::-;40685:35;40704:9;40715:4;40685:18;:35::i;:::-;-1:-1:-1;;;;;40735:23:0;;40731:64;;40767:28;;-1:-1:-1;;;40767:28:0;;;;;;;;;;;40731:64;40806:13;40822:17;40830:8;40822:7;:17::i;:::-;40806:33;-1:-1:-1;;;;;;40868:19:0;;40877:10;40868:19;;;;:69;;-1:-1:-1;40915:10:0;40905:21;;;;:9;:21;;;;;;;;-1:-1:-1;;;;;40905:32:0;;;;;;;;;;;;40904:33;40868:69;:124;;;;-1:-1:-1;40954:24:0;;;;:14;:24;;;;;;-1:-1:-1;;;;;40954:24:0;40982:10;40954:38;;40868:124;40850:195;;;41011:34;;-1:-1:-1;;;41011:34:0;;;;;;;;;;;40850:195;41063:24;;;;:14;:24;;;;;;;;41058:133;;41104:21;;;;:11;:21;;;;;;;;:29;;-1:-1:-1;;;;;;41104:29:0;-1:-1:-1;;;;;41104:29:0;;;;;41148:14;:24;;;;;:31;;-1:-1:-1;;41148:31:0;-1:-1:-1;41148:31:0;;;41058:133;41201:24;;;;:14;:24;;;;;;:36;;-1:-1:-1;;;;;;41201:36:0;-1:-1:-1;;;;;41201:36:0;;;;;;;;41255:41;;41201:24;;41264:10;;41255:41;;41201:24;41255:41;80512:188;;;:::o;82117:120::-;-1:-1:-1;;;;;82218:11:0;;82175:7;82218:11;;;:5;:11;;;;;;82202:13;;:27;;82218:11;82202:27;:::i;77061:498::-;77189:8;76029:9;76017:8;76009:5;;:16;;;;:::i;:::-;:29;76005:89;;76062:20;;-1:-1:-1;;;76062:20:0;;;;;;;;;;;76005:89;75568:4;76125:8;76108:14;:12;:14::i;:::-;:25;;;;:::i;:::-;:40;76104:91;;;76172:11;;-1:-1:-1;;;76172:11:0;;;;;;;;;;;76104:91;76240:13;;76215:10;76209:17;;;;:5;:17;;;;;;:28;;76229:8;;76209:28;:::i;:::-;:44;76205:106;;;76277:22;;-1:-1:-1;;;76277:22:0;;;;;;;;;;;76205:106;77237:15:::1;77219:14;:12;:14::i;:::-;:33;;;;;;;;:::i;:::-;;77215:65;;77261:19;;-1:-1:-1::0;;;77261:19:0::1;;;;;;;;;;;77215:65;77316:28;::::0;-1:-1:-1;;77333:10:0::1;12901:2:1::0;12897:15;12893:53;77316:28:0::1;::::0;::::1;12881:66:1::0;77291:12:0::1;::::0;12963::1;;77316:28:0::1;;;;;;;;;;;;77306:39;;;;;;77291:54;;77361:58;77380:11;;77361:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;77393:19:0::1;::::0;;-1:-1:-1;77414:4:0;;-1:-1:-1;77361:18:0::1;:58::i;:::-;77356:115;;77443:16;;-1:-1:-1::0;;;77443:16:0::1;;;;;;;;;;;77356:115;77487:10;77481:17;::::0;;;:5:::1;:17;::::0;;;;:29;;77502:8;;77481:17;:29:::1;::::0;77502:8;;77481:29:::1;:::i;:::-;::::0;;;-1:-1:-1;77521:30:0::1;::::0;-1:-1:-1;77530:10:0::1;77542:8:::0;77521::::1;:30::i;:::-;77204:355;77061:498:::0;;;;:::o;44223:124::-;44269:7;44328:11;;44310:15;;44296:11;;:29;;;;:::i;:::-;:43;;;;:::i;:::-;44289:50;;44223:124;:::o;47519:967::-;47654:15;;47643:8;:26;:56;;;;47698:1;47684:11;;:15;;;;:::i;:::-;47673:8;:26;47643:56;47639:105;;;47721:23;;-1:-1:-1;;;47721:23:0;;;;;;;;;;;47639:105;47755:13;47771:17;47779:8;47771:7;:17::i;:::-;47755:33;;47814:5;-1:-1:-1;;;;;47805:14:0;:5;-1:-1:-1;;;;;47805:14:0;;47801:55;;47828:28;;-1:-1:-1;;;47828:28:0;;;;;;;;;;;47801:55;-1:-1:-1;;;;;47885:19:0;;47894:10;47885:19;;;;:65;;-1:-1:-1;;;;;;47922:16:0;;;;;;:9;:16;;;;;;;;47939:10;47922:28;;;;;;;;;;47921:29;47885:65;:120;;;;-1:-1:-1;47967:24:0;;;;:14;:24;;;;;;-1:-1:-1;;;;;47967:24:0;47995:10;47967:38;;47885:120;47867:191;;;48024:34;;-1:-1:-1;;;48024:34:0;;;;;;;;;;;47867:191;-1:-1:-1;;;;;48073:17:0;;48069:60;;48099:30;;-1:-1:-1;;;48099:30:0;;;;;;;;;;;48069:60;48142:42;48163:5;48170:3;48175:8;48142:20;:42::i;:::-;-1:-1:-1;;;;;48197:15:0;;;;;;:8;:15;;;;;:20;;48216:1;;48197:15;:20;;48216:1;;48197:20;:::i;:::-;;;;-1:-1:-1;;;;;;;48228:13:0;;;;;;:8;:13;;;;;:18;;48245:1;;48228:13;:18;;48245:1;;48228:18;:::i;:::-;;;;-1:-1:-1;;48294:1:0;48259:24;;;:14;:24;;;;;;;;:37;;-1:-1:-1;;;;;;48259:37:0;;;;;;48307:11;:21;;;;;:27;;-1:-1:-1;;;;;48307:27:0;;;;;;;;;;;;48345:14;:24;;;;;;:31;;-1:-1:-1;;48345:31:0;48259:37;48345:31;;;48394:30;;48274:8;;48394:30;;;;;;;48437:41;47628:858;47519:967;;;:::o;62847:442::-;62944:7;63002:27;;;:17;:27;;;;;;;;62973:56;;;;;;;;;-1:-1:-1;;;;;62973:56:0;;;;;-1:-1:-1;;;62973:56:0;;;-1:-1:-1;;;;;62973:56:0;;;;;;;;62944:7;;63042:92;;-1:-1:-1;63093:29:0;;;;;;;;;63103:19;63093:29;-1:-1:-1;;;;;63093:29:0;;;;-1:-1:-1;;;63093:29:0;;-1:-1:-1;;;;;63093:29:0;;;;;63042:92;63184:23;;;;63146:21;;63655:5;;63171:36;;-1:-1:-1;;;;;63171:36:0;:10;:36;:::i;:::-;63170:58;;;;:::i;:::-;63249:16;;;-1:-1:-1;63146:82:0;;-1:-1:-1;;62847:442:0;;;;;;:::o;28129:147::-;27762:7;27789:12;;;:6;:12;;;;;:22;;;25757:16;25768:4;25757:10;:16::i;:::-;28243:25:::1;28254:4;28260:7;28243:10;:25::i;79874:356::-:0;25311:4;25757:16;25311:4;25757:10;:16::i;:::-;80067:30:::1;::::0;80013:21:::1;::::0;79995:15:::1;::::0;-1:-1:-1;;;;;80067:10:0;::::1;::::0;80013:21;;79995:15;80067:30;79995:15;80067:30;80013:21;80067:10;:30:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80045:52;;;80159:10;80154:69;;80193:18;;-1:-1:-1::0;;;80193:18:0::1;;;;;;;;;;;29273:218:::0;-1:-1:-1;;;;;29369:23:0;;808:10;29369:23;29361:83;;;;-1:-1:-1;;;29361:83:0;;13655:2:1;29361:83:0;;;13637:21:1;13694:2;13674:18;;;13667:30;13733:34;13713:18;;;13706:62;-1:-1:-1;;;13784:18:1;;;13777:45;13839:19;;29361:83:0;;;;;;;;;29457:26;29469:4;29475:7;29457:11;:26::i;:::-;29273:218;;:::o;79762:104::-;1905:13;:11;:13::i;:::-;79819:39:::1;25311:4;79850:7;2092:6:::0;;-1:-1:-1;;;;;2092:6:0;;2019:87;79850:7:::1;79819:10;:39::i;:::-;79762:104::o:0;45578:174::-;45702:42;45719:5;45726:3;45731:8;45702:42;;;;;;;;;;;;:16;:42::i;49814:269::-;49876:7;49900:22;;;:12;:22;;;;;;;;49896:45;;;-1:-1:-1;49939:1:0;;49814:269;-1:-1:-1;49814:269:0:o;49896:45::-;49972:24;;;;:14;:24;;;;;;;;:103;;50057:18;50066:8;50057;:18::i;:::-;49972:103;;;-1:-1:-1;50016:21:0;;;;:11;:21;;;;;;-1:-1:-1;;;;;50016:21:0;;49814:269::o;77804:165::-;25311:4;25757:16;25311:4;25757:10;:16::i;:::-;77932:29:::1;77941:9;77952:8;77932;:29::i;45003:208::-:0;45060:4;45109:15;;45097:8;:27;;:66;;;;;45152:11;;45141:8;:22;45097:66;:106;;;;-1:-1:-1;;45181:22:0;;;;:12;:22;;;;;;;;45180:23;;45003:208::o;78791:227::-;-1:-1:-1;;;;;;;;;;;25757:16:0;25768:4;25757:10;:16::i;:::-;78933:1:::1;78907:27:::0;;;78903:79:::1;;78958:12;;-1:-1:-1::0;;;78958:12:0::1;;;;;;;;;;;78903:79;78992:7;:18;79002:8:::0;;78992:7;:18:::1;:::i;81100:221::-:0;25311:4;25757:16;25311:4;25757:10;:16::i;:::-;81264:49:::1;81281:7;81290:8;81300:12;81264:16;:49::i;48751:383::-:0;48807:7;48842:15;;48831:8;:26;:52;;;;48872:11;;48861:8;:22;48831:52;48827:101;;;48905:23;;-1:-1:-1;;;48905:23:0;;;;;;;;;;;48827:101;48943:22;;;;:12;:22;;;;;;;;48939:53;;;48974:18;;-1:-1:-1;;;48974:18:0;;;;;;;;;;;77977:551;25311:4;25757:16;25311:4;25757:10;:16::i;:::-;78133:37;;::::1;78129:67;;78179:17;;-1:-1:-1::0;;;78179:17:0::1;;;;;;;;;;;78129:67;78207:13;::::0;78231:97:::1;78251:21:::0;;::::1;78231:97;;;78303:10;;78314:1;78303:13;;;;;;;:::i;:::-;;;;;;;78294:22;;;;;:::i;:::-;::::0;-1:-1:-1;78274:3:0;::::1;::::0;::::1;:::i;:::-;;;;78231:97;;;;75568:4;78359:5;78342:14;:12;:14::i;:::-;:22;;;;:::i;:::-;:37;78338:61;;;78388:11;;-1:-1:-1::0;;;78388:11:0::1;;;;;;;;;;;78338:61;78415:9;78410:111;78430:20:::0;;::::1;78410:111;;;78472:37;78481:9;;78491:1;78481:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;78495:10;;78506:1;78495:13;;;;;;;:::i;:::-;;;;;;;78472:8;:37::i;:::-;78452:3:::0;::::1;::::0;::::1;:::i;:::-;;;;78410:111;;;;78118:410;77977:551:::0;;;;;:::o;39377:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;44684:180::-;44742:7;-1:-1:-1;;;;;44766:20:0;;44762:60;;44795:27;;-1:-1:-1;;;44795:27:0;;;;;;;;;;;44762:60;-1:-1:-1;;;;;;44840:16:0;;;;;:8;:16;;;;;;;44684:180::o;2667:103::-;1905:13;:11;:13::i;:::-;2732:30:::1;2759:1;2732:18;:30::i;79602:152::-:0;-1:-1:-1;;;;;;;;;;;25757:16:0;25768:4;25757:10;:16::i;:::-;-1:-1:-1;79714:19:0::1;:32:::0;79602:152::o;79026:241::-;-1:-1:-1;;;;;;;;;;;25757:16:0;25768:4;25757:10;:16::i;:::-;79177:1:::1;79149:29:::0;;;79145:79:::1;;79195:17;::::0;;::::1;::::0;::::1;::::0;;;-1:-1:-1;79195:17:0;;:12:::1;::::0;:17:::1;::::0;:12;:17:::1;:::i;:::-;;79145:79;79234:12;:25;79249:10:::0;;79234:12;:25:::1;:::i;81536:103::-:0;-1:-1:-1;;;;;;;;;;;25757:16:0;25768:4;25757:10;:16::i;:::-;-1:-1:-1;81615:5:0::1;:16:::0;81536:103::o;26161:147::-;26247:4;26271:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;26271:29:0;;;;;;;;;;;;;;;26161:147::o;78536:247::-;-1:-1:-1;;;;;;;;;;;25757:16:0;25768:4;25757:10;:16::i;:::-;78690:1:::1;78660:31:::0;;;78656:83:::1;;78715:12;;-1:-1:-1::0;;;78715:12:0::1;;;;;;;;;;;78656:83;78749:11;:26;78763:12:::0;;78749:11;:26:::1;:::i;43139:89::-:0;43180:13;43213:7;43206:14;;;;;:::i;77567:229::-;77627:8;76029:9;76017:8;76009:5;;:16;;;;:::i;:::-;:29;76005:89;;76062:20;;-1:-1:-1;;;76062:20:0;;;;;;;;;;;76005:89;75568:4;76125:8;76108:14;:12;:14::i;:::-;:25;;;;:::i;:::-;:40;76104:91;;;76172:11;;-1:-1:-1;;;76172:11:0;;;;;;;;;;;76104:91;76240:13;;76215:10;76209:17;;;;:5;:17;;;;;;:28;;76229:8;;76209:28;:::i;:::-;:44;76205:106;;;76277:22;;-1:-1:-1;;;76277:22:0;;;;;;;;;;;76205:106;77670:12:::1;77652:14;:12;:14::i;:::-;:30;;;;;;;;:::i;:::-;;77648:59;;77691:16;;-1:-1:-1::0;;;77691:16:0::1;;;;;;;;;;;77648:59;77724:10;77718:17;::::0;;;:5:::1;:17;::::0;;;;:29;;77739:8;;77718:17;:29:::1;::::0;77739:8;;77718:29:::1;:::i;:::-;::::0;;;-1:-1:-1;77758:30:0::1;::::0;-1:-1:-1;77767:10:0::1;77779:8:::0;77758::::1;:30::i;41752:301::-:0;41834:40;41853:9;41864;41834:18;:40::i;:::-;41895:10;41885:21;;;;:9;:21;;;;;;;;-1:-1:-1;;;;;41885:32:0;;;;;;;;;;;;:44;;-1:-1:-1;;41885:44:0;;;;;;;;;;41947:48;;540:41:1;;;41885:32:0;;41895:10;41947:48;;513:18:1;41947:48:0;;;;;;;29273:218;;:::o;81329:199::-;-1:-1:-1;;;;;;;;;;;25757:16:0;25768:4;25757:10;:16::i;:::-;81433:13:::1;;81420:9;:26;81417:67;;81455:29;;-1:-1:-1::0;;;81455:29:0::1;;;;;;;;;;;81417:67;-1:-1:-1::0;81495:13:0::1;:25:::0;81329:199::o;46617:304::-;46769:34;46782:5;46789:3;46794:8;46769:12;:34::i;:::-;-1:-1:-1;;;;;46818:15:0;;;:19;46814:100;;46854:48;46875:5;46882:3;46887:8;46897:4;46854:20;:48::i;43507:491::-;43610:13;43656:15;;43645:8;:26;:56;;;;43700:1;43686:11;;:15;;;;:::i;:::-;43675:8;:26;43645:56;43641:105;;;43723:23;;-1:-1:-1;;;43723:23:0;;;;;;;;;;;43641:105;43801:1;43783:7;43777:21;;;;;:::i;:::-;;;:25;:213;;;;;;;;;;;;;;;;;43858:7;43888:26;43905:8;43888:16;:26::i;:::-;43937:12;43822:146;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;43757:233;43507:491;-1:-1:-1;;43507:491:0:o;28569:149::-;27762:7;27789:12;;;:6;:12;;;;;:22;;;25757:16;25768:4;25757:10;:16::i;:::-;28684:26:::1;28696:4;28702:7;28684:11;:26::i;58653:130::-:0;25311:4;25757:16;25311:4;25757:10;:16::i;:::-;-1:-1:-1;58751:15:0::1;:24:::0;;-1:-1:-1;;;;;;58751:24:0::1;-1:-1:-1::0;;;;;58751:24:0;;;::::1;::::0;;;::::1;::::0;;58653:130::o;75652:83::-;;;;;;;:::i;2925:201::-;1905:13;:11;:13::i;:::-;-1:-1:-1;;;;;3014:22:0;::::1;3006:73;;;::::0;-1:-1:-1;;;3006:73:0;;18959:2:1;3006:73:0::1;::::0;::::1;18941:21:1::0;18998:2;18978:18;;;18971:30;19037:34;19017:18;;;19010:62;-1:-1:-1;;;19088:18:1;;;19081:36;19134:19;;3006:73:0::1;18757:402:1::0;3006:73:0::1;3090:28;3109:8;3090:18;:28::i;:::-;2925:201:::0;:::o;58904:313::-;59062:4;-1:-1:-1;;;;;;59104:46:0;;-1:-1:-1;;;59104:46:0;;:105;;;59167:42;59197:11;59167:29;:42::i;26612:105::-;26679:30;26690:4;808:10;26679;:30::i;63939:332::-;63655:5;-1:-1:-1;;;;;64042:33:0;;;;64034:88;;;;-1:-1:-1;;;64034:88:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;64141:22:0;;64133:60;;;;-1:-1:-1;;;64133:60:0;;19777:2:1;64133:60:0;;;19759:21:1;19816:2;19796:18;;;19789:30;19855:27;19835:18;;;19828:55;19900:18;;64133:60:0;19575:349:1;64133:60:0;64228:35;;;;;;;;;-1:-1:-1;;;;;64228:35:0;;;;;;-1:-1:-1;;;;;64228:35:0;;;;;;;;;;-1:-1:-1;;;64206:57:0;;;;:19;:57;63939:332::o;56774:111::-;56821:7;56862:15;;56848:11;;:29;;;;:::i;59660:254::-;59763:9;:36;;;;;59777:22;59789:9;59777:11;:22::i;:::-;59776:23;59763:36;59760:89;;;59801:48;;-1:-1:-1;;;59801:48:0;;;;;;;:::i;66463:190::-;66588:4;66641;66612:25;66625:5;66632:4;66612:12;:25::i;:::-;:33;;66463:190;-1:-1:-1;;;;66463:190:0:o;50744:106::-;50814:28;50823:3;50828:9;50814:28;;;;;;;;;;;;:8;:28::i;59225:427::-;-1:-1:-1;;;;;59400:18:0;;;;;;:51;;-1:-1:-1;;;;;;59435:16:0;;;;59400:51;:102;;;;;59469:33;59482:10;59494:7;59469:12;:33::i;:::-;59468:34;59400:102;59382:207;;;59529:48;;-1:-1:-1;;;59529:48:0;;;;;;;:::i;30870:238::-;30954:22;30962:4;30968:7;30954;:22::i;:::-;30949:152;;30993:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;30993:29:0;;;;;;;;;:36;;-1:-1:-1;;30993:36:0;31025:4;30993:36;;;31076:12;808:10;;728:98;31076:12;-1:-1:-1;;;;;31049:40:0;31067:7;-1:-1:-1;;;;;31049:40:0;31061:4;31049:40;;;;;;;;;;30870:238;;:::o;31288:239::-;31372:22;31380:4;31386:7;31372;:22::i;:::-;31368:152;;;31443:5;31411:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;31411:29:0;;;;;;;;;;:37;;-1:-1:-1;;31411:37:0;;;31468:40;808:10;;31411:12;;31468:40;;31443:5;31468:40;31288:239;;:::o;2184:132::-;2092:6;;-1:-1:-1;;;;;2092:6:0;808:10;2248:23;2240:68;;;;-1:-1:-1;;;2240:68:0;;20538:2:1;2240:68:0;;;20520:21:1;;;20557:18;;;20550:30;20616:34;20596:18;;;20589:62;20668:18;;2240:68:0;20336:356:1;57427:697:0;57530:7;57570:8;57530:7;57890:189;-1:-1:-1;;;;;57897:19:0;;57890:189;;57942:20;;;;:14;:20;;;;;;;;57937:102;;-1:-1:-1;57995:24:0;;;;:18;:24;;;;;;-1:-1:-1;;;;;57995:24:0;57937:102;-1:-1:-1;;58057:6:0;;;;57890:189;;;58100:5;57427:697;-1:-1:-1;;;57427:697:0:o;64722:390::-;63655:5;-1:-1:-1;;;;;64874:33:0;;;;64866:88;;;;-1:-1:-1;;;64866:88:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;64973:22:0;;64965:62;;;;-1:-1:-1;;;64965:62:0;;20899:2:1;64965:62:0;;;20881:21:1;20938:2;20918:18;;;20911:30;20977:29;20957:18;;;20950:57;21024:18;;64965:62:0;20697:351:1;64965:62:0;65069:35;;;;;;;;-1:-1:-1;;;;;65069:35:0;;;;;-1:-1:-1;;;;;65069:35:0;;;;;;;;;;-1:-1:-1;65040:26:0;;;:17;:26;;;;;;:64;;;;;;;-1:-1:-1;;;65040:64:0;;;;;;64722:390::o;3286:191::-;3379:6;;;-1:-1:-1;;;;;3396:17:0;;;-1:-1:-1;;;;;;3396:17:0;;;;;;;3429:40;;3379:6;;;3396:17;3379:6;;3429:40;;3360:16;;3429:40;3349:128;3286:191;:::o;55752:761::-;55940:153;;-1:-1:-1;;;55940:153:0;;55906:4;;-1:-1:-1;;;;;55940:36:0;;;;;:153;;55995:10;;56024:4;;56047:7;;56073:5;;55940:153;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55940:153:0;;;;;;;;-1:-1:-1;;55940:153:0;;;;;;;;;;;;:::i;:::-;;;55923:583;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56264:6;:13;56281:1;56264:18;56260:235;;56310:40;;-1:-1:-1;;;56310:40:0;;;;;;;;;;;56260:235;56453:6;56447:13;56438:6;56434:2;56430:15;56423:38;55923:583;-1:-1:-1;;;;;;56149:55:0;-1:-1:-1;;;56149:55:0;;-1:-1:-1;55923:583:0;55752:761;;;;;;:::o;19614:723::-;19670:13;19891:5;19900:1;19891:10;19887:53;;-1:-1:-1;;19918:10:0;;;;;;;;;;;;-1:-1:-1;;;19918:10:0;;;;;19614:723::o;19887:53::-;19965:5;19950:12;20006:78;20013:9;;20006:78;;20039:8;;;;:::i;:::-;;-1:-1:-1;20062:10:0;;-1:-1:-1;20070:2:0;20062:10;;:::i;:::-;;;20006:78;;;20094:19;20126:6;20116:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20116:17:0;;20094:39;;20144:154;20151:10;;20144:154;;20178:11;20188:1;20178:11;;:::i;:::-;;-1:-1:-1;20247:10:0;20255:2;20247:5;:10;:::i;:::-;20234:24;;:2;:24;:::i;:::-;20221:39;;20204:6;20211;20204:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;20204:56:0;;;;;;;;-1:-1:-1;20275:11:0;20284:2;20275:11;;:::i;:::-;;;20144:154;;49206:367;49318:4;-1:-1:-1;;;;;;49360:34:0;;-1:-1:-1;;;49360:34:0;;:85;;-1:-1:-1;;;;;;;49411:34:0;;-1:-1:-1;;;49411:34:0;49360:85;:145;;;-1:-1:-1;;;;;;;49462:43:0;;-1:-1:-1;;;49462:43:0;49360:145;:205;;;-1:-1:-1;;;;;;;49522:43:0;;-1:-1:-1;;;49522:43:0;49340:225;49206:367;-1:-1:-1;;49206:367:0:o;27007:492::-;27096:22;27104:4;27110:7;27096;:22::i;:::-;27091:401;;27284:28;27304:7;27284:19;:28::i;:::-;27385:38;27413:4;27420:2;27385:19;:38::i;:::-;27189:257;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;27189:257:0;;;;;;;;;;-1:-1:-1;;;27135:345:0;;;;;;;:::i;59922:204::-;60057:15;;60090:28;;-1:-1:-1;;;60090:28:0;;-1:-1:-1;;;;;3274:32:1;;;60090:28:0;;;3256:51:1;60010:4:0;;60057:15;;;;60090:18;;3229::1;;60090:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;67330:296::-;67413:7;67456:4;67413:7;67471:118;67495:5;:12;67491:1;:16;67471:118;;;67544:33;67554:12;67568:5;67574:1;67568:8;;;;;;;;:::i;:::-;;;;;;;67544:9;:33::i;:::-;67529:48;-1:-1:-1;67509:3:0;;;;:::i;:::-;;;;67471:118;;;-1:-1:-1;67606:12:0;67330:296;-1:-1:-1;;;67330:296:0:o;50937:661::-;51061:21;51067:3;51072:9;51061:5;:21::i;:::-;51093:22;51132:1;51118:11;;:15;;;;:::i;:::-;51093:40;-1:-1:-1;;;;;;51173:15:0;;;:20;51169:411;;51232:11;;:23;;;-1:-1:-1;;51232:27:0;51278:287;51373:9;;51335:55;51364:1;51368:3;51373:9;51384:5;51335:20;:55::i;:::-;51304:208;;51448:40;;-1:-1:-1;;;51448:40:0;;;;;;;;;;;51304:208;51549:14;51539:7;:24;51278:287;;51195:385;51050:548;50937:661;;;:::o;60134:337::-;60287:15;;60240:4;;-1:-1:-1;;;;;60287:15:0;;60313:46;;60355:4;60348:11;;;;;60313:46;60386:16;60394:7;60386;:16::i;:::-;-1:-1:-1;;;;;60374:28:0;:8;-1:-1:-1;;;;;60374:28:0;;60370:45;;60411:4;60404:11;;;;;60370:45;60433:30;;-1:-1:-1;;;60433:30:0;;60452:10;60433:30;;;3256:51:1;-1:-1:-1;;;;;60433:18:0;;;;;3229::1;;60433:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;21555:151::-;21613:13;21646:52;-1:-1:-1;;;;;21658:22:0;;19505:2;20915:483;21017:13;21048:19;21080:10;21084:6;21080:1;:10;:::i;:::-;:14;;21093:1;21080:14;:::i;:::-;21070:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21070:25:0;;21048:47;;-1:-1:-1;;;21106:6:0;21113:1;21106:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;21106:15:0;;;;;;;;;-1:-1:-1;;;21132:6:0;21139:1;21132:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;21132:15:0;;;;;;;;-1:-1:-1;21163:9:0;21175:10;21179:6;21175:1;:10;:::i;:::-;:14;;21188:1;21175:14;:::i;:::-;21163:26;;21158:135;21195:1;21191;:5;21158:135;;;-1:-1:-1;;;21243:5:0;21251:3;21243:11;21230:25;;;;;;;:::i;:::-;;;;21218:6;21225:1;21218:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;21218:37:0;;;;;;;;-1:-1:-1;21280:1:0;21270:11;;;;;21198:3;;;:::i;:::-;;;21158:135;;;-1:-1:-1;21311:10:0;;21303:55;;;;-1:-1:-1;;;21303:55:0;;23328:2:1;21303:55:0;;;23310:21:1;;;23347:18;;;23340:30;23406:34;23386:18;;;23379:62;23458:18;;21303:55:0;23126:356:1;74370:149:0;74433:7;74464:1;74460;:5;:51;;74595:13;74689:15;;;74725:4;74718:15;;;74772:4;74756:21;;74460:51;;;74595:13;74689:15;;;74725:4;74718:15;;;74772:4;74756:21;;74468:20;74527:268;52240:544;-1:-1:-1;;;;;52311:17:0;;52307:60;;52337:30;;-1:-1:-1;;;52337:30:0;;;;;;;;;;;52307:60;52382:9;52395:1;52382:14;52378:44;;52405:17;;-1:-1:-1;;;52405:17:0;;;;;;;;;;;52378:44;-1:-1:-1;;;;;52458:13:0;;;;;;:8;:13;;;;;:26;;;;;;52518:11;;:23;;;;52558:117;52592:8;52588:1;:12;52558:117;;;52631:28;;52657:1;;-1:-1:-1;;;;;52631:28:0;;;52648:1;;52631:28;;52648:1;;52631:28;52602:3;;52558:117;;;-1:-1:-1;52710:11:0;;;52691:31;;;;:18;:31;;;;;:37;;-1:-1:-1;;;;;;52691:37:0;-1:-1:-1;;;;;52691:37:0;;;;;;;;;;;52743:22;;;-1:-1:-1;52240:544:0:o;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:188::-;660:20;;-1:-1:-1;;;;;709:46:1;;699:57;;689:85;;770:1;767;760:12;689:85;592:188;;;:::o;785:260::-;853:6;861;914:2;902:9;893:7;889:23;885:32;882:52;;;930:1;927;920:12;882:52;953:29;972:9;953:29;:::i;:::-;943:39;;1001:38;1035:2;1024:9;1020:18;1001:38;:::i;:::-;991:48;;785:260;;;;;:::o;1050:131::-;-1:-1:-1;;;;;1125:31:1;;1115:42;;1105:70;;1171:1;1168;1161:12;1186:179;1253:20;;-1:-1:-1;;;;;1302:38:1;;1292:49;;1282:77;;1355:1;1352;1345:12;1370:319;1437:6;1445;1498:2;1486:9;1477:7;1473:23;1469:32;1466:52;;;1514:1;1511;1504:12;1466:52;1553:9;1540:23;1572:31;1597:5;1572:31;:::i;:::-;1622:5;-1:-1:-1;1646:37:1;1679:2;1664:18;;1646:37;:::i;1694:127::-;1755:10;1750:3;1746:20;1743:1;1736:31;1786:4;1783:1;1776:15;1810:4;1807:1;1800:15;1826:338;1968:2;1953:18;;2001:1;1990:13;;1980:144;;2046:10;2041:3;2037:20;2034:1;2027:31;2081:4;2078:1;2071:15;2109:4;2106:1;2099:15;1980:144;2133:25;;;1826:338;:::o;2169:250::-;2254:1;2264:113;2278:6;2275:1;2272:13;2264:113;;;2354:11;;;2348:18;2335:11;;;2328:39;2300:2;2293:10;2264:113;;;-1:-1:-1;;2411:1:1;2393:16;;2386:27;2169:250::o;2424:271::-;2466:3;2504:5;2498:12;2531:6;2526:3;2519:19;2547:76;2616:6;2609:4;2604:3;2600:14;2593:4;2586:5;2582:16;2547:76;:::i;:::-;2677:2;2656:15;-1:-1:-1;;2652:29:1;2643:39;;;;2684:4;2639:50;;2424:271;-1:-1:-1;;2424:271:1:o;2700:220::-;2849:2;2838:9;2831:21;2812:4;2869:45;2910:2;2899:9;2895:18;2887:6;2869:45;:::i;2925:180::-;2984:6;3037:2;3025:9;3016:7;3012:23;3008:32;3005:52;;;3053:1;3050;3043:12;3005:52;-1:-1:-1;3076:23:1;;2925:180;-1:-1:-1;2925:180:1:o;3318:315::-;3386:6;3394;3447:2;3435:9;3426:7;3422:23;3418:32;3415:52;;;3463:1;3460;3453:12;3415:52;3502:9;3489:23;3521:31;3546:5;3521:31;:::i;:::-;3571:5;3623:2;3608:18;;;;3595:32;;-1:-1:-1;;;3318:315:1:o;3638:247::-;3697:6;3750:2;3738:9;3729:7;3725:23;3721:32;3718:52;;;3766:1;3763;3756:12;3718:52;3805:9;3792:23;3824:31;3849:5;3824:31;:::i;4072:367::-;4135:8;4145:6;4199:3;4192:4;4184:6;4180:17;4176:27;4166:55;;4217:1;4214;4207:12;4166:55;-1:-1:-1;4240:20:1;;4283:18;4272:30;;4269:50;;;4315:1;4312;4305:12;4269:50;4352:4;4344:6;4340:17;4328:29;;4412:3;4405:4;4395:6;4392:1;4388:14;4380:6;4376:27;4372:38;4369:47;4366:67;;;4429:1;4426;4419:12;4444:505;4539:6;4547;4555;4608:2;4596:9;4587:7;4583:23;4579:32;4576:52;;;4624:1;4621;4614:12;4576:52;4664:9;4651:23;4697:18;4689:6;4686:30;4683:50;;;4729:1;4726;4719:12;4683:50;4768:70;4830:7;4821:6;4810:9;4806:22;4768:70;:::i;:::-;4857:8;;4742:96;;-1:-1:-1;4939:2:1;4924:18;;;;4911:32;;4444:505;-1:-1:-1;;;;4444:505:1:o;4954:456::-;5031:6;5039;5047;5100:2;5088:9;5079:7;5075:23;5071:32;5068:52;;;5116:1;5113;5106:12;5068:52;5155:9;5142:23;5174:31;5199:5;5174:31;:::i;:::-;5224:5;-1:-1:-1;5281:2:1;5266:18;;5253:32;5294:33;5253:32;5294:33;:::i;:::-;4954:456;;5346:7;;-1:-1:-1;;;5400:2:1;5385:18;;;;5372:32;;4954:456::o;5782:248::-;5850:6;5858;5911:2;5899:9;5890:7;5886:23;5882:32;5879:52;;;5927:1;5924;5917:12;5879:52;-1:-1:-1;;5950:23:1;;;6020:2;6005:18;;;5992:32;;-1:-1:-1;5782:248:1:o;6314:315::-;6382:6;6390;6443:2;6431:9;6422:7;6418:23;6414:32;6411:52;;;6459:1;6456;6449:12;6411:52;6495:9;6482:23;6472:33;;6555:2;6544:9;6540:18;6527:32;6568:31;6593:5;6568:31;:::i;:::-;6618:5;6608:15;;;6314:315;;;;;:::o;6894:592::-;6965:6;6973;7026:2;7014:9;7005:7;7001:23;6997:32;6994:52;;;7042:1;7039;7032:12;6994:52;7082:9;7069:23;7111:18;7152:2;7144:6;7141:14;7138:34;;;7168:1;7165;7158:12;7138:34;7206:6;7195:9;7191:22;7181:32;;7251:7;7244:4;7240:2;7236:13;7232:27;7222:55;;7273:1;7270;7263:12;7222:55;7313:2;7300:16;7339:2;7331:6;7328:14;7325:34;;;7355:1;7352;7345:12;7325:34;7400:7;7395:2;7386:6;7382:2;7378:15;7374:24;7371:37;7368:57;;;7421:1;7418;7411:12;7368:57;7452:2;7444:11;;;;;7474:6;;-1:-1:-1;6894:592:1;;-1:-1:-1;;;;6894:592:1:o;7491:387::-;7567:6;7575;7583;7636:2;7624:9;7615:7;7611:23;7607:32;7604:52;;;7652:1;7649;7642:12;7604:52;7688:9;7675:23;7665:33;;7748:2;7737:9;7733:18;7720:32;7761:31;7786:5;7761:31;:::i;:::-;7811:5;-1:-1:-1;7835:37:1;7868:2;7853:18;;7835:37;:::i;:::-;7825:47;;7491:387;;;;;:::o;7883:773::-;8005:6;8013;8021;8029;8082:2;8070:9;8061:7;8057:23;8053:32;8050:52;;;8098:1;8095;8088:12;8050:52;8138:9;8125:23;8167:18;8208:2;8200:6;8197:14;8194:34;;;8224:1;8221;8214:12;8194:34;8263:70;8325:7;8316:6;8305:9;8301:22;8263:70;:::i;:::-;8352:8;;-1:-1:-1;8237:96:1;-1:-1:-1;8440:2:1;8425:18;;8412:32;;-1:-1:-1;8456:16:1;;;8453:36;;;8485:1;8482;8475:12;8453:36;;8524:72;8588:7;8577:8;8566:9;8562:24;8524:72;:::i;:::-;7883:773;;;;-1:-1:-1;8615:8:1;-1:-1:-1;;;;7883:773:1:o;9217:118::-;9303:5;9296:13;9289:21;9282:5;9279:32;9269:60;;9325:1;9322;9315:12;9340:382;9405:6;9413;9466:2;9454:9;9445:7;9441:23;9437:32;9434:52;;;9482:1;9479;9472:12;9434:52;9521:9;9508:23;9540:31;9565:5;9540:31;:::i;:::-;9590:5;-1:-1:-1;9647:2:1;9632:18;;9619:32;9660:30;9619:32;9660:30;:::i;9727:127::-;9788:10;9783:3;9779:20;9776:1;9769:31;9819:4;9816:1;9809:15;9843:4;9840:1;9833:15;9859:1266;9954:6;9962;9970;9978;10031:3;10019:9;10010:7;10006:23;10002:33;9999:53;;;10048:1;10045;10038:12;9999:53;10087:9;10074:23;10106:31;10131:5;10106:31;:::i;:::-;10156:5;-1:-1:-1;10213:2:1;10198:18;;10185:32;10226:33;10185:32;10226:33;:::i;:::-;10278:7;-1:-1:-1;10332:2:1;10317:18;;10304:32;;-1:-1:-1;10387:2:1;10372:18;;10359:32;10410:18;10440:14;;;10437:34;;;10467:1;10464;10457:12;10437:34;10505:6;10494:9;10490:22;10480:32;;10550:7;10543:4;10539:2;10535:13;10531:27;10521:55;;10572:1;10569;10562:12;10521:55;10608:2;10595:16;10630:2;10626;10623:10;10620:36;;;10636:18;;:::i;:::-;10711:2;10705:9;10679:2;10765:13;;-1:-1:-1;;10761:22:1;;;10785:2;10757:31;10753:40;10741:53;;;10809:18;;;10829:22;;;10806:46;10803:72;;;10855:18;;:::i;:::-;10895:10;10891:2;10884:22;10930:2;10922:6;10915:18;10970:7;10965:2;10960;10956;10952:11;10948:20;10945:33;10942:53;;;10991:1;10988;10981:12;10942:53;11047:2;11042;11038;11034:11;11029:2;11021:6;11017:15;11004:46;11092:1;11087:2;11082;11074:6;11070:15;11066:24;11059:35;11113:6;11103:16;;;;;;;9859:1266;;;;;;;:::o;11406:388::-;11474:6;11482;11535:2;11523:9;11514:7;11510:23;11506:32;11503:52;;;11551:1;11548;11541:12;11503:52;11590:9;11577:23;11609:31;11634:5;11609:31;:::i;:::-;11659:5;-1:-1:-1;11716:2:1;11701:18;;11688:32;11729:33;11688:32;11729:33;:::i;11799:380::-;11878:1;11874:12;;;;11921;;;11942:61;;11996:4;11988:6;11984:17;11974:27;;11942:61;12049:2;12041:6;12038:14;12018:18;12015:38;12012:161;;12095:10;12090:3;12086:20;12083:1;12076:31;12130:4;12127:1;12120:15;12158:4;12155:1;12148:15;12012:161;;11799:380;;;:::o;12184:127::-;12245:10;12240:3;12236:20;12233:1;12226:31;12276:4;12273:1;12266:15;12300:4;12297:1;12290:15;12316:128;12383:9;;;12404:11;;;12401:37;;;12418:18;;:::i;12449:168::-;12522:9;;;12553;;12570:15;;;12564:22;;12550:37;12540:71;;12591:18;;:::i;12622:125::-;12687:9;;;12708:10;;;12705:36;;;12721:18;;:::i;12986:127::-;13047:10;13042:3;13038:20;13035:1;13028:31;13078:4;13075:1;13068:15;13102:4;13099:1;13092:15;13118:120;13158:1;13184;13174:35;;13189:18;;:::i;:::-;-1:-1:-1;13223:9:1;;13118:120::o;13995:545::-;14097:2;14092:3;14089:11;14086:448;;;14133:1;14158:5;14154:2;14147:17;14203:4;14199:2;14189:19;14273:2;14261:10;14257:19;14254:1;14250:27;14244:4;14240:38;14309:4;14297:10;14294:20;14291:47;;;-1:-1:-1;14332:4:1;14291:47;14387:2;14382:3;14378:12;14375:1;14371:20;14365:4;14361:31;14351:41;;14442:82;14460:2;14453:5;14450:13;14442:82;;;14505:17;;;14486:1;14475:13;14442:82;;;14446:3;;;13995:545;;;:::o;14716:1206::-;14840:18;14835:3;14832:27;14829:53;;;14862:18;;:::i;:::-;14891:94;14981:3;14941:38;14973:4;14967:11;14941:38;:::i;:::-;14935:4;14891:94;:::i;:::-;15011:1;15036:2;15031:3;15028:11;15053:1;15048:616;;;;15708:1;15725:3;15722:93;;;-1:-1:-1;15781:19:1;;;15768:33;15722:93;-1:-1:-1;;14673:1:1;14669:11;;;14665:24;14661:29;14651:40;14697:1;14693:11;;;14648:57;15828:78;;15021:895;;15048:616;13942:1;13935:14;;;13979:4;13966:18;;-1:-1:-1;;15084:17:1;;;15185:9;15207:229;15221:7;15218:1;15215:14;15207:229;;;15310:19;;;15297:33;15282:49;;15417:4;15402:20;;;;15370:1;15358:14;;;;15237:12;15207:229;;;15211:3;15464;15455:7;15452:16;15449:159;;;15588:1;15584:6;15578:3;15572;15569:1;15565:11;15561:21;15557:34;15553:39;15540:9;15535:3;15531:19;15518:33;15514:79;15506:6;15499:95;15449:159;;;15651:1;15645:3;15642:1;15638:11;15634:19;15628:4;15621:33;15021:895;;14716:1206;;;:::o;15927:127::-;15988:10;15983:3;15979:20;15976:1;15969:31;16019:4;16016:1;16009:15;16043:4;16040:1;16033:15;16059:135;16098:3;16119:17;;;16116:43;;16139:18;;:::i;:::-;-1:-1:-1;16186:1:1;16175:13;;16059:135::o;16199:1352::-;16325:3;16319:10;16352:18;16344:6;16341:30;16338:56;;;16374:18;;:::i;:::-;16403:97;16493:6;16453:38;16485:4;16479:11;16453:38;:::i;:::-;16447:4;16403:97;:::i;:::-;16555:4;;16619:2;16608:14;;16636:1;16631:663;;;;17338:1;17355:6;17352:89;;;-1:-1:-1;17407:19:1;;;17401:26;17352:89;-1:-1:-1;;14673:1:1;14669:11;;;14665:24;14661:29;14651:40;14697:1;14693:11;;;14648:57;17454:81;;16601:944;;16631:663;13942:1;13935:14;;;13979:4;13966:18;;-1:-1:-1;;16667:20:1;;;16785:236;16799:7;16796:1;16793:14;16785:236;;;16888:19;;;16882:26;16867:42;;16980:27;;;;16948:1;16936:14;;;;16815:19;;16785:236;;;16789:3;17049:6;17040:7;17037:19;17034:201;;;17110:19;;;17104:26;-1:-1:-1;;17193:1:1;17189:14;;;17205:3;17185:24;17181:37;17177:42;17162:58;17147:74;;17034:201;-1:-1:-1;;;;;17281:1:1;17265:14;;;17261:22;17248:36;;-1:-1:-1;16199:1352:1:o;17556:722::-;17606:3;17647:5;17641:12;17676:36;17702:9;17676:36;:::i;:::-;17731:1;17748:18;;;17775:133;;;;17922:1;17917:355;;;;17741:531;;17775:133;-1:-1:-1;;17808:24:1;;17796:37;;17881:14;;17874:22;17862:35;;17853:45;;;-1:-1:-1;17775:133:1;;17917:355;17948:5;17945:1;17938:16;17977:4;18022:2;18019:1;18009:16;18047:1;18061:165;18075:6;18072:1;18069:13;18061:165;;;18153:14;;18140:11;;;18133:35;18196:16;;;;18090:10;;18061:165;;;18065:3;;;18255:6;18250:3;18246:16;18239:23;;17741:531;;;;;17556:722;;;;:::o;18283:469::-;18504:3;18532:38;18566:3;18558:6;18532:38;:::i;:::-;18599:6;18593:13;18615:65;18673:6;18669:2;18662:4;18654:6;18650:17;18615:65;:::i;:::-;18696:50;18738:6;18734:2;18730:15;18722:6;18696:50;:::i;:::-;18689:57;18283:469;-1:-1:-1;;;;;;;18283:469:1:o;19164:406::-;19366:2;19348:21;;;19405:2;19385:18;;;19378:30;19444:34;19439:2;19424:18;;19417:62;-1:-1:-1;;;19510:2:1;19495:18;;19488:40;19560:3;19545:19;;19164:406::o;19929:402::-;20131:2;20113:21;;;20170:2;20150:18;;;20143:30;20209:34;20204:2;20189:18;;20182:62;-1:-1:-1;;;20275:2:1;20260:18;;20253:36;20321:3;20306:19;;19929:402::o;21053:489::-;-1:-1:-1;;;;;21322:15:1;;;21304:34;;21374:15;;21369:2;21354:18;;21347:43;21421:2;21406:18;;21399:34;;;21469:3;21464:2;21449:18;;21442:31;;;21247:4;;21490:46;;21516:19;;21508:6;21490:46;:::i;:::-;21482:54;21053:489;-1:-1:-1;;;;;;21053:489:1:o;21547:249::-;21616:6;21669:2;21657:9;21648:7;21644:23;21640:32;21637:52;;;21685:1;21682;21675:12;21637:52;21717:9;21711:16;21736:30;21760:5;21736:30;:::i;21801:112::-;21833:1;21859;21849:35;;21864:18;;:::i;:::-;-1:-1:-1;21898:9:1;;21801:112::o;21918:812::-;22329:25;22324:3;22317:38;22299:3;22384:6;22378:13;22400:75;22468:6;22463:2;22458:3;22454:12;22447:4;22439:6;22435:17;22400:75;:::i;:::-;-1:-1:-1;;;22534:2:1;22494:16;;;22526:11;;;22519:40;22584:13;;22606:76;22584:13;22668:2;22660:11;;22653:4;22641:17;;22606:76;:::i;:::-;22702:17;22721:2;22698:26;;21918:812;-1:-1:-1;;;;21918:812:1:o;22735:245::-;22802:6;22855:2;22843:9;22834:7;22830:23;22826:32;22823:52;;;22871:1;22868;22861:12;22823:52;22903:9;22897:16;22922:28;22944:5;22922:28;:::i;22985:136::-;23024:3;23052:5;23042:39;;23061:18;;:::i;:::-;-1:-1:-1;;;23097:18:1;;22985:136::o
Swarm Source
ipfs://a53af23e2b1925c6a3a7b52e02f5af2ac1c122618fdbf083126e77b7ff2b6de1
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.