ERC-721
Overview
Max Total Supply
3,000 BANANA
Holders
157
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 BANANALoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Banana
Compiler Version
v0.8.15+commit.e14f2714
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-07-31 */ // File: @openzeppelin/contracts/security/ReentrancyGuard.sol // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } // File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol // OpenZeppelin Contracts (last updated v4.7.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 } 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"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' 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) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ 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 if (signature.length == 64) { bytes32 r; bytes32 vs; // 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)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } 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 (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // 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) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @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) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } } // File: @openzeppelin/contracts/utils/Context.sol // 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/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.7.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 * ==== * * [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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(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) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol // 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: @openzeppelin/contracts/utils/introspection/IERC165.sol // 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/ERC165.sol // 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/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v4.7.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: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * 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/IERC721Enumerable.sol // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } // File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol // 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/token/ERC721/ERC721.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol) 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 { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // 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_; } /** * @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) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[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); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual 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 nor 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 nor 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 nor 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 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) { return _owners[tokenId] != address(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); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId); } /** * @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. * * 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, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} } // File: contracts/erc721a.sol pragma solidity ^0.8.11; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata and Enumerable extension. Built to optimize for lower gas during batch mints. * * Assumes serials are sequentially minted starting at 0 (e.g. 0, 1, 2, 3..). * * Does not support burning tokens to address(0). * * Assumes that an owner cannot have more than the 2**128 - 1 (max value of uint128) of supply */ contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable { using Address for address; using Strings for uint256; struct TokenOwnership { address addr; uint64 startTimestamp; } struct AddressData { uint128 balance; uint128 numberMinted; } uint256 internal currentIndex; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. See ownershipOf implementation for details. mapping(uint256 => TokenOwnership) internal _ownerships; // Mapping owner address to address data mapping(address => AddressData) private _addressData; // 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; constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view override returns (uint256) { return currentIndex; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view override returns (uint256) { require(index < totalSupply(), "ERC721A: global index out of bounds"); return index; } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. * This read function is O(totalSupply). If calling from a separate contract, be sure to test gas first. * It may also degrade with extremely large collection sizes (e.g >> 10000), test for your use case. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) { require(index < balanceOf(owner), "ERC721A: owner index out of bounds"); uint256 numMintedSoFar = totalSupply(); uint256 tokenIdsIdx; address currOwnershipAddr; // Counter overflow is impossible as the loop breaks when uint256 i is equal to another uint256 numMintedSoFar. unchecked { for (uint256 i; i < numMintedSoFar; i++) { TokenOwnership memory ownership = _ownerships[i]; if (ownership.addr != address(0)) { currOwnershipAddr = ownership.addr; } if (currOwnershipAddr == owner) { if (tokenIdsIdx == index) { return i; } tokenIdsIdx++; } } } revert("ERC721A: unable to get token of owner by index"); } /** * @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 || interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view override returns (uint256) { require(owner != address(0), "ERC721A: balance query for the zero address"); return uint256(_addressData[owner].balance); } function _numberMinted(address owner) internal view returns (uint256) { require(owner != address(0), "ERC721A: number minted query for the zero address"); return uint256(_addressData[owner].numberMinted); } /** * Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around in the collection over time. */ function ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) { require(_exists(tokenId), "ERC721A: owner query for nonexistent token"); unchecked { for (uint256 curr = tokenId; curr >= 0; curr--) { TokenOwnership memory ownership = _ownerships[curr]; if (ownership.addr != address(0)) { return ownership; } } } revert("ERC721A: unable to determine the owner of token"); } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view override returns (address) { return ownershipOf(tokenId).addr; } /** * @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) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public override { address owner = ERC721A.ownerOf(tokenId); require(to != owner, "ERC721A: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721A: approve caller is not owner nor approved for all" ); _approve(to, tokenId, owner); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view override returns (address) { require(_exists(tokenId), "ERC721A: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public override { require(operator != _msgSender(), "ERC721A: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_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 { _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 override { _transfer(from, to, tokenId); require( _checkOnERC721Received(from, to, tokenId, _data), "ERC721A: transfer to non ERC721Receiver implementer" ); } /** * @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`), */ function _exists(uint256 tokenId) internal view returns (bool) { return tokenId < currentIndex; } function _safeMint(address to, uint256 quantity) internal { _safeMint(to, quantity, ""); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * Emits a {Transfer} event. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal { _mint(to, quantity, _data, true); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event. */ function _mint( address to, uint256 quantity, bytes memory _data, bool safe ) internal { uint256 startTokenId = currentIndex; require(to != address(0), "ERC721A: mint to the zero address"); require(quantity != 0, "ERC721A: quantity must be greater than 0"); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // balance or numberMinted overflow if current value of either + quantity > 3.4e38 (2**128) - 1 // updatedIndex overflows if currentIndex + quantity > 1.56e77 (2**256) - 1 unchecked { _addressData[to].balance += uint128(quantity); _addressData[to].numberMinted += uint128(quantity); _ownerships[startTokenId].addr = to; _ownerships[startTokenId].startTimestamp = uint64(block.timestamp); uint256 updatedIndex = startTokenId; for (uint256 i; i < quantity; i++) { emit Transfer(address(0), to, updatedIndex); if (safe) { require( _checkOnERC721Received(address(0), to, updatedIndex, _data), "ERC721A: transfer to non ERC721Receiver implementer" ); } updatedIndex++; } currentIndex = updatedIndex; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Transfers `tokenId` from `from` to `to`. * * 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 ) private { TokenOwnership memory prevOwnership = ownershipOf(tokenId); bool isApprovedOrOwner = (_msgSender() == prevOwnership.addr || getApproved(tokenId) == _msgSender() || isApprovedForAll(prevOwnership.addr, _msgSender())); require(isApprovedOrOwner, "ERC721A: transfer caller is not owner nor approved"); require(prevOwnership.addr == from, "ERC721A: transfer from incorrect owner"); require(to != address(0), "ERC721A: transfer to the zero address"); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner _approve(address(0), tokenId, prevOwnership.addr); // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256. unchecked { _addressData[from].balance -= 1; _addressData[to].balance += 1; _ownerships[tokenId].addr = to; _ownerships[tokenId].startTimestamp = uint64(block.timestamp); // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it. // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls. uint256 nextTokenId = tokenId + 1; if (_ownerships[nextTokenId].addr == address(0)) { if (_exists(nextTokenId)) { _ownerships[nextTokenId].addr = prevOwnership.addr; _ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp; } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve( address to, uint256 tokenId, address owner ) private { _tokenApprovals[tokenId] = to; emit Approval(owner, to, tokenId); } /** * @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(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721A: transfer to non ERC721Receiver implementer"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting. * * startTokenId - the first token id to be transferred * quantity - the amount to be transferred * * 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`. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes * minting. * * startTokenId - the first token id to be transferred * quantity - the amount to be transferred * * Calling conditions: * * - when `from` and `to` are both non-zero. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} } // File: contracts/banana.sol pragma solidity ^0.8.11; contract Banana is ERC721A, Ownable, ReentrancyGuard { using ECDSA for bytes32; address private systemAddress; address private kongAddress; string public hiddenURI; string public baseURI; uint public price = 0.08 ether; uint public maxPerWallet = 2; uint public teamSupply = 0; uint public whitelistSupply = 1000; uint public kongSupply = 2000; uint public maxSupply = 3000; uint public mintType = 2; // 1 - team, 2 - whitelist, 3 - kong owners, 4 - public uint public mintedKong = 0; uint public nextOwnerToExplicitlySet; bool public mintEnabled; bool public revealed; mapping(string => bool) public _usedNonces; mapping(address => uint256[]) public _kongOwners; mapping(uint256 => bool) public _redeemedKongIds; constructor(address _kongAddress, address _systemAddress) ERC721A("Banana", "BANANA"){ kongAddress = _kongAddress; systemAddress = _systemAddress; } function teamMint(address to, uint256 numberOfTokens) external onlyOwner { require(mintEnabled, "mint disabled"); require(mintType == 1, "team minting is not allowed"); require(totalSupply() + numberOfTokens < teamSupply + 1, "team supply is sold out!"); _safeMint(to, numberOfTokens); } function whitelistMint(address to, uint256 numberOfTokens, string memory nonce, bytes32 hash, bytes memory signature) external payable { uint cost = price; require(mintEnabled, "mint disabled"); require(mintType == 2, "whitelist minting is not allowed"); require(totalSupply() + numberOfTokens < teamSupply + whitelistSupply + 1, "whitelist supply is sold out!"); require(numberMinted(msg.sender) + numberOfTokens <= maxPerWallet, "too many per wallet"); require(msg.value >= numberOfTokens * cost, "ether is not enough"); // signature verification require(matchSigner(hash, signature), "please mint through website"); require(!_usedNonces[nonce], "hash reused"); require(hashTransaction(msg.sender, numberOfTokens, nonce) == hash, "hash failed"); _usedNonces[nonce] = true; _safeMint(to, numberOfTokens); } function kongMint(address to) external { require(mintEnabled, "mint disabled"); require(mintType == 3, "kong minting is not allowed"); uint toMint = 0; if(_kongOwners[msg.sender].length > 0) { uint kongsOwned = _kongOwners[msg.sender].length; // we check their kongs for (uint i = 0; i < kongsOwned; i++) { uint256 tokenId = _kongOwners[msg.sender][i]; if (!_redeemedKongIds[tokenId]) { toMint++; _redeemedKongIds[tokenId] = true; } } mintedKong = mintedKong + toMint; } else { require(IERC721(kongAddress).balanceOf(msg.sender) > 0, "only supreme kong owners are able to mint"); uint kongsOwned = IERC721(kongAddress).balanceOf(msg.sender); // we check their kongs for (uint i = 0; i < kongsOwned; i++) { uint256 tokenId = IERC721Enumerable(kongAddress).tokenOfOwnerByIndex(msg.sender, i); if (!_redeemedKongIds[tokenId]) { toMint++; _redeemedKongIds[tokenId] = true; } } mintedKong = mintedKong + toMint; } require(toMint > 0, "no redeemable kongs"); _safeMint(to, toMint); } function publicMint(address to, uint256 numberOfTokens) external payable { uint cost = price; require(mintEnabled, "mint disabled"); require(mintType == 4, "public minting is not allowed"); require(totalSupply() + numberOfTokens < maxSupply + 1, "we're sold out!"); require(numberMinted(msg.sender) + numberOfTokens <= maxPerWallet, "too many per wallet"); require(msg.value >= numberOfTokens * cost, "ether is not enough"); _safeMint(to, numberOfTokens); } function toggleMinting() external onlyOwner { mintEnabled = !mintEnabled; } function toggleRevealed() external onlyOwner { revealed = !revealed; } function kongOwnedAmount(address owner) public view returns (uint256) { uint kongsOwned = _kongOwners[owner].length; // we check their kongs uint kongsOwnedByContract = IERC721(kongAddress).balanceOf(owner); // we check their kongs uint toMint = 0; if(kongsOwned > 0){ for (uint i = 0; i < kongsOwned; i++) { uint256 tokenId = _kongOwners[owner][i]; if (!_redeemedKongIds[tokenId]) { toMint++; } } } if(kongsOwnedByContract > 0){ for (uint i = 0; i < kongsOwnedByContract; i++) { uint256 tokenId = IERC721Enumerable(kongAddress).tokenOfOwnerByIndex(owner, i); if (!_redeemedKongIds[tokenId]) { toMint++; } } } return toMint; } function numberMinted(address owner) public view returns (uint256) { return _numberMinted(owner); } function addKongOwner(address owner, uint[] memory tokenIds) external onlyOwner { _kongOwners[owner] = tokenIds; } function setHiddenURI(string calldata hiddenURI_) external onlyOwner { hiddenURI = hiddenURI_; } function setBaseURI(string calldata baseURI_) external onlyOwner { baseURI = baseURI_; } function tokenURI(uint256 tokenId) public view override returns (string memory) { require(_exists(tokenId), "banana does not exist"); if (revealed) { return baseURI; } return hiddenURI; } function setPrice(uint256 price_) external onlyOwner { price = price_; } function setMaxPerWallet(uint256 maxPerWallet_) external onlyOwner { maxPerWallet = maxPerWallet_; } function setMintType(uint256 mintType_) external onlyOwner { mintType = mintType_; } function _baseURI() internal view virtual override returns (string memory) { return baseURI; } function _kongOwnersLength() external view returns (uint) { return _kongOwners[msg.sender].length; } function withdraw() external onlyOwner nonReentrant { (bool success, ) = msg.sender.call{value: address(this).balance}(""); require(success, "transfer failed"); } function setOwnersExplicit(uint256 quantity) external onlyOwner nonReentrant { _setOwnersExplicit(quantity); } function getOwnershipData(uint256 tokenId) external view returns (TokenOwnership memory) { return ownershipOf(tokenId); } function matchSigner(bytes32 hash, bytes memory signature) public view returns (bool) { return systemAddress == hash.toEthSignedMessageHash().recover(signature); } function hashTransaction( address sender, uint256 amount, string memory nonce ) public view returns (bytes32) { bytes32 hash = keccak256( abi.encodePacked(sender, amount, nonce, address(this)) ); return hash; } /** * @dev Explicitly set `owners` to eliminate loops in future calls of ownerOf(). */ function _setOwnersExplicit(uint256 quantity) internal { require(quantity != 0, "quantity must be nonzero"); require(currentIndex != 0, "no tokens minted yet"); uint256 _nextOwnerToExplicitlySet = nextOwnerToExplicitlySet; require(_nextOwnerToExplicitlySet < currentIndex, "all ownerships have been set"); // Index underflow is impossible. // Counter or index overflow is incredibly unrealistic. unchecked { uint256 endIndex = _nextOwnerToExplicitlySet + quantity - 1; // Set the end index to be the last token index if (endIndex + 1 > currentIndex) { endIndex = currentIndex - 1; } for (uint256 i = _nextOwnerToExplicitlySet; i <= endIndex; i++) { if (_ownerships[i].addr == address(0)) { TokenOwnership memory ownership = ownershipOf(i); _ownerships[i].addr = ownership.addr; _ownerships[i].startTimestamp = ownership.startTimestamp; } } nextOwnerToExplicitlySet = endIndex + 1; } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_kongAddress","type":"address"},{"internalType":"address","name":"_systemAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"_kongOwners","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_kongOwnersLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_redeemedKongIds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"_usedNonces","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"addKongOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getOwnershipData","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"}],"internalType":"struct ERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"nonce","type":"string"}],"name":"hashTransaction","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hiddenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"kongMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"kongOwnedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kongSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"matchSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintType","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintedKong","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextOwnerToExplicitlySet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI_","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"hiddenURI_","type":"string"}],"name":"setHiddenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxPerWallet_","type":"uint256"}],"name":"setMaxPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mintType_","type":"uint256"}],"name":"setMintType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"setOwnersExplicit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price_","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"teamMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"teamSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleRevealed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"numberOfTokens","type":"uint256"},{"internalType":"string","name":"nonce","type":"string"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"whitelistSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405267011c37937e080000600d556002600e556000600f556103e86010556107d0601155610bb8601255600260135560006014553480156200004357600080fd5b5060405162003a3838038062003a3883398101604081905262000066916200018b565b6040518060400160405280600681526020016542616e616e6160d01b8152506040518060400160405280600681526020016542414e414e4160d01b8152508160019081620000b5919062000268565b506002620000c4828262000268565b505050620000e1620000db6200011860201b60201c565b6200011c565b6001600855600a80546001600160a01b039384166001600160a01b0319918216179091556009805492909316911617905562000334565b3390565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200018657600080fd5b919050565b600080604083850312156200019f57600080fd5b620001aa836200016e565b9150620001ba602084016200016e565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620001ee57607f821691505b6020821081036200020f57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200026357600081815260208120601f850160051c810160208610156200023e5750805b601f850160051c820191505b818110156200025f578281556001016200024a565b5050505b505050565b81516001600160401b03811115620002845762000284620001c3565b6200029c81620002958454620001d9565b8462000215565b602080601f831160018114620002d45760008415620002bb5750858301515b600019600386901b1c1916600185901b1785556200025f565b600085815260208120601f198616915b828110156200030557888601518255948401946001909101908401620002e4565b5085821015620003245787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6136f480620003446000396000f3fe6080604052600436106103505760003560e01c80636c0360eb116101c6578063add5a4fa116100f7578063d7224ba011610095578063dd8d74d81161006f578063dd8d74d814610975578063e268e4d314610995578063e985e9c5146109b5578063f2fde38b146109fe57600080fd5b8063d7224ba01461091f578063d7b33e1b14610935578063dc33e6811461095557600080fd5b8063c87b56dd116100d1578063c87b56dd146108bc578063ce6df2b9146108dc578063d1239730146108ef578063d5abeb011461090957600080fd5b8063add5a4fa1461085c578063b88d4fde1461087c578063bbaac02f1461089c57600080fd5b80639231ab2a11610164578063a035b1fe1161013e578063a035b1fe146107c9578063a1cd4490146107df578063a22cb46514610801578063a6ba55c71461082157600080fd5b80639231ab2a1461075157806395d89b411461079e57806396286f9a146107b357600080fd5b80637d55094d116101a05780637d55094d146106e95780638cc54e7f146106fe5780638da5cb5b1461071357806391b7f5ed1461073157600080fd5b80636c0360eb1461069f57806370a08231146106b4578063715018a6146106d457600080fd5b80632de71c5f116102a0578063518302271161023e5780636218186d116102185780636218186d1461062c5780636352211e1461063f578063647287011461065f57806367717e2a1461067f57600080fd5b806351830227146105d857806355f804b3146105f75780635bc020bc1461061757600080fd5b80633ccfd60b1161027a5780633ccfd60b1461056d57806342842e0e14610582578063453c2310146105a25780634f6ccce7146105b857600080fd5b80632de71c5f146105175780632f745c591461053757806333e614131461055757600080fd5b806318160ddd1161030d5780632a2d5394116102e75780632a2d5394146104b55780632c77f025146104cb5780632cfac6ec146104e15780632d20fb60146104f757600080fd5b806318160ddd1461044657806318890b991461046557806323b872dd1461049557600080fd5b806301ffc9a714610355578063057f45681461038a57806306fdde03146103ac578063081812fc146103ce5780630854dee614610406578063095ea7b314610426575b600080fd5b34801561036157600080fd5b50610375610370366004612e45565b610a1e565b60405190151581526020015b60405180910390f35b34801561039657600080fd5b506103aa6103a5366004612e85565b610a8b565b005b3480156103b857600080fd5b506103c1610e45565b6040516103819190612ef8565b3480156103da57600080fd5b506103ee6103e9366004612f0b565b610ed7565b6040516001600160a01b039091168152602001610381565b34801561041257600080fd5b506103aa610421366004612f6a565b610f62565b34801561043257600080fd5b506103aa610441366004613022565b610f98565b34801561045257600080fd5b506000545b604051908152602001610381565b34801561047157600080fd5b50610375610480366004612f0b565b60196020526000908152604090205460ff1681565b3480156104a157600080fd5b506103aa6104b036600461304c565b6110aa565b3480156104c157600080fd5b5061045760145481565b3480156104d757600080fd5b5061045760115481565b3480156104ed57600080fd5b50610457600f5481565b34801561050357600080fd5b506103aa610512366004612f0b565b6110b5565b34801561052357600080fd5b50610457610532366004612e85565b611125565b34801561054357600080fd5b50610457610552366004613022565b6112ff565b34801561056357600080fd5b5061045760105481565b34801561057957600080fd5b506103aa611459565b34801561058e57600080fd5b506103aa61059d36600461304c565b611542565b3480156105ae57600080fd5b50610457600e5481565b3480156105c457600080fd5b506104576105d3366004612f0b565b61155d565b3480156105e457600080fd5b5060165461037590610100900460ff1681565b34801561060357600080fd5b506103aa610612366004613088565b6115bf565b34801561062357600080fd5b506103aa6115d4565b6103aa61063a366004613168565b6115f9565b34801561064b57600080fd5b506103ee61065a366004612f0b565b6118d5565b34801561066b57600080fd5b506103aa61067a366004612f0b565b6118e7565b34801561068b57600080fd5b5061045761069a3660046131ef565b6118f4565b3480156106ab57600080fd5b506103c161192f565b3480156106c057600080fd5b506104576106cf366004612e85565b6119bd565b3480156106e057600080fd5b506103aa611a4e565b3480156106f557600080fd5b506103aa611a62565b34801561070a57600080fd5b506103c1611a7e565b34801561071f57600080fd5b506007546001600160a01b03166103ee565b34801561073d57600080fd5b506103aa61074c366004612f0b565b611a8b565b34801561075d57600080fd5b5061077161076c366004612f0b565b611a98565b6040805182516001600160a01b031681526020928301516001600160401b03169281019290925201610381565b3480156107aa57600080fd5b506103c1611ab5565b3480156107bf57600080fd5b5061045760135481565b3480156107d557600080fd5b50610457600d5481565b3480156107eb57600080fd5b5033600090815260186020526040902054610457565b34801561080d57600080fd5b506103aa61081c366004613245565b611ac4565b34801561082d57600080fd5b5061037561083c366004613281565b805160208183018101805160178252928201919093012091525460ff1681565b34801561086857600080fd5b506103aa610877366004613022565b611b88565b34801561088857600080fd5b506103aa6108973660046132b5565b611c73565b3480156108a857600080fd5b506103aa6108b7366004613088565b611cac565b3480156108c857600080fd5b506103c16108d7366004612f0b565b611cc1565b6103aa6108ea366004613022565b611dc1565b3480156108fb57600080fd5b506016546103759060ff1681565b34801561091557600080fd5b5061045760125481565b34801561092b57600080fd5b5061045760155481565b34801561094157600080fd5b50610457610950366004613022565b611f4d565b34801561096157600080fd5b50610457610970366004612e85565b611f7e565b34801561098157600080fd5b5061037561099036600461331c565b611f89565b3480156109a157600080fd5b506103aa6109b0366004612f0b565b612004565b3480156109c157600080fd5b506103756109d0366004613362565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b348015610a0a57600080fd5b506103aa610a19366004612e85565b612011565b60006001600160e01b031982166380ac58cd60e01b1480610a4f57506001600160e01b03198216635b5e139f60e01b145b80610a6a57506001600160e01b0319821663780e9d6360e01b145b80610a8557506301ffc9a760e01b6001600160e01b03198316145b92915050565b60165460ff16610ab65760405162461bcd60e51b8152600401610aad90613395565b60405180910390fd5b601354600314610b085760405162461bcd60e51b815260206004820152601b60248201527f6b6f6e67206d696e74696e67206973206e6f7420616c6c6f77656400000000006044820152606401610aad565b3360009081526018602052604081205415610bd05733600090815260186020526040812054905b81811015610bb857336000908152601860205260408120805483908110610b5857610b586133bc565b6000918252602080832090910154808352601990915260409091205490915060ff16610ba55783610b88816133e8565b6000838152601960205260409020805460ff191660011790559450505b5080610bb0816133e8565b915050610b2f565b5081601454610bc79190613401565b60145550610df1565b600a546040516370a0823160e01b81523360048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610c19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3d9190613419565b11610c9c5760405162461bcd60e51b815260206004820152602960248201527f6f6e6c792073757072656d65206b6f6e67206f776e657273206172652061626c60448201526819481d1bc81b5a5b9d60ba1b6064820152608401610aad565b600a546040516370a0823160e01b81523360048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610ce5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d099190613419565b905060005b81811015610ddd57600a54604051632f745c5960e01b8152336004820152602481018390526000916001600160a01b031690632f745c5990604401602060405180830381865afa158015610d66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8a9190613419565b60008181526019602052604090205490915060ff16610dca5783610dad816133e8565b6000838152601960205260409020805460ff191660011790559450505b5080610dd5816133e8565b915050610d0e565b5081601454610dec9190613401565b601455505b60008111610e375760405162461bcd60e51b81526020600482015260136024820152726e6f2072656465656d61626c65206b6f6e677360681b6044820152606401610aad565b610e41828261208a565b5050565b606060018054610e5490613432565b80601f0160208091040260200160405190810160405280929190818152602001828054610e8090613432565b8015610ecd5780601f10610ea257610100808354040283529160200191610ecd565b820191906000526020600020905b815481529060010190602001808311610eb057829003601f168201915b5050505050905090565b6000610ee4826000541190565b610f465760405162461bcd60e51b815260206004820152602d60248201527f455243373231413a20617070726f76656420717565727920666f72206e6f6e6560448201526c3c34b9ba32b73a103a37b5b2b760991b6064820152608401610aad565b506000908152600560205260409020546001600160a01b031690565b610f6a6120a4565b6001600160a01b03821660009081526018602090815260409091208251610f9392840190612dd8565b505050565b6000610fa3826118d5565b9050806001600160a01b0316836001600160a01b0316036110115760405162461bcd60e51b815260206004820152602260248201527f455243373231413a20617070726f76616c20746f2063757272656e74206f776e60448201526132b960f11b6064820152608401610aad565b336001600160a01b038216148061102d575061102d81336109d0565b61109f5760405162461bcd60e51b815260206004820152603960248201527f455243373231413a20617070726f76652063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656420666f7220616c6c000000000000006064820152608401610aad565b610f938383836120fe565b610f9383838361215a565b6110bd6120a4565b60026008540361110f5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610aad565b600260085561111d8161243d565b506001600855565b6001600160a01b0381811660008181526018602052604080822054600a5491516370a0823160e01b8152600481019490945291939192849291909116906370a0823190602401602060405180830381865afa158015611188573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ac9190613419565b9050600082156112345760005b83811015611232576001600160a01b03861660009081526018602052604081208054839081106111eb576111eb6133bc565b6000918252602080832090910154808352601990915260409091205490915060ff1661121f578261121b816133e8565b9350505b508061122a816133e8565b9150506111b9565b505b81156112f75760005b828110156112f557600a54604051632f745c5960e01b81526001600160a01b038881166004830152602482018490526000921690632f745c5990604401602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb9190613419565b60008181526019602052604090205490915060ff166112e257826112de816133e8565b9350505b50806112ed816133e8565b91505061123d565b505b949350505050565b600061130a836119bd565b82106113635760405162461bcd60e51b815260206004820152602260248201527f455243373231413a206f776e657220696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610aad565b600080549080805b838110156113f9576000818152600360209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b031691830191909152156113bd57805192505b876001600160a01b0316836001600160a01b0316036113f0578684036113e957509350610a8592505050565b6001909301925b5060010161136b565b5060405162461bcd60e51b815260206004820152602e60248201527f455243373231413a20756e61626c6520746f2067657420746f6b656e206f662060448201526d0deeedccae440c4f240d2dcc8caf60931b6064820152608401610aad565b6114616120a4565b6002600854036114b35760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610aad565b6002600855604051600090339047908381818185875af1925050503d80600081146114fa576040519150601f19603f3d011682016040523d82523d6000602084013e6114ff565b606091505b505090508061111d5760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b6044820152606401610aad565b610f9383838360405180602001604052806000815250611c73565b6000805482106115bb5760405162461bcd60e51b815260206004820152602360248201527f455243373231413a20676c6f62616c20696e646578206f7574206f6620626f756044820152626e647360e81b6064820152608401610aad565b5090565b6115c76120a4565b600c610f938284836134b2565b6115dc6120a4565b6016805461ff001981166101009182900460ff1615909102179055565b600d5460165460ff1661161e5760405162461bcd60e51b8152600401610aad90613395565b6013546002146116705760405162461bcd60e51b815260206004820181905260248201527f77686974656c697374206d696e74696e67206973206e6f7420616c6c6f7765646044820152606401610aad565b601054600f546116809190613401565b61168b906001613401565b8561169560005490565b61169f9190613401565b106116ec5760405162461bcd60e51b815260206004820152601d60248201527f77686974656c69737420737570706c7920697320736f6c64206f7574210000006044820152606401610aad565b600e54856116f933611f7e565b6117039190613401565b11156117475760405162461bcd60e51b81526020600482015260136024820152721d1bdbc81b585b9e481c195c881dd85b1b195d606a1b6044820152606401610aad565b6117518186613571565b3410156117965760405162461bcd60e51b81526020600482015260136024820152720cae8d0cae440d2e640dcdee840cadcdeeaced606b1b6044820152606401610aad565b6117a08383611f89565b6117ec5760405162461bcd60e51b815260206004820152601b60248201527f706c65617365206d696e74207468726f756768207765627369746500000000006044820152606401610aad565b6017846040516117fc9190613590565b9081526040519081900360200190205460ff161561184a5760405162461bcd60e51b815260206004820152600b60248201526a1a185cda081c995d5cd95960aa1b6044820152606401610aad565b826118563387876118f4565b146118915760405162461bcd60e51b815260206004820152600b60248201526a1a185cda0819985a5b195960aa1b6044820152606401610aad565b60016017856040516118a39190613590565b908152604051908190036020019020805491151560ff199092169190911790556118cd868661208a565b505050505050565b60006118e0826125d1565b5192915050565b6118ef6120a4565b601355565b6000808484843060405160200161190e94939291906135ac565b60408051808303601f19018152919052805160209091012095945050505050565b600c805461193c90613432565b80601f016020809104026020016040519081016040528092919081815260200182805461196890613432565b80156119b55780601f1061198a576101008083540402835291602001916119b5565b820191906000526020600020905b81548152906001019060200180831161199857829003601f168201915b505050505081565b60006001600160a01b038216611a295760405162461bcd60e51b815260206004820152602b60248201527f455243373231413a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b6064820152608401610aad565b506001600160a01b03166000908152600460205260409020546001600160801b031690565b611a566120a4565b611a6060006126a7565b565b611a6a6120a4565b6016805460ff19811660ff90911615179055565b600b805461193c90613432565b611a936120a4565b600d55565b6040805180820190915260008082526020820152610a85826125d1565b606060028054610e5490613432565b336001600160a01b03831603611b1c5760405162461bcd60e51b815260206004820152601a60248201527f455243373231413a20617070726f766520746f2063616c6c65720000000000006044820152606401610aad565b3360008181526006602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611b906120a4565b60165460ff16611bb25760405162461bcd60e51b8152600401610aad90613395565b601354600114611c045760405162461bcd60e51b815260206004820152601b60248201527f7465616d206d696e74696e67206973206e6f7420616c6c6f77656400000000006044820152606401610aad565b600f54611c12906001613401565b81611c1c60005490565b611c269190613401565b10610e375760405162461bcd60e51b815260206004820152601860248201527f7465616d20737570706c7920697320736f6c64206f75742100000000000000006044820152606401610aad565b611c7e84848461215a565b611c8a848484846126f9565b611ca65760405162461bcd60e51b8152600401610aad906135fb565b50505050565b611cb46120a4565b600b610f938284836134b2565b6060611cce826000541190565b611d125760405162461bcd60e51b815260206004820152601560248201527418985b985b9848191bd95cc81b9bdd08195e1a5cdd605a1b6044820152606401610aad565b601654610100900460ff1615611db457600c8054611d2f90613432565b80601f0160208091040260200160405190810160405280929190818152602001828054611d5b90613432565b8015611da85780601f10611d7d57610100808354040283529160200191611da8565b820191906000526020600020905b815481529060010190602001808311611d8b57829003601f168201915b50505050509050919050565b600b8054611d2f90613432565b600d5460165460ff16611de65760405162461bcd60e51b8152600401610aad90613395565b601354600414611e385760405162461bcd60e51b815260206004820152601d60248201527f7075626c6963206d696e74696e67206973206e6f7420616c6c6f7765640000006044820152606401610aad565b601254611e46906001613401565b82611e5060005490565b611e5a9190613401565b10611e995760405162461bcd60e51b815260206004820152600f60248201526e776527726520736f6c64206f75742160881b6044820152606401610aad565b600e5482611ea633611f7e565b611eb09190613401565b1115611ef45760405162461bcd60e51b81526020600482015260136024820152721d1bdbc81b585b9e481c195c881dd85b1b195d606a1b6044820152606401610aad565b611efe8183613571565b341015611f435760405162461bcd60e51b81526020600482015260136024820152720cae8d0cae440d2e640dcdee840cadcdeeaced606b1b6044820152606401610aad565b610f93838361208a565b60186020528160005260406000208181548110611f6957600080fd5b90600052602060002001600091509150505481565b6000610a85826127fa565b6000611fec82611fe6856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90612898565b6009546001600160a01b039182169116149392505050565b61200c6120a4565b600e55565b6120196120a4565b6001600160a01b03811661207e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610aad565b612087816126a7565b50565b610e418282604051806020016040528060008152506128bc565b6007546001600160a01b03163314611a605760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610aad565b60008281526005602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000612165826125d1565b80519091506000906001600160a01b0316336001600160a01b0316148061219c57503361219184610ed7565b6001600160a01b0316145b806121ae575081516121ae90336109d0565b9050806122185760405162461bcd60e51b815260206004820152603260248201527f455243373231413a207472616e736665722063616c6c6572206973206e6f74206044820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b6064820152608401610aad565b846001600160a01b031682600001516001600160a01b03161461228c5760405162461bcd60e51b815260206004820152602660248201527f455243373231413a207472616e736665722066726f6d20696e636f72726563746044820152651037bbb732b960d11b6064820152608401610aad565b6001600160a01b0384166122f05760405162461bcd60e51b815260206004820152602560248201527f455243373231413a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610aad565b61230060008484600001516120fe565b6001600160a01b03858116600090815260046020908152604080832080546001600160801b03198082166001600160801b03928316600019018316179092558986168086528386208054938416938316600190810190931693909317909255888552600390935281842080546001600160e01b031916909117600160a01b426001600160401b0316021790559086018083529120549091166123f3576123a7816000541190565b156123f357825160008281526003602090815260409091208054918601516001600160401b0316600160a01b026001600160e01b03199092166001600160a01b03909316929092171790555b5082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b5050505050565b8060000361248d5760405162461bcd60e51b815260206004820152601860248201527f7175616e74697479206d757374206265206e6f6e7a65726f00000000000000006044820152606401610aad565b6000546000036124d65760405162461bcd60e51b81526020600482015260146024820152731b9bc81d1bdad95b9cc81b5a5b9d1959081e595d60621b6044820152606401610aad565b601554600054811061252a5760405162461bcd60e51b815260206004820152601c60248201527f616c6c206f776e657273686970732068617665206265656e20736574000000006044820152606401610aad565b60005482820160001981019110156125455750600054600019015b815b8181116125c6576000818152600360205260409020546001600160a01b03166125be576000612575826125d1565b80516000848152600360209081526040909120805491909301516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b0390921691909117179055505b600101612547565b506001016015555050565b60408051808201909152600080825260208201526125f0826000541190565b61264f5760405162461bcd60e51b815260206004820152602a60248201527f455243373231413a206f776e657220717565727920666f72206e6f6e657869736044820152693a32b73a103a37b5b2b760b11b6064820152608401610aad565b815b6000818152600360209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b0316918301919091521561269d579392505050565b5060001901612651565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006001600160a01b0384163b156127ef57604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061273d90339089908890889060040161364e565b6020604051808303816000875af1925050508015612778575060408051601f3d908101601f191682019092526127759181019061368b565b60015b6127d5573d8080156127a6576040519150601f19603f3d011682016040523d82523d6000602084013e6127ab565b606091505b5080516000036127cd5760405162461bcd60e51b8152600401610aad906135fb565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506112f7565b506001949350505050565b60006001600160a01b03821661286c5760405162461bcd60e51b815260206004820152603160248201527f455243373231413a206e756d626572206d696e74656420717565727920666f7260448201527020746865207a65726f206164647265737360781b6064820152608401610aad565b506001600160a01b0316600090815260046020526040902054600160801b90046001600160801b031690565b60008060006128a785856128c9565b915091506128b481612937565b509392505050565b610f938383836001612aed565b60008082516041036128ff5760208301516040840151606085015160001a6128f387828585612cb2565b94509450505050612930565b8251604003612928576020830151604084015161291d868383612d9f565b935093505050612930565b506000905060025b9250929050565b600081600481111561294b5761294b6136a8565b036129535750565b6001816004811115612967576129676136a8565b036129b45760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610aad565b60028160048111156129c8576129c86136a8565b03612a155760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610aad565b6003816004811115612a2957612a296136a8565b03612a815760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610aad565b6004816004811115612a9557612a956136a8565b036120875760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610aad565b6000546001600160a01b038516612b505760405162461bcd60e51b815260206004820152602160248201527f455243373231413a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608401610aad565b83600003612bb15760405162461bcd60e51b815260206004820152602860248201527f455243373231413a207175616e74697479206d75737420626520677265617465604482015267072207468616e20360c41b6064820152608401610aad565b6001600160a01b03851660008181526004602090815260408083208054600160801b6001600160801b031982166001600160801b039283168c01831690811782900483168c01909216021790558483526003909152812080546001600160e01b031916909217600160a01b426001600160401b0316021790915581905b85811015612ca95760405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a48315612c9d57612c8160008884886126f9565b612c9d5760405162461bcd60e51b8152600401610aad906135fb565b60019182019101612c2e565b50600055612436565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612ce95750600090506003612d96565b8460ff16601b14158015612d0157508460ff16601c14155b15612d125750600090506004612d96565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612d66573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612d8f57600060019250925050612d96565b9150600090505b94509492505050565b6000806001600160ff1b03831681612dbc60ff86901c601b613401565b9050612dca87828885612cb2565b935093505050935093915050565b828054828255906000526020600020908101928215612e13579160200282015b82811115612e13578251825591602001919060010190612df8565b506115bb9291505b808211156115bb5760008155600101612e1b565b6001600160e01b03198116811461208757600080fd5b600060208284031215612e5757600080fd5b8135612e6281612e2f565b9392505050565b80356001600160a01b0381168114612e8057600080fd5b919050565b600060208284031215612e9757600080fd5b612e6282612e69565b60005b83811015612ebb578181015183820152602001612ea3565b83811115611ca65750506000910152565b60008151808452612ee4816020860160208601612ea0565b601f01601f19169290920160200192915050565b602081526000612e626020830184612ecc565b600060208284031215612f1d57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715612f6257612f62612f24565b604052919050565b60008060408385031215612f7d57600080fd5b612f8683612e69565b91506020808401356001600160401b0380821115612fa357600080fd5b818601915086601f830112612fb757600080fd5b813581811115612fc957612fc9612f24565b8060051b9150612fda848301612f3a565b8181529183018401918481019089841115612ff457600080fd5b938501935b8385101561301257843582529385019390850190612ff9565b8096505050505050509250929050565b6000806040838503121561303557600080fd5b61303e83612e69565b946020939093013593505050565b60008060006060848603121561306157600080fd5b61306a84612e69565b925061307860208501612e69565b9150604084013590509250925092565b6000806020838503121561309b57600080fd5b82356001600160401b03808211156130b257600080fd5b818501915085601f8301126130c657600080fd5b8135818111156130d557600080fd5b8660208285010111156130e757600080fd5b60209290920196919550909350505050565b600082601f83011261310a57600080fd5b81356001600160401b0381111561312357613123612f24565b613136601f8201601f1916602001612f3a565b81815284602083860101111561314b57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561318057600080fd5b61318986612e69565b94506020860135935060408601356001600160401b03808211156131ac57600080fd5b6131b889838a016130f9565b94506060880135935060808801359150808211156131d557600080fd5b506131e2888289016130f9565b9150509295509295909350565b60008060006060848603121561320457600080fd5b61320d84612e69565b92506020840135915060408401356001600160401b0381111561322f57600080fd5b61323b868287016130f9565b9150509250925092565b6000806040838503121561325857600080fd5b61326183612e69565b91506020830135801515811461327657600080fd5b809150509250929050565b60006020828403121561329357600080fd5b81356001600160401b038111156132a957600080fd5b6112f7848285016130f9565b600080600080608085870312156132cb57600080fd5b6132d485612e69565b93506132e260208601612e69565b92506040850135915060608501356001600160401b0381111561330457600080fd5b613310878288016130f9565b91505092959194509250565b6000806040838503121561332f57600080fd5b8235915060208301356001600160401b0381111561334c57600080fd5b613358858286016130f9565b9150509250929050565b6000806040838503121561337557600080fd5b61337e83612e69565b915061338c60208401612e69565b90509250929050565b6020808252600d908201526c1b5a5b9d08191a5cd8589b1959609a1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016133fa576133fa6133d2565b5060010190565b60008219821115613414576134146133d2565b500190565b60006020828403121561342b57600080fd5b5051919050565b600181811c9082168061344657607f821691505b60208210810361346657634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610f9357600081815260208120601f850160051c810160208610156134935750805b601f850160051c820191505b818110156118cd5782815560010161349f565b6001600160401b038311156134c9576134c9612f24565b6134dd836134d78354613432565b8361346c565b6000601f84116001811461351157600085156134f95750838201355b600019600387901b1c1916600186901b178355612436565b600083815260209020601f19861690835b828110156135425786850135825560209485019460019092019101613522565b508682101561355f5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b600081600019048311821515161561358b5761358b6133d2565b500290565b600082516135a2818460208701612ea0565b9190910192915050565b60006bffffffffffffffffffffffff19808760601b16835285601484015284516135dd816034860160208901612ea0565b60609490941b16919092016034810191909152604801949350505050565b60208082526033908201527f455243373231413a207472616e7366657220746f206e6f6e204552433732315260408201527232b1b2b4bb32b91034b6b83632b6b2b73a32b960691b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061368190830184612ecc565b9695505050505050565b60006020828403121561369d57600080fd5b8151612e6281612e2f565b634e487b7160e01b600052602160045260246000fdfea26469706673582212206c65449bad82196718c78aed462d783801bce46098eb7275d08dedd725d773b964736f6c634300080f003300000000000000000000000012787526c03d626aac88e6edc4d0fb930d86c631000000000000000000000000f41f1c3d48bb18b0624a38cadc63f3134a65c23e
Deployed Bytecode
0x6080604052600436106103505760003560e01c80636c0360eb116101c6578063add5a4fa116100f7578063d7224ba011610095578063dd8d74d81161006f578063dd8d74d814610975578063e268e4d314610995578063e985e9c5146109b5578063f2fde38b146109fe57600080fd5b8063d7224ba01461091f578063d7b33e1b14610935578063dc33e6811461095557600080fd5b8063c87b56dd116100d1578063c87b56dd146108bc578063ce6df2b9146108dc578063d1239730146108ef578063d5abeb011461090957600080fd5b8063add5a4fa1461085c578063b88d4fde1461087c578063bbaac02f1461089c57600080fd5b80639231ab2a11610164578063a035b1fe1161013e578063a035b1fe146107c9578063a1cd4490146107df578063a22cb46514610801578063a6ba55c71461082157600080fd5b80639231ab2a1461075157806395d89b411461079e57806396286f9a146107b357600080fd5b80637d55094d116101a05780637d55094d146106e95780638cc54e7f146106fe5780638da5cb5b1461071357806391b7f5ed1461073157600080fd5b80636c0360eb1461069f57806370a08231146106b4578063715018a6146106d457600080fd5b80632de71c5f116102a0578063518302271161023e5780636218186d116102185780636218186d1461062c5780636352211e1461063f578063647287011461065f57806367717e2a1461067f57600080fd5b806351830227146105d857806355f804b3146105f75780635bc020bc1461061757600080fd5b80633ccfd60b1161027a5780633ccfd60b1461056d57806342842e0e14610582578063453c2310146105a25780634f6ccce7146105b857600080fd5b80632de71c5f146105175780632f745c591461053757806333e614131461055757600080fd5b806318160ddd1161030d5780632a2d5394116102e75780632a2d5394146104b55780632c77f025146104cb5780632cfac6ec146104e15780632d20fb60146104f757600080fd5b806318160ddd1461044657806318890b991461046557806323b872dd1461049557600080fd5b806301ffc9a714610355578063057f45681461038a57806306fdde03146103ac578063081812fc146103ce5780630854dee614610406578063095ea7b314610426575b600080fd5b34801561036157600080fd5b50610375610370366004612e45565b610a1e565b60405190151581526020015b60405180910390f35b34801561039657600080fd5b506103aa6103a5366004612e85565b610a8b565b005b3480156103b857600080fd5b506103c1610e45565b6040516103819190612ef8565b3480156103da57600080fd5b506103ee6103e9366004612f0b565b610ed7565b6040516001600160a01b039091168152602001610381565b34801561041257600080fd5b506103aa610421366004612f6a565b610f62565b34801561043257600080fd5b506103aa610441366004613022565b610f98565b34801561045257600080fd5b506000545b604051908152602001610381565b34801561047157600080fd5b50610375610480366004612f0b565b60196020526000908152604090205460ff1681565b3480156104a157600080fd5b506103aa6104b036600461304c565b6110aa565b3480156104c157600080fd5b5061045760145481565b3480156104d757600080fd5b5061045760115481565b3480156104ed57600080fd5b50610457600f5481565b34801561050357600080fd5b506103aa610512366004612f0b565b6110b5565b34801561052357600080fd5b50610457610532366004612e85565b611125565b34801561054357600080fd5b50610457610552366004613022565b6112ff565b34801561056357600080fd5b5061045760105481565b34801561057957600080fd5b506103aa611459565b34801561058e57600080fd5b506103aa61059d36600461304c565b611542565b3480156105ae57600080fd5b50610457600e5481565b3480156105c457600080fd5b506104576105d3366004612f0b565b61155d565b3480156105e457600080fd5b5060165461037590610100900460ff1681565b34801561060357600080fd5b506103aa610612366004613088565b6115bf565b34801561062357600080fd5b506103aa6115d4565b6103aa61063a366004613168565b6115f9565b34801561064b57600080fd5b506103ee61065a366004612f0b565b6118d5565b34801561066b57600080fd5b506103aa61067a366004612f0b565b6118e7565b34801561068b57600080fd5b5061045761069a3660046131ef565b6118f4565b3480156106ab57600080fd5b506103c161192f565b3480156106c057600080fd5b506104576106cf366004612e85565b6119bd565b3480156106e057600080fd5b506103aa611a4e565b3480156106f557600080fd5b506103aa611a62565b34801561070a57600080fd5b506103c1611a7e565b34801561071f57600080fd5b506007546001600160a01b03166103ee565b34801561073d57600080fd5b506103aa61074c366004612f0b565b611a8b565b34801561075d57600080fd5b5061077161076c366004612f0b565b611a98565b6040805182516001600160a01b031681526020928301516001600160401b03169281019290925201610381565b3480156107aa57600080fd5b506103c1611ab5565b3480156107bf57600080fd5b5061045760135481565b3480156107d557600080fd5b50610457600d5481565b3480156107eb57600080fd5b5033600090815260186020526040902054610457565b34801561080d57600080fd5b506103aa61081c366004613245565b611ac4565b34801561082d57600080fd5b5061037561083c366004613281565b805160208183018101805160178252928201919093012091525460ff1681565b34801561086857600080fd5b506103aa610877366004613022565b611b88565b34801561088857600080fd5b506103aa6108973660046132b5565b611c73565b3480156108a857600080fd5b506103aa6108b7366004613088565b611cac565b3480156108c857600080fd5b506103c16108d7366004612f0b565b611cc1565b6103aa6108ea366004613022565b611dc1565b3480156108fb57600080fd5b506016546103759060ff1681565b34801561091557600080fd5b5061045760125481565b34801561092b57600080fd5b5061045760155481565b34801561094157600080fd5b50610457610950366004613022565b611f4d565b34801561096157600080fd5b50610457610970366004612e85565b611f7e565b34801561098157600080fd5b5061037561099036600461331c565b611f89565b3480156109a157600080fd5b506103aa6109b0366004612f0b565b612004565b3480156109c157600080fd5b506103756109d0366004613362565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b348015610a0a57600080fd5b506103aa610a19366004612e85565b612011565b60006001600160e01b031982166380ac58cd60e01b1480610a4f57506001600160e01b03198216635b5e139f60e01b145b80610a6a57506001600160e01b0319821663780e9d6360e01b145b80610a8557506301ffc9a760e01b6001600160e01b03198316145b92915050565b60165460ff16610ab65760405162461bcd60e51b8152600401610aad90613395565b60405180910390fd5b601354600314610b085760405162461bcd60e51b815260206004820152601b60248201527f6b6f6e67206d696e74696e67206973206e6f7420616c6c6f77656400000000006044820152606401610aad565b3360009081526018602052604081205415610bd05733600090815260186020526040812054905b81811015610bb857336000908152601860205260408120805483908110610b5857610b586133bc565b6000918252602080832090910154808352601990915260409091205490915060ff16610ba55783610b88816133e8565b6000838152601960205260409020805460ff191660011790559450505b5080610bb0816133e8565b915050610b2f565b5081601454610bc79190613401565b60145550610df1565b600a546040516370a0823160e01b81523360048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610c19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3d9190613419565b11610c9c5760405162461bcd60e51b815260206004820152602960248201527f6f6e6c792073757072656d65206b6f6e67206f776e657273206172652061626c60448201526819481d1bc81b5a5b9d60ba1b6064820152608401610aad565b600a546040516370a0823160e01b81523360048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610ce5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d099190613419565b905060005b81811015610ddd57600a54604051632f745c5960e01b8152336004820152602481018390526000916001600160a01b031690632f745c5990604401602060405180830381865afa158015610d66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8a9190613419565b60008181526019602052604090205490915060ff16610dca5783610dad816133e8565b6000838152601960205260409020805460ff191660011790559450505b5080610dd5816133e8565b915050610d0e565b5081601454610dec9190613401565b601455505b60008111610e375760405162461bcd60e51b81526020600482015260136024820152726e6f2072656465656d61626c65206b6f6e677360681b6044820152606401610aad565b610e41828261208a565b5050565b606060018054610e5490613432565b80601f0160208091040260200160405190810160405280929190818152602001828054610e8090613432565b8015610ecd5780601f10610ea257610100808354040283529160200191610ecd565b820191906000526020600020905b815481529060010190602001808311610eb057829003601f168201915b5050505050905090565b6000610ee4826000541190565b610f465760405162461bcd60e51b815260206004820152602d60248201527f455243373231413a20617070726f76656420717565727920666f72206e6f6e6560448201526c3c34b9ba32b73a103a37b5b2b760991b6064820152608401610aad565b506000908152600560205260409020546001600160a01b031690565b610f6a6120a4565b6001600160a01b03821660009081526018602090815260409091208251610f9392840190612dd8565b505050565b6000610fa3826118d5565b9050806001600160a01b0316836001600160a01b0316036110115760405162461bcd60e51b815260206004820152602260248201527f455243373231413a20617070726f76616c20746f2063757272656e74206f776e60448201526132b960f11b6064820152608401610aad565b336001600160a01b038216148061102d575061102d81336109d0565b61109f5760405162461bcd60e51b815260206004820152603960248201527f455243373231413a20617070726f76652063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656420666f7220616c6c000000000000006064820152608401610aad565b610f938383836120fe565b610f9383838361215a565b6110bd6120a4565b60026008540361110f5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610aad565b600260085561111d8161243d565b506001600855565b6001600160a01b0381811660008181526018602052604080822054600a5491516370a0823160e01b8152600481019490945291939192849291909116906370a0823190602401602060405180830381865afa158015611188573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ac9190613419565b9050600082156112345760005b83811015611232576001600160a01b03861660009081526018602052604081208054839081106111eb576111eb6133bc565b6000918252602080832090910154808352601990915260409091205490915060ff1661121f578261121b816133e8565b9350505b508061122a816133e8565b9150506111b9565b505b81156112f75760005b828110156112f557600a54604051632f745c5960e01b81526001600160a01b038881166004830152602482018490526000921690632f745c5990604401602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb9190613419565b60008181526019602052604090205490915060ff166112e257826112de816133e8565b9350505b50806112ed816133e8565b91505061123d565b505b949350505050565b600061130a836119bd565b82106113635760405162461bcd60e51b815260206004820152602260248201527f455243373231413a206f776e657220696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610aad565b600080549080805b838110156113f9576000818152600360209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b031691830191909152156113bd57805192505b876001600160a01b0316836001600160a01b0316036113f0578684036113e957509350610a8592505050565b6001909301925b5060010161136b565b5060405162461bcd60e51b815260206004820152602e60248201527f455243373231413a20756e61626c6520746f2067657420746f6b656e206f662060448201526d0deeedccae440c4f240d2dcc8caf60931b6064820152608401610aad565b6114616120a4565b6002600854036114b35760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610aad565b6002600855604051600090339047908381818185875af1925050503d80600081146114fa576040519150601f19603f3d011682016040523d82523d6000602084013e6114ff565b606091505b505090508061111d5760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b6044820152606401610aad565b610f9383838360405180602001604052806000815250611c73565b6000805482106115bb5760405162461bcd60e51b815260206004820152602360248201527f455243373231413a20676c6f62616c20696e646578206f7574206f6620626f756044820152626e647360e81b6064820152608401610aad565b5090565b6115c76120a4565b600c610f938284836134b2565b6115dc6120a4565b6016805461ff001981166101009182900460ff1615909102179055565b600d5460165460ff1661161e5760405162461bcd60e51b8152600401610aad90613395565b6013546002146116705760405162461bcd60e51b815260206004820181905260248201527f77686974656c697374206d696e74696e67206973206e6f7420616c6c6f7765646044820152606401610aad565b601054600f546116809190613401565b61168b906001613401565b8561169560005490565b61169f9190613401565b106116ec5760405162461bcd60e51b815260206004820152601d60248201527f77686974656c69737420737570706c7920697320736f6c64206f7574210000006044820152606401610aad565b600e54856116f933611f7e565b6117039190613401565b11156117475760405162461bcd60e51b81526020600482015260136024820152721d1bdbc81b585b9e481c195c881dd85b1b195d606a1b6044820152606401610aad565b6117518186613571565b3410156117965760405162461bcd60e51b81526020600482015260136024820152720cae8d0cae440d2e640dcdee840cadcdeeaced606b1b6044820152606401610aad565b6117a08383611f89565b6117ec5760405162461bcd60e51b815260206004820152601b60248201527f706c65617365206d696e74207468726f756768207765627369746500000000006044820152606401610aad565b6017846040516117fc9190613590565b9081526040519081900360200190205460ff161561184a5760405162461bcd60e51b815260206004820152600b60248201526a1a185cda081c995d5cd95960aa1b6044820152606401610aad565b826118563387876118f4565b146118915760405162461bcd60e51b815260206004820152600b60248201526a1a185cda0819985a5b195960aa1b6044820152606401610aad565b60016017856040516118a39190613590565b908152604051908190036020019020805491151560ff199092169190911790556118cd868661208a565b505050505050565b60006118e0826125d1565b5192915050565b6118ef6120a4565b601355565b6000808484843060405160200161190e94939291906135ac565b60408051808303601f19018152919052805160209091012095945050505050565b600c805461193c90613432565b80601f016020809104026020016040519081016040528092919081815260200182805461196890613432565b80156119b55780601f1061198a576101008083540402835291602001916119b5565b820191906000526020600020905b81548152906001019060200180831161199857829003601f168201915b505050505081565b60006001600160a01b038216611a295760405162461bcd60e51b815260206004820152602b60248201527f455243373231413a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b6064820152608401610aad565b506001600160a01b03166000908152600460205260409020546001600160801b031690565b611a566120a4565b611a6060006126a7565b565b611a6a6120a4565b6016805460ff19811660ff90911615179055565b600b805461193c90613432565b611a936120a4565b600d55565b6040805180820190915260008082526020820152610a85826125d1565b606060028054610e5490613432565b336001600160a01b03831603611b1c5760405162461bcd60e51b815260206004820152601a60248201527f455243373231413a20617070726f766520746f2063616c6c65720000000000006044820152606401610aad565b3360008181526006602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611b906120a4565b60165460ff16611bb25760405162461bcd60e51b8152600401610aad90613395565b601354600114611c045760405162461bcd60e51b815260206004820152601b60248201527f7465616d206d696e74696e67206973206e6f7420616c6c6f77656400000000006044820152606401610aad565b600f54611c12906001613401565b81611c1c60005490565b611c269190613401565b10610e375760405162461bcd60e51b815260206004820152601860248201527f7465616d20737570706c7920697320736f6c64206f75742100000000000000006044820152606401610aad565b611c7e84848461215a565b611c8a848484846126f9565b611ca65760405162461bcd60e51b8152600401610aad906135fb565b50505050565b611cb46120a4565b600b610f938284836134b2565b6060611cce826000541190565b611d125760405162461bcd60e51b815260206004820152601560248201527418985b985b9848191bd95cc81b9bdd08195e1a5cdd605a1b6044820152606401610aad565b601654610100900460ff1615611db457600c8054611d2f90613432565b80601f0160208091040260200160405190810160405280929190818152602001828054611d5b90613432565b8015611da85780601f10611d7d57610100808354040283529160200191611da8565b820191906000526020600020905b815481529060010190602001808311611d8b57829003601f168201915b50505050509050919050565b600b8054611d2f90613432565b600d5460165460ff16611de65760405162461bcd60e51b8152600401610aad90613395565b601354600414611e385760405162461bcd60e51b815260206004820152601d60248201527f7075626c6963206d696e74696e67206973206e6f7420616c6c6f7765640000006044820152606401610aad565b601254611e46906001613401565b82611e5060005490565b611e5a9190613401565b10611e995760405162461bcd60e51b815260206004820152600f60248201526e776527726520736f6c64206f75742160881b6044820152606401610aad565b600e5482611ea633611f7e565b611eb09190613401565b1115611ef45760405162461bcd60e51b81526020600482015260136024820152721d1bdbc81b585b9e481c195c881dd85b1b195d606a1b6044820152606401610aad565b611efe8183613571565b341015611f435760405162461bcd60e51b81526020600482015260136024820152720cae8d0cae440d2e640dcdee840cadcdeeaced606b1b6044820152606401610aad565b610f93838361208a565b60186020528160005260406000208181548110611f6957600080fd5b90600052602060002001600091509150505481565b6000610a85826127fa565b6000611fec82611fe6856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90612898565b6009546001600160a01b039182169116149392505050565b61200c6120a4565b600e55565b6120196120a4565b6001600160a01b03811661207e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610aad565b612087816126a7565b50565b610e418282604051806020016040528060008152506128bc565b6007546001600160a01b03163314611a605760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610aad565b60008281526005602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000612165826125d1565b80519091506000906001600160a01b0316336001600160a01b0316148061219c57503361219184610ed7565b6001600160a01b0316145b806121ae575081516121ae90336109d0565b9050806122185760405162461bcd60e51b815260206004820152603260248201527f455243373231413a207472616e736665722063616c6c6572206973206e6f74206044820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b6064820152608401610aad565b846001600160a01b031682600001516001600160a01b03161461228c5760405162461bcd60e51b815260206004820152602660248201527f455243373231413a207472616e736665722066726f6d20696e636f72726563746044820152651037bbb732b960d11b6064820152608401610aad565b6001600160a01b0384166122f05760405162461bcd60e51b815260206004820152602560248201527f455243373231413a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610aad565b61230060008484600001516120fe565b6001600160a01b03858116600090815260046020908152604080832080546001600160801b03198082166001600160801b03928316600019018316179092558986168086528386208054938416938316600190810190931693909317909255888552600390935281842080546001600160e01b031916909117600160a01b426001600160401b0316021790559086018083529120549091166123f3576123a7816000541190565b156123f357825160008281526003602090815260409091208054918601516001600160401b0316600160a01b026001600160e01b03199092166001600160a01b03909316929092171790555b5082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b5050505050565b8060000361248d5760405162461bcd60e51b815260206004820152601860248201527f7175616e74697479206d757374206265206e6f6e7a65726f00000000000000006044820152606401610aad565b6000546000036124d65760405162461bcd60e51b81526020600482015260146024820152731b9bc81d1bdad95b9cc81b5a5b9d1959081e595d60621b6044820152606401610aad565b601554600054811061252a5760405162461bcd60e51b815260206004820152601c60248201527f616c6c206f776e657273686970732068617665206265656e20736574000000006044820152606401610aad565b60005482820160001981019110156125455750600054600019015b815b8181116125c6576000818152600360205260409020546001600160a01b03166125be576000612575826125d1565b80516000848152600360209081526040909120805491909301516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b0390921691909117179055505b600101612547565b506001016015555050565b60408051808201909152600080825260208201526125f0826000541190565b61264f5760405162461bcd60e51b815260206004820152602a60248201527f455243373231413a206f776e657220717565727920666f72206e6f6e657869736044820152693a32b73a103a37b5b2b760b11b6064820152608401610aad565b815b6000818152600360209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b0316918301919091521561269d579392505050565b5060001901612651565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006001600160a01b0384163b156127ef57604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061273d90339089908890889060040161364e565b6020604051808303816000875af1925050508015612778575060408051601f3d908101601f191682019092526127759181019061368b565b60015b6127d5573d8080156127a6576040519150601f19603f3d011682016040523d82523d6000602084013e6127ab565b606091505b5080516000036127cd5760405162461bcd60e51b8152600401610aad906135fb565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506112f7565b506001949350505050565b60006001600160a01b03821661286c5760405162461bcd60e51b815260206004820152603160248201527f455243373231413a206e756d626572206d696e74656420717565727920666f7260448201527020746865207a65726f206164647265737360781b6064820152608401610aad565b506001600160a01b0316600090815260046020526040902054600160801b90046001600160801b031690565b60008060006128a785856128c9565b915091506128b481612937565b509392505050565b610f938383836001612aed565b60008082516041036128ff5760208301516040840151606085015160001a6128f387828585612cb2565b94509450505050612930565b8251604003612928576020830151604084015161291d868383612d9f565b935093505050612930565b506000905060025b9250929050565b600081600481111561294b5761294b6136a8565b036129535750565b6001816004811115612967576129676136a8565b036129b45760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610aad565b60028160048111156129c8576129c86136a8565b03612a155760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610aad565b6003816004811115612a2957612a296136a8565b03612a815760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610aad565b6004816004811115612a9557612a956136a8565b036120875760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610aad565b6000546001600160a01b038516612b505760405162461bcd60e51b815260206004820152602160248201527f455243373231413a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608401610aad565b83600003612bb15760405162461bcd60e51b815260206004820152602860248201527f455243373231413a207175616e74697479206d75737420626520677265617465604482015267072207468616e20360c41b6064820152608401610aad565b6001600160a01b03851660008181526004602090815260408083208054600160801b6001600160801b031982166001600160801b039283168c01831690811782900483168c01909216021790558483526003909152812080546001600160e01b031916909217600160a01b426001600160401b0316021790915581905b85811015612ca95760405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a48315612c9d57612c8160008884886126f9565b612c9d5760405162461bcd60e51b8152600401610aad906135fb565b60019182019101612c2e565b50600055612436565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612ce95750600090506003612d96565b8460ff16601b14158015612d0157508460ff16601c14155b15612d125750600090506004612d96565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612d66573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612d8f57600060019250925050612d96565b9150600090505b94509492505050565b6000806001600160ff1b03831681612dbc60ff86901c601b613401565b9050612dca87828885612cb2565b935093505050935093915050565b828054828255906000526020600020908101928215612e13579160200282015b82811115612e13578251825591602001919060010190612df8565b506115bb9291505b808211156115bb5760008155600101612e1b565b6001600160e01b03198116811461208757600080fd5b600060208284031215612e5757600080fd5b8135612e6281612e2f565b9392505050565b80356001600160a01b0381168114612e8057600080fd5b919050565b600060208284031215612e9757600080fd5b612e6282612e69565b60005b83811015612ebb578181015183820152602001612ea3565b83811115611ca65750506000910152565b60008151808452612ee4816020860160208601612ea0565b601f01601f19169290920160200192915050565b602081526000612e626020830184612ecc565b600060208284031215612f1d57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715612f6257612f62612f24565b604052919050565b60008060408385031215612f7d57600080fd5b612f8683612e69565b91506020808401356001600160401b0380821115612fa357600080fd5b818601915086601f830112612fb757600080fd5b813581811115612fc957612fc9612f24565b8060051b9150612fda848301612f3a565b8181529183018401918481019089841115612ff457600080fd5b938501935b8385101561301257843582529385019390850190612ff9565b8096505050505050509250929050565b6000806040838503121561303557600080fd5b61303e83612e69565b946020939093013593505050565b60008060006060848603121561306157600080fd5b61306a84612e69565b925061307860208501612e69565b9150604084013590509250925092565b6000806020838503121561309b57600080fd5b82356001600160401b03808211156130b257600080fd5b818501915085601f8301126130c657600080fd5b8135818111156130d557600080fd5b8660208285010111156130e757600080fd5b60209290920196919550909350505050565b600082601f83011261310a57600080fd5b81356001600160401b0381111561312357613123612f24565b613136601f8201601f1916602001612f3a565b81815284602083860101111561314b57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561318057600080fd5b61318986612e69565b94506020860135935060408601356001600160401b03808211156131ac57600080fd5b6131b889838a016130f9565b94506060880135935060808801359150808211156131d557600080fd5b506131e2888289016130f9565b9150509295509295909350565b60008060006060848603121561320457600080fd5b61320d84612e69565b92506020840135915060408401356001600160401b0381111561322f57600080fd5b61323b868287016130f9565b9150509250925092565b6000806040838503121561325857600080fd5b61326183612e69565b91506020830135801515811461327657600080fd5b809150509250929050565b60006020828403121561329357600080fd5b81356001600160401b038111156132a957600080fd5b6112f7848285016130f9565b600080600080608085870312156132cb57600080fd5b6132d485612e69565b93506132e260208601612e69565b92506040850135915060608501356001600160401b0381111561330457600080fd5b613310878288016130f9565b91505092959194509250565b6000806040838503121561332f57600080fd5b8235915060208301356001600160401b0381111561334c57600080fd5b613358858286016130f9565b9150509250929050565b6000806040838503121561337557600080fd5b61337e83612e69565b915061338c60208401612e69565b90509250929050565b6020808252600d908201526c1b5a5b9d08191a5cd8589b1959609a1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016133fa576133fa6133d2565b5060010190565b60008219821115613414576134146133d2565b500190565b60006020828403121561342b57600080fd5b5051919050565b600181811c9082168061344657607f821691505b60208210810361346657634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610f9357600081815260208120601f850160051c810160208610156134935750805b601f850160051c820191505b818110156118cd5782815560010161349f565b6001600160401b038311156134c9576134c9612f24565b6134dd836134d78354613432565b8361346c565b6000601f84116001811461351157600085156134f95750838201355b600019600387901b1c1916600186901b178355612436565b600083815260209020601f19861690835b828110156135425786850135825560209485019460019092019101613522565b508682101561355f5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b600081600019048311821515161561358b5761358b6133d2565b500290565b600082516135a2818460208701612ea0565b9190910192915050565b60006bffffffffffffffffffffffff19808760601b16835285601484015284516135dd816034860160208901612ea0565b60609490941b16919092016034810191909152604801949350505050565b60208082526033908201527f455243373231413a207472616e7366657220746f206e6f6e204552433732315260408201527232b1b2b4bb32b91034b6b83632b6b2b73a32b960691b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061368190830184612ecc565b9695505050505050565b60006020828403121561369d57600080fd5b8151612e6281612e2f565b634e487b7160e01b600052602160045260246000fdfea26469706673582212206c65449bad82196718c78aed462d783801bce46098eb7275d08dedd725d773b964736f6c634300080f0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000012787526c03d626aac88e6edc4d0fb930d86c631000000000000000000000000f41f1c3d48bb18b0624a38cadc63f3134a65c23e
-----Decoded View---------------
Arg [0] : _kongAddress (address): 0x12787526c03d626AAc88E6EDc4d0Fb930d86C631
Arg [1] : _systemAddress (address): 0xF41F1C3D48BB18b0624a38CAdc63F3134a65c23e
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000012787526c03d626aac88e6edc4d0fb930d86c631
Arg [1] : 000000000000000000000000f41f1c3d48bb18b0624a38cadc63f3134a65c23e
Deployed Bytecode Sourcemap
68118:8984:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54907:372;;;;;;;;;;-1:-1:-1;54907:372:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;54907:372:0;;;;;;;;70576:1366;;;;;;;;;;-1:-1:-1;70576:1366:0;;;;;:::i;:::-;;:::i;:::-;;56793:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;58355:214::-;;;;;;;;;;-1:-1:-1;58355:214:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2061:32:1;;;2043:51;;2031:2;2016:18;58355:214:0;1897:203:1;73706:128:0;;;;;;;;;;-1:-1:-1;73706:128:0;;;;;:::i;:::-;;:::i;57876:413::-;;;;;;;;;;-1:-1:-1;57876:413:0;;;;;:::i;:::-;;:::i;53164:100::-;;;;;;;;;;-1:-1:-1;53217:7:0;53244:12;53164:100;;;3947:25:1;;;3935:2;3920:18;53164:100:0;3801:177:1;69063:48:0;;;;;;;;;;-1:-1:-1;69063:48:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;59231:170;;;;;;;;;;-1:-1:-1;59231:170:0;;;;;:::i;:::-;;:::i;68781:42::-;;;;;;;;;;;;;;;;68572:45;;;;;;;;;;;;;;;;68471:42;;;;;;;;;;;;;;;;75074:124;;;;;;;;;;-1:-1:-1;75074:124:0;;;;;:::i;:::-;;:::i;72674:903::-;;;;;;;;;;-1:-1:-1;72674:903:0;;;;;:::i;:::-;;:::i;53828:1007::-;;;;;;;;;;-1:-1:-1;53828:1007:0;;;;;:::i;:::-;;:::i;68520:45::-;;;;;;;;;;;;;;;;74881:185;;;;;;;;;;;;;:::i;59472:::-;;;;;;;;;;-1:-1:-1;59472:185:0;;;;;:::i;:::-;;:::i;68422:42::-;;;;;;;;;;;;;;;;53341:187;;;;;;;;;;-1:-1:-1;53341:187:0;;;;;:::i;:::-;;:::i;68921:29::-;;;;;;;;;;-1:-1:-1;68921:29:0;;;;;;;;;;;73960:102;;;;;;;;;;-1:-1:-1;73960:102:0;;;;;:::i;:::-;;:::i;72582:84::-;;;;;;;;;;;;;:::i;69645:923::-;;;;;;:::i;:::-;;:::i;56602:124::-;;;;;;;;;;-1:-1:-1;56602:124:0;;;;;:::i;:::-;;:::i;74537:98::-;;;;;;;;;;-1:-1:-1;74537:98:0;;;;;:::i;:::-;;:::i;75534:279::-;;;;;;;;;;-1:-1:-1;75534:279:0;;;;;:::i;:::-;;:::i;68329:28::-;;;;;;;;;;;;;:::i;55343:221::-;;;;;;;;;;-1:-1:-1;55343:221:0;;;;;:::i;:::-;;:::i;17662:103::-;;;;;;;;;;;;;:::i;72485:89::-;;;;;;;;;;;;;:::i;68292:30::-;;;;;;;;;;;;;:::i;17014:87::-;;;;;;;;;;-1:-1:-1;17087:6:0;;-1:-1:-1;;;;;17087:6:0;17014:87;;74321:86;;;;;;;;;;-1:-1:-1;74321:86:0;;;;;:::i;:::-;;:::i;75206:135::-;;;;;;;;;;-1:-1:-1;75206:135:0;;;;;:::i;:::-;;:::i;:::-;;;;7091:13:1;;-1:-1:-1;;;;;7087:39:1;7069:58;;7187:4;7175:17;;;7169:24;-1:-1:-1;;;;;7165:49:1;7143:20;;;7136:79;;;;7042:18;75206:135:0;6859:362:1;56962:104:0;;;;;;;;;;;;;:::i;68676:42::-;;;;;;;;;;;;;;;;68364:51;;;;;;;;;;;;;;;;74759:114;;;;;;;;;;-1:-1:-1;74847:10:0;74811:4;74835:23;;;:11;:23;;;;;:30;74759:114;;58641:288;;;;;;;;;;-1:-1:-1;58641:288:0;;;;;:::i;:::-;;:::i;68959:42::-;;;;;;;;;;-1:-1:-1;68959:42:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69299:338;;;;;;;;;;-1:-1:-1;69299:338:0;;;;;:::i;:::-;;:::i;59728:355::-;;;;;;;;;;-1:-1:-1;59728:355:0;;;;;:::i;:::-;;:::i;73842:110::-;;;;;;;;;;-1:-1:-1;73842:110:0;;;;;:::i;:::-;;:::i;74070:243::-;;;;;;;;;;-1:-1:-1;74070:243:0;;;;;:::i;:::-;;:::i;71950:527::-;;;;;;:::i;:::-;;:::i;68882:32::-;;;;;;;;;;-1:-1:-1;68882:32:0;;;;;;;;68624:45;;;;;;;;;;;;;;;;68830;;;;;;;;;;;;;;;;69008:48;;;;;;;;;;-1:-1:-1;69008:48:0;;;;;:::i;:::-;;:::i;73585:113::-;;;;;;;;;;-1:-1:-1;73585:113:0;;;;;:::i;:::-;;:::i;75349:177::-;;;;;;;;;;-1:-1:-1;75349:177:0;;;;;:::i;:::-;;:::i;74415:114::-;;;;;;;;;;-1:-1:-1;74415:114:0;;;;;:::i;:::-;;:::i;59000:164::-;;;;;;;;;;-1:-1:-1;59000:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;59121:25:0;;;59097:4;59121:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;59000:164;17920:201;;;;;;;;;;-1:-1:-1;17920:201:0;;;;;:::i;:::-;;:::i;54907:372::-;55009:4;-1:-1:-1;;;;;;55046:40:0;;-1:-1:-1;;;55046:40:0;;:105;;-1:-1:-1;;;;;;;55103:48:0;;-1:-1:-1;;;55103:48:0;55046:105;:172;;;-1:-1:-1;;;;;;;55168:50:0;;-1:-1:-1;;;55168:50:0;55046:172;:225;;;-1:-1:-1;;;;;;;;;;29977:40:0;;;55235:36;55026:245;54907:372;-1:-1:-1;;54907:372:0:o;70576:1366::-;70634:11;;;;70626:37;;;;-1:-1:-1;;;70626:37:0;;;;;;;:::i;:::-;;;;;;;;;70682:8;;70694:1;70682:13;70674:53;;;;-1:-1:-1;;;70674:53:0;;9651:2:1;70674:53:0;;;9633:21:1;9690:2;9670:18;;;9663:30;9729:29;9709:18;;;9702:57;9776:18;;70674:53:0;9449:351:1;70674:53:0;70784:10;70740:11;70772:23;;;:11;:23;;;;;:30;:34;70769:1079;;70853:10;70823:15;70841:23;;;:11;:23;;;;;:30;;70910:274;70931:10;70927:1;:14;70910:274;;;70997:10;70967:15;70985:23;;;:11;:23;;;;;:26;;71009:1;;70985:26;;;;;;:::i;:::-;;;;;;;;;;;;;71035:25;;;:16;:25;;;;;;;;70985:26;;-1:-1:-1;71035:25:0;;71030:139;;71086:8;;;;:::i;:::-;71117:25;;;;:16;:25;;;;;:32;;-1:-1:-1;;71117:32:0;71145:4;71117:32;;;71086:8;-1:-1:-1;;71030:139:0;-1:-1:-1;70943:3:0;;;;:::i;:::-;;;;70910:274;;;;71224:6;71211:10;;:19;;;;:::i;:::-;71198:10;:32;-1:-1:-1;70769:1079:0;;;71279:11;;71271:42;;-1:-1:-1;;;71271:42:0;;71302:10;71271:42;;;2043:51:1;71316:1:0;;-1:-1:-1;;;;;71279:11:0;;71271:30;;2016:18:1;;71271:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:46;71263:100;;;;-1:-1:-1;;;71263:100:0;;10733:2:1;71263:100:0;;;10715:21:1;10772:2;10752:18;;;10745:30;10811:34;10791:18;;;10784:62;-1:-1:-1;;;10862:18:1;;;10855:39;10911:19;;71263:100:0;10531:405:1;71263:100:0;71404:11;;71396:42;;-1:-1:-1;;;71396:42:0;;71427:10;71396:42;;;2043:51:1;71378:15:0;;-1:-1:-1;;;;;71404:11:0;;71396:30;;2016:18:1;;71396:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71378:60;;71482:6;71477:313;71498:10;71494:1;:14;71477:313;;;71570:11;;71552:65;;-1:-1:-1;;;71552:65:0;;71603:10;71552:65;;;11115:51:1;11182:18;;;11175:34;;;71534:15:0;;-1:-1:-1;;;;;71570:11:0;;71552:50;;11088:18:1;;71552:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71641:25;;;;:16;:25;;;;;;71534:83;;-1:-1:-1;71641:25:0;;71636:139;;71692:8;;;;:::i;:::-;71723:25;;;;:16;:25;;;;;:32;;-1:-1:-1;;71723:32:0;71751:4;71723:32;;;71692:8;-1:-1:-1;;71636:139:0;-1:-1:-1;71510:3:0;;;;:::i;:::-;;;;71477:313;;;;71830:6;71817:10;;:19;;;;:::i;:::-;71804:10;:32;-1:-1:-1;70769:1079:0;71877:1;71868:6;:10;71860:42;;;;-1:-1:-1;;;71860:42:0;;11422:2:1;71860:42:0;;;11404:21:1;11461:2;11441:18;;;11434:30;-1:-1:-1;;;11480:18:1;;;11473:49;11539:18;;71860:42:0;11220:343:1;71860:42:0;71913:21;71923:2;71927:6;71913:9;:21::i;:::-;70615:1327;70576:1366;:::o;56793:100::-;56847:13;56880:5;56873:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56793:100;:::o;58355:214::-;58423:7;58451:16;58459:7;60395:4;60429:12;-1:-1:-1;60419:22:0;60338:111;58451:16;58443:74;;;;-1:-1:-1;;;58443:74:0;;12155:2:1;58443:74:0;;;12137:21:1;12194:2;12174:18;;;12167:30;12233:34;12213:18;;;12206:62;-1:-1:-1;;;12284:18:1;;;12277:43;12337:19;;58443:74:0;11953:409:1;58443:74:0;-1:-1:-1;58537:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;58537:24:0;;58355:214::o;73706:128::-;16900:13;:11;:13::i;:::-;-1:-1:-1;;;;;73797:18:0;::::1;;::::0;;;:11:::1;:18;::::0;;;;;;;:29;;::::1;::::0;;::::1;::::0;::::1;:::i;:::-;;73706:128:::0;;:::o;57876:413::-;57949:13;57965:24;57981:7;57965:15;:24::i;:::-;57949:40;;58014:5;-1:-1:-1;;;;;58008:11:0;:2;-1:-1:-1;;;;;58008:11:0;;58000:58;;;;-1:-1:-1;;;58000:58:0;;12569:2:1;58000:58:0;;;12551:21:1;12608:2;12588:18;;;12581:30;12647:34;12627:18;;;12620:62;-1:-1:-1;;;12698:18:1;;;12691:32;12740:19;;58000:58:0;12367:398:1;58000:58:0;15645:10;-1:-1:-1;;;;;58093:21:0;;;;:62;;-1:-1:-1;58118:37:0;58135:5;15645:10;59000:164;:::i;58118:37::-;58071:169;;;;-1:-1:-1;;;58071:169:0;;12972:2:1;58071:169:0;;;12954:21:1;13011:2;12991:18;;;12984:30;13050:34;13030:18;;;13023:62;13121:27;13101:18;;;13094:55;13166:19;;58071:169:0;12770:421:1;58071:169:0;58253:28;58262:2;58266:7;58275:5;58253:8;:28::i;59231:170::-;59365:28;59375:4;59381:2;59385:7;59365:9;:28::i;75074:124::-;16900:13;:11;:13::i;:::-;1812:1:::1;2410:7;;:19:::0;2402:63:::1;;;::::0;-1:-1:-1;;;2402:63:0;;13398:2:1;2402:63:0::1;::::0;::::1;13380:21:1::0;13437:2;13417:18;;;13410:30;13476:33;13456:18;;;13449:61;13527:18;;2402:63:0::1;13196:355:1::0;2402:63:0::1;1812:1;2543:7;:18:::0;75162:28:::2;75181:8:::0;75162:18:::2;:28::i;:::-;-1:-1:-1::0;1768:1:0::1;2722:7;:22:::0;75074:124::o;72674:903::-;-1:-1:-1;;;;;72773:18:0;;;72735:7;72773:18;;;:11;:18;;;;;;:25;72869:11;;72861:37;;-1:-1:-1;;;72861:37:0;;;;;2043:51:1;;;;72735:7:0;;72773:25;;72735:7;;72869:11;;;;;72861:30;;2016:18:1;;72861:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72833:65;-1:-1:-1;72933:11:0;72962:14;;72959:258;;72997:6;72992:214;73013:10;73009:1;:14;72992:214;;;-1:-1:-1;;;;;73067:18:0;;73049:15;73067:18;;;:11;:18;;;;;:21;;73086:1;;73067:21;;;;;;:::i;:::-;;;;;;;;;;;;;73112:25;;;:16;:25;;;;;;;;73067:21;;-1:-1:-1;73112:25:0;;73107:84;;73163:8;;;;:::i;:::-;;;;73107:84;-1:-1:-1;73025:3:0;;;;:::i;:::-;;;;72992:214;;;;72959:258;73230:24;;73227:317;;73275:6;73270:263;73291:20;73287:1;:24;73270:263;;;73373:11;;73355:60;;-1:-1:-1;;;73355:60:0;;-1:-1:-1;;;;;11133:32:1;;;73355:60:0;;;11115:51:1;11182:18;;;11175:34;;;73337:15:0;;73373:11;;73355:50;;11088:18:1;;73355:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73439:25;;;;:16;:25;;;;;;73337:78;;-1:-1:-1;73439:25:0;;73434:84;;73490:8;;;;:::i;:::-;;;;73434:84;-1:-1:-1;73313:3:0;;;;:::i;:::-;;;;73270:263;;;;73227:317;73563:6;72674:903;-1:-1:-1;;;;72674:903:0:o;53828:1007::-;53917:7;53953:16;53963:5;53953:9;:16::i;:::-;53945:5;:24;53937:71;;;;-1:-1:-1;;;53937:71:0;;13758:2:1;53937:71:0;;;13740:21:1;13797:2;13777:18;;;13770:30;13836:34;13816:18;;;13809:62;-1:-1:-1;;;13887:18:1;;;13880:32;13929:19;;53937:71:0;13556:398:1;53937:71:0;54019:22;53244:12;;;54019:22;;54282:466;54302:14;54298:1;:18;54282:466;;;54342:31;54376:14;;;:11;:14;;;;;;;;;54342:48;;;;;;;;;-1:-1:-1;;;;;54342:48:0;;;;;-1:-1:-1;;;54342:48:0;;;-1:-1:-1;;;;;54342:48:0;;;;;;;;54413:28;54409:111;;54486:14;;;-1:-1:-1;54409:111:0;54563:5;-1:-1:-1;;;;;54542:26:0;:17;-1:-1:-1;;;;;54542:26:0;;54538:195;;54612:5;54597:11;:20;54593:85;;-1:-1:-1;54653:1:0;-1:-1:-1;54646:8:0;;-1:-1:-1;;;54646:8:0;54593:85;54700:13;;;;;54538:195;-1:-1:-1;54318:3:0;;54282:466;;;-1:-1:-1;54771:56:0;;-1:-1:-1;;;54771:56:0;;14161:2:1;54771:56:0;;;14143:21:1;14200:2;14180:18;;;14173:30;14239:34;14219:18;;;14212:62;-1:-1:-1;;;14290:18:1;;;14283:44;14344:19;;54771:56:0;13959:410:1;74881:185:0;16900:13;:11;:13::i;:::-;1812:1:::1;2410:7;;:19:::0;2402:63:::1;;;::::0;-1:-1:-1;;;2402:63:0;;13398:2:1;2402:63:0::1;::::0;::::1;13380:21:1::0;13437:2;13417:18;;;13410:30;13476:33;13456:18;;;13449:61;13527:18;;2402:63:0::1;13196:355:1::0;2402:63:0::1;1812:1;2543:7;:18:::0;74963:49:::2;::::0;74945:12:::2;::::0;74963:10:::2;::::0;74986:21:::2;::::0;74945:12;74963:49;74945:12;74963:49;74986:21;74963:10;:49:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74944:68;;;75031:7;75023:35;;;::::0;-1:-1:-1;;;75023:35:0;;14786:2:1;75023:35:0::2;::::0;::::2;14768:21:1::0;14825:2;14805:18;;;14798:30;-1:-1:-1;;;14844:18:1;;;14837:45;14899:18;;75023:35:0::2;14584:339:1::0;59472:185:0;59610:39;59627:4;59633:2;59637:7;59610:39;;;;;;;;;;;;:16;:39::i;53341:187::-;53408:7;53244:12;;53436:5;:21;53428:69;;;;-1:-1:-1;;;53428:69:0;;15130:2:1;53428:69:0;;;15112:21:1;15169:2;15149:18;;;15142:30;15208:34;15188:18;;;15181:62;-1:-1:-1;;;15259:18:1;;;15252:33;15302:19;;53428:69:0;14928:399:1;53428:69:0;-1:-1:-1;53515:5:0;53341:187::o;73960:102::-;16900:13;:11;:13::i;:::-;74036:7:::1;:18;74046:8:::0;;74036:7;:18:::1;:::i;72582:84::-:0;16900:13;:11;:13::i;:::-;72650:8:::1;::::0;;-1:-1:-1;;72638:20:0;::::1;72650:8;::::0;;;::::1;;;72649:9;72638:20:::0;;::::1;;::::0;;72582:84::o;69645:923::-;69803:5;;69827:11;;;;69819:37;;;;-1:-1:-1;;;69819:37:0;;;;;;;:::i;:::-;69875:8;;69887:1;69875:13;69867:58;;;;-1:-1:-1;;;69867:58:0;;17592:2:1;69867:58:0;;;17574:21:1;;;17611:18;;;17604:30;17670:34;17650:18;;;17643:62;17722:18;;69867:58:0;17390:356:1;69867:58:0;69990:15;;69977:10;;:28;;;;:::i;:::-;:32;;70008:1;69977:32;:::i;:::-;69960:14;69944:13;53217:7;53244:12;;53164:100;69944:13;:30;;;;:::i;:::-;:65;69936:107;;;;-1:-1:-1;;;69936:107:0;;17953:2:1;69936:107:0;;;17935:21:1;17992:2;17972:18;;;17965:30;18031:31;18011:18;;;18004:59;18080:18;;69936:107:0;17751:353:1;69936:107:0;70107:12;;70089:14;70062:24;70075:10;70062:12;:24::i;:::-;:41;;;;:::i;:::-;:57;;70054:89;;;;-1:-1:-1;;;70054:89:0;;18311:2:1;70054:89:0;;;18293:21:1;18350:2;18330:18;;;18323:30;-1:-1:-1;;;18369:18:1;;;18362:49;18428:18;;70054:89:0;18109:343:1;70054:89:0;70175:21;70192:4;70175:14;:21;:::i;:::-;70162:9;:34;;70154:66;;;;-1:-1:-1;;;70154:66:0;;18832:2:1;70154:66:0;;;18814:21:1;18871:2;18851:18;;;18844:30;-1:-1:-1;;;18890:18:1;;;18883:49;18949:18;;70154:66:0;18630:343:1;70154:66:0;70274:28;70286:4;70292:9;70274:11;:28::i;:::-;70266:68;;;;-1:-1:-1;;;70266:68:0;;19180:2:1;70266:68:0;;;19162:21:1;19219:2;19199:18;;;19192:30;19258:29;19238:18;;;19231:57;19305:18;;70266:68:0;18978:351:1;70266:68:0;70354:11;70366:5;70354:18;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;70353:19;70345:43;;;;-1:-1:-1;;;70345:43:0;;19817:2:1;70345:43:0;;;19799:21:1;19856:2;19836:18;;;19829:30;-1:-1:-1;;;19875:18:1;;;19868:41;19926:18;;70345:43:0;19615:335:1;70345:43:0;70461:4;70407:50;70423:10;70435:14;70451:5;70407:15;:50::i;:::-;:58;70399:82;;;;-1:-1:-1;;;70399:82:0;;20157:2:1;70399:82:0;;;20139:21:1;20196:2;20176:18;;;20169:30;-1:-1:-1;;;20215:18:1;;;20208:41;20266:18;;70399:82:0;19955:335:1;70399:82:0;70516:4;70495:11;70507:5;70495:18;;;;;;:::i;:::-;;;;;;;;;;;;;;:25;;;;;-1:-1:-1;;70495:25:0;;;;;;;;;70531:29;70541:2;70545:14;70531:9;:29::i;:::-;69780:788;69645:923;;;;;:::o;56602:124::-;56666:7;56693:20;56705:7;56693:11;:20::i;:::-;:25;;56602:124;-1:-1:-1;;56602:124:0:o;74537:98::-;16900:13;:11;:13::i;:::-;74607:8:::1;:20:::0;74537:98::o;75534:279::-;75655:7;75681:12;75733:6;75741;75749:5;75764:4;75716:54;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;75716:54:0;;;;;;75696:85;;75716:54;75696:85;;;;;75534:279;-1:-1:-1;;;;;75534:279:0:o;68329:28::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;55343:221::-;55407:7;-1:-1:-1;;;;;55435:19:0;;55427:75;;;;-1:-1:-1;;;55427:75:0;;21088:2:1;55427:75:0;;;21070:21:1;21127:2;21107:18;;;21100:30;21166:34;21146:18;;;21139:62;-1:-1:-1;;;21217:18:1;;;21210:41;21268:19;;55427:75:0;20886:407:1;55427:75:0;-1:-1:-1;;;;;;55528:19:0;;;;;:12;:19;;;;;:27;-1:-1:-1;;;;;55528:27:0;;55343:221::o;17662:103::-;16900:13;:11;:13::i;:::-;17727:30:::1;17754:1;17727:18;:30::i;:::-;17662:103::o:0;72485:89::-;16900:13;:11;:13::i;:::-;72555:11:::1;::::0;;-1:-1:-1;;72540:26:0;::::1;72555:11;::::0;;::::1;72554:12;72540:26;::::0;;72485:89::o;68292:30::-;;;;;;;:::i;74321:86::-;16900:13;:11;:13::i;:::-;74385:5:::1;:14:::0;74321:86::o;75206:135::-;-1:-1:-1;;;;;;;;;;;;;;;;;75313:20:0;75325:7;75313:11;:20::i;56962:104::-;57018:13;57051:7;57044:14;;;;;:::i;58641:288::-;15645:10;-1:-1:-1;;;;;58736:24:0;;;58728:63;;;;-1:-1:-1;;;58728:63:0;;21500:2:1;58728:63:0;;;21482:21:1;21539:2;21519:18;;;21512:30;21578:28;21558:18;;;21551:56;21624:18;;58728:63:0;21298:350:1;58728:63:0;15645:10;58804:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;58804:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;58804:53:0;;;;;;;;;;58873:48;;540:41:1;;;58804:42:0;;15645:10;58873:48;;513:18:1;58873:48:0;;;;;;;58641:288;;:::o;69299:338::-;16900:13;:11;:13::i;:::-;69391:11:::1;::::0;::::1;;69383:37;;;;-1:-1:-1::0;;;69383:37:0::1;;;;;;;:::i;:::-;69439:8;;69451:1;69439:13;69431:53;;;::::0;-1:-1:-1;;;69431:53:0;;21855:2:1;69431:53:0::1;::::0;::::1;21837:21:1::0;21894:2;21874:18;;;21867:30;21933:29;21913:18;;;21906:57;21980:18;;69431:53:0::1;21653:351:1::0;69431:53:0::1;69536:10;::::0;:14:::1;::::0;69549:1:::1;69536:14;:::i;:::-;69519;69503:13;53217:7:::0;53244:12;;53164:100;69503:13:::1;:30;;;;:::i;:::-;:47;69495:84;;;::::0;-1:-1:-1;;;69495:84:0;;22211:2:1;69495:84:0::1;::::0;::::1;22193:21:1::0;22250:2;22230:18;;;22223:30;22289:26;22269:18;;;22262:54;22333:18;;69495:84:0::1;22009:348:1::0;59728:355:0;59887:28;59897:4;59903:2;59907:7;59887:9;:28::i;:::-;59948:48;59971:4;59977:2;59981:7;59990:5;59948:22;:48::i;:::-;59926:149;;;;-1:-1:-1;;;59926:149:0;;;;;;;:::i;:::-;59728:355;;;;:::o;73842:110::-;16900:13;:11;:13::i;:::-;73922:9:::1;:22;73934:10:::0;;73922:9;:22:::1;:::i;74070:243::-:0;74135:13;74169:16;74177:7;60395:4;60429:12;-1:-1:-1;60419:22:0;60338:111;74169:16;74161:50;;;;-1:-1:-1;;;74161:50:0;;22984:2:1;74161:50:0;;;22966:21:1;23023:2;23003:18;;;22996:30;-1:-1:-1;;;23042:18:1;;;23035:51;23103:18;;74161:50:0;22782:345:1;74161:50:0;74228:8;;;;;;;74224:55;;;74260:7;74253:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74070:243;;;:::o;74224:55::-;74296:9;74289:16;;;;;:::i;71950:527::-;72046:5;;72070:11;;;;72062:37;;;;-1:-1:-1;;;72062:37:0;;;;;;;:::i;:::-;72118:8;;72130:1;72118:13;72110:55;;;;-1:-1:-1;;;72110:55:0;;23334:2:1;72110:55:0;;;23316:21:1;23373:2;23353:18;;;23346:30;23412:31;23392:18;;;23385:59;23461:18;;72110:55:0;23132:353:1;72110:55:0;72217:9;;:13;;72229:1;72217:13;:::i;:::-;72200:14;72184:13;53217:7;53244:12;;53164:100;72184:13;:30;;;;:::i;:::-;:46;72176:74;;;;-1:-1:-1;;;72176:74:0;;23692:2:1;72176:74:0;;;23674:21:1;23731:2;23711:18;;;23704:30;-1:-1:-1;;;23750:18:1;;;23743:45;23805:18;;72176:74:0;23490:339:1;72176:74:0;72314:12;;72296:14;72269:24;72282:10;72269:12;:24::i;:::-;:41;;;;:::i;:::-;:57;;72261:89;;;;-1:-1:-1;;;72261:89:0;;18311:2:1;72261:89:0;;;18293:21:1;18350:2;18330:18;;;18323:30;-1:-1:-1;;;18369:18:1;;;18362:49;18428:18;;72261:89:0;18109:343:1;72261:89:0;72382:21;72399:4;72382:14;:21;:::i;:::-;72369:9;:34;;72361:66;;;;-1:-1:-1;;;72361:66:0;;18832:2:1;72361:66:0;;;18814:21:1;18871:2;18851:18;;;18844:30;-1:-1:-1;;;18890:18:1;;;18883:49;18949:18;;72361:66:0;18630:343:1;72361:66:0;72440:29;72450:2;72454:14;72440:9;:29::i;69008:48::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;73585:113::-;73643:7;73670:20;73684:5;73670:13;:20::i;75349:177::-;75429:4;75470:48;75508:9;75470:29;:4;13773:58;;29128:66:1;13773:58:0;;;29116:79:1;29211:12;;;29204:28;;;13640:7:0;;29248:12:1;;13773:58:0;;;;;;;;;;;;13763:69;;;;;;13756:76;;13571:269;;;;75470:29;:37;;:48::i;:::-;75453:13;;-1:-1:-1;;;;;75453:65:0;;;:13;;:65;;75349:177;-1:-1:-1;;;75349:177:0:o;74415:114::-;16900:13;:11;:13::i;:::-;74493:12:::1;:28:::0;74415:114::o;17920:201::-;16900:13;:11;:13::i;:::-;-1:-1:-1;;;;;18009:22:0;::::1;18001:73;;;::::0;-1:-1:-1;;;18001:73:0;;24036:2:1;18001:73:0::1;::::0;::::1;24018:21:1::0;24075:2;24055:18;;;24048:30;24114:34;24094:18;;;24087:62;-1:-1:-1;;;24165:18:1;;;24158:36;24211:19;;18001:73:0::1;23834:402:1::0;18001:73:0::1;18085:28;18104:8;18085:18;:28::i;:::-;17920:201:::0;:::o;60457:104::-;60526:27;60536:2;60540:8;60526:27;;;;;;;;;;;;:9;:27::i;17179:132::-;17087:6;;-1:-1:-1;;;;;17087:6:0;15645:10;17243:23;17235:68;;;;-1:-1:-1;;;17235:68:0;;24443:2:1;17235:68:0;;;24425:21:1;;;24462:18;;;24455:30;24521:34;24501:18;;;24494:62;24573:18;;17235:68:0;24241:356:1;65258:196:0;65373:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;65373:29:0;-1:-1:-1;;;;;65373:29:0;;;;;;;;;65418:28;;65373:24;;65418:28;;;;;;;65258:196;;;:::o;63138:2002::-;63253:35;63291:20;63303:7;63291:11;:20::i;:::-;63366:18;;63253:58;;-1:-1:-1;63324:22:0;;-1:-1:-1;;;;;63350:34:0;15645:10;-1:-1:-1;;;;;63350:34:0;;:87;;;-1:-1:-1;15645:10:0;63401:20;63413:7;63401:11;:20::i;:::-;-1:-1:-1;;;;;63401:36:0;;63350:87;:154;;;-1:-1:-1;63471:18:0;;63454:50;;15645:10;59000:164;:::i;63454:50::-;63324:181;;63526:17;63518:80;;;;-1:-1:-1;;;63518:80:0;;24804:2:1;63518:80:0;;;24786:21:1;24843:2;24823:18;;;24816:30;24882:34;24862:18;;;24855:62;-1:-1:-1;;;24933:18:1;;;24926:48;24991:19;;63518:80:0;24602:414:1;63518:80:0;63641:4;-1:-1:-1;;;;;63619:26:0;:13;:18;;;-1:-1:-1;;;;;63619:26:0;;63611:77;;;;-1:-1:-1;;;63611:77:0;;25223:2:1;63611:77:0;;;25205:21:1;25262:2;25242:18;;;25235:30;25301:34;25281:18;;;25274:62;-1:-1:-1;;;25352:18:1;;;25345:36;25398:19;;63611:77:0;25021:402:1;63611:77:0;-1:-1:-1;;;;;63707:16:0;;63699:66;;;;-1:-1:-1;;;63699:66:0;;25630:2:1;63699:66:0;;;25612:21:1;25669:2;25649:18;;;25642:30;25708:34;25688:18;;;25681:62;-1:-1:-1;;;25759:18:1;;;25752:35;25804:19;;63699:66:0;25428:401:1;63699:66:0;63886:49;63903:1;63907:7;63916:13;:18;;;63886:8;:49::i;:::-;-1:-1:-1;;;;;64231:18:0;;;;;;;:12;:18;;;;;;;;:31;;-1:-1:-1;;;;;;64231:31:0;;;-1:-1:-1;;;;;64231:31:0;;;-1:-1:-1;;64231:31:0;;;;;;;64277:16;;;;;;;;;:29;;;;;;;;-1:-1:-1;64277:29:0;;;;;;;;;;;;;64323:20;;;:11;:20;;;;;;:30;;-1:-1:-1;;;;;;64368:61:0;;;;-1:-1:-1;;;64413:15:0;-1:-1:-1;;;;;64368:61:0;;;;;64703:11;;;64733:24;;;;;:29;64703:11;;64733:29;64729:295;;64801:20;64809:11;60395:4;60429:12;-1:-1:-1;60419:22:0;60338:111;64801:20;64797:212;;;64878:18;;;64846:24;;;:11;:24;;;;;;;;:50;;64961:28;;;;-1:-1:-1;;;;;64919:70:0;-1:-1:-1;;;64919:70:0;-1:-1:-1;;;;;;64919:70:0;;;-1:-1:-1;;;;;64846:50:0;;;64919:70;;;;;;;64797:212;64206:829;65071:7;65067:2;-1:-1:-1;;;;;65052:27:0;65061:4;-1:-1:-1;;;;;65052:27:0;;;;;;;;;;;65090:42;63242:1898;;63138:2002;;;:::o;75925:1174::-;75999:8;76011:1;75999:13;75991:50;;;;-1:-1:-1;;;75991:50:0;;26036:2:1;75991:50:0;;;26018:21:1;26075:2;26055:18;;;26048:30;26114:26;26094:18;;;26087:54;26158:18;;75991:50:0;25834:348:1;75991:50:0;76060:12;;76076:1;76060:17;76052:50;;;;-1:-1:-1;;;76052:50:0;;26389:2:1;76052:50:0;;;26371:21:1;26428:2;26408:18;;;26401:30;-1:-1:-1;;;26447:18:1;;;26440:50;26507:18;;76052:50:0;26187:344:1;76052:50:0;76149:24;;76113:33;76220:12;76192:40;;76184:81;;;;-1:-1:-1;;;76184:81:0;;26738:2:1;76184:81:0;;;26720:21:1;26777:2;26757:18;;;26750:30;26816;26796:18;;;26789:58;26864:18;;76184:81:0;26536:352:1;76184:81:0;76411:16;76567:12;76430:36;;;-1:-1:-1;;76430:40:0;;;-1:-1:-1;76548:95:0;;;-1:-1:-1;76611:12:0;;-1:-1:-1;;76611:16:0;76548:95;76676:25;76659:366;76708:8;76703:1;:13;76659:366;;76777:1;76746:14;;;:11;:14;;;;;:19;-1:-1:-1;;;;;76746:19:0;76742:268;;76804:31;76838:14;76850:1;76838:11;:14::i;:::-;76897;;;76875;;;:11;:14;;;;;;;;:36;;76966:24;;;;;-1:-1:-1;;;;;76934:56:0;-1:-1:-1;;;76934:56:0;-1:-1:-1;;;;;;76934:56:0;;;-1:-1:-1;;;;;76875:36:0;;;76934:56;;;;;;;-1:-1:-1;76742:268:0;76718:3;;76659:366;;;-1:-1:-1;77079:1:0;77068:12;77041:24;:39;-1:-1:-1;;75925:1174:0:o;56003:537::-;-1:-1:-1;;;;;;;;;;;;;;;;;56106:16:0;56114:7;60395:4;60429:12;-1:-1:-1;60419:22:0;60338:111;56106:16;56098:71;;;;-1:-1:-1;;;56098:71:0;;27095:2:1;56098:71:0;;;27077:21:1;27134:2;27114:18;;;27107:30;27173:34;27153:18;;;27146:62;-1:-1:-1;;;27224:18:1;;;27217:40;27274:19;;56098:71:0;26893:406:1;56098:71:0;56227:7;56207:245;56274:31;56308:17;;;:11;:17;;;;;;;;;56274:51;;;;;;;;;-1:-1:-1;;;;;56274:51:0;;;;;-1:-1:-1;;;56274:51:0;;;-1:-1:-1;;;;;56274:51:0;;;;;;;;56348:28;56344:93;;56408:9;56003:537;-1:-1:-1;;;56003:537:0:o;56344:93::-;-1:-1:-1;;;56247:6:0;56207:245;;18281:191;18374:6;;;-1:-1:-1;;;;;18391:17:0;;;-1:-1:-1;;;;;;18391:17:0;;;;;;;18424:40;;18374:6;;;18391:17;18374:6;;18424:40;;18355:16;;18424:40;18344:128;18281:191;:::o;66019:804::-;66174:4;-1:-1:-1;;;;;66195:13:0;;20007:19;:23;66191:625;;66231:72;;-1:-1:-1;;;66231:72:0;;-1:-1:-1;;;;;66231:36:0;;;;;:72;;15645:10;;66282:4;;66288:7;;66297:5;;66231:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66231:72:0;;;;;;;;-1:-1:-1;;66231:72:0;;;;;;;;;;;;:::i;:::-;;;66227:534;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66477:6;:13;66494:1;66477:18;66473:273;;66520:61;;-1:-1:-1;;;66520:61:0;;;;;;;:::i;66473:273::-;66696:6;66690:13;66681:6;66677:2;66673:15;66666:38;66227:534;-1:-1:-1;;;;;;66354:55:0;-1:-1:-1;;;66354:55:0;;-1:-1:-1;66347:62:0;;66191:625;-1:-1:-1;66800:4:0;66019:804;;;;;;:::o;55572:229::-;55633:7;-1:-1:-1;;;;;55661:19:0;;55653:81;;;;-1:-1:-1;;;55653:81:0;;28670:2:1;55653:81:0;;;28652:21:1;28709:2;28689:18;;;28682:30;28748:34;28728:18;;;28721:62;-1:-1:-1;;;28799:18:1;;;28792:47;28856:19;;55653:81:0;28468:413:1;55653:81:0;-1:-1:-1;;;;;;55760:19:0;;;;;:12;:19;;;;;:32;-1:-1:-1;;;55760:32:0;;-1:-1:-1;;;;;55760:32:0;;55572:229::o;9769:231::-;9847:7;9868:17;9887:18;9909:27;9920:4;9926:9;9909:10;:27::i;:::-;9867:69;;;;9947:18;9959:5;9947:11;:18::i;:::-;-1:-1:-1;9983:9:0;9769:231;-1:-1:-1;;;9769:231:0:o;60924:163::-;61047:32;61053:2;61057:8;61067:5;61074:4;61047:5;:32::i;7563:1404::-;7644:7;7653:12;7878:9;:16;7898:2;7878:22;7874:1086;;8222:4;8207:20;;8201:27;8272:4;8257:20;;8251:27;8330:4;8315:20;;8309:27;7917:9;8301:36;8373:25;8384:4;8301:36;8201:27;8251;8373:10;:25::i;:::-;8366:32;;;;;;;;;7874:1086;8420:9;:16;8440:2;8420:22;8416:544;;8743:4;8728:20;;8722:27;8794:4;8779:20;;8773:27;8836:23;8847:4;8722:27;8773;8836:10;:23::i;:::-;8829:30;;;;;;;;8416:544;-1:-1:-1;8908:1:0;;-1:-1:-1;8912:35:0;8416:544;7563:1404;;;;;:::o;5834:643::-;5912:20;5903:5;:29;;;;;;;;:::i;:::-;;5899:571;;5834:643;:::o;5899:571::-;6010:29;6001:5;:38;;;;;;;;:::i;:::-;;5997:473;;6056:34;;-1:-1:-1;;;6056:34:0;;29605:2:1;6056:34:0;;;29587:21:1;29644:2;29624:18;;;29617:30;29683:26;29663:18;;;29656:54;29727:18;;6056:34:0;29403:348:1;5997:473:0;6121:35;6112:5;:44;;;;;;;;:::i;:::-;;6108:362;;6173:41;;-1:-1:-1;;;6173:41:0;;29958:2:1;6173:41:0;;;29940:21:1;29997:2;29977:18;;;29970:30;30036:33;30016:18;;;30009:61;30087:18;;6173:41:0;29756:355:1;6108:362:0;6245:30;6236:5;:39;;;;;;;;:::i;:::-;;6232:238;;6292:44;;-1:-1:-1;;;6292:44:0;;30318:2:1;6292:44:0;;;30300:21:1;30357:2;30337:18;;;30330:30;30396:34;30376:18;;;30369:62;-1:-1:-1;;;30447:18:1;;;30440:32;30489:19;;6292:44:0;30116:398:1;6232:238:0;6367:30;6358:5;:39;;;;;;;;:::i;:::-;;6354:116;;6414:44;;-1:-1:-1;;;6414:44:0;;30721:2:1;6414:44:0;;;30703:21:1;30760:2;30740:18;;;30733:30;30799:34;30779:18;;;30772:62;-1:-1:-1;;;30850:18:1;;;30843:32;30892:19;;6414:44:0;30519:398:1;61346:1538:0;61485:20;61508:12;-1:-1:-1;;;;;61539:16:0;;61531:62;;;;-1:-1:-1;;;61531:62:0;;31124:2:1;61531:62:0;;;31106:21:1;31163:2;31143:18;;;31136:30;31202:34;31182:18;;;31175:62;-1:-1:-1;;;31253:18:1;;;31246:31;31294:19;;61531:62:0;30922:397:1;61531:62:0;61612:8;61624:1;61612:13;61604:66;;;;-1:-1:-1;;;61604:66:0;;31526:2:1;61604:66:0;;;31508:21:1;31565:2;31545:18;;;31538:30;31604:34;31584:18;;;31577:62;-1:-1:-1;;;31655:18:1;;;31648:38;31703:19;;61604:66:0;31324:404:1;61604:66:0;-1:-1:-1;;;;;62022:16:0;;;;;;:12;:16;;;;;;;;:45;;-1:-1:-1;;;;;;;;;62022:45:0;;-1:-1:-1;;;;;62022:45:0;;;;;;;;;;62082:50;;;;;;;;;;;;;;62149:25;;;:11;:25;;;;;:35;;-1:-1:-1;;;;;;62199:66:0;;;;-1:-1:-1;;;62249:15:0;-1:-1:-1;;;;;62199:66:0;;;;;;62149:25;;62334:415;62354:8;62350:1;:12;62334:415;;;62393:38;;62418:12;;-1:-1:-1;;;;;62393:38:0;;;62410:1;;62393:38;;62410:1;;62393:38;62454:4;62450:249;;;62517:59;62548:1;62552:2;62556:12;62570:5;62517:22;:59::i;:::-;62483:196;;;;-1:-1:-1;;;62483:196:0;;;;;;;:::i;:::-;62719:14;;;;;62364:3;62334:415;;;-1:-1:-1;62765:12:0;:27;62816:60;59728:355;11221:1632;11352:7;;12286:66;12273:79;;12269:163;;;-1:-1:-1;12385:1:0;;-1:-1:-1;12389:30:0;12369:51;;12269:163;12446:1;:7;;12451:2;12446:7;;:18;;;;;12457:1;:7;;12462:2;12457:7;;12446:18;12442:102;;;-1:-1:-1;12497:1:0;;-1:-1:-1;12501:30:0;12481:51;;12442:102;12658:24;;;12641:14;12658:24;;;;;;;;;31960:25:1;;;32033:4;32021:17;;32001:18;;;31994:45;;;;32055:18;;;32048:34;;;32098:18;;;32091:34;;;12658:24:0;;31932:19:1;;12658:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;12658:24:0;;-1:-1:-1;;12658:24:0;;;-1:-1:-1;;;;;;;12697:20:0;;12693:103;;12750:1;12754:29;12734:50;;;;;;;12693:103;12816:6;-1:-1:-1;12824:20:0;;-1:-1:-1;11221:1632:0;;;;;;;;:::o;10263:344::-;10377:7;;-1:-1:-1;;;;;10423:80:0;;10377:7;10530:25;10546:3;10531:18;;;10553:2;10530:25;:::i;:::-;10514:42;;10574:25;10585:4;10591:1;10594;10597;10574:10;:25::i;:::-;10567:32;;;;;;10263:344;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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;:::-;384:5;150:245;-1:-1:-1;;;150:245:1:o;592:173::-;660:20;;-1:-1:-1;;;;;709:31:1;;699:42;;689:70;;755:1;752;745:12;689:70;592:173;;;:::o;770:186::-;829:6;882:2;870:9;861:7;857:23;853:32;850:52;;;898:1;895;888:12;850:52;921:29;940:9;921:29;:::i;961:258::-;1033:1;1043:113;1057:6;1054:1;1051:13;1043:113;;;1133:11;;;1127:18;1114:11;;;1107:39;1079:2;1072:10;1043:113;;;1174:6;1171:1;1168:13;1165:48;;;-1:-1:-1;;1209:1:1;1191:16;;1184:27;961:258::o;1224:::-;1266:3;1304:5;1298:12;1331:6;1326:3;1319:19;1347:63;1403:6;1396:4;1391:3;1387:14;1380:4;1373:5;1369:16;1347:63;:::i;:::-;1464:2;1443:15;-1:-1:-1;;1439:29:1;1430:39;;;;1471:4;1426:50;;1224:258;-1:-1:-1;;1224:258:1:o;1487:220::-;1636:2;1625:9;1618:21;1599:4;1656:45;1697:2;1686:9;1682:18;1674:6;1656:45;:::i;1712:180::-;1771:6;1824:2;1812:9;1803:7;1799:23;1795:32;1792:52;;;1840:1;1837;1830:12;1792:52;-1:-1:-1;1863:23:1;;1712:180;-1:-1:-1;1712:180:1:o;2105:127::-;2166:10;2161:3;2157:20;2154:1;2147:31;2197:4;2194:1;2187:15;2221:4;2218:1;2211:15;2237:275;2308:2;2302:9;2373:2;2354:13;;-1:-1:-1;;2350:27:1;2338:40;;-1:-1:-1;;;;;2393:34:1;;2429:22;;;2390:62;2387:88;;;2455:18;;:::i;:::-;2491:2;2484:22;2237:275;;-1:-1:-1;2237:275:1:o;2517:1020::-;2610:6;2618;2671:2;2659:9;2650:7;2646:23;2642:32;2639:52;;;2687:1;2684;2677:12;2639:52;2710:29;2729:9;2710:29;:::i;:::-;2700:39;;2758:2;2811;2800:9;2796:18;2783:32;-1:-1:-1;;;;;2875:2:1;2867:6;2864:14;2861:34;;;2891:1;2888;2881:12;2861:34;2929:6;2918:9;2914:22;2904:32;;2974:7;2967:4;2963:2;2959:13;2955:27;2945:55;;2996:1;2993;2986:12;2945:55;3032:2;3019:16;3054:2;3050;3047:10;3044:36;;;3060:18;;:::i;:::-;3106:2;3103:1;3099:10;3089:20;;3129:28;3153:2;3149;3145:11;3129:28;:::i;:::-;3191:15;;;3261:11;;;3257:20;;;3222:12;;;;3289:19;;;3286:39;;;3321:1;3318;3311:12;3286:39;3345:11;;;;3365:142;3381:6;3376:3;3373:15;3365:142;;;3447:17;;3435:30;;3398:12;;;;3485;;;;3365:142;;;3526:5;3516:15;;;;;;;;2517:1020;;;;;:::o;3542:254::-;3610:6;3618;3671:2;3659:9;3650:7;3646:23;3642:32;3639:52;;;3687:1;3684;3677:12;3639:52;3710:29;3729:9;3710:29;:::i;:::-;3700:39;3786:2;3771:18;;;;3758:32;;-1:-1:-1;;;3542:254:1:o;3983:328::-;4060:6;4068;4076;4129:2;4117:9;4108:7;4104:23;4100:32;4097:52;;;4145:1;4142;4135:12;4097:52;4168:29;4187:9;4168:29;:::i;:::-;4158:39;;4216:38;4250:2;4239:9;4235:18;4216:38;:::i;:::-;4206:48;;4301:2;4290:9;4286:18;4273:32;4263:42;;3983:328;;;;;:::o;4316:592::-;4387:6;4395;4448:2;4436:9;4427:7;4423:23;4419:32;4416:52;;;4464:1;4461;4454:12;4416:52;4504:9;4491:23;-1:-1:-1;;;;;4574:2:1;4566:6;4563:14;4560:34;;;4590:1;4587;4580:12;4560:34;4628:6;4617:9;4613:22;4603:32;;4673:7;4666:4;4662:2;4658:13;4654:27;4644:55;;4695:1;4692;4685:12;4644:55;4735:2;4722:16;4761:2;4753:6;4750:14;4747:34;;;4777:1;4774;4767:12;4747:34;4822:7;4817:2;4808:6;4804:2;4800:15;4796:24;4793:37;4790:57;;;4843:1;4840;4833:12;4790:57;4874:2;4866:11;;;;;4896:6;;-1:-1:-1;4316:592:1;;-1:-1:-1;;;;4316:592:1:o;4913:531::-;4956:5;5009:3;5002:4;4994:6;4990:17;4986:27;4976:55;;5027:1;5024;5017:12;4976:55;5063:6;5050:20;-1:-1:-1;;;;;5085:2:1;5082:26;5079:52;;;5111:18;;:::i;:::-;5155:55;5198:2;5179:13;;-1:-1:-1;;5175:27:1;5204:4;5171:38;5155:55;:::i;:::-;5235:2;5226:7;5219:19;5281:3;5274:4;5269:2;5261:6;5257:15;5253:26;5250:35;5247:55;;;5298:1;5295;5288:12;5247:55;5363:2;5356:4;5348:6;5344:17;5337:4;5328:7;5324:18;5311:55;5411:1;5386:16;;;5404:4;5382:27;5375:38;;;;5390:7;4913:531;-1:-1:-1;;;4913:531:1:o;5449:754::-;5563:6;5571;5579;5587;5595;5648:3;5636:9;5627:7;5623:23;5619:33;5616:53;;;5665:1;5662;5655:12;5616:53;5688:29;5707:9;5688:29;:::i;:::-;5678:39;;5764:2;5753:9;5749:18;5736:32;5726:42;;5819:2;5808:9;5804:18;5791:32;-1:-1:-1;;;;;5883:2:1;5875:6;5872:14;5869:34;;;5899:1;5896;5889:12;5869:34;5922:50;5964:7;5955:6;5944:9;5940:22;5922:50;:::i;:::-;5912:60;;6019:2;6008:9;6004:18;5991:32;5981:42;;6076:3;6065:9;6061:19;6048:33;6032:49;;6106:2;6096:8;6093:16;6090:36;;;6122:1;6119;6112:12;6090:36;;6145:52;6189:7;6178:8;6167:9;6163:24;6145:52;:::i;:::-;6135:62;;;5449:754;;;;;;;;:::o;6208:464::-;6295:6;6303;6311;6364:2;6352:9;6343:7;6339:23;6335:32;6332:52;;;6380:1;6377;6370:12;6332:52;6403:29;6422:9;6403:29;:::i;:::-;6393:39;;6479:2;6468:9;6464:18;6451:32;6441:42;;6534:2;6523:9;6519:18;6506:32;-1:-1:-1;;;;;6553:6:1;6550:30;6547:50;;;6593:1;6590;6583:12;6547:50;6616;6658:7;6649:6;6638:9;6634:22;6616:50;:::i;:::-;6606:60;;;6208:464;;;;;:::o;7226:347::-;7291:6;7299;7352:2;7340:9;7331:7;7327:23;7323:32;7320:52;;;7368:1;7365;7358:12;7320:52;7391:29;7410:9;7391:29;:::i;:::-;7381:39;;7470:2;7459:9;7455:18;7442:32;7517:5;7510:13;7503:21;7496:5;7493:32;7483:60;;7539:1;7536;7529:12;7483:60;7562:5;7552:15;;;7226:347;;;;;:::o;7578:322::-;7647:6;7700:2;7688:9;7679:7;7675:23;7671:32;7668:52;;;7716:1;7713;7706:12;7668:52;7756:9;7743:23;-1:-1:-1;;;;;7781:6:1;7778:30;7775:50;;;7821:1;7818;7811:12;7775:50;7844;7886:7;7877:6;7866:9;7862:22;7844:50;:::i;7905:538::-;8000:6;8008;8016;8024;8077:3;8065:9;8056:7;8052:23;8048:33;8045:53;;;8094:1;8091;8084:12;8045:53;8117:29;8136:9;8117:29;:::i;:::-;8107:39;;8165:38;8199:2;8188:9;8184:18;8165:38;:::i;:::-;8155:48;;8250:2;8239:9;8235:18;8222:32;8212:42;;8305:2;8294:9;8290:18;8277:32;-1:-1:-1;;;;;8324:6:1;8321:30;8318:50;;;8364:1;8361;8354:12;8318:50;8387;8429:7;8420:6;8409:9;8405:22;8387:50;:::i;:::-;8377:60;;;7905:538;;;;;;;:::o;8448:389::-;8525:6;8533;8586:2;8574:9;8565:7;8561:23;8557:32;8554:52;;;8602:1;8599;8592:12;8554:52;8638:9;8625:23;8615:33;;8699:2;8688:9;8684:18;8671:32;-1:-1:-1;;;;;8718:6:1;8715:30;8712:50;;;8758:1;8755;8748:12;8712:50;8781;8823:7;8814:6;8803:9;8799:22;8781:50;:::i;:::-;8771:60;;;8448:389;;;;;:::o;8842:260::-;8910:6;8918;8971:2;8959:9;8950:7;8946:23;8942:32;8939:52;;;8987:1;8984;8977:12;8939:52;9010:29;9029:9;9010:29;:::i;:::-;9000:39;;9058:38;9092:2;9081:9;9077:18;9058:38;:::i;:::-;9048:48;;8842:260;;;;;:::o;9107:337::-;9309:2;9291:21;;;9348:2;9328:18;;;9321:30;-1:-1:-1;;;9382:2:1;9367:18;;9360:43;9435:2;9420:18;;9107:337::o;9805:127::-;9866:10;9861:3;9857:20;9854:1;9847:31;9897:4;9894:1;9887:15;9921:4;9918:1;9911:15;9937:127;9998:10;9993:3;9989:20;9986:1;9979:31;10029:4;10026:1;10019:15;10053:4;10050:1;10043:15;10069:135;10108:3;10129:17;;;10126:43;;10149:18;;:::i;:::-;-1:-1:-1;10196:1:1;10185:13;;10069:135::o;10209:128::-;10249:3;10280:1;10276:6;10273:1;10270:13;10267:39;;;10286:18;;:::i;:::-;-1:-1:-1;10322:9:1;;10209:128::o;10342:184::-;10412:6;10465:2;10453:9;10444:7;10440:23;10436:32;10433:52;;;10481:1;10478;10471:12;10433:52;-1:-1:-1;10504:16:1;;10342:184;-1:-1:-1;10342:184:1:o;11568:380::-;11647:1;11643:12;;;;11690;;;11711:61;;11765:4;11757:6;11753:17;11743:27;;11711:61;11818:2;11810:6;11807:14;11787:18;11784:38;11781:161;;11864:10;11859:3;11855:20;11852:1;11845:31;11899:4;11896:1;11889:15;11927:4;11924:1;11917:15;11781:161;;11568:380;;;:::o;15458:545::-;15560:2;15555:3;15552:11;15549:448;;;15596:1;15621:5;15617:2;15610:17;15666:4;15662:2;15652:19;15736:2;15724:10;15720:19;15717:1;15713:27;15707:4;15703:38;15772:4;15760:10;15757:20;15754:47;;;-1:-1:-1;15795:4:1;15754:47;15850:2;15845:3;15841:12;15838:1;15834:20;15828:4;15824:31;15814:41;;15905:82;15923:2;15916:5;15913:13;15905:82;;;15968:17;;;15949:1;15938:13;15905:82;;16179:1206;-1:-1:-1;;;;;16298:3:1;16295:27;16292:53;;;16325:18;;:::i;:::-;16354:94;16444:3;16404:38;16436:4;16430:11;16404:38;:::i;:::-;16398:4;16354:94;:::i;:::-;16474:1;16499:2;16494:3;16491:11;16516:1;16511:616;;;;17171:1;17188:3;17185:93;;;-1:-1:-1;17244:19:1;;;17231:33;17185:93;-1:-1:-1;;16136:1:1;16132:11;;;16128:24;16124:29;16114:40;16160:1;16156:11;;;16111:57;17291:78;;16484:895;;16511:616;15405:1;15398:14;;;15442:4;15429:18;;-1:-1:-1;;16547:17:1;;;16648:9;16670:229;16684:7;16681:1;16678:14;16670:229;;;16773:19;;;16760:33;16745:49;;16880:4;16865:20;;;;16833:1;16821:14;;;;16700:12;16670:229;;;16674:3;16927;16918:7;16915:16;16912:159;;;17051:1;17047:6;17041:3;17035;17032:1;17028:11;17024:21;17020:34;17016:39;17003:9;16998:3;16994:19;16981:33;16977:79;16969:6;16962:95;16912:159;;;17114:1;17108:3;17105:1;17101:11;17097:19;17091:4;17084:33;16484:895;;16179:1206;;;:::o;18457:168::-;18497:7;18563:1;18559;18555:6;18551:14;18548:1;18545:21;18540:1;18533:9;18526:17;18522:45;18519:71;;;18570:18;;:::i;:::-;-1:-1:-1;18610:9:1;;18457:168::o;19334:276::-;19465:3;19503:6;19497:13;19519:53;19565:6;19560:3;19553:4;19545:6;19541:17;19519:53;:::i;:::-;19588:16;;;;;19334:276;-1:-1:-1;;19334:276:1:o;20295:586::-;20510:3;20542:26;20538:31;20611:2;20602:6;20598:2;20594:15;20590:24;20585:3;20578:37;20645:6;20640:2;20635:3;20631:12;20624:28;20681:6;20675:13;20697:62;20752:6;20747:2;20742:3;20738:12;20731:4;20723:6;20719:17;20697:62;:::i;:::-;20831:2;20827:15;;;;20823:24;20778:16;;;;20818:2;20810:11;;20803:45;;;;20872:2;20864:11;;;-1:-1:-1;;;;20295:586:1:o;22362:415::-;22564:2;22546:21;;;22603:2;22583:18;;;22576:30;22642:34;22637:2;22622:18;;22615:62;-1:-1:-1;;;22708:2:1;22693:18;;22686:49;22767:3;22752:19;;22362:415::o;27720:489::-;-1:-1:-1;;;;;27989:15:1;;;27971:34;;28041:15;;28036:2;28021:18;;28014:43;28088:2;28073:18;;28066:34;;;28136:3;28131:2;28116:18;;28109:31;;;27914:4;;28157:46;;28183:19;;28175:6;28157:46;:::i;:::-;28149:54;27720:489;-1:-1:-1;;;;;;27720:489:1:o;28214:249::-;28283:6;28336:2;28324:9;28315:7;28311:23;28307:32;28304:52;;;28352:1;28349;28342:12;28304:52;28384:9;28378:16;28403:30;28427:5;28403:30;:::i;29271:127::-;29332:10;29327:3;29323:20;29320:1;29313:31;29363:4;29360:1;29353:15;29387:4;29384:1;29377:15
Swarm Source
ipfs://6c65449bad82196718c78aed462d783801bce46098eb7275d08dedd725d773b9
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.