ERC-721
Overview
Max Total Supply
773 CEREZO
Holders
172
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
6 CEREZOLoading...
Loading
Loading...
Loading
Loading...
Loading
Contract Name:
CEREZO
Compiler Version
v0.8.21+commit.d9974bed
Contract Source Code (Solidity)
/** *Submitted for verification at polygonscan.com on 2023-11-30 */ // Sources flattened with hardhat v2.17.1 https://hardhat.org // SPDX-License-Identifier: MIT AND UNLICENSED // File @openzeppelin/contracts/access/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @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; } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @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; } } // File @openzeppelin/contracts/utils/introspection/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File @openzeppelin/contracts/utils/introspection/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @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; } } // File @openzeppelin/contracts/utils/math/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @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) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 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 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } } // File @openzeppelin/contracts/utils/math/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _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) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { 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] = _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); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } } // File @openzeppelin/contracts/access/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol) pragma solidity ^0.8.0; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ```solidity * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => 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()); } } } // File @openzeppelin/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.0; /** * @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); } // File @openzeppelin/contracts/token/common/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/common/ERC2981.sol) pragma solidity ^0.8.0; /** * @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]; } } // File @openzeppelin/contracts/token/ERC721/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // File @openzeppelin/contracts/utils/cryptography/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File contracts/coconut/IApprovalProxy.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; interface IApprovalProxy { function setApprovalForAll( address _owner, address _spender, bool _approved ) external; function isApprovedForAll( address _owner, address _spender, bool _approved ) external view returns (bool); } // File @openzeppelin/contracts/token/ERC721/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File contracts/structs/AddressData.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.4; struct AddressData { uint256 balance; uint256 numberMinted; uint256 numberBurned; uint64 aux; } // File contracts/utils/Revert.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.18; library Revert { function withSelector(bytes4 errorSelector) internal pure { assembly { mstore(0x00, errorSelector) revert(0x00, 0x04) } } } // File contracts/handlers/PackedAddressDataHandler.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.4; abstract contract PackedAddressDataHandler { // Mask of an entry in packed address data. uint256 internal constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 internal constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 internal constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 internal constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 internal constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) internal _packedAddressData; /** * @dev Return the address data for `owner`. */ function _addressDataOf( address owner ) internal view returns (AddressData memory) { uint256 packed = _packedAddressData[owner]; return AddressData({ balance: packed & _BITMASK_ADDRESS_DATA_ENTRY, numberMinted: (packed >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY, numberBurned: (packed >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY, aux: uint64(packed >> _BITPOS_AUX) }); } /** * @dev Returns the number of tokens in `owner`'s account. */ function _balanceOf(address owner) internal view returns (uint256) { if (owner == address(0)) Revert.withSelector(BalanceQueryForZeroAddress.selector); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } } // File contracts/structs/TokenOwnership.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.4; struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // File contracts/handlers/PackedTokenOwnershipHandler.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.4; abstract contract PackedTokenOwnershipHandler { // The bit position of `startTimestamp` in packed ownership. uint256 internal constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 internal constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 internal constant _BITPOS_NEXT_INITIALIZED = 225; // The bit position of `extraData` in packed ownership. uint256 internal constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 internal constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 internal constant _BITMASK_ADDRESS = (1 << 160) - 1; /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // Mapping from token ID to ownership details // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) internal _packedOwnerships; /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf( uint256 tokenId ) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt( uint256 index ) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Returns whether the ownership slot at `index` is initialized. */ function _ownershipIsInitialized( uint256 index ) internal view virtual returns (bool) { return _packedOwnerships[index] != 0; } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf( uint256 tokenId ) internal view virtual returns (uint256 packed) { packed = _packedOwnerships[tokenId]; if (packed != 0 && (packed & _BITMASK_BURNED) == 0) return packed; // the token is burned, or not exists. Revert.withSelector(OwnerQueryForNonexistentToken.selector); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership( uint256 packed ) internal pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData( address owner, uint256 flags ) internal view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or( owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags) ) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag( uint256 quantity ) internal pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) Revert.withSelector(OwnershipNotInitializedForExtraData.selector); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) internal view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } } // File contracts/erc721/ERC721.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, PackedTokenOwnershipHandler, PackedAddressDataHandler { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // The next token ID to be minted. uint256 public currentIndex; // The highest token ID that has been minted. uint256 private _currentMaxTokenId; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; currentIndex = _startTokenId(); } /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 1; } /** * @dev Set the next token ID. */ function _setCurrentIndex(uint256 newCurrentIndex) internal virtual { currentIndex = newCurrentIndex; } /** * @dev Returns the max minted token ID. */ function _maxTokenId() internal view virtual returns (uint256) { return _currentMaxTokenId; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface( bytes4 interfaceId ) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf( address owner ) public view virtual override returns (uint256) { return _balanceOf(owner); } /** * @dev See {IERC721-ownerOf}. */ function ownerOf( uint256 tokenId ) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI( uint256 tokenId ) public view virtual override returns (string memory) { _requireMinted(tokenId); return _tokenURI(tokenId); } /** * @dev Empty fy default, can be overridden in child contracts. */ function _tokenURI( uint256 /** tokenId **/ ) internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved( uint256 tokenId ) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll( address operator, bool approved ) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll( address owner, address operator ) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require( _isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved" ); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public virtual override { require( _isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved" ); _safeTransfer(from, to, tokenId, data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { _transfer(from, to, tokenId); require( _checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { uint256 packed = _packedOwnerships[tokenId]; return packed != 0 && (packed & _BITMASK_BURNED) == 0; } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner( address spender, uint256 tokenId ) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[tokenId] = _packOwnershipData( to, _nextInitializedFlag(1) | _nextExtraData(address(0), to, 0) ); // Updates: // - `balance += 1`. // - `numberMinted += 1`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += ((1 << _BITPOS_NUMBER_MINTED) | 1); } if (tokenId > _currentMaxTokenId) { _currentMaxTokenId = tokenId; } emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Mints `quantity` tokens and transfers them to `to`. */ function _mintTokens(address to, uint256 quantity) internal virtual { require(quantity > 0, "quantity must be positive"); uint256 count = 0; uint256 tokenId = currentIndex; while (count < quantity) { while (_exists(tokenId)) { tokenId++; } _safeMint(to, tokenId); unchecked { count++; tokenId++; } } currentIndex = tokenId; } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address owner = address(uint160(prevOwnershipPacked)); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[owner] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( owner, _BITMASK_BURNED | _nextExtraData(owner, address(0), prevOwnershipPacked) ); } emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require( ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner" ); require(to != address(0), "ERC721: transfer to the zero address"); uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require( ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner" ); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. _packedOwnerships[tokenId] = _packOwnershipData( to, _nextExtraData(from, to, prevOwnershipPacked) ); } emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received( _msgSender(), from, tokenId, data ) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert( "ERC721: transfer to non ERC721Receiver implementer" ); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual {} } // File contracts/erc721/extensions/IERC721Queryable.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.4; /** * @dev Interface of ERC721Queryable. * (based on IERC721AQueryable.sol from v4.2.3) */ interface IERC721Queryable is IERC721 { /** * Invalid query range (`start` >= `stop`). */ error InvalidQueryRange(); /** * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting. * * If the `tokenId` is out of bounds: * * - `addr = address(0)` * - `startTimestamp = 0` * - `burned = false` * - `extraData = 0` * * If the `tokenId` is burned: * * - `addr = <Address of owner before token was burned>` * - `startTimestamp = <Timestamp when token was burned>` * - `burned = true` * - `extraData = <Extra data when token was burned>` * * Otherwise: * * - `addr = <Address of owner>` * - `startTimestamp = <Timestamp of start of ownership>` * - `burned = false` * - `extraData = <Extra data at start of ownership>` */ function explicitOwnershipOf( uint256 tokenId ) external view returns (TokenOwnership memory); /** * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order. * See {ERC721Queryable-explicitOwnershipOf} */ function explicitOwnershipsOf( uint256[] memory tokenIds ) external view returns (TokenOwnership[] memory); /** * @dev Returns an array of token IDs owned by `owner`, * in the range [`start`, `stop`) * (i.e. `start <= tokenId < stop`). * * This function allows for tokens to be queried if the collection * grows too big for a single call of {ERC721Queryable-tokensOfOwner}. * * Requirements: * * - `start < stop` */ function tokensOfOwnerIn( address owner, uint256 start, uint256 stop ) external view returns (uint256[] memory); /** * @dev Returns an array of token IDs owned by `owner`. * * This function scans the ownership mapping and is O(`totalSupply`) in complexity. * It is meant to be called off-chain. * * See {ERC721Queryable-tokensOfOwnerIn} for splitting the scan into * multiple smaller scans if the collection is large enough to cause * an out-of-gas error (10K collections should be fine). */ function tokensOfOwner( address owner ) external view returns (uint256[] memory); } // File contracts/erc721/extensions/ERC721Queryable.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.4; /** * @title ERC721Queryable. * * @dev ERC721 subclass with convenience query functions. * (based on ERC721Queryable.sol from v 4.2.3) */ abstract contract ERC721Queryable is ERC721, IERC721Queryable { /** * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting. * * If the `tokenId` is out of bounds: * * - `addr = address(0)` * - `startTimestamp = 0` * - `burned = false` * - `extraData = 0` * * If the `tokenId` is burned: * * - `addr = <Address of owner before token was burned>` * - `startTimestamp = <Timestamp when token was burned>` * - `burned = true` * - `extraData = <Extra data when token was burned>` * * Otherwise: * * - `addr = <Address of owner>` * - `startTimestamp = <Timestamp of start of ownership>` * - `burned = false` * - `extraData = <Extra data at start of ownership>` */ function explicitOwnershipOf( uint256 tokenId ) public view virtual override returns (TokenOwnership memory ownership) { return _ownershipAt(tokenId); } /** * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order. * See {ERC721Queryable-explicitOwnershipOf} */ function explicitOwnershipsOf( uint256[] calldata tokenIds ) external view virtual override returns (TokenOwnership[] memory) { TokenOwnership[] memory ownerships; uint256 i = tokenIds.length; assembly { // Grab the free memory pointer. ownerships := mload(0x40) // Store the length. mstore(ownerships, i) // Allocate one word for the length, // `tokenIds.length` words for the pointers. i := shl(5, i) // Multiply `i` by 32. mstore(0x40, add(add(ownerships, 0x20), i)) } while (i != 0) { uint256 tokenId; assembly { i := sub(i, 0x20) tokenId := calldataload(add(tokenIds.offset, i)) } TokenOwnership memory ownership = explicitOwnershipOf(tokenId); assembly { // Store the pointer of `ownership` in the `ownerships` array. mstore(add(add(ownerships, 0x20), i), ownership) } } return ownerships; } /** * @dev Returns an array of token IDs owned by `owner`, * in the range [`start`, `stop`) * (i.e. `start <= tokenId < stop`). * * This function allows for tokens to be queried if the collection * grows too big for a single call of {ERC721Queryable-tokensOfOwner}. * * Requirements: * * - `start < stop` */ function tokensOfOwnerIn( address owner, uint256 start, uint256 stop ) external view virtual override returns (uint256[] memory) { return _tokensOfOwnerIn(owner, start, stop); } /** * @dev Returns an array of token IDs owned by `owner`. * * This function scans the ownership mapping and is O(`totalSupply`) in complexity. * It is meant to be called off-chain. * * See {ERC721Queryable-tokensOfOwnerIn} for splitting the scan into * multiple smaller scans if the collection is large enough to cause * an out-of-gas error (10K collections should be fine). */ function tokensOfOwner( address owner ) external view virtual override returns (uint256[] memory) { uint256 start = _startTokenId(); uint256 stop = _maxTokenId() + 1; uint256[] memory tokenIds; if (start != stop) tokenIds = _tokensOfOwnerIn(owner, start, stop); return tokenIds; } /** * @dev Helper function for returning an array of token IDs owned by `owner`. * * Note that this function is optimized for smaller bytecode size over runtime gas, * since it is meant to be called off-chain. */ function _tokensOfOwnerIn( address owner, uint256 start, uint256 stop ) private view returns (uint256[] memory) { unchecked { if (start >= stop) Revert.withSelector(InvalidQueryRange.selector); // Set `start = max(start, _startTokenId())`. if (start < _startTokenId()) { start = _startTokenId(); } uint256 stopLimit = _maxTokenId() + 1; // Set `stop = min(stop, stopLimit)`. if (stop >= stopLimit) { stop = stopLimit; } uint256[] memory tokenIds; uint256 tokenIdsMaxLength = balanceOf(owner); bool startLtStop = start < stop; assembly { // Set `tokenIdsMaxLength` to zero if `start` is less than `stop`. tokenIdsMaxLength := mul(tokenIdsMaxLength, startLtStop) } if (tokenIdsMaxLength != 0) { // Set `tokenIdsMaxLength = min(balanceOf(owner), stop - start)`, // to cater for cases where `balanceOf(owner)` is too big. if (stop - start <= tokenIdsMaxLength) { tokenIdsMaxLength = stop - start; } assembly { // Grab the free memory pointer. tokenIds := mload(0x40) // Allocate one word for the length, and `tokenIdsMaxLength` words // for the data. `shl(5, x)` is equivalent to `mul(32, x)`. mstore( 0x40, add(tokenIds, shl(5, add(tokenIdsMaxLength, 1))) ) } // We need to call `explicitOwnershipOf(start)`, // because the slot at `start` may not be initialized. TokenOwnership memory ownership = explicitOwnershipOf(start); address currOwnershipAddr; // If the starting slot exists (i.e. not burned), // initialize `currOwnershipAddr`. // `ownership.address` will not be zero, // as `start` is clamped to the valid token ID range. if (!ownership.burned) { currOwnershipAddr = ownership.addr; } uint256 tokenIdsIdx; // Use a do-while, which is slightly more efficient for this case, // as the array will at least contain one element. do { ownership = _ownershipAt(start); if (ownership.addr == address(0)) { // If the slot is empty, skip it. start++; continue; } assembly { switch mload(add(ownership, 0x40)) // if `ownership.burned == false`. case 0 { // if `ownership.addr != address(0)`. // The `addr` already has it's upper 96 bits clearned, // since it is written to memory with regular Solidity. if mload(ownership) { currOwnershipAddr := mload(ownership) } // if `currOwnershipAddr == owner`. // The `shl(96, x)` is to make the comparison agnostic to any // dirty upper 96 bits in `owner`. if iszero(shl(96, xor(currOwnershipAddr, owner))) { tokenIdsIdx := add(tokenIdsIdx, 1) mstore( add(tokenIds, shl(5, tokenIdsIdx)), start ) } } // Otherwise, reset `currOwnershipAddr`. // This handles the case of batch burned tokens // (burned bit of first slot set, remaining slots left uninitialized). default { currOwnershipAddr := 0 } start := add(start, 1) } } while (!(start == stop || tokenIdsIdx == tokenIdsMaxLength)); // Store the length of the array. assembly { mstore(tokenIds, tokenIdsIdx) } } return tokenIds; } } } // File contracts/structs/CoconutMintTicket.sol // Original license: SPDX_License_Identifier: UNLICENSED pragma solidity ^0.8.18; struct CoconutMintTicket { uint256 quantityLimit; uint256 extra; bytes uuid; bytes headSignature; bytes bodySignature; address bodySigner; address receiver; } // File contracts/handlers/EIP712CoconutMintTicketHandler.sol // Original license: SPDX_License_Identifier: UNLICENSED pragma solidity ^0.8.18; abstract contract EIP712CoconutMintTicketHandler { bytes32 private constant DOMAIN_SEPARATOR_TYPEHASH = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)" ); bytes32 private constant ONETIMESIGNER_TYPEHASH = keccak256("OnetimeSigner(address signer,bytes32 nonce)"); /** * @dev Return the version of the domain separator. */ function _eip712Version() internal pure virtual returns (string memory) { return "1.0"; } /** * @dev Return the salt of the domain separator. */ function _eip712Salt() internal pure virtual returns (bytes32) { return 0x0; } /** * @dev Returns the domain separator. */ function _createDomainSeparator( string memory name, address verifyingContract ) internal view returns (bytes32) { return keccak256( abi.encode( DOMAIN_SEPARATOR_TYPEHASH, keccak256(bytes(name)), keccak256(bytes(_eip712Version())), block.chainid, verifyingContract, _eip712Salt() ) ); } /** * @dev Return address tuple that are head signer and body signer. */ function _recoverSigners( bytes32 domainSeparator, CoconutMintTicket calldata mintTicket ) internal pure returns (address, address) { // onetimeSigner は EIP-712署名の認証をする bytes32 onetimeSignerHash = keccak256( // memo: abi.encode を使う // 可変長のデータの連結に使用する abi.encode( ONETIMESIGNER_TYPEHASH, mintTicket.bodySigner, keccak256(abi.encodePacked(mintTicket.bodySigner)) ) ); bytes32 headHash = keccak256( // memo: abi.encodePacked を使う // 固定長のデータの連結に使用する abi.encodePacked("\x19\x01", domainSeparator, onetimeSignerHash) ); address headSigner = ECDSA.recover(headHash, mintTicket.headSignature); bytes32 bodyHash = ECDSA.toEthSignedMessageHash( keccak256( abi.encodePacked( mintTicket.receiver, mintTicket.uuid, mintTicket.quantityLimit, mintTicket.extra ) ) ); address bodySigner = ECDSA.recover(bodyHash, mintTicket.bodySignature); return (headSigner, bodySigner); } } // File contracts/structs/SaleState.sol // Original license: SPDX_License_Identifier: UNLICENSED pragma solidity ^0.8.18; struct SaleState { bool isBeforeSale; bool isAllowlistSale; bool isPublicSale; bool isSaleEnded; } // File contracts/handlers/SaleStateHandler.sol // Original license: SPDX_License_Identifier: UNLICENSED pragma solidity ^0.8.18; abstract contract SaleStateHandler { // ============================== // errors // ============================== event UpdateSaleState(address updater, uint256 saleState); // ============================== // errors // ============================== error NotInAllolistSalePhaseError(); error NotInPublicSalePhaseError(); // ============================== // state variables // ============================== uint256 private constant _BEFORE_SALE = 1; uint256 private constant _ALLOWLIST_SALE = 1 << 1; uint256 private constant _PUBLIC_SALE = 1 << 2; uint256 private constant _SALE_ENDED = 1 << 3; uint256 private currentSaleState; constructor() { currentSaleState = _BEFORE_SALE; } // ==================== // modifier // ==================== modifier onlyDuringAllowlistSale() { if (!((currentSaleState & _ALLOWLIST_SALE) == _ALLOWLIST_SALE)) { Revert.withSelector(NotInAllolistSalePhaseError.selector); } _; } modifier onlyDuringPublicSale() { if (!((currentSaleState & _PUBLIC_SALE) == _PUBLIC_SALE)) { Revert.withSelector(NotInPublicSalePhaseError.selector); } _; } // ==================== // functions // ==================== /** * @dev Set the current sale state to before sale. */ function _resetToBeforeSale() internal { currentSaleState = _BEFORE_SALE; emit UpdateSaleState(msg.sender, currentSaleState); } /** * @dev Set the current sale state to allowlist sale. */ function _startAllowlistSale() internal { currentSaleState = _ALLOWLIST_SALE; emit UpdateSaleState(msg.sender, currentSaleState); } /** * @dev Set the current sale state to public sale. */ function _startPublicSale() internal { currentSaleState = _PUBLIC_SALE; emit UpdateSaleState(msg.sender, currentSaleState); } /** * @dev Set the current sale state to allowlist and public sale. */ function _startAllowlistAndPublicSale() internal { currentSaleState = _ALLOWLIST_SALE | _PUBLIC_SALE; emit UpdateSaleState(msg.sender, currentSaleState); } /** * @dev Set the current sale state to sale ended. */ function _endSale() internal { currentSaleState = _SALE_ENDED; emit UpdateSaleState(msg.sender, currentSaleState); } /** * @dev Returns the current sale state. */ function saleState() public view returns (SaleState memory) { return SaleState({ isBeforeSale: currentSaleState & _BEFORE_SALE == _BEFORE_SALE, isAllowlistSale: currentSaleState & _ALLOWLIST_SALE == _ALLOWLIST_SALE, isPublicSale: currentSaleState & _PUBLIC_SALE == _PUBLIC_SALE, isSaleEnded: currentSaleState & _SALE_ENDED == _SALE_ENDED }); } } // File contracts/libs/CoconutMintTicketLibs.sol // Original license: SPDX_License_Identifier: UNLICENSED pragma solidity ^0.8.18; // uint256 extra // Bits Layout: // - [0..7] `SettingsFlag`: 8bit // [0] 1bit, `priceFlag`: 0: not set, 1: set // [1] 1bit, `onceTicketFlag`: 0: not set, 1: set // [2] 1bit, `useTokenIdFlag`: 0: not set, 1: set // [3..7] 5bit, `reserved` // [8..15] `availableTerm`: 8bit, 00000000 -> not available // 00000001 -> available for before sale // 00000010 -> available for allowlist sale // 00000100 -> available for public sale // 00001000 -> available for sale ended // [12..15] 4bit, `reserved` // - [16..88] `price`: 72bit 0 ether ~ 2^72 ether // - [89..113] `tokenId`: 24bit 0 ~ 2^24, number of id // - [114..255] `reserved`: library CoconutMintTicketLibs { /** * @dev Return the price info of the mint ticket. */ function getPriceInfo( CoconutMintTicket calldata mintTicket ) internal pure returns (bool, uint256) { if (mintTicket.extra & 0x01 == 1) { uint256 priceMask = (1 << 72) - 1; uint256 price = (mintTicket.extra >> 16) & priceMask; return (true, price); } else { return (false, 0); } } /** * @dev Return whether the mint ticket is once ticket or not. */ function isOnceTicket( CoconutMintTicket calldata mintTicket ) internal pure returns (bool) { return (mintTicket.extra & 0x02) == 2; } /** * @dev Return the tokenId info of the mint ticket. */ function getTokenIdInfo( CoconutMintTicket calldata mintTicket ) internal pure returns (bool, uint256) { if (mintTicket.extra & 0x04 == 4) { uint256 tokenIdMask = (1 << 24) - 1; uint256 tokenId = (mintTicket.extra >> 89) & tokenIdMask; return (true, tokenId); } else { return (false, 0); } } /** * @dev Return whether the mint ticket is available or not. */ function isAvailableTicket( CoconutMintTicket calldata mintTicket, SaleState memory saleState ) internal pure returns (bool) { uint256 availableTerm = (mintTicket.extra >> 8) & 0xff; if (saleState.isBeforeSale && (availableTerm & 0x01) == 1) { return true; } else if (saleState.isAllowlistSale && (availableTerm & 0x02) == 2) { return true; } else if (saleState.isPublicSale && (availableTerm & 0x04) == 4) { return true; } else if (saleState.isSaleEnded && (availableTerm & 0x08) == 8) { return true; } else { return false; } } } // File contracts/coconut/CoconutERC721.sol // Original license: SPDX_License_Identifier: UNLICENSED pragma solidity ^0.8.18; abstract contract CoconutERC721 is ERC721Queryable, ERC2981, AccessControl, EIP712CoconutMintTicketHandler, SaleStateHandler { using Strings for uint256; using CoconutMintTicketLibs for CoconutMintTicket; // ============================== // roles // ============================== // (aready defined DEFAULT_ADMIN_ROLE in AccessControl.sol) bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant RELAY_MINTER_ROLE = keccak256("RELAY_MINTER_ROLE"); bytes32 public constant HEAD_SIGNER_ROLE = keccak256("HEAD_SIGNER_ROLE"); // ============================== // structs // ============================== struct AddressDataExt { uint256 balance; uint256 numberMinted; uint256 numberBurned; uint256 numberAllowlistSaleMinted; uint256 numberPublicSaleMinted; } // ============================== // events // ============================== event UpdateBaseURI(address sender, string newBaseURI); event UpdateMetadataExtension(address sender, string newMetadataExtension); event UpdateBurnPermission(address sender, bool permission); event UpdateApprovalProxy(address sender, address newProxyContract); event UpdateSupplyLimit(address sender, uint256 newSupplyLimit); event UpdateQuantityLimit(address sender, uint256 newQuantityLimit); event UpdateAllowlistSalePrice(address sender, uint256 newSalePrice); event UpdateSalePrice(address sender, uint256 newSalePrice); event UpdatePayoutAddress(address sender, address newPayoutAddress); event UpdateDefaultRoyaltyInfo( address sender, address receiver, uint96 feeNumerator ); event UpdateTokenRoyalty( address sender, uint256 tokenId, address receiver, uint96 feeNumerator ); event UpdateTokenIdIndex(address sender, uint256 newTokenIdIndex); // ============================== // errors // ============================== error BurnPermissionError(); error NotApprovedOrOwnerError(); error ExceedSupplyLimitError(); error AllowlistExceedQuantityLimitError(); error ExceedQuantityLimitError(); error HeadSignerError(); error BodySignerError(); error ZeroAddressError(); error ValueError(); error PaymentError(); error LengthMismatchError(); error NotAvailableTicketError(); error InvalidTicketPriceError(); error TicketAlreadyUsedError(); // ============================== // variables // ============================== IApprovalProxy public approvalProxy; address payable public payoutAddress; bytes32 private immutable DOMAIN_SEPARATOR; bool public burnPermission; string private _baseURI; string private _metadataExtension = ".json"; uint256 public allowlistSalePrice; uint256 public salePrice; uint256 public quantityLimit; uint256 public supplyLimit; uint256 private _totalSupply; uint256 private _mintCounter; uint256 private _burnCounter; mapping(bytes32 => bool) private _mintTicketUsed; constructor( string memory name_, string memory symbol_, uint256 allowlistSalePrice_, uint256 salePrice_, uint256 quantityLimit_, uint256 supplyLimit_, address payable payoutAddress_ ) ERC721(name_, symbol_) { _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); _grantRole(MINTER_ROLE, msg.sender); _grantRole(RELAY_MINTER_ROLE, msg.sender); _grantRole(HEAD_SIGNER_ROLE, msg.sender); allowlistSalePrice = allowlistSalePrice_; salePrice = salePrice_; quantityLimit = quantityLimit_; supplyLimit = supplyLimit_; if (address(0x0) != payoutAddress_) { payoutAddress = payoutAddress_; } else { payoutAddress = payable(msg.sender); } uint96 feeNumerator = _defaultFeeNumerator(); _setDefaultRoyalty(payoutAddress, feeNumerator); emit UpdateDefaultRoyaltyInfo(msg.sender, payoutAddress, feeNumerator); DOMAIN_SEPARATOR = _createDomainSeparator( string(abi.encodePacked("EIP712", name_, symbol_)), address(this) ); } // ==================== // modifier // ==================== modifier notExceedingSupplyLimit(uint256 quantity) { if (totalSupply() + quantity > supplyLimit) Revert.withSelector(ExceedSupplyLimitError.selector); _; } // ==================== // functions // ==================== /** * @dev Return the total number of tokens in existence. */ function totalSupply() public view virtual returns (uint256) { return _totalSupply - _burnCounter; } /** * @dev Return the total number of tokens minted. */ function totalMinted() public view virtual returns (uint256) { return _mintCounter; } /** * @dev Return the total number of tokens burned. */ function totalBurned() public view virtual returns (uint256) { return _burnCounter; } /** * @dev Return the address data for `owner_`. */ function addressDataOf( address owner_ ) public view virtual returns (AddressDataExt memory) { AddressData memory data = _addressDataOf(owner_); uint64 aux = data.aux; uint256 numberAllowlistSaleMinted = uint256(aux & 0x00000000FFFFFFFF); uint256 numberPublicSaleMinted = uint256(aux >> 32); return AddressDataExt({ balance: data.balance, numberMinted: data.numberMinted, numberBurned: data.numberBurned, numberAllowlistSaleMinted: numberAllowlistSaleMinted, numberPublicSaleMinted: numberPublicSaleMinted }); } /** * @dev Set mint count for allowlist sale. */ function _setAllowlistSaleMintCount( address owner_, uint256 count ) internal { uint64 aux = _getAux(owner_); _setAux(owner_, ((aux >> 32) << 32) | uint64(count)); } /** * @dev Set mint count for public sale. */ function _setPublicSaleMintCount(address owner_, uint256 count) internal { uint64 aux = _getAux(owner_); _setAux(owner_, uint64(count << 32) | (aux & 0x00000000FFFFFFFF)); } /** * @dev Mints `tokenId` and transfers it to `to`. */ function mint( address to, uint256 tokenId ) external onlyRole(MINTER_ROLE) notExceedingSupplyLimit(1) { unchecked { _mintCounter += 1; _totalSupply += 1; } _safeMint(to, tokenId); } /** * @dev batch mint `tokenIds` and transfers it to `receivers`. */ function batchMint( address[] memory receivers, uint256[] memory tokenIds ) external onlyRole(MINTER_ROLE) notExceedingSupplyLimit(tokenIds.length) { _batchMint(receivers, tokenIds); } /** * @dev Mints `quantity` tokens and transfers them to `to`. */ function mintTokens( address to, uint256 quantity ) external onlyRole(MINTER_ROLE) notExceedingSupplyLimit(quantity) { unchecked { _mintCounter += quantity; _totalSupply += quantity; } _mintTokens(to, quantity); } /** * @dev mint with ticket. * The anticipated scenarios are meta-transactions or handling special tickets. */ function mintWithTicket( CoconutMintTicket calldata mintTicket, uint256 quantity ) external payable { _mintWithTicket(mintTicket, quantity, 0, true); if (msg.value > 0) { (bool success, ) = payoutAddress.call{value: msg.value}(""); if (!success) Revert.withSelector(PaymentError.selector); } } /** * @dev Return true if `mintTicket` is used. */ function isUsedTicket( CoconutMintTicket calldata mintTicket ) external view returns (bool) { bool isOnceTicket = mintTicket.isOnceTicket(); if (!isOnceTicket) return false; bytes32 ticketHash = keccak256(mintTicket.bodySignature); return _mintTicketUsed[ticketHash]; } /** * @dev mint for allowlist sale. */ function allowlistSaleMint( CoconutMintTicket calldata mintTicket, uint256 quantity ) external payable notExceedingSupplyLimit(quantity) onlyDuringAllowlistSale { uint64 aux = _getAux(mintTicket.receiver); uint256 mintCount = uint256(aux & 0x00000000FFFFFFFF); if (mintCount + quantity > mintTicket.quantityLimit) Revert.withSelector(AllowlistExceedQuantityLimitError.selector); unchecked { mintCount += quantity; } _setAllowlistSaleMintCount(mintTicket.receiver, mintCount); _mintWithTicket(mintTicket, quantity, allowlistSalePrice, false); if (msg.value > 0) { (bool success, ) = payoutAddress.call{value: msg.value}(""); if (!success) Revert.withSelector(PaymentError.selector); } } /** * @dev mint for public sale. */ function publicSaleMint( address to, uint256 quantity ) external payable notExceedingSupplyLimit(quantity) onlyDuringPublicSale { uint64 aux = _getAux(to); uint256 mintCount = uint256(aux >> 32); if (quantityLimit > 0 && mintCount + quantity > quantityLimit) Revert.withSelector(ExceedQuantityLimitError.selector); if (msg.value != (salePrice * quantity)) Revert.withSelector(ValueError.selector); unchecked { mintCount += quantity; _mintCounter += quantity; _totalSupply += quantity; } _setPublicSaleMintCount(to, mintCount); _mintTokens(to, quantity); if (msg.value > 0) { (bool success, ) = payoutAddress.call{value: msg.value}(""); if (!success) Revert.withSelector(PaymentError.selector); } } /** * @dev batch mint `tokenIds` and transfers it to `receivers`. * this function called by relayer. */ function relayBatchMint( address[] memory receivers, uint256[] memory tokenIds ) external onlyRole(RELAY_MINTER_ROLE) notExceedingSupplyLimit(tokenIds.length) { _batchMint(receivers, tokenIds); } /** * @dev mint with ticket. * The anticipated scenarios are meta-transactions or handling special tickets. * this function called by relayer. */ function relayMintWithTicket( CoconutMintTicket calldata mintTicket, uint256 quantity ) external payable onlyRole(RELAY_MINTER_ROLE) { _mintWithTicket(mintTicket, quantity, 0, true); if (msg.value > 0) { (bool success, ) = payoutAddress.call{value: msg.value}(""); if (!success) Revert.withSelector(PaymentError.selector); } } /** * @dev Mints `quantity` tokens and transfers them to `to`. * this function called by relayer. */ function relayMintTokens( address to, uint256 quantity ) external onlyRole(RELAY_MINTER_ROLE) notExceedingSupplyLimit(quantity) { unchecked { _mintCounter += quantity; _totalSupply += quantity; } _mintTokens(to, quantity); } /** * @dev mint for allowlist sale. * this function called by relayer. */ function relayAllowlistSaleMint( CoconutMintTicket calldata mintTicket, uint256 quantity ) external onlyRole(RELAY_MINTER_ROLE) onlyDuringAllowlistSale { uint64 aux = _getAux(mintTicket.receiver); uint256 mintCount = uint256(aux & 0x00000000FFFFFFFF); if (mintCount + quantity > mintTicket.quantityLimit) Revert.withSelector(AllowlistExceedQuantityLimitError.selector); unchecked { mintCount += quantity; } _setAllowlistSaleMintCount(mintTicket.receiver, mintCount); _mintWithTicket(mintTicket, quantity, 0, false); } /** * @dev mint for public sale. * this function called by relayer. */ function relayPublicSaleMint( address to, uint256 quantity ) external onlyRole(RELAY_MINTER_ROLE) notExceedingSupplyLimit(quantity) onlyDuringPublicSale { uint64 aux = _getAux(to); uint256 mintCount = uint256(aux >> 32); if (quantityLimit > 0 && mintCount + quantity > quantityLimit) Revert.withSelector(ExceedQuantityLimitError.selector); unchecked { mintCount += quantity; _mintCounter += quantity; _totalSupply += quantity; } _setPublicSaleMintCount(to, mintCount); _mintTokens(to, quantity); } /** * @dev burn `tokenId`. */ function burn(uint256 tokenId) public virtual { if (!burnPermission) Revert.withSelector(BurnPermissionError.selector); _requireMinted(tokenId); if (!_isApprovedOrOwner(_msgSender(), tokenId)) Revert.withSelector(NotApprovedOrOwnerError.selector); _burn(tokenId); _burnCounter += 1; _resetTokenRoyalty(tokenId); } /** * @dev return true if `tokenId` is minted. */ function exists(uint256 tokenId) public view virtual returns (bool) { return _exists(tokenId); } /** * @dev return default fee numerator. */ function _defaultFeeNumerator() internal view virtual returns (uint96) { // default fee is 7.5% return 750; } /** * @dev batch mint `tokenIds` and transfers it to `receivers`. */ function _batchMint( address[] memory receivers, uint256[] memory tokenIds ) internal virtual { if (receivers.length != tokenIds.length) Revert.withSelector(LengthMismatchError.selector); unchecked { _mintCounter += tokenIds.length; _totalSupply += tokenIds.length; } for (uint256 i = 0; i < receivers.length; i++) { _safeMint(receivers[i], tokenIds[i]); } } /** * @dev mint with ticket. */ function _mintWithTicket( CoconutMintTicket calldata mintTicket, uint256 quantity, uint256 price, bool isTicketMode ) internal virtual { if (isTicketMode && !mintTicket.isAvailableTicket(saleState())) Revert.withSelector(NotAvailableTicketError.selector); bool isOnceTicket = mintTicket.isOnceTicket(); bytes32 ticketHash; if (isOnceTicket) { ticketHash = keccak256(mintTicket.bodySignature); if (_mintTicketUsed[ticketHash]) Revert.withSelector(TicketAlreadyUsedError.selector); } (bool tokenIdFlag, uint256 tokenId) = mintTicket.getTokenIdInfo(); tokenIdFlag = tokenIdFlag && isTicketMode; if (tokenIdFlag) { quantity = 1; } if (totalSupply() + quantity > supplyLimit) Revert.withSelector(ExceedSupplyLimitError.selector); if (!tokenIdFlag && quantity > mintTicket.quantityLimit) Revert.withSelector(ExceedQuantityLimitError.selector); if (isTicketMode) { (bool priceFlag, uint256 _price) = mintTicket.getPriceInfo(); if (!priceFlag) { Revert.withSelector(InvalidTicketPriceError.selector); } else { price = _price; } } if (msg.value != (price * quantity)) Revert.withSelector(ValueError.selector); (address headSigner, address bodySigner) = _recoverSigners( DOMAIN_SEPARATOR, mintTicket ); if (!hasRole(HEAD_SIGNER_ROLE, headSigner)) Revert.withSelector(HeadSignerError.selector); if (bodySigner != mintTicket.bodySigner) Revert.withSelector(BodySignerError.selector); unchecked { _mintCounter += quantity; _totalSupply += quantity; } if (isOnceTicket) { _mintTicketUsed[ticketHash] = true; } if (tokenIdFlag) { _safeMint(mintTicket.receiver, tokenId); } else { _mintTokens(mintTicket.receiver, quantity); } } function baseURI() public view virtual returns (string memory) { if (bytes(_baseURI).length > 0) { return _baseURI; } else { return string( abi.encodePacked( "https://image-coconut.storage.googleapis.com/production/token/metadata/", name(), "_", symbol(), "/" ) ); } } /** * @dev See {IERC721Metadata-tokenURI}. */ function _tokenURI( uint256 tokenId ) internal view virtual override returns (string memory) { string memory baseURI_ = baseURI(); return string( abi.encodePacked( baseURI_, tokenId.toString(), _metadataExtension ) ); } /** * @dev reset sale state to before sale. */ function resetToBeforeSale() external onlyRole(DEFAULT_ADMIN_ROLE) { _resetToBeforeSale(); } /** * @dev start allowlist sale (update sale state). */ function startAllowlistSale() external onlyRole(DEFAULT_ADMIN_ROLE) { _startAllowlistSale(); } /** * @dev start public sale (update sale state). */ function startPublicSale() external onlyRole(DEFAULT_ADMIN_ROLE) { _startPublicSale(); } /** * @dev start allowlist and public sale (update sale state). */ function startAllowlistAndPublicSale() external onlyRole(DEFAULT_ADMIN_ROLE) { _startAllowlistAndPublicSale(); } /** * @dev end sale (update sale state). */ function endSale() external onlyRole(DEFAULT_ADMIN_ROLE) { _endSale(); } /** * @dev Sets the royalty information that all ids in this contract will default to. */ function setDefaultRoyaltyInfo( address receiver, uint96 feeNumerator ) external onlyRole(DEFAULT_ADMIN_ROLE) { _setDefaultRoyalty(receiver, feeNumerator); emit UpdateDefaultRoyaltyInfo(msg.sender, receiver, feeNumerator); } /** * @dev Sets the royalty information for a specific token id, overriding the global default. */ function setTokenRoyalty( uint256 tokenId, address receiver, uint96 feeNumerator ) external onlyRole(DEFAULT_ADMIN_ROLE) { _setTokenRoyalty(tokenId, receiver, feeNumerator); emit UpdateTokenRoyalty(msg.sender, tokenId, receiver, feeNumerator); } /** * @dev Set the token id index. */ function setTokenIdIndex( uint256 tokenIdIndex_ ) external onlyRole(DEFAULT_ADMIN_ROLE) { _setCurrentIndex(tokenIdIndex_); emit UpdateTokenIdIndex(msg.sender, tokenIdIndex_); } /** * @dev Set the base URI for all token IDs. */ function setBaseURI( string memory baseURI_ ) external onlyRole(DEFAULT_ADMIN_ROLE) { _baseURI = baseURI_; emit UpdateBaseURI(msg.sender, baseURI_); } /** * @dev Set the metadata extension for all token IDs. */ function setMetadataExtension( string memory metadataExtension_ ) external onlyRole(DEFAULT_ADMIN_ROLE) { _metadataExtension = metadataExtension_; emit UpdateMetadataExtension(msg.sender, metadataExtension_); } /** * @dev Set the approval proxy contract. */ function setApprovalProxy( address newProxyContract ) external onlyRole(DEFAULT_ADMIN_ROLE) { approvalProxy = IApprovalProxy(newProxyContract); emit UpdateApprovalProxy(msg.sender, newProxyContract); } /** * @dev Set the supply limit. */ function setSupplyLimit( uint256 newSupplyLimit ) external onlyRole(DEFAULT_ADMIN_ROLE) { supplyLimit = newSupplyLimit; emit UpdateSupplyLimit(msg.sender, newSupplyLimit); } /** * @dev Set the quantity limit. */ function setQuantityLimit( uint256 newQuantityLimit ) external onlyRole(DEFAULT_ADMIN_ROLE) { quantityLimit = newQuantityLimit; emit UpdateQuantityLimit(msg.sender, newQuantityLimit); } /** * @dev Set the allowlist sale price. */ function setAllowlistSalePrice( uint256 allowlistSalePrice_ ) external onlyRole(DEFAULT_ADMIN_ROLE) { allowlistSalePrice = allowlistSalePrice_; emit UpdateAllowlistSalePrice(msg.sender, allowlistSalePrice_); } /** * @dev Set the sale price. */ function setSalePrice( uint256 salePrice_ ) external onlyRole(DEFAULT_ADMIN_ROLE) { salePrice = salePrice_; emit UpdateSalePrice(msg.sender, salePrice_); } /** * @dev Set the payout address. */ function setPayoutAddress( address payable newPayoutAddress ) external onlyRole(DEFAULT_ADMIN_ROLE) { if (newPayoutAddress == address(0x0)) Revert.withSelector(ZeroAddressError.selector); payoutAddress = newPayoutAddress; emit UpdatePayoutAddress(msg.sender, newPayoutAddress); } /** * @dev Set the burn permission. */ function setBurnPermission( bool burnPermission_ ) external onlyRole(DEFAULT_ADMIN_ROLE) { burnPermission = burnPermission_; emit UpdateBurnPermission(msg.sender, burnPermission_); } /** * @dev See {IERC721-approve}. */ function approve( address operator, uint256 tokenId ) public override(ERC721, IERC721) { super.approve(operator, tokenId); } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll( address operator, bool approved ) public virtual override(ERC721, IERC721) { _setApprovalForAll(_msgSender(), operator, approved); if ( address(approvalProxy) != address(0x0) && Address.isContract(operator) ) { approvalProxy.setApprovalForAll(msg.sender, operator, approved); } super.setApprovalForAll(operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll( address owner_, address operator ) public view virtual override(ERC721, IERC721) returns (bool) { bool approved = super.isApprovedForAll(owner_, operator); if (address(approvalProxy) != address(0x0)) { return approvalProxy.isApprovedForAll(owner_, operator, approved); } return approved; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface( bytes4 interfaceId ) public view virtual override(ERC721, IERC165, ERC2981, AccessControl) returns (bool) { return super.supportsInterface(interfaceId); } } // File contracts/coconut/Coconut721.sol // Original license: SPDX_License_Identifier: UNLICENSED pragma solidity ^0.8.18; contract CEREZO is CoconutERC721 { constructor() CoconutERC721( "CEREZO", "CEREZO", uint256(0), uint256(0), uint256(0), uint256(3000), payable(address(0x9be8142eeC0802d2449478d9a790208f96862cec)) ) {} function _eip712Salt() internal pure override returns (bytes32) { return bytes32(uint256(109)); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AllowlistExceedQuantityLimitError","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"BodySignerError","type":"error"},{"inputs":[],"name":"BurnPermissionError","type":"error"},{"inputs":[],"name":"ExceedQuantityLimitError","type":"error"},{"inputs":[],"name":"ExceedSupplyLimitError","type":"error"},{"inputs":[],"name":"HeadSignerError","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"InvalidTicketPriceError","type":"error"},{"inputs":[],"name":"LengthMismatchError","type":"error"},{"inputs":[],"name":"NotApprovedOrOwnerError","type":"error"},{"inputs":[],"name":"NotAvailableTicketError","type":"error"},{"inputs":[],"name":"NotInAllolistSalePhaseError","type":"error"},{"inputs":[],"name":"NotInPublicSalePhaseError","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"PaymentError","type":"error"},{"inputs":[],"name":"TicketAlreadyUsedError","type":"error"},{"inputs":[],"name":"ValueError","type":"error"},{"inputs":[],"name":"ZeroAddressError","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":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"newSalePrice","type":"uint256"}],"name":"UpdateAllowlistSalePrice","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"newProxyContract","type":"address"}],"name":"UpdateApprovalProxy","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"string","name":"newBaseURI","type":"string"}],"name":"UpdateBaseURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bool","name":"permission","type":"bool"}],"name":"UpdateBurnPermission","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"UpdateDefaultRoyaltyInfo","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"string","name":"newMetadataExtension","type":"string"}],"name":"UpdateMetadataExtension","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"newPayoutAddress","type":"address"}],"name":"UpdatePayoutAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"newQuantityLimit","type":"uint256"}],"name":"UpdateQuantityLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"newSalePrice","type":"uint256"}],"name":"UpdateSalePrice","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"uint256","name":"saleState","type":"uint256"}],"name":"UpdateSaleState","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"newSupplyLimit","type":"uint256"}],"name":"UpdateSupplyLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"newTokenIdIndex","type":"uint256"}],"name":"UpdateTokenIdIndex","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"UpdateTokenRoyalty","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HEAD_SIGNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RELAY_MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"addressDataOf","outputs":[{"components":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"numberMinted","type":"uint256"},{"internalType":"uint256","name":"numberBurned","type":"uint256"},{"internalType":"uint256","name":"numberAllowlistSaleMinted","type":"uint256"},{"internalType":"uint256","name":"numberPublicSaleMinted","type":"uint256"}],"internalType":"struct CoconutERC721.AddressDataExt","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"quantityLimit","type":"uint256"},{"internalType":"uint256","name":"extra","type":"uint256"},{"internalType":"bytes","name":"uuid","type":"bytes"},{"internalType":"bytes","name":"headSignature","type":"bytes"},{"internalType":"bytes","name":"bodySignature","type":"bytes"},{"internalType":"address","name":"bodySigner","type":"address"},{"internalType":"address","name":"receiver","type":"address"}],"internalType":"struct CoconutMintTicket","name":"mintTicket","type":"tuple"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"allowlistSaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"allowlistSalePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"approvalProxy","outputs":[{"internalType":"contract IApprovalProxy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","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":[{"internalType":"address[]","name":"receivers","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"batchMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burnPermission","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endSale","outputs":[],"stateMutability":"nonpayable","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":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct TokenOwnership","name":"ownership","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct TokenOwnership[]","name":"","type":"tuple[]"}],"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":[{"components":[{"internalType":"uint256","name":"quantityLimit","type":"uint256"},{"internalType":"uint256","name":"extra","type":"uint256"},{"internalType":"bytes","name":"uuid","type":"bytes"},{"internalType":"bytes","name":"headSignature","type":"bytes"},{"internalType":"bytes","name":"bodySignature","type":"bytes"},{"internalType":"address","name":"bodySigner","type":"address"},{"internalType":"address","name":"receiver","type":"address"}],"internalType":"struct CoconutMintTicket","name":"mintTicket","type":"tuple"}],"name":"isUsedTicket","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mintTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"quantityLimit","type":"uint256"},{"internalType":"uint256","name":"extra","type":"uint256"},{"internalType":"bytes","name":"uuid","type":"bytes"},{"internalType":"bytes","name":"headSignature","type":"bytes"},{"internalType":"bytes","name":"bodySignature","type":"bytes"},{"internalType":"address","name":"bodySigner","type":"address"},{"internalType":"address","name":"receiver","type":"address"}],"internalType":"struct CoconutMintTicket","name":"mintTicket","type":"tuple"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mintWithTicket","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"payoutAddress","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"publicSaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"quantityLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"quantityLimit","type":"uint256"},{"internalType":"uint256","name":"extra","type":"uint256"},{"internalType":"bytes","name":"uuid","type":"bytes"},{"internalType":"bytes","name":"headSignature","type":"bytes"},{"internalType":"bytes","name":"bodySignature","type":"bytes"},{"internalType":"address","name":"bodySigner","type":"address"},{"internalType":"address","name":"receiver","type":"address"}],"internalType":"struct CoconutMintTicket","name":"mintTicket","type":"tuple"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"relayAllowlistSaleMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"receivers","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"relayBatchMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"relayMintTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"quantityLimit","type":"uint256"},{"internalType":"uint256","name":"extra","type":"uint256"},{"internalType":"bytes","name":"uuid","type":"bytes"},{"internalType":"bytes","name":"headSignature","type":"bytes"},{"internalType":"bytes","name":"bodySignature","type":"bytes"},{"internalType":"address","name":"bodySigner","type":"address"},{"internalType":"address","name":"receiver","type":"address"}],"internalType":"struct CoconutMintTicket","name":"mintTicket","type":"tuple"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"relayMintWithTicket","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"relayPublicSaleMint","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":[],"name":"resetToBeforeSale","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":"salePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"saleState","outputs":[{"components":[{"internalType":"bool","name":"isBeforeSale","type":"bool"},{"internalType":"bool","name":"isAllowlistSale","type":"bool"},{"internalType":"bool","name":"isPublicSale","type":"bool"},{"internalType":"bool","name":"isSaleEnded","type":"bool"}],"internalType":"struct SaleState","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"allowlistSalePrice_","type":"uint256"}],"name":"setAllowlistSalePrice","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":"address","name":"newProxyContract","type":"address"}],"name":"setApprovalProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI_","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"burnPermission_","type":"bool"}],"name":"setBurnPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyaltyInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"metadataExtension_","type":"string"}],"name":"setMetadataExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newPayoutAddress","type":"address"}],"name":"setPayoutAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newQuantityLimit","type":"uint256"}],"name":"setQuantityLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"salePrice_","type":"uint256"}],"name":"setSalePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newSupplyLimit","type":"uint256"}],"name":"setSupplyLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenIdIndex_","type":"uint256"}],"name":"setTokenIdIndex","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":[],"name":"startAllowlistAndPublicSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startAllowlistSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startPublicSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supplyLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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"}]
Contract Creation Code
60e0604052600560a090815264173539b7b760d91b60c052600f9062000026908262000542565b503480156200003457600080fd5b50604080518082018252600680825265434552455a4f60d01b60208084018290528451808601909552918452908301529060008080610bb8739be8142eec0802d2449478d9a790208f96862cec8686600262000091838262000542565b506003620000a0828262000542565b50600160045550506001600b55620000ba60003362000247565b620000e67f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a63362000247565b620001127f05c0f7ac2b4a836d461d705215d2827b3523466a4e4e877245ccc4028acd195e3362000247565b6200013e7fbd06e35dfb74fc80605c99cb7f4326f1bf8754c8a909b71aa497ad9b9f3e82b23362000247565b60108590556011849055601283905560138290556001600160a01b038116156200018357600d80546001600160a01b0319166001600160a01b03831617905562000196565b600d80546001600160a01b031916331790555b600d546102ee90620001b2906001600160a01b031682620002ec565b600d54604080513381526001600160a01b0390921660208301526001600160601b03831682820152517ff874f682d038bfde0e507056054fb956bf3ae135b4974d2f0edc1ac65150db599181900360600190a16200023588886040516020016200021e92919062000640565b60408051601f1981840301815291905230620003f1565b60805250620006709650505050505050565b6000828152600a602090815260408083206001600160a01b038516845290915290205460ff16620002e8576000828152600a602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620002a73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6127106001600160601b0382161115620003605760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084015b60405180910390fd5b6001600160a01b038216620003b85760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c696420726563656976657200000000000000604482015260640162000357565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600855565b815160208301206000907fd87cd6ef79d4e2b95e15ce8abf732db51ec771f1ca2edccf22a46c729ac56472906200043e6040805180820190915260038152620312e360ec1b602082015290565b80516020909101204685606d604080516020810197909752860194909452606085019290925260808401526001600160a01b031660a083015260c082015260e00160405160208183030381529060405280519060200120905092915050565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620004c857607f821691505b602082108103620004e957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200053d57600081815260208120601f850160051c81016020861015620005185750805b601f850160051c820191505b81811015620005395782815560010162000524565b5050505b505050565b81516001600160401b038111156200055e576200055e6200049d565b62000576816200056f8454620004b3565b84620004ef565b602080601f831160018114620005ae5760008415620005955750858301515b600019600386901b1c1916600185901b17855562000539565b600085815260208120601f198616915b82811015620005df57888601518255948401946001909101908401620005be565b5085821015620005fe5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000815160005b8181101562000631576020818501810151868301520162000615565b50600093019283525090919050565b6522a4a81b989960d11b81526000620006686200066160068401866200060e565b846200060e565b949350505050565b608051614a0e6200068c60003960006123f40152614a0e6000f3fe60806040526004361061041b5760003560e01c80636352211e1161021e578063a22cb46511610123578063d5391393116100ab578063e985e9c51161007a578063e985e9c514610cb8578063f0dda65c14610cd8578063f51f96dd14610cf8578063f696b60614610d0e578063fb7df78814610d2e57600080fd5b8063d539139314610c4b578063d547741f14610c6d578063d5bd1fbb14610c8d578063d89135cd14610ca357600080fd5b8063b88d4fde116100f2578063b88d4fde14610bb6578063becadb6514610bd6578063c23dc68f14610beb578063c27eb7b914610c18578063c87b56dd14610c2b57600080fd5b8063a22cb46514610b59578063a2309ff814610b79578063a77eaa0914610b8e578063ac5ae11b14610ba357600080fd5b806391e170d4116101a65780639bb5c9c3116101755780639bb5c9c314610ac45780639f6350e614610ae4578063a0b133f014610b04578063a1c2169814610b24578063a217fddf14610b4457600080fd5b806391e170d414610a4f57806395a613fe14610a6f57806395d89b4114610a8f57806399a2557a14610aa457600080fd5b806370a08231116101ed57806370a08231146109ae5780638462151c146109ce57806384a6819b146109fb5780638ddae77e14610a0e57806391d1485414610a2f57600080fd5b80636352211e1461093957806367d541481461095957806368573107146109795780636c0360eb1461099957600080fd5b80632a55205a1161032457806342966c68116102ac57806355f804b31161027b57806355f804b31461085c5780635944c7531461087c5780635b8d02d71461089c5780635bbb2177146108bc578063603f4d52146108e957600080fd5b806342966c68146107dc5780634aaae9f0146107fc5780634dd09f331461081c5780634f558e791461083c57600080fd5b8063361fab25116102f3578063361fab251461074757806336568abe14610767578063380d831b1461078757806340c10f191461079c57806342842e0e146107bc57600080fd5b80632a55205a146106b95780632f2ff15d146106e757806333ea51a81461070757806335c618e61461072757600080fd5b80631919fed7116103a757806323b872dd1161037657806323b872dd14610628578063248a9ca31461064857806326987b6014610678578063272f0cd01461068e57806329cb320b146106a357600080fd5b80631919fed7146105bf57806319a04d43146105df57806319d1997a146105ff57806321542dd31461061557600080fd5b8063081812fc116103ee578063081812fc1461051b578063095ea7b3146105535780630c1c972a146105755780631796068a1461058a57806318160ddd146105aa57600080fd5b806301ffc9a71461042057806304d4f96c1461045557806306fdde03146104b7578063078fe6aa146104d9575b600080fd5b34801561042c57600080fd5b5061044061043b366004613bfd565b610d50565b60405190151581526020015b60405180910390f35b34801561046157600080fd5b50610475610470366004613c2f565b610d61565b60405161044c9190600060a082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015292915050565b3480156104c357600080fd5b506104cc610de5565b60405161044c9190613c9c565b3480156104e557600080fd5b5061050d7fbd06e35dfb74fc80605c99cb7f4326f1bf8754c8a909b71aa497ad9b9f3e82b281565b60405190815260200161044c565b34801561052757600080fd5b5061053b610536366004613caf565b610e77565b6040516001600160a01b03909116815260200161044c565b34801561055f57600080fd5b5061057361056e366004613cc8565b610e9e565b005b34801561058157600080fd5b50610573610eac565b34801561059657600080fd5b506105736105a5366004613caf565b610ec2565b3480156105b657600080fd5b5061050d610f10565b3480156105cb57600080fd5b506105736105da366004613caf565b610f27565b3480156105eb57600080fd5b506105736105fa366004613d0b565b610f69565b34801561060b57600080fd5b5061050d60135481565b610573610623366004613d58565b610fd3565b34801561063457600080fd5b50610573610643366004613d9c565b611057565b34801561065457600080fd5b5061050d610663366004613caf565b6000908152600a602052604090206001015490565b34801561068457600080fd5b5061050d60045481565b34801561069a57600080fd5b50610573611092565b3480156106af57600080fd5b5061050d60125481565b3480156106c557600080fd5b506106d96106d4366004613ddd565b6110a5565b60405161044c929190613dff565b3480156106f357600080fd5b50610573610702366004613e18565b611153565b34801561071357600080fd5b50610573610722366004613c2f565b611178565b34801561073357600080fd5b50610440610742366004613e48565b6111f6565b34801561075357600080fd5b50610573610762366004613caf565b61124f565b34801561077357600080fd5b50610573610782366004613e18565b611291565b34801561079357600080fd5b5061057361130b565b3480156107a857600080fd5b506105736107b7366004613cc8565b61131e565b3480156107c857600080fd5b506105736107d7366004613d9c565b611389565b3480156107e857600080fd5b506105736107f7366004613caf565b6113a4565b34801561080857600080fd5b50610573610817366004613caf565b61141d565b34801561082857600080fd5b50600c5461053b906001600160a01b031681565b34801561084857600080fd5b50610440610857366004613caf565b611462565b34801561086857600080fd5b50610573610877366004613f19565b61146d565b34801561088857600080fd5b50610573610897366004613f61565b6114b6565b3480156108a857600080fd5b50600d5461053b906001600160a01b031681565b3480156108c857600080fd5b506108dc6108d7366004613f9f565b611529565b60405161044c919061404f565b3480156108f557600080fd5b506108fe611575565b60405161044c919081511515815260208083015115159082015260408083015115159082015260609182015115159181019190915260800190565b34801561094557600080fd5b5061053b610954366004613caf565b6115d7565b34801561096557600080fd5b5061057361097436600461411f565b611636565b34801561098557600080fd5b5061057361099436600461411f565b611686565b3480156109a557600080fd5b506104cc61169e565b3480156109ba57600080fd5b5061050d6109c9366004613c2f565b6116f9565b3480156109da57600080fd5b506109ee6109e9366004613c2f565b611704565b60405161044c91906141e0565b610573610a09366004613d58565b61173c565b348015610a1a57600080fd5b50600d5461044090600160a01b900460ff1681565b348015610a3b57600080fd5b50610440610a4a366004613e18565b6117d3565b348015610a5b57600080fd5b50610573610a6a366004613cc8565b6117fe565b348015610a7b57600080fd5b50610573610a8a366004614226565b61185d565b348015610a9b57600080fd5b506104cc6118bc565b348015610ab057600080fd5b506109ee610abf366004614243565b6118cb565b348015610ad057600080fd5b50610573610adf366004613c2f565b6118d8565b348015610af057600080fd5b50610573610aff366004613f19565b611938565b348015610b1057600080fd5b50610573610b1f366004613caf565b611981565b348015610b3057600080fd5b50610573610b3f366004613cc8565b6119c3565b348015610b5057600080fd5b5061050d600081565b348015610b6557600080fd5b50610573610b74366004614278565b611a9c565b348015610b8557600080fd5b5060155461050d565b348015610b9a57600080fd5b50610573611b48565b610573610bb1366004613cc8565b611b5b565b348015610bc257600080fd5b50610573610bd13660046142a6565b611cb0565b348015610be257600080fd5b50610573611ce2565b348015610bf757600080fd5b50610c0b610c06366004613caf565b611cf5565b60405161044c9190614325565b610573610c26366004613d58565b611d22565b348015610c3757600080fd5b506104cc610c46366004613caf565b611dda565b348015610c5757600080fd5b5061050d60008051602061499983398151915281565b348015610c7957600080fd5b50610573610c88366004613e18565b611dee565b348015610c9957600080fd5b5061050d60105481565b348015610caf57600080fd5b5060165461050d565b348015610cc457600080fd5b50610440610cd3366004614333565b611e13565b348015610ce457600080fd5b50610573610cf3366004613cc8565b611ed8565b348015610d0457600080fd5b5061050d60115481565b348015610d1a57600080fd5b50610573610d29366004613d58565b611ef0565b348015610d3a57600080fd5b5061050d60008051602061497983398151915281565b6000610d5b82611f86565b92915050565b610d936040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b6000610d9e83611fab565b6060808201516040805160a0810182528451815260208086015182820152948201519181019190915263ffffffff80831693820193909352921c1660808201529392505050565b606060028054610df490614361565b80601f0160208091040260200160405190810160405280929190818152602001828054610e2090614361565b8015610e6d5780601f10610e4257610100808354040283529160200191610e6d565b820191906000526020600020905b815481529060010190602001808311610e5057829003601f168201915b5050505050905090565b6000610e8282612039565b506000908152600660205260409020546001600160a01b031690565b610ea88282612089565b5050565b6000610eb781612199565b610ebf6121a3565b50565b6000610ecd81612199565b60128290556040517f9074f4c535a222861a631985c506f755c216edda189cb7656116f60322228bad90610f049033908590613dff565b60405180910390a15050565b6000601654601454610f2291906143ab565b905090565b6000610f3281612199565b60118290556040517f3609bd5d3527f15800f13522a75b9fc8812914c78183aba8862844e0e07ff89c90610f049033908590613dff565b6000610f7481612199565b610f7e83836121d3565b604080513381526001600160a01b03851660208201526001600160601b0384168183015290517ff874f682d038bfde0e507056054fb956bf3ae135b4974d2f0edc1ac65150db599181900360600190a1505050565b610fe182826000600161228d565b3415610ea857600d546040516000916001600160a01b03169034908381818185875af1925050503d8060008114611034576040519150601f19603f3d011682016040523d82523d6000602084013e611039565b606091505b50509050806110525761105263abab8fc960e01b61250c565b505050565b611062335b82612516565b6110875760405162461bcd60e51b815260040161107e906143be565b60405180910390fd5b611052838383612574565b600061109d81612199565b610ebf6126e4565b60008281526009602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b031692820192909252829161111a5750604080518082019091526008546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090611139906001600160601b03168761440b565b6111439190614422565b91519350909150505b9250929050565b6000828152600a602052604090206001015461116e81612199565b611052838361270a565b600061118381612199565b6001600160a01b0382166111a1576111a1633efa09af60e01b61250c565b600d80546001600160a01b0319166001600160a01b0384169081179091556040805133815260208101929092527f54f1877b9010a3135c68dc2b0b326591d02a8cfbae5443bc11b94af1cafae4029101610f04565b600060026020830135811614806112105750600092915050565b600061121f6080850185614444565b60405161122d92919061448a565b604080519182900390912060009081526017602052205460ff16949350505050565b600061125a81612199565b60138290556040517fd60ff19058ff26897d4ccb9d7ee31a589d1230dc668dfdee26fda0a565bac73490610f049033908590613dff565b6001600160a01b03811633146113015760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840161107e565b610ea88282612790565b600061131681612199565b610ebf6127f7565b60008051602061499983398151915261133681612199565b600160135481611344610f10565b61134e919061449a565b11156113645761136463aac1eb5b60e01b61250c565b601580546001908101909155601480549091019055611383848461281d565b50505050565b61105283838360405180602001604052806000815250611cb0565b600d54600160a01b900460ff166113c5576113c563dbdcbe8360e01b61250c565b6113ce81612039565b6113d73361105c565b6113eb576113eb63453e58fd60e11b61250c565b6113f481612837565b600160166000828254611407919061449a565b9091555050600090815260096020526040812055565b600061142881612199565b61143182600455565b7fab773b7d529aa3f9149ea7b1bae8b9fdd8a0bd28c0b595b72f0c9ebf5471dcd73383604051610f04929190613dff565b6000610d5b826128df565b600061147881612199565b600e61148483826144f3565b507f6202a022117da849075762436d4cf956151ce1d67c7d3969003ab2eab4cd49fe3383604051610f049291906145b2565b60006114c181612199565b6114cc848484612905565b60408051338152602081018690526001600160a01b038516818301526001600160601b038416606082015290517f5854d7f929b02b5eacb3c32ff0c806eebb22c4b68f3cf0c57fd6826eb6207eff9181900360800190a150505050565b60408051828152600583901b8082016020019092526060915b801561156d57601f198082019186010135600061155e82611cf5565b84840160200152506115429050565b509392505050565b6040805160808101825260008082526020820181905291810182905260608101919091525060408051608081018252600b5460018181161482526002808216146020830152600480821614928201929092526008918216909114606082015290565b6000806115e3836129d0565b90506001600160a01b038116610d5b5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604482015260640161107e565b60008051602061497983398151915261164e81612199565b81516013548161165c610f10565b611666919061449a565b111561167c5761167c63aac1eb5b60e01b61250c565b61138384846129db565b60008051602061499983398151915261164e81612199565b60606000600e80546116af90614361565b905011156116c457600e8054610df490614361565b6116cc610de5565b6116d46118bc565b6040516020016116e59291906145d6565b604051602081830303815290604052905090565b6000610d5b82612a61565b60055460609060019060009061171b90600161449a565b9050606081831461173457611731858484612aa6565b90505b949350505050565b60008051602061497983398151915261175481612199565b61176283836000600161228d565b341561105257600d546040516000916001600160a01b03169034908381818185875af1925050503d80600081146117b5576040519150601f19603f3d011682016040523d82523d6000602084013e6117ba565b606091505b50509050806113835761138363abab8fc960e01b61250c565b6000918252600a602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60008051602061497983398151915261181681612199565b8160135481611823610f10565b61182d919061449a565b11156118435761184363aac1eb5b60e01b61250c565b601580548401905560148054840190556113838484612bcc565b600061186881612199565b600d805460ff60a01b1916600160a01b841515908102919091179091556040805133815260208101929092527fd0911d56226214ed1a76457bed8948fd2d11e69cc268af5212869a9f6dbc3ba19101610f04565b606060038054610df490614361565b6060611734848484612aa6565b60006118e381612199565b600c80546001600160a01b0319166001600160a01b0384169081179091556040805133815260208101929092527f7c23f9fede5a4305d068a89d49795d9fa640e65f937863b8c35aceb1c5db945e9101610f04565b600061194381612199565b600f61194f83826144f3565b507fee41836175e4185a28dc07490c88903ba0666573c4d4a4306c9a0991465f37023383604051610f049291906145b2565b600061198c81612199565b60108290556040517faab643a5211d1c06e36b6c88ce00ad728ae6a265c60b177bd617f01bf43feaab90610f049033908590613dff565b6000805160206149798339815191526119db81612199565b81601354816119e8610f10565b6119f2919061449a565b1115611a0857611a0863aac1eb5b60e01b61250c565b600480600b541614611a2457611a2463b575512f60e01b61250c565b6000611a2f85612c6a565b60125490915063ffffffff602083901c169015801590611a595750601254611a57868361449a565b115b15611a6e57611a6e633e65519560e01b61250c565b601580548601905560148054860190558401611a8a8682612c88565b611a948686612bcc565b505050505050565b611aa8335b8383612cab565b600c546001600160a01b031615801590611acb57506001600160a01b0382163b15155b15611b3e57600c54604051631b3b02e560e11b81523360048201526001600160a01b03848116602483015283151560448301529091169063367605ca90606401600060405180830381600087803b158015611b2557600080fd5b505af1158015611b39573d6000803e3d6000fd5b505050505b610ea88282612d79565b6000611b5381612199565b610ebf612d82565b8060135481611b68610f10565b611b72919061449a565b1115611b8857611b8863aac1eb5b60e01b61250c565b600480600b541614611ba457611ba463b575512f60e01b61250c565b6000611baf84612c6a565b60125490915063ffffffff602083901c169015801590611bd95750601254611bd7858361449a565b115b15611bee57611bee633e65519560e01b61250c565b83601154611bfc919061440b565b3414611c1257611c1263420116e360e11b61250c565b601580548501905560148054850190558301611c2e8582612c88565b611c388585612bcc565b3415611ca957600d546040516000916001600160a01b03169034908381818185875af1925050503d8060008114611c8b576040519150601f19603f3d011682016040523d82523d6000602084013e611c90565b606091505b5050905080611a9457611a9463abab8fc960e01b61250c565b5050505050565b611cba3383612516565b611cd65760405162461bcd60e51b815260040161107e906143be565b61138384848484612da8565b6000611ced81612199565b610ebf612ddb565b604080516080810182526000808252602082018190529181018290526060810191909152610d5b82612e01565b8060135481611d2f610f10565b611d39919061449a565b1115611d4f57611d4f63aac1eb5b60e01b61250c565b600280600b541614611d6b57611d6b633dac9e9960e21b61250c565b6000611d85611d8060e0860160c08701613c2f565b612c6a565b905063ffffffff81168435611d9a858361449a565b1115611db057611db063b8edfd7760e01b61250c565b8301611dcb611dc560e0870160c08801613c2f565b82612e7b565b611c388585601054600061228d565b6060611de582612039565b610d5b82612e9e565b6000828152600a6020526040902060010154611e0981612199565b6110528383612790565b6001600160a01b0382811660009081526007602090815260408083208585168452909152812054600c54919260ff909116911615611ed157600c546040516346e67e2960e11b81526001600160a01b0386811660048301528581166024830152831515604483015290911690638dccfc5290606401602060405180830381865afa158015611ea5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec9919061467f565b915050610d5b565b9392505050565b60008051602061499983398151915261181681612199565b600080516020614979833981519152611f0881612199565b600280600b541614611f2457611f24633dac9e9960e21b61250c565b6000611f39611d8060e0860160c08701613c2f565b905063ffffffff81168435611f4e858361449a565b1115611f6457611f6463b8edfd7760e01b61250c565b8301611f79611dc560e0870160c08801613c2f565b611ca9858560008061228d565b60006001600160e01b03198216637965db0b60e01b1480610d5b5750610d5b82612ee1565b611fdf604051806080016040528060008152602001600081526020016000815260200160006001600160401b031681525090565b506001600160a01b0316600090815260016020908152604091829020548251608080820185526001600160401b03808416835283861c81169483019490945282901c9092169282019290925260c09190911c606082015290565b612042816128df565b610ebf5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604482015260640161107e565b6000612094826115d7565b9050806001600160a01b0316836001600160a01b0316036121015760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161107e565b336001600160a01b038216148061211d575061211d8133611e13565b61218f5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000606482015260840161107e565b6110528383612f06565b610ebf8133612f74565b6004600b8190556040516000805160206149b9833981519152916121c991339190613dff565b60405180910390a1565b6127106001600160601b03821611156121fe5760405162461bcd60e51b815260040161107e9061469c565b6001600160a01b0382166122545760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c696420726563656976657200000000000000604482015260640161107e565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600855565b8080156122a957506122a76122a0611575565b8590612fcd565b155b156122be576122be6311d15f2960e31b61250c565b6002602085013581161460008115612320576122dd6080870187614444565b6040516122eb92919061448a565b604080519182900390912060008181526017602052919091205490915060ff161561232057612320630c848adf60e01b61250c565b60008061232c8861306f565b9150915081801561233a5750845b9150811561234757600196505b60135487612353610f10565b61235d919061449a565b11156123735761237363aac1eb5b60e01b61250c565b811580156123815750873587115b1561239657612396633e65519560e01b61250c565b84156123cc576000806123a88a6130a3565b91509150816123c5576123c062e363d160e01b61250c565b6123c9565b8097505b50505b6123d6878761440b565b34146123ec576123ec63420116e360e11b61250c565b6000806124197f00000000000000000000000000000000000000000000000000000000000000008b6130d2565b915091506124477fbd06e35dfb74fc80605c99cb7f4326f1bf8754c8a909b71aa497ad9b9f3e82b2836117d3565b61245b5761245b63023b8e5d60e61b61250c565b61246b60c08b0160a08c01613c2f565b6001600160a01b0316816001600160a01b031614612493576124936387a20acd60e01b61250c565b601580548a019055601480548a01905585156124c3576000858152601760205260409020805460ff191660011790555b83156124e7576124e26124dc60e08c0160c08d01613c2f565b8461281d565b612500565b6125006124fa60e08c0160c08d01613c2f565b8a612bcc565b50505050505050505050565b8060005260046000fd5b600080612522836115d7565b9050806001600160a01b0316846001600160a01b0316148061254957506125498185611e13565b806117345750836001600160a01b031661256284610e77565b6001600160a01b031614949350505050565b826001600160a01b0316612587826115d7565b6001600160a01b0316146125ad5760405162461bcd60e51b815260040161107e906146e6565b6001600160a01b03821661260f5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161107e565b600061261a826132d7565b9050836001600160a01b031661262f836115d7565b6001600160a01b0316146126555760405162461bcd60e51b815260040161107e906146e6565b600082815260066020908152604080832080546001600160a01b03191690556001600160a01b03878116808552600180855283862080546000190190559188168086528386208054909301909255868552928490528184204260a01b82179055905185939192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4611383565b6006600b8190556040516000805160206149b9833981519152916121c991339190613dff565b61271482826117d3565b610ea8576000828152600a602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561274c3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b61279a82826117d3565b15610ea8576000828152600a602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6008600b8190556040516000805160206149b9833981519152916121c991339190613dff565b610ea8828260405180602001604052806000815250613318565b6000612842826132d7565b90508061284e836115d7565b600084815260066020908152604080832080546001600160a01b03191690556001600160a01b0384168084526001835281842080546fffffffffffffffffffffffffffffffff01905587845291839052808320600160e01b4260a01b84171790555192935085927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a4505050565b6000818152602081905260408120548015801590611ed15750600160e01b161592915050565b6127106001600160601b03821611156129305760405162461bcd60e51b815260040161107e9061469c565b6001600160a01b0382166129865760405162461bcd60e51b815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d65746572730000000000604482015260640161107e565b6040805180820182526001600160a01b0393841681526001600160601b0392831660208083019182526000968752600990529190942093519051909116600160a01b029116179055565b6000610d5b826132d7565b80518251146129f4576129f4637736a16d60e01b61250c565b8051601580548201905560148054909101905560005b825181101561105257612a4f838281518110612a2857612a2861472b565b6020026020010151838381518110612a4257612a4261472b565b602002602001015161281d565b80612a5981614741565b915050612a0a565b60006001600160a01b038216612a8157612a816323d3ad8160e21b61250c565b506001600160a01b03166000908152600160205260409020546001600160401b031690565b6060818310612abf57612abf631960ccad60e11b61250c565b6001831015612acd57600192505b6000612ad860055490565b6001019050808310612ae8578092505b60606000612af5876116f9565b85871090810291508115612bc0578187870311612b125786860391505b60405192506001820160051b83016040526000612b2e88611cf5565b905060008160400151612b3f575080515b60005b612b4b8a612e01565b80519093506001600160a01b0316612b6857600190990198612ba9565b60408301518015612b7c5760009250612ba1565b835115612b8857835192505b8b831860601b612ba1576001820191508a8260051b8801525b5060018a0199505b888a1480612bb657508481145b15612b4257855250505b50909695505050505050565b60008111612c1c5760405162461bcd60e51b815260206004820152601960248201527f7175616e74697479206d75737420626520706f73697469766500000000000000604482015260640161107e565b6004546000905b82821015612c62575b612c35816128df565b15612c4c5780612c4481614741565b915050612c2c565b612c56848261281d565b60019182019101612c23565b600455505050565b6001600160a01b031660009081526001602052604090205460c01c90565b6000612c9383612c6a565b9050611052838263ffffffff16602085901b1761334b565b816001600160a01b0316836001600160a01b031603612d0c5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161107e565b6001600160a01b03838116600081815260076020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b610ea833611aa1565b6001600b8190556040516000805160206149b9833981519152916121c991339190613dff565b612db3848484612574565b612dbf8484848461337d565b6113835760405162461bcd60e51b815260040161107e9061475a565b6002600b8190556040516000805160206149b9833981519152916121c991339190613dff565b6040805160808101825260008082526020808301829052828401829052606083018290528482528190529190912054610d5b90604080516080810182526001600160a01b038316815260a083901c6001600160401b03166020820152600160e01b831615159181019190915260e89190911c606082015290565b6000612e8683612c6a565b90506110528367ffffffff000000008316841761334b565b60606000612eaa61169e565b905080612eb68461347e565b600f604051602001612eca939291906147ac565b604051602081830303815290604052915050919050565b60006001600160e01b0319821663152a902d60e11b1480610d5b5750610d5b82613510565b600081815260066020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612f3b826115d7565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b612f7e82826117d3565b610ea857612f8b81613560565b612f96836020613572565b604051602001612fa792919061484c565b60408051601f198184030181529082905262461bcd60e51b825261107e91600401613c9c565b805160009060ff602085013560081c16908015612fed5750806001166001145b15612ffc576001915050610d5b565b826020015180156130105750806002166002145b1561301f576001915050610d5b565b826040015180156130335750806004166004145b15613042576001915050610d5b565b826060015180156130565750806008166008145b15613065576001915050610d5b565b6000915050610d5b565b6000808260200135600416600403613098575060019260209092013560591c62ffffff16919050565b506000928392509050565b6000808260200135600116600103613098575060019260209092013560101c68ffffffffffffffffff16919050565b600080807f359654c27f5dfc68a3a2ce2b3673ac47f634adf6efa5ae8806509d4d09a4a43161310760c0860160a08701613c2f565b61311760c0870160a08801613c2f565b60405160200161313f919060609190911b6bffffffffffffffffffffffff1916815260140190565b60405160208183030381529060405280519060200120604051602001613181939291909283526001600160a01b03919091166020830152604082015260600190565b604051602081830303815290604052805190602001209050600085826040516020016131c492919061190160f01b81526002810192909252602282015260420190565b60408051601f1981840301815291905280516020909101209050600061322b826131f16060890189614444565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061370d92505050565b905060006132b261324260e0890160c08a01613c2f565b61324f60408a018a614444565b604051613269939291908c35906020808f013591016148c1565b604051602081830303815290604052805190602001207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b905060006132c7826131f160808b018b614444565b9299929850919650505050505050565b60008181526020819052604090205480158015906132f95750600160e01b8116155b1561330357919050565b613313636f96cda160e11b61250c565b919050565b6133228383613729565b61332f600084848461337d565b6110525760405162461bcd60e51b815260040161107e9061475a565b6001600160a01b03909116600090815260016020526040902080546001600160c01b031660c09290921b919091179055565b60006001600160a01b0384163b1561347357604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906133c19033908990889088906004016148f1565b6020604051808303816000875af19250505080156133fc575060408051601f3d908101601f191682019092526133f99181019061492e565b60015b613459573d80801561342a576040519150601f19603f3d011682016040523d82523d6000602084013e61342f565b606091505b5080516000036134515760405162461bcd60e51b815260040161107e9061475a565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611734565b506001949350505050565b6060600061348b836138bf565b60010190506000816001600160401b038111156134aa576134aa613e7c565b6040519080825280601f01601f1916602001820160405280156134d4576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846134de57509392505050565b60006001600160e01b031982166380ac58cd60e01b148061354157506001600160e01b03198216635b5e139f60e01b145b80610d5b57506301ffc9a760e01b6001600160e01b0319831614610d5b565b6060610d5b6001600160a01b03831660145b6060600061358183600261440b565b61358c90600261449a565b6001600160401b038111156135a3576135a3613e7c565b6040519080825280601f01601f1916602001820160405280156135cd576020820181803683370190505b509050600360fc1b816000815181106135e8576135e861472b565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106136175761361761472b565b60200101906001600160f81b031916908160001a905350600061363b84600261440b565b61364690600161449a565b90505b60018111156136be576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061367a5761367a61472b565b1a60f81b8282815181106136905761369061472b565b60200101906001600160f81b031916908160001a90535060049490941c936136b78161494b565b9050613649565b508315611ed15760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161107e565b600080600061371c8585613997565b9150915061156d816139d9565b6001600160a01b03821661377f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161107e565b613788816128df565b156137d55760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161107e565b6137de816128df565b1561382b5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161107e565b6001600160a01b0382164260a01b17600160e11b17600082815260208181526040808320939093556001600160a01b038516825260019052208054680100000000000000010190556005548111156138835760058190555b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106138fe5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061392a576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061394857662386f26fc10000830492506010015b6305f5e1008310613960576305f5e100830492506008015b612710831061397457612710830492506004015b60648310613986576064830492506002015b600a8310610d5b5760010192915050565b60008082516041036139cd5760208301516040840151606085015160001a6139c187828585613b23565b9450945050505061114c565b5060009050600261114c565b60008160048111156139ed576139ed614962565b036139f55750565b6001816004811115613a0957613a09614962565b03613a565760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161107e565b6002816004811115613a6a57613a6a614962565b03613ab75760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161107e565b6003816004811115613acb57613acb614962565b03610ebf5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161107e565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613b5a5750600090506003613bde565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613bae573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116613bd757600060019250925050613bde565b9150600090505b94509492505050565b6001600160e01b031981168114610ebf57600080fd5b600060208284031215613c0f57600080fd5b8135611ed181613be7565b6001600160a01b0381168114610ebf57600080fd5b600060208284031215613c4157600080fd5b8135611ed181613c1a565b60005b83811015613c67578181015183820152602001613c4f565b50506000910152565b60008151808452613c88816020860160208601613c4c565b601f01601f19169290920160200192915050565b602081526000611ed16020830184613c70565b600060208284031215613cc157600080fd5b5035919050565b60008060408385031215613cdb57600080fd5b8235613ce681613c1a565b946020939093013593505050565b80356001600160601b038116811461331357600080fd5b60008060408385031215613d1e57600080fd5b8235613d2981613c1a565b9150613d3760208401613cf4565b90509250929050565b600060e08284031215613d5257600080fd5b50919050565b60008060408385031215613d6b57600080fd5b82356001600160401b03811115613d8157600080fd5b613d8d85828601613d40565b95602094909401359450505050565b600080600060608486031215613db157600080fd5b8335613dbc81613c1a565b92506020840135613dcc81613c1a565b929592945050506040919091013590565b60008060408385031215613df057600080fd5b50508035926020909101359150565b6001600160a01b03929092168252602082015260400190565b60008060408385031215613e2b57600080fd5b823591506020830135613e3d81613c1a565b809150509250929050565b600060208284031215613e5a57600080fd5b81356001600160401b03811115613e7057600080fd5b61173484828501613d40565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613eba57613eba613e7c565b604052919050565b60006001600160401b03831115613edb57613edb613e7c565b613eee601f8401601f1916602001613e92565b9050828152838383011115613f0257600080fd5b828260208301376000602084830101529392505050565b600060208284031215613f2b57600080fd5b81356001600160401b03811115613f4157600080fd5b8201601f81018413613f5257600080fd5b61173484823560208401613ec2565b600080600060608486031215613f7657600080fd5b833592506020840135613f8881613c1a565b9150613f9660408501613cf4565b90509250925092565b60008060208385031215613fb257600080fd5b82356001600160401b0380821115613fc957600080fd5b818501915085601f830112613fdd57600080fd5b813581811115613fec57600080fd5b8660208260051b850101111561400157600080fd5b60209290920196919550909350505050565b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b6020808252825182820181905260009190848201906040850190845b81811015612bc05761407e838551614013565b928401926080929092019160010161406b565b60006001600160401b038211156140aa576140aa613e7c565b5060051b60200190565b600082601f8301126140c557600080fd5b813560206140da6140d583614091565b613e92565b82815260059290921b840181019181810190868411156140f957600080fd5b8286015b8481101561411457803583529183019183016140fd565b509695505050505050565b6000806040838503121561413257600080fd5b82356001600160401b038082111561414957600080fd5b818501915085601f83011261415d57600080fd5b8135602061416d6140d583614091565b82815260059290921b8401810191818101908984111561418c57600080fd5b948201945b838610156141b35785356141a481613c1a565b82529482019490820190614191565b965050860135925050808211156141c957600080fd5b506141d6858286016140b4565b9150509250929050565b6020808252825182820181905260009190848201906040850190845b81811015612bc0578351835292840192918401916001016141fc565b8015158114610ebf57600080fd5b60006020828403121561423857600080fd5b8135611ed181614218565b60008060006060848603121561425857600080fd5b833561426381613c1a565b95602085013595506040909401359392505050565b6000806040838503121561428b57600080fd5b823561429681613c1a565b91506020830135613e3d81614218565b600080600080608085870312156142bc57600080fd5b84356142c781613c1a565b935060208501356142d781613c1a565b92506040850135915060608501356001600160401b038111156142f957600080fd5b8501601f8101871361430a57600080fd5b61431987823560208401613ec2565b91505092959194509250565b60808101610d5b8284614013565b6000806040838503121561434657600080fd5b823561435181613c1a565b91506020830135613e3d81613c1a565b600181811c9082168061437557607f821691505b602082108103613d5257634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115610d5b57610d5b614395565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b8082028115828204841417610d5b57610d5b614395565b60008261443f57634e487b7160e01b600052601260045260246000fd5b500490565b6000808335601e1984360301811261445b57600080fd5b8301803591506001600160401b0382111561447557600080fd5b60200191503681900382131561114c57600080fd5b8183823760009101908152919050565b80820180821115610d5b57610d5b614395565b601f82111561105257600081815260208120601f850160051c810160208610156144d45750805b601f850160051c820191505b81811015611a94578281556001016144e0565b81516001600160401b0381111561450c5761450c613e7c565b6145208161451a8454614361565b846144ad565b602080601f831160018114614555576000841561453d5750858301515b600019600386901b1c1916600185901b178555611a94565b600085815260208120601f198616915b8281101561458457888601518255948401946001909101908401614565565b50858210156145a25787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b038316815260406020820181905260009061173490830184613c70565b7f68747470733a2f2f696d6167652d636f636f6e75742e73746f726167652e676f81527f6f676c65617069732e636f6d2f70726f64756374696f6e2f746f6b656e2f6d656020820152667461646174612f60c81b604082015260008351614644816047850160208801613c4c565b605f60f81b6047918401918201528351614665816048840160208801613c4c565b602f60f81b60489290910191820152604901949350505050565b60006020828403121561469157600080fd5b8151611ed181614218565b6020808252602a908201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646040820152692073616c65507269636560b01b606082015260800190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60006001820161475357614753614395565b5060010190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000845160206147bf8285838a01613c4c565b8551918401916147d28184848a01613c4c565b85549201916000906147e381614361565b600182811680156147fb57600181146148105761483c565b60ff198416875282151583028701945061483c565b896000528560002060005b848110156148345781548982015290830190870161481b565b505082870194505b50929a9950505050505050505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614884816017850160208801613c4c565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516148b5816028840160208801613c4c565b01602801949350505050565b6001600160601b03198660601b168152838560148301376014930192830191909152603482015260540192915050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061492490830184613c70565b9695505050505050565b60006020828403121561494057600080fd5b8151611ed181613be7565b60008161495a5761495a614395565b506000190190565b634e487b7160e01b600052602160045260246000fdfe05c0f7ac2b4a836d461d705215d2827b3523466a4e4e877245ccc4028acd195e9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6e6ba96c502ac04a25522516a16b95a29fbe3ca2659625a33d96c64a957a0cc27a26469706673582212202eddbdbd986f790c76c8d8e9591312a809cf0067d1f37370d6fff7e4875486a764736f6c63430008150033
Deployed Bytecode
0x60806040526004361061041b5760003560e01c80636352211e1161021e578063a22cb46511610123578063d5391393116100ab578063e985e9c51161007a578063e985e9c514610cb8578063f0dda65c14610cd8578063f51f96dd14610cf8578063f696b60614610d0e578063fb7df78814610d2e57600080fd5b8063d539139314610c4b578063d547741f14610c6d578063d5bd1fbb14610c8d578063d89135cd14610ca357600080fd5b8063b88d4fde116100f2578063b88d4fde14610bb6578063becadb6514610bd6578063c23dc68f14610beb578063c27eb7b914610c18578063c87b56dd14610c2b57600080fd5b8063a22cb46514610b59578063a2309ff814610b79578063a77eaa0914610b8e578063ac5ae11b14610ba357600080fd5b806391e170d4116101a65780639bb5c9c3116101755780639bb5c9c314610ac45780639f6350e614610ae4578063a0b133f014610b04578063a1c2169814610b24578063a217fddf14610b4457600080fd5b806391e170d414610a4f57806395a613fe14610a6f57806395d89b4114610a8f57806399a2557a14610aa457600080fd5b806370a08231116101ed57806370a08231146109ae5780638462151c146109ce57806384a6819b146109fb5780638ddae77e14610a0e57806391d1485414610a2f57600080fd5b80636352211e1461093957806367d541481461095957806368573107146109795780636c0360eb1461099957600080fd5b80632a55205a1161032457806342966c68116102ac57806355f804b31161027b57806355f804b31461085c5780635944c7531461087c5780635b8d02d71461089c5780635bbb2177146108bc578063603f4d52146108e957600080fd5b806342966c68146107dc5780634aaae9f0146107fc5780634dd09f331461081c5780634f558e791461083c57600080fd5b8063361fab25116102f3578063361fab251461074757806336568abe14610767578063380d831b1461078757806340c10f191461079c57806342842e0e146107bc57600080fd5b80632a55205a146106b95780632f2ff15d146106e757806333ea51a81461070757806335c618e61461072757600080fd5b80631919fed7116103a757806323b872dd1161037657806323b872dd14610628578063248a9ca31461064857806326987b6014610678578063272f0cd01461068e57806329cb320b146106a357600080fd5b80631919fed7146105bf57806319a04d43146105df57806319d1997a146105ff57806321542dd31461061557600080fd5b8063081812fc116103ee578063081812fc1461051b578063095ea7b3146105535780630c1c972a146105755780631796068a1461058a57806318160ddd146105aa57600080fd5b806301ffc9a71461042057806304d4f96c1461045557806306fdde03146104b7578063078fe6aa146104d9575b600080fd5b34801561042c57600080fd5b5061044061043b366004613bfd565b610d50565b60405190151581526020015b60405180910390f35b34801561046157600080fd5b50610475610470366004613c2f565b610d61565b60405161044c9190600060a082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015292915050565b3480156104c357600080fd5b506104cc610de5565b60405161044c9190613c9c565b3480156104e557600080fd5b5061050d7fbd06e35dfb74fc80605c99cb7f4326f1bf8754c8a909b71aa497ad9b9f3e82b281565b60405190815260200161044c565b34801561052757600080fd5b5061053b610536366004613caf565b610e77565b6040516001600160a01b03909116815260200161044c565b34801561055f57600080fd5b5061057361056e366004613cc8565b610e9e565b005b34801561058157600080fd5b50610573610eac565b34801561059657600080fd5b506105736105a5366004613caf565b610ec2565b3480156105b657600080fd5b5061050d610f10565b3480156105cb57600080fd5b506105736105da366004613caf565b610f27565b3480156105eb57600080fd5b506105736105fa366004613d0b565b610f69565b34801561060b57600080fd5b5061050d60135481565b610573610623366004613d58565b610fd3565b34801561063457600080fd5b50610573610643366004613d9c565b611057565b34801561065457600080fd5b5061050d610663366004613caf565b6000908152600a602052604090206001015490565b34801561068457600080fd5b5061050d60045481565b34801561069a57600080fd5b50610573611092565b3480156106af57600080fd5b5061050d60125481565b3480156106c557600080fd5b506106d96106d4366004613ddd565b6110a5565b60405161044c929190613dff565b3480156106f357600080fd5b50610573610702366004613e18565b611153565b34801561071357600080fd5b50610573610722366004613c2f565b611178565b34801561073357600080fd5b50610440610742366004613e48565b6111f6565b34801561075357600080fd5b50610573610762366004613caf565b61124f565b34801561077357600080fd5b50610573610782366004613e18565b611291565b34801561079357600080fd5b5061057361130b565b3480156107a857600080fd5b506105736107b7366004613cc8565b61131e565b3480156107c857600080fd5b506105736107d7366004613d9c565b611389565b3480156107e857600080fd5b506105736107f7366004613caf565b6113a4565b34801561080857600080fd5b50610573610817366004613caf565b61141d565b34801561082857600080fd5b50600c5461053b906001600160a01b031681565b34801561084857600080fd5b50610440610857366004613caf565b611462565b34801561086857600080fd5b50610573610877366004613f19565b61146d565b34801561088857600080fd5b50610573610897366004613f61565b6114b6565b3480156108a857600080fd5b50600d5461053b906001600160a01b031681565b3480156108c857600080fd5b506108dc6108d7366004613f9f565b611529565b60405161044c919061404f565b3480156108f557600080fd5b506108fe611575565b60405161044c919081511515815260208083015115159082015260408083015115159082015260609182015115159181019190915260800190565b34801561094557600080fd5b5061053b610954366004613caf565b6115d7565b34801561096557600080fd5b5061057361097436600461411f565b611636565b34801561098557600080fd5b5061057361099436600461411f565b611686565b3480156109a557600080fd5b506104cc61169e565b3480156109ba57600080fd5b5061050d6109c9366004613c2f565b6116f9565b3480156109da57600080fd5b506109ee6109e9366004613c2f565b611704565b60405161044c91906141e0565b610573610a09366004613d58565b61173c565b348015610a1a57600080fd5b50600d5461044090600160a01b900460ff1681565b348015610a3b57600080fd5b50610440610a4a366004613e18565b6117d3565b348015610a5b57600080fd5b50610573610a6a366004613cc8565b6117fe565b348015610a7b57600080fd5b50610573610a8a366004614226565b61185d565b348015610a9b57600080fd5b506104cc6118bc565b348015610ab057600080fd5b506109ee610abf366004614243565b6118cb565b348015610ad057600080fd5b50610573610adf366004613c2f565b6118d8565b348015610af057600080fd5b50610573610aff366004613f19565b611938565b348015610b1057600080fd5b50610573610b1f366004613caf565b611981565b348015610b3057600080fd5b50610573610b3f366004613cc8565b6119c3565b348015610b5057600080fd5b5061050d600081565b348015610b6557600080fd5b50610573610b74366004614278565b611a9c565b348015610b8557600080fd5b5060155461050d565b348015610b9a57600080fd5b50610573611b48565b610573610bb1366004613cc8565b611b5b565b348015610bc257600080fd5b50610573610bd13660046142a6565b611cb0565b348015610be257600080fd5b50610573611ce2565b348015610bf757600080fd5b50610c0b610c06366004613caf565b611cf5565b60405161044c9190614325565b610573610c26366004613d58565b611d22565b348015610c3757600080fd5b506104cc610c46366004613caf565b611dda565b348015610c5757600080fd5b5061050d60008051602061499983398151915281565b348015610c7957600080fd5b50610573610c88366004613e18565b611dee565b348015610c9957600080fd5b5061050d60105481565b348015610caf57600080fd5b5060165461050d565b348015610cc457600080fd5b50610440610cd3366004614333565b611e13565b348015610ce457600080fd5b50610573610cf3366004613cc8565b611ed8565b348015610d0457600080fd5b5061050d60115481565b348015610d1a57600080fd5b50610573610d29366004613d58565b611ef0565b348015610d3a57600080fd5b5061050d60008051602061497983398151915281565b6000610d5b82611f86565b92915050565b610d936040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b6000610d9e83611fab565b6060808201516040805160a0810182528451815260208086015182820152948201519181019190915263ffffffff80831693820193909352921c1660808201529392505050565b606060028054610df490614361565b80601f0160208091040260200160405190810160405280929190818152602001828054610e2090614361565b8015610e6d5780601f10610e4257610100808354040283529160200191610e6d565b820191906000526020600020905b815481529060010190602001808311610e5057829003601f168201915b5050505050905090565b6000610e8282612039565b506000908152600660205260409020546001600160a01b031690565b610ea88282612089565b5050565b6000610eb781612199565b610ebf6121a3565b50565b6000610ecd81612199565b60128290556040517f9074f4c535a222861a631985c506f755c216edda189cb7656116f60322228bad90610f049033908590613dff565b60405180910390a15050565b6000601654601454610f2291906143ab565b905090565b6000610f3281612199565b60118290556040517f3609bd5d3527f15800f13522a75b9fc8812914c78183aba8862844e0e07ff89c90610f049033908590613dff565b6000610f7481612199565b610f7e83836121d3565b604080513381526001600160a01b03851660208201526001600160601b0384168183015290517ff874f682d038bfde0e507056054fb956bf3ae135b4974d2f0edc1ac65150db599181900360600190a1505050565b610fe182826000600161228d565b3415610ea857600d546040516000916001600160a01b03169034908381818185875af1925050503d8060008114611034576040519150601f19603f3d011682016040523d82523d6000602084013e611039565b606091505b50509050806110525761105263abab8fc960e01b61250c565b505050565b611062335b82612516565b6110875760405162461bcd60e51b815260040161107e906143be565b60405180910390fd5b611052838383612574565b600061109d81612199565b610ebf6126e4565b60008281526009602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b031692820192909252829161111a5750604080518082019091526008546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090611139906001600160601b03168761440b565b6111439190614422565b91519350909150505b9250929050565b6000828152600a602052604090206001015461116e81612199565b611052838361270a565b600061118381612199565b6001600160a01b0382166111a1576111a1633efa09af60e01b61250c565b600d80546001600160a01b0319166001600160a01b0384169081179091556040805133815260208101929092527f54f1877b9010a3135c68dc2b0b326591d02a8cfbae5443bc11b94af1cafae4029101610f04565b600060026020830135811614806112105750600092915050565b600061121f6080850185614444565b60405161122d92919061448a565b604080519182900390912060009081526017602052205460ff16949350505050565b600061125a81612199565b60138290556040517fd60ff19058ff26897d4ccb9d7ee31a589d1230dc668dfdee26fda0a565bac73490610f049033908590613dff565b6001600160a01b03811633146113015760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840161107e565b610ea88282612790565b600061131681612199565b610ebf6127f7565b60008051602061499983398151915261133681612199565b600160135481611344610f10565b61134e919061449a565b11156113645761136463aac1eb5b60e01b61250c565b601580546001908101909155601480549091019055611383848461281d565b50505050565b61105283838360405180602001604052806000815250611cb0565b600d54600160a01b900460ff166113c5576113c563dbdcbe8360e01b61250c565b6113ce81612039565b6113d73361105c565b6113eb576113eb63453e58fd60e11b61250c565b6113f481612837565b600160166000828254611407919061449a565b9091555050600090815260096020526040812055565b600061142881612199565b61143182600455565b7fab773b7d529aa3f9149ea7b1bae8b9fdd8a0bd28c0b595b72f0c9ebf5471dcd73383604051610f04929190613dff565b6000610d5b826128df565b600061147881612199565b600e61148483826144f3565b507f6202a022117da849075762436d4cf956151ce1d67c7d3969003ab2eab4cd49fe3383604051610f049291906145b2565b60006114c181612199565b6114cc848484612905565b60408051338152602081018690526001600160a01b038516818301526001600160601b038416606082015290517f5854d7f929b02b5eacb3c32ff0c806eebb22c4b68f3cf0c57fd6826eb6207eff9181900360800190a150505050565b60408051828152600583901b8082016020019092526060915b801561156d57601f198082019186010135600061155e82611cf5565b84840160200152506115429050565b509392505050565b6040805160808101825260008082526020820181905291810182905260608101919091525060408051608081018252600b5460018181161482526002808216146020830152600480821614928201929092526008918216909114606082015290565b6000806115e3836129d0565b90506001600160a01b038116610d5b5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604482015260640161107e565b60008051602061497983398151915261164e81612199565b81516013548161165c610f10565b611666919061449a565b111561167c5761167c63aac1eb5b60e01b61250c565b61138384846129db565b60008051602061499983398151915261164e81612199565b60606000600e80546116af90614361565b905011156116c457600e8054610df490614361565b6116cc610de5565b6116d46118bc565b6040516020016116e59291906145d6565b604051602081830303815290604052905090565b6000610d5b82612a61565b60055460609060019060009061171b90600161449a565b9050606081831461173457611731858484612aa6565b90505b949350505050565b60008051602061497983398151915261175481612199565b61176283836000600161228d565b341561105257600d546040516000916001600160a01b03169034908381818185875af1925050503d80600081146117b5576040519150601f19603f3d011682016040523d82523d6000602084013e6117ba565b606091505b50509050806113835761138363abab8fc960e01b61250c565b6000918252600a602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60008051602061497983398151915261181681612199565b8160135481611823610f10565b61182d919061449a565b11156118435761184363aac1eb5b60e01b61250c565b601580548401905560148054840190556113838484612bcc565b600061186881612199565b600d805460ff60a01b1916600160a01b841515908102919091179091556040805133815260208101929092527fd0911d56226214ed1a76457bed8948fd2d11e69cc268af5212869a9f6dbc3ba19101610f04565b606060038054610df490614361565b6060611734848484612aa6565b60006118e381612199565b600c80546001600160a01b0319166001600160a01b0384169081179091556040805133815260208101929092527f7c23f9fede5a4305d068a89d49795d9fa640e65f937863b8c35aceb1c5db945e9101610f04565b600061194381612199565b600f61194f83826144f3565b507fee41836175e4185a28dc07490c88903ba0666573c4d4a4306c9a0991465f37023383604051610f049291906145b2565b600061198c81612199565b60108290556040517faab643a5211d1c06e36b6c88ce00ad728ae6a265c60b177bd617f01bf43feaab90610f049033908590613dff565b6000805160206149798339815191526119db81612199565b81601354816119e8610f10565b6119f2919061449a565b1115611a0857611a0863aac1eb5b60e01b61250c565b600480600b541614611a2457611a2463b575512f60e01b61250c565b6000611a2f85612c6a565b60125490915063ffffffff602083901c169015801590611a595750601254611a57868361449a565b115b15611a6e57611a6e633e65519560e01b61250c565b601580548601905560148054860190558401611a8a8682612c88565b611a948686612bcc565b505050505050565b611aa8335b8383612cab565b600c546001600160a01b031615801590611acb57506001600160a01b0382163b15155b15611b3e57600c54604051631b3b02e560e11b81523360048201526001600160a01b03848116602483015283151560448301529091169063367605ca90606401600060405180830381600087803b158015611b2557600080fd5b505af1158015611b39573d6000803e3d6000fd5b505050505b610ea88282612d79565b6000611b5381612199565b610ebf612d82565b8060135481611b68610f10565b611b72919061449a565b1115611b8857611b8863aac1eb5b60e01b61250c565b600480600b541614611ba457611ba463b575512f60e01b61250c565b6000611baf84612c6a565b60125490915063ffffffff602083901c169015801590611bd95750601254611bd7858361449a565b115b15611bee57611bee633e65519560e01b61250c565b83601154611bfc919061440b565b3414611c1257611c1263420116e360e11b61250c565b601580548501905560148054850190558301611c2e8582612c88565b611c388585612bcc565b3415611ca957600d546040516000916001600160a01b03169034908381818185875af1925050503d8060008114611c8b576040519150601f19603f3d011682016040523d82523d6000602084013e611c90565b606091505b5050905080611a9457611a9463abab8fc960e01b61250c565b5050505050565b611cba3383612516565b611cd65760405162461bcd60e51b815260040161107e906143be565b61138384848484612da8565b6000611ced81612199565b610ebf612ddb565b604080516080810182526000808252602082018190529181018290526060810191909152610d5b82612e01565b8060135481611d2f610f10565b611d39919061449a565b1115611d4f57611d4f63aac1eb5b60e01b61250c565b600280600b541614611d6b57611d6b633dac9e9960e21b61250c565b6000611d85611d8060e0860160c08701613c2f565b612c6a565b905063ffffffff81168435611d9a858361449a565b1115611db057611db063b8edfd7760e01b61250c565b8301611dcb611dc560e0870160c08801613c2f565b82612e7b565b611c388585601054600061228d565b6060611de582612039565b610d5b82612e9e565b6000828152600a6020526040902060010154611e0981612199565b6110528383612790565b6001600160a01b0382811660009081526007602090815260408083208585168452909152812054600c54919260ff909116911615611ed157600c546040516346e67e2960e11b81526001600160a01b0386811660048301528581166024830152831515604483015290911690638dccfc5290606401602060405180830381865afa158015611ea5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec9919061467f565b915050610d5b565b9392505050565b60008051602061499983398151915261181681612199565b600080516020614979833981519152611f0881612199565b600280600b541614611f2457611f24633dac9e9960e21b61250c565b6000611f39611d8060e0860160c08701613c2f565b905063ffffffff81168435611f4e858361449a565b1115611f6457611f6463b8edfd7760e01b61250c565b8301611f79611dc560e0870160c08801613c2f565b611ca9858560008061228d565b60006001600160e01b03198216637965db0b60e01b1480610d5b5750610d5b82612ee1565b611fdf604051806080016040528060008152602001600081526020016000815260200160006001600160401b031681525090565b506001600160a01b0316600090815260016020908152604091829020548251608080820185526001600160401b03808416835283861c81169483019490945282901c9092169282019290925260c09190911c606082015290565b612042816128df565b610ebf5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604482015260640161107e565b6000612094826115d7565b9050806001600160a01b0316836001600160a01b0316036121015760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161107e565b336001600160a01b038216148061211d575061211d8133611e13565b61218f5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000606482015260840161107e565b6110528383612f06565b610ebf8133612f74565b6004600b8190556040516000805160206149b9833981519152916121c991339190613dff565b60405180910390a1565b6127106001600160601b03821611156121fe5760405162461bcd60e51b815260040161107e9061469c565b6001600160a01b0382166122545760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c696420726563656976657200000000000000604482015260640161107e565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600855565b8080156122a957506122a76122a0611575565b8590612fcd565b155b156122be576122be6311d15f2960e31b61250c565b6002602085013581161460008115612320576122dd6080870187614444565b6040516122eb92919061448a565b604080519182900390912060008181526017602052919091205490915060ff161561232057612320630c848adf60e01b61250c565b60008061232c8861306f565b9150915081801561233a5750845b9150811561234757600196505b60135487612353610f10565b61235d919061449a565b11156123735761237363aac1eb5b60e01b61250c565b811580156123815750873587115b1561239657612396633e65519560e01b61250c565b84156123cc576000806123a88a6130a3565b91509150816123c5576123c062e363d160e01b61250c565b6123c9565b8097505b50505b6123d6878761440b565b34146123ec576123ec63420116e360e11b61250c565b6000806124197f396d38c8cb9a3236dce486715918c044c9fa1f771bca746789e49f3b3d9cca4c8b6130d2565b915091506124477fbd06e35dfb74fc80605c99cb7f4326f1bf8754c8a909b71aa497ad9b9f3e82b2836117d3565b61245b5761245b63023b8e5d60e61b61250c565b61246b60c08b0160a08c01613c2f565b6001600160a01b0316816001600160a01b031614612493576124936387a20acd60e01b61250c565b601580548a019055601480548a01905585156124c3576000858152601760205260409020805460ff191660011790555b83156124e7576124e26124dc60e08c0160c08d01613c2f565b8461281d565b612500565b6125006124fa60e08c0160c08d01613c2f565b8a612bcc565b50505050505050505050565b8060005260046000fd5b600080612522836115d7565b9050806001600160a01b0316846001600160a01b0316148061254957506125498185611e13565b806117345750836001600160a01b031661256284610e77565b6001600160a01b031614949350505050565b826001600160a01b0316612587826115d7565b6001600160a01b0316146125ad5760405162461bcd60e51b815260040161107e906146e6565b6001600160a01b03821661260f5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161107e565b600061261a826132d7565b9050836001600160a01b031661262f836115d7565b6001600160a01b0316146126555760405162461bcd60e51b815260040161107e906146e6565b600082815260066020908152604080832080546001600160a01b03191690556001600160a01b03878116808552600180855283862080546000190190559188168086528386208054909301909255868552928490528184204260a01b82179055905185939192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4611383565b6006600b8190556040516000805160206149b9833981519152916121c991339190613dff565b61271482826117d3565b610ea8576000828152600a602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561274c3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b61279a82826117d3565b15610ea8576000828152600a602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6008600b8190556040516000805160206149b9833981519152916121c991339190613dff565b610ea8828260405180602001604052806000815250613318565b6000612842826132d7565b90508061284e836115d7565b600084815260066020908152604080832080546001600160a01b03191690556001600160a01b0384168084526001835281842080546fffffffffffffffffffffffffffffffff01905587845291839052808320600160e01b4260a01b84171790555192935085927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a4505050565b6000818152602081905260408120548015801590611ed15750600160e01b161592915050565b6127106001600160601b03821611156129305760405162461bcd60e51b815260040161107e9061469c565b6001600160a01b0382166129865760405162461bcd60e51b815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d65746572730000000000604482015260640161107e565b6040805180820182526001600160a01b0393841681526001600160601b0392831660208083019182526000968752600990529190942093519051909116600160a01b029116179055565b6000610d5b826132d7565b80518251146129f4576129f4637736a16d60e01b61250c565b8051601580548201905560148054909101905560005b825181101561105257612a4f838281518110612a2857612a2861472b565b6020026020010151838381518110612a4257612a4261472b565b602002602001015161281d565b80612a5981614741565b915050612a0a565b60006001600160a01b038216612a8157612a816323d3ad8160e21b61250c565b506001600160a01b03166000908152600160205260409020546001600160401b031690565b6060818310612abf57612abf631960ccad60e11b61250c565b6001831015612acd57600192505b6000612ad860055490565b6001019050808310612ae8578092505b60606000612af5876116f9565b85871090810291508115612bc0578187870311612b125786860391505b60405192506001820160051b83016040526000612b2e88611cf5565b905060008160400151612b3f575080515b60005b612b4b8a612e01565b80519093506001600160a01b0316612b6857600190990198612ba9565b60408301518015612b7c5760009250612ba1565b835115612b8857835192505b8b831860601b612ba1576001820191508a8260051b8801525b5060018a0199505b888a1480612bb657508481145b15612b4257855250505b50909695505050505050565b60008111612c1c5760405162461bcd60e51b815260206004820152601960248201527f7175616e74697479206d75737420626520706f73697469766500000000000000604482015260640161107e565b6004546000905b82821015612c62575b612c35816128df565b15612c4c5780612c4481614741565b915050612c2c565b612c56848261281d565b60019182019101612c23565b600455505050565b6001600160a01b031660009081526001602052604090205460c01c90565b6000612c9383612c6a565b9050611052838263ffffffff16602085901b1761334b565b816001600160a01b0316836001600160a01b031603612d0c5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161107e565b6001600160a01b03838116600081815260076020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b610ea833611aa1565b6001600b8190556040516000805160206149b9833981519152916121c991339190613dff565b612db3848484612574565b612dbf8484848461337d565b6113835760405162461bcd60e51b815260040161107e9061475a565b6002600b8190556040516000805160206149b9833981519152916121c991339190613dff565b6040805160808101825260008082526020808301829052828401829052606083018290528482528190529190912054610d5b90604080516080810182526001600160a01b038316815260a083901c6001600160401b03166020820152600160e01b831615159181019190915260e89190911c606082015290565b6000612e8683612c6a565b90506110528367ffffffff000000008316841761334b565b60606000612eaa61169e565b905080612eb68461347e565b600f604051602001612eca939291906147ac565b604051602081830303815290604052915050919050565b60006001600160e01b0319821663152a902d60e11b1480610d5b5750610d5b82613510565b600081815260066020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612f3b826115d7565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b612f7e82826117d3565b610ea857612f8b81613560565b612f96836020613572565b604051602001612fa792919061484c565b60408051601f198184030181529082905262461bcd60e51b825261107e91600401613c9c565b805160009060ff602085013560081c16908015612fed5750806001166001145b15612ffc576001915050610d5b565b826020015180156130105750806002166002145b1561301f576001915050610d5b565b826040015180156130335750806004166004145b15613042576001915050610d5b565b826060015180156130565750806008166008145b15613065576001915050610d5b565b6000915050610d5b565b6000808260200135600416600403613098575060019260209092013560591c62ffffff16919050565b506000928392509050565b6000808260200135600116600103613098575060019260209092013560101c68ffffffffffffffffff16919050565b600080807f359654c27f5dfc68a3a2ce2b3673ac47f634adf6efa5ae8806509d4d09a4a43161310760c0860160a08701613c2f565b61311760c0870160a08801613c2f565b60405160200161313f919060609190911b6bffffffffffffffffffffffff1916815260140190565b60405160208183030381529060405280519060200120604051602001613181939291909283526001600160a01b03919091166020830152604082015260600190565b604051602081830303815290604052805190602001209050600085826040516020016131c492919061190160f01b81526002810192909252602282015260420190565b60408051601f1981840301815291905280516020909101209050600061322b826131f16060890189614444565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061370d92505050565b905060006132b261324260e0890160c08a01613c2f565b61324f60408a018a614444565b604051613269939291908c35906020808f013591016148c1565b604051602081830303815290604052805190602001207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b905060006132c7826131f160808b018b614444565b9299929850919650505050505050565b60008181526020819052604090205480158015906132f95750600160e01b8116155b1561330357919050565b613313636f96cda160e11b61250c565b919050565b6133228383613729565b61332f600084848461337d565b6110525760405162461bcd60e51b815260040161107e9061475a565b6001600160a01b03909116600090815260016020526040902080546001600160c01b031660c09290921b919091179055565b60006001600160a01b0384163b1561347357604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906133c19033908990889088906004016148f1565b6020604051808303816000875af19250505080156133fc575060408051601f3d908101601f191682019092526133f99181019061492e565b60015b613459573d80801561342a576040519150601f19603f3d011682016040523d82523d6000602084013e61342f565b606091505b5080516000036134515760405162461bcd60e51b815260040161107e9061475a565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611734565b506001949350505050565b6060600061348b836138bf565b60010190506000816001600160401b038111156134aa576134aa613e7c565b6040519080825280601f01601f1916602001820160405280156134d4576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846134de57509392505050565b60006001600160e01b031982166380ac58cd60e01b148061354157506001600160e01b03198216635b5e139f60e01b145b80610d5b57506301ffc9a760e01b6001600160e01b0319831614610d5b565b6060610d5b6001600160a01b03831660145b6060600061358183600261440b565b61358c90600261449a565b6001600160401b038111156135a3576135a3613e7c565b6040519080825280601f01601f1916602001820160405280156135cd576020820181803683370190505b509050600360fc1b816000815181106135e8576135e861472b565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106136175761361761472b565b60200101906001600160f81b031916908160001a905350600061363b84600261440b565b61364690600161449a565b90505b60018111156136be576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061367a5761367a61472b565b1a60f81b8282815181106136905761369061472b565b60200101906001600160f81b031916908160001a90535060049490941c936136b78161494b565b9050613649565b508315611ed15760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161107e565b600080600061371c8585613997565b9150915061156d816139d9565b6001600160a01b03821661377f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161107e565b613788816128df565b156137d55760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161107e565b6137de816128df565b1561382b5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161107e565b6001600160a01b0382164260a01b17600160e11b17600082815260208181526040808320939093556001600160a01b038516825260019052208054680100000000000000010190556005548111156138835760058190555b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106138fe5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061392a576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061394857662386f26fc10000830492506010015b6305f5e1008310613960576305f5e100830492506008015b612710831061397457612710830492506004015b60648310613986576064830492506002015b600a8310610d5b5760010192915050565b60008082516041036139cd5760208301516040840151606085015160001a6139c187828585613b23565b9450945050505061114c565b5060009050600261114c565b60008160048111156139ed576139ed614962565b036139f55750565b6001816004811115613a0957613a09614962565b03613a565760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161107e565b6002816004811115613a6a57613a6a614962565b03613ab75760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161107e565b6003816004811115613acb57613acb614962565b03610ebf5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161107e565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613b5a5750600090506003613bde565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613bae573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116613bd757600060019250925050613bde565b9150600090505b94509492505050565b6001600160e01b031981168114610ebf57600080fd5b600060208284031215613c0f57600080fd5b8135611ed181613be7565b6001600160a01b0381168114610ebf57600080fd5b600060208284031215613c4157600080fd5b8135611ed181613c1a565b60005b83811015613c67578181015183820152602001613c4f565b50506000910152565b60008151808452613c88816020860160208601613c4c565b601f01601f19169290920160200192915050565b602081526000611ed16020830184613c70565b600060208284031215613cc157600080fd5b5035919050565b60008060408385031215613cdb57600080fd5b8235613ce681613c1a565b946020939093013593505050565b80356001600160601b038116811461331357600080fd5b60008060408385031215613d1e57600080fd5b8235613d2981613c1a565b9150613d3760208401613cf4565b90509250929050565b600060e08284031215613d5257600080fd5b50919050565b60008060408385031215613d6b57600080fd5b82356001600160401b03811115613d8157600080fd5b613d8d85828601613d40565b95602094909401359450505050565b600080600060608486031215613db157600080fd5b8335613dbc81613c1a565b92506020840135613dcc81613c1a565b929592945050506040919091013590565b60008060408385031215613df057600080fd5b50508035926020909101359150565b6001600160a01b03929092168252602082015260400190565b60008060408385031215613e2b57600080fd5b823591506020830135613e3d81613c1a565b809150509250929050565b600060208284031215613e5a57600080fd5b81356001600160401b03811115613e7057600080fd5b61173484828501613d40565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613eba57613eba613e7c565b604052919050565b60006001600160401b03831115613edb57613edb613e7c565b613eee601f8401601f1916602001613e92565b9050828152838383011115613f0257600080fd5b828260208301376000602084830101529392505050565b600060208284031215613f2b57600080fd5b81356001600160401b03811115613f4157600080fd5b8201601f81018413613f5257600080fd5b61173484823560208401613ec2565b600080600060608486031215613f7657600080fd5b833592506020840135613f8881613c1a565b9150613f9660408501613cf4565b90509250925092565b60008060208385031215613fb257600080fd5b82356001600160401b0380821115613fc957600080fd5b818501915085601f830112613fdd57600080fd5b813581811115613fec57600080fd5b8660208260051b850101111561400157600080fd5b60209290920196919550909350505050565b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b6020808252825182820181905260009190848201906040850190845b81811015612bc05761407e838551614013565b928401926080929092019160010161406b565b60006001600160401b038211156140aa576140aa613e7c565b5060051b60200190565b600082601f8301126140c557600080fd5b813560206140da6140d583614091565b613e92565b82815260059290921b840181019181810190868411156140f957600080fd5b8286015b8481101561411457803583529183019183016140fd565b509695505050505050565b6000806040838503121561413257600080fd5b82356001600160401b038082111561414957600080fd5b818501915085601f83011261415d57600080fd5b8135602061416d6140d583614091565b82815260059290921b8401810191818101908984111561418c57600080fd5b948201945b838610156141b35785356141a481613c1a565b82529482019490820190614191565b965050860135925050808211156141c957600080fd5b506141d6858286016140b4565b9150509250929050565b6020808252825182820181905260009190848201906040850190845b81811015612bc0578351835292840192918401916001016141fc565b8015158114610ebf57600080fd5b60006020828403121561423857600080fd5b8135611ed181614218565b60008060006060848603121561425857600080fd5b833561426381613c1a565b95602085013595506040909401359392505050565b6000806040838503121561428b57600080fd5b823561429681613c1a565b91506020830135613e3d81614218565b600080600080608085870312156142bc57600080fd5b84356142c781613c1a565b935060208501356142d781613c1a565b92506040850135915060608501356001600160401b038111156142f957600080fd5b8501601f8101871361430a57600080fd5b61431987823560208401613ec2565b91505092959194509250565b60808101610d5b8284614013565b6000806040838503121561434657600080fd5b823561435181613c1a565b91506020830135613e3d81613c1a565b600181811c9082168061437557607f821691505b602082108103613d5257634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115610d5b57610d5b614395565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b8082028115828204841417610d5b57610d5b614395565b60008261443f57634e487b7160e01b600052601260045260246000fd5b500490565b6000808335601e1984360301811261445b57600080fd5b8301803591506001600160401b0382111561447557600080fd5b60200191503681900382131561114c57600080fd5b8183823760009101908152919050565b80820180821115610d5b57610d5b614395565b601f82111561105257600081815260208120601f850160051c810160208610156144d45750805b601f850160051c820191505b81811015611a94578281556001016144e0565b81516001600160401b0381111561450c5761450c613e7c565b6145208161451a8454614361565b846144ad565b602080601f831160018114614555576000841561453d5750858301515b600019600386901b1c1916600185901b178555611a94565b600085815260208120601f198616915b8281101561458457888601518255948401946001909101908401614565565b50858210156145a25787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b038316815260406020820181905260009061173490830184613c70565b7f68747470733a2f2f696d6167652d636f636f6e75742e73746f726167652e676f81527f6f676c65617069732e636f6d2f70726f64756374696f6e2f746f6b656e2f6d656020820152667461646174612f60c81b604082015260008351614644816047850160208801613c4c565b605f60f81b6047918401918201528351614665816048840160208801613c4c565b602f60f81b60489290910191820152604901949350505050565b60006020828403121561469157600080fd5b8151611ed181614218565b6020808252602a908201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646040820152692073616c65507269636560b01b606082015260800190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60006001820161475357614753614395565b5060010190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000845160206147bf8285838a01613c4c565b8551918401916147d28184848a01613c4c565b85549201916000906147e381614361565b600182811680156147fb57600181146148105761483c565b60ff198416875282151583028701945061483c565b896000528560002060005b848110156148345781548982015290830190870161481b565b505082870194505b50929a9950505050505050505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614884816017850160208801613c4c565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516148b5816028840160208801613c4c565b01602801949350505050565b6001600160601b03198660601b168152838560148301376014930192830191909152603482015260540192915050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061492490830184613c70565b9695505050505050565b60006020828403121561494057600080fd5b8151611ed181613be7565b60008161495a5761495a614395565b506000190190565b634e487b7160e01b600052602160045260246000fdfe05c0f7ac2b4a836d461d705215d2827b3523466a4e4e877245ccc4028acd195e9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6e6ba96c502ac04a25522516a16b95a29fbe3ca2659625a33d96c64a957a0cc27a26469706673582212202eddbdbd986f790c76c8d8e9591312a809cf0067d1f37370d6fff7e4875486a764736f6c63430008150033
Deployed Bytecode Sourcemap
141024:443:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;140625:260;;;;;;;;;;-1:-1:-1;140625:260:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;140625:260:0;;;;;;;;121835:688;;;;;;;;;;-1:-1:-1;121835:688:0;;;;;:::i;:::-;;:::i;:::-;;;;;;1136:4:1;1178:3;1167:9;1163:19;1155:27;;1215:6;1209:13;1198:9;1191:32;1279:4;1271:6;1267:17;1261:24;1254:4;1243:9;1239:20;1232:54;1342:4;1334:6;1330:17;1324:24;1317:4;1306:9;1302:20;1295:54;1405:4;1397:6;1393:17;1387:24;1380:4;1369:9;1365:20;1358:54;1468:4;1460:6;1456:17;1450:24;1443:4;1432:9;1428:20;1421:54;980:501;;;;;78183:100:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;116965:72::-;;;;;;;;;;;;117008:29;116965:72;;;;;2388:25:1;;;2376:2;2361:18;116965:72:0;2242:177:1;79482:187:0;;;;;;;;;;-1:-1:-1;79482:187:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2773:32:1;;;2755:51;;2743:2;2728:18;79482:187:0;2609:203:1;139392:161:0;;;;;;;;;;-1:-1:-1;139392:161:0;;;;;:::i;:::-;;:::i;:::-;;135037:102;;;;;;;;;;;;;:::i;137858:222::-;;;;;;;;;;-1:-1:-1;137858:222:0;;;;;:::i;:::-;;:::i;121284:114::-;;;;;;;;;;;;;:::i;138454:192::-;;;;;;;;;;-1:-1:-1;138454:192:0;;;;;:::i;:::-;;:::i;135650:270::-;;;;;;;;;;-1:-1:-1;135650:270:0;;;;;:::i;:::-;;:::i;119471:26::-;;;;;;;;;;;;;;;;124261:376;;;;;;:::i;:::-;;:::i;80248:372::-;;;;;;;;;;-1:-1:-1;80248:372:0;;;;;:::i;:::-;;:::i;28292:131::-;;;;;;;;;;-1:-1:-1;28292:131:0;;;;;:::i;:::-;28366:7;28393:12;;;:6;:12;;;;;:22;;;;28292:131;75984:27;;;;;;;;;;;;;;;;135231:149;;;;;;;;;;;;;:::i;119436:28::-;;;;;;;;;;;;;;;;34800:438;;;;;;;;;;-1:-1:-1;34800:438:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;28733:147::-;;;;;;;;;;-1:-1:-1;28733:147:0;;;;;:::i;:::-;;:::i;138709:338::-;;;;;;;;;;-1:-1:-1;138709:338:0;;;;;:::i;:::-;;:::i;124713:324::-;;;;;;;;;;-1:-1:-1;124713:324:0;;;;;:::i;:::-;;:::i;137585:210::-;;;;;;;;;;-1:-1:-1;137585:210:0;;;;;:::i;:::-;;:::i;29877:218::-;;;;;;;;;;-1:-1:-1;29877:218:0;;;;;:::i;:::-;;:::i;135449:86::-;;;;;;;;;;;;;:::i;123156:263::-;;;;;;;;;;-1:-1:-1;123156:263:0;;;;;:::i;:::-;;:::i;80691:185::-;;;;;;;;;;-1:-1:-1;80691:185:0;;;;;:::i;:::-;;:::i;129984:385::-;;;;;;;;;;-1:-1:-1;129984:385:0;;;;;:::i;:::-;;:::i;136407:213::-;;;;;;;;;;-1:-1:-1;136407:213:0;;;;;:::i;:::-;;:::i;119108:35::-;;;;;;;;;;-1:-1:-1;119108:35:0;;;;-1:-1:-1;;;;;119108:35:0;;;130444:110;;;;;;;;;;-1:-1:-1;130444:110:0;;;;;:::i;:::-;;:::i;136695:187::-;;;;;;;;;;-1:-1:-1;136695:187:0;;;;;:::i;:::-;;:::i;136044:300::-;;;;;;;;;;-1:-1:-1;136044:300:0;;;;;:::i;:::-;;:::i;119152:36::-;;;;;;;;;;-1:-1:-1;119152:36:0;;;;-1:-1:-1;;;;;119152:36:0;;;98956:1129;;;;;;;;;;-1:-1:-1;98956:1129:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;112812:472::-;;;;;;;;;;;;;:::i;:::-;;;;;;10649:13:1;;10642:21;10635:29;10617:48;;10735:4;10723:17;;;10717:24;10710:32;10703:40;10681:20;;;10674:70;10814:4;10802:17;;;10796:24;10789:32;10782:40;10760:20;;;10753:70;10893:4;10881:17;;;10875:24;10868:32;10861:40;10839:20;;;10832:70;;;;10604:3;10589:19;;10416:492;77877:239:0;;;;;;;;;;-1:-1:-1;77877:239:0;;;;;:::i;:::-;;:::i;127104:264::-;;;;;;;;;;-1:-1:-1;127104:264:0;;;;;:::i;:::-;;:::i;123513:221::-;;;;;;;;;;-1:-1:-1;123513:221:0;;;;;:::i;:::-;;:::i;133615:527::-;;;;;;;;;;;;;:::i;77675:140::-;;;;;;;;;;-1:-1:-1;77675:140:0;;;;;:::i;:::-;;:::i;101141:344::-;;;;;;;;;;-1:-1:-1;101141:344:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;127551:409::-;;;;;;:::i;:::-;;:::i;119248:26::-;;;;;;;;;;-1:-1:-1;119248:26:0;;;;-1:-1:-1;;;119248:26:0;;;;;;26765:147;;;;;;;;;;-1:-1:-1;26765:147:0;;;;;:::i;:::-;;:::i;128092:305::-;;;;;;;;;;-1:-1:-1;128092:305:0;;;;;:::i;:::-;;:::i;139111:219::-;;;;;;;;;;-1:-1:-1;139111:219:0;;;;;:::i;:::-;;:::i;78352:104::-;;;;;;;;;;;;;:::i;100472:223::-;;;;;;;;;;-1:-1:-1;100472:223:0;;;;;:::i;:::-;;:::i;137286:238::-;;;;;;;;;;-1:-1:-1;137286:238:0;;;;;:::i;:::-;;:::i;136967:247::-;;;;;;;;;;-1:-1:-1;136967:247:0;;;;;:::i;:::-;;:::i;138149:246::-;;;;;;;;;;-1:-1:-1;138149:246:0;;;;;:::i;:::-;;:::i;129244:685::-;;;;;;;;;;-1:-1:-1;129244:685:0;;;;;:::i;:::-;;:::i;25870:49::-;;;;;;;;;;-1:-1:-1;25870:49:0;25915:4;25870:49;;139625:464;;;;;;;;;;-1:-1:-1;139625:464:0;;;;;:::i;:::-;;:::i;121479:99::-;;;;;;;;;;-1:-1:-1;121558:12:0;;121479:99;;134664:106;;;;;;;;;;;;;:::i;126057:912::-;;;;;;:::i;:::-;;:::i;80947:359::-;;;;;;;;;;-1:-1:-1;80947:359:0;;;;;:::i;:::-;;:::i;134851:108::-;;;;;;;;;;;;;:::i;98618:180::-;;;;;;;;;;-1:-1:-1;98618:180:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;125101:895::-;;;;;;:::i;:::-;;:::i;78527:182::-;;;;;;;;;;-1:-1:-1;78527:182:0;;;;;:::i;:::-;;:::i;116815:62::-;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;116815:62:0;;29173:149;;;;;;;;;;-1:-1:-1;29173:149:0;;;;;:::i;:::-;;:::i;119365:33::-;;;;;;;;;;;;;;;;121659:99;;;;;;;;;;-1:-1:-1;121738:12:0;;121659:99;;140160:393;;;;;;;;;;-1:-1:-1;140160:393:0;;;;;:::i;:::-;;:::i;123825:294::-;;;;;;;;;;-1:-1:-1;123825:294:0;;;;;:::i;:::-;;:::i;119405:24::-;;;;;;;;;;;;;;;;128502:640;;;;;;;;;;-1:-1:-1;128502:640:0;;;;;:::i;:::-;;:::i;116884:74::-;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;116884:74:0;;140625:260;140812:4;140841:36;140865:11;140841:23;:36::i;:::-;140834:43;140625:260;-1:-1:-1;;140625:260:0:o;121835:688::-;121919:21;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;121919:21:0;121953:23;121979:22;121994:6;121979:14;:22::i;:::-;122025:8;;;;;122208:307;;;;;;;;122251:12;;122208:307;;122172:2;-1:-1:-1;;;122296:17:0;122208:307;;;;122346:17;;;;122208:307;;;;;;;122094:18;122088:24;;;122208:307;;;;;;;122165:9;;;122208:307;;;;;121835:688;-1:-1:-1;;;121835:688:0:o;78183:100::-;78237:13;78270:5;78263:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78183:100;:::o;79482:187::-;79574:7;79594:23;79609:7;79594:14;:23::i;:::-;-1:-1:-1;79637:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;79637:24:0;;79482:187::o;139392:161::-;139513:32;139527:8;139537:7;139513:13;:32::i;:::-;139392:161;;:::o;135037:102::-;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;135113:18:::1;:16;:18::i;:::-;135037:102:::0;:::o;137858:222::-;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;137975:13:::1;:32:::0;;;138023:49:::1;::::0;::::1;::::0;::::1;::::0;138043:10:::1;::::0;137991:16;;138023:49:::1;:::i;:::-;;;;;;;;137858:222:::0;;:::o;121284:114::-;121336:7;121378:12;;121363;;:27;;;;:::i;:::-;121356:34;;121284:114;:::o;138454:192::-;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;138561:9:::1;:22:::0;;;138599:39:::1;::::0;::::1;::::0;::::1;::::0;138615:10:::1;::::0;138573;;138599:39:::1;:::i;135650:270::-:0;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;135794:42:::1;135813:8;135823:12;135794:18;:42::i;:::-;135852:60;::::0;;135877:10:::1;17123:34:1::0;;-1:-1:-1;;;;;17193:15:1;;17188:2;17173:18;;17166:43;-1:-1:-1;;;;;17245:39:1;;17225:18;;;17218:67;135852:60:0;;::::1;::::0;;;;17073:2:1;135852:60:0;;::::1;135650:270:::0;;;:::o;124261:376::-;124395:46;124411:10;124423:8;124433:1;124436:4;124395:15;:46::i;:::-;124458:9;:13;124454:176;;124507:13;;:40;;124489:12;;-1:-1:-1;;;;;124507:13:0;;124533:9;;124489:12;124507:40;124489:12;124507:40;124533:9;124507:13;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;124488:59;;;124567:7;124562:56;;124576:42;-1:-1:-1;;;124576:19:0;:42::i;:::-;124473:157;124261:376;;:::o;80248:372::-;80457:41;4027:10;80476:12;80490:7;80457:18;:41::i;:::-;80435:136;;;;-1:-1:-1;;;80435:136:0;;;;;;;:::i;:::-;;;;;;;;;80584:28;80594:4;80600:2;80604:7;80584:9;:28::i;135231:149::-;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;135342:30:::1;:28;:30::i;34800:438::-:0;34895:7;34953:26;;;:17;:26;;;;;;;;34924:55;;;;;;;;;-1:-1:-1;;;;;34924:55:0;;;;;-1:-1:-1;;;34924:55:0;;;-1:-1:-1;;;;;34924:55:0;;;;;;;;34895:7;;34992:92;;-1:-1:-1;35043:29:0;;;;;;;;;35053:19;35043:29;-1:-1:-1;;;;;35043:29:0;;;;-1:-1:-1;;;35043:29:0;;-1:-1:-1;;;;;35043:29:0;;;;;34992:92;35133:23;;;;35096:21;;35604:5;;35121:35;;-1:-1:-1;;;;;35121:35:0;:9;:35;:::i;:::-;35120:57;;;;:::i;:::-;35198:16;;;-1:-1:-1;35096:81:0;;-1:-1:-1;;34800:438:0;;;;;;:::o;28733:147::-;28366:7;28393:12;;;:6;:12;;;;;:22;;;26361:16;26372:4;26361:10;:16::i;:::-;28847:25:::1;28858:4;28864:7;28847:10;:25::i;138709:338::-:0;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;-1:-1:-1;;;;;138838:32:0;::::1;138834:97;;138885:46;-1:-1:-1::0;;;138885:19:0::1;:46::i;:::-;138942:13;:32:::0;;-1:-1:-1;;;;;;138942:32:0::1;-1:-1:-1::0;;;;;138942:32:0;::::1;::::0;;::::1;::::0;;;138990:49:::1;::::0;;139010:10:::1;18667:34:1::0;;18732:2;18717:18;;18710:43;;;;138990:49:0::1;::::0;18602:18:1;138990:49:0::1;18447:312:1::0;124713:324:0;124813:4;114975;114956:16;;;;:23;;114955:30;;124886:31;;-1:-1:-1;124912:5:0;;124713:324;-1:-1:-1;;124713:324:0:o;124886:31::-;124928:18;124959:24;;;;:10;:24;:::i;:::-;124949:35;;;;;;;:::i;:::-;;;;;;;;;;;125002:27;;;;:15;:27;;;;;;;124713:324;-1:-1:-1;;;;124713:324:0:o;137585:210::-;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;137698:11:::1;:28:::0;;;137742:45:::1;::::0;::::1;::::0;::::1;::::0;137760:10:::1;::::0;137712:14;;137742:45:::1;:::i;29877:218::-:0;-1:-1:-1;;;;;29973:23:0;;4027:10;29973:23;29965:83;;;;-1:-1:-1;;;29965:83:0;;19768:2:1;29965:83:0;;;19750:21:1;19807:2;19787:18;;;19780:30;19846:34;19826:18;;;19819:62;-1:-1:-1;;;19897:18:1;;;19890:45;19952:19;;29965:83:0;19566:411:1;29965:83:0;30061:26;30073:4;30079:7;30061:11;:26::i;135449:86::-;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;135517:10:::1;:8;:10::i;123156:263::-:0;-1:-1:-1;;;;;;;;;;;26361:16:0;26372:4;26361:10;:16::i;:::-;123279:1:::1;121021:11;;121010:8;120994:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:38;120990:109;;;121047:52;-1:-1:-1::0;;;121047:19:0::1;:52::i;:::-;123318:12:::2;:17:::0;;123334:1:::2;123318:17:::0;;::::2;::::0;;;123350:12:::2;:17:::0;;;;::::2;::::0;;123389:22:::2;123399:2:::0;123403:7;123389:9:::2;:22::i;:::-;26388:1:::1;123156:263:::0;;;:::o;80691:185::-;80829:39;80846:4;80852:2;80856:7;80829:39;;;;;;;;;;;;:16;:39::i;129984:385::-;130046:14;;-1:-1:-1;;;130046:14:0;;;;130041:70;;130062:49;-1:-1:-1;;;130062:19:0;:49::i;:::-;130122:23;130137:7;130122:14;:23::i;:::-;130161:41;4027:10;130180:12;3947:98;130161:41;130156:114;;130217:53;-1:-1:-1;;;130217:19:0;:53::i;:::-;130281:14;130287:7;130281:5;:14::i;:::-;130322:1;130306:12;;:17;;;;;;;:::i;:::-;;;;-1:-1:-1;;37218:26:0;;;;:17;:26;;;;;37211:33;135037:102::o;136407:213::-;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;136520:31:::1;136537:13;77001:12:::0;:30;76922:117;136520:31:::1;136567:45;136586:10;136598:13;136567:45;;;;;;;:::i;130444:110::-:0;130506:4;130530:16;130538:7;130530;:16::i;136695:187::-;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;136804:8:::1;:19;136815:8:::0;136804;:19:::1;:::i;:::-;;136839:35;136853:10;136865:8;136839:35;;;;;;;:::i;136044:300::-:0;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;136208:49:::1;136225:7;136234:8;136244:12;136208:16;:49::i;:::-;136273:63;::::0;;136292:10:::1;22905:34:1::0;;22970:2;22955:18;;22948:34;;;-1:-1:-1;;;;;23018:15:1;;22998:18;;;22991:43;-1:-1:-1;;;;;23070:39:1;;23065:2;23050:18;;23043:67;136273:63:0;;::::1;::::0;;;;22854:3:1;136273:63:0;;::::1;136044:300:::0;;;;:::o;98956:1129::-;99280:4;99274:11;;99333:21;;;99485:1;99481:9;;;99540:29;;;99560:4;99540:29;99527:43;;;99071:23;;99591:459;99598:6;;99591:459;;-1:-1:-1;;99684:12:0;;;;99738:23;;;99725:37;99621:15;99825:28;99725:37;99825:19;:28::i;:::-;99983:29;;;100003:4;99983:29;99976:48;-1:-1:-1;99591:459:0;;-1:-1:-1;99591:459:0;;-1:-1:-1;100067:10:0;98956:1129;-1:-1:-1;;;98956:1129:0:o;112812:472::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;112903:373:0;;;;;;;;112946:16;;110686:1;112946:31;;;:47;112903:373;;110737:6;113029:34;;;:74;112903:373;;;;110790:6;113136:31;;;:47;112903:373;;;;;;;110842:6;113215:30;;;:45;;;112903:373;;;;;112812:472::o;77877:239::-;77965:7;77985:13;78001:17;78010:7;78001:8;:17::i;:::-;77985:33;-1:-1:-1;;;;;;78037:19:0;;78029:56;;;;-1:-1:-1;;;78029:56:0;;23323:2:1;78029:56:0;;;23305:21:1;23362:2;23342:18;;;23335:30;-1:-1:-1;;;23381:18:1;;;23374:54;23445:18;;78029:56:0;23121:348:1;127104:264:0;-1:-1:-1;;;;;;;;;;;26361:16:0;26372:4;26361:10;:16::i;:::-;127296:8:::1;:15;121021:11;;121010:8;120994:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:38;120990:109;;;121047:52;-1:-1:-1::0;;;121047:19:0::1;:52::i;:::-;127329:31:::2;127340:9;127351:8;127329:10;:31::i;123513:221::-:0;-1:-1:-1;;;;;;;;;;;26361:16:0;26372:4;26361:10;:16::i;133615:527::-;133663:13;133718:1;133699:8;133693:22;;;;;:::i;:::-;;;:26;133689:446;;;133743:8;133736:15;;;;;:::i;133689:446::-;133980:6;:4;:6::i;:::-;134043:8;:6;:8::i;:::-;133837:267;;;;;;;;;:::i;:::-;;;;;;;;;;;;;133784:339;;133615:527;:::o;77675:140::-;77763:7;77790:17;77801:5;77790:10;:17::i;101141:344::-;77192:18;;101235:16;;76851:1;;101264:13;;101321:17;;101337:1;101321:17;:::i;:::-;101306:32;;101349:25;101398:4;101389:5;:13;101385:66;;101415:36;101432:5;101439;101446:4;101415:16;:36::i;:::-;101404:47;;101385:66;101469:8;101141:344;-1:-1:-1;;;;101141:344:0:o;127551:409::-;-1:-1:-1;;;;;;;;;;;26361:16:0;26372:4;26361:10;:16::i;:::-;127718:46:::1;127734:10;127746:8;127756:1;127759:4;127718:15;:46::i;:::-;127781:9;:13:::0;127777:176:::1;;127830:13;::::0;:40:::1;::::0;127812:12:::1;::::0;-1:-1:-1;;;;;127830:13:0::1;::::0;127856:9:::1;::::0;127812:12;127830:40;127812:12;127830:40;127856:9;127830:13;:40:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;127811:59;;;127890:7;127885:56;;127899:42;-1:-1:-1::0;;;127899:19:0::1;:42::i;26765:147::-:0;26851:4;26875:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;26875:29:0;;;;;;;;;;;;;;;26765:147::o;128092:305::-;-1:-1:-1;;;;;;;;;;;26361:16:0;26372:4;26361:10;:16::i;:::-;128233:8:::1;121021:11;;121010:8;120994:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:38;120990:109;;;121047:52;-1:-1:-1::0;;;121047:19:0::1;:52::i;:::-;128279:12:::2;:24:::0;;;::::2;::::0;;128318:12:::2;:24:::0;;;::::2;::::0;;128364:25:::2;128376:2:::0;128295:8;128364:11:::2;:25::i;139111:219::-:0;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;139225:14:::1;:32:::0;;-1:-1:-1;;;;139225:32:0::1;-1:-1:-1::0;;;139225:32:0;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;;139273:49:::1;::::0;;139294:10:::1;24708:51:1::0;;24790:2;24775:18;;24768:50;;;;139273:49:0::1;::::0;24681:18:1;139273:49:0::1;24540:284:1::0;78352:104:0;78408:13;78441:7;78434:14;;;;;:::i;100472:223::-;100615:16;100651:36;100668:5;100675;100682:4;100651:16;:36::i;137286:238::-;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;137403:13:::1;:48:::0;;-1:-1:-1;;;;;;137403:48:0::1;-1:-1:-1::0;;;;;137403:48:0;::::1;::::0;;::::1;::::0;;;137467:49:::1;::::0;;137487:10:::1;18667:34:1::0;;18732:2;18717:18;;18710:43;;;;137467:49:0::1;::::0;18602:18:1;137467:49:0::1;18447:312:1::0;136967:247:0;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;137096:18:::1;:39;137117:18:::0;137096;:39:::1;:::i;:::-;;137151:55;137175:10;137187:18;137151:55;;;;;;;:::i;138149:246::-:0;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;138274:18:::1;:40:::0;;;138330:57:::1;::::0;::::1;::::0;::::1;::::0;138355:10:::1;::::0;138295:19;;138330:57:::1;:::i;129244:685::-:0;-1:-1:-1;;;;;;;;;;;26361:16:0;26372:4;26361:10;:16::i;:::-;129416:8:::1;121021:11;;121010:8;120994:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:38;120990:109;;;121047:52;-1:-1:-1::0;;;121047:19:0::1;:52::i;:::-;110790:6:::2;::::0;111316:16:::2;;:31;111315:49;111309:140;;111382:55;-1:-1:-1::0;;;111382:19:0::2;:55::i;:::-;129472:10:::3;129485:11;129493:2;129485:7;:11::i;:::-;129560:13;::::0;129472:24;;-1:-1:-1;129535:9:0;129542:2:::3;129535:9:::0;;;;;129560:17;;;;:57:::3;;-1:-1:-1::0;129604:13:0::3;::::0;129581:20:::3;129593:8:::0;129581:9;:20:::3;:::i;:::-;:36;129560:57;129556:130;;;129632:54;-1:-1:-1::0;;;129632:19:0::3;:54::i;:::-;129760:12;:24:::0;;;::::3;::::0;;129799:12:::3;:24:::0;;;::::3;::::0;;129724:21;::::3;129845:38;129869:2:::0;129724:21;129845:23:::3;:38::i;:::-;129896:25;129908:2;129912:8;129896:11;:25::i;:::-;129461:468;;26388:1:::1;129244:685:::0;;;:::o;139625:464::-;139762:52;4027:10;139781:12;139795:8;139805;139762:18;:52::i;:::-;139851:13;;-1:-1:-1;;;;;139851:13:0;139843:38;;;;:83;;-1:-1:-1;;;;;;54413:19:0;;;:23;;139898:28;139825:203;;;139953:13;;:63;;-1:-1:-1;;;139953:63:0;;139985:10;139953:63;;;25372:34:1;-1:-1:-1;;;;;25442:15:1;;;25422:18;;;25415:43;25501:14;;25494:22;25474:18;;;25467:50;139953:13:0;;;;:31;;25307:18:1;;139953:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;139825:203;140038:43;140062:8;140072;140038:23;:43::i;134664:106::-;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;134742:20:::1;:18;:20::i;126057:912::-:0;126177:8;121021:11;;121010:8;120994:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:38;120990:109;;;121047:52;-1:-1:-1;;;121047:19:0;:52::i;:::-;110790:6:::1;::::0;111316:16:::1;;:31;111315:49;111309:140;;111382:55;-1:-1:-1::0;;;111382:19:0::1;:55::i;:::-;126219:10:::2;126232:11;126240:2;126232:7;:11::i;:::-;126307:13;::::0;126219:24;;-1:-1:-1;126282:9:0;126289:2:::2;126282:9:::0;;;;;126307:17;;;;:57:::2;;-1:-1:-1::0;126351:13:0::2;::::0;126328:20:::2;126340:8:::0;126328:9;:20:::2;:::i;:::-;:36;126307:57;126303:130;;;126379:54;-1:-1:-1::0;;;126379:19:0::2;:54::i;:::-;126474:8;126462:9;;:20;;;;:::i;:::-;126448:9;:35;126444:94;;126498:40;-1:-1:-1::0;;;126498:19:0::2;:40::i;:::-;126612:12;:24:::0;;;::::2;::::0;;126651:12:::2;:24:::0;;;::::2;::::0;;126576:21;::::2;126697:38;126721:2:::0;126576:21;126697:23:::2;:38::i;:::-;126748:25;126760:2;126764:8;126748:11;:25::i;:::-;126790:9;:13:::0;126786:176:::2;;126839:13;::::0;:40:::2;::::0;126821:12:::2;::::0;-1:-1:-1;;;;;126839:13:0::2;::::0;126865:9:::2;::::0;126821:12;126839:40;126821:12;126839:40;126865:9;126839:13;:40:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;126820:59;;;126899:7;126894:56;;126908:42;-1:-1:-1::0;;;126908:19:0::2;:42::i;126786:176::-;126208:761;;126057:912:::0;;;:::o;80947:359::-;81135:41;4027:10;81168:7;81135:18;:41::i;:::-;81113:136;;;;-1:-1:-1;;;81113:136:0;;;;;;;:::i;:::-;81260:38;81274:4;81280:2;81284:7;81293:4;81260:13;:38::i;134851:108::-;25915:4;26361:16;25915:4;26361:10;:16::i;:::-;134930:21:::1;:19;:21::i;98618:180::-:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98769:21:0;98782:7;98769:12;:21::i;125101:895::-;125278:8;121021:11;;121010:8;120994:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:38;120990:109;;;121047:52;-1:-1:-1;;;121047:19:0;:52::i;:::-;110737:6:::1;::::0;111098:16:::1;;:34;111097:55;111091:148;;111170:57;-1:-1:-1::0;;;111170:19:0::1;:57::i;:::-;125337:10:::2;125350:28;125358:19;::::0;;;::::2;::::0;::::2;;:::i;:::-;125350:7;:28::i;:::-;125337:41:::0;-1:-1:-1;125423:18:0::2;125417:24:::0;::::2;125482::::0;::::2;125459:20;125471:8:::0;125417:24;125459:20:::2;:::i;:::-;:47;125455:129;;;125521:63;-1:-1:-1::0;;;125521:19:0::2;:63::i;:::-;125622:21:::0;::::2;125665:58;125692:19;::::0;;;::::2;::::0;::::2;;:::i;:::-;125713:9;125665:26;:58::i;:::-;125736:64;125752:10;125764:8;125774:18;;125794:5;125736:15;:64::i;78527:182::-:0;78616:13;78642:23;78657:7;78642:14;:23::i;:::-;78683:18;78693:7;78683:9;:18::i;29173:149::-;28366:7;28393:12;;;:6;:12;;;;;:22;;;26361:16;26372:4;26361:10;:16::i;:::-;29288:26:::1;29300:4;29306:7;29288:11;:26::i;140160:393::-:0;-1:-1:-1;;;;;80138:25:0;;;140300:4;80138:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;140396:13;;140300:4;;80138:35;;;;;140396:13;140388:38;140384:136;;140450:13;;:58;;-1:-1:-1;;;140450:58:0;;-1:-1:-1;;;;;25390:15:1;;;140450:58:0;;;25372:34:1;25442:15;;;25422:18;;;25415:43;25501:14;;25494:22;25474:18;;;25467:50;140450:13:0;;;;:30;;25307:18:1;;140450:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;140443:65;;;;;140384:136;140537:8;140160:393;-1:-1:-1;;;140160:393:0:o;123825:294::-;-1:-1:-1;;;;;;;;;;;26361:16:0;26372:4;26361:10;:16::i;128502:640::-;-1:-1:-1;;;;;;;;;;;26361:16:0;26372:4;26361:10;:16::i;:::-;110737:6:::1;::::0;111098:16:::1;;:34;111097:55;111091:148;;111170:57;-1:-1:-1::0;;;111170:19:0::1;:57::i;:::-;128688:10:::2;128701:28;128709:19;::::0;;;::::2;::::0;::::2;;:::i;128701:28::-;128688:41:::0;-1:-1:-1;128774:18:0::2;128768:24:::0;::::2;128833::::0;::::2;128810:20;128822:8:::0;128768:24;128810:20:::2;:::i;:::-;:47;128806:129;;;128872:63;-1:-1:-1::0;;;128872:19:0::2;:63::i;:::-;128973:21:::0;::::2;129016:58;129043:19;::::0;;;::::2;::::0;::::2;;:::i;129016:58::-;129087:47;129103:10;129115:8;129125:1;129128:5:::0;129087:15:::2;:47::i;26469:204::-:0;26554:4;-1:-1:-1;;;;;;26578:47:0;;-1:-1:-1;;;26578:47:0;;:87;;;26629:36;26653:11;26629:23;:36::i;65687:569::-;65765:18;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65765:18:0;-1:-1:-1;;;;;;65813:25:0;65796:14;65813:25;;;:18;:25;;;;;;;;;;65869:379;;;;;;;;-1:-1:-1;;;;;65909:36:0;;;65869:379;;65979:31;;;65978:84;;65869:379;;;;;;;66096:31;;;66095:84;;;65869:379;;;;;;;65064:3;66210:21;;;;65869:379;;;;;65687:569::o;91376:135::-;91458:16;91466:7;91458;:16::i;:::-;91450:53;;;;-1:-1:-1;;;91450:53:0;;23323:2:1;91450:53:0;;;23305:21:1;23362:2;23342:18;;;23335:30;-1:-1:-1;;;23381:18:1;;;23374:54;23445:18;;91450:53:0;23121:348:1;79000:416:0;79081:13;79097:23;79112:7;79097:14;:23::i;:::-;79081:39;;79145:5;-1:-1:-1;;;;;79139:11:0;:2;-1:-1:-1;;;;;79139:11:0;;79131:57;;;;-1:-1:-1;;;79131:57:0;;25980:2:1;79131:57:0;;;25962:21:1;26019:2;25999:18;;;25992:30;26058:34;26038:18;;;26031:62;-1:-1:-1;;;26109:18:1;;;26102:31;26150:19;;79131:57:0;25778:397:1;79131:57:0;4027:10;-1:-1:-1;;;;;79223:21:0;;;;:62;;-1:-1:-1;79248:37:0;79265:5;4027:10;140160:393;:::i;79248:37::-;79201:173;;;;-1:-1:-1;;;79201:173:0;;26382:2:1;79201:173:0;;;26364:21:1;26421:2;26401:18;;;26394:30;26460:34;26440:18;;;26433:62;26531:31;26511:18;;;26504:59;26580:19;;79201:173:0;26180:425:1;79201:173:0;79387:21;79396:2;79400:7;79387:8;:21::i;27216:105::-;27283:30;27294:4;4027:10;27283;:30::i;112099:148::-;110790:6;112147:16;:31;;;112194:45;;-1:-1:-1;;;;;;;;;;;112194:45:0;;;112210:10;;110790:6;112194:45;:::i;:::-;;;;;;;;112099:148::o;35888:332::-;35604:5;-1:-1:-1;;;;;35991:33:0;;;;35983:88;;;;-1:-1:-1;;;35983:88:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;36090:22:0;;36082:60;;;;-1:-1:-1;;;36082:60:0;;27223:2:1;36082:60:0;;;27205:21:1;27262:2;27242:18;;;27235:30;27301:27;27281:18;;;27274:55;27346:18;;36082:60:0;27021:349:1;36082:60:0;36177:35;;;;;;;;;-1:-1:-1;;;;;36177:35:0;;;;;;-1:-1:-1;;;;;36177:35:0;;;;;;;;;;-1:-1:-1;;;36155:57:0;;;;:19;:57;35888:332::o;131393:2214::-;131584:12;:58;;;;;131601:41;131630:11;:9;:11::i;:::-;131601:10;;:28;:41::i;:::-;131600:42;131584:58;131580:130;;;131657:53;-1:-1:-1;;;131657:19:0;:53::i;:::-;114975:4;114956:16;;;;:23;;114955:30;131723:17;131808:210;;;;131864:24;;;;:10;:24;:::i;:::-;131854:35;;;;;;;:::i;:::-;;;;;;;;;;;131908:27;;;;:15;:27;;;;;;;131854:35;;-1:-1:-1;131908:27:0;;131904:102;;;131954:52;-1:-1:-1;;;131954:19:0;:52::i;:::-;132031:16;132049:15;132068:27;:10;:25;:27::i;:::-;132030:65;;;;132120:11;:27;;;;;132135:12;132120:27;132106:41;;132162:11;132158:56;;;132201:1;132190:12;;132158:56;132255:11;;132244:8;132228:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:38;132224:109;;;132281:52;-1:-1:-1;;;132281:19:0;:52::i;:::-;132351:11;132350:12;:51;;;;-1:-1:-1;132377:24:0;;132366:35;;132350:51;132346:124;;;132416:54;-1:-1:-1;;;132416:19:0;:54::i;:::-;132487:12;132483:278;;;132517:14;132533;132551:25;:10;:23;:25::i;:::-;132516:60;;;;132596:9;132591:159;;132626:53;-1:-1:-1;;;132626:19:0;:53::i;:::-;132591:159;;;132728:6;132720:14;;132591:159;132501:260;;132483:278;132791:16;132799:8;132791:5;:16;:::i;:::-;132777:9;:31;132773:90;;132823:40;-1:-1:-1;;;132823:19:0;:40::i;:::-;132877:18;132897;132919:82;132949:16;132980:10;132919:15;:82::i;:::-;132876:125;;;;133019:37;117008:29;133045:10;133019:7;:37::i;:::-;133014:102;;133071:45;-1:-1:-1;;;133071:19:0;:45::i;:::-;133145:21;;;;;;;;:::i;:::-;-1:-1:-1;;;;;133131:35:0;:10;-1:-1:-1;;;;;133131:35:0;;133127:99;;133181:45;-1:-1:-1;;;133181:19:0;:45::i;:::-;133264:12;:24;;;;;;133303:12;:24;;;;;;133351:79;;;;133384:27;;;;:15;:27;;;;;:34;;-1:-1:-1;;133384:34:0;133414:4;133384:34;;;133351:79;133446:11;133442:158;;;133474:39;133484:19;;;;;;;;:::i;:::-;133505:7;133474:9;:39::i;:::-;133442:158;;;133546:42;133558:19;;;;;;;;:::i;:::-;133579:8;133546:11;:42::i;:::-;131569:2038;;;;;;131393:2214;;;;:::o;64212:170::-;64318:13;64312:4;64305:27;64359:4;64353;64346:18;83474:315;83592:4;83609:13;83625:23;83640:7;83625:14;:23::i;:::-;83609:39;;83678:5;-1:-1:-1;;;;;83667:16:0;:7;-1:-1:-1;;;;;83667:16:0;;:65;;;;83700:32;83717:5;83724:7;83700:16;:32::i;:::-;83667:113;;;;83773:7;-1:-1:-1;;;;;83749:31:0;:20;83761:7;83749:11;:20::i;:::-;-1:-1:-1;;;;;83749:31:0;;83659:122;83474:315;-1:-1:-1;;;;83474:315:0:o;89094:1442::-;89267:4;-1:-1:-1;;;;;89240:31:0;:23;89255:7;89240:14;:23::i;:::-;-1:-1:-1;;;;;89240:31:0;;89218:118;;;;-1:-1:-1;;;89218:118:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;89355:16:0;;89347:65;;;;-1:-1:-1;;;89347:65:0;;27983:2:1;89347:65:0;;;27965:21:1;28022:2;28002:18;;;27995:30;28061:34;28041:18;;;28034:62;-1:-1:-1;;;28112:18:1;;;28105:34;28156:19;;89347:65:0;27781:400:1;89347:65:0;89425:27;89455;89474:7;89455:18;:27::i;:::-;89425:57;;89681:4;-1:-1:-1;;;;;89654:31:0;:23;89669:7;89654:14;:23::i;:::-;-1:-1:-1;;;;;89654:31:0;;89632:118;;;;-1:-1:-1;;;89632:118:0;;;;;;;:::i;:::-;89822:24;;;;:15;:24;;;;;;;;89815:31;;-1:-1:-1;;;;;;89815:31:0;;;-1:-1:-1;;;;;89956:24:0;;;;;;-1:-1:-1;89956:24:0;;;;;;89954:26;;-1:-1:-1;;89954:26:0;;;90025:22;;;;;;;;;90023:24;;;;;;;;90271:26;;;;;;;;;;72853:11;72828:23;72824:41;72776:112;;90271:147;;90447:27;;89822:24;;90025:22;;89956:24;90447:27;;;90487:41;123156:263;112343:178;112422:30;112403:16;:49;;;112468:45;;-1:-1:-1;;;;;;;;;;;112468:45:0;;;112484:10;;112422:30;112468:45;:::i;31474:238::-;31558:22;31566:4;31572:7;31558;:22::i;:::-;31553:152;;31597:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;31597:29:0;;;;;;;;;:36;;-1:-1:-1;;31597:36:0;31629:4;31597:36;;;31680:12;4027:10;;3947:98;31680:12;-1:-1:-1;;;;;31653:40:0;31671:7;-1:-1:-1;;;;;31653:40:0;31665:4;31653:40;;;;;;;;;;31474:238;;:::o;31892:239::-;31976:22;31984:4;31990:7;31976;:22::i;:::-;31972:152;;;32047:5;32015:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;32015:29:0;;;;;;;;;;:37;;-1:-1:-1;;32015:37:0;;;32072:40;4027:10;;32015:12;;32072:40;;32047:5;32072:40;31892:239;;:::o;112602:139::-;110842:6;112642:16;:30;;;112688:45;;-1:-1:-1;;;;;;;;;;;112688:45:0;;;112704:10;;110842:6;112688:45;:::i;84131:110::-;84207:26;84217:2;84221:7;84207:26;;;;;;;;;;;;:9;:26::i;87386:1371::-;87446:27;87476;87495:7;87476:18;:27::i;:::-;87446:57;-1:-1:-1;87446:57:0;87744:23;87759:7;87744:14;:23::i;:::-;87815:24;;;;:15;:24;;;;;;;;87808:31;;-1:-1:-1;;;;;;87808:31:0;;;-1:-1:-1;;;;;88171:25:0;;;;;-1:-1:-1;88171:25:0;;;;;:61;;88200:32;88171:61;;;88423:26;;;;;;;;;;-1:-1:-1;;;72853:11:0;72828:23;72824:41;72776:112;;;88423:198;;88650:36;88171:25;;-1:-1:-1;87815:24:0;;88650:36;;87815:24;;88650:36;124473:157;124261:376;;:::o;83110:197::-;83175:4;83209:26;;;;;;;;;;;83253:11;;;;;:46;;-1:-1:-1;;;;83269:24:0;83268:31;;83246:53;-1:-1:-1;;83110:197:0:o;36671:356::-;35604:5;-1:-1:-1;;;;;36789:33:0;;;;36781:88;;;;-1:-1:-1;;;36781:88:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;36888:22:0;;36880:62;;;;-1:-1:-1;;;36880:62:0;;28388:2:1;36880:62:0;;;28370:21:1;28427:2;28407:18;;;28400:30;28466:29;28446:18;;;28439:57;28513:18;;36880:62:0;28186:351:1;36880:62:0;36984:35;;;;;;;;-1:-1:-1;;;;;36984:35:0;;;;;-1:-1:-1;;;;;36984:35:0;;;;;;;;;;-1:-1:-1;36955:26:0;;;:17;:26;;;;;;:64;;;;;;;-1:-1:-1;;;36955:64:0;;;;;;36671:356::o;82651:146::-;82717:7;82760:27;82779:7;82760:18;:27::i;130849:487::-;131001:8;:15;130981:9;:16;:35;130977:103;;131031:49;-1:-1:-1;;;131031:19:0;:49::i;:::-;131134:15;;131118:12;:31;;;;;;131164:12;:31;;;;;;;131118:12;131219:110;131243:9;:16;131239:1;:20;131219:110;;;131281:36;131291:9;131301:1;131291:12;;;;;;;;:::i;:::-;;;;;;;131305:8;131314:1;131305:11;;;;;;;;:::i;:::-;;;;;;;131281:9;:36::i;:::-;131261:3;;;;:::i;:::-;;;;131219:110;;66346:253;66404:7;-1:-1:-1;;;;;66428:19:0;;66424:94;;66462:56;-1:-1:-1;;;66462:19:0;:56::i;:::-;-1:-1:-1;;;;;;66536:25:0;;;;;:18;:25;;;;;;-1:-1:-1;;;;;66536:55:0;;66346:253::o;101741:4754::-;101867:16;101934:4;101925:5;:13;101921:66;;101940:47;-1:-1:-1;;;101940:19:0;:47::i;:::-;76851:1;102065:5;:23;102061:87;;;76851:1;102109:23;;102061:87;102162:17;102182:13;77192:18;;;77111:107;102182:13;102198:1;102182:17;102162:37;;102277:9;102269:4;:17;102265:74;;102314:9;102307:16;;102265:74;102353:25;102393;102421:16;102431:5;102421:9;:16::i;:::-;102471:12;;;102631:35;;;;-1:-1:-1;102699:22:0;;102695:3752;;102921:17;102912:5;102905:4;:12;:33;102901:114;;102990:5;102983:4;:12;102963:32;;102901:114;103137:4;103131:11;103119:23;;103441:1;103422:17;103418:25;103415:1;103411:33;103401:8;103397:48;103366:4;103333:135;103643:31;103677:26;103697:5;103677:19;:26::i;:::-;103643:60;;103722:25;104019:9;:16;;;104014:100;;-1:-1:-1;104080:14:0;;104014:100;104132:19;104322:1961;104360:19;104373:5;104360:12;:19::i;:::-;104406:14;;104348:31;;-1:-1:-1;;;;;;104406:28:0;104402:186;;104522:7;;;;;104556:8;;104402:186;104674:4;104659:20;;104653:27;104766:1016;;;;106103:1;106082:22;;104646:1485;;104766:1016;105049:9;105043:16;105040:123;;;105122:9;105116:16;105095:37;;105040:123;105454:5;105435:17;105431:29;105427:2;105423:38;105413:342;;105530:1;105517:11;105513:19;105498:34;;105684:5;105632:11;105629:1;105625:19;105615:8;105611:34;105566:158;105413:342;104646:1485;106177:1;106170:5;106166:13;106157:22;;104322:1961;106240:4;106231:5;:13;:49;;;;106263:17;106248:11;:32;106231:49;106229:52;104322:1961;;106384:29;;-1:-1:-1;;102695:3752:0;-1:-1:-1;106468:8:0;;101741:4754;-1:-1:-1;;;;;;101741:4754:0:o;86545:502::-;86643:1;86632:8;:12;86624:50;;;;-1:-1:-1;;;86624:50:0;;29016:2:1;86624:50:0;;;28998:21:1;29055:2;29035:18;;;29028:30;29094:27;29074:18;;;29067:55;29139:18;;86624:50:0;28814:349:1;86624:50:0;86731:12;;86685:13;;86756:251;86771:8;86763:5;:16;86756:251;;;86796:69;86803:16;86811:7;86803;:16::i;:::-;86796:69;;;86840:9;;;;:::i;:::-;;;;86796:69;;;86879:22;86889:2;86893:7;86879:9;:22::i;:::-;86945:7;;;;;86971:9;86756:251;;;87017:12;:22;-1:-1:-1;;;86545:502:0:o;67305:137::-;-1:-1:-1;;;;;67393:25:0;67360:6;67393:25;;;:18;:25;;;;;;65064:3;67393:40;;67305:137::o;122879:196::-;122963:10;122976:15;122984:6;122976:7;:15::i;:::-;122963:28;;123002:65;123010:6;123041:3;123047:18;123041:24;123034:2;123025:5;:11;;123018:48;123002:7;:65::i;90972:315::-;91127:8;-1:-1:-1;;;;;91118:17:0;:5;-1:-1:-1;;;;;91118:17:0;;91110:55;;;;-1:-1:-1;;;91110:55:0;;29370:2:1;91110:55:0;;;29352:21:1;29409:2;29389:18;;;29382:30;29448:27;29428:18;;;29421:55;29493:18;;91110:55:0;29168:349:1;91110:55:0;-1:-1:-1;;;;;91176:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;91176:46:0;;;;;;;;;;91238:41;;540::1;;;91238::0;;513:18:1;91238:41:0;;;;;;;90972:315;;;:::o;79741:180::-;79861:52;4027:10;79880:12;3947:98;111628:150;110686:1;111678:16;:31;;;111725:45;;-1:-1:-1;;;;;;;;;;;111725:45:0;;;111741:10;;110686:1;111725:45;:::i;82187:350::-;82343:28;82353:4;82359:2;82363:7;82343:9;:28::i;:::-;82404:47;82427:4;82433:2;82437:7;82446:4;82404:22;:47::i;:::-;82382:147;;;;-1:-1:-1;;;82382:147:0;;;;;;;:::i;111863:154::-;110737:6;111914:16;:34;;;111964:45;;-1:-1:-1;;;;;;;;;;;111964:45:0;;;111980:10;;110737:6;111964:45;:::i;70633:177::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70777:24:0;;;;;;;;;;;70758:44;;-1:-1:-1;;;;;;;;;;;;;72042:41:0;;;;68875:3;72128:33;;;-1:-1:-1;;;;;72094:68:0;-1:-1:-1;;;72094:68:0;-1:-1:-1;;;72192:24:0;;:29;;-1:-1:-1;;;72173:48:0;;;;69258:3;72261:28;;;;-1:-1:-1;;;72232:58:0;-1:-1:-1;71915:383:0;122597:211;122709:10;122722:15;122730:6;122722:7;:15::i;:::-;122709:28;-1:-1:-1;122748:52:0;122756:6;122765:17;;;122764:35;;122748:7;:52::i;134213:379::-;134305:13;134331:22;134356:9;:7;:9::i;:::-;134331:34;;134460:8;134491:18;:7;:16;:18::i;:::-;134532;134421:148;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;134376:208;;;134213:379;;;:::o;34530:215::-;34632:4;-1:-1:-1;;;;;;34656:41:0;;-1:-1:-1;;;34656:41:0;;:81;;;34701:36;34725:11;34701:23;:36::i;90655:174::-;90730:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;90730:29:0;-1:-1:-1;;;;;90730:29:0;;;;;;;;:24;;90784:23;90730:24;90784:14;:23::i;:::-;-1:-1:-1;;;;;90775:46:0;;;;;;;;;;;90655:174;;:::o;27611:492::-;27700:22;27708:4;27714:7;27700;:22::i;:::-;27695:401;;27888:28;27908:7;27888:19;:28::i;:::-;27989:38;28017:4;28024:2;27989:19;:38::i;:::-;27793:257;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;27793:257:0;;;;;;;;;;-1:-1:-1;;;27739:345:0;;;;;;;:::i;115556:684::-;115784:22;;115698:4;;115765;115740:16;;;;115760:1;115740:21;115739:30;;115784:53;;;;;115811:13;115827:4;115811:20;115836:1;115810:27;115784:53;115780:453;;;115861:4;115854:11;;;;;115780:453;115887:9;:25;;;:56;;;;;115917:13;115933:4;115917:20;115942:1;115916:27;115887:56;115883:350;;;115967:4;115960:11;;;;;115883:350;115993:9;:22;;;:53;;;;;116020:13;116036:4;116020:20;116045:1;116019:27;115993:53;115989:244;;;116070:4;116063:11;;;;;115989:244;116096:9;:21;;;:52;;;;;116122:13;116138:4;116122:20;116147:1;116121:27;116096:52;116092:141;;;116172:4;116165:11;;;;;116092:141;116216:5;116209:12;;;;;115076:389;115178:4;115184:7;115208:10;:16;;;115227:4;115208:23;115235:1;115208:28;115204:254;;-1:-1:-1;115382:4:0;;115322:16;;;;;115342:2;115322:22;115275:13;115321:38;;115076:389;-1:-1:-1;115076:389:0:o;115204:254::-;-1:-1:-1;115437:5:0;;;;-1:-1:-1;115076:389:0;-1:-1:-1;115076:389:0:o;114359:379::-;114459:4;114465:7;114489:10;:16;;;114508:4;114489:23;114516:1;114489:28;114485:246;;-1:-1:-1;114657:4:0;;114599:16;;;;;114619:2;114599:22;114554:13;114598:36;;114359:379;-1:-1:-1;114359:379:0:o;108405:1355::-;108542:7;;;107314:56;108860:21;;;;;;;;:::i;:::-;108927;;;;;;;;:::i;:::-;108910:39;;;;;;;32168:2:1;32164:15;;;;-1:-1:-1;;32160:53:1;32148:66;;32239:2;32230:12;;32019:229;108910:39:0;;;;;;;;;;;;;108900:50;;;;;;108790:175;;;;;;;;;32455:25:1;;;-1:-1:-1;;;;;32516:32:1;;;;32511:2;32496:18;;32489:60;32580:2;32565:18;;32558:34;32443:2;32428:18;;32253:345;108790:175:0;;;;;;;;;;;;;108661:315;;;;;;108633:343;;108987:16;109170:15;109187:17;109141:64;;;;;;;;-1:-1:-1;;;32861:27:1;;32913:1;32904:11;;32897:27;;;;32949:2;32940:12;;32933:28;32986:2;32977:12;;32603:392;109141:64:0;;;;-1:-1:-1;;109141:64:0;;;;;;;;;109006:210;;109141:64;109006:210;;;;;-1:-1:-1;109227:18:0;109248:49;109006:210;109272:24;;;;:10;:24;:::i;:::-;109248:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;109248:13:0;;-1:-1:-1;;;109248:49:0:i;:::-;109227:70;-1:-1:-1;109310:16:0;109329:298;109439:19;;;;;;;;:::i;:::-;109481:15;;;;:10;:15;:::i;:::-;109400:201;;;;;;;109519:24;;;109566:16;;;;;;109400:201;;:::i;:::-;;;;;;;;;;;;;109372:244;;;;;;50795:34;50590:15;50782:48;;;50851:4;50844:18;;;;50903:4;50887:21;;;50521:405;109329:298;109310:317;-1:-1:-1;109638:18:0;109659:49;109310:317;109683:24;;;;:10;:24;:::i;109659:49::-;109729:10;;;;-1:-1:-1;108405:1355:0;;-1:-1:-1;;;;;;;108405:1355:0:o;71458:358::-;71550:14;71586:26;;;;;;;;;;;71627:11;;;;;:46;;-1:-1:-1;;;;71643:24:0;;71642:31;71627:46;71623:65;;;71458:358;;;:::o;71623:65::-;71749:59;-1:-1:-1;;;71749:19:0;:59::i;:::-;71458:358;;;:::o;84468:319::-;84597:18;84603:2;84607:7;84597:5;:18::i;:::-;84648:53;84679:1;84683:2;84687:7;84696:4;84648:22;:53::i;:::-;84626:153;;;;-1:-1:-1;;;84626:153:0;;;;;;;:::i;67630:430::-;-1:-1:-1;;;;;67719:25:0;;;67702:14;67719:25;;;:18;:25;;;;;;;-1:-1:-1;;;;;67932:32:0;65064:3;67982:24;;;;67931:76;;;;68018:34;;67630:430::o;92075:1034::-;92229:4;-1:-1:-1;;;;;92250:13:0;;54413:19;:23;92246:856;;92303:174;;-1:-1:-1;;;92303:174:0;;-1:-1:-1;;;;;92303:36:0;;;;;:174;;4027:10;;92397:4;;92424:7;;92454:4;;92303:174;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;92303:174:0;;;;;;;;-1:-1:-1;;92303:174:0;;;;;;;;;;;;:::i;:::-;;;92282:765;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92660:6;:13;92677:1;92660:18;92656:376;;92703:108;;-1:-1:-1;;;92703:108:0;;;;;;;:::i;92656:376::-;92982:6;92976:13;92967:6;92963:2;92959:15;92952:38;92282:765;-1:-1:-1;;;;;;92541:51:0;-1:-1:-1;;;92541:51:0;;-1:-1:-1;92534:58:0;;92246:856;-1:-1:-1;93086:4:0;92075:1034;;;;;;:::o;21308:716::-;21364:13;21415:14;21432:17;21443:5;21432:10;:17::i;:::-;21452:1;21432:21;21415:38;;21468:20;21502:6;-1:-1:-1;;;;;21491:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21491:18:0;-1:-1:-1;21468:41:0;-1:-1:-1;21633:28:0;;;21649:2;21633:28;21690:288;-1:-1:-1;;21722:5:0;-1:-1:-1;;;21859:2:0;21848:14;;21843:30;21722:5;21830:44;21920:2;21911:11;;;-1:-1:-1;21941:21:0;21690:288;21941:21;-1:-1:-1;21999:6:0;21308:716;-1:-1:-1;;;21308:716:0:o;77290:321::-;77408:4;-1:-1:-1;;;;;;77445:40:0;;-1:-1:-1;;;77445:40:0;;:105;;-1:-1:-1;;;;;;;77502:48:0;;-1:-1:-1;;;77502:48:0;77445:105;:158;;;-1:-1:-1;;;;;;;;;;6164:40:0;;;77567:36;6055:157;23324:151;23382:13;23415:52;-1:-1:-1;;;;;23427:22:0;;21199:2;22720:447;22795:13;22821:19;22853:10;22857:6;22853:1;:10;:::i;:::-;:14;;22866:1;22853:14;:::i;:::-;-1:-1:-1;;;;;22843:25:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22843:25:0;;22821:47;;-1:-1:-1;;;22879:6:0;22886:1;22879:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;22879:15:0;;;;;;;;;-1:-1:-1;;;22905:6:0;22912:1;22905:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;22905:15:0;;;;;;;;-1:-1:-1;22936:9:0;22948:10;22952:6;22948:1;:10;:::i;:::-;:14;;22961:1;22948:14;:::i;:::-;22936:26;;22931:131;22968:1;22964;:5;22931:131;;;-1:-1:-1;;;23012:5:0;23020:3;23012:11;23003:21;;;;;;;:::i;:::-;;;;22991:6;22998:1;22991:9;;;;;;;;:::i;:::-;;;;:33;-1:-1:-1;;;;;22991:33:0;;;;;;;;-1:-1:-1;23049:1:0;23039:11;;;;;22971:3;;;:::i;:::-;;;22931:131;;;-1:-1:-1;23080:10:0;;23072:55;;;;-1:-1:-1;;;23072:55:0;;34594:2:1;23072:55:0;;;34576:21:1;;;34613:18;;;34606:30;34672:34;34652:18;;;34645:62;34724:18;;23072:55:0;34392:356:1;46985:231:0;47063:7;47084:17;47103:18;47125:27;47136:4;47142:9;47125:10;:27::i;:::-;47083:69;;;;47163:18;47175:5;47163:11;:18::i;85123:1331::-;-1:-1:-1;;;;;85203:16:0;;85195:61;;;;-1:-1:-1;;;85195:61:0;;34955:2:1;85195:61:0;;;34937:21:1;;;34974:18;;;34967:30;35033:34;35013:18;;;35006:62;35085:18;;85195:61:0;34753:356:1;85195:61:0;85276:16;85284:7;85276;:16::i;:::-;85275:17;85267:58;;;;-1:-1:-1;;;85267:58:0;;35316:2:1;85267:58:0;;;35298:21:1;35355:2;35335:18;;;35328:30;35394;35374:18;;;35367:58;35442:18;;85267:58:0;35114:352:1;85267:58:0;85485:16;85493:7;85485;:16::i;:::-;85484:17;85476:58;;;;-1:-1:-1;;;85476:58:0;;35316:2:1;85476:58:0;;;35298:21:1;35355:2;35335:18;;;35328:30;35394;35374:18;;;35367:58;35442:18;;85476:58:0;35114:352:1;85476:58:0;-1:-1:-1;;;;;72644:28:0;;72853:11;72828:23;72824:41;72776:112;-1:-1:-1;;;72776:112:0;85798:17;:26;;;;;;;;;;;:161;;;;-1:-1:-1;;;;;86163:22:0;;;;86191:1;86163:22;;;:60;;86190:32;86163:60;;;86261:18;;86251:28;;86247:89;;;86296:18;:28;;;86247:89;86353:33;;86378:7;;-1:-1:-1;;;;;86353:33:0;;;86370:1;;86353:33;;86370:1;;86353:33;139392:161;;:::o;16691:948::-;16744:7;;-1:-1:-1;;;16822:17:0;;16818:106;;-1:-1:-1;;;16860:17:0;;;-1:-1:-1;16906:2:0;16896:12;16818:106;16951:8;16942:5;:17;16938:106;;16989:8;16980:17;;;-1:-1:-1;17026:2:0;17016:12;16938:106;17071:8;17062:5;:17;17058:106;;17109:8;17100:17;;;-1:-1:-1;17146:2:0;17136:12;17058:106;17191:7;17182:5;:16;17178:103;;17228:7;17219:16;;;-1:-1:-1;17264:1:0;17254:11;17178:103;17308:7;17299:5;:16;17295:103;;17345:7;17336:16;;;-1:-1:-1;17381:1:0;17371:11;17295:103;17425:7;17416:5;:16;17412:103;;17462:7;17453:16;;;-1:-1:-1;17498:1:0;17488:11;17412:103;17542:7;17533:5;:16;17529:68;;17580:1;17570:11;17625:6;16691:948;-1:-1:-1;;16691:948:0:o;45436:747::-;45517:7;45526:12;45555:9;:16;45575:2;45555:22;45551:625;;45899:4;45884:20;;45878:27;45949:4;45934:20;;45928:27;46007:4;45992:20;;45986:27;45594:9;45978:36;46050:25;46061:4;45978:36;45878:27;45928;46050:10;:25::i;:::-;46043:32;;;;;;;;;45551:625;-1:-1:-1;46124:1:0;;-1:-1:-1;46128:35:0;46108:56;;43829:521;43907:20;43898:5;:29;;;;;;;;:::i;:::-;;43894:449;;43829:521;:::o;43894:449::-;44005:29;43996:5;:38;;;;;;;;:::i;:::-;;43992:351;;44051:34;;-1:-1:-1;;;44051:34:0;;35805:2:1;44051:34:0;;;35787:21:1;35844:2;35824:18;;;35817:30;35883:26;35863:18;;;35856:54;35927:18;;44051:34:0;35603:348:1;43992:351:0;44116:35;44107:5;:44;;;;;;;;:::i;:::-;;44103:240;;44168:41;;-1:-1:-1;;;44168:41:0;;36158:2:1;44168:41:0;;;36140:21:1;36197:2;36177:18;;;36170:30;36236:33;36216:18;;;36209:61;36287:18;;44168:41:0;35956:355:1;44103:240:0;44240:30;44231:5;:39;;;;;;;;:::i;:::-;;44227:116;;44287:44;;-1:-1:-1;;;44287:44:0;;36518:2:1;44287:44:0;;;36500:21:1;36557:2;36537:18;;;36530:30;36596:34;36576:18;;;36569:62;-1:-1:-1;;;36647:18:1;;;36640:32;36689:19;;44287:44:0;36316:398:1;48369:1477:0;48457:7;;49391:66;49378:79;;49374:163;;;-1:-1:-1;49490:1:0;;-1:-1:-1;49494:30:0;49474:51;;49374:163;49651:24;;;49634:14;49651:24;;;;;;;;;36946:25:1;;;37019:4;37007:17;;36987:18;;;36980:45;;;;37041:18;;;37034:34;;;37084:18;;;37077:34;;;49651:24:0;;36918:19:1;;49651:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;49651:24:0;;-1:-1:-1;;49651:24:0;;;-1:-1:-1;;;;;;;49690:20:0;;49686:103;;49743:1;49747:29;49727:50;;;;;;;49686:103;49809:6;-1:-1:-1;49817:20:0;;-1:-1:-1;48369:1477: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:131::-;-1:-1:-1;;;;;667:31:1;;657:42;;647:70;;713:1;710;703:12;728:247;787:6;840:2;828:9;819:7;815:23;811:32;808:52;;;856:1;853;846:12;808:52;895:9;882:23;914:31;939:5;914:31;:::i;1486:250::-;1571:1;1581:113;1595:6;1592:1;1589:13;1581:113;;;1671:11;;;1665:18;1652:11;;;1645:39;1617:2;1610:10;1581:113;;;-1:-1:-1;;1728:1:1;1710:16;;1703:27;1486:250::o;1741:271::-;1783:3;1821:5;1815:12;1848:6;1843:3;1836:19;1864:76;1933:6;1926:4;1921:3;1917:14;1910:4;1903:5;1899:16;1864:76;:::i;:::-;1994:2;1973:15;-1:-1:-1;;1969:29:1;1960:39;;;;2001:4;1956:50;;1741:271;-1:-1:-1;;1741:271:1:o;2017:220::-;2166:2;2155:9;2148:21;2129:4;2186:45;2227:2;2216:9;2212:18;2204:6;2186:45;:::i;2424:180::-;2483:6;2536:2;2524:9;2515:7;2511:23;2507:32;2504:52;;;2552:1;2549;2542:12;2504:52;-1:-1:-1;2575:23:1;;2424:180;-1:-1:-1;2424:180:1:o;2817:315::-;2885:6;2893;2946:2;2934:9;2925:7;2921:23;2917:32;2914:52;;;2962:1;2959;2952:12;2914:52;3001:9;2988:23;3020:31;3045:5;3020:31;:::i;:::-;3070:5;3122:2;3107:18;;;;3094:32;;-1:-1:-1;;;2817:315:1:o;3319:179::-;3386:20;;-1:-1:-1;;;;;3435:38:1;;3425:49;;3415:77;;3488:1;3485;3478:12;3503:319;3570:6;3578;3631:2;3619:9;3610:7;3606:23;3602:32;3599:52;;;3647:1;3644;3637:12;3599:52;3686:9;3673:23;3705:31;3730:5;3705:31;:::i;:::-;3755:5;-1:-1:-1;3779:37:1;3812:2;3797:18;;3779:37;:::i;:::-;3769:47;;3503:319;;;;;:::o;3827:166::-;3897:5;3942:3;3933:6;3928:3;3924:16;3920:26;3917:46;;;3959:1;3956;3949:12;3917:46;-1:-1:-1;3981:6:1;3827:166;-1:-1:-1;3827:166:1:o;3998:444::-;4103:6;4111;4164:2;4152:9;4143:7;4139:23;4135:32;4132:52;;;4180:1;4177;4170:12;4132:52;4220:9;4207:23;-1:-1:-1;;;;;4245:6:1;4242:30;4239:50;;;4285:1;4282;4275:12;4239:50;4308:77;4377:7;4368:6;4357:9;4353:22;4308:77;:::i;:::-;4298:87;4432:2;4417:18;;;;4404:32;;-1:-1:-1;;;;3998:444:1:o;4447:456::-;4524:6;4532;4540;4593:2;4581:9;4572:7;4568:23;4564:32;4561:52;;;4609:1;4606;4599:12;4561:52;4648:9;4635:23;4667:31;4692:5;4667:31;:::i;:::-;4717:5;-1:-1:-1;4774:2:1;4759:18;;4746:32;4787:33;4746:32;4787:33;:::i;:::-;4447:456;;4839:7;;-1:-1:-1;;;4893:2:1;4878:18;;;;4865:32;;4447:456::o;5093:248::-;5161:6;5169;5222:2;5210:9;5201:7;5197:23;5193:32;5190:52;;;5238:1;5235;5228:12;5190:52;-1:-1:-1;;5261:23:1;;;5331:2;5316:18;;;5303:32;;-1:-1:-1;5093:248:1:o;5346:274::-;-1:-1:-1;;;;;5538:32:1;;;;5520:51;;5602:2;5587:18;;5580:34;5508:2;5493:18;;5346:274::o;5625:315::-;5693:6;5701;5754:2;5742:9;5733:7;5729:23;5725:32;5722:52;;;5770:1;5767;5760:12;5722:52;5806:9;5793:23;5783:33;;5866:2;5855:9;5851:18;5838:32;5879:31;5904:5;5879:31;:::i;:::-;5929:5;5919:15;;;5625:315;;;;;:::o;6205:376::-;6301:6;6354:2;6342:9;6333:7;6329:23;6325:32;6322:52;;;6370:1;6367;6360:12;6322:52;6410:9;6397:23;-1:-1:-1;;;;;6435:6:1;6432:30;6429:50;;;6475:1;6472;6465:12;6429:50;6498:77;6567:7;6558:6;6547:9;6543:22;6498:77;:::i;6817:127::-;6878:10;6873:3;6869:20;6866:1;6859:31;6909:4;6906:1;6899:15;6933:4;6930:1;6923:15;6949:275;7020:2;7014:9;7085:2;7066:13;;-1:-1:-1;;7062:27:1;7050:40;;-1:-1:-1;;;;;7105:34:1;;7141:22;;;7102:62;7099:88;;;7167:18;;:::i;:::-;7203:2;7196:22;6949:275;;-1:-1:-1;6949:275:1:o;7229:407::-;7294:5;-1:-1:-1;;;;;7320:6:1;7317:30;7314:56;;;7350:18;;:::i;:::-;7388:57;7433:2;7412:15;;-1:-1:-1;;7408:29:1;7439:4;7404:40;7388:57;:::i;:::-;7379:66;;7468:6;7461:5;7454:21;7508:3;7499:6;7494:3;7490:16;7487:25;7484:45;;;7525:1;7522;7515:12;7484:45;7574:6;7569:3;7562:4;7555:5;7551:16;7538:43;7628:1;7621:4;7612:6;7605:5;7601:18;7597:29;7590:40;7229:407;;;;;:::o;7641:451::-;7710:6;7763:2;7751:9;7742:7;7738:23;7734:32;7731:52;;;7779:1;7776;7769:12;7731:52;7819:9;7806:23;-1:-1:-1;;;;;7844:6:1;7841:30;7838:50;;;7884:1;7881;7874:12;7838:50;7907:22;;7960:4;7952:13;;7948:27;-1:-1:-1;7938:55:1;;7989:1;7986;7979:12;7938:55;8012:74;8078:7;8073:2;8060:16;8055:2;8051;8047:11;8012:74;:::i;8097:387::-;8173:6;8181;8189;8242:2;8230:9;8221:7;8217:23;8213:32;8210:52;;;8258:1;8255;8248:12;8210:52;8294:9;8281:23;8271:33;;8354:2;8343:9;8339:18;8326:32;8367:31;8392:5;8367:31;:::i;:::-;8417:5;-1:-1:-1;8441:37:1;8474:2;8459:18;;8441:37;:::i;:::-;8431:47;;8097:387;;;;;:::o;8713:615::-;8799:6;8807;8860:2;8848:9;8839:7;8835:23;8831:32;8828:52;;;8876:1;8873;8866:12;8828:52;8916:9;8903:23;-1:-1:-1;;;;;8986:2:1;8978:6;8975:14;8972:34;;;9002:1;8999;8992:12;8972:34;9040:6;9029:9;9025:22;9015:32;;9085:7;9078:4;9074:2;9070:13;9066:27;9056:55;;9107:1;9104;9097:12;9056:55;9147:2;9134:16;9173:2;9165:6;9162:14;9159:34;;;9189:1;9186;9179:12;9159:34;9242:7;9237:2;9227:6;9224:1;9220:14;9216:2;9212:23;9208:32;9205:45;9202:65;;;9263:1;9260;9253:12;9202:65;9294:2;9286:11;;;;;9316:6;;-1:-1:-1;8713:615:1;;-1:-1:-1;;;;8713:615:1:o;9333:349::-;9417:12;;-1:-1:-1;;;;;9413:38:1;9401:51;;9505:4;9494:16;;;9488:23;-1:-1:-1;;;;;9484:48:1;9468:14;;;9461:72;9596:4;9585:16;;;9579:23;9572:31;9565:39;9549:14;;;9542:63;9658:4;9647:16;;;9641:23;9666:8;9637:38;9621:14;;9614:62;9333:349::o;9687:724::-;9922:2;9974:21;;;10044:13;;9947:18;;;10066:22;;;9893:4;;9922:2;10145:15;;;;10119:2;10104:18;;;9893:4;10188:197;10202:6;10199:1;10196:13;10188:197;;;10251:52;10299:3;10290:6;10284:13;10251:52;:::i;:::-;10360:15;;;;10332:4;10323:14;;;;;10224:1;10217:9;10188:197;;10913:183;10973:4;-1:-1:-1;;;;;10998:6:1;10995:30;10992:56;;;11028:18;;:::i;:::-;-1:-1:-1;11073:1:1;11069:14;11085:4;11065:25;;10913:183::o;11101:662::-;11155:5;11208:3;11201:4;11193:6;11189:17;11185:27;11175:55;;11226:1;11223;11216:12;11175:55;11262:6;11249:20;11288:4;11312:60;11328:43;11368:2;11328:43;:::i;:::-;11312:60;:::i;:::-;11406:15;;;11492:1;11488:10;;;;11476:23;;11472:32;;;11437:12;;;;11516:15;;;11513:35;;;11544:1;11541;11534:12;11513:35;11580:2;11572:6;11568:15;11592:142;11608:6;11603:3;11600:15;11592:142;;;11674:17;;11662:30;;11712:12;;;;11625;;11592:142;;;-1:-1:-1;11752:5:1;11101:662;-1:-1:-1;;;;;;11101:662:1:o;11768:1215::-;11886:6;11894;11947:2;11935:9;11926:7;11922:23;11918:32;11915:52;;;11963:1;11960;11953:12;11915:52;12003:9;11990:23;-1:-1:-1;;;;;12073:2:1;12065:6;12062:14;12059:34;;;12089:1;12086;12079:12;12059:34;12127:6;12116:9;12112:22;12102:32;;12172:7;12165:4;12161:2;12157:13;12153:27;12143:55;;12194:1;12191;12184:12;12143:55;12230:2;12217:16;12252:4;12276:60;12292:43;12332:2;12292:43;:::i;12276:60::-;12370:15;;;12452:1;12448:10;;;;12440:19;;12436:28;;;12401:12;;;;12476:19;;;12473:39;;;12508:1;12505;12498:12;12473:39;12532:11;;;;12552:217;12568:6;12563:3;12560:15;12552:217;;;12648:3;12635:17;12665:31;12690:5;12665:31;:::i;:::-;12709:18;;12585:12;;;;12747;;;;12552:217;;;12788:5;-1:-1:-1;;12831:18:1;;12818:32;;-1:-1:-1;;12862:16:1;;;12859:36;;;12891:1;12888;12881:12;12859:36;;12914:63;12969:7;12958:8;12947:9;12943:24;12914:63;:::i;:::-;12904:73;;;11768:1215;;;;;:::o;12988:632::-;13159:2;13211:21;;;13281:13;;13184:18;;;13303:22;;;13130:4;;13159:2;13382:15;;;;13356:2;13341:18;;;13130:4;13425:169;13439:6;13436:1;13433:13;13425:169;;;13500:13;;13488:26;;13569:15;;;;13534:12;;;;13461:1;13454:9;13425:169;;13625:118;13711:5;13704:13;13697:21;13690:5;13687:32;13677:60;;13733:1;13730;13723:12;13748:241;13804:6;13857:2;13845:9;13836:7;13832:23;13828:32;13825:52;;;13873:1;13870;13863:12;13825:52;13912:9;13899:23;13931:28;13953:5;13931:28;:::i;13994:383::-;14071:6;14079;14087;14140:2;14128:9;14119:7;14115:23;14111:32;14108:52;;;14156:1;14153;14146:12;14108:52;14195:9;14182:23;14214:31;14239:5;14214:31;:::i;:::-;14264:5;14316:2;14301:18;;14288:32;;-1:-1:-1;14367:2:1;14352:18;;;14339:32;;13994:383;-1:-1:-1;;;13994:383:1:o;14382:382::-;14447:6;14455;14508:2;14496:9;14487:7;14483:23;14479:32;14476:52;;;14524:1;14521;14514:12;14476:52;14563:9;14550:23;14582:31;14607:5;14582:31;:::i;:::-;14632:5;-1:-1:-1;14689:2:1;14674:18;;14661:32;14702:30;14661:32;14702:30;:::i;14769:795::-;14864:6;14872;14880;14888;14941:3;14929:9;14920:7;14916:23;14912:33;14909:53;;;14958:1;14955;14948:12;14909:53;14997:9;14984:23;15016:31;15041:5;15016:31;:::i;:::-;15066:5;-1:-1:-1;15123:2:1;15108:18;;15095:32;15136:33;15095:32;15136:33;:::i;:::-;15188:7;-1:-1:-1;15242:2:1;15227:18;;15214:32;;-1:-1:-1;15297:2:1;15282:18;;15269:32;-1:-1:-1;;;;;15313:30:1;;15310:50;;;15356:1;15353;15346:12;15310:50;15379:22;;15432:4;15424:13;;15420:27;-1:-1:-1;15410:55:1;;15461:1;15458;15451:12;15410:55;15484:74;15550:7;15545:2;15532:16;15527:2;15523;15519:11;15484:74;:::i;:::-;15474:84;;;14769:795;;;;;;;:::o;15569:268::-;15767:3;15752:19;;15780:51;15756:9;15813:6;15780:51;:::i;15842:388::-;15910:6;15918;15971:2;15959:9;15950:7;15946:23;15942:32;15939:52;;;15987:1;15984;15977:12;15939:52;16026:9;16013:23;16045:31;16070:5;16045:31;:::i;:::-;16095:5;-1:-1:-1;16152:2:1;16137:18;;16124:32;16165:33;16124:32;16165:33;:::i;16235:380::-;16314:1;16310:12;;;;16357;;;16378:61;;16432:4;16424:6;16420:17;16410:27;;16378:61;16485:2;16477:6;16474:14;16454:18;16451:38;16448:161;;16531:10;16526:3;16522:20;16519:1;16512:31;16566:4;16563:1;16556:15;16594:4;16591:1;16584:15;16620:127;16681:10;16676:3;16672:20;16669:1;16662:31;16712:4;16709:1;16702:15;16736:4;16733:1;16726:15;16752:128;16819:9;;;16840:11;;;16837:37;;;16854:18;;:::i;17506:409::-;17708:2;17690:21;;;17747:2;17727:18;;;17720:30;17786:34;17781:2;17766:18;;17759:62;-1:-1:-1;;;17852:2:1;17837:18;;17830:43;17905:3;17890:19;;17506:409::o;17920:168::-;17993:9;;;18024;;18041:15;;;18035:22;;18021:37;18011:71;;18062:18;;:::i;18225:217::-;18265:1;18291;18281:132;;18335:10;18330:3;18326:20;18323:1;18316:31;18370:4;18367:1;18360:15;18398:4;18395:1;18388:15;18281:132;-1:-1:-1;18427:9:1;;18225:217::o;18764:521::-;18841:4;18847:6;18907:11;18894:25;19001:2;18997:7;18986:8;18970:14;18966:29;18962:43;18942:18;18938:68;18928:96;;19020:1;19017;19010:12;18928:96;19047:33;;19099:20;;;-1:-1:-1;;;;;;19131:30:1;;19128:50;;;19174:1;19171;19164:12;19128:50;19207:4;19195:17;;-1:-1:-1;19238:14:1;19234:27;;;19224:38;;19221:58;;;19275:1;19272;19265:12;19290:271;19473:6;19465;19460:3;19447:33;19429:3;19499:16;;19524:13;;;19499:16;19290:271;-1:-1:-1;19290:271:1:o;19982:125::-;20047:9;;;20068:10;;;20065:36;;;20081:18;;:::i;20238:545::-;20340:2;20335:3;20332:11;20329:448;;;20376:1;20401:5;20397:2;20390:17;20446:4;20442:2;20432:19;20516:2;20504:10;20500:19;20497:1;20493:27;20487:4;20483:38;20552:4;20540:10;20537:20;20534:47;;;-1:-1:-1;20575:4:1;20534:47;20630:2;20625:3;20621:12;20618:1;20614:20;20608:4;20604:31;20594:41;;20685:82;20703:2;20696:5;20693:13;20685:82;;;20748:17;;;20729:1;20718:13;20685:82;;20959:1352;21085:3;21079:10;-1:-1:-1;;;;;21104:6:1;21101:30;21098:56;;;21134:18;;:::i;:::-;21163:97;21253:6;21213:38;21245:4;21239:11;21213:38;:::i;:::-;21207:4;21163:97;:::i;:::-;21315:4;;21379:2;21368:14;;21396:1;21391:663;;;;22098:1;22115:6;22112:89;;;-1:-1:-1;22167:19:1;;;22161:26;22112:89;-1:-1:-1;;20916:1:1;20912:11;;;20908:24;20904:29;20894:40;20940:1;20936:11;;;20891:57;22214:81;;21361:944;;21391:663;20185:1;20178:14;;;20222:4;20209:18;;-1:-1:-1;;21427:20:1;;;21545:236;21559:7;21556:1;21553:14;21545:236;;;21648:19;;;21642:26;21627:42;;21740:27;;;;21708:1;21696:14;;;;21575:19;;21545:236;;;21549:3;21809:6;21800:7;21797:19;21794:201;;;21870:19;;;21864:26;-1:-1:-1;;21953:1:1;21949:14;;;21965:3;21945:24;21941:37;21937:42;21922:58;21907:74;;21794:201;-1:-1:-1;;;;;22041:1:1;22025:14;;;22021:22;22008:36;;-1:-1:-1;20959:1352:1:o;22316:317::-;-1:-1:-1;;;;;22493:32:1;;22475:51;;22562:2;22557;22542:18;;22535:30;;;-1:-1:-1;;22582:45:1;;22608:18;;22600:6;22582:45;:::i;23474:1061::-;23986:34;23981:3;23974:47;24051:34;24046:2;24041:3;24037:12;24030:56;-1:-1:-1;;;24111:2:1;24106:3;24102:12;24095:31;23956:3;24155:6;24149:13;24171:73;24237:6;24232:2;24227:3;24223:12;24218:2;24210:6;24206:15;24171:73;:::i;:::-;-1:-1:-1;;;24303:2:1;24263:16;;;24295:11;;;24288:24;24337:13;;24359:74;24337:13;24419:2;24411:11;;24406:2;24394:15;;24359:74;:::i;:::-;-1:-1:-1;;;24493:2:1;24452:17;;;;24485:11;;;24478:24;24526:2;24518:11;;23474:1061;-1:-1:-1;;;;23474:1061:1:o;25528:245::-;25595:6;25648:2;25636:9;25627:7;25623:23;25619:32;25616:52;;;25664:1;25661;25654:12;25616:52;25696:9;25690:16;25715:28;25737:5;25715:28;:::i;26610:406::-;26812:2;26794:21;;;26851:2;26831:18;;;26824:30;26890:34;26885:2;26870:18;;26863:62;-1:-1:-1;;;26956:2:1;26941:18;;26934:40;27006:3;26991:19;;26610:406::o;27375:401::-;27577:2;27559:21;;;27616:2;27596:18;;;27589:30;27655:34;27650:2;27635:18;;27628:62;-1:-1:-1;;;27721:2:1;27706:18;;27699:35;27766:3;27751:19;;27375:401::o;28542:127::-;28603:10;28598:3;28594:20;28591:1;28584:31;28634:4;28631:1;28624:15;28658:4;28655:1;28648:15;28674:135;28713:3;28734:17;;;28731:43;;28754:18;;:::i;:::-;-1:-1:-1;28801:1:1;28790:13;;28674:135::o;29522:414::-;29724:2;29706:21;;;29763:2;29743:18;;;29736:30;29802:34;29797:2;29782:18;;29775:62;-1:-1:-1;;;29868:2:1;29853:18;;29846:48;29926:3;29911:19;;29522:414::o;29941:1256::-;30165:3;30203:6;30197:13;30229:4;30242:64;30299:6;30294:3;30289:2;30281:6;30277:15;30242:64;:::i;:::-;30369:13;;30328:16;;;;30391:68;30369:13;30328:16;30426:15;;;30391:68;:::i;:::-;30548:13;;30481:20;;;30521:1;;30586:36;30548:13;30586:36;:::i;:::-;30641:1;30658:18;;;30685:141;;;;30840:1;30835:337;;;;30651:521;;30685:141;-1:-1:-1;;30720:24:1;;30706:39;;30797:16;;30790:24;30776:39;;30765:51;;;-1:-1:-1;30685:141:1;;30835:337;30866:6;30863:1;30856:17;30914:2;30911:1;30901:16;30939:1;30953:169;30967:8;30964:1;30961:15;30953:169;;;31049:14;;31034:13;;;31027:37;31092:16;;;;30984:10;;30953:169;;;30957:3;;31153:8;31146:5;31142:20;31135:27;;30651:521;-1:-1:-1;31188:3:1;;29941:1256;-1:-1:-1;;;;;;;;;;29941:1256:1:o;31202:812::-;31613:25;31608:3;31601:38;31583:3;31668:6;31662:13;31684:75;31752:6;31747:2;31742:3;31738:12;31731:4;31723:6;31719:17;31684:75;:::i;:::-;-1:-1:-1;;;31818:2:1;31778:16;;;31810:11;;;31803:40;31868:13;;31890:76;31868:13;31952:2;31944:11;;31937:4;31925:17;;31890:76;:::i;:::-;31986:17;32005:2;31982:26;;31202:812;-1:-1:-1;;;;31202:812:1:o;33000:498::-;-1:-1:-1;;;;;33274:31:1;33265:6;33261:2;33257:15;33253:53;33248:3;33241:66;33351:6;33343;33338:2;33333:3;33329:12;33316:42;33417:2;33377:16;;33409:11;;;33402:27;;;;33453:2;33445:11;;33438:27;33489:2;33481:11;;33000:498;-1:-1:-1;;33000:498:1:o;33503:489::-;-1:-1:-1;;;;;33772:15:1;;;33754:34;;33824:15;;33819:2;33804:18;;33797:43;33871:2;33856:18;;33849:34;;;33919:3;33914:2;33899:18;;33892:31;;;33697:4;;33940:46;;33966:19;;33958:6;33940:46;:::i;:::-;33932:54;33503:489;-1:-1:-1;;;;;;33503:489:1:o;33997:249::-;34066:6;34119:2;34107:9;34098:7;34094:23;34090:32;34087:52;;;34135:1;34132;34125:12;34087:52;34167:9;34161:16;34186:30;34210:5;34186:30;:::i;34251:136::-;34290:3;34318:5;34308:39;;34327:18;;:::i;:::-;-1:-1:-1;;;34363:18:1;;34251:136::o;35471:127::-;35532:10;35527:3;35523:20;35520:1;35513:31;35563:4;35560:1;35553:15;35587:4;35584:1;35577:15
Swarm Source
ipfs://2eddbdbd986f790c76c8d8e9591312a809cf0067d1f37370d6fff7e4875486a7
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.