ETH Price: $3,332.35 (-0.33%)

Token

Project3333 (3333)
 

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

Balance
1 3333
0x4838b0aa50c7f8fa9a14bc95d6c6ba65aa57d861
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
three333

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

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

Contract ABI

[{"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"}]

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.