ERC-721
Overview
Max Total Supply
2,190 3333
Holders
554
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
2 3333Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
three333
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-11-29 */ // SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /* * @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 GSN 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) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } /** * @dev 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`, 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 be 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 Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @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 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); /** * @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; } /** * @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); } /** * @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 tokenId); /** * @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); } /** * @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 `IERC721.onERC721Received.selector`. */ function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); } /** * @dev Implementation of the {IERC165} interface. * * Contracts may inherit from this and call {_registerInterface} to declare * their support of an interface. */ abstract contract ERC165 is IERC165 { /* * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7 */ bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /** * @dev Mapping of interface ids to whether or not it's supported. */ mapping(bytes4 => bool) private _supportedInterfaces; constructor () { // Derived contracts need only register support for their own interfaces, // we register support for ERC165 itself here _registerInterface(_INTERFACE_ID_ERC165); } /** * @dev See {IERC165-supportsInterface}. * * Time complexity O(1), guaranteed to always use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev Registers the contract as an implementer of the interface defined by * `interfaceId`. Support of the actual ERC165 interface is automatic and * registering its interface id is not required. * * See {IERC165-supportsInterface}. * * Requirements: * * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). */ function _registerInterface(bytes4 interfaceId) internal virtual { require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); _supportedInterfaces[interfaceId] = true; } } /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } } /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 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"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (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"); // solhint-disable-next-line avoid-low-level-calls (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"); // solhint-disable-next-line avoid-low-level-calls (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"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } } // File: @openzeppelin/contracts/utils/EnumerableMap.sol /** * @dev Library for managing an enumerable variant of Solidity's * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] * type. * * Maps have the following properties: * * - Entries are added, removed, and checked for existence in constant time * (O(1)). * - Entries are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableMap for EnumerableMap.UintToAddressMap; * * // Declare a set state variable * EnumerableMap.UintToAddressMap private myMap; * } * ``` * * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are * supported. */ library EnumerableMap { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Map type with // bytes32 keys and values. // The Map implementation uses private functions, and user-facing // implementations (such as Uint256ToAddressMap) are just wrappers around // the underlying Map. // This means that we can only create new EnumerableMaps for types that fit // in bytes32. struct MapEntry { bytes32 _key; bytes32 _value; } struct Map { // Storage of map keys and values MapEntry[] _entries; // Position of the entry defined by a key in the `entries` array, plus 1 // because index 0 means a key is not in the map. mapping (bytes32 => uint256) _indexes; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) { // We read and store the key's index to prevent multiple reads from the same storage slot uint256 keyIndex = map._indexes[key]; if (keyIndex == 0) { // Equivalent to !contains(map, key) map._entries.push(MapEntry({ _key: key, _value: value })); // The entry is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value map._indexes[key] = map._entries.length; return true; } else { map._entries[keyIndex - 1]._value = value; return false; } } /** * @dev Removes a key-value pair from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function _remove(Map storage map, bytes32 key) private returns (bool) { // We read and store the key's index to prevent multiple reads from the same storage slot uint256 keyIndex = map._indexes[key]; if (keyIndex != 0) { // Equivalent to contains(map, key) // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one // in the array, and then remove the last entry (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = keyIndex - 1; uint256 lastIndex = map._entries.length - 1; // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. MapEntry storage lastEntry = map._entries[lastIndex]; // Move the last entry to the index where the entry to delete is map._entries[toDeleteIndex] = lastEntry; // Update the index for the moved entry map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved entry was stored map._entries.pop(); // Delete the index for the deleted slot delete map._indexes[key]; return true; } else { return false; } } /** * @dev Returns true if the key is in the map. O(1). */ function _contains(Map storage map, bytes32 key) private view returns (bool) { return map._indexes[key] != 0; } /** * @dev Returns the number of key-value pairs in the map. O(1). */ function _length(Map storage map) private view returns (uint256) { return map._entries.length; } /** * @dev Returns the key-value pair stored at position `index` in the map. O(1). * * Note that there are no guarantees on the ordering of entries inside the * array, and it may change when more entries are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) { require(map._entries.length > index, "EnumerableMap: index out of bounds"); MapEntry storage entry = map._entries[index]; return (entry._key, entry._value); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) { uint256 keyIndex = map._indexes[key]; if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key) return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function _get(Map storage map, bytes32 key) private view returns (bytes32) { uint256 keyIndex = map._indexes[key]; require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key) return map._entries[keyIndex - 1]._value; // All indexes are 1-based } /** * @dev Same as {_get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {_tryGet}. */ function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) { uint256 keyIndex = map._indexes[key]; require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key) return map._entries[keyIndex - 1]._value; // All indexes are 1-based } // UintToAddressMap struct UintToAddressMap { Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) { return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { return _remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { return _contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToAddressMap storage map) internal view returns (uint256) { return _length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { (bytes32 key, bytes32 value) = _at(map._inner, index); return (uint256(key), address(uint160(uint256(value)))); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. * * _Available since v3.4._ */ function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key)); return (success, address(uint160(uint256(value)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key))))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage)))); } } /** * @dev String operations. */ library Strings { bytes16 private constant alphabet = "0123456789abcdef"; /** * @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] = alphabet[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } } /** * @title ERC721 Non-Fungible Token Standard basic implementation * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable { using SafeMath for uint256; using Address for address; using EnumerableSet for EnumerableSet.UintSet; using EnumerableMap for EnumerableMap.UintToAddressMap; using Strings for uint256; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; // Mapping from holder address to their (enumerable) set of owned tokens mapping (address => EnumerableSet.UintSet) private _holderTokens; // Enumerable mapping from token ids to their owners EnumerableMap.UintToAddressMap private _tokenOwners; // 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; // Token name string private _name; // Token symbol string private _symbol; // Optional mapping for token URIs mapping (uint256 => string) private _tokenURIs; // Base URI string private _baseURI; /* * bytes4(keccak256('balanceOf(address)')) == 0x70a08231 * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3 * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465 * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5 * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde * * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^ * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd */ bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; /* * bytes4(keccak256('name()')) == 0x06fdde03 * bytes4(keccak256('symbol()')) == 0x95d89b41 * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd * * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f */ bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f; /* * bytes4(keccak256('totalSupply()')) == 0x18160ddd * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59 * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7 * * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63 */ bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63; /** * @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_; // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721); _registerInterface(_INTERFACE_ID_ERC721_METADATA); _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _holderTokens[owner].length(); } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token"); } /** * @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 _tokenURI = _tokenURIs[tokenId]; string memory base = baseURI(); // If there is no base URI, return the token URI. if (bytes(base).length == 0) { return _tokenURI; } // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). if (bytes(_tokenURI).length > 0) { return string(abi.encodePacked(base, _tokenURI)); } // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI. return string(abi.encodePacked(base, tokenId.toString())); } /** * @dev Returns the base URI set via {_setBaseURI}. This will be * automatically added as a prefix in {tokenURI} to each token's URI, or * to the token ID if no specific URI is set for that token ID. */ function baseURI() public view virtual returns (string memory) { return _baseURI; } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { return _holderTokens[owner].at(index); } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds return _tokenOwners.length(); } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { (uint256 tokenId, ) = _tokenOwners.at(index); return tokenId; } /** * @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 || ERC721.isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "ERC721: 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 { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not 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: transfer caller is not 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 _tokenOwners.contains(tokenId); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: d* * - `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); _holderTokens[to].add(tokenId); _tokenOwners.set(tokenId, to); emit Transfer(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); // internal owner _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); // Clear metadata (if any) if (bytes(_tokenURIs[tokenId]).length != 0) { delete _tokenURIs[tokenId]; } _holderTokens[owner].remove(tokenId); _tokenOwners.remove(tokenId); emit Transfer(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 of token that is not own"); // internal 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); _holderTokens[from].remove(tokenId); _holderTokens[to].add(tokenId); _tokenOwners.set(tokenId, to); emit Transfer(from, to, tokenId); } /** * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token"); _tokenURIs[tokenId] = _tokenURI; } /** * @dev Internal function to set the base URI for all token IDs. It is * automatically added as a prefix to the value returned in {tokenURI}, * or to the token ID if {tokenURI} is empty. */ function _setBaseURI(string memory baseURI_) internal virtual { _baseURI = baseURI_; } /** * @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()) { return true; } bytes memory returndata = to.functionCall(abi.encodeWithSelector( IERC721Receiver(to).onERC721Received.selector, _msgSender(), from, tokenId, _data ), "ERC721: transfer to non ERC721Receiver implementer"); bytes4 retval = abi.decode(returndata, (bytes4)); return (retval == _ERC721_RECEIVED); } /** * @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); // internal owner } /** * @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` cannot be the zero address. * - `to` cannot be the zero address. * * 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 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 () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { 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 { emit OwnershipTransferred(_owner, address(0)); _owner = 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"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } 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; } /**voucherPresaleNfts * @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 make 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; } modifier isHuman() { require(tx.origin == msg.sender, "sorry humans only"); _; } } /** * @title contract * @dev Extends ERC721 Non-Fungible Token Standard basic implementation */ contract three333 is ERC721, Ownable, ReentrancyGuard { using SafeMath for uint256; uint256 public mintPrice; uint256 public presaleMintPrice; uint256 public maxPublicToMint; uint256 public maxPresaleToMint; uint256 public maxNftSupply; uint256 public maxPresaleSupply; uint256 public curTicketId; mapping(address => uint256) public presaleNumOfUser; mapping(address => uint256) public publicNumOfUser; mapping(address => uint256) public totalClaimed; bool public presaleAllowed; bool public publicSaleAllowed; uint256 public presaleStartTimestamp; uint256 public publicSaleStartTimestamp; mapping(address => bool) private presaleWhitelist; constructor() ERC721("Project3333", "3333") { maxNftSupply = 3333; maxPresaleSupply = 1333; mintPrice = 0.25 ether; presaleMintPrice = 0.15 ether; maxPublicToMint = 10; maxPresaleToMint = 5; curTicketId = 0; presaleAllowed = false; publicSaleAllowed = false; presaleStartTimestamp = 0; publicSaleStartTimestamp = 0; } function tokensOfOwner(address _owner) external view returns(uint256[] memory) { uint256 tokenCount = balanceOf(_owner); if (tokenCount == 0) { return new uint256[](0); } else { uint256[] memory result = new uint256[](tokenCount); for (uint256 index; index < tokenCount; index++) { result[index] = tokenOfOwnerByIndex(_owner, index); } return result; } } function exists(uint256 _tokenId) public view returns (bool) { return _exists(_tokenId); } function isPresaleLive() public view returns(bool) { uint256 curTimestamp = block.timestamp; if (presaleAllowed && presaleStartTimestamp <= curTimestamp && curTicketId < maxPresaleSupply) { return true; } return false; } function isPublicSaleLive() public view returns(bool) { uint256 curTimestamp = block.timestamp; if (publicSaleAllowed && publicSaleStartTimestamp <= curTimestamp) { return true; } return false; } function setMintPrice(uint256 _price) external onlyOwner { mintPrice = _price; } function setPresaleMintPrice(uint256 _price) external onlyOwner { presaleMintPrice = _price; } function setMaxNftSupply(uint256 _maxValue) external onlyOwner { maxNftSupply = _maxValue; } function setMaxPresaleSupply(uint256 _maxValue) external onlyOwner { maxPresaleSupply = _maxValue; } function setMaxPresaleToMint(uint256 _maxValue) external onlyOwner { maxPresaleToMint = _maxValue; } function setMaxPublicToMint(uint256 _maxValue) external onlyOwner { maxPublicToMint = _maxValue; } function reserveNfts(address _to, uint256 _numberOfTokens) external onlyOwner { uint256 supply = totalSupply(); require(_to != address(0), "Invalid address to reserve."); require(supply == curTicketId, "Ticket id and supply not matched."); uint256 i; for (i = 0; i < _numberOfTokens; i++) { _safeMint(_to, supply + i); } curTicketId = curTicketId.add(_numberOfTokens); } function setBaseURI(string memory baseURI) external onlyOwner { _setBaseURI(baseURI); } function updatePresaleState(bool newStatus, uint256 timestamp) external onlyOwner { presaleAllowed = newStatus; if (timestamp != 0) { presaleStartTimestamp = timestamp; } } function updatePublicSaleState(bool newStatus, uint256 timestamp) external onlyOwner { publicSaleAllowed = newStatus; if (timestamp != 0) { publicSaleStartTimestamp = timestamp; } } function addToPresale(address[] calldata addresses) external onlyOwner { for (uint256 i = 0; i < addresses.length; i++) { presaleWhitelist[addresses[i]] = true; } } function removeToPresale(address[] calldata addresses) external onlyOwner { for (uint256 i = 0; i < addresses.length; i++) { presaleWhitelist[addresses[i]] = false; } } function isInWhitelist(address user) external view returns (bool) { return presaleWhitelist[user]; } function doPresale(uint256 numberOfTokens) isHuman nonReentrant external payable { uint256 numOfUser = presaleNumOfUser[_msgSender()]; require(isPresaleLive(), "Presale has not started yet"); require(presaleWhitelist[_msgSender()], "You are not on white list"); require(numberOfTokens.add(numOfUser) <= maxPresaleToMint, "Exceeds max presale allowed per user"); require(curTicketId.add(numberOfTokens) <= maxPresaleSupply, "Exceeds max presale supply"); require(numberOfTokens > 0, "Must mint at least one token"); require(presaleMintPrice.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct"); presaleNumOfUser[_msgSender()] = numberOfTokens.add(presaleNumOfUser[_msgSender()]); curTicketId = curTicketId.add(numberOfTokens); } function doPublic(uint256 numberOfTokens) isHuman nonReentrant external payable { uint256 numOfUser = publicNumOfUser[_msgSender()]; require(isPublicSaleLive(), "Public sale has not started yet"); require(numberOfTokens.add(numOfUser) <= maxPublicToMint, "Exceeds max public sale allowed per user"); require(curTicketId.add(numberOfTokens) <= maxNftSupply, "Exceeds max supply"); require(numberOfTokens > 0, "Must mint at least one token"); require(mintPrice.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct"); publicNumOfUser[_msgSender()] = numberOfTokens.add(publicNumOfUser[_msgSender()]); curTicketId = curTicketId.add(numberOfTokens); } function getUserClaimableTicketCount(address user) public view returns (uint256) { return presaleNumOfUser[user].add(publicNumOfUser[user]).sub(totalClaimed[user]); } function claimNfts() isHuman nonReentrant external { uint256 numbersOfTickets = getUserClaimableTicketCount(_msgSender()); for(uint256 i = 0; i < numbersOfTickets; i++) { uint256 mintIndex = totalSupply(); _safeMint(_msgSender(), mintIndex); } totalClaimed[_msgSender()] = numbersOfTickets.add(totalClaimed[_msgSender()]); } function withdraw() external onlyOwner { uint256 balance = address(this).balance; payable(owner()).transfer(balance); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"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":"addresses","type":"address[]"}],"name":"addToPresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimNfts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"curTicketId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"doPresale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"doPublic","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserClaimableTicketCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"user","type":"address"}],"name":"isInWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPresaleLive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPublicSaleLive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxNftSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPresaleSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPresaleToMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPublicToMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleMintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"presaleNumOfUser","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleStartTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"publicNumOfUser","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSaleAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSaleStartTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"name":"removeToPresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_numberOfTokens","type":"uint256"}],"name":"reserveNfts","outputs":[],"stateMutability":"nonpayable","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":"uint256","name":"_maxValue","type":"uint256"}],"name":"setMaxNftSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxValue","type":"uint256"}],"name":"setMaxPresaleSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxValue","type":"uint256"}],"name":"setMaxPresaleToMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxValue","type":"uint256"}],"name":"setMaxPublicToMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPresaleMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"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":[{"internalType":"address","name":"_owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"updatePresaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"updatePublicSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604080518082018252600b81526a50726f6a6563743333333360a81b602080830191909152825180840190935260048352633333333360e01b9083015290620000626301ffc9a760e01b6200015c565b815162000077906006906020850190620001e0565b5080516200008d906007906020840190620001e0565b50620000a06380ac58cd60e01b6200015c565b620000b2635b5e139f60e01b6200015c565b620000c463780e9d6360e01b6200015c565b5050600a80546001600160a01b0319163390811790915560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001600b55610d056010556105356011556703782dace9d90000600c55670214e8348c4f0000600d55600a600e556005600f55600060128190556016805461ffff191690556017819055601855620002c3565b6001600160e01b03198082161415620001bb5760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015260640160405180910390fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b828054620001ee9062000286565b90600052602060002090601f0160209004810192826200021257600085556200025d565b82601f106200022d57805160ff19168380011785556200025d565b828001600101855582156200025d579182015b828111156200025d57825182559160200191906001019062000240565b506200026b9291506200026f565b5090565b5b808211156200026b576000815560010162000270565b600181811c908216806200029b57607f821691505b60208210811415620002bd57634e487b7160e01b600052602260045260246000fd5b50919050565b61327e80620002d36000396000f3fe60806040526004361061036b5760003560e01c80636c0360eb116101c6578063bcc08b2c116100f7578063e985e9c511610095578063f2fde38b1161006f578063f2fde38b146109dd578063f4a0a528146109fd578063fa5b6d7814610a1d578063fb2efcd514610a3d57600080fd5b8063e985e9c514610947578063ed1b463f14610990578063ef5d9ae8146109b057600080fd5b8063ce364d7c116100d1578063ce364d7c146108e4578063d7822c9914610904578063de83c1aa1461091a578063e85ceae21461092d57600080fd5b8063bcc08b2c14610882578063c87b56dd14610897578063ccd35e1d146108b757600080fd5b80638da5cb5b11610164578063a29ca4491161013e578063a29ca4491461080d578063a542ba8d14610823578063aef6ee1f14610842578063b88d4fde1461086257600080fd5b80638da5cb5b146107ba57806395d89b41146107d8578063a22cb465146107ed57600080fd5b8063715018a6116101a0578063715018a61461074d578063746f90b9146107625780638462151c1461077857806386233071146107a557600080fd5b80636c0360eb146106f85780636d8429931461070d57806370a082311461072d57600080fd5b80633ccfd60b116102a0578063520423fc1161023e5780635be50521116102185780635be505211461068c5780636352211e146106a25780636817c76c146106c257806369cd9768146106d857600080fd5b8063520423fc1461063657806355f804b31461065657806356cbeb921461067657600080fd5b80634538170a1161027a5780634538170a146105c05780634ea37fec146105e05780634f558e79146105f65780634f6ccce71461061657600080fd5b80633ccfd60b146105785780633f3df2791461058d57806342842e0e146105a057600080fd5b806321bdb26e1161030d5780632f745c59116102e75780632f745c59146104f8578063366626fa1461051857806337a13193146105385780633c302c191461055857600080fd5b806321bdb26e146104ad57806323b872dd146104c35780632c9ad1fb146104e357600080fd5b8063095ea7b311610349578063095ea7b31461041957806309fd82121461043b57806317984feb1461047457806318160ddd1461049857600080fd5b806301ffc9a71461037057806306fdde03146103bf578063081812fc146103e1575b600080fd5b34801561037c57600080fd5b506103aa61038b366004612b1f565b6001600160e01b03191660009081526020819052604090205460ff1690565b60405190151581526020015b60405180910390f35b3480156103cb57600080fd5b506103d4610a6a565b6040516103b69190612b94565b3480156103ed57600080fd5b506104016103fc366004612ba7565b610afc565b6040516001600160a01b0390911681526020016103b6565b34801561042557600080fd5b50610439610434366004612bdc565b610b89565b005b34801561044757600080fd5b506103aa610456366004612c06565b6001600160a01b031660009081526019602052604090205460ff1690565b34801561048057600080fd5b5061048a600f5481565b6040519081526020016103b6565b3480156104a457600080fd5b5061048a610c9f565b3480156104b957600080fd5b5061048a60115481565b3480156104cf57600080fd5b506104396104de366004612c21565b610cb0565b3480156104ef57600080fd5b506103aa610ce1565b34801561050457600080fd5b5061048a610513366004612bdc565b610d1e565b34801561052457600080fd5b50610439610533366004612ba7565b610d49565b34801561054457600080fd5b50610439610553366004612ba7565b610d78565b34801561056457600080fd5b50610439610573366004612c6d565b610da7565b34801561058457600080fd5b50610439610df4565b61043961059b366004612ba7565b610e69565b3480156105ac57600080fd5b506104396105bb366004612c21565b611148565b3480156105cc57600080fd5b506104396105db366004612bdc565b611163565b3480156105ec57600080fd5b5061048a60175481565b34801561060257600080fd5b506103aa610611366004612ba7565b611290565b34801561062257600080fd5b5061048a610631366004612ba7565b61129b565b34801561064257600080fd5b50610439610651366004612c89565b6112b1565b34801561066257600080fd5b50610439610671366004612d8a565b61134d565b34801561068257600080fd5b5061048a600e5481565b34801561069857600080fd5b5061048a600d5481565b3480156106ae57600080fd5b506104016106bd366004612ba7565b611383565b3480156106ce57600080fd5b5061048a600c5481565b3480156106e457600080fd5b5061048a6106f3366004612c06565b6113ab565b34801561070457600080fd5b506103d46113ec565b34801561071957600080fd5b50610439610728366004612ba7565b6113fb565b34801561073957600080fd5b5061048a610748366004612c06565b61142a565b34801561075957600080fd5b506104396114b6565b34801561076e57600080fd5b5061048a60125481565b34801561078457600080fd5b50610798610793366004612c06565b61152a565b6040516103b69190612dd3565b3480156107b157600080fd5b506103aa6115e5565b3480156107c657600080fd5b50600a546001600160a01b0316610401565b3480156107e457600080fd5b506103d461160d565b3480156107f957600080fd5b50610439610808366004612e17565b61161c565b34801561081957600080fd5b5061048a60105481565b34801561082f57600080fd5b506016546103aa90610100900460ff1681565b34801561084e57600080fd5b5061043961085d366004612c89565b6116e1565b34801561086e57600080fd5b5061043961087d366004612e4a565b61177d565b34801561088e57600080fd5b506104396117b5565b3480156108a357600080fd5b506103d46108b2366004612ba7565b611871565b3480156108c357600080fd5b5061048a6108d2366004612c06565b60136020526000908152604090205481565b3480156108f057600080fd5b506104396108ff366004612c6d565b6119e3565b34801561091057600080fd5b5061048a60185481565b610439610928366004612ba7565b611a27565b34801561093957600080fd5b506016546103aa9060ff1681565b34801561095357600080fd5b506103aa610962366004612ec6565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561099c57600080fd5b506104396109ab366004612ba7565b611c55565b3480156109bc57600080fd5b5061048a6109cb366004612c06565b60156020526000908152604090205481565b3480156109e957600080fd5b506104396109f8366004612c06565b611c84565b348015610a0957600080fd5b50610439610a18366004612ba7565b611d6f565b348015610a2957600080fd5b50610439610a38366004612ba7565b611d9e565b348015610a4957600080fd5b5061048a610a58366004612c06565b60146020526000908152604090205481565b606060068054610a7990612ef0565b80601f0160208091040260200160405190810160405280929190818152602001828054610aa590612ef0565b8015610af25780601f10610ac757610100808354040283529160200191610af2565b820191906000526020600020905b815481529060010190602001808311610ad557829003601f168201915b5050505050905090565b6000610b0782611dcd565b610b6d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610b9482611383565b9050806001600160a01b0316836001600160a01b03161415610c025760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610b64565b336001600160a01b0382161480610c1e5750610c1e8133610962565b610c905760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610b64565b610c9a8383611dda565b505050565b6000610cab6002611e48565b905090565b610cba3382611e52565b610cd65760405162461bcd60e51b8152600401610b6490612f25565b610c9a838383611f3c565b601654600090429060ff168015610cfa57508060175411155b8015610d095750601154601254105b15610d1657600191505090565b600091505090565b6001600160a01b0382166000908152600160205260408120610d4090836120bd565b90505b92915050565b600a546001600160a01b03163314610d735760405162461bcd60e51b8152600401610b6490612f76565b600e55565b600a546001600160a01b03163314610da25760405162461bcd60e51b8152600401610b6490612f76565b600d55565b600a546001600160a01b03163314610dd15760405162461bcd60e51b8152600401610b6490612f76565b6016805461ff001916610100841515021790558015610df05760188190555b5050565b600a546001600160a01b03163314610e1e5760405162461bcd60e51b8152600401610b6490612f76565b47610e31600a546001600160a01b031690565b6001600160a01b03166108fc829081150290604051600060405180830381858888f19350505050158015610df0573d6000803e3d6000fd5b323314610e885760405162461bcd60e51b8152600401610b6490612fab565b6002600b541415610eab5760405162461bcd60e51b8152600401610b6490612fd6565b6002600b5533600090815260136020526040902054610ec8610ce1565b610f145760405162461bcd60e51b815260206004820152601b60248201527f50726573616c6520686173206e6f7420737461727465642079657400000000006044820152606401610b64565b3360009081526019602052604090205460ff16610f735760405162461bcd60e51b815260206004820152601960248201527f596f7520617265206e6f74206f6e207768697465206c697374000000000000006044820152606401610b64565b600f54610f8083836120c9565b1115610fda5760405162461bcd60e51b8152602060048201526024808201527f45786365656473206d61782070726573616c6520616c6c6f77656420706572206044820152633ab9b2b960e11b6064820152608401610b64565b601154601254610fea90846120c9565b11156110385760405162461bcd60e51b815260206004820152601a60248201527f45786365656473206d61782070726573616c6520737570706c790000000000006044820152606401610b64565b600082116110885760405162461bcd60e51b815260206004820152601c60248201527f4d757374206d696e74206174206c65617374206f6e6520746f6b656e000000006044820152606401610b64565b600d5434906110979084612128565b11156110e55760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f7272656374006044820152606401610b64565b61110f60136000335b6001600160a01b0316815260208101919091526040016000205483906120c9565b60136000335b6001600160a01b0316815260208101919091526040016000205560125461113c90836120c9565b60125550506001600b55565b610c9a8383836040518060200160405280600081525061177d565b600a546001600160a01b0316331461118d5760405162461bcd60e51b8152600401610b6490612f76565b6000611197610c9f565b90506001600160a01b0383166111ef5760405162461bcd60e51b815260206004820152601b60248201527f496e76616c6964206164647265737320746f20726573657276652e00000000006044820152606401610b64565b601254811461124a5760405162461bcd60e51b815260206004820152602160248201527f5469636b657420696420616e6420737570706c79206e6f74206d6174636865646044820152601760f91b6064820152608401610b64565b60005b8281101561127a57611268846112638385613023565b6121a7565b806112728161303b565b91505061124d565b60125461128790846120c9565b60125550505050565b6000610d4382611dcd565b6000806112a96002846121c1565b509392505050565b600a546001600160a01b031633146112db5760405162461bcd60e51b8152600401610b6490612f76565b60005b81811015610c9a576000601960008585858181106112fe576112fe613056565b90506020020160208101906113139190612c06565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055806113458161303b565b9150506112de565b600a546001600160a01b031633146113775760405162461bcd60e51b8152600401610b6490612f76565b611380816121dd565b50565b6000610d438260405180606001604052806029815260200161322060299139600291906121f0565b6001600160a01b0381166000908152601560209081526040808320546014835281842054601390935290832054610d43926113e691906120c9565b90612207565b606060098054610a7990612ef0565b600a546001600160a01b031633146114255760405162461bcd60e51b8152600401610b6490612f76565b601055565b60006001600160a01b0382166114955760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610b64565b6001600160a01b0382166000908152600160205260409020610d4390611e48565b600a546001600160a01b031633146114e05760405162461bcd60e51b8152600401610b6490612f76565b600a546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600a80546001600160a01b0319169055565b606060006115378361142a565b9050806115545760408051600080825260208201909252906112a9565b60008167ffffffffffffffff81111561156f5761156f612cfe565b604051908082528060200260200182016040528015611598578160200160208202803683370190505b50905060005b828110156112a9576115b08582610d1e565b8282815181106115c2576115c2613056565b6020908102919091010152806115d78161303b565b91505061159e565b50919050565b6016546000904290610100900460ff168015610d0957508060185411610d1657600191505090565b606060078054610a7990612ef0565b6001600160a01b0382163314156116755760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610b64565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600a546001600160a01b0316331461170b5760405162461bcd60e51b8152600401610b6490612f76565b60005b81811015610c9a5760016019600085858581811061172e5761172e613056565b90506020020160208101906117439190612c06565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055806117758161303b565b91505061170e565b6117873383611e52565b6117a35760405162461bcd60e51b8152600401610b6490612f25565b6117af84848484612263565b50505050565b3233146117d45760405162461bcd60e51b8152600401610b6490612fab565b6002600b5414156117f75760405162461bcd60e51b8152600401610b6490612fd6565b6002600b556000611807336113ab565b905060005b8181101561183d57600061181e610c9f565b905061182a33826121a7565b50806118358161303b565b91505061180c565b50336000908152601560205260409020546118599082906120c9565b33600090815260156020526040902055506001600b55565b606061187c82611dcd565b6118e05760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610b64565b600082815260086020526040812080546118f990612ef0565b80601f016020809104026020016040519081016040528092919081815260200182805461192590612ef0565b80156119725780601f1061194757610100808354040283529160200191611972565b820191906000526020600020905b81548152906001019060200180831161195557829003601f168201915b5050505050905060006119836113ec565b9050805160001415611996575092915050565b8151156119c85780826040516020016119b092919061306c565b60405160208183030381529060405292505050919050565b806119d285612296565b6040516020016119b092919061306c565b600a546001600160a01b03163314611a0d5760405162461bcd60e51b8152600401610b6490612f76565b6016805460ff19168315151790558015610df05760175550565b323314611a465760405162461bcd60e51b8152600401610b6490612fab565b6002600b541415611a695760405162461bcd60e51b8152600401610b6490612fd6565b6002600b5533600090815260146020526040902054611a866115e5565b611ad25760405162461bcd60e51b815260206004820152601f60248201527f5075626c69632073616c6520686173206e6f74207374617274656420796574006044820152606401610b64565b600e54611adf83836120c9565b1115611b3e5760405162461bcd60e51b815260206004820152602860248201527f45786365656473206d6178207075626c69632073616c6520616c6c6f776564206044820152673832b9103ab9b2b960c11b6064820152608401610b64565b601054601254611b4e90846120c9565b1115611b915760405162461bcd60e51b815260206004820152601260248201527145786365656473206d617820737570706c7960701b6044820152606401610b64565b60008211611be15760405162461bcd60e51b815260206004820152601c60248201527f4d757374206d696e74206174206c65617374206f6e6520746f6b656e000000006044820152606401610b64565b600c543490611bf09084612128565b1115611c3e5760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f7272656374006044820152606401610b64565b611c4b60146000336110ee565b6014600033611115565b600a546001600160a01b03163314611c7f5760405162461bcd60e51b8152600401610b6490612f76565b600f55565b600a546001600160a01b03163314611cae5760405162461bcd60e51b8152600401610b6490612f76565b6001600160a01b038116611d135760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b64565b600a546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600a80546001600160a01b0319166001600160a01b0392909216919091179055565b600a546001600160a01b03163314611d995760405162461bcd60e51b8152600401610b6490612f76565b600c55565b600a546001600160a01b03163314611dc85760405162461bcd60e51b8152600401610b6490612f76565b601155565b6000610d43600283612394565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611e0f82611383565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610d43825490565b6000611e5d82611dcd565b611ebe5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610b64565b6000611ec983611383565b9050806001600160a01b0316846001600160a01b03161480611f045750836001600160a01b0316611ef984610afc565b6001600160a01b0316145b80611f3457506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611f4f82611383565b6001600160a01b031614611fb75760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610b64565b6001600160a01b0382166120195760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610b64565b612024600082611dda565b6001600160a01b038316600090815260016020526040902061204690826123ac565b506001600160a01b038216600090815260016020526040902061206990826123b8565b50612076600282846123c4565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000610d4083836123da565b6000806120d68385613023565b905083811015610d405760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610b64565b60008261213757506000610d43565b6000612143838561309b565b90508261215085836130d0565b14610d405760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610b64565b610df0828260405180602001604052806000815250612460565b60008080806121d08686612493565b9097909650945050505050565b8051610df0906009906020840190612a70565b60006121fd848484612530565b90505b9392505050565b6000828211156122595760405162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006044820152606401610b64565b610d4082846130e4565b61226e848484611f3c565b61227a84848484612599565b6117af5760405162461bcd60e51b8152600401610b64906130fb565b6060816122ba5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156122e457806122ce8161303b565b91506122dd9050600a836130d0565b91506122be565b60008167ffffffffffffffff8111156122ff576122ff612cfe565b6040519080825280601f01601f191660200182016040528015612329576020820181803683370190505b5090505b8415611f345761233e6001836130e4565b915061234b600a8661314d565b612356906030613023565b60f81b81838151811061236b5761236b613056565b60200101906001600160f81b031916908160001a90535061238d600a866130d0565b945061232d565b60008181526001830160205260408120541515610d40565b6000610d40838361266a565b6000610d40838361275d565b60006121fd84846001600160a01b0385166127ac565b815460009082106124385760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610b64565b82600001828154811061244d5761244d613056565b9060005260206000200154905092915050565b61246a838361284d565b6124776000848484612599565b610c9a5760405162461bcd60e51b8152600401610b64906130fb565b8154600090819083106124f35760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610b64565b600084600001848154811061250a5761250a613056565b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816125605760405162461bcd60e51b8152600401610b649190612b94565b508461256d6001836130e4565b8154811061257d5761257d613056565b9060005260206000209060020201600101549150509392505050565b60006001600160a01b0384163b6125b257506001611f34565b6000612633630a85bd0160e11b338887876040516024016125d69493929190613161565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050506040518060600160405280603281526020016131ee603291396001600160a01b0388169190612965565b905060008180602001905181019061264b919061319e565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b6000818152600183016020526040812054801561275357600061268e6001836130e4565b85549091506000906126a2906001906130e4565b905060008660000182815481106126bb576126bb613056565b90600052602060002001549050808760000184815481106126de576126de613056565b6000918252602090912001556126f5836001613023565b60008281526001890160205260409020558654879080612717576127176131bb565b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610d43565b6000915050610d43565b60008181526001830160205260408120546127a457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d43565b506000610d43565b600082815260018401602052604081205480612811575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055612200565b828561281e6001846130e4565b8154811061282e5761282e613056565b9060005260206000209060020201600101819055506000915050612200565b6001600160a01b0382166128a35760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610b64565b6128ac81611dcd565b156128f95760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610b64565b6001600160a01b038216600090815260016020526040902061291b90826123b8565b50612928600282846123c4565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60606121fd848460008585843b6129be5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b64565b600080866001600160a01b031685876040516129da91906131d1565b60006040518083038185875af1925050503d8060008114612a17576040519150601f19603f3d011682016040523d82523d6000602084013e612a1c565b606091505b5091509150612a2c828286612a37565b979650505050505050565b60608315612a46575081612200565b825115612a565782518084602001fd5b8160405162461bcd60e51b8152600401610b649190612b94565b828054612a7c90612ef0565b90600052602060002090601f016020900481019282612a9e5760008555612ae4565b82601f10612ab757805160ff1916838001178555612ae4565b82800160010185558215612ae4579182015b82811115612ae4578251825591602001919060010190612ac9565b50612af0929150612af4565b5090565b5b80821115612af05760008155600101612af5565b6001600160e01b03198116811461138057600080fd5b600060208284031215612b3157600080fd5b8135610d4081612b09565b60005b83811015612b57578181015183820152602001612b3f565b838111156117af5750506000910152565b60008151808452612b80816020860160208601612b3c565b601f01601f19169290920160200192915050565b602081526000610d406020830184612b68565b600060208284031215612bb957600080fd5b5035919050565b80356001600160a01b0381168114612bd757600080fd5b919050565b60008060408385031215612bef57600080fd5b612bf883612bc0565b946020939093013593505050565b600060208284031215612c1857600080fd5b610d4082612bc0565b600080600060608486031215612c3657600080fd5b612c3f84612bc0565b9250612c4d60208501612bc0565b9150604084013590509250925092565b80358015158114612bd757600080fd5b60008060408385031215612c8057600080fd5b612bf883612c5d565b60008060208385031215612c9c57600080fd5b823567ffffffffffffffff80821115612cb457600080fd5b818501915085601f830112612cc857600080fd5b813581811115612cd757600080fd5b8660208260051b8501011115612cec57600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612d2f57612d2f612cfe565b604051601f8501601f19908116603f01168101908282118183101715612d5757612d57612cfe565b81604052809350858152868686011115612d7057600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215612d9c57600080fd5b813567ffffffffffffffff811115612db357600080fd5b8201601f81018413612dc457600080fd5b611f3484823560208401612d14565b6020808252825182820181905260009190848201906040850190845b81811015612e0b57835183529284019291840191600101612def565b50909695505050505050565b60008060408385031215612e2a57600080fd5b612e3383612bc0565b9150612e4160208401612c5d565b90509250929050565b60008060008060808587031215612e6057600080fd5b612e6985612bc0565b9350612e7760208601612bc0565b925060408501359150606085013567ffffffffffffffff811115612e9a57600080fd5b8501601f81018713612eab57600080fd5b612eba87823560208401612d14565b91505092959194509250565b60008060408385031215612ed957600080fd5b612ee283612bc0565b9150612e4160208401612bc0565b600181811c90821680612f0457607f821691505b602082108114156115df57634e487b7160e01b600052602260045260246000fd5b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b602080825260119082015270736f7272792068756d616e73206f6e6c7960781b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082198211156130365761303661300d565b500190565b600060001982141561304f5761304f61300d565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6000835161307e818460208801612b3c565b835190830190613092818360208801612b3c565b01949350505050565b60008160001904831182151516156130b5576130b561300d565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826130df576130df6130ba565b500490565b6000828210156130f6576130f661300d565b500390565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60008261315c5761315c6130ba565b500690565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061319490830184612b68565b9695505050505050565b6000602082840312156131b057600080fd5b8151610d4081612b09565b634e487b7160e01b600052603160045260246000fd5b600082516131e3818460208701612b3c565b919091019291505056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220e38dad1205bebd25f4398a5be34b38ca1e20c1991faae774ca5afc514131f68c64736f6c63430008090033
Deployed Bytecode
0x60806040526004361061036b5760003560e01c80636c0360eb116101c6578063bcc08b2c116100f7578063e985e9c511610095578063f2fde38b1161006f578063f2fde38b146109dd578063f4a0a528146109fd578063fa5b6d7814610a1d578063fb2efcd514610a3d57600080fd5b8063e985e9c514610947578063ed1b463f14610990578063ef5d9ae8146109b057600080fd5b8063ce364d7c116100d1578063ce364d7c146108e4578063d7822c9914610904578063de83c1aa1461091a578063e85ceae21461092d57600080fd5b8063bcc08b2c14610882578063c87b56dd14610897578063ccd35e1d146108b757600080fd5b80638da5cb5b11610164578063a29ca4491161013e578063a29ca4491461080d578063a542ba8d14610823578063aef6ee1f14610842578063b88d4fde1461086257600080fd5b80638da5cb5b146107ba57806395d89b41146107d8578063a22cb465146107ed57600080fd5b8063715018a6116101a0578063715018a61461074d578063746f90b9146107625780638462151c1461077857806386233071146107a557600080fd5b80636c0360eb146106f85780636d8429931461070d57806370a082311461072d57600080fd5b80633ccfd60b116102a0578063520423fc1161023e5780635be50521116102185780635be505211461068c5780636352211e146106a25780636817c76c146106c257806369cd9768146106d857600080fd5b8063520423fc1461063657806355f804b31461065657806356cbeb921461067657600080fd5b80634538170a1161027a5780634538170a146105c05780634ea37fec146105e05780634f558e79146105f65780634f6ccce71461061657600080fd5b80633ccfd60b146105785780633f3df2791461058d57806342842e0e146105a057600080fd5b806321bdb26e1161030d5780632f745c59116102e75780632f745c59146104f8578063366626fa1461051857806337a13193146105385780633c302c191461055857600080fd5b806321bdb26e146104ad57806323b872dd146104c35780632c9ad1fb146104e357600080fd5b8063095ea7b311610349578063095ea7b31461041957806309fd82121461043b57806317984feb1461047457806318160ddd1461049857600080fd5b806301ffc9a71461037057806306fdde03146103bf578063081812fc146103e1575b600080fd5b34801561037c57600080fd5b506103aa61038b366004612b1f565b6001600160e01b03191660009081526020819052604090205460ff1690565b60405190151581526020015b60405180910390f35b3480156103cb57600080fd5b506103d4610a6a565b6040516103b69190612b94565b3480156103ed57600080fd5b506104016103fc366004612ba7565b610afc565b6040516001600160a01b0390911681526020016103b6565b34801561042557600080fd5b50610439610434366004612bdc565b610b89565b005b34801561044757600080fd5b506103aa610456366004612c06565b6001600160a01b031660009081526019602052604090205460ff1690565b34801561048057600080fd5b5061048a600f5481565b6040519081526020016103b6565b3480156104a457600080fd5b5061048a610c9f565b3480156104b957600080fd5b5061048a60115481565b3480156104cf57600080fd5b506104396104de366004612c21565b610cb0565b3480156104ef57600080fd5b506103aa610ce1565b34801561050457600080fd5b5061048a610513366004612bdc565b610d1e565b34801561052457600080fd5b50610439610533366004612ba7565b610d49565b34801561054457600080fd5b50610439610553366004612ba7565b610d78565b34801561056457600080fd5b50610439610573366004612c6d565b610da7565b34801561058457600080fd5b50610439610df4565b61043961059b366004612ba7565b610e69565b3480156105ac57600080fd5b506104396105bb366004612c21565b611148565b3480156105cc57600080fd5b506104396105db366004612bdc565b611163565b3480156105ec57600080fd5b5061048a60175481565b34801561060257600080fd5b506103aa610611366004612ba7565b611290565b34801561062257600080fd5b5061048a610631366004612ba7565b61129b565b34801561064257600080fd5b50610439610651366004612c89565b6112b1565b34801561066257600080fd5b50610439610671366004612d8a565b61134d565b34801561068257600080fd5b5061048a600e5481565b34801561069857600080fd5b5061048a600d5481565b3480156106ae57600080fd5b506104016106bd366004612ba7565b611383565b3480156106ce57600080fd5b5061048a600c5481565b3480156106e457600080fd5b5061048a6106f3366004612c06565b6113ab565b34801561070457600080fd5b506103d46113ec565b34801561071957600080fd5b50610439610728366004612ba7565b6113fb565b34801561073957600080fd5b5061048a610748366004612c06565b61142a565b34801561075957600080fd5b506104396114b6565b34801561076e57600080fd5b5061048a60125481565b34801561078457600080fd5b50610798610793366004612c06565b61152a565b6040516103b69190612dd3565b3480156107b157600080fd5b506103aa6115e5565b3480156107c657600080fd5b50600a546001600160a01b0316610401565b3480156107e457600080fd5b506103d461160d565b3480156107f957600080fd5b50610439610808366004612e17565b61161c565b34801561081957600080fd5b5061048a60105481565b34801561082f57600080fd5b506016546103aa90610100900460ff1681565b34801561084e57600080fd5b5061043961085d366004612c89565b6116e1565b34801561086e57600080fd5b5061043961087d366004612e4a565b61177d565b34801561088e57600080fd5b506104396117b5565b3480156108a357600080fd5b506103d46108b2366004612ba7565b611871565b3480156108c357600080fd5b5061048a6108d2366004612c06565b60136020526000908152604090205481565b3480156108f057600080fd5b506104396108ff366004612c6d565b6119e3565b34801561091057600080fd5b5061048a60185481565b610439610928366004612ba7565b611a27565b34801561093957600080fd5b506016546103aa9060ff1681565b34801561095357600080fd5b506103aa610962366004612ec6565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561099c57600080fd5b506104396109ab366004612ba7565b611c55565b3480156109bc57600080fd5b5061048a6109cb366004612c06565b60156020526000908152604090205481565b3480156109e957600080fd5b506104396109f8366004612c06565b611c84565b348015610a0957600080fd5b50610439610a18366004612ba7565b611d6f565b348015610a2957600080fd5b50610439610a38366004612ba7565b611d9e565b348015610a4957600080fd5b5061048a610a58366004612c06565b60146020526000908152604090205481565b606060068054610a7990612ef0565b80601f0160208091040260200160405190810160405280929190818152602001828054610aa590612ef0565b8015610af25780601f10610ac757610100808354040283529160200191610af2565b820191906000526020600020905b815481529060010190602001808311610ad557829003601f168201915b5050505050905090565b6000610b0782611dcd565b610b6d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610b9482611383565b9050806001600160a01b0316836001600160a01b03161415610c025760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610b64565b336001600160a01b0382161480610c1e5750610c1e8133610962565b610c905760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610b64565b610c9a8383611dda565b505050565b6000610cab6002611e48565b905090565b610cba3382611e52565b610cd65760405162461bcd60e51b8152600401610b6490612f25565b610c9a838383611f3c565b601654600090429060ff168015610cfa57508060175411155b8015610d095750601154601254105b15610d1657600191505090565b600091505090565b6001600160a01b0382166000908152600160205260408120610d4090836120bd565b90505b92915050565b600a546001600160a01b03163314610d735760405162461bcd60e51b8152600401610b6490612f76565b600e55565b600a546001600160a01b03163314610da25760405162461bcd60e51b8152600401610b6490612f76565b600d55565b600a546001600160a01b03163314610dd15760405162461bcd60e51b8152600401610b6490612f76565b6016805461ff001916610100841515021790558015610df05760188190555b5050565b600a546001600160a01b03163314610e1e5760405162461bcd60e51b8152600401610b6490612f76565b47610e31600a546001600160a01b031690565b6001600160a01b03166108fc829081150290604051600060405180830381858888f19350505050158015610df0573d6000803e3d6000fd5b323314610e885760405162461bcd60e51b8152600401610b6490612fab565b6002600b541415610eab5760405162461bcd60e51b8152600401610b6490612fd6565b6002600b5533600090815260136020526040902054610ec8610ce1565b610f145760405162461bcd60e51b815260206004820152601b60248201527f50726573616c6520686173206e6f7420737461727465642079657400000000006044820152606401610b64565b3360009081526019602052604090205460ff16610f735760405162461bcd60e51b815260206004820152601960248201527f596f7520617265206e6f74206f6e207768697465206c697374000000000000006044820152606401610b64565b600f54610f8083836120c9565b1115610fda5760405162461bcd60e51b8152602060048201526024808201527f45786365656473206d61782070726573616c6520616c6c6f77656420706572206044820152633ab9b2b960e11b6064820152608401610b64565b601154601254610fea90846120c9565b11156110385760405162461bcd60e51b815260206004820152601a60248201527f45786365656473206d61782070726573616c6520737570706c790000000000006044820152606401610b64565b600082116110885760405162461bcd60e51b815260206004820152601c60248201527f4d757374206d696e74206174206c65617374206f6e6520746f6b656e000000006044820152606401610b64565b600d5434906110979084612128565b11156110e55760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f7272656374006044820152606401610b64565b61110f60136000335b6001600160a01b0316815260208101919091526040016000205483906120c9565b60136000335b6001600160a01b0316815260208101919091526040016000205560125461113c90836120c9565b60125550506001600b55565b610c9a8383836040518060200160405280600081525061177d565b600a546001600160a01b0316331461118d5760405162461bcd60e51b8152600401610b6490612f76565b6000611197610c9f565b90506001600160a01b0383166111ef5760405162461bcd60e51b815260206004820152601b60248201527f496e76616c6964206164647265737320746f20726573657276652e00000000006044820152606401610b64565b601254811461124a5760405162461bcd60e51b815260206004820152602160248201527f5469636b657420696420616e6420737570706c79206e6f74206d6174636865646044820152601760f91b6064820152608401610b64565b60005b8281101561127a57611268846112638385613023565b6121a7565b806112728161303b565b91505061124d565b60125461128790846120c9565b60125550505050565b6000610d4382611dcd565b6000806112a96002846121c1565b509392505050565b600a546001600160a01b031633146112db5760405162461bcd60e51b8152600401610b6490612f76565b60005b81811015610c9a576000601960008585858181106112fe576112fe613056565b90506020020160208101906113139190612c06565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055806113458161303b565b9150506112de565b600a546001600160a01b031633146113775760405162461bcd60e51b8152600401610b6490612f76565b611380816121dd565b50565b6000610d438260405180606001604052806029815260200161322060299139600291906121f0565b6001600160a01b0381166000908152601560209081526040808320546014835281842054601390935290832054610d43926113e691906120c9565b90612207565b606060098054610a7990612ef0565b600a546001600160a01b031633146114255760405162461bcd60e51b8152600401610b6490612f76565b601055565b60006001600160a01b0382166114955760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610b64565b6001600160a01b0382166000908152600160205260409020610d4390611e48565b600a546001600160a01b031633146114e05760405162461bcd60e51b8152600401610b6490612f76565b600a546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600a80546001600160a01b0319169055565b606060006115378361142a565b9050806115545760408051600080825260208201909252906112a9565b60008167ffffffffffffffff81111561156f5761156f612cfe565b604051908082528060200260200182016040528015611598578160200160208202803683370190505b50905060005b828110156112a9576115b08582610d1e565b8282815181106115c2576115c2613056565b6020908102919091010152806115d78161303b565b91505061159e565b50919050565b6016546000904290610100900460ff168015610d0957508060185411610d1657600191505090565b606060078054610a7990612ef0565b6001600160a01b0382163314156116755760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610b64565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600a546001600160a01b0316331461170b5760405162461bcd60e51b8152600401610b6490612f76565b60005b81811015610c9a5760016019600085858581811061172e5761172e613056565b90506020020160208101906117439190612c06565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055806117758161303b565b91505061170e565b6117873383611e52565b6117a35760405162461bcd60e51b8152600401610b6490612f25565b6117af84848484612263565b50505050565b3233146117d45760405162461bcd60e51b8152600401610b6490612fab565b6002600b5414156117f75760405162461bcd60e51b8152600401610b6490612fd6565b6002600b556000611807336113ab565b905060005b8181101561183d57600061181e610c9f565b905061182a33826121a7565b50806118358161303b565b91505061180c565b50336000908152601560205260409020546118599082906120c9565b33600090815260156020526040902055506001600b55565b606061187c82611dcd565b6118e05760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610b64565b600082815260086020526040812080546118f990612ef0565b80601f016020809104026020016040519081016040528092919081815260200182805461192590612ef0565b80156119725780601f1061194757610100808354040283529160200191611972565b820191906000526020600020905b81548152906001019060200180831161195557829003601f168201915b5050505050905060006119836113ec565b9050805160001415611996575092915050565b8151156119c85780826040516020016119b092919061306c565b60405160208183030381529060405292505050919050565b806119d285612296565b6040516020016119b092919061306c565b600a546001600160a01b03163314611a0d5760405162461bcd60e51b8152600401610b6490612f76565b6016805460ff19168315151790558015610df05760175550565b323314611a465760405162461bcd60e51b8152600401610b6490612fab565b6002600b541415611a695760405162461bcd60e51b8152600401610b6490612fd6565b6002600b5533600090815260146020526040902054611a866115e5565b611ad25760405162461bcd60e51b815260206004820152601f60248201527f5075626c69632073616c6520686173206e6f74207374617274656420796574006044820152606401610b64565b600e54611adf83836120c9565b1115611b3e5760405162461bcd60e51b815260206004820152602860248201527f45786365656473206d6178207075626c69632073616c6520616c6c6f776564206044820152673832b9103ab9b2b960c11b6064820152608401610b64565b601054601254611b4e90846120c9565b1115611b915760405162461bcd60e51b815260206004820152601260248201527145786365656473206d617820737570706c7960701b6044820152606401610b64565b60008211611be15760405162461bcd60e51b815260206004820152601c60248201527f4d757374206d696e74206174206c65617374206f6e6520746f6b656e000000006044820152606401610b64565b600c543490611bf09084612128565b1115611c3e5760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f7272656374006044820152606401610b64565b611c4b60146000336110ee565b6014600033611115565b600a546001600160a01b03163314611c7f5760405162461bcd60e51b8152600401610b6490612f76565b600f55565b600a546001600160a01b03163314611cae5760405162461bcd60e51b8152600401610b6490612f76565b6001600160a01b038116611d135760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b64565b600a546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600a80546001600160a01b0319166001600160a01b0392909216919091179055565b600a546001600160a01b03163314611d995760405162461bcd60e51b8152600401610b6490612f76565b600c55565b600a546001600160a01b03163314611dc85760405162461bcd60e51b8152600401610b6490612f76565b601155565b6000610d43600283612394565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611e0f82611383565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610d43825490565b6000611e5d82611dcd565b611ebe5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610b64565b6000611ec983611383565b9050806001600160a01b0316846001600160a01b03161480611f045750836001600160a01b0316611ef984610afc565b6001600160a01b0316145b80611f3457506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611f4f82611383565b6001600160a01b031614611fb75760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610b64565b6001600160a01b0382166120195760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610b64565b612024600082611dda565b6001600160a01b038316600090815260016020526040902061204690826123ac565b506001600160a01b038216600090815260016020526040902061206990826123b8565b50612076600282846123c4565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000610d4083836123da565b6000806120d68385613023565b905083811015610d405760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610b64565b60008261213757506000610d43565b6000612143838561309b565b90508261215085836130d0565b14610d405760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610b64565b610df0828260405180602001604052806000815250612460565b60008080806121d08686612493565b9097909650945050505050565b8051610df0906009906020840190612a70565b60006121fd848484612530565b90505b9392505050565b6000828211156122595760405162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006044820152606401610b64565b610d4082846130e4565b61226e848484611f3c565b61227a84848484612599565b6117af5760405162461bcd60e51b8152600401610b64906130fb565b6060816122ba5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156122e457806122ce8161303b565b91506122dd9050600a836130d0565b91506122be565b60008167ffffffffffffffff8111156122ff576122ff612cfe565b6040519080825280601f01601f191660200182016040528015612329576020820181803683370190505b5090505b8415611f345761233e6001836130e4565b915061234b600a8661314d565b612356906030613023565b60f81b81838151811061236b5761236b613056565b60200101906001600160f81b031916908160001a90535061238d600a866130d0565b945061232d565b60008181526001830160205260408120541515610d40565b6000610d40838361266a565b6000610d40838361275d565b60006121fd84846001600160a01b0385166127ac565b815460009082106124385760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610b64565b82600001828154811061244d5761244d613056565b9060005260206000200154905092915050565b61246a838361284d565b6124776000848484612599565b610c9a5760405162461bcd60e51b8152600401610b64906130fb565b8154600090819083106124f35760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610b64565b600084600001848154811061250a5761250a613056565b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816125605760405162461bcd60e51b8152600401610b649190612b94565b508461256d6001836130e4565b8154811061257d5761257d613056565b9060005260206000209060020201600101549150509392505050565b60006001600160a01b0384163b6125b257506001611f34565b6000612633630a85bd0160e11b338887876040516024016125d69493929190613161565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050506040518060600160405280603281526020016131ee603291396001600160a01b0388169190612965565b905060008180602001905181019061264b919061319e565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b6000818152600183016020526040812054801561275357600061268e6001836130e4565b85549091506000906126a2906001906130e4565b905060008660000182815481106126bb576126bb613056565b90600052602060002001549050808760000184815481106126de576126de613056565b6000918252602090912001556126f5836001613023565b60008281526001890160205260409020558654879080612717576127176131bb565b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610d43565b6000915050610d43565b60008181526001830160205260408120546127a457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d43565b506000610d43565b600082815260018401602052604081205480612811575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055612200565b828561281e6001846130e4565b8154811061282e5761282e613056565b9060005260206000209060020201600101819055506000915050612200565b6001600160a01b0382166128a35760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610b64565b6128ac81611dcd565b156128f95760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610b64565b6001600160a01b038216600090815260016020526040902061291b90826123b8565b50612928600282846123c4565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60606121fd848460008585843b6129be5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b64565b600080866001600160a01b031685876040516129da91906131d1565b60006040518083038185875af1925050503d8060008114612a17576040519150601f19603f3d011682016040523d82523d6000602084013e612a1c565b606091505b5091509150612a2c828286612a37565b979650505050505050565b60608315612a46575081612200565b825115612a565782518084602001fd5b8160405162461bcd60e51b8152600401610b649190612b94565b828054612a7c90612ef0565b90600052602060002090601f016020900481019282612a9e5760008555612ae4565b82601f10612ab757805160ff1916838001178555612ae4565b82800160010185558215612ae4579182015b82811115612ae4578251825591602001919060010190612ac9565b50612af0929150612af4565b5090565b5b80821115612af05760008155600101612af5565b6001600160e01b03198116811461138057600080fd5b600060208284031215612b3157600080fd5b8135610d4081612b09565b60005b83811015612b57578181015183820152602001612b3f565b838111156117af5750506000910152565b60008151808452612b80816020860160208601612b3c565b601f01601f19169290920160200192915050565b602081526000610d406020830184612b68565b600060208284031215612bb957600080fd5b5035919050565b80356001600160a01b0381168114612bd757600080fd5b919050565b60008060408385031215612bef57600080fd5b612bf883612bc0565b946020939093013593505050565b600060208284031215612c1857600080fd5b610d4082612bc0565b600080600060608486031215612c3657600080fd5b612c3f84612bc0565b9250612c4d60208501612bc0565b9150604084013590509250925092565b80358015158114612bd757600080fd5b60008060408385031215612c8057600080fd5b612bf883612c5d565b60008060208385031215612c9c57600080fd5b823567ffffffffffffffff80821115612cb457600080fd5b818501915085601f830112612cc857600080fd5b813581811115612cd757600080fd5b8660208260051b8501011115612cec57600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612d2f57612d2f612cfe565b604051601f8501601f19908116603f01168101908282118183101715612d5757612d57612cfe565b81604052809350858152868686011115612d7057600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215612d9c57600080fd5b813567ffffffffffffffff811115612db357600080fd5b8201601f81018413612dc457600080fd5b611f3484823560208401612d14565b6020808252825182820181905260009190848201906040850190845b81811015612e0b57835183529284019291840191600101612def565b50909695505050505050565b60008060408385031215612e2a57600080fd5b612e3383612bc0565b9150612e4160208401612c5d565b90509250929050565b60008060008060808587031215612e6057600080fd5b612e6985612bc0565b9350612e7760208601612bc0565b925060408501359150606085013567ffffffffffffffff811115612e9a57600080fd5b8501601f81018713612eab57600080fd5b612eba87823560208401612d14565b91505092959194509250565b60008060408385031215612ed957600080fd5b612ee283612bc0565b9150612e4160208401612bc0565b600181811c90821680612f0457607f821691505b602082108114156115df57634e487b7160e01b600052602260045260246000fd5b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b602080825260119082015270736f7272792068756d616e73206f6e6c7960781b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082198211156130365761303661300d565b500190565b600060001982141561304f5761304f61300d565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6000835161307e818460208801612b3c565b835190830190613092818360208801612b3c565b01949350505050565b60008160001904831182151516156130b5576130b561300d565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826130df576130df6130ba565b500490565b6000828210156130f6576130f661300d565b500390565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60008261315c5761315c6130ba565b500690565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061319490830184612b68565b9695505050505050565b6000602082840312156131b057600080fd5b8151610d4081612b09565b634e487b7160e01b600052603160045260246000fd5b600082516131e3818460208701612b3c565b919091019291505056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220e38dad1205bebd25f4398a5be34b38ca1e20c1991faae774ca5afc514131f68c64736f6c63430008090033
Deployed Bytecode Sourcemap
68607:6934:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9535:150;;;;;;;;;;-1:-1:-1;9535:150:0;;;;;:::i;:::-;-1:-1:-1;;;;;;9644:33:0;9620:4;9644:33;;;;;;;;;;;;;;9535:150;;;;565:14:1;;558:22;540:41;;528:2;513:18;9535:150:0;;;;;;;;51381:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;54167:221::-;;;;;;;;;;-1:-1:-1;54167:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1692:32:1;;;1674:51;;1662:2;1647:18;54167:221:0;1528:203:1;53697:404:0;;;;;;;;;;-1:-1:-1;53697:404:0;;;;;:::i;:::-;;:::i;:::-;;73087:114;;;;;;;;;;-1:-1:-1;73087:114:0;;;;;:::i;:::-;-1:-1:-1;;;;;73171:22:0;73147:4;73171:22;;;:16;:22;;;;;;;;;73087:114;68809:31;;;;;;;;;;;;;;;;;;;2510:25:1;;;2498:2;2483:18;68809:31:0;2364:177:1;53175:211:0;;;;;;;;;;;;;:::i;68881:31::-;;;;;;;;;;;;;;;;55057:305;;;;;;;;;;-1:-1:-1;55057:305:0;;;;;:::i;:::-;;:::i;70384:274::-;;;;;;;;;;;;;:::i;52937:162::-;;;;;;;;;;-1:-1:-1;52937:162:0;;;;;:::i;:::-;;:::i;71499:112::-;;;;;;;;;;-1:-1:-1;71499:112:0;;;;;:::i;:::-;;:::i;71025:108::-;;;;;;;;;;-1:-1:-1;71025:108:0;;;;;:::i;:::-;;:::i;72432:227::-;;;;;;;;;;-1:-1:-1;72432:227:0;;;;;:::i;:::-;;:::i;75396:142::-;;;;;;;;;;;;;:::i;73209:833::-;;;;;;:::i;:::-;;:::i;55433:151::-;;;;;;;;;;-1:-1:-1;55433:151:0;;;;;:::i;:::-;;:::i;71619:463::-;;;;;;;;;;-1:-1:-1;71619:463:0;;;;;:::i;:::-;;:::i;69198:36::-;;;;;;;;;;;;;;;;70272:104;;;;;;;;;;-1:-1:-1;70272:104:0;;;;;:::i;:::-;;:::i;53463:172::-;;;;;;;;;;-1:-1:-1;53463:172:0;;;;;:::i;:::-;;:::i;72875:204::-;;;;;;;;;;-1:-1:-1;72875:204:0;;;;;:::i;:::-;;:::i;72090:101::-;;;;;;;;;;-1:-1:-1;72090:101:0;;;;;:::i;:::-;;:::i;68772:30::-;;;;;;;;;;;;;;;;68734:31;;;;;;;;;;;;;;;;51137:177;;;;;;;;;;-1:-1:-1;51137:177:0;;;;;:::i;:::-;;:::i;68703:24::-;;;;;;;;;;;;;;;;74797:180;;;;;;;;;;-1:-1:-1;74797:180:0;;;;;:::i;:::-;;:::i;52756:97::-;;;;;;;;;;;;;:::i;71141:106::-;;;;;;;;;;-1:-1:-1;71141:106:0;;;;;:::i;:::-;;:::i;50854:221::-;;;;;;;;;;-1:-1:-1;50854:221:0;;;;;:::i;:::-;;:::i;65991:148::-;;;;;;;;;;;;;:::i;68919:26::-;;;;;;;;;;;;;;;;69787:477;;;;;;;;;;-1:-1:-1;69787:477:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;70666:249::-;;;;;;;;;;;;;:::i;65340:87::-;;;;;;;;;;-1:-1:-1;65413:6:0;;-1:-1:-1;;;;;65413:6:0;65340:87;;51550:104;;;;;;;;;;;;;:::i;54460:295::-;;;;;;;;;;-1:-1:-1;54460:295:0;;;;;:::i;:::-;;:::i;68847:27::-;;;;;;;;;;;;;;;;69158:29;;;;;;;;;;-1:-1:-1;69158:29:0;;;;;;;;;;;72667:200;;;;;;;;;;-1:-1:-1;72667:200:0;;;;;:::i;:::-;;:::i;55655:285::-;;;;;;;;;;-1:-1:-1;55655:285:0;;;;;:::i;:::-;;:::i;74985:403::-;;;;;;;;;;;;;:::i;51725:792::-;;;;;;;;;;-1:-1:-1;51725:792:0;;;;;:::i;:::-;;:::i;68954:51::-;;;;;;;;;;-1:-1:-1;68954:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;72199:225;;;;;;;;;;-1:-1:-1;72199:225:0;;;;;:::i;:::-;;:::i;69241:39::-;;;;;;;;;;;;;;;;74050:739;;;;;;:::i;:::-;;:::i;69125:26::-;;;;;;;;;;-1:-1:-1;69125:26:0;;;;;;;;54826:164;;;;;;;;;;-1:-1:-1;54826:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;54947:25:0;;;54923:4;54947:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;54826:164;71377:114;;;;;;;;;;-1:-1:-1;71377:114:0;;;;;:::i;:::-;;:::i;69069:47::-;;;;;;;;;;-1:-1:-1;69069:47:0;;;;;:::i;:::-;;;;;;;;;;;;;;66294:244;;;;;;;;;;-1:-1:-1;66294:244:0;;;;;:::i;:::-;;:::i;70923:94::-;;;;;;;;;;-1:-1:-1;70923:94:0;;;;;:::i;:::-;;:::i;71255:114::-;;;;;;;;;;-1:-1:-1;71255:114:0;;;;;:::i;:::-;;:::i;69012:50::-;;;;;;;;;;-1:-1:-1;69012:50:0;;;;;:::i;:::-;;;;;;;;;;;;;;51381:100;51435:13;51468:5;51461:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51381:100;:::o;54167:221::-;54243:7;54271:16;54279:7;54271;:16::i;:::-;54263:73;;;;-1:-1:-1;;;54263:73:0;;7562:2:1;54263:73:0;;;7544:21:1;7601:2;7581:18;;;7574:30;7640:34;7620:18;;;7613:62;-1:-1:-1;;;7691:18:1;;;7684:42;7743:19;;54263:73:0;;;;;;;;;-1:-1:-1;54356:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;54356:24:0;;54167:221::o;53697:404::-;53778:13;53794:23;53809:7;53794:14;:23::i;:::-;53778:39;;53842:5;-1:-1:-1;;;;;53836:11:0;:2;-1:-1:-1;;;;;53836:11:0;;;53828:57;;;;-1:-1:-1;;;53828:57:0;;7975:2:1;53828:57:0;;;7957:21:1;8014:2;7994:18;;;7987:30;8053:34;8033:18;;;8026:62;-1:-1:-1;;;8104:18:1;;;8097:31;8145:19;;53828:57:0;7773:397:1;53828:57:0;687:10;-1:-1:-1;;;;;53906:21:0;;;;:69;;-1:-1:-1;53931:44:0;53955:5;687:10;54826:164;:::i;53931:44::-;53898:161;;;;-1:-1:-1;;;53898:161:0;;8377:2:1;53898:161:0;;;8359:21:1;8416:2;8396:18;;;8389:30;8455:34;8435:18;;;8428:62;8526:26;8506:18;;;8499:54;8570:19;;53898:161:0;8175:420:1;53898:161:0;54072:21;54081:2;54085:7;54072:8;:21::i;:::-;53767:334;53697:404;;:::o;53175:211::-;53236:7;53357:21;:12;:19;:21::i;:::-;53350:28;;53175:211;:::o;55057:305::-;55218:41;687:10;55251:7;55218:18;:41::i;:::-;55210:103;;;;-1:-1:-1;;;55210:103:0;;;;;;;:::i;:::-;55326:28;55336:4;55342:2;55346:7;55326:9;:28::i;70384:274::-;70499:14;;70429:4;;70469:15;;70499:14;;:55;;;;;70542:12;70517:21;;:37;;70499:55;:89;;;;;70572:16;;70558:11;;:30;70499:89;70495:133;;;70612:4;70605:11;;;70384:274;:::o;70495:133::-;70645:5;70638:12;;;70384:274;:::o;52937:162::-;-1:-1:-1;;;;;53061:20:0;;53034:7;53061:20;;;:13;:20;;;;;:30;;53085:5;53061:23;:30::i;:::-;53054:37;;52937:162;;;;;:::o;71499:112::-;65413:6;;-1:-1:-1;;;;;65413:6:0;687:10;65560:23;65552:68;;;;-1:-1:-1;;;65552:68:0;;;;;;;:::i;:::-;71576:15:::1;:27:::0;71499:112::o;71025:108::-;65413:6;;-1:-1:-1;;;;;65413:6:0;687:10;65560:23;65552:68;;;;-1:-1:-1;;;65552:68:0;;;;;;;:::i;:::-;71100:16:::1;:25:::0;71025:108::o;72432:227::-;65413:6;;-1:-1:-1;;;;;65413:6:0;687:10;65560:23;65552:68;;;;-1:-1:-1;;;65552:68:0;;;;;;;:::i;:::-;72528:17:::1;:29:::0;;-1:-1:-1;;72528:29:0::1;;::::0;::::1;;;;::::0;;72572:14;;72568:83:::1;;72603:24;:36:::0;;;72568:83:::1;72432:227:::0;;:::o;75396:142::-;65413:6;;-1:-1:-1;;;;;65413:6:0;687:10;65560:23;65552:68;;;;-1:-1:-1;;;65552:68:0;;;;;;;:::i;:::-;75464:21:::1;75504:7;65413:6:::0;;-1:-1:-1;;;;;65413:6:0;;65340:87;75504:7:::1;-1:-1:-1::0;;;;;75496:25:0::1;:34;75522:7;75496:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;73209:833:::0;68432:9;68445:10;68432:23;68424:53;;;;-1:-1:-1;;;68424:53:0;;;;;;;:::i;:::-;67429:1:::1;68044:7;;:19;;68036:63;;;;-1:-1:-1::0;;;68036:63:0::1;;;;;;;:::i;:::-;67429:1;68177:7;:18:::0;687:10;73301:17:::2;73321:30:::0;;;:16:::2;:30;::::0;;;;;73372:15:::2;:13;:15::i;:::-;73364:55;;;::::0;-1:-1:-1;;;73364:55:0;;10287:2:1;73364:55:0::2;::::0;::::2;10269:21:1::0;10326:2;10306:18;;;10299:30;10365:29;10345:18;;;10338:57;10412:18;;73364:55:0::2;10085:351:1::0;73364:55:0::2;687:10:::0;73438:30:::2;::::0;;;:16:::2;:30;::::0;;;;;::::2;;73430:68;;;::::0;-1:-1:-1;;;73430:68:0;;10643:2:1;73430:68:0::2;::::0;::::2;10625:21:1::0;10682:2;10662:18;;;10655:30;10721:27;10701:18;;;10694:55;10766:18;;73430:68:0::2;10441:349:1::0;73430:68:0::2;73550:16;::::0;73517:29:::2;:14:::0;73536:9;73517:18:::2;:29::i;:::-;:49;;73509:98;;;::::0;-1:-1:-1;;;73509:98:0;;10997:2:1;73509:98:0::2;::::0;::::2;10979:21:1::0;11036:2;11016:18;;;11009:30;11075:34;11055:18;;;11048:62;-1:-1:-1;;;11126:18:1;;;11119:34;11170:19;;73509:98:0::2;10795:400:1::0;73509:98:0::2;73661:16;::::0;73626:11:::2;::::0;:31:::2;::::0;73642:14;73626:15:::2;:31::i;:::-;:51;;73618:90;;;::::0;-1:-1:-1;;;73618:90:0;;11402:2:1;73618:90:0::2;::::0;::::2;11384:21:1::0;11441:2;11421:18;;;11414:30;11480:28;11460:18;;;11453:56;11526:18;;73618:90:0::2;11200:350:1::0;73618:90:0::2;73744:1;73727:14;:18;73719:59;;;::::0;-1:-1:-1;;;73719:59:0;;11757:2:1;73719:59:0::2;::::0;::::2;11739:21:1::0;11796:2;11776:18;;;11769:30;11835;11815:18;;;11808:58;11883:18;;73719:59:0::2;11555:352:1::0;73719:59:0::2;73797:16;::::0;73837:9:::2;::::0;73797:36:::2;::::0;73818:14;73797:20:::2;:36::i;:::-;:49;;73789:93;;;::::0;-1:-1:-1;;;73789:93:0;;12114:2:1;73789:93:0::2;::::0;::::2;12096:21:1::0;12153:2;12133:18;;;12126:30;12192:33;12172:18;;;12165:61;12243:18;;73789:93:0::2;11912:355:1::0;73789:93:0::2;73928:50;73947:16;:30;687:10:::0;73964:12:::2;-1:-1:-1::0;;;;;73947:30:0::2;::::0;;::::2;::::0;::::2;::::0;;;;;;-1:-1:-1;73947:30:0;;73928:14;;:18:::2;:50::i;:::-;73895:16;:30;687:10:::0;73912:12:::2;-1:-1:-1::0;;;;;73895:30:0::2;::::0;;::::2;::::0;::::2;::::0;;;;;;-1:-1:-1;73895:30:0;:83;74003:11:::2;::::0;:31:::2;::::0;74019:14;74003:15:::2;:31::i;:::-;73989:11;:45:::0;-1:-1:-1;;67385:1:0::1;68356:7;:22:::0;73209:833::o;55433:151::-;55537:39;55554:4;55560:2;55564:7;55537:39;;;;;;;;;;;;:16;:39::i;71619:463::-;65413:6;;-1:-1:-1;;;;;65413:6:0;687:10;65560:23;65552:68;;;;-1:-1:-1;;;65552:68:0;;;;;;;:::i;:::-;71708:14:::1;71725:13;:11;:13::i;:::-;71708:30:::0;-1:-1:-1;;;;;;71757:17:0;::::1;71749:57;;;::::0;-1:-1:-1;;;71749:57:0;;12474:2:1;71749:57:0::1;::::0;::::1;12456:21:1::0;12513:2;12493:18;;;12486:30;12552:29;12532:18;;;12525:57;12599:18;;71749:57:0::1;12272:351:1::0;71749:57:0::1;71835:11;;71825:6;:21;71817:67;;;::::0;-1:-1:-1;;;71817:67:0;;12830:2:1;71817:67:0::1;::::0;::::1;12812:21:1::0;12869:2;12849:18;;;12842:30;12908:34;12888:18;;;12881:62;-1:-1:-1;;;12959:18:1;;;12952:31;13000:19;;71817:67:0::1;12628:397:1::0;71817:67:0::1;71895:9;71925:91;71941:15;71937:1;:19;71925:91;;;71978:26;71988:3:::0;71993:10:::1;72002:1:::0;71993:6;:10:::1;:::i;:::-;71978:9;:26::i;:::-;71958:3:::0;::::1;::::0;::::1;:::i;:::-;;;;71925:91;;;72042:11;::::0;:32:::1;::::0;72058:15;72042::::1;:32::i;:::-;72028:11;:46:::0;-1:-1:-1;;;;71619:463:0:o;70272:104::-;70327:4;70351:17;70359:8;70351:7;:17::i;53463:172::-;53538:7;;53580:22;:12;53596:5;53580:15;:22::i;:::-;-1:-1:-1;53558:44:0;53463:172;-1:-1:-1;;;53463:172:0:o;72875:204::-;65413:6;;-1:-1:-1;;;;;65413:6:0;687:10;65560:23;65552:68;;;;-1:-1:-1;;;65552:68:0;;;;;;;:::i;:::-;72965:9:::1;72960:112;72980:20:::0;;::::1;72960:112;;;73055:5;73022:16;:30;73039:9;;73049:1;73039:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;73022:30:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;73022:30:0;:38;;-1:-1:-1;;73022:38:0::1;::::0;::::1;;::::0;;;::::1;::::0;;73002:3;::::1;::::0;::::1;:::i;:::-;;;;72960:112;;72090:101:::0;65413:6;;-1:-1:-1;;;;;65413:6:0;687:10;65560:23;65552:68;;;;-1:-1:-1;;;65552:68:0;;;;;;;:::i;:::-;72163:20:::1;72175:7;72163:11;:20::i;:::-;72090:101:::0;:::o;51137:177::-;51209:7;51236:70;51253:7;51236:70;;;;;;;;;;;;;;;;;:12;;:70;:16;:70::i;74797:180::-;-1:-1:-1;;;;;74950:18:0;;74869:7;74950:18;;;:12;:18;;;;;;;;;74923:15;:21;;;;;;74896:16;:22;;;;;;;:73;;:49;;:22;:26;:49::i;:::-;:53;;:73::i;52756:97::-;52804:13;52837:8;52830:15;;;;;:::i;71141:106::-;65413:6;;-1:-1:-1;;;;;65413:6:0;687:10;65560:23;65552:68;;;;-1:-1:-1;;;65552:68:0;;;;;;;:::i;:::-;71215:12:::1;:24:::0;71141:106::o;50854:221::-;50926:7;-1:-1:-1;;;;;50954:19:0;;50946:74;;;;-1:-1:-1;;;50946:74:0;;13769:2:1;50946:74:0;;;13751:21:1;13808:2;13788:18;;;13781:30;13847:34;13827:18;;;13820:62;-1:-1:-1;;;13898:18:1;;;13891:40;13948:19;;50946:74:0;13567:406:1;50946:74:0;-1:-1:-1;;;;;51038:20:0;;;;;;:13;:20;;;;;:29;;:27;:29::i;65991:148::-;65413:6;;-1:-1:-1;;;;;65413:6:0;687:10;65560:23;65552:68;;;;-1:-1:-1;;;65552:68:0;;;;;;;:::i;:::-;66082:6:::1;::::0;66061:40:::1;::::0;66098:1:::1;::::0;-1:-1:-1;;;;;66082:6:0::1;::::0;66061:40:::1;::::0;66098:1;;66061:40:::1;66112:6;:19:::0;;-1:-1:-1;;;;;;66112:19:0::1;::::0;;65991:148::o;69787:477::-;69848:16;69877:18;69898:17;69908:6;69898:9;:17::i;:::-;69877:38;-1:-1:-1;69930:15:0;69926:331;;69969:16;;;69983:1;69969:16;;;;;;;;;;;;69926:331;70018:23;70058:10;70044:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;70044:25:0;;70018:51;;70089:13;70084:134;70112:10;70104:5;:18;70084:134;;;70168:34;70188:6;70196:5;70168:19;:34::i;:::-;70152:6;70159:5;70152:13;;;;;;;;:::i;:::-;;;;;;;;;;:50;70124:7;;;;:::i;:::-;;;;70084:134;;69926:331;69866:398;69787:477;;;:::o;70666:249::-;70784:17;;70714:4;;70754:15;;70784:17;;;;;:61;;;;;70833:12;70805:24;;:40;70780:105;;70869:4;70862:11;;;70666:249;:::o;51550:104::-;51606:13;51639:7;51632:14;;;;;:::i;54460:295::-;-1:-1:-1;;;;;54563:24:0;;687:10;54563:24;;54555:62;;;;-1:-1:-1;;;54555:62:0;;14180:2:1;54555:62:0;;;14162:21:1;14219:2;14199:18;;;14192:30;14258:27;14238:18;;;14231:55;14303:18;;54555:62:0;13978:349:1;54555:62:0;687:10;54630:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;54630:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;54630:53:0;;;;;;;;;;54699:48;;540:41:1;;;54630:42:0;;687:10;54699:48;;513:18:1;54699:48:0;;;;;;;54460:295;;:::o;72667:200::-;65413:6;;-1:-1:-1;;;;;65413:6:0;687:10;65560:23;65552:68;;;;-1:-1:-1;;;65552:68:0;;;;;;;:::i;:::-;72754:9:::1;72749:111;72769:20:::0;;::::1;72749:111;;;72844:4;72811:16;:30;72828:9;;72838:1;72828:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;72811:30:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;72811:30:0;:37;;-1:-1:-1;;72811:37:0::1;::::0;::::1;;::::0;;;::::1;::::0;;72791:3;::::1;::::0;::::1;:::i;:::-;;;;72749:111;;55655:285:::0;55787:41;687:10;55820:7;55787:18;:41::i;:::-;55779:103;;;;-1:-1:-1;;;55779:103:0;;;;;;;:::i;:::-;55893:39;55907:4;55913:2;55917:7;55926:5;55893:13;:39::i;:::-;55655:285;;;;:::o;74985:403::-;68432:9;68445:10;68432:23;68424:53;;;;-1:-1:-1;;;68424:53:0;;;;;;;:::i;:::-;67429:1:::1;68044:7;;:19;;68036:63;;;;-1:-1:-1::0;;;68036:63:0::1;;;;;;;:::i;:::-;67429:1;68177:7;:18:::0;75047:24:::2;75074:41;687:10:::0;74797:180;:::i;75074:41::-:2;75047:68;;75140:9;75136:155;75159:16;75155:1;:20;75136:155;;;75197:17;75217:13;:11;:13::i;:::-;75197:33:::0;-1:-1:-1;75245:34:0::2;687:10:::0;75269:9:::2;75245;:34::i;:::-;-1:-1:-1::0;75177:3:0;::::2;::::0;::::2;:::i;:::-;;;;75136:155;;;-1:-1:-1::0;687:10:0;75353:26:::2;::::0;;;:12:::2;:26;::::0;;;;;75332:48:::2;::::0;:16;;:20:::2;:48::i;:::-;687:10:::0;75303:26:::2;::::0;;;:12:::2;:26;::::0;;;;:77;-1:-1:-1;67385:1:0::1;68356:7;:22:::0;74985:403::o;51725:792::-;51798:13;51832:16;51840:7;51832;:16::i;:::-;51824:76;;;;-1:-1:-1;;;51824:76:0;;14534:2:1;51824:76:0;;;14516:21:1;14573:2;14553:18;;;14546:30;14612:34;14592:18;;;14585:62;-1:-1:-1;;;14663:18:1;;;14656:45;14718:19;;51824:76:0;14332:411:1;51824:76:0;51913:23;51939:19;;;:10;:19;;;;;51913:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51969:18;51990:9;:7;:9::i;:::-;51969:30;;52081:4;52075:18;52097:1;52075:23;52071:72;;;-1:-1:-1;52122:9:0;51725:792;-1:-1:-1;;51725:792:0:o;52071:72::-;52247:23;;:27;52243:108;;52322:4;52328:9;52305:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;52291:48;;;;51725:792;;;:::o;52243:108::-;52483:4;52489:18;:7;:16;:18::i;:::-;52466:42;;;;;;;;;:::i;72199:225::-;65413:6;;-1:-1:-1;;;;;65413:6:0;687:10;65560:23;65552:68;;;;-1:-1:-1;;;65552:68:0;;;;;;;:::i;:::-;72292:14:::1;:26:::0;;-1:-1:-1;;72292:26:0::1;::::0;::::1;;;::::0;;72333:14;;72329:80:::1;;72364:21;:33:::0;-1:-1:-1;72199:225:0:o;74050:739::-;68432:9;68445:10;68432:23;68424:53;;;;-1:-1:-1;;;68424:53:0;;;;;;;:::i;:::-;67429:1:::1;68044:7;;:19;;68036:63;;;;-1:-1:-1::0;;;68036:63:0::1;;;;;;;:::i;:::-;67429:1;68177:7;:18:::0;687:10;74141:17:::2;74161:29:::0;;;:15:::2;:29;::::0;;;;;74209:18:::2;:16;:18::i;:::-;74201:62;;;::::0;-1:-1:-1;;;74201:62:0;;15425:2:1;74201:62:0::2;::::0;::::2;15407:21:1::0;15464:2;15444:18;;;15437:30;15503:33;15483:18;;;15476:61;15554:18;;74201:62:0::2;15223:355:1::0;74201:62:0::2;74315:15;::::0;74282:29:::2;:14:::0;74301:9;74282:18:::2;:29::i;:::-;:48;;74274:101;;;::::0;-1:-1:-1;;;74274:101:0;;15785:2:1;74274:101:0::2;::::0;::::2;15767:21:1::0;15824:2;15804:18;;;15797:30;15863:34;15843:18;;;15836:62;-1:-1:-1;;;15914:18:1;;;15907:38;15962:19;;74274:101:0::2;15583:404:1::0;74274:101:0::2;74429:12;::::0;74394:11:::2;::::0;:31:::2;::::0;74410:14;74394:15:::2;:31::i;:::-;:47;;74386:78;;;::::0;-1:-1:-1;;;74386:78:0;;16194:2:1;74386:78:0::2;::::0;::::2;16176:21:1::0;16233:2;16213:18;;;16206:30;-1:-1:-1;;;16252:18:1;;;16245:48;16310:18;;74386:78:0::2;15992:342:1::0;74386:78:0::2;74500:1;74483:14;:18;74475:59;;;::::0;-1:-1:-1;;;74475:59:0;;11757:2:1;74475:59:0::2;::::0;::::2;11739:21:1::0;11796:2;11776:18;;;11769:30;11835;11815:18;;;11808:58;11883:18;;74475:59:0::2;11555:352:1::0;74475:59:0::2;74553:9;::::0;74586::::2;::::0;74553:29:::2;::::0;74567:14;74553:13:::2;:29::i;:::-;:42;;74545:86;;;::::0;-1:-1:-1;;;74545:86:0;;12114:2:1;74545:86:0::2;::::0;::::2;12096:21:1::0;12153:2;12133:18;;;12126:30;12192:33;12172:18;;;12165:61;12243:18;;74545:86:0::2;11912:355:1::0;74545:86:0::2;74676:49;74695:15;:29;687:10:::0;74711:12:::2;607:98:::0;74676:49:::2;74644:15;:29;687:10:::0;74660:12:::2;607:98:::0;71377:114;65413:6;;-1:-1:-1;;;;;65413:6:0;687:10;65560:23;65552:68;;;;-1:-1:-1;;;65552:68:0;;;;;;;:::i;:::-;71455:16:::1;:28:::0;71377:114::o;66294:244::-;65413:6;;-1:-1:-1;;;;;65413:6:0;687:10;65560:23;65552:68;;;;-1:-1:-1;;;65552:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;66383:22:0;::::1;66375:73;;;::::0;-1:-1:-1;;;66375:73:0;;16541:2:1;66375:73:0::1;::::0;::::1;16523:21:1::0;16580:2;16560:18;;;16553:30;16619:34;16599:18;;;16592:62;-1:-1:-1;;;16670:18:1;;;16663:36;16716:19;;66375:73:0::1;16339:402:1::0;66375:73:0::1;66485:6;::::0;66464:38:::1;::::0;-1:-1:-1;;;;;66464:38:0;;::::1;::::0;66485:6:::1;::::0;66464:38:::1;::::0;66485:6:::1;::::0;66464:38:::1;66513:6;:17:::0;;-1:-1:-1;;;;;;66513:17:0::1;-1:-1:-1::0;;;;;66513:17:0;;;::::1;::::0;;;::::1;::::0;;66294:244::o;70923:94::-;65413:6;;-1:-1:-1;;;;;65413:6:0;687:10;65560:23;65552:68;;;;-1:-1:-1;;;65552:68:0;;;;;;;:::i;:::-;70991:9:::1;:18:::0;70923:94::o;71255:114::-;65413:6;;-1:-1:-1;;;;;65413:6:0;687:10;65560:23;65552:68;;;;-1:-1:-1;;;65552:68:0;;;;;;;:::i;:::-;71333:16:::1;:28:::0;71255:114::o;57407:127::-;57472:4;57496:30;:12;57518:7;57496:21;:30::i;63425:192::-;63500:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;63500:29:0;-1:-1:-1;;;;;63500:29:0;;;;;;;;:24;;63554:23;63500:24;63554:14;:23::i;:::-;-1:-1:-1;;;;;63545:46:0;;;;;;;;;;;63425:192;;:::o;43260:123::-;43329:7;43356:19;43364:3;39922:19;;39839:110;57701:355;57794:4;57819:16;57827:7;57819;:16::i;:::-;57811:73;;;;-1:-1:-1;;;57811:73:0;;16948:2:1;57811:73:0;;;16930:21:1;16987:2;16967:18;;;16960:30;17026:34;17006:18;;;16999:62;-1:-1:-1;;;17077:18:1;;;17070:42;17129:19;;57811:73:0;16746:408:1;57811:73:0;57895:13;57911:23;57926:7;57911:14;:23::i;:::-;57895:39;;57964:5;-1:-1:-1;;;;;57953:16:0;:7;-1:-1:-1;;;;;57953:16:0;;:51;;;;57997:7;-1:-1:-1;;;;;57973:31:0;:20;57985:7;57973:11;:20::i;:::-;-1:-1:-1;;;;;57973:31:0;;57953:51;:94;;;-1:-1:-1;;;;;;54947:25:0;;;54923:4;54947:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;58008:39;57945:103;57701:355;-1:-1:-1;;;;57701:355:0:o;60837:599::-;60962:4;-1:-1:-1;;;;;60935:31:0;:23;60950:7;60935:14;:23::i;:::-;-1:-1:-1;;;;;60935:31:0;;60927:85;;;;-1:-1:-1;;;60927:85:0;;17361:2:1;60927:85:0;;;17343:21:1;17400:2;17380:18;;;17373:30;17439:34;17419:18;;;17412:62;-1:-1:-1;;;17490:18:1;;;17483:39;17539:19;;60927:85:0;17159:405:1;60927:85:0;-1:-1:-1;;;;;61049:16:0;;61041:65;;;;-1:-1:-1;;;61041:65:0;;17771:2:1;61041:65:0;;;17753:21:1;17810:2;17790:18;;;17783:30;17849:34;17829:18;;;17822:62;-1:-1:-1;;;17900:18:1;;;17893:34;17944:19;;61041:65:0;17569:400:1;61041:65:0;61223:29;61240:1;61244:7;61223:8;:29::i;:::-;-1:-1:-1;;;;;61265:19:0;;;;;;:13;:19;;;;;:35;;61292:7;61265:26;:35::i;:::-;-1:-1:-1;;;;;;61311:17:0;;;;;;:13;:17;;;;;:30;;61333:7;61311:21;:30::i;:::-;-1:-1:-1;61354:29:0;:12;61371:7;61380:2;61354:16;:29::i;:::-;;61420:7;61416:2;-1:-1:-1;;;;;61401:27:0;61410:4;-1:-1:-1;;;;;61401:27:0;;;;;;;;;;;60837:599;;;:::o;35090:137::-;35161:7;35196:22;35200:3;35212:5;35196:3;:22::i;13006:179::-;13064:7;;13096:5;13100:1;13096;:5;:::i;:::-;13084:17;;13125:1;13120;:6;;13112:46;;;;-1:-1:-1;;;13112:46:0;;18176:2:1;13112:46:0;;;18158:21:1;18215:2;18195:18;;;18188:30;18254:29;18234:18;;;18227:57;18301:18;;13112:46:0;17974:351:1;13885:220:0;13943:7;13967:6;13963:20;;-1:-1:-1;13982:1:0;13975:8;;13963:20;13994:9;14006:5;14010:1;14006;:5;:::i;:::-;13994:17;-1:-1:-1;14039:1:0;14030:5;14034:1;13994:17;14030:5;:::i;:::-;:10;14022:56;;;;-1:-1:-1;;;14022:56:0;;18962:2:1;14022:56:0;;;18944:21:1;19001:2;18981:18;;;18974:30;19040:34;19020:18;;;19013:62;-1:-1:-1;;;19091:18:1;;;19084:31;19132:19;;14022:56:0;18760:397:1;58399:110:0;58475:26;58485:2;58489:7;58475:26;;;;;;;;;;;;:9;:26::i;43722:236::-;43802:7;;;;43862:22;43866:3;43878:5;43862:3;:22::i;:::-;43831:53;;;;-1:-1:-1;43722:236:0;-1:-1:-1;;;;;43722:236:0:o;62037:100::-;62110:19;;;;:8;;:19;;;;;:::i;45008:213::-;45115:7;45166:44;45171:3;45191;45197:12;45166:4;:44::i;:::-;45158:53;-1:-1:-1;45008:213:0;;;;;;:::o;13468:158::-;13526:7;13559:1;13554;:6;;13546:49;;;;-1:-1:-1;;;13546:49:0;;19364:2:1;13546:49:0;;;19346:21:1;19403:2;19383:18;;;19376:30;19442:32;19422:18;;;19415:60;19492:18;;13546:49:0;19162:354:1;13546:49:0;13613:5;13617:1;13613;:5;:::i;56822:272::-;56936:28;56946:4;56952:2;56956:7;56936:9;:28::i;:::-;56983:48;57006:4;57012:2;57016:7;57025:5;56983:22;:48::i;:::-;56975:111;;;;-1:-1:-1;;;56975:111:0;;;;;;;:::i;45452:723::-;45508:13;45729:10;45725:53;;-1:-1:-1;;45756:10:0;;;;;;;;;;;;-1:-1:-1;;;45756:10:0;;;;;45452:723::o;45725:53::-;45803:5;45788:12;45844:78;45851:9;;45844:78;;45877:8;;;;:::i;:::-;;-1:-1:-1;45900:10:0;;-1:-1:-1;45908:2:0;45900:10;;:::i;:::-;;;45844:78;;;45932:19;45964:6;45954:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45954:17:0;;45932:39;;45982:154;45989:10;;45982:154;;46016:11;46026:1;46016:11;;:::i;:::-;;-1:-1:-1;46085:10:0;46093:2;46085:5;:10;:::i;:::-;46072:24;;:2;:24;:::i;:::-;46059:39;;46042:6;46049;46042:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;46042:56:0;;;;;;;;-1:-1:-1;46113:11:0;46122:2;46113:11;;:::i;:::-;;;45982:154;;43021:151;43105:4;39714:17;;;:12;;;:17;;;;;;:22;;43129:35;39619:125;34177:137;34247:4;34271:35;34279:3;34299:5;34271:7;:35::i;33870:131::-;33937:4;33961:32;33966:3;33986:5;33961:4;:32::i;42444:185::-;42533:4;42557:64;42562:3;42582;-1:-1:-1;;;;;42596:23:0;;42557:4;:64::i;30128:204::-;30223:18;;30195:7;;30223:26;-1:-1:-1;30215:73:0;;;;-1:-1:-1;;;30215:73:0;;20389:2:1;30215:73:0;;;20371:21:1;20428:2;20408:18;;;20401:30;20467:34;20447:18;;;20440:62;-1:-1:-1;;;20518:18:1;;;20511:32;20560:19;;30215:73:0;20187:398:1;30215:73:0;30306:3;:11;;30318:5;30306:18;;;;;;;;:::i;:::-;;;;;;;;;30299:25;;30128:204;;;;:::o;58736:250::-;58832:18;58838:2;58842:7;58832:5;:18::i;:::-;58869:54;58900:1;58904:2;58908:7;58917:5;58869:22;:54::i;:::-;58861:117;;;;-1:-1:-1;;;58861:117:0;;;;;;;:::i;40304:279::-;40408:19;;40371:7;;;;40408:27;-1:-1:-1;40400:74:0;;;;-1:-1:-1;;;40400:74:0;;20792:2:1;40400:74:0;;;20774:21:1;20831:2;20811:18;;;20804:30;20870:34;20850:18;;;20843:62;-1:-1:-1;;;20921:18:1;;;20914:32;20963:19;;40400:74:0;20590:398:1;40400:74:0;40487:22;40512:3;:12;;40525:5;40512:19;;;;;;;;:::i;:::-;;;;;;;;;;;40487:44;;40550:5;:10;;;40562:5;:12;;;40542:33;;;;;40304:279;;;;;:::o;41801:319::-;41895:7;41934:17;;;:12;;;:17;;;;;;41985:12;41970:13;41962:36;;;;-1:-1:-1;;;41962:36:0;;;;;;;;:::i;:::-;-1:-1:-1;42052:3:0;42065:12;42076:1;42065:8;:12;:::i;:::-;42052:26;;;;;;;;:::i;:::-;;;;;;;;;;;:33;;;42045:40;;;41801:319;;;;;:::o;62702:604::-;62823:4;-1:-1:-1;;;;;62850:13:0;;18723:20;62845:60;;-1:-1:-1;62889:4:0;62882:11;;62845:60;62915:23;62941:252;-1:-1:-1;;;687:10:0;63081:4;63100:7;63122:5;62957:181;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;62957:181:0;;;;;;;-1:-1:-1;;;;;62957:181:0;;;;;;;;;;;62941:252;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;62941:15:0;;;:252;:15;:252::i;:::-;62915:278;;63204:13;63231:10;63220:32;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;63271:26:0;-1:-1:-1;;;63271:26:0;;-1:-1:-1;;;62702:604:0;;;;;;:::o;27830:1544::-;27896:4;28035:19;;;:12;;;:19;;;;;;28071:15;;28067:1300;;28433:21;28457:14;28470:1;28457:10;:14;:::i;:::-;28506:18;;28433:38;;-1:-1:-1;28486:17:0;;28506:22;;28527:1;;28506:22;:::i;:::-;28486:42;;28773:17;28793:3;:11;;28805:9;28793:22;;;;;;;;:::i;:::-;;;;;;;;;28773:42;;28939:9;28910:3;:11;;28922:13;28910:26;;;;;;;;:::i;:::-;;;;;;;;;;:38;29042:17;:13;29058:1;29042:17;:::i;:::-;29016:23;;;;:12;;;:23;;;;;:43;29168:17;;29016:3;;29168:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;29263:3;:12;;:19;29276:5;29263:19;;;;;;;;;;;29256:26;;;29306:4;29299:11;;;;;;;;28067:1300;29350:5;29343:12;;;;;27240:414;27303:4;39714:17;;;:12;;;:17;;;;;;27320:327;;-1:-1:-1;27363:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;27546:18;;27524:19;;;:12;;;:19;;;;;;:40;;;;27579:11;;27320:327;-1:-1:-1;27630:5:0;27623:12;;37119:692;37195:4;37330:17;;;:12;;;:17;;;;;;37364:13;37360:444;;-1:-1:-1;;37449:38:0;;;;;;;;;;;;;;;;;;37431:57;;;;;;;;:12;:57;;;;;;;;;;;;;;;;;;;;;;;;37646:19;;37626:17;;;:12;;;:17;;;;;;;:39;37680:11;;37360:444;37760:5;37724:3;37737:12;37748:1;37737:8;:12;:::i;:::-;37724:26;;;;;;;;:::i;:::-;;;;;;;;;;;:33;;:41;;;;37787:5;37780:12;;;;;59322:404;-1:-1:-1;;;;;59402:16:0;;59394:61;;;;-1:-1:-1;;;59394:61:0;;22075:2:1;59394:61:0;;;22057:21:1;;;22094:18;;;22087:30;22153:34;22133:18;;;22126:62;22205:18;;59394:61:0;21873:356:1;59394:61:0;59475:16;59483:7;59475;:16::i;:::-;59474:17;59466:58;;;;-1:-1:-1;;;59466:58:0;;22436:2:1;59466:58:0;;;22418:21:1;22475:2;22455:18;;;22448:30;22514;22494:18;;;22487:58;22562:18;;59466:58:0;22234:352:1;59466:58:0;-1:-1:-1;;;;;59595:17:0;;;;;;:13;:17;;;;;:30;;59617:7;59595:21;:30::i;:::-;-1:-1:-1;59638:29:0;:12;59655:7;59664:2;59638:16;:29::i;:::-;-1:-1:-1;59685:33:0;;59710:7;;-1:-1:-1;;;;;59685:33:0;;;59702:1;;59685:33;;59702:1;;59685:33;59322:404;;:::o;21274:195::-;21377:12;21409:52;21431:6;21439:4;21445:1;21448:12;21377;18723:20;;22570:60;;;;-1:-1:-1;;;22570:60:0;;23200:2:1;22570:60:0;;;23182:21:1;23239:2;23219:18;;;23212:30;23278:31;23258:18;;;23251:59;23327:18;;22570:60:0;22998:353:1;22570:60:0;22704:12;22718:23;22745:6;-1:-1:-1;;;;;22745:11:0;22765:5;22773:4;22745:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22703:75;;;;22796:52;22814:7;22823:10;22835:12;22796:17;:52::i;:::-;22789:59;22326:530;-1:-1:-1;;;;;;;22326:530:0:o;24866:742::-;24981:12;25010:7;25006:595;;;-1:-1:-1;25041:10:0;25034:17;;25006:595;25155:17;;:21;25151:439;;25418:10;25412:17;25479:15;25466:10;25462:2;25458:19;25451:44;25151:439;25561:12;25554:20;;-1:-1:-1;;;25554:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:::-;897:3;935:5;929:12;962:6;957:3;950:19;978:63;1034:6;1027:4;1022:3;1018:14;1011:4;1004:5;1000:16;978:63;:::i;:::-;1095:2;1074:15;-1:-1:-1;;1070:29:1;1061:39;;;;1102:4;1057:50;;855:258;-1:-1:-1;;855:258:1:o;1118:220::-;1267:2;1256:9;1249:21;1230:4;1287:45;1328:2;1317:9;1313:18;1305:6;1287:45;:::i;1343:180::-;1402:6;1455:2;1443:9;1434:7;1430:23;1426:32;1423:52;;;1471:1;1468;1461:12;1423:52;-1:-1:-1;1494:23:1;;1343:180;-1:-1:-1;1343:180:1:o;1736:173::-;1804:20;;-1:-1:-1;;;;;1853:31:1;;1843:42;;1833:70;;1899:1;1896;1889:12;1833:70;1736:173;;;:::o;1914:254::-;1982:6;1990;2043:2;2031:9;2022:7;2018:23;2014:32;2011:52;;;2059:1;2056;2049:12;2011:52;2082:29;2101:9;2082:29;:::i;:::-;2072:39;2158:2;2143:18;;;;2130:32;;-1:-1:-1;;;1914:254:1:o;2173:186::-;2232:6;2285:2;2273:9;2264:7;2260:23;2256:32;2253:52;;;2301:1;2298;2291:12;2253:52;2324:29;2343:9;2324:29;:::i;2546:328::-;2623:6;2631;2639;2692:2;2680:9;2671:7;2667:23;2663:32;2660:52;;;2708:1;2705;2698:12;2660:52;2731:29;2750:9;2731:29;:::i;:::-;2721:39;;2779:38;2813:2;2802:9;2798:18;2779:38;:::i;:::-;2769:48;;2864:2;2853:9;2849:18;2836:32;2826:42;;2546:328;;;;;:::o;2879:160::-;2944:20;;3000:13;;2993:21;2983:32;;2973:60;;3029:1;3026;3019:12;3044:248;3109:6;3117;3170:2;3158:9;3149:7;3145:23;3141:32;3138:52;;;3186:1;3183;3176:12;3138:52;3209:26;3225:9;3209:26;:::i;3297:615::-;3383:6;3391;3444:2;3432:9;3423:7;3419:23;3415:32;3412:52;;;3460:1;3457;3450:12;3412:52;3500:9;3487:23;3529:18;3570:2;3562:6;3559:14;3556:34;;;3586:1;3583;3576:12;3556:34;3624:6;3613:9;3609:22;3599:32;;3669:7;3662:4;3658:2;3654:13;3650:27;3640:55;;3691:1;3688;3681:12;3640:55;3731:2;3718:16;3757:2;3749:6;3746:14;3743:34;;;3773:1;3770;3763:12;3743:34;3826:7;3821:2;3811:6;3808:1;3804:14;3800:2;3796:23;3792:32;3789:45;3786:65;;;3847:1;3844;3837:12;3786:65;3878:2;3870:11;;;;;3900:6;;-1:-1:-1;3297:615:1;;-1:-1:-1;;;;3297:615:1:o;3917:127::-;3978:10;3973:3;3969:20;3966:1;3959:31;4009:4;4006:1;3999:15;4033:4;4030:1;4023:15;4049:632;4114:5;4144:18;4185:2;4177:6;4174:14;4171:40;;;4191:18;;:::i;:::-;4266:2;4260:9;4234:2;4320:15;;-1:-1:-1;;4316:24:1;;;4342:2;4312:33;4308:42;4296:55;;;4366:18;;;4386:22;;;4363:46;4360:72;;;4412:18;;:::i;:::-;4452:10;4448:2;4441:22;4481:6;4472:15;;4511:6;4503;4496:22;4551:3;4542:6;4537:3;4533:16;4530:25;4527:45;;;4568:1;4565;4558:12;4527:45;4618:6;4613:3;4606:4;4598:6;4594:17;4581:44;4673:1;4666:4;4657:6;4649;4645:19;4641:30;4634:41;;;;4049:632;;;;;:::o;4686:451::-;4755:6;4808:2;4796:9;4787:7;4783:23;4779:32;4776:52;;;4824:1;4821;4814:12;4776:52;4864:9;4851:23;4897:18;4889:6;4886:30;4883:50;;;4929:1;4926;4919:12;4883:50;4952:22;;5005:4;4997:13;;4993:27;-1:-1:-1;4983:55:1;;5034:1;5031;5024:12;4983:55;5057:74;5123:7;5118:2;5105:16;5100:2;5096;5092:11;5057:74;:::i;5142:632::-;5313:2;5365:21;;;5435:13;;5338:18;;;5457:22;;;5284:4;;5313:2;5536:15;;;;5510:2;5495:18;;;5284:4;5579:169;5593:6;5590:1;5587:13;5579:169;;;5654:13;;5642:26;;5723:15;;;;5688:12;;;;5615:1;5608:9;5579:169;;;-1:-1:-1;5765:3:1;;5142:632;-1:-1:-1;;;;;;5142:632:1:o;5779:254::-;5844:6;5852;5905:2;5893:9;5884:7;5880:23;5876:32;5873:52;;;5921:1;5918;5911:12;5873:52;5944:29;5963:9;5944:29;:::i;:::-;5934:39;;5992:35;6023:2;6012:9;6008:18;5992:35;:::i;:::-;5982:45;;5779:254;;;;;:::o;6038:667::-;6133:6;6141;6149;6157;6210:3;6198:9;6189:7;6185:23;6181:33;6178:53;;;6227:1;6224;6217:12;6178:53;6250:29;6269:9;6250:29;:::i;:::-;6240:39;;6298:38;6332:2;6321:9;6317:18;6298:38;:::i;:::-;6288:48;;6383:2;6372:9;6368:18;6355:32;6345:42;;6438:2;6427:9;6423:18;6410:32;6465:18;6457:6;6454:30;6451:50;;;6497:1;6494;6487:12;6451:50;6520:22;;6573:4;6565:13;;6561:27;-1:-1:-1;6551:55:1;;6602:1;6599;6592:12;6551:55;6625:74;6691:7;6686:2;6673:16;6668:2;6664;6660:11;6625:74;:::i;:::-;6615:84;;;6038:667;;;;;;;:::o;6710:260::-;6778:6;6786;6839:2;6827:9;6818:7;6814:23;6810:32;6807:52;;;6855:1;6852;6845:12;6807:52;6878:29;6897:9;6878:29;:::i;:::-;6868:39;;6926:38;6960:2;6949:9;6945:18;6926:38;:::i;6975:380::-;7054:1;7050:12;;;;7097;;;7118:61;;7172:4;7164:6;7160:17;7150:27;;7118:61;7225:2;7217:6;7214:14;7194:18;7191:38;7188:161;;;7271:10;7266:3;7262:20;7259:1;7252:31;7306:4;7303:1;7296:15;7334:4;7331:1;7324:15;8600:413;8802:2;8784:21;;;8841:2;8821:18;;;8814:30;8880:34;8875:2;8860:18;;8853:62;-1:-1:-1;;;8946:2:1;8931:18;;8924:47;9003:3;8988:19;;8600:413::o;9018:356::-;9220:2;9202:21;;;9239:18;;;9232:30;9298:34;9293:2;9278:18;;9271:62;9365:2;9350:18;;9018:356::o;9379:341::-;9581:2;9563:21;;;9620:2;9600:18;;;9593:30;-1:-1:-1;;;9654:2:1;9639:18;;9632:47;9711:2;9696:18;;9379:341::o;9725:355::-;9927:2;9909:21;;;9966:2;9946:18;;;9939:30;10005:33;10000:2;9985:18;;9978:61;10071:2;10056:18;;9725:355::o;13030:127::-;13091:10;13086:3;13082:20;13079:1;13072:31;13122:4;13119:1;13112:15;13146:4;13143:1;13136:15;13162:128;13202:3;13233:1;13229:6;13226:1;13223:13;13220:39;;;13239:18;;:::i;:::-;-1:-1:-1;13275:9:1;;13162:128::o;13295:135::-;13334:3;-1:-1:-1;;13355:17:1;;13352:43;;;13375:18;;:::i;:::-;-1:-1:-1;13422:1:1;13411:13;;13295:135::o;13435:127::-;13496:10;13491:3;13487:20;13484:1;13477:31;13527:4;13524:1;13517:15;13551:4;13548:1;13541:15;14748:470;14927:3;14965:6;14959:13;14981:53;15027:6;15022:3;15015:4;15007:6;15003:17;14981:53;:::i;:::-;15097:13;;15056:16;;;;15119:57;15097:13;15056:16;15153:4;15141:17;;15119:57;:::i;:::-;15192:20;;14748:470;-1:-1:-1;;;;14748:470:1:o;18330:168::-;18370:7;18436:1;18432;18428:6;18424:14;18421:1;18418:21;18413:1;18406:9;18399:17;18395:45;18392:71;;;18443:18;;:::i;:::-;-1:-1:-1;18483:9:1;;18330:168::o;18503:127::-;18564:10;18559:3;18555:20;18552:1;18545:31;18595:4;18592:1;18585:15;18619:4;18616:1;18609:15;18635:120;18675:1;18701;18691:35;;18706:18;;:::i;:::-;-1:-1:-1;18740:9:1;;18635:120::o;19521:125::-;19561:4;19589:1;19586;19583:8;19580:34;;;19594:18;;:::i;:::-;-1:-1:-1;19631:9:1;;19521:125::o;19651:414::-;19853:2;19835:21;;;19892:2;19872:18;;;19865:30;19931:34;19926:2;19911:18;;19904:62;-1:-1:-1;;;19997:2:1;19982:18;;19975:48;20055:3;20040:19;;19651:414::o;20070:112::-;20102:1;20128;20118:35;;20133:18;;:::i;:::-;-1:-1:-1;20167:9:1;;20070:112::o;20993:489::-;-1:-1:-1;;;;;21262:15:1;;;21244:34;;21314:15;;21309:2;21294:18;;21287:43;21361:2;21346:18;;21339:34;;;21409:3;21404:2;21389:18;;21382:31;;;21187:4;;21430:46;;21456:19;;21448:6;21430:46;:::i;:::-;21422:54;20993:489;-1:-1:-1;;;;;;20993:489:1:o;21487:249::-;21556:6;21609:2;21597:9;21588:7;21584:23;21580:32;21577:52;;;21625:1;21622;21615:12;21577:52;21657:9;21651:16;21676:30;21700:5;21676:30;:::i;21741:127::-;21802:10;21797:3;21793:20;21790:1;21783:31;21833:4;21830:1;21823:15;21857:4;21854:1;21847:15;23356:274;23485:3;23523:6;23517:13;23539:53;23585:6;23580:3;23573:4;23565:6;23561:17;23539:53;:::i;:::-;23608:16;;;;;23356:274;-1:-1:-1;;23356:274:1:o
Swarm Source
ipfs://e38dad1205bebd25f4398a5be34b38ca1e20c1991faae774ca5afc514131f68c
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.