ETH Price: $3,657.81 (-5.82%)

Token

Zenlicious (Zenlicious)
 

Overview

Max Total Supply

728 Zenlicious

Holders

512

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
2 Zenlicious
0x46b699d7136703cc637e15998f89f89c2788accd
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Zenlicious is the first-ever food video to pioneer in the NFT space.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Zenlicous

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-04-04
*/

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


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

pragma solidity ^0.8.7;

/**
 * @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/token/ERC20/IERC20.sol


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

pragma solidity ^0.8.7;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.7;


/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

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


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

pragma solidity ^0.8.7;

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


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

/**
 * @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/security/Pausable.sol


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

pragma solidity ^0.8.7;


/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

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


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

pragma solidity ^0.8.7;




/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

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

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, _allowances[owner][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = _allowances[owner][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Spend `amount` form the allowance of `owner` toward `spender`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens 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 amount
    ) 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, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been 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 _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

// File: @openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)

pragma solidity ^0.8.7;



/**
 * @dev ERC20 token with pausable token transfers, minting and burning.
 *
 * Useful for scenarios such as preventing trades until the end of an evaluation
 * period, or having an emergency switch for freezing all token transfers in the
 * event of a large bug.
 */
abstract contract ERC20Pausable is ERC20, Pausable {
    /**
     * @dev See {ERC20-_beforeTokenTransfer}.
     *
     * Requirements:
     *
     * - the contract must not be paused.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, amount);

        require(!paused(), "ERC20Pausable: token transfer while paused");
    }
}

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


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

pragma solidity ^0.8.7;


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

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

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

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


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


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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.7;


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

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

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

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


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

pragma solidity ^0.8.7;


/**
 * @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: ERC721A.sol


// Creator: Chiru Labs

pragma solidity ^0.8.7;

error ApprovalCallerNotOwnerNorApproved();
error ApprovalQueryForNonexistentToken();
error ApproveToCaller();
error ApprovalToCurrentOwner();
error BalanceQueryForZeroAddress();
error MintedQueryForZeroAddress();
error BurnedQueryForZeroAddress();
error AuxQueryForZeroAddress();
error MintToZeroAddress();
error MintZeroQuantity();
error OwnerIndexOutOfBounds();
error OwnerQueryForNonexistentToken();
error TokenIndexOutOfBounds();
error TransferCallerNotOwnerNorApproved();
error TransferFromIncorrectOwner();
error TransferToNonERC721ReceiverImplementer();
error TransferToZeroAddress();
error URIQueryForNonexistentToken();

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Compiler will pack this into a single 256bit word.
    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
    }

    // Compiler will pack this into a single 256bit word.
    struct AddressData {
        // Realistically, 2**64-1 is more than enough.
        uint64 balance;
        // Keeps track of mint count with minimal overhead for tokenomics.
        uint64 numberMinted;
        // Keeps track of burn count with minimal overhead for tokenomics.
        uint64 numberBurned;
        // For miscellaneous variable(s) pertaining to the address
        // (e.g. number of whitelist mint slots used).
        // If there are multiple variables, please pack them into a uint64.
        uint64 aux;
    }

    // The tokenId of the next token to be minted.
    uint256 internal _currentIndex;

    // The number of tokens burned.
    uint256 internal _burnCounter;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned. See ownershipOf implementation for details.
    mapping(uint256 => TokenOwnership) internal _ownerships;

    // Mapping owner address to address data
    mapping(address => AddressData) private _addressData;

    // 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;

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _currentIndex = _startTokenId();
    }

    /**
     * To change the starting tokenId, please override this function.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 0;
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     * @dev Burned tokens are calculated here, use _totalMinted() if you want to count just minted tokens.
     */
    function totalSupply() public view returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than _currentIndex - _startTokenId() times
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view returns (uint256) {
        // Counter underflow is impossible as _currentIndex does not decrement,
        // and it is initialized to _startTokenId()
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

    /**
     * @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 override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return uint256(_addressData[owner].balance);
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        if (owner == address(0)) revert MintedQueryForZeroAddress();
        return uint256(_addressData[owner].numberMinted);
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        if (owner == address(0)) revert BurnedQueryForZeroAddress();
        return uint256(_addressData[owner].numberBurned);
    }

    /**
     * Returns the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        if (owner == address(0)) revert AuxQueryForZeroAddress();
        return _addressData[owner].aux;
    }

    /**
     * Sets the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal {
        if (owner == address(0)) revert AuxQueryForZeroAddress();
        _addressData[owner].aux = aux;
    }

    /**
     * Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around in the collection over time.
     */
    function ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr && curr < _currentIndex) {
                TokenOwnership memory ownership = _ownerships[curr];
                if (!ownership.burned) {
                    if (ownership.addr != address(0)) {
                        return ownership;
                    }
                    // Invariant:
                    // There will always be an ownership that has an address and is not burned
                    // before an ownership that does not have an address and is not burned.
                    // Hence, curr will not underflow.
                    while (true) {
                        curr--;
                        ownership = _ownerships[curr];
                        if (ownership.addr != address(0)) {
                            return ownership;
                        }
                    }
                }
            }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view override returns (address) {
        return ownershipOf(tokenId).addr;
    }

    /**
     * @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) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        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 override {
        address owner = ERC721A.ownerOf(tokenId);
        if (to == owner) revert ApprovalToCurrentOwner();

        if (_msgSender() != owner && !isApprovedForAll(owner, _msgSender())) {
            revert ApprovalCallerNotOwnerNorApproved();
        }

        _approve(to, tokenId, owner);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public override {
        if (operator == _msgSender()) revert ApproveToCaller();

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

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        _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 {
        _transfer(from, to, tokenId);
        if (to.isContract() && !_checkContractOnERC721Received(from, to, tokenId, _data)) {
            revert TransferToNonERC721ReceiverImplementer();
        }
    }

    /**
     * @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`),
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return _startTokenId() <= tokenId && tokenId < _currentIndex &&
            !_ownerships[tokenId].burned;
    }

    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, '');
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        _mint(to, quantity, _data, true);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _mint(
        address to,
        uint256 quantity,
        bytes memory _data,
        bool safe
    ) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            if (safe && to.isContract()) {
                do {
                    emit Transfer(address(0), to, updatedIndex);
                    if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (updatedIndex != end);
                // Reentrancy protection
                if (_currentIndex != startTokenId) revert();
            } else {
                do {
                    emit Transfer(address(0), to, updatedIndex++);
                } while (updatedIndex != end);
            }
            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * 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
    ) private {
        TokenOwnership memory prevOwnership = ownershipOf(tokenId);

        bool isApprovedOrOwner = (_msgSender() == prevOwnership.addr ||
            isApprovedForAll(prevOwnership.addr, _msgSender()) ||
            getApproved(tokenId) == _msgSender());

        if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        if (prevOwnership.addr != from) revert TransferFromIncorrectOwner();
        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

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

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            _addressData[from].balance -= 1;
            _addressData[to].balance += 1;

            _ownerships[tokenId].addr = to;
            _ownerships[tokenId].startTimestamp = uint64(block.timestamp);

            // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            if (_ownerships[nextTokenId].addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId < _currentIndex) {
                    _ownerships[nextTokenId].addr = prevOwnership.addr;
                    _ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

        emit Transfer(from, to, tokenId);
        _afterTokenTransfers(from, to, tokenId, 1);
    }

    /**
     * @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 {
        TokenOwnership memory prevOwnership = ownershipOf(tokenId);

        _beforeTokenTransfers(prevOwnership.addr, address(0), tokenId, 1);

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

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            _addressData[prevOwnership.addr].balance -= 1;
            _addressData[prevOwnership.addr].numberBurned += 1;

            // Keep track of who burned the token, and the timestamp of burning.
            _ownerships[tokenId].addr = prevOwnership.addr;
            _ownerships[tokenId].startTimestamp = uint64(block.timestamp);
            _ownerships[tokenId].burned = true;

            // If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            if (_ownerships[nextTokenId].addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId < _currentIndex) {
                    _ownerships[nextTokenId].addr = prevOwnership.addr;
                    _ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

        emit Transfer(prevOwnership.addr, address(0), tokenId);
        _afterTokenTransfers(prevOwnership.addr, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

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

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target 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 _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
            return retval == IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    /**
     * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
     * And also called before burning one token.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * 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, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes
     * minting.
     * And also called after one token has been burned.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}
}

// File: zenlicious.sol
pragma solidity ^0.8.7;

contract Zenlicous is ERC721A, Ownable, ReentrancyGuard {
    using ECDSA for bytes32;

    enum Status {
        Paused,
        WhitelistSale,
        PublicSale,
        Finished
    }

    Status public status;
    string public baseURI;
    bool public burnLocked = true;
    
    uint256 public tokensReserved;

    uint256 public RESERVED_AMOUNT = 32;
    uint256 public MAX_SUPPLY = 888;
    uint256 public PRICE = 0.15 * 10**18; // 0.15 ETH
    address public signer = 0xa6d9E1682dca1080463CAEa9470d775ec208B6dC;
    address public marketingWallet = 0x55D0790Bc0Fb64d9fE4DC100986B0E7e9Ebce389;

    event Minted(address minter, uint256 amount);
    event StatusChanged(Status status);
    event SignerChanged(address signer);
    event ReservedToken(address minter, address recipient, uint256 amount);
    event BaseURIChanged(string newBaseURI);

    // Constructor
    // ------------------------------------------------------------------------
    constructor()
        ERC721A("Zenlicious", "Zenlicious")
    {}

    function _hash(uint256 maxAllowed, address _address)
        public
        view
        returns (bytes32)
    {
        return keccak256(abi.encode(Strings.toString(maxAllowed), address(this), _address));
    }

    function _verify(bytes32 hash, bytes memory signature)
        internal
        view
        returns (bool)
    {
        return (_recover(hash, signature) == signer);
    }

    function _recover(bytes32 hash, bytes memory signature)
        internal
        pure
        returns (address)
    {
        return hash.toEthSignedMessageHash().recover(signature);
    }

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

    function reserve(address recipient, uint256 amount) external onlyOwner {
        require(amount > 0, "Amount too low");
        require(
            totalSupply() + amount <= MAX_SUPPLY,
            "Max supply exceeded"
        );
        require(
            tokensReserved + amount <= RESERVED_AMOUNT,
            "Max reserve amount exceeded"
        );

        _safeMint(recipient, amount);
        tokensReserved += amount;
        emit ReservedToken(msg.sender, recipient, amount);
    }

    function whitelistMint(uint256 amount, uint256 maxAllowed, bytes calldata signature)
        external
        payable
    {
        require(status == Status.WhitelistSale, "WhitelistSale is not active.");
        require(
            _verify(_hash(maxAllowed, msg.sender), signature),
            "Invalid signature."
        );
        require(PRICE * amount == msg.value, "Price incorrect.");
        require(
            numberMinted(msg.sender) + amount <= maxAllowed,
            "Max mint amount per wallet exceeded."
        );
        require(
            totalSupply() + amount + RESERVED_AMOUNT - tokensReserved <=
                MAX_SUPPLY,
            "Max supply exceeded."
        );
        require(tx.origin == msg.sender, "Contract is not allowed to mint.");
        
        _safeMint(msg.sender, amount);
        emit Minted(msg.sender, amount);
    }


    function mint() external payable {
        require(status == Status.PublicSale, "Public sale is not active.");
        require(tx.origin == msg.sender, "Contract is not allowed to mint.");
        require(
            totalSupply() + 1 + RESERVED_AMOUNT - tokensReserved <=
                MAX_SUPPLY,
            "Max supply exceeded."
        );
        require(PRICE == msg.value, "Price incorrect.");

        _safeMint(msg.sender, 1);
        emit Minted(msg.sender, 1);
    }

    function _startTokenId() internal view override virtual returns (uint256) {
        return 1;
    }

    function withdraw() external nonReentrant onlyOwner {
        uint256 balance = address(this).balance;
        (bool success1, ) = payable(marketingWallet).call{value: balance}("");
        require(success1, "Transfer failed.");
    }

    function setPRICE(uint256 newPRICE) external onlyOwner {
        PRICE = newPRICE;
    }

    function setBaseURI(string calldata newBaseURI) external onlyOwner {
        baseURI = newBaseURI;
        emit BaseURIChanged(newBaseURI);
    }

    function setStatus(Status _status) external onlyOwner {
        status = _status;
        emit StatusChanged(_status);
    }

    function setBurnLocked(bool locked) external onlyOwner {
        burnLocked = locked;
    }

    function setSigner(address newSigner) external onlyOwner {
        signer = newSigner;
        emit SignerChanged(signer);
    }

    function setMarketingWallet(address newMarketingWallet) external onlyOwner {
        marketingWallet = newMarketingWallet;
    }

    function numberMinted(address owner) public view returns (uint256) {
        return _numberMinted(owner);
    }

    function getOwnershipData(uint256 tokenId)
        external
        view
        returns (TokenOwnership memory)
    {
        return ownershipOf(tokenId);
    }

    function burn(uint256 tokenId) public virtual {
        require(burnLocked == false, "Burning is not enabled.");
        require(ownerOf(tokenId) == _msgSender(), "Not owner.");
        _burn(tokenId);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"MintedQueryForZeroAddress","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"newBaseURI","type":"string"}],"name":"BaseURIChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReservedToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"SignerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum Zenlicous.Status","name":"status","type":"uint8"}],"name":"StatusChanged","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_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESERVED_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxAllowed","type":"uint256"},{"internalType":"address","name":"_address","type":"address"}],"name":"_hash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burnLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getOwnershipData","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"}],"internalType":"struct ERC721A.TokenOwnership","name":"","type":"tuple"}],"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":"marketingWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"reserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"locked","type":"bool"}],"name":"setBurnLocked","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newMarketingWallet","type":"address"}],"name":"setMarketingWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPRICE","type":"uint256"}],"name":"setPRICE","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSigner","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum Zenlicous.Status","name":"_status","type":"uint8"}],"name":"setStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"status","outputs":[{"internalType":"enum Zenlicous.Status","name":"","type":"uint8"}],"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":"tokensReserved","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"maxAllowed","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052600c805460ff191660011790556020600e55610378600f55670214e8348c4f0000601055601180546001600160a01b031990811673a6d9e1682dca1080463caea9470d775ec208b6dc17909155601280549091167355d0790bc0fb64d9fe4dc100986b0e7e9ebce3891790553480156200007d57600080fd5b50604080518082018252600a808252695a656e6c6963696f757360b01b602080840182815285518087019096529285528401528151919291620000c39160029162000149565b508051620000d990600390602084019062000149565b5050600160005550620000ec33620000f7565b60016009556200022c565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8280546200015790620001ef565b90600052602060002090601f0160209004810192826200017b5760008555620001c6565b82601f106200019657805160ff1916838001178555620001c6565b82800160010185558215620001c6579182015b82811115620001c6578251825591602001919060010190620001a9565b50620001d4929150620001d8565b5090565b5b80821115620001d45760008155600101620001d9565b600181811c908216806200020457607f821691505b602082108114156200022657634e487b7160e01b600052602260045260246000fd5b50919050565b612be8806200023c6000396000f3fe60806040526004361061023b5760003560e01c80636c0360eb1161012e578063b88d4fde116100ab578063e722ba751161006f578063e722ba75146106a6578063e985e9c5146106c6578063ec596b721461070f578063eea52d3814610722578063f2fde38b1461074257600080fd5b8063b88d4fde14610610578063c87b56dd14610630578063cc47a40b14610650578063d85f274014610670578063dc33e6811461068657600080fd5b80638d859f3e116100f25780638d859f3e146105515780638da5cb5b146105675780639231ab2a1461058557806395d89b41146105db578063a22cb465146105f057600080fd5b80636c0360eb146104c75780636c19e783146104dc57806370a08231146104fc578063715018a61461051c57806375f0a8741461053157600080fd5b806332cb6b0c116101bc578063433adb0511610180578063433adb05146104375780634d3ef8dd1461044d57806355f804b3146104675780635d098b38146104875780636352211e146104a757600080fd5b806332cb6b0c146103ac5780633576e85f146103c25780633ccfd60b146103e257806342842e0e146103f757806342966c681461041757600080fd5b806318160ddd1161020357806318160ddd146102f9578063200d2ed214610325578063238ac9331461034c57806323b872dd1461036c5780632e49d78b1461038c57600080fd5b806301ffc9a71461024057806306fdde0314610275578063081812fc14610297578063095ea7b3146102cf5780631249c58b146102f1575b600080fd5b34801561024c57600080fd5b5061026061025b366004612782565b610762565b60405190151581526020015b60405180910390f35b34801561028157600080fd5b5061028a6107b4565b60405161026c919061299b565b3480156102a357600080fd5b506102b76102b236600461281e565b610846565b6040516001600160a01b03909116815260200161026c565b3480156102db57600080fd5b506102ef6102ea36600461273d565b61088a565b005b6102ef610918565b34801561030557600080fd5b50610317600154600054036000190190565b60405190815260200161026c565b34801561033157600080fd5b50600a5461033f9060ff1681565b60405161026c9190612944565b34801561035857600080fd5b506011546102b7906001600160a01b031681565b34801561037857600080fd5b506102ef6103873660046125fc565b610ada565b34801561039857600080fd5b506102ef6103a73660046127bc565b610ae5565b3480156103b857600080fd5b50610317600f5481565b3480156103ce57600080fd5b506103176103dd366004612837565b610b6d565b3480156103ee57600080fd5b506102ef610baa565b34801561040357600080fd5b506102ef6104123660046125fc565b610ccf565b34801561042357600080fd5b506102ef61043236600461281e565b610cea565b34801561044357600080fd5b50610317600d5481565b34801561045957600080fd5b50600c546102609060ff1681565b34801561047357600080fd5b506102ef6104823660046127dd565b610d96565b34801561049357600080fd5b506102ef6104a23660046125ae565b610e0a565b3480156104b357600080fd5b506102b76104c236600461281e565b610e56565b3480156104d357600080fd5b5061028a610e68565b3480156104e857600080fd5b506102ef6104f73660046125ae565b610ef6565b34801561050857600080fd5b506103176105173660046125ae565b610f6e565b34801561052857600080fd5b506102ef610fbc565b34801561053d57600080fd5b506012546102b7906001600160a01b031681565b34801561055d57600080fd5b5061031760105481565b34801561057357600080fd5b506008546001600160a01b03166102b7565b34801561059157600080fd5b506105a56105a036600461281e565b610ff2565b6040805182516001600160a01b031681526020808401516001600160401b0316908201529181015115159082015260600161026c565b3480156105e757600080fd5b5061028a611018565b3480156105fc57600080fd5b506102ef61060b366004612713565b611027565b34801561061c57600080fd5b506102ef61062b366004612638565b6110bd565b34801561063c57600080fd5b5061028a61064b36600461281e565b61110e565b34801561065c57600080fd5b506102ef61066b36600461273d565b611193565b34801561067c57600080fd5b50610317600e5481565b34801561069257600080fd5b506103176106a13660046125ae565b611327565b3480156106b257600080fd5b506102ef6106c1366004612767565b611332565b3480156106d257600080fd5b506102606106e13660046125c9565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b6102ef61071d36600461285a565b61136f565b34801561072e57600080fd5b506102ef61073d36600461281e565b611633565b34801561074e57600080fd5b506102ef61075d3660046125ae565b611662565b60006001600160e01b031982166380ac58cd60e01b148061079357506001600160e01b03198216635b5e139f60e01b145b806107ae57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600280546107c390612aa4565b80601f01602080910402602001604051908101604052809291908181526020018280546107ef90612aa4565b801561083c5780601f106108115761010080835404028352916020019161083c565b820191906000526020600020905b81548152906001019060200180831161081f57829003601f168201915b5050505050905090565b6000610851826116fa565b61086e576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600061089582610e56565b9050806001600160a01b0316836001600160a01b031614156108ca5760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b038216148015906108ea57506108e881336106e1565b155b15610908576040516367d9dca160e11b815260040160405180910390fd5b610913838383611733565b505050565b6002600a5460ff16600381111561093157610931612b3a565b146109835760405162461bcd60e51b815260206004820152601a60248201527f5075626c69632073616c65206973206e6f74206163746976652e00000000000060448201526064015b60405180910390fd5b3233146109d25760405162461bcd60e51b815260206004820181905260248201527f436f6e7472616374206973206e6f7420616c6c6f77656420746f206d696e742e604482015260640161097a565b600f54600d54600e546109ec600154600054036000190190565b6109f7906001612a16565b610a019190612a16565b610a0b9190612a61565b1115610a505760405162461bcd60e51b815260206004820152601460248201527326b0bc1039bab838363c9032bc31b2b2b232b21760611b604482015260640161097a565b3460105414610a945760405162461bcd60e51b815260206004820152601060248201526f283934b1b29034b731b7b93932b1ba1760811b604482015260640161097a565b610a9f33600161178f565b60408051338152600160208201527f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe910160405180910390a1565b6109138383836117ad565b6008546001600160a01b03163314610b0f5760405162461bcd60e51b815260040161097a906129e1565b600a805482919060ff19166001836003811115610b2e57610b2e612b3a565b02179055507fafa725e7f44cadb687a7043853fa1a7e7b8f0da74ce87ec546e9420f04da8c1e81604051610b629190612944565b60405180910390a150565b6000610b78836119af565b3083604051602001610b8c939291906129ae565b60405160208183030381529060405280519060200120905092915050565b60026009541415610bfd5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161097a565b60026009556008546001600160a01b03163314610c2c5760405162461bcd60e51b815260040161097a906129e1565b60125460405147916000916001600160a01b039091169083908381818185875af1925050503d8060008114610c7d576040519150601f19603f3d011682016040523d82523d6000602084013e610c82565b606091505b5050905080610cc65760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b604482015260640161097a565b50506001600955565b610913838383604051806020016040528060008152506110bd565b600c5460ff1615610d3d5760405162461bcd60e51b815260206004820152601760248201527f4275726e696e67206973206e6f7420656e61626c65642e000000000000000000604482015260640161097a565b33610d4782610e56565b6001600160a01b031614610d8a5760405162461bcd60e51b815260206004820152600a6024820152692737ba1037bbb732b91760b11b604482015260640161097a565b610d9381611ab4565b50565b6008546001600160a01b03163314610dc05760405162461bcd60e51b815260040161097a906129e1565b610dcc600b83836124a8565b507f5411e8ebf1636d9e83d5fc4900bf80cbac82e8790da2a4c94db4895e889eedf68282604051610dfe92919061296c565b60405180910390a15050565b6008546001600160a01b03163314610e345760405162461bcd60e51b815260040161097a906129e1565b601280546001600160a01b0319166001600160a01b0392909216919091179055565b6000610e6182611c1e565b5192915050565b600b8054610e7590612aa4565b80601f0160208091040260200160405190810160405280929190818152602001828054610ea190612aa4565b8015610eee5780601f10610ec357610100808354040283529160200191610eee565b820191906000526020600020905b815481529060010190602001808311610ed157829003601f168201915b505050505081565b6008546001600160a01b03163314610f205760405162461bcd60e51b815260040161097a906129e1565b601180546001600160a01b0319166001600160a01b0383169081179091556040519081527f5719a5656c5cfdaafa148ecf366fd3b0a7fae06449ce2a46225977fb7417e29d90602001610b62565b60006001600160a01b038216610f97576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6008546001600160a01b03163314610fe65760405162461bcd60e51b815260040161097a906129e1565b610ff06000611d45565b565b60408051606081018252600080825260208201819052918101919091526107ae82611c1e565b6060600380546107c390612aa4565b6001600160a01b0382163314156110515760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6110c88484846117ad565b6001600160a01b0383163b151580156110ea57506110e884848484611d97565b155b15611108576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6060611119826116fa565b61113657604051630a14c4b560e41b815260040160405180910390fd5b6000611140611e8e565b9050805160001415611161576040518060200160405280600081525061118c565b8061116b846119af565b60405160200161117c9291906128d8565b6040516020818303038152906040525b9392505050565b6008546001600160a01b031633146111bd5760405162461bcd60e51b815260040161097a906129e1565b600081116111fe5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b604482015260640161097a565b600f5481611213600154600054036000190190565b61121d9190612a16565b11156112615760405162461bcd60e51b815260206004820152601360248201527213585e081cdd5c1c1b1e48195e18d959591959606a1b604482015260640161097a565b600e5481600d546112729190612a16565b11156112c05760405162461bcd60e51b815260206004820152601b60248201527f4d6178207265736572766520616d6f756e742065786365656465640000000000604482015260640161097a565b6112ca828261178f565b80600d60008282546112dc9190612a16565b9091555050604080513381526001600160a01b03841660208201529081018290527fd729ebd340be850113adba35e3218ac6bd77c375ce35c256e3493fdf30b99f3e90606001610dfe565b60006107ae82611e9d565b6008546001600160a01b0316331461135c5760405162461bcd60e51b815260040161097a906129e1565b600c805460ff1916911515919091179055565b6001600a5460ff16600381111561138857611388612b3a565b146113d55760405162461bcd60e51b815260206004820152601c60248201527f57686974656c69737453616c65206973206e6f74206163746976652e00000000604482015260640161097a565b61141e6113e28433610b6d565b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611ef292505050565b61145f5760405162461bcd60e51b815260206004820152601260248201527124b73b30b634b21039b4b3b730ba3ab9329760711b604482015260640161097a565b348460105461146e9190612a42565b146114ae5760405162461bcd60e51b815260206004820152601060248201526f283934b1b29034b731b7b93932b1ba1760811b604482015260640161097a565b82846114b933611327565b6114c39190612a16565b111561151d5760405162461bcd60e51b8152602060048201526024808201527f4d6178206d696e7420616d6f756e74207065722077616c6c65742065786365656044820152633232b21760e11b606482015260840161097a565b600f54600d54600e5486611538600154600054036000190190565b6115429190612a16565b61154c9190612a16565b6115569190612a61565b111561159b5760405162461bcd60e51b815260206004820152601460248201527326b0bc1039bab838363c9032bc31b2b2b232b21760611b604482015260640161097a565b3233146115ea5760405162461bcd60e51b815260206004820181905260248201527f436f6e7472616374206973206e6f7420616c6c6f77656420746f206d696e742e604482015260640161097a565b6115f4338561178f565b60408051338152602081018690527f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe910160405180910390a150505050565b6008546001600160a01b0316331461165d5760405162461bcd60e51b815260040161097a906129e1565b601055565b6008546001600160a01b0316331461168c5760405162461bcd60e51b815260040161097a906129e1565b6001600160a01b0381166116f15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161097a565b610d9381611d45565b60008160011115801561170e575060005482105b80156107ae575050600090815260046020526040902054600160e01b900460ff161590565b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6117a9828260405180602001604052806000815250611f1c565b5050565b60006117b882611c1e565b80519091506000906001600160a01b0316336001600160a01b031614806117e6575081516117e690336106e1565b806118015750336117f684610846565b6001600160a01b0316145b90508061182157604051632ce44b5f60e11b815260040160405180910390fd5b846001600160a01b031682600001516001600160a01b0316146118565760405162a1148160e81b815260040160405180910390fd5b6001600160a01b03841661187d57604051633a954ecd60e21b815260040160405180910390fd5b61188d6000848460000151611733565b6001600160a01b038581166000908152600560209081526040808320805467ffffffffffffffff198082166001600160401b0392831660001901831617909255898616808652838620805493841693831660019081018416949094179055898652600490945282852080546001600160e01b031916909417600160a01b4290921691909102179092559086018083529120549091166119775760005481101561197757825160008281526004602090815260409091208054918601516001600160401b0316600160a01b026001600160e01b03199092166001600160a01b03909316929092171790555b5082846001600160a01b0316866001600160a01b0316600080516020612b9383398151915260405160405180910390a45b5050505050565b6060816119d35750506040805180820190915260018152600360fc1b602082015290565b8160005b81156119fd57806119e781612adf565b91506119f69050600a83612a2e565b91506119d7565b6000816001600160401b03811115611a1757611a17612b66565b6040519080825280601f01601f191660200182016040528015611a41576020820181803683370190505b5090505b8415611aac57611a56600183612a61565b9150611a63600a86612afa565b611a6e906030612a16565b60f81b818381518110611a8357611a83612b50565b60200101906001600160f81b031916908160001a905350611aa5600a86612a2e565b9450611a45565b949350505050565b6000611abf82611c1e565b9050611ad16000838360000151611733565b80516001600160a01b039081166000908152600560209081526040808320805467ffffffffffffffff1981166001600160401b0391821660001901821617909155855185168452818420805467ffffffffffffffff60801b198116600160801b9182900484166001908101851690920217909155865188865260049094528285208054600160e01b9588166001600160e01b031990911617600160a01b42909416939093029290921760ff60e01b1916939093179055908501808352912054909116611be857600054811015611be857815160008281526004602090815260409091208054918501516001600160401b0316600160a01b026001600160e01b03199092166001600160a01b03909316929092171790555b50805160405183916000916001600160a01b0390911690600080516020612b93833981519152908390a450506001805481019055565b60408051606081018252600080825260208201819052918101919091528180600111158015611c4e575060005481105b15611d2c57600081815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff16151591810182905290611d2a5780516001600160a01b031615611cc1579392505050565b5060001901600081815260046020908152604091829020825160608101845290546001600160a01b038116808352600160a01b82046001600160401b031693830193909352600160e01b900460ff1615159281019290925215611d25579392505050565b611cc1565b505b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611dcc903390899088908890600401612907565b602060405180830381600087803b158015611de657600080fd5b505af1925050508015611e16575060408051601f3d908101601f19168201909252611e139181019061279f565b60015b611e71573d808015611e44576040519150601f19603f3d011682016040523d82523d6000602084013e611e49565b606091505b508051611e69576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b6060600b80546107c390612aa4565b60006001600160a01b038216611ec6576040516335ebb31960e01b815260040160405180910390fd5b506001600160a01b0316600090815260056020526040902054600160401b90046001600160401b031690565b6011546000906001600160a01b0316611f0b8484611f29565b6001600160a01b0316149392505050565b6109138383836001611f8c565b600061118c82611f86856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90612133565b6000546001600160a01b038516611fb557604051622e076360e81b815260040160405180910390fd5b83611fd35760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038516600081815260056020908152604080832080546fffffffffffffffffffffffffffffffff1981166001600160401b038083168c018116918217600160401b67ffffffffffffffff1990941690921783900481168c01811690920217909155858452600490925290912080546001600160e01b031916909217600160a01b42909216919091021790558080850183801561207f57506001600160a01b0387163b15155b156120f6575b60405182906001600160a01b03891690600090600080516020612b93833981519152908290a46120be6000888480600101955088611d97565b6120db576040516368d2bf6b60e11b815260040160405180910390fd5b808214156120855782600054146120f157600080fd5b61212a565b5b6040516001830192906001600160a01b03891690600090600080516020612b93833981519152908290a4808214156120f7575b506000556119a8565b60008060006121428585612157565b9150915061214f816121c7565b509392505050565b60008082516041141561218e5760208301516040840151606085015160001a61218287828585612382565b945094505050506121c0565b8251604014156121b857602083015160408401516121ad86838361246f565b9350935050506121c0565b506000905060025b9250929050565b60008160048111156121db576121db612b3a565b14156121e45750565b60018160048111156121f8576121f8612b3a565b14156122465760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161097a565b600281600481111561225a5761225a612b3a565b14156122a85760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161097a565b60038160048111156122bc576122bc612b3a565b14156123155760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161097a565b600481600481111561232957612329612b3a565b1415610d935760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b606482015260840161097a565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156123b95750600090506003612466565b8460ff16601b141580156123d157508460ff16601c14155b156123e25750600090506004612466565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612436573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661245f57600060019250925050612466565b9150600090505b94509492505050565b6000806001600160ff1b0383168161248c60ff86901c601b612a16565b905061249a87828885612382565b935093505050935093915050565b8280546124b490612aa4565b90600052602060002090601f0160209004810192826124d6576000855561251c565b82601f106124ef5782800160ff1982351617855561251c565b8280016001018555821561251c579182015b8281111561251c578235825591602001919060010190612501565b5061252892915061252c565b5090565b5b80821115612528576000815560010161252d565b80356001600160a01b038116811461255857600080fd5b919050565b8035801515811461255857600080fd5b60008083601f84011261257f57600080fd5b5081356001600160401b0381111561259657600080fd5b6020830191508360208285010111156121c057600080fd5b6000602082840312156125c057600080fd5b61118c82612541565b600080604083850312156125dc57600080fd5b6125e583612541565b91506125f360208401612541565b90509250929050565b60008060006060848603121561261157600080fd5b61261a84612541565b925061262860208501612541565b9150604084013590509250925092565b6000806000806080858703121561264e57600080fd5b61265785612541565b935061266560208601612541565b92506040850135915060608501356001600160401b038082111561268857600080fd5b818701915087601f83011261269c57600080fd5b8135818111156126ae576126ae612b66565b604051601f8201601f19908116603f011681019083821181831017156126d6576126d6612b66565b816040528281528a60208487010111156126ef57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561272657600080fd5b61272f83612541565b91506125f36020840161255d565b6000806040838503121561275057600080fd5b61275983612541565b946020939093013593505050565b60006020828403121561277957600080fd5b61118c8261255d565b60006020828403121561279457600080fd5b813561118c81612b7c565b6000602082840312156127b157600080fd5b815161118c81612b7c565b6000602082840312156127ce57600080fd5b81356004811061118c57600080fd5b600080602083850312156127f057600080fd5b82356001600160401b0381111561280657600080fd5b6128128582860161256d565b90969095509350505050565b60006020828403121561283057600080fd5b5035919050565b6000806040838503121561284a57600080fd5b823591506125f360208401612541565b6000806000806060858703121561287057600080fd5b843593506020850135925060408501356001600160401b0381111561289457600080fd5b6128a08782880161256d565b95989497509550505050565b600081518084526128c4816020860160208601612a78565b601f01601f19169290920160200192915050565b600083516128ea818460208801612a78565b8351908301906128fe818360208801612a78565b01949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061293a908301846128ac565b9695505050505050565b602081016004831061296657634e487b7160e01b600052602160045260246000fd5b91905290565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60208152600061118c60208301846128ac565b6060815260006129c160608301866128ac565b6001600160a01b0394851660208401529290931660409091015292915050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60008219821115612a2957612a29612b0e565b500190565b600082612a3d57612a3d612b24565b500490565b6000816000190483118215151615612a5c57612a5c612b0e565b500290565b600082821015612a7357612a73612b0e565b500390565b60005b83811015612a93578181015183820152602001612a7b565b838111156111085750506000910152565b600181811c90821680612ab857607f821691505b60208210811415612ad957634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612af357612af3612b0e565b5060010190565b600082612b0957612b09612b24565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610d9357600080fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220b9562ade8609fed14007380afea1c962ad1fed8f086f9124c4b233c1eca8cf3064736f6c63430008070033

Deployed Bytecode

0x60806040526004361061023b5760003560e01c80636c0360eb1161012e578063b88d4fde116100ab578063e722ba751161006f578063e722ba75146106a6578063e985e9c5146106c6578063ec596b721461070f578063eea52d3814610722578063f2fde38b1461074257600080fd5b8063b88d4fde14610610578063c87b56dd14610630578063cc47a40b14610650578063d85f274014610670578063dc33e6811461068657600080fd5b80638d859f3e116100f25780638d859f3e146105515780638da5cb5b146105675780639231ab2a1461058557806395d89b41146105db578063a22cb465146105f057600080fd5b80636c0360eb146104c75780636c19e783146104dc57806370a08231146104fc578063715018a61461051c57806375f0a8741461053157600080fd5b806332cb6b0c116101bc578063433adb0511610180578063433adb05146104375780634d3ef8dd1461044d57806355f804b3146104675780635d098b38146104875780636352211e146104a757600080fd5b806332cb6b0c146103ac5780633576e85f146103c25780633ccfd60b146103e257806342842e0e146103f757806342966c681461041757600080fd5b806318160ddd1161020357806318160ddd146102f9578063200d2ed214610325578063238ac9331461034c57806323b872dd1461036c5780632e49d78b1461038c57600080fd5b806301ffc9a71461024057806306fdde0314610275578063081812fc14610297578063095ea7b3146102cf5780631249c58b146102f1575b600080fd5b34801561024c57600080fd5b5061026061025b366004612782565b610762565b60405190151581526020015b60405180910390f35b34801561028157600080fd5b5061028a6107b4565b60405161026c919061299b565b3480156102a357600080fd5b506102b76102b236600461281e565b610846565b6040516001600160a01b03909116815260200161026c565b3480156102db57600080fd5b506102ef6102ea36600461273d565b61088a565b005b6102ef610918565b34801561030557600080fd5b50610317600154600054036000190190565b60405190815260200161026c565b34801561033157600080fd5b50600a5461033f9060ff1681565b60405161026c9190612944565b34801561035857600080fd5b506011546102b7906001600160a01b031681565b34801561037857600080fd5b506102ef6103873660046125fc565b610ada565b34801561039857600080fd5b506102ef6103a73660046127bc565b610ae5565b3480156103b857600080fd5b50610317600f5481565b3480156103ce57600080fd5b506103176103dd366004612837565b610b6d565b3480156103ee57600080fd5b506102ef610baa565b34801561040357600080fd5b506102ef6104123660046125fc565b610ccf565b34801561042357600080fd5b506102ef61043236600461281e565b610cea565b34801561044357600080fd5b50610317600d5481565b34801561045957600080fd5b50600c546102609060ff1681565b34801561047357600080fd5b506102ef6104823660046127dd565b610d96565b34801561049357600080fd5b506102ef6104a23660046125ae565b610e0a565b3480156104b357600080fd5b506102b76104c236600461281e565b610e56565b3480156104d357600080fd5b5061028a610e68565b3480156104e857600080fd5b506102ef6104f73660046125ae565b610ef6565b34801561050857600080fd5b506103176105173660046125ae565b610f6e565b34801561052857600080fd5b506102ef610fbc565b34801561053d57600080fd5b506012546102b7906001600160a01b031681565b34801561055d57600080fd5b5061031760105481565b34801561057357600080fd5b506008546001600160a01b03166102b7565b34801561059157600080fd5b506105a56105a036600461281e565b610ff2565b6040805182516001600160a01b031681526020808401516001600160401b0316908201529181015115159082015260600161026c565b3480156105e757600080fd5b5061028a611018565b3480156105fc57600080fd5b506102ef61060b366004612713565b611027565b34801561061c57600080fd5b506102ef61062b366004612638565b6110bd565b34801561063c57600080fd5b5061028a61064b36600461281e565b61110e565b34801561065c57600080fd5b506102ef61066b36600461273d565b611193565b34801561067c57600080fd5b50610317600e5481565b34801561069257600080fd5b506103176106a13660046125ae565b611327565b3480156106b257600080fd5b506102ef6106c1366004612767565b611332565b3480156106d257600080fd5b506102606106e13660046125c9565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b6102ef61071d36600461285a565b61136f565b34801561072e57600080fd5b506102ef61073d36600461281e565b611633565b34801561074e57600080fd5b506102ef61075d3660046125ae565b611662565b60006001600160e01b031982166380ac58cd60e01b148061079357506001600160e01b03198216635b5e139f60e01b145b806107ae57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600280546107c390612aa4565b80601f01602080910402602001604051908101604052809291908181526020018280546107ef90612aa4565b801561083c5780601f106108115761010080835404028352916020019161083c565b820191906000526020600020905b81548152906001019060200180831161081f57829003601f168201915b5050505050905090565b6000610851826116fa565b61086e576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600061089582610e56565b9050806001600160a01b0316836001600160a01b031614156108ca5760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b038216148015906108ea57506108e881336106e1565b155b15610908576040516367d9dca160e11b815260040160405180910390fd5b610913838383611733565b505050565b6002600a5460ff16600381111561093157610931612b3a565b146109835760405162461bcd60e51b815260206004820152601a60248201527f5075626c69632073616c65206973206e6f74206163746976652e00000000000060448201526064015b60405180910390fd5b3233146109d25760405162461bcd60e51b815260206004820181905260248201527f436f6e7472616374206973206e6f7420616c6c6f77656420746f206d696e742e604482015260640161097a565b600f54600d54600e546109ec600154600054036000190190565b6109f7906001612a16565b610a019190612a16565b610a0b9190612a61565b1115610a505760405162461bcd60e51b815260206004820152601460248201527326b0bc1039bab838363c9032bc31b2b2b232b21760611b604482015260640161097a565b3460105414610a945760405162461bcd60e51b815260206004820152601060248201526f283934b1b29034b731b7b93932b1ba1760811b604482015260640161097a565b610a9f33600161178f565b60408051338152600160208201527f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe910160405180910390a1565b6109138383836117ad565b6008546001600160a01b03163314610b0f5760405162461bcd60e51b815260040161097a906129e1565b600a805482919060ff19166001836003811115610b2e57610b2e612b3a565b02179055507fafa725e7f44cadb687a7043853fa1a7e7b8f0da74ce87ec546e9420f04da8c1e81604051610b629190612944565b60405180910390a150565b6000610b78836119af565b3083604051602001610b8c939291906129ae565b60405160208183030381529060405280519060200120905092915050565b60026009541415610bfd5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161097a565b60026009556008546001600160a01b03163314610c2c5760405162461bcd60e51b815260040161097a906129e1565b60125460405147916000916001600160a01b039091169083908381818185875af1925050503d8060008114610c7d576040519150601f19603f3d011682016040523d82523d6000602084013e610c82565b606091505b5050905080610cc65760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b604482015260640161097a565b50506001600955565b610913838383604051806020016040528060008152506110bd565b600c5460ff1615610d3d5760405162461bcd60e51b815260206004820152601760248201527f4275726e696e67206973206e6f7420656e61626c65642e000000000000000000604482015260640161097a565b33610d4782610e56565b6001600160a01b031614610d8a5760405162461bcd60e51b815260206004820152600a6024820152692737ba1037bbb732b91760b11b604482015260640161097a565b610d9381611ab4565b50565b6008546001600160a01b03163314610dc05760405162461bcd60e51b815260040161097a906129e1565b610dcc600b83836124a8565b507f5411e8ebf1636d9e83d5fc4900bf80cbac82e8790da2a4c94db4895e889eedf68282604051610dfe92919061296c565b60405180910390a15050565b6008546001600160a01b03163314610e345760405162461bcd60e51b815260040161097a906129e1565b601280546001600160a01b0319166001600160a01b0392909216919091179055565b6000610e6182611c1e565b5192915050565b600b8054610e7590612aa4565b80601f0160208091040260200160405190810160405280929190818152602001828054610ea190612aa4565b8015610eee5780601f10610ec357610100808354040283529160200191610eee565b820191906000526020600020905b815481529060010190602001808311610ed157829003601f168201915b505050505081565b6008546001600160a01b03163314610f205760405162461bcd60e51b815260040161097a906129e1565b601180546001600160a01b0319166001600160a01b0383169081179091556040519081527f5719a5656c5cfdaafa148ecf366fd3b0a7fae06449ce2a46225977fb7417e29d90602001610b62565b60006001600160a01b038216610f97576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6008546001600160a01b03163314610fe65760405162461bcd60e51b815260040161097a906129e1565b610ff06000611d45565b565b60408051606081018252600080825260208201819052918101919091526107ae82611c1e565b6060600380546107c390612aa4565b6001600160a01b0382163314156110515760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6110c88484846117ad565b6001600160a01b0383163b151580156110ea57506110e884848484611d97565b155b15611108576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6060611119826116fa565b61113657604051630a14c4b560e41b815260040160405180910390fd5b6000611140611e8e565b9050805160001415611161576040518060200160405280600081525061118c565b8061116b846119af565b60405160200161117c9291906128d8565b6040516020818303038152906040525b9392505050565b6008546001600160a01b031633146111bd5760405162461bcd60e51b815260040161097a906129e1565b600081116111fe5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b604482015260640161097a565b600f5481611213600154600054036000190190565b61121d9190612a16565b11156112615760405162461bcd60e51b815260206004820152601360248201527213585e081cdd5c1c1b1e48195e18d959591959606a1b604482015260640161097a565b600e5481600d546112729190612a16565b11156112c05760405162461bcd60e51b815260206004820152601b60248201527f4d6178207265736572766520616d6f756e742065786365656465640000000000604482015260640161097a565b6112ca828261178f565b80600d60008282546112dc9190612a16565b9091555050604080513381526001600160a01b03841660208201529081018290527fd729ebd340be850113adba35e3218ac6bd77c375ce35c256e3493fdf30b99f3e90606001610dfe565b60006107ae82611e9d565b6008546001600160a01b0316331461135c5760405162461bcd60e51b815260040161097a906129e1565b600c805460ff1916911515919091179055565b6001600a5460ff16600381111561138857611388612b3a565b146113d55760405162461bcd60e51b815260206004820152601c60248201527f57686974656c69737453616c65206973206e6f74206163746976652e00000000604482015260640161097a565b61141e6113e28433610b6d565b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611ef292505050565b61145f5760405162461bcd60e51b815260206004820152601260248201527124b73b30b634b21039b4b3b730ba3ab9329760711b604482015260640161097a565b348460105461146e9190612a42565b146114ae5760405162461bcd60e51b815260206004820152601060248201526f283934b1b29034b731b7b93932b1ba1760811b604482015260640161097a565b82846114b933611327565b6114c39190612a16565b111561151d5760405162461bcd60e51b8152602060048201526024808201527f4d6178206d696e7420616d6f756e74207065722077616c6c65742065786365656044820152633232b21760e11b606482015260840161097a565b600f54600d54600e5486611538600154600054036000190190565b6115429190612a16565b61154c9190612a16565b6115569190612a61565b111561159b5760405162461bcd60e51b815260206004820152601460248201527326b0bc1039bab838363c9032bc31b2b2b232b21760611b604482015260640161097a565b3233146115ea5760405162461bcd60e51b815260206004820181905260248201527f436f6e7472616374206973206e6f7420616c6c6f77656420746f206d696e742e604482015260640161097a565b6115f4338561178f565b60408051338152602081018690527f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe910160405180910390a150505050565b6008546001600160a01b0316331461165d5760405162461bcd60e51b815260040161097a906129e1565b601055565b6008546001600160a01b0316331461168c5760405162461bcd60e51b815260040161097a906129e1565b6001600160a01b0381166116f15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161097a565b610d9381611d45565b60008160011115801561170e575060005482105b80156107ae575050600090815260046020526040902054600160e01b900460ff161590565b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6117a9828260405180602001604052806000815250611f1c565b5050565b60006117b882611c1e565b80519091506000906001600160a01b0316336001600160a01b031614806117e6575081516117e690336106e1565b806118015750336117f684610846565b6001600160a01b0316145b90508061182157604051632ce44b5f60e11b815260040160405180910390fd5b846001600160a01b031682600001516001600160a01b0316146118565760405162a1148160e81b815260040160405180910390fd5b6001600160a01b03841661187d57604051633a954ecd60e21b815260040160405180910390fd5b61188d6000848460000151611733565b6001600160a01b038581166000908152600560209081526040808320805467ffffffffffffffff198082166001600160401b0392831660001901831617909255898616808652838620805493841693831660019081018416949094179055898652600490945282852080546001600160e01b031916909417600160a01b4290921691909102179092559086018083529120549091166119775760005481101561197757825160008281526004602090815260409091208054918601516001600160401b0316600160a01b026001600160e01b03199092166001600160a01b03909316929092171790555b5082846001600160a01b0316866001600160a01b0316600080516020612b9383398151915260405160405180910390a45b5050505050565b6060816119d35750506040805180820190915260018152600360fc1b602082015290565b8160005b81156119fd57806119e781612adf565b91506119f69050600a83612a2e565b91506119d7565b6000816001600160401b03811115611a1757611a17612b66565b6040519080825280601f01601f191660200182016040528015611a41576020820181803683370190505b5090505b8415611aac57611a56600183612a61565b9150611a63600a86612afa565b611a6e906030612a16565b60f81b818381518110611a8357611a83612b50565b60200101906001600160f81b031916908160001a905350611aa5600a86612a2e565b9450611a45565b949350505050565b6000611abf82611c1e565b9050611ad16000838360000151611733565b80516001600160a01b039081166000908152600560209081526040808320805467ffffffffffffffff1981166001600160401b0391821660001901821617909155855185168452818420805467ffffffffffffffff60801b198116600160801b9182900484166001908101851690920217909155865188865260049094528285208054600160e01b9588166001600160e01b031990911617600160a01b42909416939093029290921760ff60e01b1916939093179055908501808352912054909116611be857600054811015611be857815160008281526004602090815260409091208054918501516001600160401b0316600160a01b026001600160e01b03199092166001600160a01b03909316929092171790555b50805160405183916000916001600160a01b0390911690600080516020612b93833981519152908390a450506001805481019055565b60408051606081018252600080825260208201819052918101919091528180600111158015611c4e575060005481105b15611d2c57600081815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff16151591810182905290611d2a5780516001600160a01b031615611cc1579392505050565b5060001901600081815260046020908152604091829020825160608101845290546001600160a01b038116808352600160a01b82046001600160401b031693830193909352600160e01b900460ff1615159281019290925215611d25579392505050565b611cc1565b505b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611dcc903390899088908890600401612907565b602060405180830381600087803b158015611de657600080fd5b505af1925050508015611e16575060408051601f3d908101601f19168201909252611e139181019061279f565b60015b611e71573d808015611e44576040519150601f19603f3d011682016040523d82523d6000602084013e611e49565b606091505b508051611e69576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b6060600b80546107c390612aa4565b60006001600160a01b038216611ec6576040516335ebb31960e01b815260040160405180910390fd5b506001600160a01b0316600090815260056020526040902054600160401b90046001600160401b031690565b6011546000906001600160a01b0316611f0b8484611f29565b6001600160a01b0316149392505050565b6109138383836001611f8c565b600061118c82611f86856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90612133565b6000546001600160a01b038516611fb557604051622e076360e81b815260040160405180910390fd5b83611fd35760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038516600081815260056020908152604080832080546fffffffffffffffffffffffffffffffff1981166001600160401b038083168c018116918217600160401b67ffffffffffffffff1990941690921783900481168c01811690920217909155858452600490925290912080546001600160e01b031916909217600160a01b42909216919091021790558080850183801561207f57506001600160a01b0387163b15155b156120f6575b60405182906001600160a01b03891690600090600080516020612b93833981519152908290a46120be6000888480600101955088611d97565b6120db576040516368d2bf6b60e11b815260040160405180910390fd5b808214156120855782600054146120f157600080fd5b61212a565b5b6040516001830192906001600160a01b03891690600090600080516020612b93833981519152908290a4808214156120f7575b506000556119a8565b60008060006121428585612157565b9150915061214f816121c7565b509392505050565b60008082516041141561218e5760208301516040840151606085015160001a61218287828585612382565b945094505050506121c0565b8251604014156121b857602083015160408401516121ad86838361246f565b9350935050506121c0565b506000905060025b9250929050565b60008160048111156121db576121db612b3a565b14156121e45750565b60018160048111156121f8576121f8612b3a565b14156122465760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161097a565b600281600481111561225a5761225a612b3a565b14156122a85760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161097a565b60038160048111156122bc576122bc612b3a565b14156123155760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161097a565b600481600481111561232957612329612b3a565b1415610d935760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b606482015260840161097a565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156123b95750600090506003612466565b8460ff16601b141580156123d157508460ff16601c14155b156123e25750600090506004612466565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612436573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661245f57600060019250925050612466565b9150600090505b94509492505050565b6000806001600160ff1b0383168161248c60ff86901c601b612a16565b905061249a87828885612382565b935093505050935093915050565b8280546124b490612aa4565b90600052602060002090601f0160209004810192826124d6576000855561251c565b82601f106124ef5782800160ff1982351617855561251c565b8280016001018555821561251c579182015b8281111561251c578235825591602001919060010190612501565b5061252892915061252c565b5090565b5b80821115612528576000815560010161252d565b80356001600160a01b038116811461255857600080fd5b919050565b8035801515811461255857600080fd5b60008083601f84011261257f57600080fd5b5081356001600160401b0381111561259657600080fd5b6020830191508360208285010111156121c057600080fd5b6000602082840312156125c057600080fd5b61118c82612541565b600080604083850312156125dc57600080fd5b6125e583612541565b91506125f360208401612541565b90509250929050565b60008060006060848603121561261157600080fd5b61261a84612541565b925061262860208501612541565b9150604084013590509250925092565b6000806000806080858703121561264e57600080fd5b61265785612541565b935061266560208601612541565b92506040850135915060608501356001600160401b038082111561268857600080fd5b818701915087601f83011261269c57600080fd5b8135818111156126ae576126ae612b66565b604051601f8201601f19908116603f011681019083821181831017156126d6576126d6612b66565b816040528281528a60208487010111156126ef57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561272657600080fd5b61272f83612541565b91506125f36020840161255d565b6000806040838503121561275057600080fd5b61275983612541565b946020939093013593505050565b60006020828403121561277957600080fd5b61118c8261255d565b60006020828403121561279457600080fd5b813561118c81612b7c565b6000602082840312156127b157600080fd5b815161118c81612b7c565b6000602082840312156127ce57600080fd5b81356004811061118c57600080fd5b600080602083850312156127f057600080fd5b82356001600160401b0381111561280657600080fd5b6128128582860161256d565b90969095509350505050565b60006020828403121561283057600080fd5b5035919050565b6000806040838503121561284a57600080fd5b823591506125f360208401612541565b6000806000806060858703121561287057600080fd5b843593506020850135925060408501356001600160401b0381111561289457600080fd5b6128a08782880161256d565b95989497509550505050565b600081518084526128c4816020860160208601612a78565b601f01601f19169290920160200192915050565b600083516128ea818460208801612a78565b8351908301906128fe818360208801612a78565b01949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061293a908301846128ac565b9695505050505050565b602081016004831061296657634e487b7160e01b600052602160045260246000fd5b91905290565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60208152600061118c60208301846128ac565b6060815260006129c160608301866128ac565b6001600160a01b0394851660208401529290931660409091015292915050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60008219821115612a2957612a29612b0e565b500190565b600082612a3d57612a3d612b24565b500490565b6000816000190483118215151615612a5c57612a5c612b0e565b500290565b600082821015612a7357612a73612b0e565b500390565b60005b83811015612a93578181015183820152602001612a7b565b838111156111085750506000910152565b600181811c90821680612ab857607f821691505b60208210811415612ad957634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612af357612af3612b0e565b5060010190565b600082612b0957612b09612b24565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610d9357600080fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220b9562ade8609fed14007380afea1c962ad1fed8f086f9124c4b233c1eca8cf3064736f6c63430008070033

Deployed Bytecode Sourcemap

77868:5340:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60353:305;;;;;;;;;;-1:-1:-1;60353:305:0;;;;;:::i;:::-;;:::i;:::-;;;8673:14:1;;8666:22;8648:41;;8636:2;8621:18;60353:305:0;;;;;;;;63738:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;65241:204::-;;;;;;;;;;-1:-1:-1;65241:204:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;7025:32:1;;;7007:51;;6995:2;6980:18;65241:204:0;6861:203:1;64804:371:0;;;;;;;;;;-1:-1:-1;64804:371:0;;;;;:::i;:::-;;:::i;:::-;;81075:493;;;:::i;59602:303::-;;;;;;;;;;;;81668:1;59856:12;59646:7;59840:13;:28;-1:-1:-1;;59840:46:0;;59602:303;;;;8846:25:1;;;8834:2;8819:18;59602:303:0;8700:177:1;78071:20:0;;;;;;;;;;-1:-1:-1;78071:20:0;;;;;;;;;;;;;;;:::i;78341:66::-;;;;;;;;;;-1:-1:-1;78341:66:0;;;;-1:-1:-1;;;;;78341:66:0;;;66098:170;;;;;;;;;;-1:-1:-1;66098:170:0;;;;;:::i;:::-;;:::i;82185:127::-;;;;;;;;;;-1:-1:-1;82185:127:0;;;;;:::i;:::-;;:::i;78248:31::-;;;;;;;;;;;;;;;;78932:217;;;;;;;;;;-1:-1:-1;78932:217:0;;;;;:::i;:::-;;:::i;81685:238::-;;;;;;;;;;;;;:::i;66339:185::-;;;;;;;;;;-1:-1:-1;66339:185:0;;;;;:::i;:::-;;:::i;82994:211::-;;;;;;;;;;-1:-1:-1;82994:211:0;;;;;:::i;:::-;;:::i;78168:29::-;;;;;;;;;;;;;;;;78126;;;;;;;;;;-1:-1:-1;78126:29:0;;;;;;;;82029:148;;;;;;;;;;-1:-1:-1;82029:148:0;;;;;:::i;:::-;;:::i;82560:130::-;;;;;;;;;;-1:-1:-1;82560:130:0;;;;;:::i;:::-;;:::i;63547:124::-;;;;;;;;;;-1:-1:-1;63547:124:0;;;;;:::i;:::-;;:::i;78098:21::-;;;;;;;;;;;;;:::i;82421:131::-;;;;;;;;;;-1:-1:-1;82421:131:0;;;;;:::i;:::-;;:::i;60722:206::-;;;;;;;;;;-1:-1:-1;60722:206:0;;;;;:::i;:::-;;:::i;36845:103::-;;;;;;;;;;;;;:::i;78414:75::-;;;;;;;;;;-1:-1:-1;78414:75:0;;;;-1:-1:-1;;;;;78414:75:0;;;78286:36;;;;;;;;;;;;;;;;36194:87;;;;;;;;;;-1:-1:-1;36267:6:0;;-1:-1:-1;;;;;36267:6:0;36194:87;;82819:167;;;;;;;;;;-1:-1:-1;82819:167:0;;;;;:::i;:::-;;:::i;:::-;;;;18151:13:1;;-1:-1:-1;;;;;18147:39:1;18129:58;;18247:4;18235:17;;;18229:24;-1:-1:-1;;;;;18225:49:1;18203:20;;;18196:79;18333:17;;;18327:24;18320:32;18313:40;18291:20;;;18284:70;18117:2;18102:18;82819:167:0;17919:441:1;63907:104:0;;;;;;;;;;;;;:::i;65517:279::-;;;;;;;;;;-1:-1:-1;65517:279:0;;;;;:::i;:::-;;:::i;66595:369::-;;;;;;;;;;-1:-1:-1;66595:369:0;;;;;:::i;:::-;;:::i;64082:318::-;;;;;;;;;;-1:-1:-1;64082:318:0;;;;;:::i;:::-;;:::i;79654:509::-;;;;;;;;;;-1:-1:-1;79654:509:0;;;;;:::i;:::-;;:::i;78206:35::-;;;;;;;;;;;;;;;;82698:113;;;;;;;;;;-1:-1:-1;82698:113:0;;;;;:::i;:::-;;:::i;82320:93::-;;;;;;;;;;-1:-1:-1;82320:93:0;;;;;:::i;:::-;;:::i;65867:164::-;;;;;;;;;;-1:-1:-1;65867:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;65988:25:0;;;65964:4;65988:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;65867:164;80171:894;;;;;;:::i;:::-;;:::i;81931:90::-;;;;;;;;;;-1:-1:-1;81931:90:0;;;;;:::i;:::-;;:::i;37103:201::-;;;;;;;;;;-1:-1:-1;37103:201:0;;;;;:::i;:::-;;:::i;60353:305::-;60455:4;-1:-1:-1;;;;;;60492:40:0;;-1:-1:-1;;;60492:40:0;;:105;;-1:-1:-1;;;;;;;60549:48:0;;-1:-1:-1;;;60549:48:0;60492:105;:158;;;-1:-1:-1;;;;;;;;;;49087:40:0;;;60614:36;60472:178;60353:305;-1:-1:-1;;60353:305:0:o;63738:100::-;63792:13;63825:5;63818:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63738:100;:::o;65241:204::-;65309:7;65334:16;65342:7;65334;:16::i;:::-;65329:64;;65359:34;;-1:-1:-1;;;65359:34:0;;;;;;;;;;;65329:64;-1:-1:-1;65413:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;65413:24:0;;65241:204::o;64804:371::-;64877:13;64893:24;64909:7;64893:15;:24::i;:::-;64877:40;;64938:5;-1:-1:-1;;;;;64932:11:0;:2;-1:-1:-1;;;;;64932:11:0;;64928:48;;;64952:24;;-1:-1:-1;;;64952:24:0;;;;;;;;;;;64928:48;18790:10;-1:-1:-1;;;;;64993:21:0;;;;;;:63;;-1:-1:-1;65019:37:0;65036:5;18790:10;65867:164;:::i;65019:37::-;65018:38;64993:63;64989:138;;;65080:35;;-1:-1:-1;;;65080:35:0;;;;;;;;;;;64989:138;65139:28;65148:2;65152:7;65161:5;65139:8;:28::i;:::-;64866:309;64804:371;;:::o;81075:493::-;81137:17;81127:6;;;;:27;;;;;;;;:::i;:::-;;81119:66;;;;-1:-1:-1;;;81119:66:0;;13053:2:1;81119:66:0;;;13035:21:1;13092:2;13072:18;;;13065:30;13131:28;13111:18;;;13104:56;13177:18;;81119:66:0;;;;;;;;;81204:9;81217:10;81204:23;81196:68;;;;-1:-1:-1;;;81196:68:0;;12340:2:1;81196:68:0;;;12322:21:1;;;12359:18;;;12352:30;12418:34;12398:18;;;12391:62;12470:18;;81196:68:0;12138:356:1;81196:68:0;81370:10;;81335:14;;81317:15;;81297:13;81668:1;59856:12;59646:7;59840:13;:28;-1:-1:-1;;59840:46:0;;59602:303;81297:13;:17;;81313:1;81297:17;:::i;:::-;:35;;;;:::i;:::-;:52;;;;:::i;:::-;:83;;81275:153;;;;-1:-1:-1;;;81275:153:0;;17772:2:1;81275:153:0;;;17754:21:1;17811:2;17791:18;;;17784:30;-1:-1:-1;;;17830:18:1;;;17823:50;17890:18;;81275:153:0;17570:344:1;81275:153:0;81456:9;81447:5;;:18;81439:47;;;;-1:-1:-1;;;81439:47:0;;16021:2:1;81439:47:0;;;16003:21:1;16060:2;16040:18;;;16033:30;-1:-1:-1;;;16079:18:1;;;16072:46;16135:18;;81439:47:0;15819:340:1;81439:47:0;81499:24;81509:10;81521:1;81499:9;:24::i;:::-;81539:21;;;81546:10;8124:51:1;;81558:1:0;8206:2:1;8191:18;;8184:34;81539:21:0;;8097:18:1;81539:21:0;;;;;;;81075:493::o;66098:170::-;66232:28;66242:4;66248:2;66252:7;66232:9;:28::i;82185:127::-;36267:6;;-1:-1:-1;;;;;36267:6:0;18790:10;36414:23;36406:68;;;;-1:-1:-1;;;36406:68:0;;;;;;;:::i;:::-;82250:6:::1;:16:::0;;82259:7;;82250:6;-1:-1:-1;;82250:16:0::1;::::0;82259:7;82250:16:::1;::::0;::::1;;;;;;:::i;:::-;;;;;;82282:22;82296:7;82282:22;;;;;;:::i;:::-;;;;;;;;82185:127:::0;:::o;78932:217::-;79033:7;79086:28;79103:10;79086:16;:28::i;:::-;79124:4;79131:8;79075:65;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;79065:76;;;;;;79058:83;;78932:217;;;;:::o;81685:238::-;1812:1;2410:7;;:19;;2402:63;;;;-1:-1:-1;;;2402:63:0;;17069:2:1;2402:63:0;;;17051:21:1;17108:2;17088:18;;;17081:30;17147:33;17127:18;;;17120:61;17198:18;;2402:63:0;16867:355:1;2402:63:0;1812:1;2543:7;:18;36267:6;;-1:-1:-1;;;;;36267:6:0;18790:10;36414:23:::1;36406:68;;;;-1:-1:-1::0;;;36406:68:0::1;;;;;;;:::i;:::-;81826:15:::2;::::0;81818:49:::2;::::0;81766:21:::2;::::0;81748:15:::2;::::0;-1:-1:-1;;;;;81826:15:0;;::::2;::::0;81766:21;;81748:15;81818:49;81748:15;81818:49;81766:21;81826:15;81818:49:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81798:69;;;81886:8;81878:37;;;::::0;-1:-1:-1;;;81878:37:0;;15676:2:1;81878:37:0::2;::::0;::::2;15658:21:1::0;15715:2;15695:18;;;15688:30;-1:-1:-1;;;15734:18:1;;;15727:46;15790:18;;81878:37:0::2;15474:340:1::0;81878:37:0::2;-1:-1:-1::0;;1768:1:0;2722:7;:22;81685:238::o;66339:185::-;66477:39;66494:4;66500:2;66504:7;66477:39;;;;;;;;;;;;:16;:39::i;82994:211::-;83059:10;;;;:19;83051:55;;;;-1:-1:-1;;;83051:55:0;;12701:2:1;83051:55:0;;;12683:21:1;12740:2;12720:18;;;12713:30;12779:25;12759:18;;;12752:53;12822:18;;83051:55:0;12499:347:1;83051:55:0;18790:10;83125:16;83133:7;83125;:16::i;:::-;-1:-1:-1;;;;;83125:32:0;;83117:55;;;;-1:-1:-1;;;83117:55:0;;15337:2:1;83117:55:0;;;15319:21:1;15376:2;15356:18;;;15349:30;-1:-1:-1;;;15395:18:1;;;15388:40;15445:18;;83117:55:0;15135:334:1;83117:55:0;83183:14;83189:7;83183:5;:14::i;:::-;82994:211;:::o;82029:148::-;36267:6;;-1:-1:-1;;;;;36267:6:0;18790:10;36414:23;36406:68;;;;-1:-1:-1;;;36406:68:0;;;;;;;:::i;:::-;82107:20:::1;:7;82117:10:::0;;82107:20:::1;:::i;:::-;;82143:26;82158:10;;82143:26;;;;;;;:::i;:::-;;;;;;;;82029:148:::0;;:::o;82560:130::-;36267:6;;-1:-1:-1;;;;;36267:6:0;18790:10;36414:23;36406:68;;;;-1:-1:-1;;;36406:68:0;;;;;;;:::i;:::-;82646:15:::1;:36:::0;;-1:-1:-1;;;;;;82646:36:0::1;-1:-1:-1::0;;;;;82646:36:0;;;::::1;::::0;;;::::1;::::0;;82560:130::o;63547:124::-;63611:7;63638:20;63650:7;63638:11;:20::i;:::-;:25;;63547:124;-1:-1:-1;;63547:124:0:o;78098:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;82421:131::-;36267:6;;-1:-1:-1;;;;;36267:6:0;18790:10;36414:23;36406:68;;;;-1:-1:-1;;;36406:68:0;;;;;;;:::i;:::-;82489:6:::1;:18:::0;;-1:-1:-1;;;;;;82489:18:0::1;-1:-1:-1::0;;;;;82489:18:0;::::1;::::0;;::::1;::::0;;;82523:21:::1;::::0;7007:51:1;;;82523:21:0::1;::::0;6995:2:1;6980:18;82523:21:0::1;6861:203:1::0;60722:206:0;60786:7;-1:-1:-1;;;;;60810:19:0;;60806:60;;60838:28;;-1:-1:-1;;;60838:28:0;;;;;;;;;;;60806:60;-1:-1:-1;;;;;;60892:19:0;;;;;:12;:19;;;;;:27;-1:-1:-1;;;;;60892:27:0;;60722:206::o;36845:103::-;36267:6;;-1:-1:-1;;;;;36267:6:0;18790:10;36414:23;36406:68;;;;-1:-1:-1;;;36406:68:0;;;;;;;:::i;:::-;36910:30:::1;36937:1;36910:18;:30::i;:::-;36845:103::o:0;82819:167::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;82958:20:0;82970:7;82958:11;:20::i;63907:104::-;63963:13;63996:7;63989:14;;;;;:::i;65517:279::-;-1:-1:-1;;;;;65608:24:0;;18790:10;65608:24;65604:54;;;65641:17;;-1:-1:-1;;;65641:17:0;;;;;;;;;;;65604:54;18790:10;65671:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;65671:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;65671:53:0;;;;;;;;;;65740:48;;8648:41:1;;;65671:42:0;;18790:10;65740:48;;8621:18:1;65740:48:0;;;;;;;65517:279;;:::o;66595:369::-;66762:28;66772:4;66778:2;66782:7;66762:9;:28::i;:::-;-1:-1:-1;;;;;66805:13:0;;39190:19;:23;;66805:76;;;;;66825:56;66856:4;66862:2;66866:7;66875:5;66825:30;:56::i;:::-;66824:57;66805:76;66801:156;;;66905:40;;-1:-1:-1;;;66905:40:0;;;;;;;;;;;66801:156;66595:369;;;;:::o;64082:318::-;64155:13;64186:16;64194:7;64186;:16::i;:::-;64181:59;;64211:29;;-1:-1:-1;;;64211:29:0;;;;;;;;;;;64181:59;64253:21;64277:10;:8;:10::i;:::-;64253:34;;64311:7;64305:21;64330:1;64305:26;;:87;;;;;;;;;;;;;;;;;64358:7;64367:18;:7;:16;:18::i;:::-;64341:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;64305:87;64298:94;64082:318;-1:-1:-1;;;64082:318:0:o;79654:509::-;36267:6;;-1:-1:-1;;;;;36267:6:0;18790:10;36414:23;36406:68;;;;-1:-1:-1;;;36406:68:0;;;;;;;:::i;:::-;79753:1:::1;79744:6;:10;79736:37;;;::::0;-1:-1:-1;;;79736:37:0;;17429:2:1;79736:37:0::1;::::0;::::1;17411:21:1::0;17468:2;17448:18;;;17441:30;-1:-1:-1;;;17487:18:1;;;17480:44;17541:18;;79736:37:0::1;17227:338:1::0;79736:37:0::1;79832:10;;79822:6;79806:13;81668:1:::0;59856:12;59646:7;59840:13;:28;-1:-1:-1;;59840:46:0;;59602:303;79806:13:::1;:22;;;;:::i;:::-;:36;;79784:105;;;::::0;-1:-1:-1;;;79784:105:0;;11225:2:1;79784:105:0::1;::::0;::::1;11207:21:1::0;11264:2;11244:18;;;11237:30;-1:-1:-1;;;11283:18:1;;;11276:49;11342:18;;79784:105:0::1;11023:343:1::0;79784:105:0::1;79949:15;;79939:6;79922:14;;:23;;;;:::i;:::-;:42;;79900:119;;;::::0;-1:-1:-1;;;79900:119:0;;16366:2:1;79900:119:0::1;::::0;::::1;16348:21:1::0;16405:2;16385:18;;;16378:30;16444:29;16424:18;;;16417:57;16491:18;;79900:119:0::1;16164:351:1::0;79900:119:0::1;80032:28;80042:9;80053:6;80032:9;:28::i;:::-;80089:6;80071:14;;:24;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;80111:44:0::1;::::0;;80125:10:::1;7309:34:1::0;;-1:-1:-1;;;;;7379:15:1;;7374:2;7359:18;;7352:43;7411:18;;;7404:34;;;80111:44:0::1;::::0;7259:2:1;7244:18;80111:44:0::1;7069:375:1::0;82698:113:0;82756:7;82783:20;82797:5;82783:13;:20::i;82320:93::-;36267:6;;-1:-1:-1;;;;;36267:6:0;18790:10;36414:23;36406:68;;;;-1:-1:-1;;;36406:68:0;;;;;;;:::i;:::-;82386:10:::1;:19:::0;;-1:-1:-1;;82386:19:0::1;::::0;::::1;;::::0;;;::::1;::::0;;82320:93::o;80171:894::-;80325:20;80315:6;;;;:30;;;;;;;;:::i;:::-;;80307:71;;;;-1:-1:-1;;;80307:71:0;;14216:2:1;80307:71:0;;;14198:21:1;14255:2;14235:18;;;14228:30;14294;14274:18;;;14267:58;14342:18;;80307:71:0;14014:352:1;80307:71:0;80411:49;80419:29;80425:10;80437;80419:5;:29::i;:::-;80450:9;;80411:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;80411:7:0;;-1:-1:-1;;;80411:49:0:i;:::-;80389:117;;;;-1:-1:-1;;;80389:117:0;;16722:2:1;80389:117:0;;;16704:21:1;16761:2;16741:18;;;16734:30;-1:-1:-1;;;16780:18:1;;;16773:48;16838:18;;80389:117:0;16520:342:1;80389:117:0;80543:9;80533:6;80525:5;;:14;;;;:::i;:::-;:27;80517:56;;;;-1:-1:-1;;;80517:56:0;;16021:2:1;80517:56:0;;;16003:21:1;16060:2;16040:18;;;16033:30;-1:-1:-1;;;16079:18:1;;;16072:46;16135:18;;80517:56:0;15819:340:1;80517:56:0;80643:10;80633:6;80606:24;80619:10;80606:12;:24::i;:::-;:33;;;;:::i;:::-;:47;;80584:133;;;;-1:-1:-1;;;80584:133:0;;13408:2:1;80584:133:0;;;13390:21:1;13447:2;13427:18;;;13420:30;13486:34;13466:18;;;13459:62;-1:-1:-1;;;13537:18:1;;;13530:34;13581:19;;80584:133:0;13206:400:1;80584:133:0;80828:10;;80793:14;;80775:15;;80766:6;80750:13;81668:1;59856:12;59646:7;59840:13;:28;-1:-1:-1;;59840:46:0;;59602:303;80750:13;:22;;;;:::i;:::-;:40;;;;:::i;:::-;:57;;;;:::i;:::-;:88;;80728:158;;;;-1:-1:-1;;;80728:158:0;;17772:2:1;80728:158:0;;;17754:21:1;17811:2;17791:18;;;17784:30;-1:-1:-1;;;17830:18:1;;;17823:50;17890:18;;80728:158:0;17570:344:1;80728:158:0;80905:9;80918:10;80905:23;80897:68;;;;-1:-1:-1;;;80897:68:0;;12340:2:1;80897:68:0;;;12322:21:1;;;12359:18;;;12352:30;12418:34;12398:18;;;12391:62;12470:18;;80897:68:0;12138:356:1;80897:68:0;80986:29;80996:10;81008:6;80986:9;:29::i;:::-;81031:26;;;81038:10;8124:51:1;;8206:2;8191:18;;8184:34;;;81031:26:0;;8097:18:1;81031:26:0;;;;;;;80171:894;;;;:::o;81931:90::-;36267:6;;-1:-1:-1;;;;;36267:6:0;18790:10;36414:23;36406:68;;;;-1:-1:-1;;;36406:68:0;;;;;;;:::i;:::-;81997:5:::1;:16:::0;81931:90::o;37103:201::-;36267:6;;-1:-1:-1;;;;;36267:6:0;18790:10;36414:23;36406:68;;;;-1:-1:-1;;;36406:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;37192:22:0;::::1;37184:73;;;::::0;-1:-1:-1;;;37184:73:0;;11933:2:1;37184:73:0::1;::::0;::::1;11915:21:1::0;11972:2;11952:18;;;11945:30;12011:34;11991:18;;;11984:62;-1:-1:-1;;;12062:18:1;;;12055:36;12108:19;;37184:73:0::1;11731:402:1::0;37184:73:0::1;37268:28;37287:8;37268:18;:28::i;67219:187::-:0;67276:4;67319:7;81668:1;67300:26;;:53;;;;;67340:13;;67330:7;:23;67300:53;:98;;;;-1:-1:-1;;67371:20:0;;;;:11;:20;;;;;:27;-1:-1:-1;;;67371:27:0;;;;67370:28;;67219:187::o;74830:196::-;74945:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;74945:29:0;-1:-1:-1;;;;;74945:29:0;;;;;;;;;74990:28;;74945:24;;74990:28;;;;;;;74830:196;;;:::o;67414:104::-;67483:27;67493:2;67497:8;67483:27;;;;;;;;;;;;:9;:27::i;:::-;67414:104;;:::o;70332:2112::-;70447:35;70485:20;70497:7;70485:11;:20::i;:::-;70560:18;;70447:58;;-1:-1:-1;70518:22:0;;-1:-1:-1;;;;;70544:34:0;18790:10;-1:-1:-1;;;;;70544:34:0;;:101;;;-1:-1:-1;70612:18:0;;70595:50;;18790:10;65867:164;:::i;70595:50::-;70544:154;;;-1:-1:-1;18790:10:0;70662:20;70674:7;70662:11;:20::i;:::-;-1:-1:-1;;;;;70662:36:0;;70544:154;70518:181;;70717:17;70712:66;;70743:35;;-1:-1:-1;;;70743:35:0;;;;;;;;;;;70712:66;70815:4;-1:-1:-1;;;;;70793:26:0;:13;:18;;;-1:-1:-1;;;;;70793:26:0;;70789:67;;70828:28;;-1:-1:-1;;;70828:28:0;;;;;;;;;;;70789:67;-1:-1:-1;;;;;70871:16:0;;70867:52;;70896:23;;-1:-1:-1;;;70896:23:0;;;;;;;;;;;70867:52;71040:49;71057:1;71061:7;71070:13;:18;;;71040:8;:49::i;:::-;-1:-1:-1;;;;;71385:18:0;;;;;;;:12;:18;;;;;;;;:31;;-1:-1:-1;;71385:31:0;;;-1:-1:-1;;;;;71385:31:0;;;-1:-1:-1;;71385:31:0;;;;;;;71431:16;;;;;;;;;:29;;;;;;;;-1:-1:-1;71431:29:0;;;;;;;;;;;71477:20;;;:11;:20;;;;;;:30;;-1:-1:-1;;;;;;71522:61:0;;;;-1:-1:-1;;;71567:15:0;71522:61;;;;;;;;;;;71857:11;;;71887:24;;;;;:29;71857:11;;71887:29;71883:445;;72112:13;;72098:11;:27;72094:219;;;72182:18;;;72150:24;;;:11;:24;;;;;;;;:50;;72265:28;;;;-1:-1:-1;;;;;72223:70:0;-1:-1:-1;;;72223:70:0;-1:-1:-1;;;;;;72223:70:0;;;-1:-1:-1;;;;;72150:50:0;;;72223:70;;;;;;;72094:219;71360:979;72375:7;72371:2;-1:-1:-1;;;;;72356:27:0;72365:4;-1:-1:-1;;;;;72356:27:0;-1:-1:-1;;;;;;;;;;;72356:27:0;;;;;;;;;72394:42;70436:2008;;70332:2112;;;:::o;6738:723::-;6794:13;7015:10;7011:53;;-1:-1:-1;;7042:10:0;;;;;;;;;;;;-1:-1:-1;;;7042:10:0;;;;;6738:723::o;7011:53::-;7089:5;7074:12;7130:78;7137:9;;7130:78;;7163:8;;;;:::i;:::-;;-1:-1:-1;7186:10:0;;-1:-1:-1;7194:2:0;7186:10;;:::i;:::-;;;7130:78;;;7218:19;7250:6;-1:-1:-1;;;;;7240:17:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7240:17:0;;7218:39;;7268:154;7275:10;;7268:154;;7302:11;7312:1;7302:11;;:::i;:::-;;-1:-1:-1;7371:10:0;7379:2;7371:5;:10;:::i;:::-;7358:24;;:2;:24;:::i;:::-;7345:39;;7328:6;7335;7328:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;7328:56:0;;;;;;;;-1:-1:-1;7399:11:0;7408:2;7399:11;;:::i;:::-;;;7268:154;;;7446:6;6738:723;-1:-1:-1;;;;6738:723:0:o;72673:2039::-;72733:35;72771:20;72783:7;72771:11;:20::i;:::-;72733:58;-1:-1:-1;72934:49:0;72951:1;72955:7;72964:13;:18;;;72934:8;:49::i;:::-;73292:18;;-1:-1:-1;;;;;73279:32:0;;;;;;;:12;:32;;;;;;;;:45;;-1:-1:-1;;73279:45:0;;-1:-1:-1;;;;;73279:45:0;;;-1:-1:-1;;73279:45:0;;;;;;;73352:18;;73339:32;;;;;;;:50;;-1:-1:-1;;;;73339:50:0;;-1:-1:-1;;;73339:50:0;;;;;;-1:-1:-1;73339:50:0;;;;;;;;;;;;73516:18;;73488:20;;;:11;:20;;;;;;:46;;-1:-1:-1;;;73488:46:0;;;-1:-1:-1;;;;;;73549:61:0;;;;-1:-1:-1;;;73594:15:0;73549:61;;;;;;;;;;;-1:-1:-1;;;;73625:34:0;;;;;;;73929:11;;;73959:24;;;;;:29;73929:11;;73959:29;73955:445;;74184:13;;74170:11;:27;74166:219;;;74254:18;;;74222:24;;;:11;:24;;;;;;;;:50;;74337:28;;;;-1:-1:-1;;;;;74295:70:0;-1:-1:-1;;;74295:70:0;-1:-1:-1;;;;;;74295:70:0;;;-1:-1:-1;;;;;74222:50:0;;;74295:70;;;;;;;74166:219;-1:-1:-1;74437:18:0;;74428:49;;74469:7;;74465:1;;-1:-1:-1;;;;;74428:49:0;;;;-1:-1:-1;;;;;;;;;;;74428:49:0;74465:1;;74428:49;-1:-1:-1;;74679:12:0;:14;;;;;;72673:2039::o;62377:1108::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;62487:7:0;;81668:1;62536:23;;:47;;;;;62570:13;;62563:4;:20;62536:47;62532:886;;;62604:31;62638:17;;;:11;:17;;;;;;;;;62604:51;;;;;;;;;-1:-1:-1;;;;;62604:51:0;;;;-1:-1:-1;;;62604:51:0;;-1:-1:-1;;;;;62604:51:0;;;;;;;;-1:-1:-1;;;62604:51:0;;;;;;;;;;;;;;62674:729;;62724:14;;-1:-1:-1;;;;;62724:28:0;;62720:101;;62788:9;62377:1108;-1:-1:-1;;;62377:1108:0:o;62720:101::-;-1:-1:-1;;;63163:6:0;63208:17;;;;:11;:17;;;;;;;;;63196:29;;;;;;;;;-1:-1:-1;;;;;63196:29:0;;;;;-1:-1:-1;;;63196:29:0;;-1:-1:-1;;;;;63196:29:0;;;;;;;;-1:-1:-1;;;63196:29:0;;;;;;;;;;;;;63256:28;63252:109;;63324:9;62377:1108;-1:-1:-1;;;62377:1108:0:o;63252:109::-;63123:261;;;62585:833;62532:886;63446:31;;-1:-1:-1;;;63446:31:0;;;;;;;;;;;37464:191;37557:6;;;-1:-1:-1;;;;;37574:17:0;;;-1:-1:-1;;;;;;37574:17:0;;;;;;;37607:40;;37557:6;;;37574:17;37557:6;;37607:40;;37538:16;;37607:40;37527:128;37464:191;:::o;75518:667::-;75702:72;;-1:-1:-1;;;75702:72:0;;75681:4;;-1:-1:-1;;;;;75702:36:0;;;;;:72;;18790:10;;75753:4;;75759:7;;75768:5;;75702:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;75702:72:0;;;;;;;;-1:-1:-1;;75702:72:0;;;;;;;;;;;;:::i;:::-;;;75698:480;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;75936:13:0;;75932:235;;75982:40;;-1:-1:-1;;;75982:40:0;;;;;;;;;;;75932:235;76125:6;76119:13;76110:6;76106:2;76102:15;76095:38;75698:480;-1:-1:-1;;;;;;75821:55:0;-1:-1:-1;;;75821:55:0;;-1:-1:-1;75518:667:0;;;;;;:::o;79546:100::-;79598:13;79631:7;79624:14;;;;;:::i;61010:207::-;61071:7;-1:-1:-1;;;;;61095:19:0;;61091:59;;61123:27;;-1:-1:-1;;;61123:27:0;;;;;;;;;;;61091:59;-1:-1:-1;;;;;;61176:19:0;;;;;:12;:19;;;;;:32;-1:-1:-1;;;61176:32:0;;-1:-1:-1;;;;;61176:32:0;;61010:207::o;79157:179::-;79321:6;;79262:4;;-1:-1:-1;;;;;79321:6:0;79292:25;79301:4;79307:9;79292:8;:25::i;:::-;-1:-1:-1;;;;;79292:35:0;;;79157:179;-1:-1:-1;;;79157:179:0:o;67881:163::-;68004:32;68010:2;68014:8;68024:5;68031:4;68004:5;:32::i;79344:194::-;79450:7;79482:48;79520:9;79482:29;:4;16918:58;;6508:66:1;16918:58:0;;;6496:79:1;6591:12;;;6584:28;;;16785:7:0;;6628:12:1;;16918:58:0;;;;;;;;;;;;16908:69;;;;;;16901:76;;16716:269;;;;79482:29;:37;;:48::i;68303:1775::-;68442:20;68465:13;-1:-1:-1;;;;;68493:16:0;;68489:48;;68518:19;;-1:-1:-1;;;68518:19:0;;;;;;;;;;;68489:48;68552:13;68548:44;;68574:18;;-1:-1:-1;;;68574:18:0;;;;;;;;;;;68548:44;-1:-1:-1;;;;;68943:16:0;;;;;;:12;:16;;;;;;;;:44;;-1:-1:-1;;69002:49:0;;-1:-1:-1;;;;;68943:44:0;;;;;;;69002:49;;;-1:-1:-1;;;;;68943:44:0;;;;;;69002:49;;;;;;;;;;;;;;;;69068:25;;;:11;:25;;;;;;:35;;-1:-1:-1;;;;;;69118:66:0;;;;-1:-1:-1;;;69168:15:0;69118:66;;;;;;;;;;69068:25;69265:23;;;69309:4;:23;;;;-1:-1:-1;;;;;;69317:13:0;;39190:19;:23;;69317:15;69305:641;;;69353:314;69384:38;;69409:12;;-1:-1:-1;;;;;69384:38:0;;;69401:1;;-1:-1:-1;;;;;;;;;;;69384:38:0;69401:1;;69384:38;69450:69;69489:1;69493:2;69497:14;;;;;;69513:5;69450:30;:69::i;:::-;69445:174;;69555:40;;-1:-1:-1;;;69555:40:0;;;;;;;;;;;69445:174;69662:3;69646:12;:19;;69353:314;;69748:12;69731:13;;:29;69727:43;;69762:8;;;69727:43;69305:641;;;69811:120;69842:40;;69867:14;;;;;-1:-1:-1;;;;;69842:40:0;;;69859:1;;-1:-1:-1;;;;;;;;;;;69842:40:0;69859:1;;69842:40;69926:3;69910:12;:19;;69811:120;;69305:641;-1:-1:-1;69960:13:0;:28;70010:60;66595:369;12914:231;12992:7;13013:17;13032:18;13054:27;13065:4;13071:9;13054:10;:27::i;:::-;13012:69;;;;13092:18;13104:5;13092:11;:18::i;:::-;-1:-1:-1;13128:9:0;12914:231;-1:-1:-1;;;12914:231:0:o;10804:1308::-;10885:7;10894:12;11119:9;:16;11139:2;11119:22;11115:990;;;11415:4;11400:20;;11394:27;11465:4;11450:20;;11444:27;11523:4;11508:20;;11502:27;11158:9;11494:36;11566:25;11577:4;11494:36;11394:27;11444;11566:10;:25::i;:::-;11559:32;;;;;;;;;11115:990;11613:9;:16;11633:2;11613:22;11609:496;;;11888:4;11873:20;;11867:27;11939:4;11924:20;;11918:27;11981:23;11992:4;11867:27;11918;11981:10;:23::i;:::-;11974:30;;;;;;;;11609:496;-1:-1:-1;12053:1:0;;-1:-1:-1;12057:35:0;11609:496;10804:1308;;;;;:::o;9075:643::-;9153:20;9144:5;:29;;;;;;;;:::i;:::-;;9140:571;;;9075:643;:::o;9140:571::-;9251:29;9242:5;:38;;;;;;;;:::i;:::-;;9238:473;;;9297:34;;-1:-1:-1;;;9297:34:0;;10872:2:1;9297:34:0;;;10854:21:1;10911:2;10891:18;;;10884:30;10950:26;10930:18;;;10923:54;10994:18;;9297:34:0;10670:348:1;9238:473:0;9362:35;9353:5;:44;;;;;;;;:::i;:::-;;9349:362;;;9414:41;;-1:-1:-1;;;9414:41:0;;11573:2:1;9414:41:0;;;11555:21:1;11612:2;11592:18;;;11585:30;11651:33;11631:18;;;11624:61;11702:18;;9414:41:0;11371:355:1;9349:362:0;9486:30;9477:5;:39;;;;;;;;:::i;:::-;;9473:238;;;9533:44;;-1:-1:-1;;;9533:44:0;;13813:2:1;9533:44:0;;;13795:21:1;13852:2;13832:18;;;13825:30;13891:34;13871:18;;;13864:62;-1:-1:-1;;;13942:18:1;;;13935:32;13984:19;;9533:44:0;13611:398:1;9473:238:0;9608:30;9599:5;:39;;;;;;;;:::i;:::-;;9595:116;;;9655:44;;-1:-1:-1;;;9655:44:0;;14573:2:1;9655:44:0;;;14555:21:1;14612:2;14592:18;;;14585:30;14651:34;14631:18;;;14624:62;-1:-1:-1;;;14702:18:1;;;14695:32;14744:19;;9655:44:0;14371:398:1;14366:1632:0;14497:7;;15431:66;15418:79;;15414:163;;;-1:-1:-1;15530:1:0;;-1:-1:-1;15534:30:0;15514:51;;15414:163;15591:1;:7;;15596:2;15591:7;;:18;;;;;15602:1;:7;;15607:2;15602:7;;15591:18;15587:102;;;-1:-1:-1;15642:1:0;;-1:-1:-1;15646:30:0;15626:51;;15587:102;15803:24;;;15786:14;15803:24;;;;;;;;;9109:25:1;;;9182:4;9170:17;;9150:18;;;9143:45;;;;9204:18;;;9197:34;;;9247:18;;;9240:34;;;15803:24:0;;9081:19:1;;15803:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;15803:24:0;;-1:-1:-1;;15803:24:0;;;-1:-1:-1;;;;;;;15842:20:0;;15838:103;;15895:1;15899:29;15879:50;;;;;;;15838:103;15961:6;-1:-1:-1;15969:20:0;;-1:-1:-1;14366:1632:0;;;;;;;;:::o;13408:344::-;13522:7;;-1:-1:-1;;;;;13568:80:0;;13522:7;13675:25;13691:3;13676:18;;;13698:2;13675:25;:::i;:::-;13659:42;;13719:25;13730:4;13736:1;13739;13742;13719:10;:25::i;:::-;13712:32;;;;;;13408:344;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:173:1;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:160::-;257:20;;313:13;;306:21;296:32;;286:60;;342:1;339;332:12;357:347;408:8;418:6;472:3;465:4;457:6;453:17;449:27;439:55;;490:1;487;480:12;439:55;-1:-1:-1;513:20:1;;-1:-1:-1;;;;;545:30:1;;542:50;;;588:1;585;578:12;542:50;625:4;617:6;613:17;601:29;;677:3;670:4;661:6;653;649:19;645:30;642:39;639:59;;;694:1;691;684:12;709:186;768:6;821:2;809:9;800:7;796:23;792:32;789:52;;;837:1;834;827:12;789:52;860:29;879:9;860:29;:::i;900:260::-;968:6;976;1029:2;1017:9;1008:7;1004:23;1000:32;997:52;;;1045:1;1042;1035:12;997:52;1068:29;1087:9;1068:29;:::i;:::-;1058:39;;1116:38;1150:2;1139:9;1135:18;1116:38;:::i;:::-;1106:48;;900:260;;;;;:::o;1165:328::-;1242:6;1250;1258;1311:2;1299:9;1290:7;1286:23;1282:32;1279:52;;;1327:1;1324;1317:12;1279:52;1350:29;1369:9;1350:29;:::i;:::-;1340:39;;1398:38;1432:2;1421:9;1417:18;1398:38;:::i;:::-;1388:48;;1483:2;1472:9;1468:18;1455:32;1445:42;;1165:328;;;;;:::o;1498:1138::-;1593:6;1601;1609;1617;1670:3;1658:9;1649:7;1645:23;1641:33;1638:53;;;1687:1;1684;1677:12;1638:53;1710:29;1729:9;1710:29;:::i;:::-;1700:39;;1758:38;1792:2;1781:9;1777:18;1758:38;:::i;:::-;1748:48;;1843:2;1832:9;1828:18;1815:32;1805:42;;1898:2;1887:9;1883:18;1870:32;-1:-1:-1;;;;;1962:2:1;1954:6;1951:14;1948:34;;;1978:1;1975;1968:12;1948:34;2016:6;2005:9;2001:22;1991:32;;2061:7;2054:4;2050:2;2046:13;2042:27;2032:55;;2083:1;2080;2073:12;2032:55;2119:2;2106:16;2141:2;2137;2134:10;2131:36;;;2147:18;;:::i;:::-;2222:2;2216:9;2190:2;2276:13;;-1:-1:-1;;2272:22:1;;;2296:2;2268:31;2264:40;2252:53;;;2320:18;;;2340:22;;;2317:46;2314:72;;;2366:18;;:::i;:::-;2406:10;2402:2;2395:22;2441:2;2433:6;2426:18;2481:7;2476:2;2471;2467;2463:11;2459:20;2456:33;2453:53;;;2502:1;2499;2492:12;2453:53;2558:2;2553;2549;2545:11;2540:2;2532:6;2528:15;2515:46;2603:1;2598:2;2593;2585:6;2581:15;2577:24;2570:35;2624:6;2614:16;;;;;;;1498:1138;;;;;;;:::o;2641:254::-;2706:6;2714;2767:2;2755:9;2746:7;2742:23;2738:32;2735:52;;;2783:1;2780;2773:12;2735:52;2806:29;2825:9;2806:29;:::i;:::-;2796:39;;2854:35;2885:2;2874:9;2870:18;2854:35;:::i;2900:254::-;2968:6;2976;3029:2;3017:9;3008:7;3004:23;3000:32;2997:52;;;3045:1;3042;3035:12;2997:52;3068:29;3087:9;3068:29;:::i;:::-;3058:39;3144:2;3129:18;;;;3116:32;;-1:-1:-1;;;2900:254:1:o;3159:180::-;3215:6;3268:2;3256:9;3247:7;3243:23;3239:32;3236:52;;;3284:1;3281;3274:12;3236:52;3307:26;3323:9;3307:26;:::i;3344:245::-;3402:6;3455:2;3443:9;3434:7;3430:23;3426:32;3423:52;;;3471:1;3468;3461:12;3423:52;3510:9;3497:23;3529:30;3553:5;3529:30;:::i;3594:249::-;3663:6;3716:2;3704:9;3695:7;3691:23;3687:32;3684:52;;;3732:1;3729;3722:12;3684:52;3764:9;3758:16;3783:30;3807:5;3783:30;:::i;3848:267::-;3918:6;3971:2;3959:9;3950:7;3946:23;3942:32;3939:52;;;3987:1;3984;3977:12;3939:52;4026:9;4013:23;4065:1;4058:5;4055:12;4045:40;;4081:1;4078;4071:12;4120:410;4191:6;4199;4252:2;4240:9;4231:7;4227:23;4223:32;4220:52;;;4268:1;4265;4258:12;4220:52;4308:9;4295:23;-1:-1:-1;;;;;4333:6:1;4330:30;4327:50;;;4373:1;4370;4363:12;4327:50;4412:58;4462:7;4453:6;4442:9;4438:22;4412:58;:::i;:::-;4489:8;;4386:84;;-1:-1:-1;4120:410:1;-1:-1:-1;;;;4120:410:1:o;4535:180::-;4594:6;4647:2;4635:9;4626:7;4622:23;4618:32;4615:52;;;4663:1;4660;4653:12;4615:52;-1:-1:-1;4686:23:1;;4535:180;-1:-1:-1;4535:180:1:o;4720:254::-;4788:6;4796;4849:2;4837:9;4828:7;4824:23;4820:32;4817:52;;;4865:1;4862;4855:12;4817:52;4901:9;4888:23;4878:33;;4930:38;4964:2;4953:9;4949:18;4930:38;:::i;4979:545::-;5067:6;5075;5083;5091;5144:2;5132:9;5123:7;5119:23;5115:32;5112:52;;;5160:1;5157;5150:12;5112:52;5196:9;5183:23;5173:33;;5253:2;5242:9;5238:18;5225:32;5215:42;;5308:2;5297:9;5293:18;5280:32;-1:-1:-1;;;;;5327:6:1;5324:30;5321:50;;;5367:1;5364;5357:12;5321:50;5406:58;5456:7;5447:6;5436:9;5432:22;5406:58;:::i;:::-;4979:545;;;;-1:-1:-1;5483:8:1;-1:-1:-1;;;;4979:545:1:o;5529:257::-;5570:3;5608:5;5602:12;5635:6;5630:3;5623:19;5651:63;5707:6;5700:4;5695:3;5691:14;5684:4;5677:5;5673:16;5651:63;:::i;:::-;5768:2;5747:15;-1:-1:-1;;5743:29:1;5734:39;;;;5775:4;5730:50;;5529:257;-1:-1:-1;;5529:257:1:o;5791:470::-;5970:3;6008:6;6002:13;6024:53;6070:6;6065:3;6058:4;6050:6;6046:17;6024:53;:::i;:::-;6140:13;;6099:16;;;;6162:57;6140:13;6099:16;6196:4;6184:17;;6162:57;:::i;:::-;6235:20;;5791:470;-1:-1:-1;;;;5791:470:1:o;7449:488::-;-1:-1:-1;;;;;7718:15:1;;;7700:34;;7770:15;;7765:2;7750:18;;7743:43;7817:2;7802:18;;7795:34;;;7865:3;7860:2;7845:18;;7838:31;;;7643:4;;7886:45;;7911:19;;7903:6;7886:45;:::i;:::-;7878:53;7449:488;-1:-1:-1;;;;;;7449:488:1:o;9285:339::-;9428:2;9413:18;;9461:1;9450:13;;9440:144;;9506:10;9501:3;9497:20;9494:1;9487:31;9541:4;9538:1;9531:15;9569:4;9566:1;9559:15;9440:144;9593:25;;;9285:339;:::o;9629:390::-;9788:2;9777:9;9770:21;9827:6;9822:2;9811:9;9807:18;9800:34;9884:6;9876;9871:2;9860:9;9856:18;9843:48;9940:1;9911:22;;;9935:2;9907:31;;;9900:42;;;;10003:2;9982:15;;;-1:-1:-1;;9978:29:1;9963:45;9959:54;;9629:390;-1:-1:-1;9629:390:1:o;10024:219::-;10173:2;10162:9;10155:21;10136:4;10193:44;10233:2;10222:9;10218:18;10210:6;10193:44;:::i;10248:417::-;10453:2;10442:9;10435:21;10416:4;10473:44;10513:2;10502:9;10498:18;10490:6;10473:44;:::i;:::-;-1:-1:-1;;;;;10591:15:1;;;10586:2;10571:18;;10564:43;10643:15;;;;10638:2;10623:18;;;10616:43;10465:52;10248:417;-1:-1:-1;;10248:417:1:o;14774:356::-;14976:2;14958:21;;;14995:18;;;14988:30;15054:34;15049:2;15034:18;;15027:62;15121:2;15106:18;;14774:356::o;18547:128::-;18587:3;18618:1;18614:6;18611:1;18608:13;18605:39;;;18624:18;;:::i;:::-;-1:-1:-1;18660:9:1;;18547:128::o;18680:120::-;18720:1;18746;18736:35;;18751:18;;:::i;:::-;-1:-1:-1;18785:9:1;;18680:120::o;18805:168::-;18845:7;18911:1;18907;18903:6;18899:14;18896:1;18893:21;18888:1;18881:9;18874:17;18870:45;18867:71;;;18918:18;;:::i;:::-;-1:-1:-1;18958:9:1;;18805:168::o;18978:125::-;19018:4;19046:1;19043;19040:8;19037:34;;;19051:18;;:::i;:::-;-1:-1:-1;19088:9:1;;18978:125::o;19108:258::-;19180:1;19190:113;19204:6;19201:1;19198:13;19190:113;;;19280:11;;;19274:18;19261:11;;;19254:39;19226:2;19219:10;19190:113;;;19321:6;19318:1;19315:13;19312:48;;;-1:-1:-1;;19356:1:1;19338:16;;19331:27;19108:258::o;19371:380::-;19450:1;19446:12;;;;19493;;;19514:61;;19568:4;19560:6;19556:17;19546:27;;19514:61;19621:2;19613:6;19610:14;19590:18;19587:38;19584:161;;;19667:10;19662:3;19658:20;19655:1;19648:31;19702:4;19699:1;19692:15;19730:4;19727:1;19720:15;19584:161;;19371:380;;;:::o;19756:135::-;19795:3;-1:-1:-1;;19816:17:1;;19813:43;;;19836:18;;:::i;:::-;-1:-1:-1;19883:1:1;19872:13;;19756:135::o;19896:112::-;19928:1;19954;19944:35;;19959:18;;:::i;:::-;-1:-1:-1;19993:9:1;;19896:112::o;20013:127::-;20074:10;20069:3;20065:20;20062:1;20055:31;20105:4;20102:1;20095:15;20129:4;20126:1;20119:15;20145:127;20206:10;20201:3;20197:20;20194:1;20187:31;20237:4;20234:1;20227:15;20261:4;20258:1;20251:15;20277:127;20338:10;20333:3;20329:20;20326:1;20319:31;20369:4;20366:1;20359:15;20393:4;20390:1;20383:15;20409:127;20470:10;20465:3;20461:20;20458:1;20451:31;20501:4;20498:1;20491:15;20525:4;20522:1;20515:15;20541:127;20602:10;20597:3;20593:20;20590:1;20583:31;20633:4;20630:1;20623:15;20657:4;20654:1;20647:15;20673:131;-1:-1:-1;;;;;;20747:32:1;;20737:43;;20727:71;;20794:1;20791;20784:12

Swarm Source

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