ETH Price: $3,484.94 (+2.06%)
Gas: 3.5 Gwei

Token

Vault NFT (VAULT)
 

Overview

Max Total Supply

191 VAULT

Holders

35

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 VAULT
0x8dF9719d29AAcac7E46dB46974f58Ad953352c42
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:
VaultNFT

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-03-11
*/

// SPDX-License-Identifier: MIT 

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol


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

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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

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


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

pragma solidity ^0.8.0;

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

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

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


// OpenZeppelin Contracts v4.4.1 (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/Strings.sol


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

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

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


// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;


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

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

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

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

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

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

        return (signer, RecoverError.NoError);
    }

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

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

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

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

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


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

pragma solidity ^0.8.0;

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

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

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

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


// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;


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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

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


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

pragma solidity ^0.8.0;


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

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

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

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


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;








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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

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

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

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

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

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

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

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

        _afterTokenTransfer(address(0), to, tokenId);
    }

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

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

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

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

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

        _afterTokenTransfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

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

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

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

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

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

// File: contracts/VaultNFT.sol



pragma solidity >=0.7.0 <0.9.0;








contract VaultNFT is ERC721, Ownable, ReentrancyGuard {
  using SafeMath for uint256;
  using ECDSA for bytes32;
  using Strings for uint256;
  using Counters for Counters.Counter;

  Counters.Counter public supply;

  string public uriPrefix = "";
  string public uriSuffix = ".json";
  string public hiddenMetadataUri;
  
  uint256 public cost = 0.08 ether;
  uint256 public maxSupply = 10000;
  uint256 public maxMintAmountPerTx = 5;
  uint256 public MAX_VAULT_WHITELIST_CAP = 5;
  uint256 public constant RESERVED_VAULTS = 75;

  bool public presaleActive = false;
  bool public paused = true;
  bool public revealed = false;
  bool public reservesMinted = false;

  mapping(address => uint256) private whitelistAddressMintCount;

  constructor() ERC721("Vault NFT", "VAULT") {
    setHiddenMetadataUri("ipfs://QmXfhqE9DkXzkQzLjUtbfU8GvtdfWho8ZyoaFoxMc6pi2b/hidden.json");
  }

  function totalSupply() public view returns (uint256) {
    return supply.current();
  }

  // mint
  function presaleMint(uint256 _mintAmount, bytes calldata _whitelistSignature) external payable nonReentrant {
    require(verifyOwnerSignature(keccak256(abi.encode(msg.sender)), _whitelistSignature), "Invalid whitelist signature");
    require(presaleActive, "Presale is not active");
    require(_mintAmount <= MAX_VAULT_WHITELIST_CAP, "You can only mint a maximum of 3 for presale");
    require(whitelistAddressMintCount[msg.sender].add(_mintAmount) <= MAX_VAULT_WHITELIST_CAP, "This purchase would exceed the maximum Vaults you are allowed to mint in the presale");

    whitelistAddressMintCount[msg.sender] += _mintAmount;
    _safeMintVault(_mintAmount);
  }

  function mint(uint256 _mintAmount) external payable {
    require(!paused, "The contract is paused!");
    require(msg.value >= cost * _mintAmount, "Insufficient funds!");
    require(_mintAmount <= maxMintAmountPerTx, "Quantity is more than allowed per transaction.");

    _safeMintVault(_mintAmount);
  }

  function _safeMintVault(uint256 _mintAmount) internal {
    require(_mintAmount > 0, "You must mint at least 1 vault");
    require(supply.current().add(_mintAmount) <= maxSupply, "This purchase would exceed max supply of Vaults");
    require(msg.value >= cost.mul(_mintAmount), "The ether value sent is not correct");

    for (uint256 i = 0; i < _mintAmount; i++) {
      uint256 mintIndex = supply.current();

      if (mintIndex < maxSupply) {
        supply.increment();
        _safeMint(msg.sender, mintIndex);
      }
    }
  }
  
  //Note: Reserved vaults will be minted before the presale

  function mintReservedVaults() external onlyOwner {
    require(!reservesMinted, "Reserves have already been minted.");
    require(supply.current().add(RESERVED_VAULTS) <= maxSupply, "This mint would exceed max supply of Vaults");

    for (uint256 i = 0; i < RESERVED_VAULTS; i++) {
      uint256 mintIndex = supply.current();

      if (mintIndex < maxSupply) {
        supply.increment();
        _safeMint(msg.sender, mintIndex);
      }
    }
    reservesMinted = true;
  }

  function tokenURI(uint256 _tokenId)
    public
    view
    virtual
    override
    returns (string memory)
  {
    require(
      _exists(_tokenId),
      "ERC721Metadata: URI query for nonexistent token"
    );

    if (revealed == false) {
      return hiddenMetadataUri;
    }

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

  function setRevealed(bool _state) external onlyOwner {
    revealed = _state;
  }

  function setCost(uint256 _cost) external onlyOwner {
    cost = _cost;
  }

  function setHiddenMetadataUri(string memory _hiddenMetadataUri) public onlyOwner {
    hiddenMetadataUri = _hiddenMetadataUri;
  }

  function setUriPrefix(string memory _uriPrefix) external onlyOwner {
    uriPrefix = _uriPrefix;
  }

  function setUriSuffix(string memory _uriSuffix) external onlyOwner {
    uriSuffix = _uriSuffix;
  }

  function setPresaleActive(bool _active) external onlyOwner {
    presaleActive = _active;
  }

  function setPaused(bool _state) external onlyOwner {
    paused = _state;
  }

  function withdraw() public onlyOwner {
    // This will transfer the remaining contract balance to the owner.
    // Do not remove this otherwise you will not be able to withdraw the funds.
    // =============================================================================
    (bool os, ) = payable(owner()).call{value: address(this).balance}("");
    require(os);
    // =============================================================================
  }

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

  /************
   * Security *
   ************/

  function verifyOwnerSignature(bytes32 hash, bytes memory signature) private view returns(bool) {
    return hash.toEthSignedMessageHash().recover(signature) == owner();
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_VAULT_WHITELIST_CAP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESERVED_VAULTS","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":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hiddenMetadataUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintAmountPerTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintReservedVaults","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"bytes","name":"_whitelistSignature","type":"bytes"}],"name":"presaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reservesMinted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cost","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_hiddenMetadataUri","type":"string"}],"name":"setHiddenMetadataUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_active","type":"bool"}],"name":"setPresaleActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setRevealed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriPrefix","type":"string"}],"name":"setUriPrefix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriSuffix","type":"string"}],"name":"setUriSuffix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supply","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","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":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uriPrefix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uriSuffix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040819052600060808190526200001b9160099162000207565b5060408051808201909152600580825264173539b7b760d91b60209092019182526200004a91600a9162000207565b5067011c37937e080000600c55612710600d556005600e819055600f556010805463ffffffff19166101001790553480156200008557600080fd5b50604080518082018252600981526815985d5b1d0813919560ba1b602080830191825283518085019094526005845264159055531560da1b908401528151919291620000d49160009162000207565b508051620000ea90600190602084019062000207565b50505062000107620001016200013960201b60201c565b6200013d565b60016007819055506200013360405180608001604052806041815260200162002de8604191396200018f565b620002ea565b3390565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6006546001600160a01b03163314620001ee5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640160405180910390fd5b80516200020390600b90602084019062000207565b5050565b8280546200021590620002ad565b90600052602060002090601f01602090048101928262000239576000855562000284565b82601f106200025457805160ff191683800117855562000284565b8280016001018555821562000284579182015b828111156200028457825182559160200191906001019062000267565b506200029292915062000296565b5090565b5b8082111562000292576000815560010162000297565b600181811c90821680620002c257607f821691505b60208210811415620002e457634e487b7160e01b600052602260045260246000fd5b50919050565b612aee80620002fa6000396000f3fe6080604052600436106102465760003560e01c80635c975abb11610139578063a22cb465116100b6578063d5abeb011161007a578063d5abeb0114610656578063de2e4fe81461066c578063e0a8085314610681578063e985e9c5146106a1578063f2fde38b146106ea578063fd24a8541461070a57600080fd5b8063a22cb465146105c0578063a45ba8e7146105e0578063b88d4fde146105f5578063c87b56dd14610615578063cc41d7951461063557600080fd5b80637ec4a659116100fd5780637ec4a659146105445780638da5cb5b1461056457806394354fd01461058257806395d89b4114610598578063a0712d68146105ad57600080fd5b80635c975abb146104bb57806362b99ad4146104da5780636352211e146104ef57806370a082311461050f578063715018a61461052f57600080fd5b806323b872dd116101c757806344a0d68a1161018b57806344a0d68a1461042c5780634fdd43cb1461044c578063518302271461046c57806353135ca01461048c5780635503a0e8146104a657600080fd5b806323b872dd146103a25780633ccfd60b146103c25780633f8121a2146103d757806342842e0e146103f757806343b36a861461041757600080fd5b80630cac229d1161020e5780630cac229d1461032157806313faede61461033757806316ba10e01461034d57806316c38b3c1461036d57806318160ddd1461038d57600080fd5b806301ffc9a71461024b578063047fc9aa1461028057806306fdde03146102a5578063081812fc146102c7578063095ea7b3146102ff575b600080fd5b34801561025757600080fd5b5061026b61026636600461260c565b61071d565b60405190151581526020015b60405180910390f35b34801561028c57600080fd5b506008546102979081565b604051908152602001610277565b3480156102b157600080fd5b506102ba61076f565b6040516102779190612851565b3480156102d357600080fd5b506102e76102e236600461268f565b610801565b6040516001600160a01b039091168152602001610277565b34801561030b57600080fd5b5061031f61031a3660046125c7565b61089b565b005b34801561032d57600080fd5b50610297600f5481565b34801561034357600080fd5b50610297600c5481565b34801561035957600080fd5b5061031f610368366004612646565b6109b1565b34801561037957600080fd5b5061031f6103883660046125f1565b6109f2565b34801561039957600080fd5b50610297610a36565b3480156103ae57600080fd5b5061031f6103bd3660046124e5565b610a46565b3480156103ce57600080fd5b5061031f610a77565b3480156103e357600080fd5b5061031f6103f23660046125f1565b610b15565b34801561040357600080fd5b5061031f6104123660046124e5565b610b52565b34801561042357600080fd5b5061031f610b6d565b34801561043857600080fd5b5061031f61044736600461268f565b610cd9565b34801561045857600080fd5b5061031f610467366004612646565b610d08565b34801561047857600080fd5b5060105461026b9062010000900460ff1681565b34801561049857600080fd5b5060105461026b9060ff1681565b3480156104b257600080fd5b506102ba610d45565b3480156104c757600080fd5b5060105461026b90610100900460ff1681565b3480156104e657600080fd5b506102ba610dd3565b3480156104fb57600080fd5b506102e761050a36600461268f565b610de0565b34801561051b57600080fd5b5061029761052a366004612497565b610e57565b34801561053b57600080fd5b5061031f610ede565b34801561055057600080fd5b5061031f61055f366004612646565b610f14565b34801561057057600080fd5b506006546001600160a01b03166102e7565b34801561058e57600080fd5b50610297600e5481565b3480156105a457600080fd5b506102ba610f51565b61031f6105bb36600461268f565b610f60565b3480156105cc57600080fd5b5061031f6105db36600461259d565b61107d565b3480156105ec57600080fd5b506102ba611088565b34801561060157600080fd5b5061031f610610366004612521565b611095565b34801561062157600080fd5b506102ba61063036600461268f565b6110cd565b34801561064157600080fd5b5060105461026b906301000000900460ff1681565b34801561066257600080fd5b50610297600d5481565b34801561067857600080fd5b50610297604b81565b34801561068d57600080fd5b5061031f61069c3660046125f1565b61124d565b3480156106ad57600080fd5b5061026b6106bc3660046124b2565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156106f657600080fd5b5061031f610705366004612497565b611293565b61031f6107183660046126a8565b61132b565b60006001600160e01b031982166380ac58cd60e01b148061074e57506001600160e01b03198216635b5e139f60e01b145b8061076957506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606000805461077e906129ca565b80601f01602080910402602001604051908101604052809291908181526020018280546107aa906129ca565b80156107f75780601f106107cc576101008083540402835291602001916107f7565b820191906000526020600020905b8154815290600101906020018083116107da57829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b031661087f5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006108a682610de0565b9050806001600160a01b0316836001600160a01b031614156109145760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610876565b336001600160a01b0382161480610930575061093081336106bc565b6109a25760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610876565b6109ac83836115c7565b505050565b6006546001600160a01b031633146109db5760405162461bcd60e51b8152600401610876906128b6565b80516109ee90600a90602084019061235c565b5050565b6006546001600160a01b03163314610a1c5760405162461bcd60e51b8152600401610876906128b6565b601080549115156101000261ff0019909216919091179055565b6000610a4160085490565b905090565b610a503382611635565b610a6c5760405162461bcd60e51b8152600401610876906128eb565b6109ac83838361172c565b6006546001600160a01b03163314610aa15760405162461bcd60e51b8152600401610876906128b6565b6000610ab56006546001600160a01b031690565b6001600160a01b03164760405160006040518083038185875af1925050503d8060008114610aff576040519150601f19603f3d011682016040523d82523d6000602084013e610b04565b606091505b5050905080610b1257600080fd5b50565b6006546001600160a01b03163314610b3f5760405162461bcd60e51b8152600401610876906128b6565b6010805460ff1916911515919091179055565b6109ac83838360405180602001604052806000815250611095565b6006546001600160a01b03163314610b975760405162461bcd60e51b8152600401610876906128b6565b6010546301000000900460ff1615610bfc5760405162461bcd60e51b815260206004820152602260248201527f5265736572766573206861766520616c7265616479206265656e206d696e7465604482015261321760f11b6064820152608401610876565b600d54610c13604b610c0d60085490565b906118c8565b1115610c755760405162461bcd60e51b815260206004820152602b60248201527f54686973206d696e7420776f756c6420657863656564206d617820737570706c60448201526a79206f66205661756c747360a81b6064820152608401610876565b60005b604b811015610cc3576000610c8c60085490565b9050600d54811015610cb057610ca6600880546001019055565b610cb033826118d4565b5080610cbb81612a05565b915050610c78565b506010805463ff00000019166301000000179055565b6006546001600160a01b03163314610d035760405162461bcd60e51b8152600401610876906128b6565b600c55565b6006546001600160a01b03163314610d325760405162461bcd60e51b8152600401610876906128b6565b80516109ee90600b90602084019061235c565b600a8054610d52906129ca565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7e906129ca565b8015610dcb5780601f10610da057610100808354040283529160200191610dcb565b820191906000526020600020905b815481529060010190602001808311610dae57829003601f168201915b505050505081565b60098054610d52906129ca565b6000818152600260205260408120546001600160a01b0316806107695760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610876565b60006001600160a01b038216610ec25760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610876565b506001600160a01b031660009081526003602052604090205490565b6006546001600160a01b03163314610f085760405162461bcd60e51b8152600401610876906128b6565b610f1260006118ee565b565b6006546001600160a01b03163314610f3e5760405162461bcd60e51b8152600401610876906128b6565b80516109ee90600990602084019061235c565b60606001805461077e906129ca565b601054610100900460ff1615610fb85760405162461bcd60e51b815260206004820152601760248201527f54686520636f6e747261637420697320706175736564210000000000000000006044820152606401610876565b80600c54610fc69190612968565b34101561100b5760405162461bcd60e51b8152602060048201526013602482015272496e73756666696369656e742066756e64732160681b6044820152606401610876565b600e548111156110745760405162461bcd60e51b815260206004820152602e60248201527f5175616e74697479206973206d6f7265207468616e20616c6c6f77656420706560448201526d39103a3930b739b0b1ba34b7b71760911b6064820152608401610876565b610b1281611940565b6109ee338383611abb565b600b8054610d52906129ca565b61109f3383611635565b6110bb5760405162461bcd60e51b8152600401610876906128eb565b6110c784848484611b8a565b50505050565b6000818152600260205260409020546060906001600160a01b031661114c5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610876565b60105462010000900460ff166111ee57600b8054611169906129ca565b80601f0160208091040260200160405190810160405280929190818152602001828054611195906129ca565b80156111e25780601f106111b7576101008083540402835291602001916111e2565b820191906000526020600020905b8154815290600101906020018083116111c557829003601f168201915b50505050509050919050565b60006111f8611bbd565b905060008151116112185760405180602001604052806000815250611246565b8061122284611bcc565b600a60405160200161123693929190612750565b6040516020818303038152906040525b9392505050565b6006546001600160a01b031633146112775760405162461bcd60e51b8152600401610876906128b6565b60108054911515620100000262ff000019909216919091179055565b6006546001600160a01b031633146112bd5760405162461bcd60e51b8152600401610876906128b6565b6001600160a01b0381166113225760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610876565b610b12816118ee565b6002600754141561137e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610876565b6002600755604080513360208201526113e491016040516020818303038152906040528051906020012083838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611cca92505050565b6114305760405162461bcd60e51b815260206004820152601b60248201527f496e76616c69642077686974656c697374207369676e617475726500000000006044820152606401610876565b60105460ff1661147a5760405162461bcd60e51b815260206004820152601560248201527450726573616c65206973206e6f742061637469766560581b6044820152606401610876565b600f548311156114e15760405162461bcd60e51b815260206004820152602c60248201527f596f752063616e206f6e6c79206d696e742061206d6178696d756d206f66203360448201526b20666f722070726573616c6560a01b6064820152608401610876565b600f54336000908152601160205260409020546114fe90856118c8565b111561158f5760405162461bcd60e51b815260206004820152605460248201527f5468697320707572636861736520776f756c642065786365656420746865206d60448201527f6178696d756d205661756c747320796f752061726520616c6c6f77656420746f606482015273206d696e7420696e207468652070726573616c6560601b608482015260a401610876565b33600090815260116020526040812080548592906115ae90849061293c565b909155506115bd905083611940565b5050600160075550565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906115fc82610de0565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600260205260408120546001600160a01b03166116ae5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610876565b60006116b983610de0565b9050806001600160a01b0316846001600160a01b031614806116f45750836001600160a01b03166116e984610801565b6001600160a01b0316145b8061172457506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661173f82610de0565b6001600160a01b0316146117a35760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610876565b6001600160a01b0382166118055760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610876565b6118106000826115c7565b6001600160a01b0383166000908152600360205260408120805460019290611839908490612987565b90915550506001600160a01b038216600090815260036020526040812080546001929061186790849061293c565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000611246828461293c565b6109ee828260405180602001604052806000815250611d59565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600081116119905760405162461bcd60e51b815260206004820152601e60248201527f596f75206d757374206d696e74206174206c656173742031207661756c7400006044820152606401610876565b600d546119a082610c0d60085490565b1115611a065760405162461bcd60e51b815260206004820152602f60248201527f5468697320707572636861736520776f756c6420657863656564206d6178207360448201526e7570706c79206f66205661756c747360881b6064820152608401610876565b600c54611a139082611d8c565b341015611a6e5760405162461bcd60e51b815260206004820152602360248201527f5468652065746865722076616c75652073656e74206973206e6f7420636f72726044820152621958dd60ea1b6064820152608401610876565b60005b818110156109ee576000611a8460085490565b9050600d54811015611aa857611a9e600880546001019055565b611aa833826118d4565b5080611ab381612a05565b915050611a71565b816001600160a01b0316836001600160a01b03161415611b1d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610876565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611b9584848461172c565b611ba184848484611d98565b6110c75760405162461bcd60e51b815260040161087690612864565b60606009805461077e906129ca565b606081611bf05750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611c1a5780611c0481612a05565b9150611c139050600a83612954565b9150611bf4565b60008167ffffffffffffffff811115611c3557611c35612a8c565b6040519080825280601f01601f191660200182016040528015611c5f576020820181803683370190505b5090505b841561172457611c74600183612987565b9150611c81600a86612a20565b611c8c90603061293c565b60f81b818381518110611ca157611ca1612a76565b60200101906001600160f81b031916908160001a905350611cc3600a86612954565b9450611c63565b6000611cde6006546001600160a01b031690565b6001600160a01b0316611d4883611d42866040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90611ea5565b6001600160a01b0316149392505050565b611d638383611ec9565b611d706000848484611d98565b6109ac5760405162461bcd60e51b815260040161087690612864565b60006112468284612968565b60006001600160a01b0384163b15611e9a57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611ddc903390899088908890600401612814565b602060405180830381600087803b158015611df657600080fd5b505af1925050508015611e26575060408051601f3d908101601f19168201909252611e2391810190612629565b60015b611e80573d808015611e54576040519150601f19603f3d011682016040523d82523d6000602084013e611e59565b606091505b508051611e785760405162461bcd60e51b815260040161087690612864565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611724565b506001949350505050565b6000806000611eb4858561200b565b91509150611ec18161207b565b509392505050565b6001600160a01b038216611f1f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610876565b6000818152600260205260409020546001600160a01b031615611f845760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610876565b6001600160a01b0382166000908152600360205260408120805460019290611fad90849061293c565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000808251604114156120425760208301516040840151606085015160001a61203687828585612236565b94509450505050612074565b82516040141561206c5760208301516040840151612061868383612323565b935093505050612074565b506000905060025b9250929050565b600081600481111561208f5761208f612a60565b14156120985750565b60018160048111156120ac576120ac612a60565b14156120fa5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610876565b600281600481111561210e5761210e612a60565b141561215c5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610876565b600381600481111561217057612170612a60565b14156121c95760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610876565b60048160048111156121dd576121dd612a60565b1415610b125760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610876565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561226d575060009050600361231a565b8460ff16601b1415801561228557508460ff16601c14155b15612296575060009050600461231a565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156122ea573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166123135760006001925092505061231a565b9150600090505b94509492505050565b6000806001600160ff1b0383168161234060ff86901c601b61293c565b905061234e87828885612236565b935093505050935093915050565b828054612368906129ca565b90600052602060002090601f01602090048101928261238a57600085556123d0565b82601f106123a357805160ff19168380011785556123d0565b828001600101855582156123d0579182015b828111156123d05782518255916020019190600101906123b5565b506123dc9291506123e0565b5090565b5b808211156123dc57600081556001016123e1565b600067ffffffffffffffff8084111561241057612410612a8c565b604051601f8501601f19908116603f0116810190828211818310171561243857612438612a8c565b8160405280935085815286868601111561245157600080fd5b858560208301376000602087830101525050509392505050565b80356001600160a01b038116811461248257600080fd5b919050565b8035801515811461248257600080fd5b6000602082840312156124a957600080fd5b6112468261246b565b600080604083850312156124c557600080fd5b6124ce8361246b565b91506124dc6020840161246b565b90509250929050565b6000806000606084860312156124fa57600080fd5b6125038461246b565b92506125116020850161246b565b9150604084013590509250925092565b6000806000806080858703121561253757600080fd5b6125408561246b565b935061254e6020860161246b565b925060408501359150606085013567ffffffffffffffff81111561257157600080fd5b8501601f8101871361258257600080fd5b612591878235602084016123f5565b91505092959194509250565b600080604083850312156125b057600080fd5b6125b98361246b565b91506124dc60208401612487565b600080604083850312156125da57600080fd5b6125e38361246b565b946020939093013593505050565b60006020828403121561260357600080fd5b61124682612487565b60006020828403121561261e57600080fd5b813561124681612aa2565b60006020828403121561263b57600080fd5b815161124681612aa2565b60006020828403121561265857600080fd5b813567ffffffffffffffff81111561266f57600080fd5b8201601f8101841361268057600080fd5b611724848235602084016123f5565b6000602082840312156126a157600080fd5b5035919050565b6000806000604084860312156126bd57600080fd5b83359250602084013567ffffffffffffffff808211156126dc57600080fd5b818601915086601f8301126126f057600080fd5b8135818111156126ff57600080fd5b87602082850101111561271157600080fd5b6020830194508093505050509250925092565b6000815180845261273c81602086016020860161299e565b601f01601f19169290920160200192915050565b6000845160206127638285838a0161299e565b8551918401916127768184848a0161299e565b8554920191600090600181811c908083168061279357607f831692505b8583108114156127b157634e487b7160e01b85526022600452602485fd5b8080156127c557600181146127d657612803565b60ff19851688528388019550612803565b60008b81526020902060005b858110156127fb5781548a8201529084019088016127e2565b505083880195505b50939b9a5050505050505050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061284790830184612724565b9695505050505050565b6020815260006112466020830184612724565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6000821982111561294f5761294f612a34565b500190565b60008261296357612963612a4a565b500490565b600081600019048311821515161561298257612982612a34565b500290565b60008282101561299957612999612a34565b500390565b60005b838110156129b95781810151838201526020016129a1565b838111156110c75750506000910152565b600181811c908216806129de57607f821691505b602082108114156129ff57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612a1957612a19612a34565b5060010190565b600082612a2f57612a2f612a4a565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610b1257600080fdfea26469706673582212208148e083a810fc0ba5cc34b016b2f5ce174239d29e695b87b3b7f85d3f92eeaf64736f6c63430008070033697066733a2f2f516d586668714539446b587a6b517a4c6a557462665538477674646657686f385a796f61466f784d6336706932622f68696464656e2e6a736f6e

Deployed Bytecode

0x6080604052600436106102465760003560e01c80635c975abb11610139578063a22cb465116100b6578063d5abeb011161007a578063d5abeb0114610656578063de2e4fe81461066c578063e0a8085314610681578063e985e9c5146106a1578063f2fde38b146106ea578063fd24a8541461070a57600080fd5b8063a22cb465146105c0578063a45ba8e7146105e0578063b88d4fde146105f5578063c87b56dd14610615578063cc41d7951461063557600080fd5b80637ec4a659116100fd5780637ec4a659146105445780638da5cb5b1461056457806394354fd01461058257806395d89b4114610598578063a0712d68146105ad57600080fd5b80635c975abb146104bb57806362b99ad4146104da5780636352211e146104ef57806370a082311461050f578063715018a61461052f57600080fd5b806323b872dd116101c757806344a0d68a1161018b57806344a0d68a1461042c5780634fdd43cb1461044c578063518302271461046c57806353135ca01461048c5780635503a0e8146104a657600080fd5b806323b872dd146103a25780633ccfd60b146103c25780633f8121a2146103d757806342842e0e146103f757806343b36a861461041757600080fd5b80630cac229d1161020e5780630cac229d1461032157806313faede61461033757806316ba10e01461034d57806316c38b3c1461036d57806318160ddd1461038d57600080fd5b806301ffc9a71461024b578063047fc9aa1461028057806306fdde03146102a5578063081812fc146102c7578063095ea7b3146102ff575b600080fd5b34801561025757600080fd5b5061026b61026636600461260c565b61071d565b60405190151581526020015b60405180910390f35b34801561028c57600080fd5b506008546102979081565b604051908152602001610277565b3480156102b157600080fd5b506102ba61076f565b6040516102779190612851565b3480156102d357600080fd5b506102e76102e236600461268f565b610801565b6040516001600160a01b039091168152602001610277565b34801561030b57600080fd5b5061031f61031a3660046125c7565b61089b565b005b34801561032d57600080fd5b50610297600f5481565b34801561034357600080fd5b50610297600c5481565b34801561035957600080fd5b5061031f610368366004612646565b6109b1565b34801561037957600080fd5b5061031f6103883660046125f1565b6109f2565b34801561039957600080fd5b50610297610a36565b3480156103ae57600080fd5b5061031f6103bd3660046124e5565b610a46565b3480156103ce57600080fd5b5061031f610a77565b3480156103e357600080fd5b5061031f6103f23660046125f1565b610b15565b34801561040357600080fd5b5061031f6104123660046124e5565b610b52565b34801561042357600080fd5b5061031f610b6d565b34801561043857600080fd5b5061031f61044736600461268f565b610cd9565b34801561045857600080fd5b5061031f610467366004612646565b610d08565b34801561047857600080fd5b5060105461026b9062010000900460ff1681565b34801561049857600080fd5b5060105461026b9060ff1681565b3480156104b257600080fd5b506102ba610d45565b3480156104c757600080fd5b5060105461026b90610100900460ff1681565b3480156104e657600080fd5b506102ba610dd3565b3480156104fb57600080fd5b506102e761050a36600461268f565b610de0565b34801561051b57600080fd5b5061029761052a366004612497565b610e57565b34801561053b57600080fd5b5061031f610ede565b34801561055057600080fd5b5061031f61055f366004612646565b610f14565b34801561057057600080fd5b506006546001600160a01b03166102e7565b34801561058e57600080fd5b50610297600e5481565b3480156105a457600080fd5b506102ba610f51565b61031f6105bb36600461268f565b610f60565b3480156105cc57600080fd5b5061031f6105db36600461259d565b61107d565b3480156105ec57600080fd5b506102ba611088565b34801561060157600080fd5b5061031f610610366004612521565b611095565b34801561062157600080fd5b506102ba61063036600461268f565b6110cd565b34801561064157600080fd5b5060105461026b906301000000900460ff1681565b34801561066257600080fd5b50610297600d5481565b34801561067857600080fd5b50610297604b81565b34801561068d57600080fd5b5061031f61069c3660046125f1565b61124d565b3480156106ad57600080fd5b5061026b6106bc3660046124b2565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156106f657600080fd5b5061031f610705366004612497565b611293565b61031f6107183660046126a8565b61132b565b60006001600160e01b031982166380ac58cd60e01b148061074e57506001600160e01b03198216635b5e139f60e01b145b8061076957506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606000805461077e906129ca565b80601f01602080910402602001604051908101604052809291908181526020018280546107aa906129ca565b80156107f75780601f106107cc576101008083540402835291602001916107f7565b820191906000526020600020905b8154815290600101906020018083116107da57829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b031661087f5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006108a682610de0565b9050806001600160a01b0316836001600160a01b031614156109145760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610876565b336001600160a01b0382161480610930575061093081336106bc565b6109a25760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610876565b6109ac83836115c7565b505050565b6006546001600160a01b031633146109db5760405162461bcd60e51b8152600401610876906128b6565b80516109ee90600a90602084019061235c565b5050565b6006546001600160a01b03163314610a1c5760405162461bcd60e51b8152600401610876906128b6565b601080549115156101000261ff0019909216919091179055565b6000610a4160085490565b905090565b610a503382611635565b610a6c5760405162461bcd60e51b8152600401610876906128eb565b6109ac83838361172c565b6006546001600160a01b03163314610aa15760405162461bcd60e51b8152600401610876906128b6565b6000610ab56006546001600160a01b031690565b6001600160a01b03164760405160006040518083038185875af1925050503d8060008114610aff576040519150601f19603f3d011682016040523d82523d6000602084013e610b04565b606091505b5050905080610b1257600080fd5b50565b6006546001600160a01b03163314610b3f5760405162461bcd60e51b8152600401610876906128b6565b6010805460ff1916911515919091179055565b6109ac83838360405180602001604052806000815250611095565b6006546001600160a01b03163314610b975760405162461bcd60e51b8152600401610876906128b6565b6010546301000000900460ff1615610bfc5760405162461bcd60e51b815260206004820152602260248201527f5265736572766573206861766520616c7265616479206265656e206d696e7465604482015261321760f11b6064820152608401610876565b600d54610c13604b610c0d60085490565b906118c8565b1115610c755760405162461bcd60e51b815260206004820152602b60248201527f54686973206d696e7420776f756c6420657863656564206d617820737570706c60448201526a79206f66205661756c747360a81b6064820152608401610876565b60005b604b811015610cc3576000610c8c60085490565b9050600d54811015610cb057610ca6600880546001019055565b610cb033826118d4565b5080610cbb81612a05565b915050610c78565b506010805463ff00000019166301000000179055565b6006546001600160a01b03163314610d035760405162461bcd60e51b8152600401610876906128b6565b600c55565b6006546001600160a01b03163314610d325760405162461bcd60e51b8152600401610876906128b6565b80516109ee90600b90602084019061235c565b600a8054610d52906129ca565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7e906129ca565b8015610dcb5780601f10610da057610100808354040283529160200191610dcb565b820191906000526020600020905b815481529060010190602001808311610dae57829003601f168201915b505050505081565b60098054610d52906129ca565b6000818152600260205260408120546001600160a01b0316806107695760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610876565b60006001600160a01b038216610ec25760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610876565b506001600160a01b031660009081526003602052604090205490565b6006546001600160a01b03163314610f085760405162461bcd60e51b8152600401610876906128b6565b610f1260006118ee565b565b6006546001600160a01b03163314610f3e5760405162461bcd60e51b8152600401610876906128b6565b80516109ee90600990602084019061235c565b60606001805461077e906129ca565b601054610100900460ff1615610fb85760405162461bcd60e51b815260206004820152601760248201527f54686520636f6e747261637420697320706175736564210000000000000000006044820152606401610876565b80600c54610fc69190612968565b34101561100b5760405162461bcd60e51b8152602060048201526013602482015272496e73756666696369656e742066756e64732160681b6044820152606401610876565b600e548111156110745760405162461bcd60e51b815260206004820152602e60248201527f5175616e74697479206973206d6f7265207468616e20616c6c6f77656420706560448201526d39103a3930b739b0b1ba34b7b71760911b6064820152608401610876565b610b1281611940565b6109ee338383611abb565b600b8054610d52906129ca565b61109f3383611635565b6110bb5760405162461bcd60e51b8152600401610876906128eb565b6110c784848484611b8a565b50505050565b6000818152600260205260409020546060906001600160a01b031661114c5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610876565b60105462010000900460ff166111ee57600b8054611169906129ca565b80601f0160208091040260200160405190810160405280929190818152602001828054611195906129ca565b80156111e25780601f106111b7576101008083540402835291602001916111e2565b820191906000526020600020905b8154815290600101906020018083116111c557829003601f168201915b50505050509050919050565b60006111f8611bbd565b905060008151116112185760405180602001604052806000815250611246565b8061122284611bcc565b600a60405160200161123693929190612750565b6040516020818303038152906040525b9392505050565b6006546001600160a01b031633146112775760405162461bcd60e51b8152600401610876906128b6565b60108054911515620100000262ff000019909216919091179055565b6006546001600160a01b031633146112bd5760405162461bcd60e51b8152600401610876906128b6565b6001600160a01b0381166113225760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610876565b610b12816118ee565b6002600754141561137e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610876565b6002600755604080513360208201526113e491016040516020818303038152906040528051906020012083838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611cca92505050565b6114305760405162461bcd60e51b815260206004820152601b60248201527f496e76616c69642077686974656c697374207369676e617475726500000000006044820152606401610876565b60105460ff1661147a5760405162461bcd60e51b815260206004820152601560248201527450726573616c65206973206e6f742061637469766560581b6044820152606401610876565b600f548311156114e15760405162461bcd60e51b815260206004820152602c60248201527f596f752063616e206f6e6c79206d696e742061206d6178696d756d206f66203360448201526b20666f722070726573616c6560a01b6064820152608401610876565b600f54336000908152601160205260409020546114fe90856118c8565b111561158f5760405162461bcd60e51b815260206004820152605460248201527f5468697320707572636861736520776f756c642065786365656420746865206d60448201527f6178696d756d205661756c747320796f752061726520616c6c6f77656420746f606482015273206d696e7420696e207468652070726573616c6560601b608482015260a401610876565b33600090815260116020526040812080548592906115ae90849061293c565b909155506115bd905083611940565b5050600160075550565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906115fc82610de0565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600260205260408120546001600160a01b03166116ae5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610876565b60006116b983610de0565b9050806001600160a01b0316846001600160a01b031614806116f45750836001600160a01b03166116e984610801565b6001600160a01b0316145b8061172457506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661173f82610de0565b6001600160a01b0316146117a35760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610876565b6001600160a01b0382166118055760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610876565b6118106000826115c7565b6001600160a01b0383166000908152600360205260408120805460019290611839908490612987565b90915550506001600160a01b038216600090815260036020526040812080546001929061186790849061293c565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000611246828461293c565b6109ee828260405180602001604052806000815250611d59565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600081116119905760405162461bcd60e51b815260206004820152601e60248201527f596f75206d757374206d696e74206174206c656173742031207661756c7400006044820152606401610876565b600d546119a082610c0d60085490565b1115611a065760405162461bcd60e51b815260206004820152602f60248201527f5468697320707572636861736520776f756c6420657863656564206d6178207360448201526e7570706c79206f66205661756c747360881b6064820152608401610876565b600c54611a139082611d8c565b341015611a6e5760405162461bcd60e51b815260206004820152602360248201527f5468652065746865722076616c75652073656e74206973206e6f7420636f72726044820152621958dd60ea1b6064820152608401610876565b60005b818110156109ee576000611a8460085490565b9050600d54811015611aa857611a9e600880546001019055565b611aa833826118d4565b5080611ab381612a05565b915050611a71565b816001600160a01b0316836001600160a01b03161415611b1d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610876565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611b9584848461172c565b611ba184848484611d98565b6110c75760405162461bcd60e51b815260040161087690612864565b60606009805461077e906129ca565b606081611bf05750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611c1a5780611c0481612a05565b9150611c139050600a83612954565b9150611bf4565b60008167ffffffffffffffff811115611c3557611c35612a8c565b6040519080825280601f01601f191660200182016040528015611c5f576020820181803683370190505b5090505b841561172457611c74600183612987565b9150611c81600a86612a20565b611c8c90603061293c565b60f81b818381518110611ca157611ca1612a76565b60200101906001600160f81b031916908160001a905350611cc3600a86612954565b9450611c63565b6000611cde6006546001600160a01b031690565b6001600160a01b0316611d4883611d42866040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90611ea5565b6001600160a01b0316149392505050565b611d638383611ec9565b611d706000848484611d98565b6109ac5760405162461bcd60e51b815260040161087690612864565b60006112468284612968565b60006001600160a01b0384163b15611e9a57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611ddc903390899088908890600401612814565b602060405180830381600087803b158015611df657600080fd5b505af1925050508015611e26575060408051601f3d908101601f19168201909252611e2391810190612629565b60015b611e80573d808015611e54576040519150601f19603f3d011682016040523d82523d6000602084013e611e59565b606091505b508051611e785760405162461bcd60e51b815260040161087690612864565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611724565b506001949350505050565b6000806000611eb4858561200b565b91509150611ec18161207b565b509392505050565b6001600160a01b038216611f1f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610876565b6000818152600260205260409020546001600160a01b031615611f845760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610876565b6001600160a01b0382166000908152600360205260408120805460019290611fad90849061293c565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000808251604114156120425760208301516040840151606085015160001a61203687828585612236565b94509450505050612074565b82516040141561206c5760208301516040840151612061868383612323565b935093505050612074565b506000905060025b9250929050565b600081600481111561208f5761208f612a60565b14156120985750565b60018160048111156120ac576120ac612a60565b14156120fa5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610876565b600281600481111561210e5761210e612a60565b141561215c5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610876565b600381600481111561217057612170612a60565b14156121c95760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610876565b60048160048111156121dd576121dd612a60565b1415610b125760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610876565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561226d575060009050600361231a565b8460ff16601b1415801561228557508460ff16601c14155b15612296575060009050600461231a565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156122ea573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166123135760006001925092505061231a565b9150600090505b94509492505050565b6000806001600160ff1b0383168161234060ff86901c601b61293c565b905061234e87828885612236565b935093505050935093915050565b828054612368906129ca565b90600052602060002090601f01602090048101928261238a57600085556123d0565b82601f106123a357805160ff19168380011785556123d0565b828001600101855582156123d0579182015b828111156123d05782518255916020019190600101906123b5565b506123dc9291506123e0565b5090565b5b808211156123dc57600081556001016123e1565b600067ffffffffffffffff8084111561241057612410612a8c565b604051601f8501601f19908116603f0116810190828211818310171561243857612438612a8c565b8160405280935085815286868601111561245157600080fd5b858560208301376000602087830101525050509392505050565b80356001600160a01b038116811461248257600080fd5b919050565b8035801515811461248257600080fd5b6000602082840312156124a957600080fd5b6112468261246b565b600080604083850312156124c557600080fd5b6124ce8361246b565b91506124dc6020840161246b565b90509250929050565b6000806000606084860312156124fa57600080fd5b6125038461246b565b92506125116020850161246b565b9150604084013590509250925092565b6000806000806080858703121561253757600080fd5b6125408561246b565b935061254e6020860161246b565b925060408501359150606085013567ffffffffffffffff81111561257157600080fd5b8501601f8101871361258257600080fd5b612591878235602084016123f5565b91505092959194509250565b600080604083850312156125b057600080fd5b6125b98361246b565b91506124dc60208401612487565b600080604083850312156125da57600080fd5b6125e38361246b565b946020939093013593505050565b60006020828403121561260357600080fd5b61124682612487565b60006020828403121561261e57600080fd5b813561124681612aa2565b60006020828403121561263b57600080fd5b815161124681612aa2565b60006020828403121561265857600080fd5b813567ffffffffffffffff81111561266f57600080fd5b8201601f8101841361268057600080fd5b611724848235602084016123f5565b6000602082840312156126a157600080fd5b5035919050565b6000806000604084860312156126bd57600080fd5b83359250602084013567ffffffffffffffff808211156126dc57600080fd5b818601915086601f8301126126f057600080fd5b8135818111156126ff57600080fd5b87602082850101111561271157600080fd5b6020830194508093505050509250925092565b6000815180845261273c81602086016020860161299e565b601f01601f19169290920160200192915050565b6000845160206127638285838a0161299e565b8551918401916127768184848a0161299e565b8554920191600090600181811c908083168061279357607f831692505b8583108114156127b157634e487b7160e01b85526022600452602485fd5b8080156127c557600181146127d657612803565b60ff19851688528388019550612803565b60008b81526020902060005b858110156127fb5781548a8201529084019088016127e2565b505083880195505b50939b9a5050505050505050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061284790830184612724565b9695505050505050565b6020815260006112466020830184612724565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6000821982111561294f5761294f612a34565b500190565b60008261296357612963612a4a565b500490565b600081600019048311821515161561298257612982612a34565b500290565b60008282101561299957612999612a34565b500390565b60005b838110156129b95781810151838201526020016129a1565b838111156110c75750506000910152565b600181811c908216806129de57607f821691505b602082108114156129ff57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612a1957612a19612a34565b5060010190565b600082612a2f57612a2f612a4a565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610b1257600080fdfea26469706673582212208148e083a810fc0ba5cc34b016b2f5ce174239d29e695b87b3b7f85d3f92eeaf64736f6c63430008070033

Deployed Bytecode Sourcemap

58132:5154:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44930:305;;;;;;;;;;-1:-1:-1;44930:305:0;;;;;:::i;:::-;;:::i;:::-;;;8219:14:1;;8212:22;8194:41;;8182:2;8167:18;44930:305:0;;;;;;;;58322:30;;;;;;;;;;-1:-1:-1;58322:30:0;;;;;;;;;21997:25:1;;;21985:2;21970:18;58322:30:0;21851:177:1;45875:100:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;47434:221::-;;;;;;;;;;-1:-1:-1;47434:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;7517:32:1;;;7499:51;;7487:2;7472:18;47434:221:0;7353:203:1;46957:411:0;;;;;;;;;;-1:-1:-1;46957:411:0;;;;;:::i;:::-;;:::i;:::-;;58586:42;;;;;;;;;;;;;;;;58470:32;;;;;;;;;;;;;;;;62183:102;;;;;;;;;;-1:-1:-1;62183:102:0;;;;;:::i;:::-;;:::i;62392:79::-;;;;;;;;;;-1:-1:-1;62392:79:0;;;;;:::i;:::-;;:::i;59045:89::-;;;;;;;;;;;;;:::i;48184:339::-;;;;;;;;;;-1:-1:-1;48184:339:0;;;;;:::i;:::-;;:::i;62477:462::-;;;;;;;;;;;;;:::i;62291:95::-;;;;;;;;;;-1:-1:-1;62291:95:0;;;;;:::i;:::-;;:::i;48594:185::-;;;;;;;;;;-1:-1:-1;48594:185:0;;;;;:::i;:::-;;:::i;60769:491::-;;;;;;;;;;;;;:::i;61855:76::-;;;;;;;;;;-1:-1:-1;61855:76:0;;;;;:::i;:::-;;:::i;61937:132::-;;;;;;;;;;-1:-1:-1;61937:132:0;;;;;:::i;:::-;;:::i;58752:28::-;;;;;;;;;;-1:-1:-1;58752:28:0;;;;;;;;;;;58684:33;;;;;;;;;;-1:-1:-1;58684:33:0;;;;;;;;58392;;;;;;;;;;;;;:::i;58722:25::-;;;;;;;;;;-1:-1:-1;58722:25:0;;;;;;;;;;;58359:28;;;;;;;;;;;;;:::i;45569:239::-;;;;;;;;;;-1:-1:-1;45569:239:0;;;;;:::i;:::-;;:::i;45299:208::-;;;;;;;;;;-1:-1:-1;45299:208:0;;;;;:::i;:::-;;:::i;25551:103::-;;;;;;;;;;;;;:::i;62075:102::-;;;;;;;;;;-1:-1:-1;62075:102:0;;;;;:::i;:::-;;:::i;24900:87::-;;;;;;;;;;-1:-1:-1;24973:6:0;;-1:-1:-1;;;;;24973:6:0;24900:87;;58544:37;;;;;;;;;;;;;;;;46044:104;;;;;;;;;;;;;:::i;59830:313::-;;;;;;:::i;:::-;;:::i;47727:155::-;;;;;;;;;;-1:-1:-1;47727:155:0;;;;;:::i;:::-;;:::i;58430:31::-;;;;;;;;;;;;;:::i;48850:328::-;;;;;;;;;;-1:-1:-1;48850:328:0;;;;;:::i;:::-;;:::i;61266:494::-;;;;;;;;;;-1:-1:-1;61266:494:0;;;;;:::i;:::-;;:::i;58785:34::-;;;;;;;;;;-1:-1:-1;58785:34:0;;;;;;;;;;;58507:32;;;;;;;;;;;;;;;;58633:44;;;;;;;;;;;;58675:2;58633:44;;61766:83;;;;;;;;;;-1:-1:-1;61766:83:0;;;;;:::i;:::-;;:::i;47953:164::-;;;;;;;;;;-1:-1:-1;47953:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;48074:25:0;;;48050:4;48074:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;47953:164;25809:201;;;;;;;;;;-1:-1:-1;25809:201:0;;;;;:::i;:::-;;:::i;59151:673::-;;;;;;:::i;:::-;;:::i;44930:305::-;45032:4;-1:-1:-1;;;;;;45069:40:0;;-1:-1:-1;;;45069:40:0;;:105;;-1:-1:-1;;;;;;;45126:48:0;;-1:-1:-1;;;45126:48:0;45069:105;:158;;;-1:-1:-1;;;;;;;;;;37793:40:0;;;45191:36;45049:178;44930:305;-1:-1:-1;;44930:305:0:o;45875:100::-;45929:13;45962:5;45955:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45875:100;:::o;47434:221::-;47510:7;50777:16;;;:7;:16;;;;;;-1:-1:-1;;;;;50777:16:0;47530:73;;;;-1:-1:-1;;;47530:73:0;;16552:2:1;47530:73:0;;;16534:21:1;16591:2;16571:18;;;16564:30;16630:34;16610:18;;;16603:62;-1:-1:-1;;;16681:18:1;;;16674:42;16733:19;;47530:73:0;;;;;;;;;-1:-1:-1;47623:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;47623:24:0;;47434:221::o;46957:411::-;47038:13;47054:23;47069:7;47054:14;:23::i;:::-;47038:39;;47102:5;-1:-1:-1;;;;;47096:11:0;:2;-1:-1:-1;;;;;47096:11:0;;;47088:57;;;;-1:-1:-1;;;47088:57:0;;19000:2:1;47088:57:0;;;18982:21:1;19039:2;19019:18;;;19012:30;19078:34;19058:18;;;19051:62;-1:-1:-1;;;19129:18:1;;;19122:31;19170:19;;47088:57:0;18798:397:1;47088:57:0;23704:10;-1:-1:-1;;;;;47180:21:0;;;;:62;;-1:-1:-1;47205:37:0;47222:5;23704:10;47953:164;:::i;47205:37::-;47158:168;;;;-1:-1:-1;;;47158:168:0;;14183:2:1;47158:168:0;;;14165:21:1;14222:2;14202:18;;;14195:30;14261:34;14241:18;;;14234:62;14332:26;14312:18;;;14305:54;14376:19;;47158:168:0;13981:420:1;47158:168:0;47339:21;47348:2;47352:7;47339:8;:21::i;:::-;47027:341;46957:411;;:::o;62183:102::-;24973:6;;-1:-1:-1;;;;;24973:6:0;23704:10;25120:23;25112:68;;;;-1:-1:-1;;;25112:68:0;;;;;;;:::i;:::-;62257:22;;::::1;::::0;:9:::1;::::0;:22:::1;::::0;::::1;::::0;::::1;:::i;:::-;;62183:102:::0;:::o;62392:79::-;24973:6;;-1:-1:-1;;;;;24973:6:0;23704:10;25120:23;25112:68;;;;-1:-1:-1;;;25112:68:0;;;;;;;:::i;:::-;62450:6:::1;:15:::0;;;::::1;;;;-1:-1:-1::0;;62450:15:0;;::::1;::::0;;;::::1;::::0;;62392:79::o;59045:89::-;59089:7;59112:16;:6;10786:14;;10694:114;59112:16;59105:23;;59045:89;:::o;48184:339::-;48379:41;23704:10;48412:7;48379:18;:41::i;:::-;48371:103;;;;-1:-1:-1;;;48371:103:0;;;;;;;:::i;:::-;48487:28;48497:4;48503:2;48507:7;48487:9;:28::i;62477:462::-;24973:6;;-1:-1:-1;;;;;24973:6:0;23704:10;25120:23;25112:68;;;;-1:-1:-1;;;25112:68:0;;;;;;;:::i;:::-;62761:7:::1;62782;24973:6:::0;;-1:-1:-1;;;;;24973:6:0;;24900:87;62782:7:::1;-1:-1:-1::0;;;;;62774:21:0::1;62803;62774:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62760:69;;;62844:2;62836:11;;;::::0;::::1;;62514:425;62477:462::o:0;62291:95::-;24973:6;;-1:-1:-1;;;;;24973:6:0;23704:10;25120:23;25112:68;;;;-1:-1:-1;;;25112:68:0;;;;;;;:::i;:::-;62357:13:::1;:23:::0;;-1:-1:-1;;62357:23:0::1;::::0;::::1;;::::0;;;::::1;::::0;;62291:95::o;48594:185::-;48732:39;48749:4;48755:2;48759:7;48732:39;;;;;;;;;;;;:16;:39::i;60769:491::-;24973:6;;-1:-1:-1;;;;;24973:6:0;23704:10;25120:23;25112:68;;;;-1:-1:-1;;;25112:68:0;;;;;;;:::i;:::-;60834:14:::1;::::0;;;::::1;;;60833:15;60825:62;;;::::0;-1:-1:-1;;;60825:62:0;;11789:2:1;60825:62:0::1;::::0;::::1;11771:21:1::0;11828:2;11808:18;;;11801:30;11867:34;11847:18;;;11840:62;-1:-1:-1;;;11918:18:1;;;11911:32;11960:19;;60825:62:0::1;11587:398:1::0;60825:62:0::1;60943:9;;60902:37;58675:2;60902:16;:6;10786:14:::0;;10694:114;60902:16:::1;:20:::0;::::1;:37::i;:::-;:50;;60894:106;;;::::0;-1:-1:-1;;;60894:106:0;;11377:2:1;60894:106:0::1;::::0;::::1;11359:21:1::0;11416:2;11396:18;;;11389:30;11455:34;11435:18;;;11428:62;-1:-1:-1;;;11506:18:1;;;11499:41;11557:19;;60894:106:0::1;11175:407:1::0;60894:106:0::1;61014:9;61009:218;58675:2;61029:1;:19;61009:218;;;61064:17;61084:16;:6;10786:14:::0;;10694:114;61084:16:::1;61064:36;;61127:9;;61115;:21;61111:109;;;61149:18;:6;10905:19:::0;;10923:1;10905:19;;;10816:127;61149:18:::1;61178:32;61188:10;61200:9;61178;:32::i;:::-;-1:-1:-1::0;61050:3:0;::::1;::::0;::::1;:::i;:::-;;;;61009:218;;;-1:-1:-1::0;61233:14:0::1;:21:::0;;-1:-1:-1;;61233:21:0::1;::::0;::::1;::::0;;60769:491::o;61855:76::-;24973:6;;-1:-1:-1;;;;;24973:6:0;23704:10;25120:23;25112:68;;;;-1:-1:-1;;;25112:68:0;;;;;;;:::i;:::-;61913:4:::1;:12:::0;61855:76::o;61937:132::-;24973:6;;-1:-1:-1;;;;;24973:6:0;23704:10;25120:23;25112:68;;;;-1:-1:-1;;;25112:68:0;;;;;;;:::i;:::-;62025:38;;::::1;::::0;:17:::1;::::0;:38:::1;::::0;::::1;::::0;::::1;:::i;58392:33::-:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;58359:28::-;;;;;;;:::i;45569:239::-;45641:7;45677:16;;;:7;:16;;;;;;-1:-1:-1;;;;;45677:16:0;45712:19;45704:73;;;;-1:-1:-1;;;45704:73:0;;15378:2:1;45704:73:0;;;15360:21:1;15417:2;15397:18;;;15390:30;15456:34;15436:18;;;15429:62;-1:-1:-1;;;15507:18:1;;;15500:39;15556:19;;45704:73:0;15176:405:1;45299:208:0;45371:7;-1:-1:-1;;;;;45399:19:0;;45391:74;;;;-1:-1:-1;;;45391:74:0;;14967:2:1;45391:74:0;;;14949:21:1;15006:2;14986:18;;;14979:30;15045:34;15025:18;;;15018:62;-1:-1:-1;;;15096:18:1;;;15089:40;15146:19;;45391:74:0;14765:406:1;45391:74:0;-1:-1:-1;;;;;;45483:16:0;;;;;:9;:16;;;;;;;45299:208::o;25551:103::-;24973:6;;-1:-1:-1;;;;;24973:6:0;23704:10;25120:23;25112:68;;;;-1:-1:-1;;;25112:68:0;;;;;;;:::i;:::-;25616:30:::1;25643:1;25616:18;:30::i;:::-;25551:103::o:0;62075:102::-;24973:6;;-1:-1:-1;;;;;24973:6:0;23704:10;25120:23;25112:68;;;;-1:-1:-1;;;25112:68:0;;;;;;;:::i;:::-;62149:22;;::::1;::::0;:9:::1;::::0;:22:::1;::::0;::::1;::::0;::::1;:::i;46044:104::-:0;46100:13;46133:7;46126:14;;;;;:::i;59830:313::-;59898:6;;;;;;;59897:7;59889:43;;;;-1:-1:-1;;;59889:43:0;;17739:2:1;59889:43:0;;;17721:21:1;17778:2;17758:18;;;17751:30;17817:25;17797:18;;;17790:53;17860:18;;59889:43:0;17537:347:1;59889:43:0;59967:11;59960:4;;:18;;;;:::i;:::-;59947:9;:31;;59939:63;;;;-1:-1:-1;;;59939:63:0;;21705:2:1;59939:63:0;;;21687:21:1;21744:2;21724:18;;;21717:30;-1:-1:-1;;;21763:18:1;;;21756:49;21822:18;;59939:63:0;21503:343:1;59939:63:0;60032:18;;60017:11;:33;;60009:92;;;;-1:-1:-1;;;60009:92:0;;19402:2:1;60009:92:0;;;19384:21:1;19441:2;19421:18;;;19414:30;19480:34;19460:18;;;19453:62;-1:-1:-1;;;19531:18:1;;;19524:44;19585:19;;60009:92:0;19200:410:1;60009:92:0;60110:27;60125:11;60110:14;:27::i;47727:155::-;47822:52;23704:10;47855:8;47865;47822:18;:52::i;58430:31::-;;;;;;;:::i;48850:328::-;49025:41;23704:10;49058:7;49025:18;:41::i;:::-;49017:103;;;;-1:-1:-1;;;49017:103:0;;;;;;;:::i;:::-;49131:39;49145:4;49151:2;49155:7;49164:5;49131:13;:39::i;:::-;48850:328;;;;:::o;61266:494::-;50753:4;50777:16;;;:7;:16;;;;;;61365:13;;-1:-1:-1;;;;;50777:16:0;61390:98;;;;-1:-1:-1;;;61390:98:0;;18091:2:1;61390:98:0;;;18073:21:1;18130:2;18110:18;;;18103:30;18169:34;18149:18;;;18142:62;-1:-1:-1;;;18220:18:1;;;18213:45;18275:19;;61390:98:0;17889:411:1;61390:98:0;61501:8;;;;;;;61497:64;;61536:17;61529:24;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61266:494;;;:::o;61497:64::-;61569:28;61600:10;:8;:10::i;:::-;61569:41;;61655:1;61630:14;61624:28;:32;:130;;;;;;;;;;;;;;;;;61692:14;61708:19;:8;:17;:19::i;:::-;61729:9;61675:64;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;61624:130;61617:137;61266:494;-1:-1:-1;;;61266:494:0:o;61766:83::-;24973:6;;-1:-1:-1;;;;;24973:6:0;23704:10;25120:23;25112:68;;;;-1:-1:-1;;;25112:68:0;;;;;;;:::i;:::-;61826:8:::1;:17:::0;;;::::1;;::::0;::::1;-1:-1:-1::0;;61826:17:0;;::::1;::::0;;;::::1;::::0;;61766:83::o;25809:201::-;24973:6;;-1:-1:-1;;;;;24973:6:0;23704:10;25120:23;25112:68;;;;-1:-1:-1;;;25112:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;25898:22:0;::::1;25890:73;;;::::0;-1:-1:-1;;;25890:73:0;;10207:2:1;25890:73:0::1;::::0;::::1;10189:21:1::0;10246:2;10226:18;;;10219:30;10285:34;10265:18;;;10258:62;-1:-1:-1;;;10336:18:1;;;10329:36;10382:19;;25890:73:0::1;10005:402:1::0;25890:73:0::1;25974:28;25993:8;25974:18;:28::i;59151:673::-:0;1848:1;2446:7;;:19;;2438:63;;;;-1:-1:-1;;;2438:63:0;;20941:2:1;2438:63:0;;;20923:21:1;20980:2;20960:18;;;20953:30;21019:33;20999:18;;;20992:61;21070:18;;2438:63:0;20739:355:1;2438:63:0;1848:1;2579:7;:18;59305:22:::1;::::0;;59316:10:::1;59305:22;::::0;::::1;7499:51:1::0;59274:76:0::1;::::0;7472:18:1;59305:22:0::1;;;;;;;;;;;;59295:33;;;;;;59330:19;;59274:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;59274:20:0::1;::::0;-1:-1:-1;;;59274:76:0:i:1;:::-;59266:116;;;::::0;-1:-1:-1;;;59266:116:0;;20585:2:1;59266:116:0::1;::::0;::::1;20567:21:1::0;20624:2;20604:18;;;20597:30;20663:29;20643:18;;;20636:57;20710:18;;59266:116:0::1;20383:351:1::0;59266:116:0::1;59397:13;::::0;::::1;;59389:47;;;::::0;-1:-1:-1;;;59389:47:0;;20235:2:1;59389:47:0::1;::::0;::::1;20217:21:1::0;20274:2;20254:18;;;20247:30;-1:-1:-1;;;20293:18:1;;;20286:51;20354:18;;59389:47:0::1;20033:345:1::0;59389:47:0::1;59466:23;;59451:11;:38;;59443:95;;;::::0;-1:-1:-1;;;59443:95:0;;17326:2:1;59443:95:0::1;::::0;::::1;17308:21:1::0;17365:2;17345:18;;;17338:30;17404:34;17384:18;;;17377:62;-1:-1:-1;;;17455:18:1;;;17448:42;17507:19;;59443:95:0::1;17124:408:1::0;59443:95:0::1;59611:23;::::0;59579:10:::1;59553:37;::::0;;;:25:::1;:37;::::0;;;;;:54:::1;::::0;59595:11;59553:41:::1;:54::i;:::-;:81;;59545:178;;;::::0;-1:-1:-1;;;59545:178:0;;18507:2:1;59545:178:0::1;::::0;::::1;18489:21:1::0;18546:2;18526:18;;;18519:30;18585:34;18565:18;;;18558:62;18656:34;18636:18;;;18629:62;-1:-1:-1;;;18707:19:1;;;18700:51;18768:19;;59545:178:0::1;18305:488:1::0;59545:178:0::1;59758:10;59732:37;::::0;;;:25:::1;:37;::::0;;;;:52;;59773:11;;59732:37;:52:::1;::::0;59773:11;;59732:52:::1;:::i;:::-;::::0;;;-1:-1:-1;59791:27:0::1;::::0;-1:-1:-1;59806:11:0;59791:14:::1;:27::i;:::-;-1:-1:-1::0;;1804:1:0;2758:7;:22;-1:-1:-1;59151:673:0:o;54834:174::-;54909:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;54909:29:0;-1:-1:-1;;;;;54909:29:0;;;;;;;;:24;;54963:23;54909:24;54963:14;:23::i;:::-;-1:-1:-1;;;;;54954:46:0;;;;;;;;;;;54834:174;;:::o;50982:348::-;51075:4;50777:16;;;:7;:16;;;;;;-1:-1:-1;;;;;50777:16:0;51092:73;;;;-1:-1:-1;;;51092:73:0;;13354:2:1;51092:73:0;;;13336:21:1;13393:2;13373:18;;;13366:30;13432:34;13412:18;;;13405:62;-1:-1:-1;;;13483:18:1;;;13476:42;13535:19;;51092:73:0;13152:408:1;51092:73:0;51176:13;51192:23;51207:7;51192:14;:23::i;:::-;51176:39;;51245:5;-1:-1:-1;;;;;51234:16:0;:7;-1:-1:-1;;;;;51234:16:0;;:51;;;;51278:7;-1:-1:-1;;;;;51254:31:0;:20;51266:7;51254:11;:20::i;:::-;-1:-1:-1;;;;;51254:31:0;;51234:51;:87;;;-1:-1:-1;;;;;;48074:25:0;;;48050:4;48074:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;51289:32;51226:96;50982:348;-1:-1:-1;;;;50982:348:0:o;54091:625::-;54250:4;-1:-1:-1;;;;;54223:31:0;:23;54238:7;54223:14;:23::i;:::-;-1:-1:-1;;;;;54223:31:0;;54215:81;;;;-1:-1:-1;;;54215:81:0;;10614:2:1;54215:81:0;;;10596:21:1;10653:2;10633:18;;;10626:30;10692:34;10672:18;;;10665:62;-1:-1:-1;;;10743:18:1;;;10736:35;10788:19;;54215:81:0;10412:401:1;54215:81:0;-1:-1:-1;;;;;54315:16:0;;54307:65;;;;-1:-1:-1;;;54307:65:0;;12192:2:1;54307:65:0;;;12174:21:1;12231:2;12211:18;;;12204:30;12270:34;12250:18;;;12243:62;-1:-1:-1;;;12321:18:1;;;12314:34;12365:19;;54307:65:0;11990:400:1;54307:65:0;54489:29;54506:1;54510:7;54489:8;:29::i;:::-;-1:-1:-1;;;;;54531:15:0;;;;;;:9;:15;;;;;:20;;54550:1;;54531:15;:20;;54550:1;;54531:20;:::i;:::-;;;;-1:-1:-1;;;;;;;54562:13:0;;;;;;:9;:13;;;;;:18;;54579:1;;54562:13;:18;;54579:1;;54562:18;:::i;:::-;;;;-1:-1:-1;;54591:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;54591:21:0;-1:-1:-1;;;;;54591:21:0;;;;;;;;;54630:27;;54591:16;;54630:27;;;;;;;47027:341;46957:411;;:::o;5657:98::-;5715:7;5742:5;5746:1;5742;:5;:::i;51672:110::-;51748:26;51758:2;51762:7;51748:26;;;;;;;;;;;;:9;:26::i;26170:191::-;26263:6;;;-1:-1:-1;;;;;26280:17:0;;;-1:-1:-1;;;;;;26280:17:0;;;;;;;26313:40;;26263:6;;;26280:17;26263:6;;26313:40;;26244:16;;26313:40;26233:128;26170:191;:::o;60149:549::-;60232:1;60218:11;:15;60210:58;;;;-1:-1:-1;;;60210:58:0;;14608:2:1;60210:58:0;;;14590:21:1;14647:2;14627:18;;;14620:30;14686:32;14666:18;;;14659:60;14736:18;;60210:58:0;14406:354:1;60210:58:0;60320:9;;60283:33;60304:11;60283:16;:6;10786:14;;10694:114;60283:33;:46;;60275:106;;;;-1:-1:-1;;;60275:106:0;;13767:2:1;60275:106:0;;;13749:21:1;13806:2;13786:18;;;13779:30;13845:34;13825:18;;;13818:62;-1:-1:-1;;;13896:18:1;;;13889:45;13951:19;;60275:106:0;13565:411:1;60275:106:0;60409:4;;:21;;60418:11;60409:8;:21::i;:::-;60396:9;:34;;60388:82;;;;-1:-1:-1;;;60388:82:0;;21301:2:1;60388:82:0;;;21283:21:1;21340:2;21320:18;;;21313:30;21379:34;21359:18;;;21352:62;-1:-1:-1;;;21430:18:1;;;21423:33;21473:19;;60388:82:0;21099:399:1;60388:82:0;60484:9;60479:214;60503:11;60499:1;:15;60479:214;;;60530:17;60550:16;:6;10786:14;;10694:114;60550:16;60530:36;;60593:9;;60581;:21;60577:109;;;60615:18;:6;10905:19;;10923:1;10905:19;;;10816:127;60615:18;60644:32;60654:10;60666:9;60644;:32::i;:::-;-1:-1:-1;60516:3:0;;;;:::i;:::-;;;;60479:214;;55150:315;55305:8;-1:-1:-1;;;;;55296:17:0;:5;-1:-1:-1;;;;;55296:17:0;;;55288:55;;;;-1:-1:-1;;;55288:55:0;;12597:2:1;55288:55:0;;;12579:21:1;12636:2;12616:18;;;12609:30;12675:27;12655:18;;;12648:55;12720:18;;55288:55:0;12395:349:1;55288:55:0;-1:-1:-1;;;;;55354:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;55354:46:0;;;;;;;;;;55416:41;;8194::1;;;55416::0;;8167:18:1;55416:41:0;;;;;;;55150:315;;;:::o;50060:::-;50217:28;50227:4;50233:2;50237:7;50217:9;:28::i;:::-;50264:48;50287:4;50293:2;50297:7;50306:5;50264:22;:48::i;:::-;50256:111;;;;-1:-1:-1;;;50256:111:0;;;;;;;:::i;62945:104::-;63005:13;63034:9;63027:16;;;;;:::i;11652:723::-;11708:13;11929:10;11925:53;;-1:-1:-1;;11956:10:0;;;;;;;;;;;;-1:-1:-1;;;11956:10:0;;;;;11652:723::o;11925:53::-;12003:5;11988:12;12044:78;12051:9;;12044:78;;12077:8;;;;:::i;:::-;;-1:-1:-1;12100:10:0;;-1:-1:-1;12108:2:0;12100:10;;:::i;:::-;;;12044:78;;;12132:19;12164:6;12154:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12154:17:0;;12132:39;;12182:154;12189:10;;12182:154;;12216:11;12226:1;12216:11;;:::i;:::-;;-1:-1:-1;12285:10:0;12293:2;12285:5;:10;:::i;:::-;12272:24;;:2;:24;:::i;:::-;12259:39;;12242:6;12249;12242:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;12242:56:0;;;;;;;;-1:-1:-1;12313:11:0;12322:2;12313:11;;:::i;:::-;;;12182:154;;63109:174;63198:4;63270:7;24973:6;;-1:-1:-1;;;;;24973:6:0;;24900:87;63270:7;-1:-1:-1;;;;;63218:59:0;:48;63256:9;63218:29;:4;21832:58;;7000:66:1;21832:58:0;;;6988:79:1;7083:12;;;7076:28;;;21699:7:0;;7120:12:1;;21832:58:0;;;;;;;;;;;;21822:69;;;;;;21815:76;;21630:269;;;;63218:29;:37;;:48::i;:::-;-1:-1:-1;;;;;63218:59:0;;;63109:174;-1:-1:-1;;;63109:174:0:o;52009:321::-;52139:18;52145:2;52149:7;52139:5;:18::i;:::-;52190:54;52221:1;52225:2;52229:7;52238:5;52190:22;:54::i;:::-;52168:154;;;;-1:-1:-1;;;52168:154:0;;;;;;;:::i;6395:98::-;6453:7;6480:5;6484:1;6480;:5;:::i;56030:799::-;56185:4;-1:-1:-1;;;;;56206:13:0;;27896:19;:23;56202:620;;56242:72;;-1:-1:-1;;;56242:72:0;;-1:-1:-1;;;;;56242:36:0;;;;;:72;;23704:10;;56293:4;;56299:7;;56308:5;;56242:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56242:72:0;;;;;;;;-1:-1:-1;;56242:72:0;;;;;;;;;;;;:::i;:::-;;;56238:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56484:13:0;;56480:272;;56527:60;;-1:-1:-1;;;56527:60:0;;;;;;;:::i;56480:272::-;56702:6;56696:13;56687:6;56683:2;56679:15;56672:38;56238:529;-1:-1:-1;;;;;;56365:51:0;-1:-1:-1;;;56365:51:0;;-1:-1:-1;56358:58:0;;56202:620;-1:-1:-1;56806:4:0;56030:799;;;;;;:::o;17828:231::-;17906:7;17927:17;17946:18;17968:27;17979:4;17985:9;17968:10;:27::i;:::-;17926:69;;;;18006:18;18018:5;18006:11;:18::i;:::-;-1:-1:-1;18042:9:0;17828:231;-1:-1:-1;;;17828:231:0:o;52666:439::-;-1:-1:-1;;;;;52746:16:0;;52738:61;;;;-1:-1:-1;;;52738:61:0;;16191:2:1;52738:61:0;;;16173:21:1;;;16210:18;;;16203:30;16269:34;16249:18;;;16242:62;16321:18;;52738:61:0;15989:356:1;52738:61:0;50753:4;50777:16;;;:7;:16;;;;;;-1:-1:-1;;;;;50777:16:0;:30;52810:58;;;;-1:-1:-1;;;52810:58:0;;11020:2:1;52810:58:0;;;11002:21:1;11059:2;11039:18;;;11032:30;11098;11078:18;;;11071:58;11146:18;;52810:58:0;10818:352:1;52810:58:0;-1:-1:-1;;;;;52939:13:0;;;;;;:9;:13;;;;;:18;;52956:1;;52939:13;:18;;52956:1;;52939:18;:::i;:::-;;;;-1:-1:-1;;52968:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;52968:21:0;-1:-1:-1;;;;;52968:21:0;;;;;;;;53007:33;;52968:16;;;53007:33;;52968:16;;53007:33;62257:22:::1;62183:102:::0;:::o;15718:1308::-;15799:7;15808:12;16033:9;:16;16053:2;16033:22;16029:990;;;16329:4;16314:20;;16308:27;16379:4;16364:20;;16358:27;16437:4;16422:20;;16416:27;16072:9;16408:36;16480:25;16491:4;16408:36;16308:27;16358;16480:10;:25::i;:::-;16473:32;;;;;;;;;16029:990;16527:9;:16;16547:2;16527:22;16523:496;;;16802:4;16787:20;;16781:27;16853:4;16838:20;;16832:27;16895:23;16906:4;16781:27;16832;16895:10;:23::i;:::-;16888:30;;;;;;;;16523:496;-1:-1:-1;16967:1:0;;-1:-1:-1;16971:35:0;16523:496;15718:1308;;;;;:::o;13989:643::-;14067:20;14058:5;:29;;;;;;;;:::i;:::-;;14054:571;;;13989:643;:::o;14054:571::-;14165:29;14156:5;:38;;;;;;;;:::i;:::-;;14152:473;;;14211:34;;-1:-1:-1;;;14211:34:0;;9075:2:1;14211:34:0;;;9057:21:1;9114:2;9094:18;;;9087:30;9153:26;9133:18;;;9126:54;9197:18;;14211:34:0;8873:348:1;14152:473:0;14276:35;14267:5;:44;;;;;;;;:::i;:::-;;14263:362;;;14328:41;;-1:-1:-1;;;14328:41:0;;9428:2:1;14328:41:0;;;9410:21:1;9467:2;9447:18;;;9440:30;9506:33;9486:18;;;9479:61;9557:18;;14328:41:0;9226:355:1;14263:362:0;14400:30;14391:5;:39;;;;;;;;:::i;:::-;;14387:238;;;14447:44;;-1:-1:-1;;;14447:44:0;;12951:2:1;14447:44:0;;;12933:21:1;12990:2;12970:18;;;12963:30;13029:34;13009:18;;;13002:62;-1:-1:-1;;;13080:18:1;;;13073:32;13122:19;;14447:44:0;12749:398:1;14387:238:0;14522:30;14513:5;:39;;;;;;;;:::i;:::-;;14509:116;;;14569:44;;-1:-1:-1;;;14569:44:0;;15788:2:1;14569:44:0;;;15770:21:1;15827:2;15807:18;;;15800:30;15866:34;15846:18;;;15839:62;-1:-1:-1;;;15917:18:1;;;15910:32;15959:19;;14569:44:0;15586:398:1;19280:1632:0;19411:7;;20345:66;20332:79;;20328:163;;;-1:-1:-1;20444:1:0;;-1:-1:-1;20448:30:0;20428:51;;20328:163;20505:1;:7;;20510:2;20505:7;;:18;;;;;20516:1;:7;;20521:2;20516:7;;20505:18;20501:102;;;-1:-1:-1;20556:1:0;;-1:-1:-1;20560:30:0;20540:51;;20501:102;20717:24;;;20700:14;20717:24;;;;;;;;;8473:25:1;;;8546:4;8534:17;;8514:18;;;8507:45;;;;8568:18;;;8561:34;;;8611:18;;;8604:34;;;20717:24:0;;8445:19:1;;20717:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;20717:24:0;;-1:-1:-1;;20717:24:0;;;-1:-1:-1;;;;;;;20756:20:0;;20752:103;;20809:1;20813:29;20793:50;;;;;;;20752:103;20875:6;-1:-1:-1;20883:20:0;;-1:-1:-1;19280:1632:0;;;;;;;;:::o;18322:344::-;18436:7;;-1:-1:-1;;;;;18482:80:0;;18436:7;18589:25;18605:3;18590:18;;;18612:2;18589:25;:::i;:::-;18573:42;;18633:25;18644:4;18650:1;18653;18656;18633:10;:25::i;:::-;18626:32;;;;;;18322:344;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:631:1;78:5;108:18;149:2;141:6;138:14;135:40;;;155:18;;:::i;:::-;230:2;224:9;198:2;284:15;;-1:-1:-1;;280:24:1;;;306:2;276:33;272:42;260:55;;;330:18;;;350:22;;;327:46;324:72;;;376:18;;:::i;:::-;416:10;412:2;405:22;445:6;436:15;;475:6;467;460:22;515:3;506:6;501:3;497:16;494:25;491:45;;;532:1;529;522:12;491:45;582:6;577:3;570:4;562:6;558:17;545:44;637:1;630:4;621:6;613;609:19;605:30;598:41;;;;14:631;;;;;:::o;650:173::-;718:20;;-1:-1:-1;;;;;767:31:1;;757:42;;747:70;;813:1;810;803:12;747:70;650:173;;;:::o;828:160::-;893:20;;949:13;;942:21;932:32;;922:60;;978:1;975;968:12;993:186;1052:6;1105:2;1093:9;1084:7;1080:23;1076:32;1073:52;;;1121:1;1118;1111:12;1073:52;1144:29;1163:9;1144:29;:::i;1184:260::-;1252:6;1260;1313:2;1301:9;1292:7;1288:23;1284:32;1281:52;;;1329:1;1326;1319:12;1281:52;1352:29;1371:9;1352:29;:::i;:::-;1342:39;;1400:38;1434:2;1423:9;1419:18;1400:38;:::i;:::-;1390:48;;1184:260;;;;;:::o;1449:328::-;1526:6;1534;1542;1595:2;1583:9;1574:7;1570:23;1566:32;1563:52;;;1611:1;1608;1601:12;1563:52;1634:29;1653:9;1634:29;:::i;:::-;1624:39;;1682:38;1716:2;1705:9;1701:18;1682:38;:::i;:::-;1672:48;;1767:2;1756:9;1752:18;1739:32;1729:42;;1449:328;;;;;:::o;1782:666::-;1877:6;1885;1893;1901;1954:3;1942:9;1933:7;1929:23;1925:33;1922:53;;;1971:1;1968;1961:12;1922:53;1994:29;2013:9;1994:29;:::i;:::-;1984:39;;2042:38;2076:2;2065:9;2061:18;2042:38;:::i;:::-;2032:48;;2127:2;2116:9;2112:18;2099:32;2089:42;;2182:2;2171:9;2167:18;2154:32;2209:18;2201:6;2198:30;2195:50;;;2241:1;2238;2231:12;2195:50;2264:22;;2317:4;2309:13;;2305:27;-1:-1:-1;2295:55:1;;2346:1;2343;2336:12;2295:55;2369:73;2434:7;2429:2;2416:16;2411:2;2407;2403:11;2369:73;:::i;:::-;2359:83;;;1782:666;;;;;;;:::o;2453:254::-;2518:6;2526;2579:2;2567:9;2558:7;2554:23;2550:32;2547:52;;;2595:1;2592;2585:12;2547:52;2618:29;2637:9;2618:29;:::i;:::-;2608:39;;2666:35;2697:2;2686:9;2682:18;2666:35;:::i;2712:254::-;2780:6;2788;2841:2;2829:9;2820:7;2816:23;2812:32;2809:52;;;2857:1;2854;2847:12;2809:52;2880:29;2899:9;2880:29;:::i;:::-;2870:39;2956:2;2941:18;;;;2928:32;;-1:-1:-1;;;2712:254:1:o;2971:180::-;3027:6;3080:2;3068:9;3059:7;3055:23;3051:32;3048:52;;;3096:1;3093;3086:12;3048:52;3119:26;3135:9;3119:26;:::i;3156:245::-;3214:6;3267:2;3255:9;3246:7;3242:23;3238:32;3235:52;;;3283:1;3280;3273:12;3235:52;3322:9;3309:23;3341:30;3365:5;3341:30;:::i;3406:249::-;3475:6;3528:2;3516:9;3507:7;3503:23;3499:32;3496:52;;;3544:1;3541;3534:12;3496:52;3576:9;3570:16;3595:30;3619:5;3595:30;:::i;3660:450::-;3729:6;3782:2;3770:9;3761:7;3757:23;3753:32;3750:52;;;3798:1;3795;3788:12;3750:52;3838:9;3825:23;3871:18;3863:6;3860:30;3857:50;;;3903:1;3900;3893:12;3857:50;3926:22;;3979:4;3971:13;;3967:27;-1:-1:-1;3957:55:1;;4008:1;4005;3998:12;3957:55;4031:73;4096:7;4091:2;4078:16;4073:2;4069;4065:11;4031:73;:::i;4115:180::-;4174:6;4227:2;4215:9;4206:7;4202:23;4198:32;4195:52;;;4243:1;4240;4233:12;4195:52;-1:-1:-1;4266:23:1;;4115:180;-1:-1:-1;4115:180:1:o;4300:659::-;4379:6;4387;4395;4448:2;4436:9;4427:7;4423:23;4419:32;4416:52;;;4464:1;4461;4454:12;4416:52;4500:9;4487:23;4477:33;;4561:2;4550:9;4546:18;4533:32;4584:18;4625:2;4617:6;4614:14;4611:34;;;4641:1;4638;4631:12;4611:34;4679:6;4668:9;4664:22;4654:32;;4724:7;4717:4;4713:2;4709:13;4705:27;4695:55;;4746:1;4743;4736:12;4695:55;4786:2;4773:16;4812:2;4804:6;4801:14;4798:34;;;4828:1;4825;4818:12;4798:34;4873:7;4868:2;4859:6;4855:2;4851:15;4847:24;4844:37;4841:57;;;4894:1;4891;4884:12;4841:57;4925:2;4921;4917:11;4907:21;;4947:6;4937:16;;;;;4300:659;;;;;:::o;4964:257::-;5005:3;5043:5;5037:12;5070:6;5065:3;5058:19;5086:63;5142:6;5135:4;5130:3;5126:14;5119:4;5112:5;5108:16;5086:63;:::i;:::-;5203:2;5182:15;-1:-1:-1;;5178:29:1;5169:39;;;;5210:4;5165:50;;4964:257;-1:-1:-1;;4964:257:1:o;5226:1527::-;5450:3;5488:6;5482:13;5514:4;5527:51;5571:6;5566:3;5561:2;5553:6;5549:15;5527:51;:::i;:::-;5641:13;;5600:16;;;;5663:55;5641:13;5600:16;5685:15;;;5663:55;:::i;:::-;5807:13;;5740:20;;;5780:1;;5867;5889:18;;;;5942;;;;5969:93;;6047:4;6037:8;6033:19;6021:31;;5969:93;6110:2;6100:8;6097:16;6077:18;6074:40;6071:167;;;-1:-1:-1;;;6137:33:1;;6193:4;6190:1;6183:15;6223:4;6144:3;6211:17;6071:167;6254:18;6281:110;;;;6405:1;6400:328;;;;6247:481;;6281:110;-1:-1:-1;;6316:24:1;;6302:39;;6361:20;;;;-1:-1:-1;6281:110:1;;6400:328;22106:1;22099:14;;;22143:4;22130:18;;6495:1;6509:169;6523:8;6520:1;6517:15;6509:169;;;6605:14;;6590:13;;;6583:37;6648:16;;;;6540:10;;6509:169;;;6513:3;;6709:8;6702:5;6698:20;6691:27;;6247:481;-1:-1:-1;6744:3:1;;5226:1527;-1:-1:-1;;;;;;;;;;;5226:1527:1:o;7561:488::-;-1:-1:-1;;;;;7830:15:1;;;7812:34;;7882:15;;7877:2;7862:18;;7855:43;7929:2;7914:18;;7907:34;;;7977:3;7972:2;7957:18;;7950:31;;;7755:4;;7998:45;;8023:19;;8015:6;7998:45;:::i;:::-;7990:53;7561:488;-1:-1:-1;;;;;;7561:488:1:o;8649:219::-;8798:2;8787:9;8780:21;8761:4;8818:44;8858:2;8847:9;8843:18;8835:6;8818:44;:::i;9586:414::-;9788:2;9770:21;;;9827:2;9807:18;;;9800:30;9866:34;9861:2;9846:18;;9839:62;-1:-1:-1;;;9932:2:1;9917:18;;9910:48;9990:3;9975:19;;9586:414::o;16763:356::-;16965:2;16947:21;;;16984:18;;;16977:30;17043:34;17038:2;17023:18;;17016:62;17110:2;17095:18;;16763:356::o;19615:413::-;19817:2;19799:21;;;19856:2;19836:18;;;19829:30;19895:34;19890:2;19875:18;;19868:62;-1:-1:-1;;;19961:2:1;19946:18;;19939:47;20018:3;20003:19;;19615:413::o;22159:128::-;22199:3;22230:1;22226:6;22223:1;22220:13;22217:39;;;22236:18;;:::i;:::-;-1:-1:-1;22272:9:1;;22159:128::o;22292:120::-;22332:1;22358;22348:35;;22363:18;;:::i;:::-;-1:-1:-1;22397:9:1;;22292:120::o;22417:168::-;22457:7;22523:1;22519;22515:6;22511:14;22508:1;22505:21;22500:1;22493:9;22486:17;22482:45;22479:71;;;22530:18;;:::i;:::-;-1:-1:-1;22570:9:1;;22417:168::o;22590:125::-;22630:4;22658:1;22655;22652:8;22649:34;;;22663:18;;:::i;:::-;-1:-1:-1;22700:9:1;;22590:125::o;22720:258::-;22792:1;22802:113;22816:6;22813:1;22810:13;22802:113;;;22892:11;;;22886:18;22873:11;;;22866:39;22838:2;22831:10;22802:113;;;22933:6;22930:1;22927:13;22924:48;;;-1:-1:-1;;22968:1:1;22950:16;;22943:27;22720:258::o;22983:380::-;23062:1;23058:12;;;;23105;;;23126:61;;23180:4;23172:6;23168:17;23158:27;;23126:61;23233:2;23225:6;23222:14;23202:18;23199:38;23196:161;;;23279:10;23274:3;23270:20;23267:1;23260:31;23314:4;23311:1;23304:15;23342:4;23339:1;23332:15;23196:161;;22983:380;;;:::o;23368:135::-;23407:3;-1:-1:-1;;23428:17:1;;23425:43;;;23448:18;;:::i;:::-;-1:-1:-1;23495:1:1;23484:13;;23368:135::o;23508:112::-;23540:1;23566;23556:35;;23571:18;;:::i;:::-;-1:-1:-1;23605:9:1;;23508:112::o;23625:127::-;23686:10;23681:3;23677:20;23674:1;23667:31;23717:4;23714:1;23707:15;23741:4;23738:1;23731:15;23757:127;23818:10;23813:3;23809:20;23806:1;23799:31;23849:4;23846:1;23839:15;23873:4;23870:1;23863:15;23889:127;23950:10;23945:3;23941:20;23938:1;23931:31;23981:4;23978:1;23971:15;24005:4;24002:1;23995:15;24021:127;24082:10;24077:3;24073:20;24070:1;24063:31;24113:4;24110:1;24103:15;24137:4;24134:1;24127:15;24153:127;24214:10;24209:3;24205:20;24202:1;24195:31;24245:4;24242:1;24235:15;24269:4;24266:1;24259:15;24285:131;-1:-1:-1;;;;;;24359:32:1;;24349:43;;24339:71;;24406:1;24403;24396:12

Swarm Source

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