ETH Price: $2,520.27 (-5.23%)

Token

MetaLordz (MTL)
 

Overview

Max Total Supply

291 MTL

Holders

171

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 MTL
0xe645f52912f351195f6588c9330fe13d834215eb
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:
MetaLordz

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-12-15
*/

/**
 *Submitted for verification at Etherscan.io on 2021-12-13
*/

// SPDX-License-Identifier: MIT

// File: @openzeppelin/contracts/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) {
        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));
            }
        }

        // Check if the computed hash (root) is equal to the provided root
        return computedHash == root;
    }
}

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



pragma solidity ^0.8.0;

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s;
        uint8 v;
        assembly {
            s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            v := add(shr(255, vs), 27)
        }
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

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



pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

// File: @openzeppelin/contracts/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 no longer needed starting with Solidity 0.8. 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/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/Context.sol



pragma solidity ^0.8.0;

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

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

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



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() {
        _setOwner(_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 {
    //    _setOwner(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");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: @openzeppelin/contracts/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



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



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



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



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



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: @openzeppelin/contracts/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: 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 Edit for rawOwnerOf token
     */
    function rawOwnerOf(uint256 tokenId) public view returns (address) {
        return _owners[tokenId];
    }

    /**
     * @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 {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _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);
        address to = address(0);

        _beforeTokenTransfer(owner, to, tokenId);

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

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

        emit Transfer(owner, to, 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 Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver(to).onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("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: 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();
    }
}

pragma solidity ^0.8.0;
pragma abicoder v2;

contract MetaLordz is ERC721Enumerable, Ownable {
    
    using SafeMath for uint256;

    address private owner_;
    bytes32 public merkleRoot;
	bytes32 public claimsRoot;
	address public wallet1 = 0x94C967079DFB253E4dE24c0a845ff2A13E279bbA;
    address public wallet2 = 0x82d7ed59eB4a573e7AaceFc6f84F579014f433BE;
    address public wallet3 = 0xcA0ff953D73c0c86C8aA9069A092de1010c5Ae99;
    address public wallet4 = 0x16A0A11E0dbff1Cc1e7144A9311D1D4EA9e0DEc3;

    uint256 public constant metalordzPrice = 90000000000000000;
    uint256 public constant metalordzWLPrice = 70000000000000000;
    uint public maxMetalordzPurchase = 3;
	uint public maxMetalordzPerAddress = 6;
    uint256 public constant MAX_METALORDZ = 4444;
    uint public metalordzReserve = 200;

    bool public saleIsActive = false;
	bool public ClaimIsActive = false;
	bool public whitelistSaleIsActive = false;
	
    mapping(address => bool) private whitelisted_minters;
    mapping(address => uint) private max_mints_per_address;
    
	event WhitelistedMint(address minter);
    event MerkleRootUpdated(bytes32 new_merkle_root);
    event ReserveRootUpdated(bytes32 new_merkle_root);	
	event wallet1AddressChanged(address _wallet1);
    event wallet2AddressChanged(address _wallet2);
    event wallet3AddressChanged(address _wallet3);
    event wallet4AddressChanged(address _wallet4);
    
    string public baseTokenURI;
    
    constructor() ERC721("MetaLordz", "MTL") { }
    
    function withdraw() public onlyOwner {
        uint balance = address(this).balance;
        payable(msg.sender).transfer(balance);
    }

	function setPuchaseLimit(uint maxAllowed) external onlyOwner {
        maxMetalordzPurchase = maxAllowed;
    }
	
	function setAddressLimit(uint maxAllowed) external onlyOwner {
        maxMetalordzPerAddress = maxAllowed;
    }

    function updateReserveRoot(bytes32 newmerkleRoot) external onlyOwner {
        claimsRoot = newmerkleRoot;
        emit ReserveRootUpdated(claimsRoot);
    }

    function claimMetalordz(bytes32[] calldata merkleProof) public {        
        require(ClaimIsActive, "Giveaways must be active to claim MetaLordz");
        require(max_mints_per_address[msg.sender].add(1) <= 1,"Max 1 mints allowed per whitelisted wallet");

        // Verify the merkle proof
        require(MerkleProof.verify(merkleProof, claimsRoot,  keccak256(abi.encodePacked(msg.sender))  ), "Invalid proof");
		
        _safeMint(msg.sender, totalSupply());
		max_mints_per_address[msg.sender] = max_mints_per_address[msg.sender].add(1);
        metalordzReserve = metalordzReserve.sub(1);
    }


    function _baseURI() internal view virtual override returns (string memory) {
        return baseTokenURI;
    }

    function setBaseURI(string memory baseURI) public onlyOwner {
        baseTokenURI = baseURI;
    }


    function flipSaleState() public onlyOwner {
        saleIsActive = !saleIsActive;
    }

    function flipWhitelistSaleState() public onlyOwner {
        whitelistSaleIsActive = !whitelistSaleIsActive;
    }    

    function flipClaimState() public onlyOwner {
        ClaimIsActive = !ClaimIsActive;
    }  
       
     function mintMetalordz(uint numberOfTokens) public payable {
        require(saleIsActive, "Sale must be active to mint MetaLordz");
        require(numberOfTokens > 0 && numberOfTokens <= maxMetalordzPurchase, "Per transaction limit exceeded");
        require(msg.value == metalordzPrice.mul(numberOfTokens), "Ether value sent is not correct");
        require(max_mints_per_address[msg.sender].add(numberOfTokens) <= maxMetalordzPerAddress,"Per waller limit exceeded");
        
        for(uint i = 0; i < numberOfTokens; i++) {
            if (totalSupply() < MAX_METALORDZ) {
                _safeMint(msg.sender, totalSupply());
                max_mints_per_address[msg.sender] = max_mints_per_address[msg.sender].add(1);
            } else {
               saleIsActive = !saleIsActive;
                payable(msg.sender).transfer(numberOfTokens.sub(i).mul(metalordzPrice));
                break;
            }
        }
    }

   
   // to set the merkle proof
    function updateMerkleRoot(bytes32 newmerkleRoot) external onlyOwner {
        merkleRoot = newmerkleRoot;
        emit MerkleRootUpdated(merkleRoot);
    }


    function whitelistedMints(uint numberOfTokens, bytes32[] calldata merkleProof ) payable external  {
        address user_ = msg.sender;
        require(whitelistSaleIsActive, "Sale must be active to mint MetaLordz");
        require(numberOfTokens > 0 && numberOfTokens <= 2, "Can only mint 2 tokens at a time");
        require(msg.value == metalordzWLPrice.mul(numberOfTokens), "Ether value sent is not correct");
        require(max_mints_per_address[msg.sender].add(numberOfTokens) <= 2,"Max 2 mints allowed per whitelisted wallet");

        // Verify the merkle proof
        require(MerkleProof.verify(merkleProof, merkleRoot,  keccak256(abi.encodePacked(user_))  ), "Invalid proof");
		
		for(uint i = 0; i < numberOfTokens; i++) {
            if (totalSupply() < MAX_METALORDZ) {
                _safeMint(msg.sender, totalSupply());
                max_mints_per_address[msg.sender] = max_mints_per_address[msg.sender].add(1);
            } else {
			    whitelistSaleIsActive = !whitelistSaleIsActive;
                payable(msg.sender).transfer(numberOfTokens.sub(i).mul(metalordzWLPrice));
                break;
            }
        }

        emit WhitelistedMint(user_);
    }
	
    function setWallet_1(address _address) external onlyOwner {
        wallet1 = _address;
        emit wallet1AddressChanged(_address);
    }
    
    function setWallet_2(address _address) external onlyOwner {
        wallet2 = _address;
        emit wallet2AddressChanged(_address);
    }

    function setWallet_3(address _address) external onlyOwner {
        wallet3 = _address;
        emit wallet3AddressChanged(_address);
    }
    
    function setWallet_4(address _address) external onlyOwner {
        wallet4 = _address;
        emit wallet4AddressChanged(_address);
    }

    function withdrawAll() external onlyOwner {
        require(address(this).balance > 0, "No balance to withdraw.");
        uint256 _amount = address(this).balance;
        (bool wallet1Success, ) = wallet1.call{value: _amount.mul(63).div(100)}("");
        (bool wallet2Success, ) = wallet2.call{value: _amount.mul(33).div(100)}("");
        (bool wallet3Success, ) = wallet3.call{value: _amount.mul(3).div(100)}("");
        (bool wallet4Success, ) = wallet4.call{value: _amount.mul(1).div(100)}("");

        require(wallet1Success && wallet2Success && wallet3Success && wallet4Success, "Withdrawal failed.");
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"new_merkle_root","type":"bytes32"}],"name":"MerkleRootUpdated","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":"bytes32","name":"new_merkle_root","type":"bytes32"}],"name":"ReserveRootUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"minter","type":"address"}],"name":"WhitelistedMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_wallet1","type":"address"}],"name":"wallet1AddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_wallet2","type":"address"}],"name":"wallet2AddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_wallet3","type":"address"}],"name":"wallet3AddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_wallet4","type":"address"}],"name":"wallet4AddressChanged","type":"event"},{"inputs":[],"name":"ClaimIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_METALORDZ","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":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"claimMetalordz","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimsRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flipClaimState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipWhitelistSaleState","outputs":[],"stateMutability":"nonpayable","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"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMetalordzPerAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMetalordzPurchase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metalordzPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metalordzReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metalordzWLPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"mintMetalordz","outputs":[],"stateMutability":"payable","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":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"rawOwnerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxAllowed","type":"uint256"}],"name":"setAddressLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxAllowed","type":"uint256"}],"name":"setPuchaseLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setWallet_1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setWallet_2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setWallet_3","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setWallet_4","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"newmerkleRoot","type":"bytes32"}],"name":"updateMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"newmerkleRoot","type":"bytes32"}],"name":"updateReserveRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wallet1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wallet2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wallet3","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wallet4","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistSaleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"whitelistedMints","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052600e80546001600160a01b03199081167394c967079dfb253e4de24c0a845ff2a13e279bba17909155600f805482167382d7ed59eb4a573e7aacefc6f84f579014f433be17905560108054821673ca0ff953d73c0c86c8aa9069a092de1010c5ae99179055601180549091167316a0a11e0dbff1cc1e7144a9311d1d4ea9e0dec31790556003601255600660135560c86014556015805462ffffff19169055348015620000b057600080fd5b50604080518082018252600981526826b2ba30a637b9323d60b91b60208083019182528351808501909452600384526213551360ea1b908401528151919291620000fd916000916200018c565b508051620001139060019060208401906200018c565b505050620001306200012a6200013660201b60201c565b6200013a565b6200026f565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8280546200019a9062000232565b90600052602060002090601f016020900481019282620001be576000855562000209565b82601f10620001d957805160ff191683800117855562000209565b8280016001018555821562000209579182015b8281111562000209578251825591602001919060010190620001ec565b50620002179291506200021b565b5090565b5b808211156200021757600081556001016200021c565b600181811c908216806200024757607f821691505b602082108114156200026957634e487b7160e01b600052602260045260246000fd5b50919050565b61308f806200027f6000396000f3fe6080604052600436106102e45760003560e01c806370a0823111610190578063c87b56dd116100dc578063eb8d244411610095578063f5a881771161006f578063f5a881771461089b578063f685fff8146108bb578063f6dc3934146108d1578063f70f31ff146108f157600080fd5b8063eb8d244414610841578063ef2dbc991461085b578063f2fde38b1461087b57600080fd5b8063c87b56dd1461077f578063d1beca641461079f578063d31a1112146107b4578063d547cfb7146107c7578063e194f6b5146107dc578063e985e9c5146107f857600080fd5b80638da5cb5b11610149578063a22cb46511610123578063a22cb4651461070d578063b2644cc51461072d578063b88d4fde14610740578063c6e7b5b81461076057600080fd5b80638da5cb5b146106ba5780639225de64146106d857806395d89b41146106f857600080fd5b806370a08231146105fe5780637673faf01461061e57806377eb75dd1461063e5780637f81be691461065457806384955ccd1461068a578063853828b6146106a557600080fd5b80632bcdf3f41161024f5780633f45ce6a116102085780634f6ccce7116101e25780634f6ccce71461058957806355f804b3146105a95780636352211e146105c95780636d60e6c1146105e957600080fd5b80633f45ce6a1461053357806342842e0e146105495780634783f0ef1461056957600080fd5b80632bcdf3f4146104935780632d15898a146104b35780632eb4a7ab146104d357806334918dfd146104e95780633c918bae146104fe5780633ccfd60b1461051e57600080fd5b806310b5454d116102a157806310b5454d146103de578063128cf3f8146103fe57806318160ddd1461041e5780631a026c961461043357806321822fed1461045357806323b872dd1461047357600080fd5b806301a0004d146102e957806301ffc9a71461031257806306fdde0314610342578063081812fc14610364578063095ea7b31461039c5780630b8d0a28146103be575b600080fd5b3480156102f557600080fd5b506102ff61115c81565b6040519081526020015b60405180910390f35b34801561031e57600080fd5b5061033261032d3660046129b7565b610907565b6040519015158152602001610309565b34801561034e57600080fd5b50610357610932565b6040516103099190612a2c565b34801561037057600080fd5b5061038461037f366004612a3f565b6109c4565b6040516001600160a01b039091168152602001610309565b3480156103a857600080fd5b506103bc6103b7366004612a74565b610a5e565b005b3480156103ca57600080fd5b50600f54610384906001600160a01b031681565b3480156103ea57600080fd5b506015546103329062010000900460ff1681565b34801561040a57600080fd5b506103bc610419366004612a9e565b610b74565b34801561042a57600080fd5b506008546102ff565b34801561043f57600080fd5b50600e54610384906001600160a01b031681565b34801561045f57600080fd5b506103bc61046e366004612a9e565b610bf3565b34801561047f57600080fd5b506103bc61048e366004612ab9565b610c6b565b34801561049f57600080fd5b506103bc6104ae366004612a3f565b610c9c565b3480156104bf57600080fd5b506103bc6104ce366004612a3f565b610ccb565b3480156104df57600080fd5b506102ff600c5481565b3480156104f557600080fd5b506103bc610cfa565b34801561050a57600080fd5b50601054610384906001600160a01b031681565b34801561052a57600080fd5b506103bc610d38565b34801561053f57600080fd5b506102ff60135481565b34801561055557600080fd5b506103bc610564366004612ab9565b610d95565b34801561057557600080fd5b506103bc610584366004612a3f565b610db0565b34801561059557600080fd5b506102ff6105a4366004612a3f565b610e0f565b3480156105b557600080fd5b506103bc6105c4366004612b81565b610ea2565b3480156105d557600080fd5b506103846105e4366004612a3f565b610edf565b3480156105f557600080fd5b506103bc610f56565b34801561060a57600080fd5b506102ff610619366004612a9e565b610f9d565b34801561062a57600080fd5b50601154610384906001600160a01b031681565b34801561064a57600080fd5b506102ff60145481565b34801561066057600080fd5b5061038461066f366004612a3f565b6000908152600260205260409020546001600160a01b031690565b34801561069657600080fd5b506102ff66f8b0a10e47000081565b3480156106b157600080fd5b506103bc611024565b3480156106c657600080fd5b50600a546001600160a01b0316610384565b3480156106e457600080fd5b506103bc6106f3366004612a9e565b61129d565b34801561070457600080fd5b50610357611315565b34801561071957600080fd5b506103bc610728366004612bca565b611324565b6103bc61073b366004612a3f565b6113e9565b34801561074c57600080fd5b506103bc61075b366004612c06565b6115ff565b34801561076c57600080fd5b5060155461033290610100900460ff1681565b34801561078b57600080fd5b5061035761079a366004612a3f565b611637565b3480156107ab57600080fd5b506103bc611712565b6103bc6107c2366004612cce565b61175b565b3480156107d357600080fd5b50610357611a85565b3480156107e857600080fd5b506102ff67013fbe85edc9000081565b34801561080457600080fd5b50610332610813366004612d1a565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561084d57600080fd5b506015546103329060ff1681565b34801561086757600080fd5b506103bc610876366004612a3f565b611b13565b34801561088757600080fd5b506103bc610896366004612a9e565b611b72565b3480156108a757600080fd5b506103bc6108b6366004612d4d565b611c0d565b3480156108c757600080fd5b506102ff60125481565b3480156108dd57600080fd5b506103bc6108ec366004612a9e565b611dde565b3480156108fd57600080fd5b506102ff600d5481565b60006001600160e01b03198216632bbd609d60e11b148061092c575061092c82611e56565b92915050565b60606000805461094190612d8f565b80601f016020809104026020016040519081016040528092919081815260200182805461096d90612d8f565b80156109ba5780601f1061098f576101008083540402835291602001916109ba565b820191906000526020600020905b81548152906001019060200180831161099d57829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b0316610a425760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610a6982610edf565b9050806001600160a01b0316836001600160a01b03161415610ad75760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610a39565b336001600160a01b0382161480610af35750610af38133610813565b610b655760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610a39565b610b6f8383611ea6565b505050565b600a546001600160a01b03163314610b9e5760405162461bcd60e51b8152600401610a3990612dca565b600f80546001600160a01b0319166001600160a01b0383169081179091556040519081527f9539f0adf432f6612656f7ec15ddf8a7e5835132bd4a474f39954885dbfc4554906020015b60405180910390a150565b600a546001600160a01b03163314610c1d5760405162461bcd60e51b8152600401610a3990612dca565b601080546001600160a01b0319166001600160a01b0383169081179091556040519081527fcfe8d0199cafb54be527f2e63b41b75a9ecf2d411b91b457f3ac20e38fbb921590602001610be8565b610c753382611f14565b610c915760405162461bcd60e51b8152600401610a3990612dff565b610b6f83838361200b565b600a546001600160a01b03163314610cc65760405162461bcd60e51b8152600401610a3990612dca565b601355565b600a546001600160a01b03163314610cf55760405162461bcd60e51b8152600401610a3990612dca565b601255565b600a546001600160a01b03163314610d245760405162461bcd60e51b8152600401610a3990612dca565b6015805460ff19811660ff90911615179055565b600a546001600160a01b03163314610d625760405162461bcd60e51b8152600401610a3990612dca565b6040514790339082156108fc029083906000818181858888f19350505050158015610d91573d6000803e3d6000fd5b5050565b610b6f838383604051806020016040528060008152506115ff565b600a546001600160a01b03163314610dda5760405162461bcd60e51b8152600401610a3990612dca565b600c8190556040518181527f90004c04698bc3322499a575ed3752dd4abf33e0a7294c06a787a0fe01bea94190602001610be8565b6000610e1a60085490565b8210610e7d5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610a39565b60088281548110610e9057610e90612e50565b90600052602060002001549050919050565b600a546001600160a01b03163314610ecc5760405162461bcd60e51b8152600401610a3990612dca565b8051610d91906018906020840190612908565b6000818152600260205260408120546001600160a01b03168061092c5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610a39565b600a546001600160a01b03163314610f805760405162461bcd60e51b8152600401610a3990612dca565b6015805461ff001981166101009182900460ff1615909102179055565b60006001600160a01b0382166110085760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610a39565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b0316331461104e5760405162461bcd60e51b8152600401610a3990612dca565b6000471161109e5760405162461bcd60e51b815260206004820152601760248201527f4e6f2062616c616e636520746f2077697468647261772e0000000000000000006044820152606401610a39565b600e5447906000906001600160a01b03166110c560646110bf85603f6121b6565b906121c2565b604051600081818185875af1925050503d8060008114611101576040519150601f19603f3d011682016040523d82523d6000602084013e611106565b606091505b5050600f549091506000906001600160a01b031661112a60646110bf8660216121b6565b604051600081818185875af1925050503d8060008114611166576040519150601f19603f3d011682016040523d82523d6000602084013e61116b565b606091505b50506010549091506000906001600160a01b031661118f60646110bf8760036121b6565b604051600081818185875af1925050503d80600081146111cb576040519150601f19603f3d011682016040523d82523d6000602084013e6111d0565b606091505b50506011549091506000906001600160a01b03166111f460646110bf8860016121b6565b604051600081818185875af1925050503d8060008114611230576040519150601f19603f3d011682016040523d82523d6000602084013e611235565b606091505b505090508380156112435750825b801561124c5750815b80156112555750805b6112965760405162461bcd60e51b81526020600482015260126024820152712bb4ba34323930bbb0b6103330b4b632b21760711b6044820152606401610a39565b5050505050565b600a546001600160a01b031633146112c75760405162461bcd60e51b8152600401610a3990612dca565b600e80546001600160a01b0319166001600160a01b0383169081179091556040519081527f1354f2ed7ad63d510fe05b011c0f4585cc0503e5f2a9cf0ac0b2e7dc80127d5d90602001610be8565b60606001805461094190612d8f565b6001600160a01b03821633141561137d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610a39565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60155460ff1661140b5760405162461bcd60e51b8152600401610a3990612e66565b60008111801561141d57506012548111155b6114695760405162461bcd60e51b815260206004820152601e60248201527f506572207472616e73616374696f6e206c696d697420657863656564656400006044820152606401610a39565b61147b67013fbe85edc90000826121b6565b34146114c95760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f7272656374006044820152606401610a39565b601354336000908152601760205260409020546114e690836121ce565b11156115345760405162461bcd60e51b815260206004820152601960248201527f5065722077616c6c6572206c696d6974206578636565646564000000000000006044820152606401610a39565b60005b81811015610d915761115c61154b60085490565b1015611593576115633361155e60085490565b6121da565b3360009081526017602052604090205461157e9060016121ce565b336000908152601760205260409020556115ed565b6015805460ff19811660ff90911615179055336108fc6115c567013fbe85edc900006115bf86866121f4565b906121b6565b6040518115909202916000818181858888f19350505050158015610b6f573d6000803e3d6000fd5b806115f781612ec1565b915050611537565b6116093383611f14565b6116255760405162461bcd60e51b8152600401610a3990612dff565b61163184848484612200565b50505050565b6000818152600260205260409020546060906001600160a01b03166116b65760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610a39565b60006116c0612233565b905060008151116116e0576040518060200160405280600081525061170b565b806116ea84612242565b6040516020016116fb929190612edc565b6040516020818303038152906040525b9392505050565b600a546001600160a01b0316331461173c5760405162461bcd60e51b8152600401610a3990612dca565b6015805462ff0000198116620100009182900460ff1615909102179055565b601554339062010000900460ff166117855760405162461bcd60e51b8152600401610a3990612e66565b600084118015611796575060028411155b6117e25760405162461bcd60e51b815260206004820181905260248201527f43616e206f6e6c79206d696e74203220746f6b656e7320617420612074696d656044820152606401610a39565b6117f366f8b0a10e470000856121b6565b34146118415760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f7272656374006044820152606401610a39565b3360009081526017602052604090205460029061185e90866121ce565b11156118bf5760405162461bcd60e51b815260206004820152602a60248201527f4d61782032206d696e747320616c6c6f776564207065722077686974656c69736044820152691d1959081dd85b1b195d60b21b6064820152608401610a39565b61193683838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050600c546040516bffffffffffffffffffffffff19606088901b16602082015290925060340190505b60405160208183030381529060405280519060200120612340565b6119725760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610a39565b60005b84811015611a425761115c61198960085490565b10156119cc5761199c3361155e60085490565b336000908152601760205260409020546119b79060016121ce565b33600090815260176020526040902055611a30565b6015805462ff0000198116620100009182900460ff1615909102179055336108fc611a0266f8b0a10e4700006115bf89866121f4565b6040518115909202916000818181858888f19350505050158015611a2a573d6000803e3d6000fd5b50611a42565b80611a3a81612ec1565b915050611975565b506040516001600160a01b03821681527f67c400238edbf2cfe078e9c46b03af4a14f535dafde7829c4ebd8ffc76448bee9060200160405180910390a150505050565b60188054611a9290612d8f565b80601f0160208091040260200160405190810160405280929190818152602001828054611abe90612d8f565b8015611b0b5780601f10611ae057610100808354040283529160200191611b0b565b820191906000526020600020905b815481529060010190602001808311611aee57829003601f168201915b505050505081565b600a546001600160a01b03163314611b3d5760405162461bcd60e51b8152600401610a3990612dca565b600d8190556040518181527f92e8a31a1b5397f82bbae03aad039df87f6af7ecbd505eb7351d2dda5a33aa8390602001610be8565b600a546001600160a01b03163314611b9c5760405162461bcd60e51b8152600401610a3990612dca565b6001600160a01b038116611c015760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a39565b611c0a816123ef565b50565b601554610100900460ff16611c785760405162461bcd60e51b815260206004820152602b60248201527f476976656177617973206d7573742062652061637469766520746f20636c616960448201526a369026b2ba30a637b9323d60a91b6064820152608401610a39565b33600090815260176020526040902054600190611c9590826121ce565b1115611cf65760405162461bcd60e51b815260206004820152602a60248201527f4d61782031206d696e747320616c6c6f776564207065722077686974656c69736044820152691d1959081dd85b1b195d60b21b6064820152608401610a39565b611d5582828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050600d546040516bffffffffffffffffffffffff193360601b166020820152909250603401905061191b565b611d915760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610a39565b611d9e3361155e60085490565b33600090815260176020526040902054611db99060016121ce565b33600090815260176020526040902055601454611dd79060016121f4565b6014555050565b600a546001600160a01b03163314611e085760405162461bcd60e51b8152600401610a3990612dca565b601180546001600160a01b0319166001600160a01b0383169081179091556040519081527f89e6a58e4bc2c31cd8683e43e00e307d1dad49adef29ed929e68eb02a39c7d5d90602001610be8565b60006001600160e01b031982166380ac58cd60e01b1480611e8757506001600160e01b03198216635b5e139f60e01b145b8061092c57506301ffc9a760e01b6001600160e01b031983161461092c565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611edb82610edf565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600260205260408120546001600160a01b0316611f8d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610a39565b6000611f9883610edf565b9050806001600160a01b0316846001600160a01b03161480611fd35750836001600160a01b0316611fc8846109c4565b6001600160a01b0316145b8061200357506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661201e82610edf565b6001600160a01b0316146120865760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610a39565b6001600160a01b0382166120e85760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610a39565b6120f3838383612441565b6120fe600082611ea6565b6001600160a01b0383166000908152600360205260408120805460019290612127908490612f0b565b90915550506001600160a01b0382166000908152600360205260408120805460019290612155908490612f22565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061170b8284612f3a565b600061170b8284612f6f565b600061170b8284612f22565b610d918282604051806020016040528060008152506124f9565b600061170b8284612f0b565b61220b84848461200b565b6122178484848461252c565b6116315760405162461bcd60e51b8152600401610a3990612f83565b60606018805461094190612d8f565b6060816122665750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612290578061227a81612ec1565b91506122899050600a83612f6f565b915061226a565b60008167ffffffffffffffff8111156122ab576122ab612af5565b6040519080825280601f01601f1916602001820160405280156122d5576020820181803683370190505b5090505b8415612003576122ea600183612f0b565b91506122f7600a86612fd5565b612302906030612f22565b60f81b81838151811061231757612317612e50565b60200101906001600160f81b031916908160001a905350612339600a86612f6f565b94506122d9565b600081815b85518110156123e457600086828151811061236257612362612e50565b602002602001015190508083116123a45760408051602081018590529081018290526060016040516020818303038152906040528051906020012092506123d1565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b50806123dc81612ec1565b915050612345565b509092149392505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03831661249c5761249781600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6124bf565b816001600160a01b0316836001600160a01b0316146124bf576124bf838261262a565b6001600160a01b0382166124d657610b6f816126c7565b826001600160a01b0316826001600160a01b031614610b6f57610b6f8282612776565b61250383836127ba565b612510600084848461252c565b610b6f5760405162461bcd60e51b8152600401610a3990612f83565b60006001600160a01b0384163b1561261f57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612570903390899088908890600401612fe9565b6020604051808303816000875af19250505080156125ab575060408051601f3d908101601f191682019092526125a891810190613026565b60015b612605573d8080156125d9576040519150601f19603f3d011682016040523d82523d6000602084013e6125de565b606091505b5080516125fd5760405162461bcd60e51b8152600401610a3990612f83565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612003565b506001949350505050565b6000600161263784610f9d565b6126419190612f0b565b600083815260076020526040902054909150808214612694576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906126d990600190612f0b565b6000838152600960205260408120546008805493945090928490811061270157612701612e50565b90600052602060002001549050806008838154811061272257612722612e50565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061275a5761275a613043565b6001900381819060005260206000200160009055905550505050565b600061278183610f9d565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b0382166128105760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610a39565b6000818152600260205260409020546001600160a01b0316156128755760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610a39565b61288160008383612441565b6001600160a01b03821660009081526003602052604081208054600192906128aa908490612f22565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b82805461291490612d8f565b90600052602060002090601f016020900481019282612936576000855561297c565b82601f1061294f57805160ff191683800117855561297c565b8280016001018555821561297c579182015b8281111561297c578251825591602001919060010190612961565b5061298892915061298c565b5090565b5b80821115612988576000815560010161298d565b6001600160e01b031981168114611c0a57600080fd5b6000602082840312156129c957600080fd5b813561170b816129a1565b60005b838110156129ef5781810151838201526020016129d7565b838111156116315750506000910152565b60008151808452612a188160208601602086016129d4565b601f01601f19169290920160200192915050565b60208152600061170b6020830184612a00565b600060208284031215612a5157600080fd5b5035919050565b80356001600160a01b0381168114612a6f57600080fd5b919050565b60008060408385031215612a8757600080fd5b612a9083612a58565b946020939093013593505050565b600060208284031215612ab057600080fd5b61170b82612a58565b600080600060608486031215612ace57600080fd5b612ad784612a58565b9250612ae560208501612a58565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612b2657612b26612af5565b604051601f8501601f19908116603f01168101908282118183101715612b4e57612b4e612af5565b81604052809350858152868686011115612b6757600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215612b9357600080fd5b813567ffffffffffffffff811115612baa57600080fd5b8201601f81018413612bbb57600080fd5b61200384823560208401612b0b565b60008060408385031215612bdd57600080fd5b612be683612a58565b915060208301358015158114612bfb57600080fd5b809150509250929050565b60008060008060808587031215612c1c57600080fd5b612c2585612a58565b9350612c3360208601612a58565b925060408501359150606085013567ffffffffffffffff811115612c5657600080fd5b8501601f81018713612c6757600080fd5b612c7687823560208401612b0b565b91505092959194509250565b60008083601f840112612c9457600080fd5b50813567ffffffffffffffff811115612cac57600080fd5b6020830191508360208260051b8501011115612cc757600080fd5b9250929050565b600080600060408486031215612ce357600080fd5b83359250602084013567ffffffffffffffff811115612d0157600080fd5b612d0d86828701612c82565b9497909650939450505050565b60008060408385031215612d2d57600080fd5b612d3683612a58565b9150612d4460208401612a58565b90509250929050565b60008060208385031215612d6057600080fd5b823567ffffffffffffffff811115612d7757600080fd5b612d8385828601612c82565b90969095509350505050565b600181811c90821680612da357607f821691505b60208210811415612dc457634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60208082526025908201527f53616c65206d7573742062652061637469766520746f206d696e74204d6574616040820152642637b9323d60d91b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b6000600019821415612ed557612ed5612eab565b5060010190565b60008351612eee8184602088016129d4565b835190830190612f028183602088016129d4565b01949350505050565b600082821015612f1d57612f1d612eab565b500390565b60008219821115612f3557612f35612eab565b500190565b6000816000190483118215151615612f5457612f54612eab565b500290565b634e487b7160e01b600052601260045260246000fd5b600082612f7e57612f7e612f59565b500490565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600082612fe457612fe4612f59565b500690565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061301c90830184612a00565b9695505050505050565b60006020828403121561303857600080fd5b815161170b816129a1565b634e487b7160e01b600052603160045260246000fdfea264697066735822122025134eb6287c6609848b170e5348a89965c5f87976b716fd873a138ed26d4a8e64736f6c634300080a0033

Deployed Bytecode

0x6080604052600436106102e45760003560e01c806370a0823111610190578063c87b56dd116100dc578063eb8d244411610095578063f5a881771161006f578063f5a881771461089b578063f685fff8146108bb578063f6dc3934146108d1578063f70f31ff146108f157600080fd5b8063eb8d244414610841578063ef2dbc991461085b578063f2fde38b1461087b57600080fd5b8063c87b56dd1461077f578063d1beca641461079f578063d31a1112146107b4578063d547cfb7146107c7578063e194f6b5146107dc578063e985e9c5146107f857600080fd5b80638da5cb5b11610149578063a22cb46511610123578063a22cb4651461070d578063b2644cc51461072d578063b88d4fde14610740578063c6e7b5b81461076057600080fd5b80638da5cb5b146106ba5780639225de64146106d857806395d89b41146106f857600080fd5b806370a08231146105fe5780637673faf01461061e57806377eb75dd1461063e5780637f81be691461065457806384955ccd1461068a578063853828b6146106a557600080fd5b80632bcdf3f41161024f5780633f45ce6a116102085780634f6ccce7116101e25780634f6ccce71461058957806355f804b3146105a95780636352211e146105c95780636d60e6c1146105e957600080fd5b80633f45ce6a1461053357806342842e0e146105495780634783f0ef1461056957600080fd5b80632bcdf3f4146104935780632d15898a146104b35780632eb4a7ab146104d357806334918dfd146104e95780633c918bae146104fe5780633ccfd60b1461051e57600080fd5b806310b5454d116102a157806310b5454d146103de578063128cf3f8146103fe57806318160ddd1461041e5780631a026c961461043357806321822fed1461045357806323b872dd1461047357600080fd5b806301a0004d146102e957806301ffc9a71461031257806306fdde0314610342578063081812fc14610364578063095ea7b31461039c5780630b8d0a28146103be575b600080fd5b3480156102f557600080fd5b506102ff61115c81565b6040519081526020015b60405180910390f35b34801561031e57600080fd5b5061033261032d3660046129b7565b610907565b6040519015158152602001610309565b34801561034e57600080fd5b50610357610932565b6040516103099190612a2c565b34801561037057600080fd5b5061038461037f366004612a3f565b6109c4565b6040516001600160a01b039091168152602001610309565b3480156103a857600080fd5b506103bc6103b7366004612a74565b610a5e565b005b3480156103ca57600080fd5b50600f54610384906001600160a01b031681565b3480156103ea57600080fd5b506015546103329062010000900460ff1681565b34801561040a57600080fd5b506103bc610419366004612a9e565b610b74565b34801561042a57600080fd5b506008546102ff565b34801561043f57600080fd5b50600e54610384906001600160a01b031681565b34801561045f57600080fd5b506103bc61046e366004612a9e565b610bf3565b34801561047f57600080fd5b506103bc61048e366004612ab9565b610c6b565b34801561049f57600080fd5b506103bc6104ae366004612a3f565b610c9c565b3480156104bf57600080fd5b506103bc6104ce366004612a3f565b610ccb565b3480156104df57600080fd5b506102ff600c5481565b3480156104f557600080fd5b506103bc610cfa565b34801561050a57600080fd5b50601054610384906001600160a01b031681565b34801561052a57600080fd5b506103bc610d38565b34801561053f57600080fd5b506102ff60135481565b34801561055557600080fd5b506103bc610564366004612ab9565b610d95565b34801561057557600080fd5b506103bc610584366004612a3f565b610db0565b34801561059557600080fd5b506102ff6105a4366004612a3f565b610e0f565b3480156105b557600080fd5b506103bc6105c4366004612b81565b610ea2565b3480156105d557600080fd5b506103846105e4366004612a3f565b610edf565b3480156105f557600080fd5b506103bc610f56565b34801561060a57600080fd5b506102ff610619366004612a9e565b610f9d565b34801561062a57600080fd5b50601154610384906001600160a01b031681565b34801561064a57600080fd5b506102ff60145481565b34801561066057600080fd5b5061038461066f366004612a3f565b6000908152600260205260409020546001600160a01b031690565b34801561069657600080fd5b506102ff66f8b0a10e47000081565b3480156106b157600080fd5b506103bc611024565b3480156106c657600080fd5b50600a546001600160a01b0316610384565b3480156106e457600080fd5b506103bc6106f3366004612a9e565b61129d565b34801561070457600080fd5b50610357611315565b34801561071957600080fd5b506103bc610728366004612bca565b611324565b6103bc61073b366004612a3f565b6113e9565b34801561074c57600080fd5b506103bc61075b366004612c06565b6115ff565b34801561076c57600080fd5b5060155461033290610100900460ff1681565b34801561078b57600080fd5b5061035761079a366004612a3f565b611637565b3480156107ab57600080fd5b506103bc611712565b6103bc6107c2366004612cce565b61175b565b3480156107d357600080fd5b50610357611a85565b3480156107e857600080fd5b506102ff67013fbe85edc9000081565b34801561080457600080fd5b50610332610813366004612d1a565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561084d57600080fd5b506015546103329060ff1681565b34801561086757600080fd5b506103bc610876366004612a3f565b611b13565b34801561088757600080fd5b506103bc610896366004612a9e565b611b72565b3480156108a757600080fd5b506103bc6108b6366004612d4d565b611c0d565b3480156108c757600080fd5b506102ff60125481565b3480156108dd57600080fd5b506103bc6108ec366004612a9e565b611dde565b3480156108fd57600080fd5b506102ff600d5481565b60006001600160e01b03198216632bbd609d60e11b148061092c575061092c82611e56565b92915050565b60606000805461094190612d8f565b80601f016020809104026020016040519081016040528092919081815260200182805461096d90612d8f565b80156109ba5780601f1061098f576101008083540402835291602001916109ba565b820191906000526020600020905b81548152906001019060200180831161099d57829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b0316610a425760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610a6982610edf565b9050806001600160a01b0316836001600160a01b03161415610ad75760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610a39565b336001600160a01b0382161480610af35750610af38133610813565b610b655760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610a39565b610b6f8383611ea6565b505050565b600a546001600160a01b03163314610b9e5760405162461bcd60e51b8152600401610a3990612dca565b600f80546001600160a01b0319166001600160a01b0383169081179091556040519081527f9539f0adf432f6612656f7ec15ddf8a7e5835132bd4a474f39954885dbfc4554906020015b60405180910390a150565b600a546001600160a01b03163314610c1d5760405162461bcd60e51b8152600401610a3990612dca565b601080546001600160a01b0319166001600160a01b0383169081179091556040519081527fcfe8d0199cafb54be527f2e63b41b75a9ecf2d411b91b457f3ac20e38fbb921590602001610be8565b610c753382611f14565b610c915760405162461bcd60e51b8152600401610a3990612dff565b610b6f83838361200b565b600a546001600160a01b03163314610cc65760405162461bcd60e51b8152600401610a3990612dca565b601355565b600a546001600160a01b03163314610cf55760405162461bcd60e51b8152600401610a3990612dca565b601255565b600a546001600160a01b03163314610d245760405162461bcd60e51b8152600401610a3990612dca565b6015805460ff19811660ff90911615179055565b600a546001600160a01b03163314610d625760405162461bcd60e51b8152600401610a3990612dca565b6040514790339082156108fc029083906000818181858888f19350505050158015610d91573d6000803e3d6000fd5b5050565b610b6f838383604051806020016040528060008152506115ff565b600a546001600160a01b03163314610dda5760405162461bcd60e51b8152600401610a3990612dca565b600c8190556040518181527f90004c04698bc3322499a575ed3752dd4abf33e0a7294c06a787a0fe01bea94190602001610be8565b6000610e1a60085490565b8210610e7d5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610a39565b60088281548110610e9057610e90612e50565b90600052602060002001549050919050565b600a546001600160a01b03163314610ecc5760405162461bcd60e51b8152600401610a3990612dca565b8051610d91906018906020840190612908565b6000818152600260205260408120546001600160a01b03168061092c5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610a39565b600a546001600160a01b03163314610f805760405162461bcd60e51b8152600401610a3990612dca565b6015805461ff001981166101009182900460ff1615909102179055565b60006001600160a01b0382166110085760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610a39565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b0316331461104e5760405162461bcd60e51b8152600401610a3990612dca565b6000471161109e5760405162461bcd60e51b815260206004820152601760248201527f4e6f2062616c616e636520746f2077697468647261772e0000000000000000006044820152606401610a39565b600e5447906000906001600160a01b03166110c560646110bf85603f6121b6565b906121c2565b604051600081818185875af1925050503d8060008114611101576040519150601f19603f3d011682016040523d82523d6000602084013e611106565b606091505b5050600f549091506000906001600160a01b031661112a60646110bf8660216121b6565b604051600081818185875af1925050503d8060008114611166576040519150601f19603f3d011682016040523d82523d6000602084013e61116b565b606091505b50506010549091506000906001600160a01b031661118f60646110bf8760036121b6565b604051600081818185875af1925050503d80600081146111cb576040519150601f19603f3d011682016040523d82523d6000602084013e6111d0565b606091505b50506011549091506000906001600160a01b03166111f460646110bf8860016121b6565b604051600081818185875af1925050503d8060008114611230576040519150601f19603f3d011682016040523d82523d6000602084013e611235565b606091505b505090508380156112435750825b801561124c5750815b80156112555750805b6112965760405162461bcd60e51b81526020600482015260126024820152712bb4ba34323930bbb0b6103330b4b632b21760711b6044820152606401610a39565b5050505050565b600a546001600160a01b031633146112c75760405162461bcd60e51b8152600401610a3990612dca565b600e80546001600160a01b0319166001600160a01b0383169081179091556040519081527f1354f2ed7ad63d510fe05b011c0f4585cc0503e5f2a9cf0ac0b2e7dc80127d5d90602001610be8565b60606001805461094190612d8f565b6001600160a01b03821633141561137d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610a39565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60155460ff1661140b5760405162461bcd60e51b8152600401610a3990612e66565b60008111801561141d57506012548111155b6114695760405162461bcd60e51b815260206004820152601e60248201527f506572207472616e73616374696f6e206c696d697420657863656564656400006044820152606401610a39565b61147b67013fbe85edc90000826121b6565b34146114c95760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f7272656374006044820152606401610a39565b601354336000908152601760205260409020546114e690836121ce565b11156115345760405162461bcd60e51b815260206004820152601960248201527f5065722077616c6c6572206c696d6974206578636565646564000000000000006044820152606401610a39565b60005b81811015610d915761115c61154b60085490565b1015611593576115633361155e60085490565b6121da565b3360009081526017602052604090205461157e9060016121ce565b336000908152601760205260409020556115ed565b6015805460ff19811660ff90911615179055336108fc6115c567013fbe85edc900006115bf86866121f4565b906121b6565b6040518115909202916000818181858888f19350505050158015610b6f573d6000803e3d6000fd5b806115f781612ec1565b915050611537565b6116093383611f14565b6116255760405162461bcd60e51b8152600401610a3990612dff565b61163184848484612200565b50505050565b6000818152600260205260409020546060906001600160a01b03166116b65760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610a39565b60006116c0612233565b905060008151116116e0576040518060200160405280600081525061170b565b806116ea84612242565b6040516020016116fb929190612edc565b6040516020818303038152906040525b9392505050565b600a546001600160a01b0316331461173c5760405162461bcd60e51b8152600401610a3990612dca565b6015805462ff0000198116620100009182900460ff1615909102179055565b601554339062010000900460ff166117855760405162461bcd60e51b8152600401610a3990612e66565b600084118015611796575060028411155b6117e25760405162461bcd60e51b815260206004820181905260248201527f43616e206f6e6c79206d696e74203220746f6b656e7320617420612074696d656044820152606401610a39565b6117f366f8b0a10e470000856121b6565b34146118415760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f7272656374006044820152606401610a39565b3360009081526017602052604090205460029061185e90866121ce565b11156118bf5760405162461bcd60e51b815260206004820152602a60248201527f4d61782032206d696e747320616c6c6f776564207065722077686974656c69736044820152691d1959081dd85b1b195d60b21b6064820152608401610a39565b61193683838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050600c546040516bffffffffffffffffffffffff19606088901b16602082015290925060340190505b60405160208183030381529060405280519060200120612340565b6119725760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610a39565b60005b84811015611a425761115c61198960085490565b10156119cc5761199c3361155e60085490565b336000908152601760205260409020546119b79060016121ce565b33600090815260176020526040902055611a30565b6015805462ff0000198116620100009182900460ff1615909102179055336108fc611a0266f8b0a10e4700006115bf89866121f4565b6040518115909202916000818181858888f19350505050158015611a2a573d6000803e3d6000fd5b50611a42565b80611a3a81612ec1565b915050611975565b506040516001600160a01b03821681527f67c400238edbf2cfe078e9c46b03af4a14f535dafde7829c4ebd8ffc76448bee9060200160405180910390a150505050565b60188054611a9290612d8f565b80601f0160208091040260200160405190810160405280929190818152602001828054611abe90612d8f565b8015611b0b5780601f10611ae057610100808354040283529160200191611b0b565b820191906000526020600020905b815481529060010190602001808311611aee57829003601f168201915b505050505081565b600a546001600160a01b03163314611b3d5760405162461bcd60e51b8152600401610a3990612dca565b600d8190556040518181527f92e8a31a1b5397f82bbae03aad039df87f6af7ecbd505eb7351d2dda5a33aa8390602001610be8565b600a546001600160a01b03163314611b9c5760405162461bcd60e51b8152600401610a3990612dca565b6001600160a01b038116611c015760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a39565b611c0a816123ef565b50565b601554610100900460ff16611c785760405162461bcd60e51b815260206004820152602b60248201527f476976656177617973206d7573742062652061637469766520746f20636c616960448201526a369026b2ba30a637b9323d60a91b6064820152608401610a39565b33600090815260176020526040902054600190611c9590826121ce565b1115611cf65760405162461bcd60e51b815260206004820152602a60248201527f4d61782031206d696e747320616c6c6f776564207065722077686974656c69736044820152691d1959081dd85b1b195d60b21b6064820152608401610a39565b611d5582828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050600d546040516bffffffffffffffffffffffff193360601b166020820152909250603401905061191b565b611d915760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610a39565b611d9e3361155e60085490565b33600090815260176020526040902054611db99060016121ce565b33600090815260176020526040902055601454611dd79060016121f4565b6014555050565b600a546001600160a01b03163314611e085760405162461bcd60e51b8152600401610a3990612dca565b601180546001600160a01b0319166001600160a01b0383169081179091556040519081527f89e6a58e4bc2c31cd8683e43e00e307d1dad49adef29ed929e68eb02a39c7d5d90602001610be8565b60006001600160e01b031982166380ac58cd60e01b1480611e8757506001600160e01b03198216635b5e139f60e01b145b8061092c57506301ffc9a760e01b6001600160e01b031983161461092c565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611edb82610edf565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600260205260408120546001600160a01b0316611f8d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610a39565b6000611f9883610edf565b9050806001600160a01b0316846001600160a01b03161480611fd35750836001600160a01b0316611fc8846109c4565b6001600160a01b0316145b8061200357506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661201e82610edf565b6001600160a01b0316146120865760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610a39565b6001600160a01b0382166120e85760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610a39565b6120f3838383612441565b6120fe600082611ea6565b6001600160a01b0383166000908152600360205260408120805460019290612127908490612f0b565b90915550506001600160a01b0382166000908152600360205260408120805460019290612155908490612f22565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061170b8284612f3a565b600061170b8284612f6f565b600061170b8284612f22565b610d918282604051806020016040528060008152506124f9565b600061170b8284612f0b565b61220b84848461200b565b6122178484848461252c565b6116315760405162461bcd60e51b8152600401610a3990612f83565b60606018805461094190612d8f565b6060816122665750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612290578061227a81612ec1565b91506122899050600a83612f6f565b915061226a565b60008167ffffffffffffffff8111156122ab576122ab612af5565b6040519080825280601f01601f1916602001820160405280156122d5576020820181803683370190505b5090505b8415612003576122ea600183612f0b565b91506122f7600a86612fd5565b612302906030612f22565b60f81b81838151811061231757612317612e50565b60200101906001600160f81b031916908160001a905350612339600a86612f6f565b94506122d9565b600081815b85518110156123e457600086828151811061236257612362612e50565b602002602001015190508083116123a45760408051602081018590529081018290526060016040516020818303038152906040528051906020012092506123d1565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b50806123dc81612ec1565b915050612345565b509092149392505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03831661249c5761249781600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6124bf565b816001600160a01b0316836001600160a01b0316146124bf576124bf838261262a565b6001600160a01b0382166124d657610b6f816126c7565b826001600160a01b0316826001600160a01b031614610b6f57610b6f8282612776565b61250383836127ba565b612510600084848461252c565b610b6f5760405162461bcd60e51b8152600401610a3990612f83565b60006001600160a01b0384163b1561261f57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612570903390899088908890600401612fe9565b6020604051808303816000875af19250505080156125ab575060408051601f3d908101601f191682019092526125a891810190613026565b60015b612605573d8080156125d9576040519150601f19603f3d011682016040523d82523d6000602084013e6125de565b606091505b5080516125fd5760405162461bcd60e51b8152600401610a3990612f83565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612003565b506001949350505050565b6000600161263784610f9d565b6126419190612f0b565b600083815260076020526040902054909150808214612694576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906126d990600190612f0b565b6000838152600960205260408120546008805493945090928490811061270157612701612e50565b90600052602060002001549050806008838154811061272257612722612e50565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061275a5761275a613043565b6001900381819060005260206000200160009055905550505050565b600061278183610f9d565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b0382166128105760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610a39565b6000818152600260205260409020546001600160a01b0316156128755760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610a39565b61288160008383612441565b6001600160a01b03821660009081526003602052604081208054600192906128aa908490612f22565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b82805461291490612d8f565b90600052602060002090601f016020900481019282612936576000855561297c565b82601f1061294f57805160ff191683800117855561297c565b8280016001018555821561297c579182015b8281111561297c578251825591602001919060010190612961565b5061298892915061298c565b5090565b5b80821115612988576000815560010161298d565b6001600160e01b031981168114611c0a57600080fd5b6000602082840312156129c957600080fd5b813561170b816129a1565b60005b838110156129ef5781810151838201526020016129d7565b838111156116315750506000910152565b60008151808452612a188160208601602086016129d4565b601f01601f19169290920160200192915050565b60208152600061170b6020830184612a00565b600060208284031215612a5157600080fd5b5035919050565b80356001600160a01b0381168114612a6f57600080fd5b919050565b60008060408385031215612a8757600080fd5b612a9083612a58565b946020939093013593505050565b600060208284031215612ab057600080fd5b61170b82612a58565b600080600060608486031215612ace57600080fd5b612ad784612a58565b9250612ae560208501612a58565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612b2657612b26612af5565b604051601f8501601f19908116603f01168101908282118183101715612b4e57612b4e612af5565b81604052809350858152868686011115612b6757600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215612b9357600080fd5b813567ffffffffffffffff811115612baa57600080fd5b8201601f81018413612bbb57600080fd5b61200384823560208401612b0b565b60008060408385031215612bdd57600080fd5b612be683612a58565b915060208301358015158114612bfb57600080fd5b809150509250929050565b60008060008060808587031215612c1c57600080fd5b612c2585612a58565b9350612c3360208601612a58565b925060408501359150606085013567ffffffffffffffff811115612c5657600080fd5b8501601f81018713612c6757600080fd5b612c7687823560208401612b0b565b91505092959194509250565b60008083601f840112612c9457600080fd5b50813567ffffffffffffffff811115612cac57600080fd5b6020830191508360208260051b8501011115612cc757600080fd5b9250929050565b600080600060408486031215612ce357600080fd5b83359250602084013567ffffffffffffffff811115612d0157600080fd5b612d0d86828701612c82565b9497909650939450505050565b60008060408385031215612d2d57600080fd5b612d3683612a58565b9150612d4460208401612a58565b90509250929050565b60008060208385031215612d6057600080fd5b823567ffffffffffffffff811115612d7757600080fd5b612d8385828601612c82565b90969095509350505050565b600181811c90821680612da357607f821691505b60208210811415612dc457634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60208082526025908201527f53616c65206d7573742062652061637469766520746f206d696e74204d6574616040820152642637b9323d60d91b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b6000600019821415612ed557612ed5612eab565b5060010190565b60008351612eee8184602088016129d4565b835190830190612f028183602088016129d4565b01949350505050565b600082821015612f1d57612f1d612eab565b500390565b60008219821115612f3557612f35612eab565b500190565b6000816000190483118215151615612f5457612f54612eab565b500290565b634e487b7160e01b600052601260045260246000fd5b600082612f7e57612f7e612f59565b500490565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600082612fe457612fe4612f59565b500690565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061301c90830184612a00565b9695505050505050565b60006020828403121561303857600080fd5b815161170b816129a1565b634e487b7160e01b600052603160045260246000fdfea264697066735822122025134eb6287c6609848b170e5348a89965c5f87976b716fd873a138ed26d4a8e64736f6c634300080a0033

Deployed Bytecode Sourcemap

62423:6876:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63121:44;;;;;;;;;;;;63161:4;63121:44;;;;;160:25:1;;;148:2;133:18;63121:44:0;;;;;;;;56219:224;;;;;;;;;;-1:-1:-1;56219:224:0;;;;;:::i;:::-;;:::i;:::-;;;747:14:1;;740:22;722:41;;710:2;695:18;56219:224:0;582:187:1;44141:100:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;45700:221::-;;;;;;;;;;-1:-1:-1;45700:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1874:32:1;;;1856:51;;1844:2;1829:18;45700:221:0;1710:203:1;45223:411:0;;;;;;;;;;-1:-1:-1;45223:411:0;;;;;:::i;:::-;;:::i;:::-;;62680:67;;;;;;;;;;-1:-1:-1;62680:67:0;;;;-1:-1:-1;;;;;62680:67:0;;;63288:41;;;;;;;;;;-1:-1:-1;63288:41:0;;;;;;;;;;;68216:142;;;;;;;;;;-1:-1:-1;68216:142:0;;;;;:::i;:::-;;:::i;56867:113::-;;;;;;;;;;-1:-1:-1;56955:10:0;:17;56867:113;;62606:67;;;;;;;;;;-1:-1:-1;62606:67:0;;;;-1:-1:-1;;;;;62606:67:0;;;68366:142;;;;;;;;;;-1:-1:-1;68366:142:0;;;;;:::i;:::-;;:::i;46590:339::-;;;;;;;;;;-1:-1:-1;46590:339:0;;;;;:::i;:::-;;:::i;64188:115::-;;;;;;;;;;-1:-1:-1;64188:115:0;;;;;:::i;:::-;;:::i;64069:113::-;;;;;;;;;;-1:-1:-1;64069:113:0;;;;;:::i;:::-;;:::i;62548:25::-;;;;;;;;;;;;;;;;65337:89;;;;;;;;;;;;;:::i;62754:67::-;;;;;;;;;;-1:-1:-1;62754:67:0;;;;-1:-1:-1;;;;;62754:67:0;;;63924:140;;;;;;;;;;;;;:::i;63076:38::-;;;;;;;;;;;;;;;;47000:185;;;;;;;;;;-1:-1:-1;47000:185:0;;;;;:::i;:::-;;:::i;66669:158::-;;;;;;;;;;-1:-1:-1;66669:158:0;;;;;:::i;:::-;;:::i;57057:233::-;;;;;;;;;;-1:-1:-1;57057:233:0;;;;;:::i;:::-;;:::i;65226:101::-;;;;;;;;;;-1:-1:-1;65226:101:0;;;;;:::i;:::-;;:::i;43661:239::-;;;;;;;;;;-1:-1:-1;43661:239:0;;;;;:::i;:::-;;:::i;65562:92::-;;;;;;;;;;;;;:::i;43391:208::-;;;;;;;;;;-1:-1:-1;43391:208:0;;;;;:::i;:::-;;:::i;62828:67::-;;;;;;;;;;-1:-1:-1;62828:67:0;;;;-1:-1:-1;;;;;62828:67:0;;;63172:34;;;;;;;;;;;;;;;;43965:109;;;;;;;;;;-1:-1:-1;43965:109:0;;;;;:::i;:::-;44023:7;44050:16;;;:7;:16;;;;;;-1:-1:-1;;;;;44050:16:0;;43965:109;62969:60;;;;;;;;;;;;63012:17;62969:60;;68670:626;;;;;;;;;;;;;:::i;23056:87::-;;;;;;;;;;-1:-1:-1;23129:6:0;;-1:-1:-1;;;;;23129:6:0;23056:87;;68062:142;;;;;;;;;;-1:-1:-1;68062:142:0;;;;;:::i;:::-;;:::i;44310:104::-;;;;;;;;;;;;;:::i;45993:295::-;;;;;;;;;;-1:-1:-1;45993:295:0;;;;;:::i;:::-;;:::i;65672:953::-;;;;;;:::i;:::-;;:::i;47256:328::-;;;;;;;;;;-1:-1:-1;47256:328:0;;;;;:::i;:::-;;:::i;63251:33::-;;;;;;;;;;-1:-1:-1;63251:33:0;;;;;;;;;;;44485:334;;;;;;;;;;-1:-1:-1;44485:334:0;;;;;:::i;:::-;;:::i;65434:116::-;;;;;;;;;;;;;:::i;66837:1216::-;;;;;;:::i;:::-;;:::i;63829:26::-;;;;;;;;;;;;;:::i;62904:58::-;;;;;;;;;;;;62945:17;62904:58;;46359:164;;;;;;;;;;-1:-1:-1;46359:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;46480:25:0;;;46456:4;46480:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;46359:164;63215:32;;;;;;;;;;-1:-1:-1;63215:32:0;;;;;;;;64311:160;;;;;;;;;;-1:-1:-1;64311:160:0;;;;;:::i;:::-;;:::i;23962:192::-;;;;;;;;;;-1:-1:-1;23962:192:0;;;;;:::i;:::-;;:::i;64479:616::-;;;;;;;;;;-1:-1:-1;64479:616:0;;;;;:::i;:::-;;:::i;63036:36::-;;;;;;;;;;;;;;;;68520:142;;;;;;;;;;-1:-1:-1;68520:142:0;;;;;:::i;:::-;;:::i;62577:25::-;;;;;;;;;;;;;;;;56219:224;56321:4;-1:-1:-1;;;;;;56345:50:0;;-1:-1:-1;;;56345:50:0;;:90;;;56399:36;56423:11;56399:23;:36::i;:::-;56338:97;56219:224;-1:-1:-1;;56219:224:0:o;44141:100::-;44195:13;44228:5;44221:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44141:100;:::o;45700:221::-;45776:7;49183:16;;;:7;:16;;;;;;-1:-1:-1;;;;;49183:16:0;45796:73;;;;-1:-1:-1;;;45796:73:0;;7671:2:1;45796:73:0;;;7653:21:1;7710:2;7690:18;;;7683:30;7749:34;7729:18;;;7722:62;-1:-1:-1;;;7800:18:1;;;7793:42;7852:19;;45796:73:0;;;;;;;;;-1:-1:-1;45889:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;45889:24:0;;45700:221::o;45223:411::-;45304:13;45320:23;45335:7;45320:14;:23::i;:::-;45304:39;;45368:5;-1:-1:-1;;;;;45362:11:0;:2;-1:-1:-1;;;;;45362:11:0;;;45354:57;;;;-1:-1:-1;;;45354:57:0;;8084:2:1;45354:57:0;;;8066:21:1;8123:2;8103:18;;;8096:30;8162:34;8142:18;;;8135:62;-1:-1:-1;;;8213:18:1;;;8206:31;8254:19;;45354:57:0;7882:397:1;45354:57:0;21924:10;-1:-1:-1;;;;;45446:21:0;;;;:62;;-1:-1:-1;45471:37:0;45488:5;21924:10;46359:164;:::i;45471:37::-;45424:168;;;;-1:-1:-1;;;45424:168:0;;8486:2:1;45424:168:0;;;8468:21:1;8525:2;8505:18;;;8498:30;8564:34;8544:18;;;8537:62;8635:26;8615:18;;;8608:54;8679:19;;45424:168:0;8284:420:1;45424:168:0;45605:21;45614:2;45618:7;45605:8;:21::i;:::-;45293:341;45223:411;;:::o;68216:142::-;23129:6;;-1:-1:-1;;;;;23129:6:0;21924:10;23276:23;23268:68;;;;-1:-1:-1;;;23268:68:0;;;;;;;:::i;:::-;68285:7:::1;:18:::0;;-1:-1:-1;;;;;;68285:18:0::1;-1:-1:-1::0;;;;;68285:18:0;::::1;::::0;;::::1;::::0;;;68319:31:::1;::::0;1856:51:1;;;68319:31:0::1;::::0;1844:2:1;1829:18;68319:31:0::1;;;;;;;;68216:142:::0;:::o;68366:::-;23129:6;;-1:-1:-1;;;;;23129:6:0;21924:10;23276:23;23268:68;;;;-1:-1:-1;;;23268:68:0;;;;;;;:::i;:::-;68435:7:::1;:18:::0;;-1:-1:-1;;;;;;68435:18:0::1;-1:-1:-1::0;;;;;68435:18:0;::::1;::::0;;::::1;::::0;;;68469:31:::1;::::0;1856:51:1;;;68469:31:0::1;::::0;1844:2:1;1829:18;68469:31:0::1;1710:203:1::0;46590:339:0;46785:41;21924:10;46818:7;46785:18;:41::i;:::-;46777:103;;;;-1:-1:-1;;;46777:103:0;;;;;;;:::i;:::-;46893:28;46903:4;46909:2;46913:7;46893:9;:28::i;64188:115::-;23129:6;;-1:-1:-1;;;;;23129:6:0;21924:10;23276:23;23268:68;;;;-1:-1:-1;;;23268:68:0;;;;;;;:::i;:::-;64260:22:::1;:35:::0;64188:115::o;64069:113::-;23129:6;;-1:-1:-1;;;;;23129:6:0;21924:10;23276:23;23268:68;;;;-1:-1:-1;;;23268:68:0;;;;;;;:::i;:::-;64141:20:::1;:33:::0;64069:113::o;65337:89::-;23129:6;;-1:-1:-1;;;;;23129:6:0;21924:10;23276:23;23268:68;;;;-1:-1:-1;;;23268:68:0;;;;;;;:::i;:::-;65406:12:::1;::::0;;-1:-1:-1;;65390:28:0;::::1;65406:12;::::0;;::::1;65405:13;65390:28;::::0;;65337:89::o;63924:140::-;23129:6;;-1:-1:-1;;;;;23129:6:0;21924:10;23276:23;23268:68;;;;-1:-1:-1;;;23268:68:0;;;;;;;:::i;:::-;64019:37:::1;::::0;63987:21:::1;::::0;64027:10:::1;::::0;64019:37;::::1;;;::::0;63987:21;;63972:12:::1;64019:37:::0;63972:12;64019:37;63987:21;64027:10;64019:37;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;63961:103;63924:140::o:0;47000:185::-;47138:39;47155:4;47161:2;47165:7;47138:39;;;;;;;;;;;;:16;:39::i;66669:158::-;23129:6;;-1:-1:-1;;;;;23129:6:0;21924:10;23276:23;23268:68;;;;-1:-1:-1;;;23268:68:0;;;;;;;:::i;:::-;66748:10:::1;:26:::0;;;66790:29:::1;::::0;160:25:1;;;66790:29:0::1;::::0;148:2:1;133:18;66790:29:0::1;14:177:1::0;57057:233:0;57132:7;57168:30;56955:10;:17;;56867:113;57168:30;57160:5;:38;57152:95;;;;-1:-1:-1;;;57152:95:0;;9690:2:1;57152:95:0;;;9672:21:1;9729:2;9709:18;;;9702:30;9768:34;9748:18;;;9741:62;-1:-1:-1;;;9819:18:1;;;9812:42;9871:19;;57152:95:0;9488:408:1;57152:95:0;57265:10;57276:5;57265:17;;;;;;;;:::i;:::-;;;;;;;;;57258:24;;57057:233;;;:::o;65226:101::-;23129:6;;-1:-1:-1;;;;;23129:6:0;21924:10;23276:23;23268:68;;;;-1:-1:-1;;;23268:68:0;;;;;;;:::i;:::-;65297:22;;::::1;::::0;:12:::1;::::0;:22:::1;::::0;::::1;::::0;::::1;:::i;43661:239::-:0;43733:7;43769:16;;;:7;:16;;;;;;-1:-1:-1;;;;;43769:16:0;43804:19;43796:73;;;;-1:-1:-1;;;43796:73:0;;10235:2:1;43796:73:0;;;10217:21:1;10274:2;10254:18;;;10247:30;10313:34;10293:18;;;10286:62;-1:-1:-1;;;10364:18:1;;;10357:39;10413:19;;43796:73:0;10033:405:1;65562:92:0;23129:6;;-1:-1:-1;;;;;23129:6:0;21924:10;23276:23;23268:68;;;;-1:-1:-1;;;23268:68:0;;;;;;;:::i;:::-;65633:13:::1;::::0;;-1:-1:-1;;65616:30:0;::::1;65633:13;::::0;;;::::1;;;65632:14;65616:30:::0;;::::1;;::::0;;65562:92::o;43391:208::-;43463:7;-1:-1:-1;;;;;43491:19:0;;43483:74;;;;-1:-1:-1;;;43483:74:0;;10645:2:1;43483:74:0;;;10627:21:1;10684:2;10664:18;;;10657:30;10723:34;10703:18;;;10696:62;-1:-1:-1;;;10774:18:1;;;10767:40;10824:19;;43483:74:0;10443:406:1;43483:74:0;-1:-1:-1;;;;;;43575:16:0;;;;;:9;:16;;;;;;;43391:208::o;68670:626::-;23129:6;;-1:-1:-1;;;;;23129:6:0;21924:10;23276:23;23268:68;;;;-1:-1:-1;;;23268:68:0;;;;;;;:::i;:::-;68755:1:::1;68731:21;:25;68723:61;;;::::0;-1:-1:-1;;;68723:61:0;;11056:2:1;68723:61:0::1;::::0;::::1;11038:21:1::0;11095:2;11075:18;;;11068:30;11134:25;11114:18;;;11107:53;11177:18;;68723:61:0::1;10854:347:1::0;68723:61:0::1;68871:7;::::0;68813:21:::1;::::0;68795:15:::1;::::0;-1:-1:-1;;;;;68871:7:0::1;68891:24;68911:3;68891:15;68813:21:::0;68903:2:::1;68891:11;:15::i;:::-;:19:::0;::::1;:24::i;:::-;68871:49;::::0;::::1;::::0;;;;;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;68957:7:0::1;::::0;68845:75;;-1:-1:-1;68932:19:0::1;::::0;-1:-1:-1;;;;;68957:7:0::1;68977:24;68997:3;68977:15;:7:::0;68989:2:::1;68977:11;:15::i;:24::-;68957:49;::::0;::::1;::::0;;;;;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;69043:7:0::1;::::0;68931:75;;-1:-1:-1;69018:19:0::1;::::0;-1:-1:-1;;;;;69043:7:0::1;69063:23;69082:3;69063:14;:7:::0;69075:1:::1;69063:11;:14::i;:23::-;69043:48;::::0;::::1;::::0;;;;;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;69128:7:0::1;::::0;69017:74;;-1:-1:-1;69103:19:0::1;::::0;-1:-1:-1;;;;;69128:7:0::1;69148:23;69167:3;69148:14;:7:::0;69128;69148:11:::1;:14::i;:23::-;69128:48;::::0;::::1;::::0;;;;;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69102:74;;;69197:14;:32;;;;;69215:14;69197:32;:50;;;;;69233:14;69197:50;:68;;;;;69251:14;69197:68;69189:99;;;::::0;-1:-1:-1;;;69189:99:0;;11618:2:1;69189:99:0::1;::::0;::::1;11600:21:1::0;11657:2;11637:18;;;11630:30;-1:-1:-1;;;11676:18:1;;;11669:48;11734:18;;69189:99:0::1;11416:342:1::0;69189:99:0::1;68712:584;;;;;68670:626::o:0;68062:142::-;23129:6;;-1:-1:-1;;;;;23129:6:0;21924:10;23276:23;23268:68;;;;-1:-1:-1;;;23268:68:0;;;;;;;:::i;:::-;68131:7:::1;:18:::0;;-1:-1:-1;;;;;;68131:18:0::1;-1:-1:-1::0;;;;;68131:18:0;::::1;::::0;;::::1;::::0;;;68165:31:::1;::::0;1856:51:1;;;68165:31:0::1;::::0;1844:2:1;1829:18;68165:31:0::1;1710:203:1::0;44310:104:0;44366:13;44399:7;44392:14;;;;;:::i;45993:295::-;-1:-1:-1;;;;;46096:24:0;;21924:10;46096:24;;46088:62;;;;-1:-1:-1;;;46088:62:0;;11965:2:1;46088:62:0;;;11947:21:1;12004:2;11984:18;;;11977:30;12043:27;12023:18;;;12016:55;12088:18;;46088:62:0;11763:349:1;46088:62:0;21924:10;46163:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;46163:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;46163:53:0;;;;;;;;;;46232:48;;722:41:1;;;46163:42:0;;21924:10;46232:48;;695:18:1;46232:48:0;;;;;;;45993:295;;:::o;65672:953::-;65750:12;;;;65742:62;;;;-1:-1:-1;;;65742:62:0;;;;;;;:::i;:::-;65840:1;65823:14;:18;:60;;;;;65863:20;;65845:14;:38;;65823:60;65815:103;;;;-1:-1:-1;;;65815:103:0;;12725:2:1;65815:103:0;;;12707:21:1;12764:2;12744:18;;;12737:30;12803:32;12783:18;;;12776:60;12853:18;;65815:103:0;12523:354:1;65815:103:0;65950:34;62945:17;65969:14;65950:18;:34::i;:::-;65937:9;:47;65929:91;;;;-1:-1:-1;;;65929:91:0;;13084:2:1;65929:91:0;;;13066:21:1;13123:2;13103:18;;;13096:30;13162:33;13142:18;;;13135:61;13213:18;;65929:91:0;12882:355:1;65929:91:0;66096:22;;66061:10;66039:33;;;;:21;:33;;;;;;:53;;66077:14;66039:37;:53::i;:::-;:79;;66031:116;;;;-1:-1:-1;;;66031:116:0;;13444:2:1;66031:116:0;;;13426:21:1;13483:2;13463:18;;;13456:30;13522:27;13502:18;;;13495:55;13567:18;;66031:116:0;13242:349:1;66031:116:0;66172:6;66168:450;66188:14;66184:1;:18;66168:450;;;63161:4;66228:13;56955:10;:17;;56867:113;66228:13;:29;66224:383;;;66278:36;66288:10;66300:13;56955:10;:17;;56867:113;66300:13;66278:9;:36::i;:::-;66391:10;66369:33;;;;:21;:33;;;;;;:40;;66407:1;66369:37;:40::i;:::-;66355:10;66333:33;;;;:21;:33;;;;;:76;66224:383;;;66465:12;;;-1:-1:-1;;66449:28:0;;66465:12;;;;66464:13;66449:28;;;66504:10;66496:71;66525:41;62945:17;66525:21;:14;66544:1;66525:18;:21::i;:::-;:25;;:41::i;:::-;66496:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66224:383;66204:3;;;;:::i;:::-;;;;66168:450;;47256:328;47431:41;21924:10;47464:7;47431:18;:41::i;:::-;47423:103;;;;-1:-1:-1;;;47423:103:0;;;;;;;:::i;:::-;47537:39;47551:4;47557:2;47561:7;47570:5;47537:13;:39::i;:::-;47256:328;;;;:::o;44485:334::-;49159:4;49183:16;;;:7;:16;;;;;;44558:13;;-1:-1:-1;;;;;49183:16:0;44584:76;;;;-1:-1:-1;;;44584:76:0;;14070:2:1;44584:76:0;;;14052:21:1;14109:2;14089:18;;;14082:30;14148:34;14128:18;;;14121:62;-1:-1:-1;;;14199:18:1;;;14192:45;14254:19;;44584:76:0;13868:411:1;44584:76:0;44673:21;44697:10;:8;:10::i;:::-;44673:34;;44749:1;44731:7;44725:21;:25;:86;;;;;;;;;;;;;;;;;44777:7;44786:18;:7;:16;:18::i;:::-;44760:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;44725:86;44718:93;44485:334;-1:-1:-1;;;44485:334:0:o;65434:116::-;23129:6;;-1:-1:-1;;;;;23129:6:0;21924:10;23276:23;23268:68;;;;-1:-1:-1;;;23268:68:0;;;;;;;:::i;:::-;65521:21:::1;::::0;;-1:-1:-1;;65496:46:0;::::1;65521:21:::0;;;;::::1;;;65520:22;65496:46:::0;;::::1;;::::0;;65434:116::o;66837:1216::-;66991:21;;66962:10;;66991:21;;;;;66983:71;;;;-1:-1:-1;;;66983:71:0;;;;;;;:::i;:::-;67090:1;67073:14;:18;:41;;;;;67113:1;67095:14;:19;;67073:41;67065:86;;;;-1:-1:-1;;;67065:86:0;;14961:2:1;67065:86:0;;;14943:21:1;;;14980:18;;;14973:30;15039:34;15019:18;;;15012:62;15091:18;;67065:86:0;14759:356:1;67065:86:0;67183:36;63012:17;67204:14;67183:20;:36::i;:::-;67170:9;:49;67162:93;;;;-1:-1:-1;;;67162:93:0;;13084:2:1;67162:93:0;;;13066:21:1;13123:2;13103:18;;;13096:30;13162:33;13142:18;;;13135:61;13213:18;;67162:93:0;12882:355:1;67162:93:0;67296:10;67274:33;;;;:21;:33;;;;;;67331:1;;67274:53;;67312:14;67274:37;:53::i;:::-;:58;;67266:112;;;;-1:-1:-1;;;67266:112:0;;15322:2:1;67266:112:0;;;15304:21:1;15361:2;15341:18;;;15334:30;15400:34;15380:18;;;15373:62;-1:-1:-1;;;15451:18:1;;;15444:40;15501:19;;67266:112:0;15120:406:1;67266:112:0;67435:82;67454:11;;67435:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;67467:10:0;;67490:23;;-1:-1:-1;;15680:2:1;15676:15;;;15672:53;67490:23:0;;;15660:66:1;67467:10:0;;-1:-1:-1;15742:12:1;;;-1:-1:-1;67490:23:0;;;;;;;;;;;;;67480:34;;;;;;67435:18;:82::i;:::-;67427:108;;;;-1:-1:-1;;;67427:108:0;;15967:2:1;67427:108:0;;;15949:21:1;16006:2;15986:18;;;15979:30;-1:-1:-1;;;16025:18:1;;;16018:43;16078:18;;67427:108:0;15765:337:1;67427:108:0;67548:6;67544:462;67564:14;67560:1;:18;67544:462;;;63161:4;67604:13;56955:10;:17;;56867:113;67604:13;:29;67600:395;;;67654:36;67664:10;67676:13;56955:10;:17;;56867:113;67654:36;67767:10;67745:33;;;;:21;:33;;;;;;:40;;67783:1;67745:37;:40::i;:::-;67731:10;67709:33;;;;:21;:33;;;;;:76;67600:395;;;67842:21;;;-1:-1:-1;;67817:46:0;;67842:21;;;;;;;67841:22;67817:46;;;;;;67890:10;67882:73;67911:43;63012:17;67911:21;:14;67930:1;67911:18;:21::i;:43::-;67882:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67974:5;;67600:395;67580:3;;;;:::i;:::-;;;;67544:462;;;-1:-1:-1;68023:22:0;;-1:-1:-1;;;;;1874:32:1;;1856:51;;68023:22:0;;1844:2:1;1829:18;68023:22:0;;;;;;;66935:1118;66837:1216;;;:::o;63829:26::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;64311:160::-;23129:6;;-1:-1:-1;;;;;23129:6:0;21924:10;23276:23;23268:68;;;;-1:-1:-1;;;23268:68:0;;;;;;;:::i;:::-;64391:10:::1;:26:::0;;;64433:30:::1;::::0;160:25:1;;;64433:30:0::1;::::0;148:2:1;133:18;64433:30:0::1;14:177:1::0;23962:192:0;23129:6;;-1:-1:-1;;;;;23129:6:0;21924:10;23276:23;23268:68;;;;-1:-1:-1;;;23268:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;24051:22:0;::::1;24043:73;;;::::0;-1:-1:-1;;;24043:73:0;;16309:2:1;24043:73:0::1;::::0;::::1;16291:21:1::0;16348:2;16328:18;;;16321:30;16387:34;16367:18;;;16360:62;-1:-1:-1;;;16438:18:1;;;16431:36;16484:19;;24043:73:0::1;16107:402:1::0;24043:73:0::1;24127:19;24137:8;24127:9;:19::i;:::-;23962:192:::0;:::o;64479:616::-;64569:13;;;;;;;64561:69;;;;-1:-1:-1;;;64561:69:0;;16716:2:1;64561:69:0;;;16698:21:1;16755:2;16735:18;;;16728:30;16794:34;16774:18;;;16767:62;-1:-1:-1;;;16845:18:1;;;16838:41;16896:19;;64561:69:0;16514:407:1;64561:69:0;64671:10;64649:33;;;;:21;:33;;;;;;64693:1;;64649:40;;64693:1;64649:37;:40::i;:::-;:45;;64641:99;;;;-1:-1:-1;;;64641:99:0;;17128:2:1;64641:99:0;;;17110:21:1;17167:2;17147:18;;;17140:30;17206:34;17186:18;;;17179:62;-1:-1:-1;;;17257:18:1;;;17250:40;17307:19;;64641:99:0;16926:406:1;64641:99:0;64797:87;64816:11;;64797:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;64829:10:0;;64852:28;;-1:-1:-1;;64869:10:0;15680:2:1;15676:15;15672:53;64852:28:0;;;15660:66:1;64829:10:0;;-1:-1:-1;15742:12:1;;;-1:-1:-1;64852:28:0;15531:229:1;64797:87:0;64789:113;;;;-1:-1:-1;;;64789:113:0;;15967:2:1;64789:113:0;;;15949:21:1;16006:2;15986:18;;;15979:30;-1:-1:-1;;;16025:18:1;;;16018:43;16078:18;;64789:113:0;15765:337:1;64789:113:0;64917:36;64927:10;64939:13;56955:10;:17;;56867:113;64917:36;65016:10;64994:33;;;;:21;:33;;;;;;:40;;65032:1;64994:37;:40::i;:::-;64980:10;64958:33;;;;:21;:33;;;;;:76;65064:16;;:23;;65085:1;65064:20;:23::i;:::-;65045:16;:42;-1:-1:-1;;64479:616:0:o;68520:142::-;23129:6;;-1:-1:-1;;;;;23129:6:0;21924:10;23276:23;23268:68;;;;-1:-1:-1;;;23268:68:0;;;;;;;:::i;:::-;68589:7:::1;:18:::0;;-1:-1:-1;;;;;;68589:18:0::1;-1:-1:-1::0;;;;;68589:18:0;::::1;::::0;;::::1;::::0;;;68623:31:::1;::::0;1856:51:1;;;68623:31:0::1;::::0;1844:2:1;1829:18;68623:31:0::1;1710:203:1::0;43034:293:0;43136:4;-1:-1:-1;;;;;;43169:40:0;;-1:-1:-1;;;43169:40:0;;:101;;-1:-1:-1;;;;;;;43222:48:0;;-1:-1:-1;;;43222:48:0;43169:101;:150;;;-1:-1:-1;;;;;;;;;;35157:40:0;;;43283:36;35048:157;53094:174;53169:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;53169:29:0;-1:-1:-1;;;;;53169:29:0;;;;;;;;:24;;53223:23;53169:24;53223:14;:23::i;:::-;-1:-1:-1;;;;;53214:46:0;;;;;;;;;;;53094:174;;:::o;49388:348::-;49481:4;49183:16;;;:7;:16;;;;;;-1:-1:-1;;;;;49183:16:0;49498:73;;;;-1:-1:-1;;;49498:73:0;;17539:2:1;49498:73:0;;;17521:21:1;17578:2;17558:18;;;17551:30;17617:34;17597:18;;;17590:62;-1:-1:-1;;;17668:18:1;;;17661:42;17720:19;;49498:73:0;17337:408:1;49498:73:0;49582:13;49598:23;49613:7;49598:14;:23::i;:::-;49582:39;;49651:5;-1:-1:-1;;;;;49640:16:0;:7;-1:-1:-1;;;;;49640:16:0;;:51;;;;49684:7;-1:-1:-1;;;;;49660:31:0;:20;49672:7;49660:11;:20::i;:::-;-1:-1:-1;;;;;49660:31:0;;49640:51;:87;;;-1:-1:-1;;;;;;46480:25:0;;;46456:4;46480:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;49695:32;49632:96;49388:348;-1:-1:-1;;;;49388:348:0:o;52398:578::-;52557:4;-1:-1:-1;;;;;52530:31:0;:23;52545:7;52530:14;:23::i;:::-;-1:-1:-1;;;;;52530:31:0;;52522:85;;;;-1:-1:-1;;;52522:85:0;;17952:2:1;52522:85:0;;;17934:21:1;17991:2;17971:18;;;17964:30;18030:34;18010:18;;;18003:62;-1:-1:-1;;;18081:18:1;;;18074:39;18130:19;;52522:85:0;17750:405:1;52522:85:0;-1:-1:-1;;;;;52626:16:0;;52618:65;;;;-1:-1:-1;;;52618:65:0;;18362:2:1;52618:65:0;;;18344:21:1;18401:2;18381:18;;;18374:30;18440:34;18420:18;;;18413:62;-1:-1:-1;;;18491:18:1;;;18484:34;18535:19;;52618:65:0;18160:400:1;52618:65:0;52696:39;52717:4;52723:2;52727:7;52696:20;:39::i;:::-;52800:29;52817:1;52821:7;52800:8;:29::i;:::-;-1:-1:-1;;;;;52842:15:0;;;;;;:9;:15;;;;;:20;;52861:1;;52842:15;:20;;52861:1;;52842:20;:::i;:::-;;;;-1:-1:-1;;;;;;;52873:13:0;;;;;;:9;:13;;;;;:18;;52890:1;;52873:13;:18;;52890:1;;52873:18;:::i;:::-;;;;-1:-1:-1;;52902:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;52902:21:0;-1:-1:-1;;;;;52902:21:0;;;;;;;;;52941:27;;52902:16;;52941:27;;;;;;;52398:578;;;:::o;15722:98::-;15780:7;15807:5;15811:1;15807;:5;:::i;16121:98::-;16179:7;16206:5;16210:1;16206;:5;:::i;14984:98::-;15042:7;15069:5;15073:1;15069;:5;:::i;50078:110::-;50154:26;50164:2;50168:7;50154:26;;;;;;;;;;;;:9;:26::i;15365:98::-;15423:7;15450:5;15454:1;15450;:5;:::i;48466:315::-;48623:28;48633:4;48639:2;48643:7;48623:9;:28::i;:::-;48670:48;48693:4;48699:2;48703:7;48712:5;48670:22;:48::i;:::-;48662:111;;;;-1:-1:-1;;;48662:111:0;;;;;;;:::i;65105:113::-;65165:13;65198:12;65191:19;;;;;:::i;19460:723::-;19516:13;19737:10;19733:53;;-1:-1:-1;;19764:10:0;;;;;;;;;;;;-1:-1:-1;;;19764:10:0;;;;;19460:723::o;19733:53::-;19811:5;19796:12;19852:78;19859:9;;19852:78;;19885:8;;;;:::i;:::-;;-1:-1:-1;19908:10:0;;-1:-1:-1;19916:2:0;19908:10;;:::i;:::-;;;19852:78;;;19940:19;19972:6;19962:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19962:17:0;;19940:39;;19990:154;19997:10;;19990:154;;20024:11;20034:1;20024:11;;:::i;:::-;;-1:-1:-1;20093:10:0;20101:2;20093:5;:10;:::i;:::-;20080:24;;:2;:24;:::i;:::-;20067:39;;20050:6;20057;20050:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;20050:56:0;;;;;;;;-1:-1:-1;20121:11:0;20130:2;20121:11;;:::i;:::-;;;19990:154;;939:830;1064:4;1104;1064;1121:525;1145:5;:12;1141:1;:16;1121:525;;;1179:20;1202:5;1208:1;1202:8;;;;;;;;:::i;:::-;;;;;;;1179:31;;1247:12;1231;:28;1227:408;;1384:44;;;;;;19951:19:1;;;19986:12;;;19979:28;;;20023:12;;1384:44:0;;;;;;;;;;;;1374:55;;;;;;1359:70;;1227:408;;;1574:44;;;;;;19951:19:1;;;19986:12;;;19979:28;;;20023:12;;1574:44:0;;;;;;;;;;;;1564:55;;;;;;1549:70;;1227:408;-1:-1:-1;1159:3:0;;;;:::i;:::-;;;;1121:525;;;-1:-1:-1;1741:20:0;;;;939:830;-1:-1:-1;;;939:830:0:o;24162:173::-;24237:6;;;-1:-1:-1;;;;;24254:17:0;;;-1:-1:-1;;;;;;24254:17:0;;;;;;;24287:40;;24237:6;;;24254:17;24237:6;;24287:40;;24218:16;;24287:40;24207:128;24162:173;:::o;57903:589::-;-1:-1:-1;;;;;58109:18:0;;58105:187;;58144:40;58176:7;59319:10;:17;;59292:24;;;;:15;:24;;;;;:44;;;59347:24;;;;;;;;;;;;59215:164;58144:40;58105:187;;;58214:2;-1:-1:-1;;;;;58206:10:0;:4;-1:-1:-1;;;;;58206:10:0;;58202:90;;58233:47;58266:4;58272:7;58233:32;:47::i;:::-;-1:-1:-1;;;;;58306:16:0;;58302:183;;58339:45;58376:7;58339:36;:45::i;58302:183::-;58412:4;-1:-1:-1;;;;;58406:10:0;:2;-1:-1:-1;;;;;58406:10:0;;58402:83;;58433:40;58461:2;58465:7;58433:27;:40::i;50415:321::-;50545:18;50551:2;50555:7;50545:5;:18::i;:::-;50596:54;50627:1;50631:2;50635:7;50644:5;50596:22;:54::i;:::-;50574:154;;;;-1:-1:-1;;;50574:154:0;;;;;;;:::i;53833:803::-;53988:4;-1:-1:-1;;;;;54009:13:0;;25431:20;25479:8;54005:624;;54045:72;;-1:-1:-1;;;54045:72:0;;-1:-1:-1;;;;;54045:36:0;;;;;:72;;21924:10;;54096:4;;54102:7;;54111:5;;54045:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54045:72:0;;;;;;;;-1:-1:-1;;54045:72:0;;;;;;;;;;;;:::i;:::-;;;54041:533;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54291:13:0;;54287:272;;54334:60;;-1:-1:-1;;;54334:60:0;;;;;;;:::i;54287:272::-;54509:6;54503:13;54494:6;54490:2;54486:15;54479:38;54041:533;-1:-1:-1;;;;;;54168:55:0;-1:-1:-1;;;54168:55:0;;-1:-1:-1;54161:62:0;;54005:624;-1:-1:-1;54613:4:0;53833:803;;;;;;:::o;60006:988::-;60272:22;60322:1;60297:22;60314:4;60297:16;:22::i;:::-;:26;;;;:::i;:::-;60334:18;60355:26;;;:17;:26;;;;;;60272:51;;-1:-1:-1;60488:28:0;;;60484:328;;-1:-1:-1;;;;;60555:18:0;;60533:19;60555:18;;;:12;:18;;;;;;;;:34;;;;;;;;;60606:30;;;;;;:44;;;60723:30;;:17;:30;;;;;:43;;;60484:328;-1:-1:-1;60908:26:0;;;;:17;:26;;;;;;;;60901:33;;;-1:-1:-1;;;;;60952:18:0;;;;;:12;:18;;;;;:34;;;;;;;60945:41;60006:988::o;61289:1079::-;61567:10;:17;61542:22;;61567:21;;61587:1;;61567:21;:::i;:::-;61599:18;61620:24;;;:15;:24;;;;;;61993:10;:26;;61542:46;;-1:-1:-1;61620:24:0;;61542:46;;61993:26;;;;;;:::i;:::-;;;;;;;;;61971:48;;62057:11;62032:10;62043;62032:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;62137:28;;;:15;:28;;;;;;;:41;;;62309:24;;;;;62302:31;62344:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;61360:1008;;;61289:1079;:::o;58793:221::-;58878:14;58895:20;58912:2;58895:16;:20::i;:::-;-1:-1:-1;;;;;58926:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;58971:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;58793:221:0:o;51072:382::-;-1:-1:-1;;;;;51152:16:0;;51144:61;;;;-1:-1:-1;;;51144:61:0;;21128:2:1;51144:61:0;;;21110:21:1;;;21147:18;;;21140:30;21206:34;21186:18;;;21179:62;21258:18;;51144:61:0;20926:356:1;51144:61:0;49159:4;49183:16;;;:7;:16;;;;;;-1:-1:-1;;;;;49183:16:0;:30;51216:58;;;;-1:-1:-1;;;51216:58:0;;21489:2:1;51216:58:0;;;21471:21:1;21528:2;21508:18;;;21501:30;21567;21547:18;;;21540:58;21615:18;;51216:58:0;21287:352:1;51216:58:0;51287:45;51316:1;51320:2;51324:7;51287:20;:45::i;:::-;-1:-1:-1;;;;;51345:13:0;;;;;;:9;:13;;;;;:18;;51362:1;;51345:13;:18;;51362:1;;51345:18;:::i;:::-;;;;-1:-1:-1;;51374:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;51374:21:0;-1:-1:-1;;;;;51374:21:0;;;;;;;;51413:33;;51374:16;;;51413:33;;51374:16;;51413:33;51072:382;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;196:131:1;-1:-1:-1;;;;;;270:32:1;;260:43;;250:71;;317:1;314;307:12;332:245;390:6;443:2;431:9;422:7;418:23;414:32;411:52;;;459:1;456;449:12;411:52;498:9;485:23;517:30;541:5;517:30;:::i;774:258::-;846:1;856:113;870:6;867:1;864:13;856:113;;;946:11;;;940:18;927:11;;;920:39;892:2;885:10;856:113;;;987:6;984:1;981:13;978:48;;;-1:-1:-1;;1022:1:1;1004:16;;997:27;774:258::o;1037:::-;1079:3;1117:5;1111:12;1144:6;1139:3;1132:19;1160:63;1216:6;1209:4;1204:3;1200:14;1193:4;1186:5;1182:16;1160:63;:::i;:::-;1277:2;1256:15;-1:-1:-1;;1252:29:1;1243:39;;;;1284:4;1239:50;;1037:258;-1:-1:-1;;1037:258:1:o;1300:220::-;1449:2;1438:9;1431:21;1412:4;1469:45;1510:2;1499:9;1495:18;1487:6;1469:45;:::i;1525:180::-;1584:6;1637:2;1625:9;1616:7;1612:23;1608:32;1605:52;;;1653:1;1650;1643:12;1605:52;-1:-1:-1;1676:23:1;;1525:180;-1:-1:-1;1525:180:1:o;1918:173::-;1986:20;;-1:-1:-1;;;;;2035:31:1;;2025:42;;2015:70;;2081:1;2078;2071:12;2015:70;1918:173;;;:::o;2096:254::-;2164:6;2172;2225:2;2213:9;2204:7;2200:23;2196:32;2193:52;;;2241:1;2238;2231:12;2193:52;2264:29;2283:9;2264:29;:::i;:::-;2254:39;2340:2;2325:18;;;;2312:32;;-1:-1:-1;;;2096:254:1:o;2355:186::-;2414:6;2467:2;2455:9;2446:7;2442:23;2438:32;2435:52;;;2483:1;2480;2473:12;2435:52;2506:29;2525:9;2506:29;:::i;2546:328::-;2623:6;2631;2639;2692:2;2680:9;2671:7;2667:23;2663:32;2660:52;;;2708:1;2705;2698:12;2660:52;2731:29;2750:9;2731:29;:::i;:::-;2721:39;;2779:38;2813:2;2802:9;2798:18;2779:38;:::i;:::-;2769:48;;2864:2;2853:9;2849:18;2836:32;2826:42;;2546:328;;;;;:::o;3246:127::-;3307:10;3302:3;3298:20;3295:1;3288:31;3338:4;3335:1;3328:15;3362:4;3359:1;3352:15;3378:632;3443:5;3473:18;3514:2;3506:6;3503:14;3500:40;;;3520:18;;:::i;:::-;3595:2;3589:9;3563:2;3649:15;;-1:-1:-1;;3645:24:1;;;3671:2;3641:33;3637:42;3625:55;;;3695:18;;;3715:22;;;3692:46;3689:72;;;3741:18;;:::i;:::-;3781:10;3777:2;3770:22;3810:6;3801:15;;3840:6;3832;3825:22;3880:3;3871:6;3866:3;3862:16;3859:25;3856:45;;;3897:1;3894;3887:12;3856:45;3947:6;3942:3;3935:4;3927:6;3923:17;3910:44;4002:1;3995:4;3986:6;3978;3974:19;3970:30;3963:41;;;;3378:632;;;;;:::o;4015:451::-;4084:6;4137:2;4125:9;4116:7;4112:23;4108:32;4105:52;;;4153:1;4150;4143:12;4105:52;4193:9;4180:23;4226:18;4218:6;4215:30;4212:50;;;4258:1;4255;4248:12;4212:50;4281:22;;4334:4;4326:13;;4322:27;-1:-1:-1;4312:55:1;;4363:1;4360;4353:12;4312:55;4386:74;4452:7;4447:2;4434:16;4429:2;4425;4421:11;4386:74;:::i;4471:347::-;4536:6;4544;4597:2;4585:9;4576:7;4572:23;4568:32;4565:52;;;4613:1;4610;4603:12;4565:52;4636:29;4655:9;4636:29;:::i;:::-;4626:39;;4715:2;4704:9;4700:18;4687:32;4762:5;4755:13;4748:21;4741:5;4738:32;4728:60;;4784:1;4781;4774:12;4728:60;4807:5;4797:15;;;4471:347;;;;;:::o;4823:667::-;4918:6;4926;4934;4942;4995:3;4983:9;4974:7;4970:23;4966:33;4963:53;;;5012:1;5009;5002:12;4963:53;5035:29;5054:9;5035:29;:::i;:::-;5025:39;;5083:38;5117:2;5106:9;5102:18;5083:38;:::i;:::-;5073:48;;5168:2;5157:9;5153:18;5140:32;5130:42;;5223:2;5212:9;5208:18;5195:32;5250:18;5242:6;5239:30;5236:50;;;5282:1;5279;5272:12;5236:50;5305:22;;5358:4;5350:13;;5346:27;-1:-1:-1;5336:55:1;;5387:1;5384;5377:12;5336:55;5410:74;5476:7;5471:2;5458:16;5453:2;5449;5445:11;5410:74;:::i;:::-;5400:84;;;4823:667;;;;;;;:::o;5495:367::-;5558:8;5568:6;5622:3;5615:4;5607:6;5603:17;5599:27;5589:55;;5640:1;5637;5630:12;5589:55;-1:-1:-1;5663:20:1;;5706:18;5695:30;;5692:50;;;5738:1;5735;5728:12;5692:50;5775:4;5767:6;5763:17;5751:29;;5835:3;5828:4;5818:6;5815:1;5811:14;5803:6;5799:27;5795:38;5792:47;5789:67;;;5852:1;5849;5842:12;5789:67;5495:367;;;;;:::o;5867:505::-;5962:6;5970;5978;6031:2;6019:9;6010:7;6006:23;6002:32;5999:52;;;6047:1;6044;6037:12;5999:52;6083:9;6070:23;6060:33;;6144:2;6133:9;6129:18;6116:32;6171:18;6163:6;6160:30;6157:50;;;6203:1;6200;6193:12;6157:50;6242:70;6304:7;6295:6;6284:9;6280:22;6242:70;:::i;:::-;5867:505;;6331:8;;-1:-1:-1;6216:96:1;;-1:-1:-1;;;;5867:505:1:o;6377:260::-;6445:6;6453;6506:2;6494:9;6485:7;6481:23;6477:32;6474:52;;;6522:1;6519;6512:12;6474:52;6545:29;6564:9;6545:29;:::i;:::-;6535:39;;6593:38;6627:2;6616:9;6612:18;6593:38;:::i;:::-;6583:48;;6377:260;;;;;:::o;6642:437::-;6728:6;6736;6789:2;6777:9;6768:7;6764:23;6760:32;6757:52;;;6805:1;6802;6795:12;6757:52;6845:9;6832:23;6878:18;6870:6;6867:30;6864:50;;;6910:1;6907;6900:12;6864:50;6949:70;7011:7;7002:6;6991:9;6987:22;6949:70;:::i;:::-;7038:8;;6923:96;;-1:-1:-1;6642:437:1;-1:-1:-1;;;;6642:437:1:o;7084:380::-;7163:1;7159:12;;;;7206;;;7227:61;;7281:4;7273:6;7269:17;7259:27;;7227:61;7334:2;7326:6;7323:14;7303:18;7300:38;7297:161;;;7380:10;7375:3;7371:20;7368:1;7361:31;7415:4;7412:1;7405:15;7443:4;7440:1;7433:15;7297:161;;7084:380;;;:::o;8709:356::-;8911:2;8893:21;;;8930:18;;;8923:30;8989:34;8984:2;8969:18;;8962:62;9056:2;9041:18;;8709:356::o;9070:413::-;9272:2;9254:21;;;9311:2;9291:18;;;9284:30;9350:34;9345:2;9330:18;;9323:62;-1:-1:-1;;;9416:2:1;9401:18;;9394:47;9473:3;9458:19;;9070:413::o;9901:127::-;9962:10;9957:3;9953:20;9950:1;9943:31;9993:4;9990:1;9983:15;10017:4;10014:1;10007:15;12117:401;12319:2;12301:21;;;12358:2;12338:18;;;12331:30;12397:34;12392:2;12377:18;;12370:62;-1:-1:-1;;;12463:2:1;12448:18;;12441:35;12508:3;12493:19;;12117:401::o;13596:127::-;13657:10;13652:3;13648:20;13645:1;13638:31;13688:4;13685:1;13678:15;13712:4;13709:1;13702:15;13728:135;13767:3;-1:-1:-1;;13788:17:1;;13785:43;;;13808:18;;:::i;:::-;-1:-1:-1;13855:1:1;13844:13;;13728:135::o;14284:470::-;14463:3;14501:6;14495:13;14517:53;14563:6;14558:3;14551:4;14543:6;14539:17;14517:53;:::i;:::-;14633:13;;14592:16;;;;14655:57;14633:13;14592:16;14689:4;14677:17;;14655:57;:::i;:::-;14728:20;;14284:470;-1:-1:-1;;;;14284:470:1:o;18565:125::-;18605:4;18633:1;18630;18627:8;18624:34;;;18638:18;;:::i;:::-;-1:-1:-1;18675:9:1;;18565:125::o;18695:128::-;18735:3;18766:1;18762:6;18759:1;18756:13;18753:39;;;18772:18;;:::i;:::-;-1:-1:-1;18808:9:1;;18695:128::o;18828:168::-;18868:7;18934:1;18930;18926:6;18922:14;18919:1;18916:21;18911:1;18904:9;18897:17;18893:45;18890:71;;;18941:18;;:::i;:::-;-1:-1:-1;18981:9:1;;18828:168::o;19001:127::-;19062:10;19057:3;19053:20;19050:1;19043:31;19093:4;19090:1;19083:15;19117:4;19114:1;19107:15;19133:120;19173:1;19199;19189:35;;19204:18;;:::i;:::-;-1:-1:-1;19238:9:1;;19133:120::o;19258:414::-;19460:2;19442:21;;;19499:2;19479:18;;;19472:30;19538:34;19533:2;19518:18;;19511:62;-1:-1:-1;;;19604:2:1;19589:18;;19582:48;19662:3;19647:19;;19258:414::o;19677:112::-;19709:1;19735;19725:35;;19740:18;;:::i;:::-;-1:-1:-1;19774:9:1;;19677:112::o;20046:489::-;-1:-1:-1;;;;;20315:15:1;;;20297:34;;20367:15;;20362:2;20347:18;;20340:43;20414:2;20399:18;;20392:34;;;20462:3;20457:2;20442:18;;20435:31;;;20240:4;;20483:46;;20509:19;;20501:6;20483:46;:::i;:::-;20475:54;20046:489;-1:-1:-1;;;;;;20046:489:1:o;20540:249::-;20609:6;20662:2;20650:9;20641:7;20637:23;20633:32;20630:52;;;20678:1;20675;20668:12;20630:52;20710:9;20704:16;20729:30;20753:5;20729:30;:::i;20794:127::-;20855:10;20850:3;20846:20;20843:1;20836:31;20886:4;20883:1;20876:15;20910:4;20907:1;20900:15

Swarm Source

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