ETH Price: $3,293.81 (-1.82%)
Gas: 4.54 Gwei

Token

PeachProjectID (TPP)
 

Overview

Max Total Supply

450 TPP

Holders

283

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 TPP
0xea8ad4ff247f944148b676e8eb68e14d76104974
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:
PeachProjectID

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-01-31
*/

// SPDX-License-Identifier: MIT
// File: contracts/interfaces/IOpenSeaCompatible.sol



pragma solidity ^0.8.0;

interface IOpenSeaCompatible {
    /**
     * Get the contract metadata
     */
    function contractURI() external view returns (string memory);

    /**
     * Set the contract metadata
     */
    function setContractURI(string memory contract_uri) external;
}
// File: @openzeppelin/contracts/security/ReentrancyGuard.sol


// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

// File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol


// OpenZeppelin Contracts v4.4.1 (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }
        }
        return computedHash;
    }
}

// File: @openzeppelin/contracts/utils/Strings.sol


// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "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] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

// File: @openzeppelin/contracts/utils/Address.sol


// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)

pragma solidity ^0.8.0;

/**
 * @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;
        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");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, 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;
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 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);
}

// File: contracts/interfaces/IPeachProject.sol


pragma solidity ^0.8.0;


interface IPeachProject is IERC721Enumerable {
    function canMint(uint256 quantity) external view returns (bool);

    function canMintPresale(
        address owner,
        uint256 quantity,
        bytes32[] calldata proof
    ) external view returns (bool);

    function presaleMinted(address owner) external view returns (uint256);

    function purchase(uint256 quantity) external payable;

    function purchasePresale(uint256 quantity, bytes32[] calldata proof) external payable;
}

interface IPeachProjectAdmin {
    function mintToAddress(uint256 quantity, address to) external;

    function mintToAddresses(address[] calldata to) external;

    function setBaseURI(string memory baseURI) external;

    function setBaseURIRevealed(string memory baseURI) external;

    function setPresaleLimit(uint256 limit) external;

    function setPresaleRoot(bytes32 merkleRoot) external;

    function togglePresaleIsActive() external;

    function toggleSaleIsActive() external;

    function withdraw() external;
}

interface IPeachToken {
  function burn(address from, uint256 amount) external;
}

interface ITraits {
  function tokenURI(uint256 tokenId) external view returns (string memory);
}

interface IPeachStakingFactory {
  function addManyPeachToStake(address account, uint16[] calldata tokenIds) external;
}
// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

// File: @openzeppelin/contracts/utils/math/SafeMath.sol


// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
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) {
        unchecked {
            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) {
        unchecked {
            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) {
        unchecked {
            // 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) {
        unchecked {
            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) {
        unchecked {
            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) {
        return a + b;
    }

    /**
     * @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) {
        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) {
        return a * b;
    }

    /**
     * @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.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        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) {
        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) {
        unchecked {
            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.
     *
     * 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) {
        unchecked {
            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) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

// File: @openzeppelin/contracts/token/ERC721/ERC721.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;








/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not 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 {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: 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 _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @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");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits a {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.0;



/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
        return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @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 override {
        super._beforeTokenTransfer(from, to, tokenId);

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev 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 {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: contracts/IDCard-ERC721.sol


// Author: @Harry.XBT
// ID Card NFT for PeachProject

pragma solidity ^0.8.0;










contract PeachProjectID is Ownable, ERC721Enumerable, ReentrancyGuard, IPeachProject, IPeachProjectAdmin, IOpenSeaCompatible {
    using Address for address;
    using Strings for uint256;
    using SafeMath for uint256;

    event PresaleActive(bool state);
    event SaleActive(bool state);
    event PresaleLimitChanged(uint256 limit);

    bool public saleIsActive;
    bool public presaleIsActive;

    uint256 public maxPurchaseQuantity;
    uint256 public maxMintableSupply;
    uint256 public maxAdminSupply;
    uint256 public MAX_TOKENS;
    uint256 public presaleLimit;
    uint256 public baseExtension;
    bytes32 public presaleRoot;
    uint256 public price;

    uint256 private _adminMinted = 0;
    uint256 private _publicMinted = 0;

    string private _contractURI;
    string private _tokenBaseURI;
    string private _tokenRevealedBaseURI;

    address payable public payments;

    mapping(address => uint256) private _presaleClaimedCount;

    constructor(
        string memory name,
        string memory symbol,
        address _payments
    ) ERC721(name, symbol) {

        saleIsActive = false;
        presaleIsActive = false;
        payments = payable(_payments);
        presaleLimit = 2; //Pending

        price = 50000000000000000; //0.05 ETH
        maxPurchaseQuantity = 2; 
        MAX_TOKENS = 450; 
        maxMintableSupply = 400; 
        maxAdminSupply = 50; 

        _contractURI = 'PENDING';
        _tokenBaseURI = 'PENDING';
        _tokenRevealedBaseURI = 'PENDING';
    }

    // IOpenSeaCompatible

    function contractURI() public view override returns (string memory) {
        return _contractURI;
    }

    function setContractURI(string memory contract_uri) external override onlyOwner {
        _contractURI = contract_uri;
    }

    //IPeachProjectMetadata

    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        require(_exists(tokenId), 'Token does not exist');

        string memory revealedBaseURI = _tokenRevealedBaseURI;
        return
            bytes(revealedBaseURI).length > 0
                ? string(abi.encodePacked(revealedBaseURI, tokenId.toString()))
                : _tokenBaseURI;
    }

    // IPeachProject

    function canMint(uint256 quantity) public view override returns (bool) {
        require(saleIsActive, "sale hasn't started");
        require(!presaleIsActive, 'only presale');
        require(totalSupply().add(quantity) <= MAX_TOKENS, 'quantity exceeds supply');
        require(_publicMinted.add(quantity) <= maxMintableSupply, 'quantity exceeds mintable');
        require(quantity <= maxPurchaseQuantity, 'quantity exceeds max');

        return true;
    }

    function canMintPresale(
        address owner,
        uint256 quantity,
        bytes32[] calldata proof
    ) public view override returns (bool) {
        require(!saleIsActive && presaleIsActive, "presale hasn't started");
        require(_verify(_leaf(owner), proof), 'invalid proof');
        require(totalSupply().add(quantity) <= MAX_TOKENS, 'quantity exceeds supply');
        require(_publicMinted.add(quantity) <= maxMintableSupply, 'quantity exceeds mintable');
        require(_presaleClaimedCount[owner].add(quantity) <= presaleLimit, 'quantity exceeds limit');

        return true;
    }

    function presaleMinted(address owner) external view override returns (uint256) {
        require(owner != address(0), 'black hole not allowed');
        return _presaleClaimedCount[owner];
    }

    function purchase(uint256 quantity) external payable override nonReentrant {
        require(canMint(quantity), 'cannot mint');
        require(msg.value >= price.mul(quantity), 'amount too low');

        for (uint256 i = 0; i < quantity; i++) {
            uint256 mintIndex = totalSupply();
            if (totalSupply() < MAX_TOKENS) {
                _publicMinted += 1;
                _safeMint(msg.sender, mintIndex);
            }
        }
    }

    function purchasePresale(uint256 quantity, bytes32[] calldata proof) external payable override nonReentrant {
        require(canMintPresale(msg.sender, quantity, proof), 'cannot mint presale');
        require(msg.value >= price.mul(quantity), 'amount too low');

        for (uint256 i = 0; i < quantity; i++) {
            uint256 mintIndex = totalSupply();
            if (totalSupply() < MAX_TOKENS) {
                _publicMinted += 1;
                _presaleClaimedCount[msg.sender] += 1;
                _safeMint(msg.sender, mintIndex);
            }
        }
    }

    // IPeachProjectAdmin

    function mintToAddress(uint256 quantity, address to) external override onlyOwner {
        require(totalSupply().add(quantity) <= MAX_TOKENS, 'quantity exceeds supply');
        require(_adminMinted.add(quantity) <= maxAdminSupply, 'quantity exceeds mintable');

        for (uint256 i = 0; i < quantity; i++) {
            uint256 mintIndex = totalSupply();
            if (totalSupply() < MAX_TOKENS) {
                _adminMinted += 1;
                _safeMint(to, mintIndex);
            }
        }
    }

    function mintToAddresses(address[] calldata to) external override onlyOwner {
        require(totalSupply().add(to.length) <= MAX_TOKENS, 'quantity exceeds supply');
        require(_adminMinted.add(to.length) <= maxAdminSupply, 'quantity exceeds mintable');

        for (uint256 i = 0; i < to.length; i++) {
            uint256 mintIndex = totalSupply();
            if (totalSupply() < MAX_TOKENS) {
                _adminMinted += 1;
                _safeMint(to[i], mintIndex);
            }
        }
    }

    function setBaseURI(string memory baseURI) external override onlyOwner {
        _tokenBaseURI = baseURI;
    }

    function setBaseURIRevealed(string memory baseURI) external override onlyOwner {
        _tokenRevealedBaseURI = baseURI;
    }

    function setPresaleLimit(uint256 limit) external override onlyOwner {
        presaleLimit = limit;
        emit PresaleLimitChanged(presaleLimit);
    }

    function setPresaleRoot(bytes32 merkleRoot) external override onlyOwner {
        presaleRoot = merkleRoot;
    }

    function togglePresaleIsActive() external override onlyOwner {
        presaleIsActive = !presaleIsActive;
        emit PresaleActive(presaleIsActive);
    }

    function toggleSaleIsActive() external override onlyOwner {
        saleIsActive = !saleIsActive;
        emit SaleActive(saleIsActive);
    }

    function withdraw() public override onlyOwner {
        uint256 balance = address(this).balance;
        payable(msg.sender).transfer(balance);
    }

    function getTokenIds(address _owner) public view returns (uint256[] memory _tokensOfOwner) {
        _tokensOfOwner = new uint256[](balanceOf(_owner));
        for (uint256 i;i<balanceOf(_owner);i++){
            _tokensOfOwner[i] = tokenOfOwnerByIndex(_owner, i);
        }
      }


    // _internal

    function _leaf(address account) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked(account));
    }

    function _verify(bytes32 leaf, bytes32[] memory proof) internal view returns (bool) {
        return MerkleProof.verify(proof, presaleRoot, leaf);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"_payments","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"state","type":"bool"}],"name":"PresaleActive","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"limit","type":"uint256"}],"name":"PresaleLimitChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"state","type":"bool"}],"name":"SaleActive","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"baseExtension","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"canMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"canMintPresale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"getTokenIds","outputs":[{"internalType":"uint256[]","name":"_tokensOfOwner","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":[],"name":"maxAdminSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintableSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPurchaseQuantity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"mintToAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"to","type":"address[]"}],"name":"mintToAddresses","outputs":[],"stateMutability":"nonpayable","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":"payments","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"presaleMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"purchase","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"purchasePresale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","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":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURIRevealed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"contract_uri","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"setPresaleLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"setPresaleRoot","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":[],"name":"togglePresaleIsActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleSaleIsActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052600060155560006016553480156200001b57600080fd5b5060405162003387380380620033878339810160408190526200003e9162000313565b82826200004b3362000166565b815162000060906001906020850190620001b6565b50805162000076906002906020840190620001b6565b50506001600b5550600c805461ffff19169055601a80546001600160a01b0319166001600160a01b0383161790556002601181905566b1a2bc2ec50000601455600d556101c2601055610190600e556032600f556040805180820190915260078082526650454e44494e4760c81b6020909201918252620000fa91601791620001b6565b506040805180820190915260078082526650454e44494e4760c81b60209092019182526200012b91601891620001b6565b506040805180820190915260078082526650454e44494e4760c81b60209092019182526200015c91601991620001b6565b50505050620003f3565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b828054620001c490620003a0565b90600052602060002090601f016020900481019282620001e8576000855562000233565b82601f106200020357805160ff191683800117855562000233565b8280016001018555821562000233579182015b828111156200023357825182559160200191906001019062000216565b506200024192915062000245565b5090565b5b8082111562000241576000815560010162000246565b600082601f8301126200026e57600080fd5b81516001600160401b03808211156200028b576200028b620003dd565b604051601f8301601f19908116603f01168101908282118183101715620002b657620002b6620003dd565b81604052838152602092508683858801011115620002d357600080fd5b600091505b83821015620002f75785820183015181830184015290820190620002d8565b83821115620003095760008385830101525b9695505050505050565b6000806000606084860312156200032957600080fd5b83516001600160401b03808211156200034157600080fd5b6200034f878388016200025c565b945060208601519150808211156200036657600080fd5b5062000375868287016200025c565b604086015190935090506001600160a01b03811681146200039557600080fd5b809150509250925092565b600181811c90821680620003b557607f821691505b60208210811415620003d757634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b612f8480620004036000396000f3fe6080604052600436106102885760003560e01c8063715018a61161015a578063bc660cac116100c1578063e8a3d4851161007a578063e8a3d48514610761578063e985e9c514610776578063eb8d2444146107bf578063efef39a1146107d9578063f2fde38b146107ec578063f47c84c51461080c57600080fd5b8063bc660cac146106a8578063c6682862146106c8578063c87b56dd146106de578063c8dabf64146106fe578063d004b0361461071e578063d61670c91461074b57600080fd5b8063a035b1fe11610113578063a035b1fe146105fd578063a11d122614610613578063a22cb46514610628578063a6d23e1014610648578063b658b60f14610668578063b88d4fde1461068857600080fd5b8063715018a61461055f5780637fd255f11461057457806385449697146105945780638da5cb5b146105aa578063938e3d7b146105c857806395d89b41146105e857600080fd5b80633a8b097d116101fe578063525b3fe3116101b7578063525b3fe3146104b657806355f804b3146104cc5780635dd871a3146104ec5780636352211e1461050c57806370970d561461052c57806370a082311461053f57600080fd5b80633a8b097d1461040c5780633ccfd60b1461042157806342842e0e146104365780634a933d0f146104565780634f6ccce714610476578063512b658d1461049657600080fd5b8063095ea7b311610250578063095ea7b3146103625780630da92d661461038257806318160ddd1461039857806323b872dd146103ad5780632f745c59146103cd57806330f72cd4146103ed57600080fd5b806301ffc9a71461028d57806304a6c8c9146102c257806306fdde03146102e657806306ff396214610308578063081812fc1461032a575b600080fd5b34801561029957600080fd5b506102ad6102a8366004612ab1565b610822565b60405190151581526020015b60405180910390f35b3480156102ce57600080fd5b506102d8600e5481565b6040519081526020016102b9565b3480156102f257600080fd5b506102fb61084d565b6040516102b99190612c7f565b34801561031457600080fd5b50610328610323366004612a56565b6108df565b005b34801561033657600080fd5b5061034a610345366004612a98565b6109ff565b6040516001600160a01b0390911681526020016102b9565b34801561036e57600080fd5b5061032861037d3660046129d2565b610a94565b34801561038e57600080fd5b506102d8600d5481565b3480156103a457600080fd5b506009546102d8565b3480156103b957600080fd5b506103286103c83660046128de565b610ba5565b3480156103d957600080fd5b506102d86103e83660046129d2565b610bd6565b3480156103f957600080fd5b50600c546102ad90610100900460ff1681565b34801561041857600080fd5b50610328610c6c565b34801561042d57600080fd5b50610328610cf8565b34801561044257600080fd5b506103286104513660046128de565b610d55565b34801561046257600080fd5b50610328610471366004612aeb565b610d70565b34801561048257600080fd5b506102d8610491366004612a98565b610dad565b3480156104a257600080fd5b506103286104b1366004612b34565b610e40565b3480156104c257600080fd5b506102d860115481565b3480156104d857600080fd5b506103286104e7366004612aeb565b610f26565b3480156104f857600080fd5b506102ad610507366004612a98565b610f63565b34801561051857600080fd5b5061034a610527366004612a98565b6110a2565b61032861053a366004612b57565b611119565b34801561054b57600080fd5b506102d861055a366004612890565b61129c565b34801561056b57600080fd5b50610328611323565b34801561058057600080fd5b5061032861058f366004612a98565b611359565b3480156105a057600080fd5b506102d860135481565b3480156105b657600080fd5b506000546001600160a01b031661034a565b3480156105d457600080fd5b506103286105e3366004612aeb565b6113be565b3480156105f457600080fd5b506102fb6113fb565b34801561060957600080fd5b506102d860145481565b34801561061f57600080fd5b5061032861140a565b34801561063457600080fd5b50610328610643366004612996565b61147c565b34801561065457600080fd5b50601a5461034a906001600160a01b031681565b34801561067457600080fd5b50610328610683366004612a98565b611487565b34801561069457600080fd5b506103286106a336600461291a565b6114b6565b3480156106b457600080fd5b506102d86106c3366004612890565b6114ee565b3480156106d457600080fd5b506102d860125481565b3480156106ea57600080fd5b506102fb6106f9366004612a98565b61155b565b34801561070a57600080fd5b506102ad6107193660046129fc565b611713565b34801561072a57600080fd5b5061073e610739366004612890565b6118fb565b6040516102b99190612c3b565b34801561075757600080fd5b506102d8600f5481565b34801561076d57600080fd5b506102fb61199c565b34801561078257600080fd5b506102ad6107913660046128ab565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b3480156107cb57600080fd5b50600c546102ad9060ff1681565b6103286107e7366004612a98565b6119ab565b3480156107f857600080fd5b50610328610807366004612890565b611afc565b34801561081857600080fd5b506102d860105481565b60006001600160e01b0319821663780e9d6360e01b1480610847575061084782611b97565b92915050565b60606001805461085c90612e66565b80601f016020809104026020016040519081016040528092919081815260200182805461088890612e66565b80156108d55780601f106108aa576101008083540402835291602001916108d5565b820191906000526020600020905b8154815290600101906020018083116108b857829003601f168201915b5050505050905090565b6000546001600160a01b031633146109125760405162461bcd60e51b815260040161090990612d52565b60405180910390fd5b6010546109288261092260095490565b90611be7565b11156109465760405162461bcd60e51b815260040161090990612c92565b600f546015546109569083611be7565b11156109745760405162461bcd60e51b815260040161090990612d1b565b60005b818110156109fa57600061098a60095490565b905060105461099860095490565b10156109e7576001601560008282546109b19190612dd8565b909155506109e790508484848181106109cc576109cc612f0c565b90506020020160208101906109e19190612890565b82611bf3565b50806109f281612e9b565b915050610977565b505050565b6000818152600360205260408120546001600160a01b0316610a785760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610909565b506000908152600560205260409020546001600160a01b031690565b6000610a9f826110a2565b9050806001600160a01b0316836001600160a01b03161415610b0d5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610909565b336001600160a01b0382161480610b295750610b298133610791565b610b9b5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610909565b6109fa8383611c0d565b610baf3382611c7b565b610bcb5760405162461bcd60e51b815260040161090990612d87565b6109fa838383611d6e565b6000610be18361129c565b8210610c435760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610909565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b6000546001600160a01b03163314610c965760405162461bcd60e51b815260040161090990612d52565b600c805460ff610100808304821615810261ff001990931692909217928390556040517f0c56c7e2f62fe49aadfdce1fa53a6112839d06c4cfb65eee8a68476b34e79ab693610cee9390049091161515815260200190565b60405180910390a1565b6000546001600160a01b03163314610d225760405162461bcd60e51b815260040161090990612d52565b6040514790339082156108fc029083906000818181858888f19350505050158015610d51573d6000803e3d6000fd5b5050565b6109fa838383604051806020016040528060008152506114b6565b6000546001600160a01b03163314610d9a5760405162461bcd60e51b815260040161090990612d52565b8051610d51906019906020840190612719565b6000610db860095490565b8210610e1b5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610909565b60098281548110610e2e57610e2e612f0c565b90600052602060002001549050919050565b6000546001600160a01b03163314610e6a5760405162461bcd60e51b815260040161090990612d52565b601054610e7a8361092260095490565b1115610e985760405162461bcd60e51b815260040161090990612c92565b600f54601554610ea89084611be7565b1115610ec65760405162461bcd60e51b815260040161090990612d1b565b60005b828110156109fa576000610edc60095490565b9050601054610eea60095490565b1015610f1357600160156000828254610f039190612dd8565b90915550610f1390508382611bf3565b5080610f1e81612e9b565b915050610ec9565b6000546001600160a01b03163314610f505760405162461bcd60e51b815260040161090990612d52565b8051610d51906018906020840190612719565b600c5460009060ff16610fae5760405162461bcd60e51b81526020600482015260136024820152721cd85b19481a185cdb89dd081cdd185c9d1959606a1b6044820152606401610909565b600c54610100900460ff1615610ff55760405162461bcd60e51b815260206004820152600c60248201526b6f6e6c792070726573616c6560a01b6044820152606401610909565b6010546110058361092260095490565b11156110235760405162461bcd60e51b815260040161090990612c92565b600e546016546110339084611be7565b11156110515760405162461bcd60e51b815260040161090990612d1b565b600d5482111561109a5760405162461bcd60e51b81526020600482015260146024820152730e2eac2dce8d2e8f240caf0c6cacac8e640dac2f60631b6044820152606401610909565b506001919050565b6000818152600360205260408120546001600160a01b0316806108475760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610909565b6002600b54141561116c5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610909565b6002600b5561117d33848484611713565b6111bf5760405162461bcd60e51b815260206004820152601360248201527263616e6e6f74206d696e742070726573616c6560681b6044820152606401610909565b6014546111cc9084611f19565b34101561120c5760405162461bcd60e51b815260206004820152600e60248201526d616d6f756e7420746f6f206c6f7760901b6044820152606401610909565b60005b8381101561129157600061122260095490565b905060105461123060095490565b101561127e576001601660008282546112499190612dd8565b9091555050336000908152601b6020526040812080546001929061126e908490612dd8565b9091555061127e90503382611bf3565b508061128981612e9b565b91505061120f565b50506001600b555050565b60006001600160a01b0382166113075760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610909565b506001600160a01b031660009081526004602052604090205490565b6000546001600160a01b0316331461134d5760405162461bcd60e51b815260040161090990612d52565b6113576000611f25565b565b6000546001600160a01b031633146113835760405162461bcd60e51b815260040161090990612d52565b60118190556040518181527f50c56e412426ddd9e4d245502be1c96365d7af445d18edc22a9d261cf3936efa9060200160405180910390a150565b6000546001600160a01b031633146113e85760405162461bcd60e51b815260040161090990612d52565b8051610d51906017906020840190612719565b60606002805461085c90612e66565b6000546001600160a01b031633146114345760405162461bcd60e51b815260040161090990612d52565b600c805460ff8082161560ff1990921682179092556040519116151581527fe8a4303c22d8b575a6f175ea4803f56b0a4551ac9e22153304feb0ddfd61435590602001610cee565b610d51338383611f75565b6000546001600160a01b031633146114b15760405162461bcd60e51b815260040161090990612d52565b601355565b6114c03383611c7b565b6114dc5760405162461bcd60e51b815260040161090990612d87565b6114e884848484612044565b50505050565b60006001600160a01b03821661153f5760405162461bcd60e51b8152602060048201526016602482015275189b1858dac81a1bdb19481b9bdd08185b1b1bddd95960521b6044820152606401610909565b506001600160a01b03166000908152601b602052604090205490565b6000818152600360205260409020546060906001600160a01b03166115b95760405162461bcd60e51b8152602060048201526014602482015273151bdad95b88191bd95cc81b9bdd08195e1a5cdd60621b6044820152606401610909565b6000601980546115c890612e66565b80601f01602080910402602001604051908101604052809291908181526020018280546115f490612e66565b80156116415780601f1061161657610100808354040283529160200191611641565b820191906000526020600020905b81548152906001019060200180831161162457829003601f168201915b5050505050905060008151116116e1576018805461165e90612e66565b80601f016020809104026020016040519081016040528092919081815260200182805461168a90612e66565b80156116d75780601f106116ac576101008083540402835291602001916116d7565b820191906000526020600020905b8154815290600101906020018083116116ba57829003601f168201915b505050505061170c565b806116eb84612077565b6040516020016116fc929190612bcf565b6040516020818303038152906040525b9392505050565b600c5460009060ff161580156117305750600c54610100900460ff165b6117755760405162461bcd60e51b81526020600482015260166024820152751c1c995cd85b19481a185cdb89dd081cdd185c9d195960521b6044820152606401610909565b60408051606087901b6bffffffffffffffffffffffff191660208083019190915282516014818403018152603490920190925280519101206117ea9084848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061217592505050565b6118265760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610909565b6010546118368561092260095490565b11156118545760405162461bcd60e51b815260040161090990612c92565b600e546016546118649086611be7565b11156118825760405162461bcd60e51b815260040161090990612d1b565b6011546001600160a01b0386166000908152601b60205260409020546118a89086611be7565b11156118ef5760405162461bcd60e51b81526020600482015260166024820152751c5d585b9d1a5d1e48195e18d959591cc81b1a5b5a5d60521b6044820152606401610909565b5060015b949350505050565b60606119068261129c565b67ffffffffffffffff81111561191e5761191e612f22565b604051908082528060200260200182016040528015611947578160200160208202803683370190505b50905060005b6119568361129c565b811015611996576119678382610bd6565b82828151811061197957611979612f0c565b60209081029190910101528061198e81612e9b565b91505061194d565b50919050565b60606017805461085c90612e66565b6002600b5414156119fe5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610909565b6002600b55611a0c81610f63565b611a465760405162461bcd60e51b815260206004820152600b60248201526a18d85b9b9bdd081b5a5b9d60aa1b6044820152606401610909565b601454611a539082611f19565b341015611a935760405162461bcd60e51b815260206004820152600e60248201526d616d6f756e7420746f6f206c6f7760901b6044820152606401610909565b60005b81811015611af3576000611aa960095490565b9050601054611ab760095490565b1015611ae057600160166000828254611ad09190612dd8565b90915550611ae090503382611bf3565b5080611aeb81612e9b565b915050611a96565b50506001600b55565b6000546001600160a01b03163314611b265760405162461bcd60e51b815260040161090990612d52565b6001600160a01b038116611b8b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610909565b611b9481611f25565b50565b60006001600160e01b031982166380ac58cd60e01b1480611bc857506001600160e01b03198216635b5e139f60e01b145b8061084757506301ffc9a760e01b6001600160e01b0319831614610847565b600061170c8284612dd8565b610d51828260405180602001604052806000815250612184565b600081815260056020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611c42826110a2565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600360205260408120546001600160a01b0316611cf45760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610909565b6000611cff836110a2565b9050806001600160a01b0316846001600160a01b03161480611d3a5750836001600160a01b0316611d2f846109ff565b6001600160a01b0316145b806118f357506001600160a01b0380821660009081526006602090815260408083209388168352929052205460ff166118f3565b826001600160a01b0316611d81826110a2565b6001600160a01b031614611de95760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610909565b6001600160a01b038216611e4b5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610909565b611e568383836121b7565b611e61600082611c0d565b6001600160a01b0383166000908152600460205260408120805460019290611e8a908490612e23565b90915550506001600160a01b0382166000908152600460205260408120805460019290611eb8908490612dd8565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061170c8284612e04565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b816001600160a01b0316836001600160a01b03161415611fd75760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610909565b6001600160a01b03838116600081815260066020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61204f848484611d6e565b61205b8484848461226f565b6114e85760405162461bcd60e51b815260040161090990612cc9565b60608161209b5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156120c557806120af81612e9b565b91506120be9050600a83612df0565b915061209f565b60008167ffffffffffffffff8111156120e0576120e0612f22565b6040519080825280601f01601f19166020018201604052801561210a576020820181803683370190505b5090505b84156118f35761211f600183612e23565b915061212c600a86612eb6565b612137906030612dd8565b60f81b81838151811061214c5761214c612f0c565b60200101906001600160f81b031916908160001a90535061216e600a86612df0565b945061210e565b600061170c8260135485612379565b61218e838361238f565b61219b600084848461226f565b6109fa5760405162461bcd60e51b815260040161090990612cc9565b6001600160a01b0383166122125761220d81600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b612235565b816001600160a01b0316836001600160a01b0316146122355761223583826124dd565b6001600160a01b03821661224c576109fa8161257a565b826001600160a01b0316826001600160a01b0316146109fa576109fa8282612629565b60006001600160a01b0384163b1561237157604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906122b3903390899088908890600401612bfe565b602060405180830381600087803b1580156122cd57600080fd5b505af19250505080156122fd575060408051601f3d908101601f191682019092526122fa91810190612ace565b60015b612357573d80801561232b576040519150601f19603f3d011682016040523d82523d6000602084013e612330565b606091505b50805161234f5760405162461bcd60e51b815260040161090990612cc9565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506118f3565b5060016118f3565b600082612386858461266d565b14949350505050565b6001600160a01b0382166123e55760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610909565b6000818152600360205260409020546001600160a01b03161561244a5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610909565b612456600083836121b7565b6001600160a01b038216600090815260046020526040812080546001929061247f908490612dd8565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600060016124ea8461129c565b6124f49190612e23565b600083815260086020526040902054909150808214612547576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b60095460009061258c90600190612e23565b6000838152600a6020526040812054600980549394509092849081106125b4576125b4612f0c565b9060005260206000200154905080600983815481106125d5576125d5612f0c565b6000918252602080832090910192909255828152600a9091526040808220849055858252812055600980548061260d5761260d612ef6565b6001900381819060005260206000200160009055905550505050565b60006126348361129c565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b600081815b845181101561271157600085828151811061268f5761268f612f0c565b602002602001015190508083116126d15760408051602081018590529081018290526060016040516020818303038152906040528051906020012092506126fe565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b508061270981612e9b565b915050612672565b509392505050565b82805461272590612e66565b90600052602060002090601f016020900481019282612747576000855561278d565b82601f1061276057805160ff191683800117855561278d565b8280016001018555821561278d579182015b8281111561278d578251825591602001919060010190612772565b5061279992915061279d565b5090565b5b80821115612799576000815560010161279e565b600067ffffffffffffffff808411156127cd576127cd612f22565b604051601f8501601f19908116603f011681019082821181831017156127f5576127f5612f22565b8160405280935085815286868601111561280e57600080fd5b858560208301376000602087830101525050509392505050565b80356001600160a01b038116811461283f57600080fd5b919050565b60008083601f84011261285657600080fd5b50813567ffffffffffffffff81111561286e57600080fd5b6020830191508360208260051b850101111561288957600080fd5b9250929050565b6000602082840312156128a257600080fd5b61170c82612828565b600080604083850312156128be57600080fd5b6128c783612828565b91506128d560208401612828565b90509250929050565b6000806000606084860312156128f357600080fd5b6128fc84612828565b925061290a60208501612828565b9150604084013590509250925092565b6000806000806080858703121561293057600080fd5b61293985612828565b935061294760208601612828565b925060408501359150606085013567ffffffffffffffff81111561296a57600080fd5b8501601f8101871361297b57600080fd5b61298a878235602084016127b2565b91505092959194509250565b600080604083850312156129a957600080fd5b6129b283612828565b9150602083013580151581146129c757600080fd5b809150509250929050565b600080604083850312156129e557600080fd5b6129ee83612828565b946020939093013593505050565b60008060008060608587031215612a1257600080fd5b612a1b85612828565b935060208501359250604085013567ffffffffffffffff811115612a3e57600080fd5b612a4a87828801612844565b95989497509550505050565b60008060208385031215612a6957600080fd5b823567ffffffffffffffff811115612a8057600080fd5b612a8c85828601612844565b90969095509350505050565b600060208284031215612aaa57600080fd5b5035919050565b600060208284031215612ac357600080fd5b813561170c81612f38565b600060208284031215612ae057600080fd5b815161170c81612f38565b600060208284031215612afd57600080fd5b813567ffffffffffffffff811115612b1457600080fd5b8201601f81018413612b2557600080fd5b6118f3848235602084016127b2565b60008060408385031215612b4757600080fd5b823591506128d560208401612828565b600080600060408486031215612b6c57600080fd5b83359250602084013567ffffffffffffffff811115612b8a57600080fd5b612b9686828701612844565b9497909650939450505050565b60008151808452612bbb816020860160208601612e3a565b601f01601f19169290920160200192915050565b60008351612be1818460208801612e3a565b835190830190612bf5818360208801612e3a565b01949350505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612c3190830184612ba3565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612c7357835183529284019291840191600101612c57565b50909695505050505050565b60208152600061170c6020830184612ba3565b60208082526017908201527f7175616e74697479206578636565647320737570706c79000000000000000000604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526019908201527f7175616e746974792065786365656473206d696e7461626c6500000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60008219821115612deb57612deb612eca565b500190565b600082612dff57612dff612ee0565b500490565b6000816000190483118215151615612e1e57612e1e612eca565b500290565b600082821015612e3557612e35612eca565b500390565b60005b83811015612e55578181015183820152602001612e3d565b838111156114e85750506000910152565b600181811c90821680612e7a57607f821691505b6020821081141561199657634e487b7160e01b600052602260045260246000fd5b6000600019821415612eaf57612eaf612eca565b5060010190565b600082612ec557612ec5612ee0565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114611b9457600080fdfea2646970667358221220db0d3a85fd3669c88da319fe831f4f4644943d8cf84784060d307080ffceb05264736f6c63430008070033000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000005c9fdd22a1ce576cf43dcd8b415fdd0745cfb5cf000000000000000000000000000000000000000000000000000000000000000e506561636850726f6a656374494400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035450500000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106102885760003560e01c8063715018a61161015a578063bc660cac116100c1578063e8a3d4851161007a578063e8a3d48514610761578063e985e9c514610776578063eb8d2444146107bf578063efef39a1146107d9578063f2fde38b146107ec578063f47c84c51461080c57600080fd5b8063bc660cac146106a8578063c6682862146106c8578063c87b56dd146106de578063c8dabf64146106fe578063d004b0361461071e578063d61670c91461074b57600080fd5b8063a035b1fe11610113578063a035b1fe146105fd578063a11d122614610613578063a22cb46514610628578063a6d23e1014610648578063b658b60f14610668578063b88d4fde1461068857600080fd5b8063715018a61461055f5780637fd255f11461057457806385449697146105945780638da5cb5b146105aa578063938e3d7b146105c857806395d89b41146105e857600080fd5b80633a8b097d116101fe578063525b3fe3116101b7578063525b3fe3146104b657806355f804b3146104cc5780635dd871a3146104ec5780636352211e1461050c57806370970d561461052c57806370a082311461053f57600080fd5b80633a8b097d1461040c5780633ccfd60b1461042157806342842e0e146104365780634a933d0f146104565780634f6ccce714610476578063512b658d1461049657600080fd5b8063095ea7b311610250578063095ea7b3146103625780630da92d661461038257806318160ddd1461039857806323b872dd146103ad5780632f745c59146103cd57806330f72cd4146103ed57600080fd5b806301ffc9a71461028d57806304a6c8c9146102c257806306fdde03146102e657806306ff396214610308578063081812fc1461032a575b600080fd5b34801561029957600080fd5b506102ad6102a8366004612ab1565b610822565b60405190151581526020015b60405180910390f35b3480156102ce57600080fd5b506102d8600e5481565b6040519081526020016102b9565b3480156102f257600080fd5b506102fb61084d565b6040516102b99190612c7f565b34801561031457600080fd5b50610328610323366004612a56565b6108df565b005b34801561033657600080fd5b5061034a610345366004612a98565b6109ff565b6040516001600160a01b0390911681526020016102b9565b34801561036e57600080fd5b5061032861037d3660046129d2565b610a94565b34801561038e57600080fd5b506102d8600d5481565b3480156103a457600080fd5b506009546102d8565b3480156103b957600080fd5b506103286103c83660046128de565b610ba5565b3480156103d957600080fd5b506102d86103e83660046129d2565b610bd6565b3480156103f957600080fd5b50600c546102ad90610100900460ff1681565b34801561041857600080fd5b50610328610c6c565b34801561042d57600080fd5b50610328610cf8565b34801561044257600080fd5b506103286104513660046128de565b610d55565b34801561046257600080fd5b50610328610471366004612aeb565b610d70565b34801561048257600080fd5b506102d8610491366004612a98565b610dad565b3480156104a257600080fd5b506103286104b1366004612b34565b610e40565b3480156104c257600080fd5b506102d860115481565b3480156104d857600080fd5b506103286104e7366004612aeb565b610f26565b3480156104f857600080fd5b506102ad610507366004612a98565b610f63565b34801561051857600080fd5b5061034a610527366004612a98565b6110a2565b61032861053a366004612b57565b611119565b34801561054b57600080fd5b506102d861055a366004612890565b61129c565b34801561056b57600080fd5b50610328611323565b34801561058057600080fd5b5061032861058f366004612a98565b611359565b3480156105a057600080fd5b506102d860135481565b3480156105b657600080fd5b506000546001600160a01b031661034a565b3480156105d457600080fd5b506103286105e3366004612aeb565b6113be565b3480156105f457600080fd5b506102fb6113fb565b34801561060957600080fd5b506102d860145481565b34801561061f57600080fd5b5061032861140a565b34801561063457600080fd5b50610328610643366004612996565b61147c565b34801561065457600080fd5b50601a5461034a906001600160a01b031681565b34801561067457600080fd5b50610328610683366004612a98565b611487565b34801561069457600080fd5b506103286106a336600461291a565b6114b6565b3480156106b457600080fd5b506102d86106c3366004612890565b6114ee565b3480156106d457600080fd5b506102d860125481565b3480156106ea57600080fd5b506102fb6106f9366004612a98565b61155b565b34801561070a57600080fd5b506102ad6107193660046129fc565b611713565b34801561072a57600080fd5b5061073e610739366004612890565b6118fb565b6040516102b99190612c3b565b34801561075757600080fd5b506102d8600f5481565b34801561076d57600080fd5b506102fb61199c565b34801561078257600080fd5b506102ad6107913660046128ab565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b3480156107cb57600080fd5b50600c546102ad9060ff1681565b6103286107e7366004612a98565b6119ab565b3480156107f857600080fd5b50610328610807366004612890565b611afc565b34801561081857600080fd5b506102d860105481565b60006001600160e01b0319821663780e9d6360e01b1480610847575061084782611b97565b92915050565b60606001805461085c90612e66565b80601f016020809104026020016040519081016040528092919081815260200182805461088890612e66565b80156108d55780601f106108aa576101008083540402835291602001916108d5565b820191906000526020600020905b8154815290600101906020018083116108b857829003601f168201915b5050505050905090565b6000546001600160a01b031633146109125760405162461bcd60e51b815260040161090990612d52565b60405180910390fd5b6010546109288261092260095490565b90611be7565b11156109465760405162461bcd60e51b815260040161090990612c92565b600f546015546109569083611be7565b11156109745760405162461bcd60e51b815260040161090990612d1b565b60005b818110156109fa57600061098a60095490565b905060105461099860095490565b10156109e7576001601560008282546109b19190612dd8565b909155506109e790508484848181106109cc576109cc612f0c565b90506020020160208101906109e19190612890565b82611bf3565b50806109f281612e9b565b915050610977565b505050565b6000818152600360205260408120546001600160a01b0316610a785760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610909565b506000908152600560205260409020546001600160a01b031690565b6000610a9f826110a2565b9050806001600160a01b0316836001600160a01b03161415610b0d5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610909565b336001600160a01b0382161480610b295750610b298133610791565b610b9b5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610909565b6109fa8383611c0d565b610baf3382611c7b565b610bcb5760405162461bcd60e51b815260040161090990612d87565b6109fa838383611d6e565b6000610be18361129c565b8210610c435760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610909565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b6000546001600160a01b03163314610c965760405162461bcd60e51b815260040161090990612d52565b600c805460ff610100808304821615810261ff001990931692909217928390556040517f0c56c7e2f62fe49aadfdce1fa53a6112839d06c4cfb65eee8a68476b34e79ab693610cee9390049091161515815260200190565b60405180910390a1565b6000546001600160a01b03163314610d225760405162461bcd60e51b815260040161090990612d52565b6040514790339082156108fc029083906000818181858888f19350505050158015610d51573d6000803e3d6000fd5b5050565b6109fa838383604051806020016040528060008152506114b6565b6000546001600160a01b03163314610d9a5760405162461bcd60e51b815260040161090990612d52565b8051610d51906019906020840190612719565b6000610db860095490565b8210610e1b5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610909565b60098281548110610e2e57610e2e612f0c565b90600052602060002001549050919050565b6000546001600160a01b03163314610e6a5760405162461bcd60e51b815260040161090990612d52565b601054610e7a8361092260095490565b1115610e985760405162461bcd60e51b815260040161090990612c92565b600f54601554610ea89084611be7565b1115610ec65760405162461bcd60e51b815260040161090990612d1b565b60005b828110156109fa576000610edc60095490565b9050601054610eea60095490565b1015610f1357600160156000828254610f039190612dd8565b90915550610f1390508382611bf3565b5080610f1e81612e9b565b915050610ec9565b6000546001600160a01b03163314610f505760405162461bcd60e51b815260040161090990612d52565b8051610d51906018906020840190612719565b600c5460009060ff16610fae5760405162461bcd60e51b81526020600482015260136024820152721cd85b19481a185cdb89dd081cdd185c9d1959606a1b6044820152606401610909565b600c54610100900460ff1615610ff55760405162461bcd60e51b815260206004820152600c60248201526b6f6e6c792070726573616c6560a01b6044820152606401610909565b6010546110058361092260095490565b11156110235760405162461bcd60e51b815260040161090990612c92565b600e546016546110339084611be7565b11156110515760405162461bcd60e51b815260040161090990612d1b565b600d5482111561109a5760405162461bcd60e51b81526020600482015260146024820152730e2eac2dce8d2e8f240caf0c6cacac8e640dac2f60631b6044820152606401610909565b506001919050565b6000818152600360205260408120546001600160a01b0316806108475760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610909565b6002600b54141561116c5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610909565b6002600b5561117d33848484611713565b6111bf5760405162461bcd60e51b815260206004820152601360248201527263616e6e6f74206d696e742070726573616c6560681b6044820152606401610909565b6014546111cc9084611f19565b34101561120c5760405162461bcd60e51b815260206004820152600e60248201526d616d6f756e7420746f6f206c6f7760901b6044820152606401610909565b60005b8381101561129157600061122260095490565b905060105461123060095490565b101561127e576001601660008282546112499190612dd8565b9091555050336000908152601b6020526040812080546001929061126e908490612dd8565b9091555061127e90503382611bf3565b508061128981612e9b565b91505061120f565b50506001600b555050565b60006001600160a01b0382166113075760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610909565b506001600160a01b031660009081526004602052604090205490565b6000546001600160a01b0316331461134d5760405162461bcd60e51b815260040161090990612d52565b6113576000611f25565b565b6000546001600160a01b031633146113835760405162461bcd60e51b815260040161090990612d52565b60118190556040518181527f50c56e412426ddd9e4d245502be1c96365d7af445d18edc22a9d261cf3936efa9060200160405180910390a150565b6000546001600160a01b031633146113e85760405162461bcd60e51b815260040161090990612d52565b8051610d51906017906020840190612719565b60606002805461085c90612e66565b6000546001600160a01b031633146114345760405162461bcd60e51b815260040161090990612d52565b600c805460ff8082161560ff1990921682179092556040519116151581527fe8a4303c22d8b575a6f175ea4803f56b0a4551ac9e22153304feb0ddfd61435590602001610cee565b610d51338383611f75565b6000546001600160a01b031633146114b15760405162461bcd60e51b815260040161090990612d52565b601355565b6114c03383611c7b565b6114dc5760405162461bcd60e51b815260040161090990612d87565b6114e884848484612044565b50505050565b60006001600160a01b03821661153f5760405162461bcd60e51b8152602060048201526016602482015275189b1858dac81a1bdb19481b9bdd08185b1b1bddd95960521b6044820152606401610909565b506001600160a01b03166000908152601b602052604090205490565b6000818152600360205260409020546060906001600160a01b03166115b95760405162461bcd60e51b8152602060048201526014602482015273151bdad95b88191bd95cc81b9bdd08195e1a5cdd60621b6044820152606401610909565b6000601980546115c890612e66565b80601f01602080910402602001604051908101604052809291908181526020018280546115f490612e66565b80156116415780601f1061161657610100808354040283529160200191611641565b820191906000526020600020905b81548152906001019060200180831161162457829003601f168201915b5050505050905060008151116116e1576018805461165e90612e66565b80601f016020809104026020016040519081016040528092919081815260200182805461168a90612e66565b80156116d75780601f106116ac576101008083540402835291602001916116d7565b820191906000526020600020905b8154815290600101906020018083116116ba57829003601f168201915b505050505061170c565b806116eb84612077565b6040516020016116fc929190612bcf565b6040516020818303038152906040525b9392505050565b600c5460009060ff161580156117305750600c54610100900460ff165b6117755760405162461bcd60e51b81526020600482015260166024820152751c1c995cd85b19481a185cdb89dd081cdd185c9d195960521b6044820152606401610909565b60408051606087901b6bffffffffffffffffffffffff191660208083019190915282516014818403018152603490920190925280519101206117ea9084848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061217592505050565b6118265760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610909565b6010546118368561092260095490565b11156118545760405162461bcd60e51b815260040161090990612c92565b600e546016546118649086611be7565b11156118825760405162461bcd60e51b815260040161090990612d1b565b6011546001600160a01b0386166000908152601b60205260409020546118a89086611be7565b11156118ef5760405162461bcd60e51b81526020600482015260166024820152751c5d585b9d1a5d1e48195e18d959591cc81b1a5b5a5d60521b6044820152606401610909565b5060015b949350505050565b60606119068261129c565b67ffffffffffffffff81111561191e5761191e612f22565b604051908082528060200260200182016040528015611947578160200160208202803683370190505b50905060005b6119568361129c565b811015611996576119678382610bd6565b82828151811061197957611979612f0c565b60209081029190910101528061198e81612e9b565b91505061194d565b50919050565b60606017805461085c90612e66565b6002600b5414156119fe5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610909565b6002600b55611a0c81610f63565b611a465760405162461bcd60e51b815260206004820152600b60248201526a18d85b9b9bdd081b5a5b9d60aa1b6044820152606401610909565b601454611a539082611f19565b341015611a935760405162461bcd60e51b815260206004820152600e60248201526d616d6f756e7420746f6f206c6f7760901b6044820152606401610909565b60005b81811015611af3576000611aa960095490565b9050601054611ab760095490565b1015611ae057600160166000828254611ad09190612dd8565b90915550611ae090503382611bf3565b5080611aeb81612e9b565b915050611a96565b50506001600b55565b6000546001600160a01b03163314611b265760405162461bcd60e51b815260040161090990612d52565b6001600160a01b038116611b8b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610909565b611b9481611f25565b50565b60006001600160e01b031982166380ac58cd60e01b1480611bc857506001600160e01b03198216635b5e139f60e01b145b8061084757506301ffc9a760e01b6001600160e01b0319831614610847565b600061170c8284612dd8565b610d51828260405180602001604052806000815250612184565b600081815260056020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611c42826110a2565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600360205260408120546001600160a01b0316611cf45760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610909565b6000611cff836110a2565b9050806001600160a01b0316846001600160a01b03161480611d3a5750836001600160a01b0316611d2f846109ff565b6001600160a01b0316145b806118f357506001600160a01b0380821660009081526006602090815260408083209388168352929052205460ff166118f3565b826001600160a01b0316611d81826110a2565b6001600160a01b031614611de95760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610909565b6001600160a01b038216611e4b5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610909565b611e568383836121b7565b611e61600082611c0d565b6001600160a01b0383166000908152600460205260408120805460019290611e8a908490612e23565b90915550506001600160a01b0382166000908152600460205260408120805460019290611eb8908490612dd8565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061170c8284612e04565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b816001600160a01b0316836001600160a01b03161415611fd75760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610909565b6001600160a01b03838116600081815260066020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61204f848484611d6e565b61205b8484848461226f565b6114e85760405162461bcd60e51b815260040161090990612cc9565b60608161209b5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156120c557806120af81612e9b565b91506120be9050600a83612df0565b915061209f565b60008167ffffffffffffffff8111156120e0576120e0612f22565b6040519080825280601f01601f19166020018201604052801561210a576020820181803683370190505b5090505b84156118f35761211f600183612e23565b915061212c600a86612eb6565b612137906030612dd8565b60f81b81838151811061214c5761214c612f0c565b60200101906001600160f81b031916908160001a90535061216e600a86612df0565b945061210e565b600061170c8260135485612379565b61218e838361238f565b61219b600084848461226f565b6109fa5760405162461bcd60e51b815260040161090990612cc9565b6001600160a01b0383166122125761220d81600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b612235565b816001600160a01b0316836001600160a01b0316146122355761223583826124dd565b6001600160a01b03821661224c576109fa8161257a565b826001600160a01b0316826001600160a01b0316146109fa576109fa8282612629565b60006001600160a01b0384163b1561237157604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906122b3903390899088908890600401612bfe565b602060405180830381600087803b1580156122cd57600080fd5b505af19250505080156122fd575060408051601f3d908101601f191682019092526122fa91810190612ace565b60015b612357573d80801561232b576040519150601f19603f3d011682016040523d82523d6000602084013e612330565b606091505b50805161234f5760405162461bcd60e51b815260040161090990612cc9565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506118f3565b5060016118f3565b600082612386858461266d565b14949350505050565b6001600160a01b0382166123e55760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610909565b6000818152600360205260409020546001600160a01b03161561244a5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610909565b612456600083836121b7565b6001600160a01b038216600090815260046020526040812080546001929061247f908490612dd8565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600060016124ea8461129c565b6124f49190612e23565b600083815260086020526040902054909150808214612547576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b60095460009061258c90600190612e23565b6000838152600a6020526040812054600980549394509092849081106125b4576125b4612f0c565b9060005260206000200154905080600983815481106125d5576125d5612f0c565b6000918252602080832090910192909255828152600a9091526040808220849055858252812055600980548061260d5761260d612ef6565b6001900381819060005260206000200160009055905550505050565b60006126348361129c565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b600081815b845181101561271157600085828151811061268f5761268f612f0c565b602002602001015190508083116126d15760408051602081018590529081018290526060016040516020818303038152906040528051906020012092506126fe565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b508061270981612e9b565b915050612672565b509392505050565b82805461272590612e66565b90600052602060002090601f016020900481019282612747576000855561278d565b82601f1061276057805160ff191683800117855561278d565b8280016001018555821561278d579182015b8281111561278d578251825591602001919060010190612772565b5061279992915061279d565b5090565b5b80821115612799576000815560010161279e565b600067ffffffffffffffff808411156127cd576127cd612f22565b604051601f8501601f19908116603f011681019082821181831017156127f5576127f5612f22565b8160405280935085815286868601111561280e57600080fd5b858560208301376000602087830101525050509392505050565b80356001600160a01b038116811461283f57600080fd5b919050565b60008083601f84011261285657600080fd5b50813567ffffffffffffffff81111561286e57600080fd5b6020830191508360208260051b850101111561288957600080fd5b9250929050565b6000602082840312156128a257600080fd5b61170c82612828565b600080604083850312156128be57600080fd5b6128c783612828565b91506128d560208401612828565b90509250929050565b6000806000606084860312156128f357600080fd5b6128fc84612828565b925061290a60208501612828565b9150604084013590509250925092565b6000806000806080858703121561293057600080fd5b61293985612828565b935061294760208601612828565b925060408501359150606085013567ffffffffffffffff81111561296a57600080fd5b8501601f8101871361297b57600080fd5b61298a878235602084016127b2565b91505092959194509250565b600080604083850312156129a957600080fd5b6129b283612828565b9150602083013580151581146129c757600080fd5b809150509250929050565b600080604083850312156129e557600080fd5b6129ee83612828565b946020939093013593505050565b60008060008060608587031215612a1257600080fd5b612a1b85612828565b935060208501359250604085013567ffffffffffffffff811115612a3e57600080fd5b612a4a87828801612844565b95989497509550505050565b60008060208385031215612a6957600080fd5b823567ffffffffffffffff811115612a8057600080fd5b612a8c85828601612844565b90969095509350505050565b600060208284031215612aaa57600080fd5b5035919050565b600060208284031215612ac357600080fd5b813561170c81612f38565b600060208284031215612ae057600080fd5b815161170c81612f38565b600060208284031215612afd57600080fd5b813567ffffffffffffffff811115612b1457600080fd5b8201601f81018413612b2557600080fd5b6118f3848235602084016127b2565b60008060408385031215612b4757600080fd5b823591506128d560208401612828565b600080600060408486031215612b6c57600080fd5b83359250602084013567ffffffffffffffff811115612b8a57600080fd5b612b9686828701612844565b9497909650939450505050565b60008151808452612bbb816020860160208601612e3a565b601f01601f19169290920160200192915050565b60008351612be1818460208801612e3a565b835190830190612bf5818360208801612e3a565b01949350505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612c3190830184612ba3565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612c7357835183529284019291840191600101612c57565b50909695505050505050565b60208152600061170c6020830184612ba3565b60208082526017908201527f7175616e74697479206578636565647320737570706c79000000000000000000604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526019908201527f7175616e746974792065786365656473206d696e7461626c6500000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60008219821115612deb57612deb612eca565b500190565b600082612dff57612dff612ee0565b500490565b6000816000190483118215151615612e1e57612e1e612eca565b500290565b600082821015612e3557612e35612eca565b500390565b60005b83811015612e55578181015183820152602001612e3d565b838111156114e85750506000910152565b600181811c90821680612e7a57607f821691505b6020821081141561199657634e487b7160e01b600052602260045260246000fd5b6000600019821415612eaf57612eaf612eca565b5060010190565b600082612ec557612ec5612ee0565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114611b9457600080fdfea2646970667358221220db0d3a85fd3669c88da319fe831f4f4644943d8cf84784060d307080ffceb05264736f6c63430008070033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000005c9fdd22a1ce576cf43dcd8b415fdd0745cfb5cf000000000000000000000000000000000000000000000000000000000000000e506561636850726f6a656374494400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035450500000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name (string): PeachProjectID
Arg [1] : symbol (string): TPP
Arg [2] : _payments (address): 0x5C9fDd22A1ce576CF43DCD8b415fDD0745cFB5cf

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 0000000000000000000000005c9fdd22a1ce576cf43dcd8b415fdd0745cfb5cf
Arg [3] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [4] : 506561636850726f6a6563744944000000000000000000000000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [6] : 5450500000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

58364:7416:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49541:224;;;;;;;;;;-1:-1:-1;49541:224:0;;;;;:::i;:::-;;:::i;:::-;;;9345:14:1;;9338:22;9320:41;;9308:2;9293:18;49541:224:0;;;;;;;;58825:32;;;;;;;;;;;;;;;;;;;9518:25:1;;;9506:2;9491:18;58825:32:0;9372:177:1;37035:100:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;63615:523::-;;;;;;;;;;-1:-1:-1;63615:523:0;;;;;:::i;:::-;;:::i;:::-;;38594:221;;;;;;;;;;-1:-1:-1;38594:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;7782:32:1;;;7764:51;;7752:2;7737:18;38594:221:0;7618:203:1;38117:411:0;;;;;;;;;;-1:-1:-1;38117:411:0;;;;;:::i;:::-;;:::i;58784:34::-;;;;;;;;;;;;;;;;50181:113;;;;;;;;;;-1:-1:-1;50269:10:0;:17;50181:113;;39344:339;;;;;;;;;;-1:-1:-1;39344:339:0;;;;;:::i;:::-;;:::i;49849:256::-;;;;;;;;;;-1:-1:-1;49849:256:0;;;;;:::i;:::-;;:::i;58748:27::-;;;;;;;;;;-1:-1:-1;58748:27:0;;;;;;;;;;;64691:160;;;;;;;;;;;;;:::i;65012:152::-;;;;;;;;;;;;;:::i;39754:185::-;;;;;;;;;;-1:-1:-1;39754:185:0;;;;;:::i;:::-;;:::i;64267:129::-;;;;;;;;;;-1:-1:-1;64267:129:0;;;;;:::i;:::-;;:::i;50371:233::-;;;;;;;;;;-1:-1:-1;50371:233:0;;;;;:::i;:::-;;:::i;63085:522::-;;;;;;;;;;-1:-1:-1;63085:522:0;;;;;:::i;:::-;;:::i;58932:27::-;;;;;;;;;;;;;;;;64146:113;;;;;;;;;;-1:-1:-1;64146:113:0;;;;;:::i;:::-;;:::i;60678:470::-;;;;;;;;;;-1:-1:-1;60678:470:0;;;;;:::i;:::-;;:::i;36729:239::-;;;;;;;;;;-1:-1:-1;36729:239:0;;;;;:::i;:::-;;:::i;62459:589::-;;;;;;:::i;:::-;;:::i;36459:208::-;;;;;;;;;;-1:-1:-1;36459:208:0;;;;;:::i;:::-;;:::i;57402:103::-;;;;;;;;;;;;;:::i;64404:156::-;;;;;;;;;;-1:-1:-1;64404:156:0;;;;;:::i;:::-;;:::i;59001:26::-;;;;;;;;;;;;;;;;56751:87;;;;;;;;;;-1:-1:-1;56797:7:0;56824:6;-1:-1:-1;;;;;56824:6:0;56751:87;;60089:126;;;;;;;;;;-1:-1:-1;60089:126:0;;;;;:::i;:::-;;:::i;37204:104::-;;;;;;;;;;;;;:::i;59034:20::-;;;;;;;;;;;;;;;;64859:145;;;;;;;;;;;;;:::i;38887:155::-;;;;;;;;;;-1:-1:-1;38887:155:0;;;;;:::i;:::-;;:::i;59258:31::-;;;;;;;;;;-1:-1:-1;59258:31:0;;;;-1:-1:-1;;;;;59258:31:0;;;64568:115;;;;;;;;;;-1:-1:-1;64568:115:0;;;;;:::i;:::-;;:::i;40010:328::-;;;;;;;;;;-1:-1:-1;40010:328:0;;;;;:::i;:::-;;:::i;61780:197::-;;;;;;;;;;-1:-1:-1;61780:197:0;;;;;:::i;:::-;;:::i;58966:28::-;;;;;;;;;;;;;;;;60254:392;;;;;;;;;;-1:-1:-1;60254:392:0;;;;;:::i;:::-;;:::i;61156:616::-;;;;;;;;;;-1:-1:-1;61156:616:0;;;;;:::i;:::-;;:::i;65172:287::-;;;;;;;;;;-1:-1:-1;65172:287:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;58864:29::-;;;;;;;;;;;;;;;;59975:106;;;;;;;;;;;;;:::i;39113:164::-;;;;;;;;;;-1:-1:-1;39113:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;39234:25:0;;;39210:4;39234:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;39113:164;58717:24;;;;;;;;;;-1:-1:-1;58717:24:0;;;;;;;;61985:466;;;;;;:::i;:::-;;:::i;57660:201::-;;;;;;;;;;-1:-1:-1;57660:201:0;;;;;:::i;:::-;;:::i;58900:25::-;;;;;;;;;;;;;;;;49541:224;49643:4;-1:-1:-1;;;;;;49667:50:0;;-1:-1:-1;;;49667:50:0;;:90;;;49721:36;49745:11;49721:23;:36::i;:::-;49660:97;49541:224;-1:-1:-1;;49541:224:0:o;37035:100::-;37089:13;37122:5;37115:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37035:100;:::o;63615:523::-;56797:7;56824:6;-1:-1:-1;;;;;56824:6:0;34564:10;56971:23;56963:68;;;;-1:-1:-1;;;56963:68:0;;;;;;;:::i;:::-;;;;;;;;;63742:10:::1;::::0;63710:28:::1;63728:2:::0;63710:13:::1;50269:10:::0;:17;;50181:113;63710:13:::1;:17:::0;::::1;:28::i;:::-;:42;;63702:78;;;;-1:-1:-1::0;;;63702:78:0::1;;;;;;;:::i;:::-;63830:14;::::0;63799:12:::1;::::0;:27:::1;::::0;63816:2;63799:16:::1;:27::i;:::-;:45;;63791:83;;;;-1:-1:-1::0;;;63791:83:0::1;;;;;;;:::i;:::-;63892:9;63887:244;63907:13:::0;;::::1;63887:244;;;63942:17;63962:13;50269:10:::0;:17;;50181:113;63962:13:::1;63942:33;;64010:10;;63994:13;50269:10:::0;:17;;50181:113;63994:13:::1;:26;63990:130;;;64057:1;64041:12;;:17;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;64077:27:0::1;::::0;-1:-1:-1;64087:2:0;;64090:1;64087:5;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;64094:9;64077;:27::i;:::-;-1:-1:-1::0;63922:3:0;::::1;::::0;::::1;:::i;:::-;;;;63887:244;;;;63615:523:::0;;:::o;38594:221::-;38670:7;41937:16;;;:7;:16;;;;;;-1:-1:-1;;;;;41937:16:0;38690:73;;;;-1:-1:-1;;;38690:73:0;;17831:2:1;38690:73:0;;;17813:21:1;17870:2;17850:18;;;17843:30;17909:34;17889:18;;;17882:62;-1:-1:-1;;;17960:18:1;;;17953:42;18012:19;;38690:73:0;17629:408:1;38690:73:0;-1:-1:-1;38783:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;38783:24:0;;38594:221::o;38117:411::-;38198:13;38214:23;38229:7;38214:14;:23::i;:::-;38198:39;;38262:5;-1:-1:-1;;;;;38256:11:0;:2;-1:-1:-1;;;;;38256:11:0;;;38248:57;;;;-1:-1:-1;;;38248:57:0;;19364:2:1;38248:57:0;;;19346:21:1;19403:2;19383:18;;;19376:30;19442:34;19422:18;;;19415:62;-1:-1:-1;;;19493:18:1;;;19486:31;19534:19;;38248:57:0;19162:397:1;38248:57:0;34564:10;-1:-1:-1;;;;;38340:21:0;;;;:62;;-1:-1:-1;38365:37:0;38382:5;34564:10;39113:164;:::i;38365:37::-;38318:168;;;;-1:-1:-1;;;38318:168:0;;15529:2:1;38318:168:0;;;15511:21:1;15568:2;15548:18;;;15541:30;15607:34;15587:18;;;15580:62;15678:26;15658:18;;;15651:54;15722:19;;38318:168:0;15327:420:1;38318:168:0;38499:21;38508:2;38512:7;38499:8;:21::i;39344:339::-;39539:41;34564:10;39572:7;39539:18;:41::i;:::-;39531:103;;;;-1:-1:-1;;;39531:103:0;;;;;;;:::i;:::-;39647:28;39657:4;39663:2;39667:7;39647:9;:28::i;49849:256::-;49946:7;49982:23;49999:5;49982:16;:23::i;:::-;49974:5;:31;49966:87;;;;-1:-1:-1;;;49966:87:0;;10680:2:1;49966:87:0;;;10662:21:1;10719:2;10699:18;;;10692:30;10758:34;10738:18;;;10731:62;-1:-1:-1;;;10809:18:1;;;10802:41;10860:19;;49966:87:0;10478:407:1;49966:87:0;-1:-1:-1;;;;;;50071:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;49849:256::o;64691:160::-;56797:7;56824:6;-1:-1:-1;;;;;56824:6:0;34564:10;56971:23;56963:68;;;;-1:-1:-1;;;56963:68:0;;;;;;;:::i;:::-;64782:15:::1;::::0;;::::1;;::::0;;::::1;::::0;::::1;64781:16;64763:34:::0;::::1;-1:-1:-1::0;;64763:34:0;;::::1;::::0;;;::::1;::::0;;;;64813:30:::1;::::0;::::1;::::0;::::1;::::0;64827:15;::::1;::::0;;::::1;9345:14:1::0;9338:22;9320:41;;9308:2;9293:18;;9180:187;64813:30:0::1;;;;;;;;64691:160::o:0;65012:152::-;56797:7;56824:6;-1:-1:-1;;;;;56824:6:0;34564:10;56971:23;56963:68;;;;-1:-1:-1;;;56963:68:0;;;;;;;:::i;:::-;65119:37:::1;::::0;65087:21:::1;::::0;65127:10:::1;::::0;65119:37;::::1;;;::::0;65087:21;;65069:15:::1;65119:37:::0;65069:15;65119:37;65087:21;65127:10;65119:37;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;65058:106;65012:152::o:0;39754:185::-;39892:39;39909:4;39915:2;39919:7;39892:39;;;;;;;;;;;;:16;:39::i;64267:129::-;56797:7;56824:6;-1:-1:-1;;;;;56824:6:0;34564:10;56971:23;56963:68;;;;-1:-1:-1;;;56963:68:0;;;;;;;:::i;:::-;64357:31;;::::1;::::0;:21:::1;::::0;:31:::1;::::0;::::1;::::0;::::1;:::i;50371:233::-:0;50446:7;50482:30;50269:10;:17;;50181:113;50482:30;50474:5;:38;50466:95;;;;-1:-1:-1;;;50466:95:0;;20526:2:1;50466:95:0;;;20508:21:1;20565:2;20545:18;;;20538:30;20604:34;20584:18;;;20577:62;-1:-1:-1;;;20655:18:1;;;20648:42;20707:19;;50466:95:0;20324:408:1;50466:95:0;50579:10;50590:5;50579:17;;;;;;;;:::i;:::-;;;;;;;;;50572:24;;50371:233;;;:::o;63085:522::-;56797:7;56824:6;-1:-1:-1;;;;;56824:6:0;34564:10;56971:23;56963:68;;;;-1:-1:-1;;;56963:68:0;;;;;;;:::i;:::-;63216:10:::1;;63185:27;63203:8;63185:13;50269:10:::0;:17;;50181:113;63185:27:::1;:41;;63177:77;;;;-1:-1:-1::0;;;63177:77:0::1;;;;;;;:::i;:::-;63303:14;::::0;63273:12:::1;::::0;:26:::1;::::0;63290:8;63273:16:::1;:26::i;:::-;:44;;63265:82;;;;-1:-1:-1::0;;;63265:82:0::1;;;;;;;:::i;:::-;63365:9;63360:240;63384:8;63380:1;:12;63360:240;;;63414:17;63434:13;50269:10:::0;:17;;50181:113;63434:13:::1;63414:33;;63482:10;;63466:13;50269:10:::0;:17;;50181:113;63466:13:::1;:26;63462:127;;;63529:1;63513:12;;:17;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;63549:24:0::1;::::0;-1:-1:-1;63559:2:0;63563:9;63549::::1;:24::i;:::-;-1:-1:-1::0;63394:3:0;::::1;::::0;::::1;:::i;:::-;;;;63360:240;;64146:113:::0;56797:7;56824:6;-1:-1:-1;;;;;56824:6:0;34564:10;56971:23;56963:68;;;;-1:-1:-1;;;56963:68:0;;;;;;;:::i;:::-;64228:23;;::::1;::::0;:13:::1;::::0;:23:::1;::::0;::::1;::::0;::::1;:::i;60678:470::-:0;60768:12;;60743:4;;60768:12;;60760:44;;;;-1:-1:-1;;;60760:44:0;;9980:2:1;60760:44:0;;;9962:21:1;10019:2;9999:18;;;9992:30;-1:-1:-1;;;10038:18:1;;;10031:49;10097:18;;60760:44:0;9778:343:1;60760:44:0;60824:15;;;;;;;60823:16;60815:41;;;;-1:-1:-1;;;60815:41:0;;17129:2:1;60815:41:0;;;17111:21:1;17168:2;17148:18;;;17141:30;-1:-1:-1;;;17187:18:1;;;17180:42;17239:18;;60815:41:0;16927:336:1;60815:41:0;60906:10;;60875:27;60893:8;60875:13;50269:10;:17;;50181:113;60875:27;:41;;60867:77;;;;-1:-1:-1;;;60867:77:0;;;;;;;:::i;:::-;60994:17;;60963:13;;:27;;60981:8;60963:17;:27::i;:::-;:48;;60955:86;;;;-1:-1:-1;;;60955:86:0;;;;;;;:::i;:::-;61072:19;;61060:8;:31;;61052:64;;;;-1:-1:-1;;;61052:64:0;;19015:2:1;61052:64:0;;;18997:21:1;19054:2;19034:18;;;19027:30;-1:-1:-1;;;19073:18:1;;;19066:50;19133:18;;61052:64:0;18813:344:1;61052:64:0;-1:-1:-1;61136:4:0;;60678:470;-1:-1:-1;60678:470:0:o;36729:239::-;36801:7;36837:16;;;:7;:16;;;;;;-1:-1:-1;;;;;36837:16:0;36872:19;36864:73;;;;-1:-1:-1;;;36864:73:0;;16365:2:1;36864:73:0;;;16347:21:1;16404:2;16384:18;;;16377:30;16443:34;16423:18;;;16416:62;-1:-1:-1;;;16494:18:1;;;16487:39;16543:19;;36864:73:0;16163:405:1;62459:589:0;2207:1;2805:7;;:19;;2797:63;;;;-1:-1:-1;;;2797:63:0;;20939:2:1;2797:63:0;;;20921:21:1;20978:2;20958:18;;;20951:30;21017:33;20997:18;;;20990:61;21068:18;;2797:63:0;20737:355:1;2797:63:0;2207:1;2938:7;:18;62586:43:::1;62601:10;62613:8:::0;62623:5;;62586:14:::1;:43::i;:::-;62578:75;;;::::0;-1:-1:-1;;;62578:75:0;;12275:2:1;62578:75:0::1;::::0;::::1;12257:21:1::0;12314:2;12294:18;;;12287:30;-1:-1:-1;;;12333:18:1;;;12326:49;12392:18;;62578:75:0::1;12073:343:1::0;62578:75:0::1;62685:5;::::0;:19:::1;::::0;62695:8;62685:9:::1;:19::i;:::-;62672:9;:32;;62664:59;;;::::0;-1:-1:-1;;;62664:59:0;;13382:2:1;62664:59:0::1;::::0;::::1;13364:21:1::0;13421:2;13401:18;;;13394:30;-1:-1:-1;;;13440:18:1;;;13433:44;13494:18;;62664:59:0::1;13180:338:1::0;62664:59:0::1;62741:9;62736:305;62760:8;62756:1;:12;62736:305;;;62790:17;62810:13;50269:10:::0;:17;;50181:113;62810:13:::1;62790:33;;62858:10;;62842:13;50269:10:::0;:17;;50181:113;62842:13:::1;:26;62838:192;;;62906:1;62889:13;;:18;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;62947:10:0::1;62926:32;::::0;;;:20:::1;:32;::::0;;;;:37;;62962:1:::1;::::0;62926:32;:37:::1;::::0;62962:1;;62926:37:::1;:::i;:::-;::::0;;;-1:-1:-1;62982:32:0::1;::::0;-1:-1:-1;62992:10:0::1;63004:9:::0;62982::::1;:32::i;:::-;-1:-1:-1::0;62770:3:0;::::1;::::0;::::1;:::i;:::-;;;;62736:305;;;-1:-1:-1::0;;2163:1:0;3117:7;:22;-1:-1:-1;;62459:589:0:o;36459:208::-;36531:7;-1:-1:-1;;;;;36559:19:0;;36551:74;;;;-1:-1:-1;;;36551:74:0;;15954:2:1;36551:74:0;;;15936:21:1;15993:2;15973:18;;;15966:30;16032:34;16012:18;;;16005:62;-1:-1:-1;;;16083:18:1;;;16076:40;16133:19;;36551:74:0;15752:406:1;36551:74:0;-1:-1:-1;;;;;;36643:16:0;;;;;:9;:16;;;;;;;36459:208::o;57402:103::-;56797:7;56824:6;-1:-1:-1;;;;;56824:6:0;34564:10;56971:23;56963:68;;;;-1:-1:-1;;;56963:68:0;;;;;;;:::i;:::-;57467:30:::1;57494:1;57467:18;:30::i;:::-;57402:103::o:0;64404:156::-;56797:7;56824:6;-1:-1:-1;;;;;56824:6:0;34564:10;56971:23;56963:68;;;;-1:-1:-1;;;56963:68:0;;;;;;;:::i;:::-;64483:12:::1;:20:::0;;;64519:33:::1;::::0;9518:25:1;;;64519:33:0::1;::::0;9506:2:1;9491:18;64519:33:0::1;;;;;;;64404:156:::0;:::o;60089:126::-;56797:7;56824:6;-1:-1:-1;;;;;56824:6:0;34564:10;56971:23;56963:68;;;;-1:-1:-1;;;56963:68:0;;;;;;;:::i;:::-;60180:27;;::::1;::::0;:12:::1;::::0;:27:::1;::::0;::::1;::::0;::::1;:::i;37204:104::-:0;37260:13;37293:7;37286:14;;;;;:::i;64859:145::-;56797:7;56824:6;-1:-1:-1;;;;;56824:6:0;34564:10;56971:23;56963:68;;;;-1:-1:-1;;;56963:68:0;;;;;;;:::i;:::-;64944:12:::1;::::0;;::::1;::::0;;::::1;64943:13;-1:-1:-1::0;;64928:28:0;;::::1;::::0;::::1;::::0;;;64972:24:::1;::::0;64983:12;;9345:14:1;9338:22;9320:41;;64972:24:0::1;::::0;9308:2:1;9293:18;64972:24:0::1;9180:187:1::0;38887:155:0;38982:52;34564:10;39015:8;39025;38982:18;:52::i;64568:115::-;56797:7;56824:6;-1:-1:-1;;;;;56824:6:0;34564:10;56971:23;56963:68;;;;-1:-1:-1;;;56963:68:0;;;;;;;:::i;:::-;64651:11:::1;:24:::0;64568:115::o;40010:328::-;40185:41;34564:10;40218:7;40185:18;:41::i;:::-;40177:103;;;;-1:-1:-1;;;40177:103:0;;;;;;;:::i;:::-;40291:39;40305:4;40311:2;40315:7;40324:5;40291:13;:39::i;:::-;40010:328;;;;:::o;61780:197::-;61850:7;-1:-1:-1;;;;;61878:19:0;;61870:54;;;;-1:-1:-1;;;61870:54:0;;14838:2:1;61870:54:0;;;14820:21:1;14877:2;14857:18;;;14850:30;-1:-1:-1;;;14896:18:1;;;14889:52;14958:18;;61870:54:0;14636:346:1;61870:54:0;-1:-1:-1;;;;;;61942:27:0;;;;;:20;:27;;;;;;;61780:197::o;60254:392::-;41913:4;41937:16;;;:7;:16;;;;;;60319:13;;-1:-1:-1;;;;;41937:16:0;60345:49;;;;-1:-1:-1;;;60345:49:0;;14076:2:1;60345:49:0;;;14058:21:1;14115:2;14095:18;;;14088:30;-1:-1:-1;;;14134:18:1;;;14127:50;14194:18;;60345:49:0;13874:344:1;60345:49:0;60407:29;60439:21;60407:53;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60523:1;60497:15;60491:29;:33;:147;;60625:13;60491:147;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60568:15;60585:18;:7;:16;:18::i;:::-;60551:53;;;;;;;;;:::i;:::-;;;;;;;;;;;;;60491:147;60471:167;60254:392;-1:-1:-1;;;60254:392:0:o;61156:616::-;61329:12;;61303:4;;61329:12;;61328:13;:32;;;;-1:-1:-1;61345:15:0;;;;;;;61328:32;61320:67;;;;-1:-1:-1;;;61320:67:0;;21299:2:1;61320:67:0;;;21281:21:1;21338:2;21318:18;;;21311:30;-1:-1:-1;;;21357:18:1;;;21350:52;21419:18;;61320:67:0;21097:346:1;61320:67:0;65581:25;;;6806:2:1;6802:15;;;-1:-1:-1;;6798:53:1;65581:25:0;;;;6786:66:1;;;;65581:25:0;;;;;;;;;6868:12:1;;;;65581:25:0;;;65571:36;;;;;61406:28;;61428:5;;61406:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61406:7:0;;-1:-1:-1;;;61406:28:0:i;:::-;61398:54;;;;-1:-1:-1;;;61398:54:0;;20184:2:1;61398:54:0;;;20166:21:1;20223:2;20203:18;;;20196:30;-1:-1:-1;;;20242:18:1;;;20235:43;20295:18;;61398:54:0;19982:337:1;61398:54:0;61502:10;;61471:27;61489:8;61471:13;50269:10;:17;;50181:113;61471:27;:41;;61463:77;;;;-1:-1:-1;;;61463:77:0;;;;;;;:::i;:::-;61590:17;;61559:13;;:27;;61577:8;61559:17;:27::i;:::-;:48;;61551:86;;;;-1:-1:-1;;;61551:86:0;;;;;;;:::i;:::-;61701:12;;-1:-1:-1;;;;;61656:27:0;;;;;;:20;:27;;;;;;:41;;61688:8;61656:31;:41::i;:::-;:57;;61648:92;;;;-1:-1:-1;;;61648:92:0;;13725:2:1;61648:92:0;;;13707:21:1;13764:2;13744:18;;;13737:30;-1:-1:-1;;;13783:18:1;;;13776:52;13845:18;;61648:92:0;13523:346:1;61648:92:0;-1:-1:-1;61760:4:0;61156:616;;;;;;;:::o;65172:287::-;65230:31;65305:17;65315:6;65305:9;:17::i;:::-;65291:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65291:32:0;;65274:49;;65339:9;65334:116;65351:17;65361:6;65351:9;:17::i;:::-;65349:1;:19;65334:116;;;65408:30;65428:6;65436:1;65408:19;:30::i;:::-;65388:14;65403:1;65388:17;;;;;;;;:::i;:::-;;;;;;;;;;:50;65369:3;;;;:::i;:::-;;;;65334:116;;;;65172:287;;;:::o;59975:106::-;60028:13;60061:12;60054:19;;;;;:::i;61985:466::-;2207:1;2805:7;;:19;;2797:63;;;;-1:-1:-1;;;2797:63:0;;20939:2:1;2797:63:0;;;20921:21:1;20978:2;20958:18;;;20951:30;21017:33;20997:18;;;20990:61;21068:18;;2797:63:0;20737:355:1;2797:63:0;2207:1;2938:7;:18;62079:17:::1;62087:8:::0;62079:7:::1;:17::i;:::-;62071:41;;;::::0;-1:-1:-1;;;62071:41:0;;15189:2:1;62071:41:0::1;::::0;::::1;15171:21:1::0;15228:2;15208:18;;;15201:30;-1:-1:-1;;;15247:18:1;;;15240:41;15298:18;;62071:41:0::1;14987:335:1::0;62071:41:0::1;62144:5;::::0;:19:::1;::::0;62154:8;62144:9:::1;:19::i;:::-;62131:9;:32;;62123:59;;;::::0;-1:-1:-1;;;62123:59:0;;13382:2:1;62123:59:0::1;::::0;::::1;13364:21:1::0;13421:2;13401:18;;;13394:30;-1:-1:-1;;;13440:18:1;;;13433:44;13494:18;;62123:59:0::1;13180:338:1::0;62123:59:0::1;62200:9;62195:249;62219:8;62215:1;:12;62195:249;;;62249:17;62269:13;50269:10:::0;:17;;50181:113;62269:13:::1;62249:33;;62317:10;;62301:13;50269:10:::0;:17;;50181:113;62301:13:::1;:26;62297:136;;;62365:1;62348:13;;:18;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;62385:32:0::1;::::0;-1:-1:-1;62395:10:0::1;62407:9:::0;62385::::1;:32::i;:::-;-1:-1:-1::0;62229:3:0;::::1;::::0;::::1;:::i;:::-;;;;62195:249;;;-1:-1:-1::0;;2163:1:0;3117:7;:22;61985:466::o;57660:201::-;56797:7;56824:6;-1:-1:-1;;;;;56824:6:0;34564:10;56971:23;56963:68;;;;-1:-1:-1;;;56963:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;57749:22:0;::::1;57741:73;;;::::0;-1:-1:-1;;;57741:73:0;;11511:2:1;57741:73:0::1;::::0;::::1;11493:21:1::0;11550:2;11530:18;;;11523:30;11589:34;11569:18;;;11562:62;-1:-1:-1;;;11640:18:1;;;11633:36;11686:19;;57741:73:0::1;11309:402:1::0;57741:73:0::1;57825:28;57844:8;57825:18;:28::i;:::-;57660:201:::0;:::o;36090:305::-;36192:4;-1:-1:-1;;;;;;36229:40:0;;-1:-1:-1;;;36229:40:0;;:105;;-1:-1:-1;;;;;;;36286:48:0;;-1:-1:-1;;;36286:48:0;36229:105;:158;;;-1:-1:-1;;;;;;;;;;18519:40:0;;;36351:36;18410:157;29640:98;29698:7;29725:5;29729:1;29725;:5;:::i;42832:110::-;42908:26;42918:2;42922:7;42908:26;;;;;;;;;;;;:9;:26::i;45830:174::-;45905:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;45905:29:0;-1:-1:-1;;;;;45905:29:0;;;;;;;;:24;;45959:23;45905:24;45959:14;:23::i;:::-;-1:-1:-1;;;;;45950:46:0;;;;;;;;;;;45830:174;;:::o;42142:348::-;42235:4;41937:16;;;:7;:16;;;;;;-1:-1:-1;;;;;41937:16:0;42252:73;;;;-1:-1:-1;;;42252:73:0;;14425:2:1;42252:73:0;;;14407:21:1;14464:2;14444:18;;;14437:30;14503:34;14483:18;;;14476:62;-1:-1:-1;;;14554:18:1;;;14547:42;14606:19;;42252:73:0;14223:408:1;42252:73:0;42336:13;42352:23;42367:7;42352:14;:23::i;:::-;42336:39;;42405:5;-1:-1:-1;;;;;42394:16:0;:7;-1:-1:-1;;;;;42394:16:0;;:51;;;;42438:7;-1:-1:-1;;;;;42414:31:0;:20;42426:7;42414:11;:20::i;:::-;-1:-1:-1;;;;;42414:31:0;;42394:51;:87;;;-1:-1:-1;;;;;;39234:25:0;;;39210:4;39234:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;42449:32;39113:164;45134:578;45293:4;-1:-1:-1;;;;;45266:31:0;:23;45281:7;45266:14;:23::i;:::-;-1:-1:-1;;;;;45266:31:0;;45258:85;;;;-1:-1:-1;;;45258:85:0;;18605:2:1;45258:85:0;;;18587:21:1;18644:2;18624:18;;;18617:30;18683:34;18663:18;;;18656:62;-1:-1:-1;;;18734:18:1;;;18727:39;18783:19;;45258:85:0;18403:405:1;45258:85:0;-1:-1:-1;;;;;45362:16:0;;45354:65;;;;-1:-1:-1;;;45354:65:0;;12623:2:1;45354:65:0;;;12605:21:1;12662:2;12642:18;;;12635:30;12701:34;12681:18;;;12674:62;-1:-1:-1;;;12752:18:1;;;12745:34;12796:19;;45354:65:0;12421:400:1;45354:65:0;45432:39;45453:4;45459:2;45463:7;45432:20;:39::i;:::-;45536:29;45553:1;45557:7;45536:8;:29::i;:::-;-1:-1:-1;;;;;45578:15:0;;;;;;:9;:15;;;;;:20;;45597:1;;45578:15;:20;;45597:1;;45578:20;:::i;:::-;;;;-1:-1:-1;;;;;;;45609:13:0;;;;;;:9;:13;;;;;:18;;45626:1;;45609:13;:18;;45626:1;;45609:18;:::i;:::-;;;;-1:-1:-1;;45638:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;45638:21:0;-1:-1:-1;;;;;45638:21:0;;;;;;;;;45677:27;;45638:16;;45677:27;;;;;;;45134:578;;;:::o;30378:98::-;30436:7;30463:5;30467:1;30463;:5;:::i;58021:191::-;58095:16;58114:6;;-1:-1:-1;;;;;58131:17:0;;;-1:-1:-1;;;;;;58131:17:0;;;;;;58164:40;;58114:6;;;;;;;58164:40;;58095:16;58164:40;58084:128;58021:191;:::o;46146:315::-;46301:8;-1:-1:-1;;;;;46292:17:0;:5;-1:-1:-1;;;;;46292:17:0;;;46284:55;;;;-1:-1:-1;;;46284:55:0;;13028:2:1;46284:55:0;;;13010:21:1;13067:2;13047:18;;;13040:30;13106:27;13086:18;;;13079:55;13151:18;;46284:55:0;12826:349:1;46284:55:0;-1:-1:-1;;;;;46350:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;46350:46:0;;;;;;;;;;46412:41;;9320::1;;;46412::0;;9293:18:1;46412:41:0;;;;;;;46146:315;;;:::o;41220:::-;41377:28;41387:4;41393:2;41397:7;41377:9;:28::i;:::-;41424:48;41447:4;41453:2;41457:7;41466:5;41424:22;:48::i;:::-;41416:111;;;;-1:-1:-1;;;41416:111:0;;;;;;;:::i;5687:723::-;5743:13;5964:10;5960:53;;-1:-1:-1;;5991:10:0;;;;;;;;;;;;-1:-1:-1;;;5991:10:0;;;;;5687:723::o;5960:53::-;6038:5;6023:12;6079:78;6086:9;;6079:78;;6112:8;;;;:::i;:::-;;-1:-1:-1;6135:10:0;;-1:-1:-1;6143:2:0;6135:10;;:::i;:::-;;;6079:78;;;6167:19;6199:6;6189:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6189:17:0;;6167:39;;6217:154;6224:10;;6217:154;;6251:11;6261:1;6251:11;;:::i;:::-;;-1:-1:-1;6320:10:0;6328:2;6320:5;:10;:::i;:::-;6307:24;;:2;:24;:::i;:::-;6294:39;;6277:6;6284;6277:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;6277:56:0;;;;;;;;-1:-1:-1;6348:11:0;6357:2;6348:11;;:::i;:::-;;;6217:154;;65623;65701:4;65725:44;65744:5;65751:11;;65764:4;65725:18;:44::i;43169:321::-;43299:18;43305:2;43309:7;43299:5;:18::i;:::-;43350:54;43381:1;43385:2;43389:7;43398:5;43350:22;:54::i;:::-;43328:154;;;;-1:-1:-1;;;43328:154:0;;;;;;;:::i;51217:589::-;-1:-1:-1;;;;;51423:18:0;;51419:187;;51458:40;51490:7;52633:10;:17;;52606:24;;;;:15;:24;;;;;:44;;;52661:24;;;;;;;;;;;;52529:164;51458:40;51419:187;;;51528:2;-1:-1:-1;;;;;51520:10:0;:4;-1:-1:-1;;;;;51520:10:0;;51516:90;;51547:47;51580:4;51586:7;51547:32;:47::i;:::-;-1:-1:-1;;;;;51620:16:0;;51616:183;;51653:45;51690:7;51653:36;:45::i;51616:183::-;51726:4;-1:-1:-1;;;;;51720:10:0;:2;-1:-1:-1;;;;;51720:10:0;;51716:83;;51747:40;51775:2;51779:7;51747:27;:40::i;47026:799::-;47181:4;-1:-1:-1;;;;;47202:13:0;;8589:20;8637:8;47198:620;;47238:72;;-1:-1:-1;;;47238:72:0;;-1:-1:-1;;;;;47238:36:0;;;;;:72;;34564:10;;47289:4;;47295:7;;47304:5;;47238:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47238:72:0;;;;;;;;-1:-1:-1;;47238:72:0;;;;;;;;;;;;:::i;:::-;;;47234:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47480:13:0;;47476:272;;47523:60;;-1:-1:-1;;;47523:60:0;;;;;;;:::i;47476:272::-;47698:6;47692:13;47683:6;47679:2;47675:15;47668:38;47234:529;-1:-1:-1;;;;;;47361:51:0;-1:-1:-1;;;47361:51:0;;-1:-1:-1;47354:58:0;;47198:620;-1:-1:-1;47802:4:0;47795:11;;4062:190;4187:4;4240;4211:25;4224:5;4231:4;4211:12;:25::i;:::-;:33;;4062:190;-1:-1:-1;;;;4062:190:0:o;43826:382::-;-1:-1:-1;;;;;43906:16:0;;43898:61;;;;-1:-1:-1;;;43898:61:0;;17470:2:1;43898:61:0;;;17452:21:1;;;17489:18;;;17482:30;17548:34;17528:18;;;17521:62;17600:18;;43898:61:0;17268:356:1;43898:61:0;41913:4;41937:16;;;:7;:16;;;;;;-1:-1:-1;;;;;41937:16:0;:30;43970:58;;;;-1:-1:-1;;;43970:58:0;;11918:2:1;43970:58:0;;;11900:21:1;11957:2;11937:18;;;11930:30;11996;11976:18;;;11969:58;12044:18;;43970:58:0;11716:352:1;43970:58:0;44041:45;44070:1;44074:2;44078:7;44041:20;:45::i;:::-;-1:-1:-1;;;;;44099:13:0;;;;;;:9;:13;;;;;:18;;44116:1;;44099:13;:18;;44116:1;;44099:18;:::i;:::-;;;;-1:-1:-1;;44128:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;44128:21:0;-1:-1:-1;;;;;44128:21:0;;;;;;;;44167:33;;44128:16;;;44167:33;;44128:16;;44167:33;43826:382;;:::o;53320:988::-;53586:22;53636:1;53611:22;53628:4;53611:16;:22::i;:::-;:26;;;;:::i;:::-;53648:18;53669:26;;;:17;:26;;;;;;53586:51;;-1:-1:-1;53802:28:0;;;53798:328;;-1:-1:-1;;;;;53869:18:0;;53847:19;53869:18;;;:12;:18;;;;;;;;:34;;;;;;;;;53920:30;;;;;;:44;;;54037:30;;:17;:30;;;;;:43;;;53798:328;-1:-1:-1;54222:26:0;;;;:17;:26;;;;;;;;54215:33;;;-1:-1:-1;;;;;54266:18:0;;;;;:12;:18;;;;;:34;;;;;;;54259:41;53320:988::o;54603:1079::-;54881:10;:17;54856:22;;54881:21;;54901:1;;54881:21;:::i;:::-;54913:18;54934:24;;;:15;:24;;;;;;55307:10;:26;;54856:46;;-1:-1:-1;54934:24:0;;54856:46;;55307:26;;;;;;:::i;:::-;;;;;;;;;55285:48;;55371:11;55346:10;55357;55346:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;55451:28;;;:15;:28;;;;;;;:41;;;55623:24;;;;;55616:31;55658:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;54674:1008;;;54603:1079;:::o;52107:221::-;52192:14;52209:20;52226:2;52209:16;:20::i;:::-;-1:-1:-1;;;;;52240:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;52285:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;52107:221:0:o;4614:701::-;4697:7;4740:4;4697:7;4755:523;4779:5;:12;4775:1;:16;4755:523;;;4813:20;4836:5;4842:1;4836:8;;;;;;;;:::i;:::-;;;;;;;4813:31;;4879:12;4863;:28;4859:408;;5016:44;;;;;;7048:19:1;;;7083:12;;;7076:28;;;7120:12;;5016:44:0;;;;;;;;;;;;5006:55;;;;;;4991:70;;4859:408;;;5206:44;;;;;;7048:19:1;;;7083:12;;;7076:28;;;7120:12;;5206:44:0;;;;;;;;;;;;5196:55;;;;;;5181:70;;4859:408;-1:-1:-1;4793:3:0;;;;:::i;:::-;;;;4755:523;;;-1:-1:-1;5295:12:0;4614:701;-1:-1:-1;;;4614:701:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:631:1;78:5;108:18;149:2;141:6;138:14;135:40;;;155:18;;:::i;:::-;230:2;224:9;198:2;284:15;;-1:-1:-1;;280:24:1;;;306:2;276:33;272:42;260:55;;;330:18;;;350:22;;;327:46;324:72;;;376:18;;:::i;:::-;416:10;412:2;405:22;445:6;436:15;;475:6;467;460:22;515:3;506:6;501:3;497:16;494:25;491:45;;;532:1;529;522:12;491:45;582:6;577:3;570:4;562:6;558:17;545:44;637:1;630:4;621:6;613;609:19;605:30;598:41;;;;14:631;;;;;:::o;650:173::-;718:20;;-1:-1:-1;;;;;767:31:1;;757:42;;747:70;;813:1;810;803:12;747:70;650:173;;;:::o;828:367::-;891:8;901:6;955:3;948:4;940:6;936:17;932:27;922:55;;973:1;970;963:12;922:55;-1:-1:-1;996:20:1;;1039:18;1028:30;;1025:50;;;1071:1;1068;1061:12;1025:50;1108:4;1100:6;1096:17;1084:29;;1168:3;1161:4;1151:6;1148:1;1144:14;1136:6;1132:27;1128:38;1125:47;1122:67;;;1185:1;1182;1175:12;1122:67;828:367;;;;;:::o;1200:186::-;1259:6;1312:2;1300:9;1291:7;1287:23;1283:32;1280:52;;;1328:1;1325;1318:12;1280:52;1351:29;1370:9;1351:29;:::i;1391:260::-;1459:6;1467;1520:2;1508:9;1499:7;1495:23;1491:32;1488:52;;;1536:1;1533;1526:12;1488:52;1559:29;1578:9;1559:29;:::i;:::-;1549:39;;1607:38;1641:2;1630:9;1626:18;1607:38;:::i;:::-;1597:48;;1391:260;;;;;:::o;1656:328::-;1733:6;1741;1749;1802:2;1790:9;1781:7;1777:23;1773:32;1770:52;;;1818:1;1815;1808:12;1770:52;1841:29;1860:9;1841:29;:::i;:::-;1831:39;;1889:38;1923:2;1912:9;1908:18;1889:38;:::i;:::-;1879:48;;1974:2;1963:9;1959:18;1946:32;1936:42;;1656:328;;;;;:::o;1989:666::-;2084:6;2092;2100;2108;2161:3;2149:9;2140:7;2136:23;2132:33;2129:53;;;2178:1;2175;2168:12;2129:53;2201:29;2220:9;2201:29;:::i;:::-;2191:39;;2249:38;2283:2;2272:9;2268:18;2249:38;:::i;:::-;2239:48;;2334:2;2323:9;2319:18;2306:32;2296:42;;2389:2;2378:9;2374:18;2361:32;2416:18;2408:6;2405:30;2402:50;;;2448:1;2445;2438:12;2402:50;2471:22;;2524:4;2516:13;;2512:27;-1:-1:-1;2502:55:1;;2553:1;2550;2543:12;2502:55;2576:73;2641:7;2636:2;2623:16;2618:2;2614;2610:11;2576:73;:::i;:::-;2566:83;;;1989:666;;;;;;;:::o;2660:347::-;2725:6;2733;2786:2;2774:9;2765:7;2761:23;2757:32;2754:52;;;2802:1;2799;2792:12;2754:52;2825:29;2844:9;2825:29;:::i;:::-;2815:39;;2904:2;2893:9;2889:18;2876:32;2951:5;2944:13;2937:21;2930:5;2927:32;2917:60;;2973:1;2970;2963:12;2917:60;2996:5;2986:15;;;2660:347;;;;;:::o;3012:254::-;3080:6;3088;3141:2;3129:9;3120:7;3116:23;3112:32;3109:52;;;3157:1;3154;3147:12;3109:52;3180:29;3199:9;3180:29;:::i;:::-;3170:39;3256:2;3241:18;;;;3228:32;;-1:-1:-1;;;3012:254:1:o;3271:579::-;3375:6;3383;3391;3399;3452:2;3440:9;3431:7;3427:23;3423:32;3420:52;;;3468:1;3465;3458:12;3420:52;3491:29;3510:9;3491:29;:::i;:::-;3481:39;;3567:2;3556:9;3552:18;3539:32;3529:42;;3622:2;3611:9;3607:18;3594:32;3649:18;3641:6;3638:30;3635:50;;;3681:1;3678;3671:12;3635:50;3720:70;3782:7;3773:6;3762:9;3758:22;3720:70;:::i;:::-;3271:579;;;;-1:-1:-1;3809:8:1;-1:-1:-1;;;;3271:579:1:o;3855:437::-;3941:6;3949;4002:2;3990:9;3981:7;3977:23;3973:32;3970:52;;;4018:1;4015;4008:12;3970:52;4058:9;4045:23;4091:18;4083:6;4080:30;4077:50;;;4123:1;4120;4113:12;4077:50;4162:70;4224:7;4215:6;4204:9;4200:22;4162:70;:::i;:::-;4251:8;;4136:96;;-1:-1:-1;3855:437:1;-1:-1:-1;;;;3855:437:1:o;4297:180::-;4356:6;4409:2;4397:9;4388:7;4384:23;4380:32;4377:52;;;4425:1;4422;4415:12;4377:52;-1:-1:-1;4448:23:1;;4297:180;-1:-1:-1;4297:180:1:o;4482:245::-;4540:6;4593:2;4581:9;4572:7;4568:23;4564:32;4561:52;;;4609:1;4606;4599:12;4561:52;4648:9;4635:23;4667:30;4691:5;4667:30;:::i;4732:249::-;4801:6;4854:2;4842:9;4833:7;4829:23;4825:32;4822:52;;;4870:1;4867;4860:12;4822:52;4902:9;4896:16;4921:30;4945:5;4921:30;:::i;4986:450::-;5055:6;5108:2;5096:9;5087:7;5083:23;5079:32;5076:52;;;5124:1;5121;5114:12;5076:52;5164:9;5151:23;5197:18;5189:6;5186:30;5183:50;;;5229:1;5226;5219:12;5183:50;5252:22;;5305:4;5297:13;;5293:27;-1:-1:-1;5283:55:1;;5334:1;5331;5324:12;5283:55;5357:73;5422:7;5417:2;5404:16;5399:2;5395;5391:11;5357:73;:::i;5626:254::-;5694:6;5702;5755:2;5743:9;5734:7;5730:23;5726:32;5723:52;;;5771:1;5768;5761:12;5723:52;5807:9;5794:23;5784:33;;5836:38;5870:2;5859:9;5855:18;5836:38;:::i;5885:505::-;5980:6;5988;5996;6049:2;6037:9;6028:7;6024:23;6020:32;6017:52;;;6065:1;6062;6055:12;6017:52;6101:9;6088:23;6078:33;;6162:2;6151:9;6147:18;6134:32;6189:18;6181:6;6178:30;6175:50;;;6221:1;6218;6211:12;6175:50;6260:70;6322:7;6313:6;6302:9;6298:22;6260:70;:::i;:::-;5885:505;;6349:8;;-1:-1:-1;6234:96:1;;-1:-1:-1;;;;5885:505:1:o;6395:257::-;6436:3;6474:5;6468:12;6501:6;6496:3;6489:19;6517:63;6573:6;6566:4;6561:3;6557:14;6550:4;6543:5;6539:16;6517:63;:::i;:::-;6634:2;6613:15;-1:-1:-1;;6609:29:1;6600:39;;;;6641:4;6596:50;;6395:257;-1:-1:-1;;6395:257:1:o;7143:470::-;7322:3;7360:6;7354:13;7376:53;7422:6;7417:3;7410:4;7402:6;7398:17;7376:53;:::i;:::-;7492:13;;7451:16;;;;7514:57;7492:13;7451:16;7548:4;7536:17;;7514:57;:::i;:::-;7587:20;;7143:470;-1:-1:-1;;;;7143:470:1:o;8050:488::-;-1:-1:-1;;;;;8319:15:1;;;8301:34;;8371:15;;8366:2;8351:18;;8344:43;8418:2;8403:18;;8396:34;;;8466:3;8461:2;8446:18;;8439:31;;;8244:4;;8487:45;;8512:19;;8504:6;8487:45;:::i;:::-;8479:53;8050:488;-1:-1:-1;;;;;;8050:488:1:o;8543:632::-;8714:2;8766:21;;;8836:13;;8739:18;;;8858:22;;;8685:4;;8714:2;8937:15;;;;8911:2;8896:18;;;8685:4;8980:169;8994:6;8991:1;8988:13;8980:169;;;9055:13;;9043:26;;9124:15;;;;9089:12;;;;9016:1;9009:9;8980:169;;;-1:-1:-1;9166:3:1;;8543:632;-1:-1:-1;;;;;;8543:632:1:o;9554:219::-;9703:2;9692:9;9685:21;9666:4;9723:44;9763:2;9752:9;9748:18;9740:6;9723:44;:::i;10126:347::-;10328:2;10310:21;;;10367:2;10347:18;;;10340:30;10406:25;10401:2;10386:18;;10379:53;10464:2;10449:18;;10126:347::o;10890:414::-;11092:2;11074:21;;;11131:2;11111:18;;;11104:30;11170:34;11165:2;11150:18;;11143:62;-1:-1:-1;;;11236:2:1;11221:18;;11214:48;11294:3;11279:19;;10890:414::o;16573:349::-;16775:2;16757:21;;;16814:2;16794:18;;;16787:30;16853:27;16848:2;16833:18;;16826:55;16913:2;16898:18;;16573:349::o;18042:356::-;18244:2;18226:21;;;18263:18;;;18256:30;18322:34;18317:2;18302:18;;18295:62;18389:2;18374:18;;18042:356::o;19564:413::-;19766:2;19748:21;;;19805:2;19785:18;;;19778:30;19844:34;19839:2;19824:18;;19817:62;-1:-1:-1;;;19910:2:1;19895:18;;19888:47;19967:3;19952:19;;19564:413::o;21630:128::-;21670:3;21701:1;21697:6;21694:1;21691:13;21688:39;;;21707:18;;:::i;:::-;-1:-1:-1;21743:9:1;;21630:128::o;21763:120::-;21803:1;21829;21819:35;;21834:18;;:::i;:::-;-1:-1:-1;21868:9:1;;21763:120::o;21888:168::-;21928:7;21994:1;21990;21986:6;21982:14;21979:1;21976:21;21971:1;21964:9;21957:17;21953:45;21950:71;;;22001:18;;:::i;:::-;-1:-1:-1;22041:9:1;;21888:168::o;22061:125::-;22101:4;22129:1;22126;22123:8;22120:34;;;22134:18;;:::i;:::-;-1:-1:-1;22171:9:1;;22061:125::o;22191:258::-;22263:1;22273:113;22287:6;22284:1;22281:13;22273:113;;;22363:11;;;22357:18;22344:11;;;22337:39;22309:2;22302:10;22273:113;;;22404:6;22401:1;22398:13;22395:48;;;-1:-1:-1;;22439:1:1;22421:16;;22414:27;22191:258::o;22454:380::-;22533:1;22529:12;;;;22576;;;22597:61;;22651:4;22643:6;22639:17;22629:27;;22597:61;22704:2;22696:6;22693:14;22673:18;22670:38;22667:161;;;22750:10;22745:3;22741:20;22738:1;22731:31;22785:4;22782:1;22775:15;22813:4;22810:1;22803:15;22839:135;22878:3;-1:-1:-1;;22899:17:1;;22896:43;;;22919:18;;:::i;:::-;-1:-1:-1;22966:1:1;22955:13;;22839:135::o;22979:112::-;23011:1;23037;23027:35;;23042:18;;:::i;:::-;-1:-1:-1;23076:9:1;;22979:112::o;23096:127::-;23157:10;23152:3;23148:20;23145:1;23138:31;23188:4;23185:1;23178:15;23212:4;23209:1;23202:15;23228:127;23289:10;23284:3;23280:20;23277:1;23270:31;23320:4;23317:1;23310:15;23344:4;23341:1;23334:15;23360:127;23421:10;23416:3;23412:20;23409:1;23402:31;23452:4;23449:1;23442:15;23476:4;23473:1;23466:15;23492:127;23553:10;23548:3;23544:20;23541:1;23534:31;23584:4;23581:1;23574:15;23608:4;23605:1;23598:15;23624:127;23685:10;23680:3;23676:20;23673:1;23666:31;23716:4;23713:1;23706:15;23740:4;23737:1;23730:15;23756:131;-1:-1:-1;;;;;;23830:32:1;;23820:43;;23810:71;;23877:1;23874;23867:12

Swarm Source

ipfs://db0d3a85fd3669c88da319fe831f4f4644943d8cf84784060d307080ffceb052
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.