ETH Price: $3,876.94 (+0.76%)

Token

The EscapeVerse (PUZZLE)
 

Overview

Max Total Supply

455 PUZZLE

Holders

101

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
2 PUZZLE
0x24e6d109b7085ad340480fa2a1d484d144b41efb
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
TheEscapeVerseCollection

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// SPDX-License-Identifier: MIT
// File: contracts/IOperatorFilterRegistry.sol


pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);
    function register(address registrant) external;
    function registerAndSubscribe(address registrant, address subscription) external;
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;
    function unregister(address addr) external;
    function updateOperator(address registrant, address operator, bool filtered) external;
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
    function subscribe(address registrant, address registrantToSubscribe) external;
    function unsubscribe(address registrant, bool copyExistingEntries) external;
    function subscriptionOf(address addr) external returns (address registrant);
    function subscribers(address registrant) external returns (address[] memory);
    function subscriberAt(address registrant, uint256 index) external returns (address);
    function copyEntriesOf(address registrant, address registrantToCopy) external;
    function isOperatorFiltered(address registrant, address operator) external returns (bool);
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
    function filteredOperators(address addr) external returns (address[] memory);
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
    function isRegistered(address addr) external returns (bool);
    function codeHashOf(address addr) external returns (bytes32);
}

// File: contracts/OperatorFilterer.sol


pragma solidity ^0.8.13;


abstract contract OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry constant operatorFilterRegistry =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

    constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(operatorFilterRegistry).code.length > 0) {
            if (subscribe) {
                operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
                } else {
                    operatorFilterRegistry.register(address(this));
                }
            }
        }
    }

    modifier onlyAllowedOperator(address from) virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(operatorFilterRegistry).code.length > 0) {
            // Allow spending tokens from addresses with balance
            // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
            // from an EOA.
            if (from == msg.sender) {
                _;
                return;
            }
            if (
                !(
                    operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)
                        && operatorFilterRegistry.isOperatorAllowed(address(this), from)
                )
            ) {
                revert OperatorNotAllowed(msg.sender);
            }
        }
        _;
    }
}

// File: contracts/DefaultOperatorFilterer.sol


pragma solidity ^0.8.13;


abstract contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}

// File: contracts/nft_contract_new.sol




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

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

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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

// File: contracts/contract.sol

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

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

pragma solidity ^0.8.0;

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

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

    function _efficientHash(bytes32 a, bytes32 b)
        private
        pure
        returns (bytes32 value)
    {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

// File: default_workspace/contracts/contract.sol

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

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

pragma solidity ^0.8.0;

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

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

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

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

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


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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

        return (signer, RecoverError.NoError);
    }

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

pragma solidity ^0.8.0;

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

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

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

pragma solidity ^0.8.0;

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/**
 * @dev Interface of an ERC721A compliant contract.
 */
interface IERC721A is IERC721, IERC721Metadata {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

    /**
     * The token does not exist.
     */
    error ApprovalQueryForNonexistentToken();

    /**
     * The caller cannot approve to their own address.
     */
    error ApproveToCaller();

    /**
     * The caller cannot approve to the current owner.
     */
    error ApprovalToCurrentOwner();

    /**
     * Cannot query the balance for the zero address.
     */
    error BalanceQueryForZeroAddress();

    /**
     * Cannot mint to the zero address.
     */
    error MintToZeroAddress();

    /**
     * The quantity of tokens minted must be more than zero.
     */
    error MintZeroQuantity();

    /**
     * The token does not exist.
     */
    error OwnerQueryForNonexistentToken();

    /**
     * The caller must own the token or be an approved operator.
     */
    error TransferCallerNotOwnerNorApproved();

    /**
     * The token must be owned by `from`.
     */
    error TransferFromIncorrectOwner();

    /**
     * Cannot safely transfer to a contract that does not implement the ERC721Receiver interface.
     */
    error TransferToNonERC721ReceiverImplementer();

    /**
     * Cannot transfer to the zero address.
     */
    error TransferToZeroAddress();

    /**
     * The token does not exist.
     */
    error URIQueryForNonexistentToken();

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

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     *
     * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens.
     */
    function totalSupply() external view returns (uint256);
}

/**
 * @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 DefaultOperatorFilterer, Context, ERC165, IERC721A {
    using Address for address;
    using Strings for uint256;

    // 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 Burned tokens are calculated here, use _totalMinted() if you want to count just minted tokens.
     */
    function totalSupply() public view override 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) {
        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) {
        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) {
        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 {
        _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)
                if (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)
            if (!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
        virtual
        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 onlyAllowedOperator(from) {
        _transfer(from, to, tokenId);
    }

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

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

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    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 {
        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 (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 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) 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;

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

        if (prevOwnership.addr != from) revert TransferFromIncorrectOwner();

        bool isApprovedOrOwner = (_msgSender() == from ||
            isApprovedForAll(from, _msgSender()) ||
            getApproved(tokenId) == _msgSender());

        if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

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

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

            TokenOwnership storage currSlot = _ownerships[tokenId];
            currSlot.addr = to;
            currSlot.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;
            TokenOwnership storage nextSlot = _ownerships[nextTokenId];
            if (nextSlot.addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId != _currentIndex) {
                    nextSlot.addr = from;
                    nextSlot.startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

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

    /**
     * @dev Equivalent to `_burn(tokenId, false)`.
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
        TokenOwnership memory prevOwnership = _ownershipOf(tokenId);

        address from = prevOwnership.addr;

        if (approvalCheck) {
            bool isApprovedOrOwner = (_msgSender() == from ||
                isApprovedForAll(from, _msgSender()) ||
                getApproved(tokenId) == _msgSender());

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

        _beforeTokenTransfers(from, address(0), tokenId, 1);

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

        // 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 storage addressData = _addressData[from];
            addressData.balance -= 1;
            addressData.numberBurned += 1;

            // Keep track of who burned the token, and the timestamp of burning.
            TokenOwnership storage currSlot = _ownerships[tokenId];
            currSlot.addr = from;
            currSlot.startTimestamp = uint64(block.timestamp);
            currSlot.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;
            TokenOwnership storage nextSlot = _ownerships[nextTokenId];
            if (nextSlot.addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId != _currentIndex) {
                    nextSlot.addr = from;
                    nextSlot.startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, 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 {}
}

interface Verifier {
  function verify(address, uint256, bytes32[] memory) external view returns (bool);
}

contract TheEscapeVerseCollection is ERC721A, Ownable, ReentrancyGuard {
    using ECDSA for bytes32;
    using Strings for uint256;

    uint256 public presaleTokenPrice = 0.04 ether;
    uint256 public tokenPrice = 0.04 ether;
    uint256 public bonusTokenPrice = 0;

    //uint256 public maxTokensPerMint = 0; //not used
    uint256 public maxTokensPerWhitelistedAddress = 100000;
    uint256 public maxTokensPerAddress = 100000;
    
    string public tokenURIExtension = "";
    string public tokenBaseURI = "ipfs://QmXHXPZDVYtDH2w4c7AfQeGtJkgkgHUN1aHiTDoAy4Kiji/";

    uint256 public tokensToGift = 0;
    uint256 public teamReservedTokens = 200;
    address public teamTokensAddress =
        0xe939777Bd4992DB4Ae3C2DD0431b38D1F7c1451d;
    uint256 public currentMaxTokens = 1200;
    uint256 public firstStageTokens = 7500;
    uint256 public tokensToBuyAmount =
        firstStageTokens - tokensToGift - teamReservedTokens;
    uint256 public secondStageTokensRemaining = 2500;

    bool public hasPresaleStarted = false;
    bool public hasPublicSaleStarted = false;
    
    address public bonusVerifierAddr;

    bytes32 public whitelistRoot;
    mapping(address => uint256) public purchased;

    address public signerAddress;
    mapping(uint256 => uint256) public iqPoints;
    mapping(address => uint256) private usedNonces;

    constructor() ERC721A("The EscapeVerse", "PUZZLE") {
        _safeMint(teamTokensAddress, teamReservedTokens);
    }

    function _startTokenId() internal pure override(ERC721A) returns (uint256) {
        return 1;
    }

    function setSignerAddress(address val) external onlyOwner {
        signerAddress = val;
    }

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

    function hashTransaction(address sender, uint256 amount, uint256 nonce) private pure returns(bytes32) {
        bytes32 hash = keccak256(abi.encodePacked(
            "\x19Ethereum Signed Message:\n32",
            keccak256(abi.encodePacked(sender, amount, nonce)))
        );
        
        return hash;
    }

    function addIqPoints(uint256[] calldata tokenIds, uint256[] calldata points, bytes32 hash, bytes memory signature, uint256 nonce) external {
        require(tokenIds.length == points.length, "Different number of tokens and iq points batches.");
        require(matchAddresSigner(hash, signature), "Direct iq add is not allowed");
        require(nonce == usedNonces[msg.sender], "Nonce already used");

        uint256 sum = 0;
        for(uint256 i = 0; i < points.length; i++) {
            iqPoints[points[i]] += points[i];
        }

        require(hashTransaction(msg.sender, sum, nonce) == hash, "Hash does not match");

        for(uint256 i = 0; i < tokenIds.length; i++) {
            iqPoints[tokenIds[i]] += points[i];
        }

        usedNonces[msg.sender] += 1;
    }

    function getIQ(uint256 id) public view returns (uint256) {
        return iqPoints[id];
    }

    function updateCurrentMaxTokens(uint256 val) external onlyOwner {
        require(val <= firstStageTokens);
        currentMaxTokens = val;
    }

    function setBonusVerifier(address addr) external onlyOwner {
        bonusVerifierAddr = addr;
    }

    function setMaxTokensPerWhitelistedAddress(uint256 val) external onlyOwner {
        maxTokensPerWhitelistedAddress = val;
    }

    function setMaxTokensPerAddress(uint256 val) external onlyOwner {
        maxTokensPerAddress = val;
    }

    function stopSale() external onlyOwner {
        hasPresaleStarted = false;
        hasPublicSaleStarted = false;
    }

    function startPresale() external onlyOwner {
        hasPresaleStarted = true;
        hasPublicSaleStarted = false;
    }

    function startPublicSale() external onlyOwner {
        hasPresaleStarted = true;
        hasPublicSaleStarted = true;
    }

    function setPresalePrice(uint256 val) external onlyOwner {
        presaleTokenPrice = val;
    }

    function setTokenPrice(uint256 val) external onlyOwner {
        tokenPrice = val;
    }

    function setBonusTokenPrice(uint256 val) external onlyOwner {
        bonusTokenPrice = val;
    }

    function getCurrenTokenPrice() public view returns (uint256) {
        if (hasPublicSaleStarted) {
            return tokenPrice;
        } else {
            return presaleTokenPrice;
        }
    }

    function verify(address account, bytes32[] memory proof)
        public
        view
        returns (bool)
    {
        bytes32 leaf = keccak256(abi.encodePacked(account));
        return MerkleProof.verify(proof, whitelistRoot, leaf);
    }

    function mint(address to, uint256 amount, bytes32[] memory proof) external payable nonReentrant {
        require(msg.value >= (hasPublicSaleStarted ? tokenPrice : presaleTokenPrice) * amount, "Incorrect ETH");
        require(hasPresaleStarted, "Cannot mint before presale");
        //require(amount <= maxTokensPerMint, "Cannot mint more than the max tokens per mint");
        require(amount <= tokensToBuyAmount, "No tokens left for minting");
        require(totalSupply() + amount <= currentMaxTokens, "No more tokens allowed at this stage of mint.");

        if (hasPublicSaleStarted) {
            require(purchased[to] + amount <= maxTokensPerAddress, "Cannot mint more than max tokens per address");
        } else {
            require(verify(to, proof), "Buyer not whitelisted for presale");
            require(purchased[to] + amount <= maxTokensPerWhitelistedAddress, "Cannot mint more than the max tokens per whitelisted address");
        }

        _safeMint(to, amount);

        purchased[to] += amount;

        tokensToBuyAmount -= amount;
    }

    function bonusMint(address to, uint256 amount, bytes32[] memory proof) external payable nonReentrant {
        require(msg.value >= bonusTokenPrice * amount, "Incorrect ETH");
        require(amount <= secondStageTokensRemaining, "No tokens left for minting");

        require(bonusVerifierAddr != address(0), "Verifier address is not valid");

        Verifier ver = Verifier(bonusVerifierAddr);
        require(ver.verify(to, amount, proof), "Not eligible to mint bonus tokens");
        
        _safeMint(to, amount);

        secondStageTokensRemaining -= amount;
    }

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

    function setBaseURI(string calldata URI) external onlyOwner {
        tokenBaseURI = URI;
    }

    function setURIExtension(string calldata ext) external onlyOwner {
        tokenURIExtension = ext;
    }

    function setWhitelistRoot(bytes32 _whitelistRoot) public onlyOwner {
        whitelistRoot = _whitelistRoot;
    }

    function withdraw() external onlyOwner {
        require(payable(msg.sender).send(address(this).balance));
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721A)
        returns (string memory)
    {
        return string(abi.encodePacked(super.tokenURI(tokenId), tokenURIExtension));
    }
}

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":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","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":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"points","type":"uint256[]"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"addIqPoints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"bonusMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"bonusTokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bonusVerifierAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentMaxTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"firstStageTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrenTokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getIQ","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hasPresaleStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hasPublicSaleStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"iqPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokensPerAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokensPerWhitelistedAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleTokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"purchased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"secondStageTokensRemaining","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"URI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"setBonusTokenPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setBonusVerifier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"setMaxTokensPerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"setMaxTokensPerWhitelistedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"setPresalePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"val","type":"address"}],"name":"setSignerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"setTokenPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"ext","type":"string"}],"name":"setURIExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_whitelistRoot","type":"bytes32"}],"name":"setWhitelistRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startPresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startPublicSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stopSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamReservedTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamTokensAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenBaseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenURIExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensToBuyAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensToGift","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":"val","type":"uint256"}],"name":"updateCurrentMaxTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"verify","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

668e1bc9bf040000600a819055600b556000600c819055620186a0600d819055600e5560a06040526080908152600f906200003b9082620006c5565b5060405180606001604052806036815260200162003ed160369139601090620000659082620006c5565b506000601181905560c86012819055601380546001600160a01b03191673e939777bd4992db4ae3c2dd0431b38d1f7c1451d1790556104b0601455611d4c60158190559091620000b59162000791565b620000c1919062000791565b6016556109c46017556018805461ffff19169055348015620000e257600080fd5b50604080518082018252600f81526e54686520457363617065566572736560881b6020808301919091528251808401909352600683526550555a5a4c4560d01b9083015290733cc6cdda760b79bafa08df41ecfa224f810dceb660016daaeb6d7670e522a718067333cd4e3b1562000283578015620001d157604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b158015620001b257600080fd5b505af1158015620001c7573d6000803e3d6000fd5b5050505062000283565b6001600160a01b03821615620002225760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af29039060440162000197565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b1580156200026957600080fd5b505af11580156200027e573d6000803e3d6000fd5b505050505b5060029050620002948382620006c5565b506003620002a38282620006c5565b5050600160005550620002b633620002dc565b6001600955601354601254620002d6916001600160a01b0316906200032e565b6200085f565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b620003508282604051806020016040528060008152506200035460201b60201c565b5050565b6000546001600160a01b0384166200037e57604051622e076360e81b815260040160405180910390fd5b82600003620003a05760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038416600081815260056020908152604080832080546001600160801b031981166001600160401b038083168b018116918217680100000000000000006001600160401b031990941690921783900481168b0181169092021790915585845260048352922080546001600160e01b0319168417600160a01b4290941693909302929092179091558291828601916200044991906200051d811b6200207317901c565b15620004c8575b60405182906001600160a01b0388169060009060008051602062003f07833981519152908290a460018201916200048d906000908890876200052c565b620004ab576040516368d2bf6b60e11b815260040160405180910390fd5b80821062000450578260005414620004c257600080fd5b620004fd565b5b6040516001830192906001600160a01b0388169060009060008051602062003f07833981519152908290a4808210620004c9575b50600090815562000517908583866001600160e01b038516565b50505050565b6001600160a01b03163b151590565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a029062000563903390899088908890600401620007b9565b6020604051808303816000875af1925050508015620005a1575060408051601f3d908101601f191682019092526200059e918101906200082c565b60015b62000603573d808015620005d2576040519150601f19603f3d011682016040523d82523d6000602084013e620005d7565b606091505b508051600003620005fb576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200064b57607f821691505b6020821081036200066c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620006c057600081815260208120601f850160051c810160208610156200069b5750805b601f850160051c820191505b81811015620006bc57828155600101620006a7565b5050505b505050565b81516001600160401b03811115620006e157620006e162000620565b620006f981620006f2845462000636565b8462000672565b602080601f831160018114620007315760008415620007185750858301515b600019600386901b1c1916600185901b178555620006bc565b600085815260208120601f198616915b82811015620007625788860151825594840194600190910190840162000741565b5085821015620007815787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b81810381811115620007b357634e487b7160e01b600052601160045260246000fd5b92915050565b600060018060a01b038087168352602081871681850152856040850152608060608501528451915081608085015260005b82811015620008085785810182015185820160a001528101620007ea565b5050600060a0828501015260a0601f19601f83011684010191505095945050505050565b6000602082840312156200083f57600080fd5b81516001600160e01b0319811681146200085857600080fd5b9392505050565b613662806200086f6000396000f3fe60806040526004361061038c5760003560e01c8063715018a6116101dc578063b76a0df411610102578063f112e0a7116100a0578063fdd4b0f01161006f578063fdd4b0f014610a1a578063fdfd30d214610a39578063ff45cb9514610a4f578063ffc22fa814610a6557600080fd5b8063f112e0a7146109a4578063f2fde38b146109c4578063f5aa406d146109e4578063f8972c8a14610a0457600080fd5b8063dbb84f11116100dc578063dbb84f1114610910578063e36b0b3714610930578063e985e9c514610945578063efe3f3931461098e57600080fd5b8063b76a0df4146108b0578063b88d4fde146108d0578063c87b56dd146108f057600080fd5b8063907097511161017a578063a22cb46511610149578063a22cb4651461083a578063a6d233ff1461085a578063ae47e72b14610880578063b02200151461089657600080fd5b806390709751146107d957806393777fb3146107f9578063949e180a1461080f57806395d89b411461082557600080fd5b80637ff9b596116101b65780637ff9b59614610770578063854d319c146107865780638da5cb5b1461079b5780638ea67909146107b957600080fd5b8063715018a61461072657806379f874fd1461073b5780637b0de0151461075057600080fd5b80633549345e116102c15780635b7633d01161025f57806364ae92eb1161022e57806364ae92eb146106995780636a61e5fc146106b95780636efe28bd146106d957806370a082311461070657600080fd5b80635b7633d01461063057806360033400146106505780636352211e14610666578063641ce1401461068657600080fd5b806342842e0e1161029b57806342842e0e146105ae5780634e99b800146105ce578063522fe98e146105e357806355f804b31461061057600080fd5b80633549345e14610563578063386bfc98146105835780633ccfd60b1461059957600080fd5b806309b2c7f31161032e5780631b2dcfde116103085780631b2dcfde146104e057806323a1baaa1461050057806323b872dd146105165780633164e5e01461053657600080fd5b806309b2c7f31461049b5780630c1c972a146104ae57806318160ddd146104c357600080fd5b806304c98b2b1161036a57806304c98b2b1461040c57806306fdde0314610421578063081812fc14610443578063095ea7b31461047b57600080fd5b80630108bdb71461039157806301ffc9a7146103ba578063046dc166146103ea575b600080fd5b34801561039d57600080fd5b506103a7600c5481565b6040519081526020015b60405180910390f35b3480156103c657600080fd5b506103da6103d5366004612d03565b610a85565b60405190151581526020016103b1565b3480156103f657600080fd5b5061040a610405366004612d3c565b610ad7565b005b34801561041857600080fd5b5061040a610b2c565b34801561042d57600080fd5b50610436610b66565b6040516103b19190612da7565b34801561044f57600080fd5b5061046361045e366004612dba565b610bf8565b6040516001600160a01b0390911681526020016103b1565b34801561048757600080fd5b5061040a610496366004612dd3565b610c3c565b61040a6104a9366004612ec2565b610cc2565b3480156104ba57600080fd5b5061040a610f14565b3480156104cf57600080fd5b5060015460005403600019016103a7565b3480156104ec57600080fd5b5061040a6104fb366004612dba565b610f4f565b34801561050c57600080fd5b506103a7600e5481565b34801561052257600080fd5b5061040a610531366004612f18565b610f7e565b34801561054257600080fd5b506103a7610551366004612dba565b601c6020526000908152604090205481565b34801561056f57600080fd5b5061040a61057e366004612dba565b6110da565b34801561058f57600080fd5b506103a760195481565b3480156105a557600080fd5b5061040a611109565b3480156105ba57600080fd5b5061040a6105c9366004612f18565b611159565b3480156105da57600080fd5b506104366112ca565b3480156105ef57600080fd5b506103a76105fe366004612d3c565b601a6020526000908152604090205481565b34801561061c57600080fd5b5061040a61062b366004612f54565b611358565b34801561063c57600080fd5b50601b54610463906001600160a01b031681565b34801561065c57600080fd5b506103a7600d5481565b34801561067257600080fd5b50610463610681366004612dba565b61138f565b61040a610694366004612ec2565b6113a1565b3480156106a557600080fd5b5061040a6106b4366004613078565b611775565b3480156106c557600080fd5b5061040a6106d4366004612dba565b611a74565b3480156106e557600080fd5b506103a76106f4366004612dba565b6000908152601c602052604090205490565b34801561071257600080fd5b506103a7610721366004612d3c565b611aa3565b34801561073257600080fd5b5061040a611af1565b34801561074757600080fd5b506103a7611b25565b34801561075c57600080fd5b50601354610463906001600160a01b031681565b34801561077c57600080fd5b506103a7600b5481565b34801561079257600080fd5b50610436611b46565b3480156107a757600080fd5b506008546001600160a01b0316610463565b3480156107c557600080fd5b5061040a6107d4366004612d3c565b611b53565b3480156107e557600080fd5b5061040a6107f4366004612f54565b611ba7565b34801561080557600080fd5b506103a7600a5481565b34801561081b57600080fd5b506103a760125481565b34801561083157600080fd5b50610436611bde565b34801561084657600080fd5b5061040a61085536600461312c565b611bed565b34801561086657600080fd5b50601854610463906201000090046001600160a01b031681565b34801561088c57600080fd5b506103a760175481565b3480156108a257600080fd5b506018546103da9060ff1681565b3480156108bc57600080fd5b506103da6108cb366004613163565b611c82565b3480156108dc57600080fd5b5061040a6108eb3660046131b0565b611cd3565b3480156108fc57600080fd5b5061043661090b366004612dba565b611ea2565b34801561091c57600080fd5b5061040a61092b366004612dba565b611ed6565b34801561093c57600080fd5b5061040a611f05565b34801561095157600080fd5b506103da610960366004613217565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561099a57600080fd5b506103a760115481565b3480156109b057600080fd5b5061040a6109bf366004612dba565b611f3c565b3480156109d057600080fd5b5061040a6109df366004612d3c565b611f7a565b3480156109f057600080fd5b5061040a6109ff366004612dba565b612015565b348015610a1057600080fd5b506103a760145481565b348015610a2657600080fd5b506018546103da90610100900460ff1681565b348015610a4557600080fd5b506103a760155481565b348015610a5b57600080fd5b506103a760165481565b348015610a7157600080fd5b5061040a610a80366004612dba565b612044565b60006001600160e01b031982166380ac58cd60e01b1480610ab657506001600160e01b03198216635b5e139f60e01b145b80610ad157506301ffc9a760e01b6001600160e01b03198316145b92915050565b6008546001600160a01b03163314610b0a5760405162461bcd60e51b8152600401610b019061324a565b60405180910390fd5b601b80546001600160a01b0319166001600160a01b0392909216919091179055565b6008546001600160a01b03163314610b565760405162461bcd60e51b8152600401610b019061324a565b6018805461ffff19166001179055565b606060028054610b759061327f565b80601f0160208091040260200160405190810160405280929190818152602001828054610ba19061327f565b8015610bee5780601f10610bc357610100808354040283529160200191610bee565b820191906000526020600020905b815481529060010190602001808311610bd157829003601f168201915b5050505050905090565b6000610c0382612082565b610c20576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610c478261138f565b9050806001600160a01b0316836001600160a01b031603610c7b5760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b03821614610cb257610c958133610960565b610cb2576040516367d9dca160e11b815260040160405180910390fd5b610cbd8383836120bb565b505050565b600260095403610d145760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610b01565b6002600955600c54610d279083906132cf565b341015610d665760405162461bcd60e51b815260206004820152600d60248201526c092dcc6dee4e4cac6e8408aa89609b1b6044820152606401610b01565b601754821115610db85760405162461bcd60e51b815260206004820152601a60248201527f4e6f20746f6b656e73206c65667420666f72206d696e74696e670000000000006044820152606401610b01565b6018546201000090046001600160a01b0316610e165760405162461bcd60e51b815260206004820152601d60248201527f56657269666965722061646472657373206973206e6f742076616c69640000006044820152606401610b01565b6018546040516345f0430f60e11b8152620100009091046001600160a01b0316908190638be0861e90610e51908790879087906004016132e6565b602060405180830381865afa158015610e6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e929190613343565b610ee85760405162461bcd60e51b815260206004820152602160248201527f4e6f7420656c696769626c6520746f206d696e7420626f6e757320746f6b656e6044820152607360f81b6064820152608401610b01565b610ef28484612117565b8260176000828254610f049190613360565b9091555050600160095550505050565b6008546001600160a01b03163314610f3e5760405162461bcd60e51b8152600401610b019061324a565b6018805461ffff1916610101179055565b6008546001600160a01b03163314610f795760405162461bcd60e51b8152600401610b019061324a565b600c55565b826daaeb6d7670e522a718067333cd4e3b156110c957336001600160a01b03821603610fb457610faf848484612135565b6110d4565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611003573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110279190613343565b80156110aa5750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611086573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110aa9190613343565b6110c957604051633b79c77360e21b8152336004820152602401610b01565b6110d4848484612135565b50505050565b6008546001600160a01b031633146111045760405162461bcd60e51b8152600401610b019061324a565b600a55565b6008546001600160a01b031633146111335760405162461bcd60e51b8152600401610b019061324a565b60405133904780156108fc02916000818181858888f1935050505061115757600080fd5b565b826daaeb6d7670e522a718067333cd4e3b156112af57336001600160a01b0382160361119a57610faf84848460405180602001604052806000815250611cd3565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa1580156111e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061120d9190613343565b80156112905750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa15801561126c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112909190613343565b6112af57604051633b79c77360e21b8152336004820152602401610b01565b6110d484848460405180602001604052806000815250611cd3565b601080546112d79061327f565b80601f01602080910402602001604051908101604052809291908181526020018280546113039061327f565b80156113505780601f1061132557610100808354040283529160200191611350565b820191906000526020600020905b81548152906001019060200180831161133357829003601f168201915b505050505081565b6008546001600160a01b031633146113825760405162461bcd60e51b8152600401610b019061324a565b6010610cbd8284836133c1565b600061139a82612320565b5192915050565b6002600954036113f35760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610b01565b60026009556018548290610100900460ff1661141157600a54611415565b600b545b61141f91906132cf565b34101561145e5760405162461bcd60e51b815260206004820152600d60248201526c092dcc6dee4e4cac6e8408aa89609b1b6044820152606401610b01565b60185460ff166114b05760405162461bcd60e51b815260206004820152601a60248201527f43616e6e6f74206d696e74206265666f72652070726573616c650000000000006044820152606401610b01565b6016548211156115025760405162461bcd60e51b815260206004820152601a60248201527f4e6f20746f6b656e73206c65667420666f72206d696e74696e670000000000006044820152606401610b01565b601454600154600054849190036000190161151d9190613480565b11156115815760405162461bcd60e51b815260206004820152602d60248201527f4e6f206d6f726520746f6b656e7320616c6c6f7765642061742074686973207360448201526c3a30b3b29037b31036b4b73a1760991b6064820152608401610b01565b601854610100900460ff161561162057600e546001600160a01b0384166000908152601a60205260409020546115b8908490613480565b111561161b5760405162461bcd60e51b815260206004820152602c60248201527f43616e6e6f74206d696e74206d6f7265207468616e206d617820746f6b656e7360448201526b20706572206164647265737360a01b6064820152608401610b01565b61171b565b61162a8382611c82565b6116805760405162461bcd60e51b815260206004820152602160248201527f4275796572206e6f742077686974656c697374656420666f722070726573616c6044820152606560f81b6064820152608401610b01565b600d546001600160a01b0384166000908152601a60205260409020546116a7908490613480565b111561171b5760405162461bcd60e51b815260206004820152603c60248201527f43616e6e6f74206d696e74206d6f7265207468616e20746865206d617820746f60448201527f6b656e73207065722077686974656c69737465642061646472657373000000006064820152608401610b01565b6117258383612117565b6001600160a01b0383166000908152601a60205260408120805484929061174d908490613480565b9250508190555081601660008282546117669190613360565b90915550506001600955505050565b8584146117de5760405162461bcd60e51b815260206004820152603160248201527f446966666572656e74206e756d626572206f6620746f6b656e7320616e64206960448201527038903837b4b73a39903130ba31b432b99760791b6064820152608401610b01565b6117e88383612442565b6118345760405162461bcd60e51b815260206004820152601c60248201527f44697265637420697120616464206973206e6f7420616c6c6f776564000000006044820152606401610b01565b336000908152601d602052604090205481146118875760405162461bcd60e51b8152602060048201526012602482015271139bdb98d948185b1c9958591e481d5cd95960721b6044820152606401610b01565b6000805b858110156118fe578686828181106118a5576118a5613493565b90506020020135601c60008989858181106118c2576118c2613493565b90506020020135815260200190815260200160002060008282546118e69190613480565b909155508190506118f6816134a9565b91505061188b565b50604080513360601b6bffffffffffffffffffffffff1916602080830191909152603482018490526054808301869052835180840390910181526074830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a333200000000609484015260b0808401919091528351808403909101815260d0909201909252805191012084146119ce5760405162461bcd60e51b8152602060048201526013602482015272090c2e6d040c8decae640dcdee840dac2e8c6d606b1b6044820152606401610b01565b60005b87811015611a44578686828181106119eb576119eb613493565b90506020020135601c60008b8b85818110611a0857611a08613493565b9050602002013581526020019081526020016000206000828254611a2c9190613480565b90915550819050611a3c816134a9565b9150506119d1565b50336000908152601d60205260408120805460019290611a65908490613480565b90915550505050505050505050565b6008546001600160a01b03163314611a9e5760405162461bcd60e51b8152600401610b019061324a565b600b55565b60006001600160a01b038216611acc576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6008546001600160a01b03163314611b1b5760405162461bcd60e51b8152600401610b019061324a565b6111576000612466565b601854600090610100900460ff1615611b3f5750600b5490565b50600a5490565b600f80546112d79061327f565b6008546001600160a01b03163314611b7d5760405162461bcd60e51b8152600401610b019061324a565b601880546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6008546001600160a01b03163314611bd15760405162461bcd60e51b8152600401610b019061324a565b600f610cbd8284836133c1565b606060038054610b759061327f565b336001600160a01b03831603611c165760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6040516bffffffffffffffffffffffff19606084901b1660208201526000908190603401604051602081830303815290604052805190602001209050611ccb83601954836124b8565b949350505050565b836daaeb6d7670e522a718067333cd4e3b15611e5757336001600160a01b03821603611d4257611d04858585612135565b6001600160a01b0384163b15611d3d57611d20858585856124ce565b611d3d576040516368d2bf6b60e11b815260040160405180910390fd5b611e9b565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611d91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db59190613343565b8015611e385750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611e14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e389190613343565b611e5757604051633b79c77360e21b8152336004820152602401610b01565b611e62858585612135565b6001600160a01b0384163b15611e9b57611e7e858585856124ce565b611e9b576040516368d2bf6b60e11b815260040160405180910390fd5b5050505050565b6060611ead826125b9565b600f604051602001611ec09291906134c2565b6040516020818303038152906040529050919050565b6008546001600160a01b03163314611f005760405162461bcd60e51b8152600401610b019061324a565b600e55565b6008546001600160a01b03163314611f2f5760405162461bcd60e51b8152600401610b019061324a565b6018805461ffff19169055565b6008546001600160a01b03163314611f665760405162461bcd60e51b8152600401610b019061324a565b601554811115611f7557600080fd5b601455565b6008546001600160a01b03163314611fa45760405162461bcd60e51b8152600401610b019061324a565b6001600160a01b0381166120095760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b01565b61201281612466565b50565b6008546001600160a01b0316331461203f5760405162461bcd60e51b8152600401610b019061324a565b601955565b6008546001600160a01b0316331461206e5760405162461bcd60e51b8152600401610b019061324a565b600d55565b6001600160a01b03163b151590565b600081600111158015612096575060005482105b8015610ad1575050600090815260046020526040902054600160e01b900460ff161590565b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b61213182826040518060200160405280600081525061263d565b5050565b600061214082612320565b9050836001600160a01b031681600001516001600160a01b0316146121775760405162a1148160e81b815260040160405180910390fd5b6000336001600160a01b038616148061219557506121958533610960565b806121b05750336121a584610bf8565b6001600160a01b0316145b9050806121d057604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b0384166121f757604051633a954ecd60e21b815260040160405180910390fd5b612203600084876120bb565b6001600160a01b038581166000908152600560209081526040808320805467ffffffffffffffff198082166001600160401b0392831660001901831617909255898616808652838620805493841693831660019081018416949094179055898652600490945282852080546001600160e01b031916909417600160a01b429092169190910217835587018084529220805491939091166122d75760005482146122d757805460208601516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038a16171781555b50505082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611e9b565b604080516060810182526000808252602082018190529181019190915281806001116124295760005481101561242957600081815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161515918101829052906124275780516001600160a01b0316156123be579392505050565b5060001901600081815260046020908152604091829020825160608101845290546001600160a01b038116808352600160a01b82046001600160401b031693830193909352600160e01b900460ff1615159281019290925215612422579392505050565b6123be565b505b604051636f96cda160e11b815260040160405180910390fd5b600061244e8383612804565b601b546001600160a01b039182169116149392505050565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000826124c58584612828565b14949350505050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a029061250390339089908890889060040161354f565b6020604051808303816000875af192505050801561253e575060408051601f3d908101601f1916820190925261253b9181019061358c565b60015b61259c573d80801561256c576040519150601f19603f3d011682016040523d82523d6000602084013e612571565b606091505b508051600003612594576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b60606125c482612082565b6125e157604051630a14c4b560e41b815260040160405180910390fd5b60006125eb612894565b9050805160000361260b5760405180602001604052806000815250612636565b80612615846128a3565b6040516020016126269291906135a9565b6040516020818303038152906040525b9392505050565b6000546001600160a01b03841661266657604051622e076360e81b815260040160405180910390fd5b826000036126875760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038416600081815260056020908152604080832080546fffffffffffffffffffffffffffffffff1981166001600160401b038083168b0181169182176801000000000000000067ffffffffffffffff1990941690921783900481168b01811690920217909155858452600490925290912080546001600160e01b0319168317600160a01b42909316929092029190911790558190818501903b156127af575b60405182906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a461277860008784806001019550876124ce565b612795576040516368d2bf6b60e11b815260040160405180910390fd5b80821061272d5782600054146127aa57600080fd5b6127f4565b5b6040516001830192906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a48082106127b0575b5060009081556110d49085838684565b600080600061281385856129a3565b9150915061282081612a11565b509392505050565b600081815b845181101561282057600085828151811061284a5761284a613493565b602002602001015190508083116128705760008381526020829052604090209250612881565b600081815260208490526040902092505b508061288c816134a9565b91505061282d565b606060108054610b759061327f565b6060816000036128ca5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156128f457806128de816134a9565b91506128ed9050600a836135ee565b91506128ce565b6000816001600160401b0381111561290e5761290e612dfd565b6040519080825280601f01601f191660200182016040528015612938576020820181803683370190505b5090505b8415611ccb5761294d600183613360565b915061295a600a86613602565b612965906030613480565b60f81b81838151811061297a5761297a613493565b60200101906001600160f81b031916908160001a90535061299c600a866135ee565b945061293c565b60008082516041036129d95760208301516040840151606085015160001a6129cd87828585612bc7565b94509450505050612a0a565b8251604003612a0257602083015160408401516129f7868383612cb4565b935093505050612a0a565b506000905060025b9250929050565b6000816004811115612a2557612a25613616565b03612a2d5750565b6001816004811115612a4157612a41613616565b03612a8e5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610b01565b6002816004811115612aa257612aa2613616565b03612aef5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610b01565b6003816004811115612b0357612b03613616565b03612b5b5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610b01565b6004816004811115612b6f57612b6f613616565b036120125760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610b01565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612bfe5750600090506003612cab565b8460ff16601b14158015612c1657508460ff16601c14155b15612c275750600090506004612cab565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612c7b573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612ca457600060019250925050612cab565b9150600090505b94509492505050565b6000806001600160ff1b03831681612cd160ff86901c601b613480565b9050612cdf87828885612bc7565b935093505050935093915050565b6001600160e01b03198116811461201257600080fd5b600060208284031215612d1557600080fd5b813561263681612ced565b80356001600160a01b0381168114612d3757600080fd5b919050565b600060208284031215612d4e57600080fd5b61263682612d20565b60005b83811015612d72578181015183820152602001612d5a565b50506000910152565b60008151808452612d93816020860160208601612d57565b601f01601f19169290920160200192915050565b6020815260006126366020830184612d7b565b600060208284031215612dcc57600080fd5b5035919050565b60008060408385031215612de657600080fd5b612def83612d20565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715612e3b57612e3b612dfd565b604052919050565b600082601f830112612e5457600080fd5b813560206001600160401b03821115612e6f57612e6f612dfd565b8160051b612e7e828201612e13565b9283528481018201928281019087851115612e9857600080fd5b83870192505b84831015612eb757823582529183019190830190612e9e565b979650505050505050565b600080600060608486031215612ed757600080fd5b612ee084612d20565b92506020840135915060408401356001600160401b03811115612f0257600080fd5b612f0e86828701612e43565b9150509250925092565b600080600060608486031215612f2d57600080fd5b612f3684612d20565b9250612f4460208501612d20565b9150604084013590509250925092565b60008060208385031215612f6757600080fd5b82356001600160401b0380821115612f7e57600080fd5b818501915085601f830112612f9257600080fd5b813581811115612fa157600080fd5b866020828501011115612fb357600080fd5b60209290920196919550909350505050565b60008083601f840112612fd757600080fd5b5081356001600160401b03811115612fee57600080fd5b6020830191508360208260051b8501011115612a0a57600080fd5b600082601f83011261301a57600080fd5b81356001600160401b0381111561303357613033612dfd565b613046601f8201601f1916602001612e13565b81815284602083860101111561305b57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600080600060a0888a03121561309357600080fd5b87356001600160401b03808211156130aa57600080fd5b6130b68b838c01612fc5565b909950975060208a01359150808211156130cf57600080fd5b6130db8b838c01612fc5565b909750955060408a0135945060608a01359150808211156130fb57600080fd5b506131088a828b01613009565b9250506080880135905092959891949750929550565b801515811461201257600080fd5b6000806040838503121561313f57600080fd5b61314883612d20565b915060208301356131588161311e565b809150509250929050565b6000806040838503121561317657600080fd5b61317f83612d20565b915060208301356001600160401b0381111561319a57600080fd5b6131a685828601612e43565b9150509250929050565b600080600080608085870312156131c657600080fd5b6131cf85612d20565b93506131dd60208601612d20565b92506040850135915060608501356001600160401b038111156131ff57600080fd5b61320b87828801613009565b91505092959194509250565b6000806040838503121561322a57600080fd5b61323383612d20565b915061324160208401612d20565b90509250929050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600181811c9082168061329357607f821691505b6020821081036132b357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610ad157610ad16132b9565b6001600160a01b038416815260208082018490526060604083018190528351908301819052600091848101916080850190845b8181101561333557845183529383019391830191600101613319565b509098975050505050505050565b60006020828403121561335557600080fd5b81516126368161311e565b81810381811115610ad157610ad16132b9565b601f821115610cbd57600081815260208120601f850160051c8101602086101561339a5750805b601f850160051c820191505b818110156133b9578281556001016133a6565b505050505050565b6001600160401b038311156133d8576133d8612dfd565b6133ec836133e6835461327f565b83613373565b6000601f84116001811461342057600085156134085750838201355b600019600387901b1c1916600186901b178355611e9b565b600083815260209020601f19861690835b828110156134515786850135825560209485019460019092019101613431565b508682101561346e5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b80820180821115610ad157610ad16132b9565b634e487b7160e01b600052603260045260246000fd5b6000600182016134bb576134bb6132b9565b5060010190565b6000835160206134d58285838901612d57565b8184019150600085546134e78161327f565b600182811680156134ff576001811461351457613540565b60ff1984168752821515830287019450613540565b896000528560002060005b848110156135385781548982015290830190870161351f565b505082870194505b50929998505050505050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061358290830184612d7b565b9695505050505050565b60006020828403121561359e57600080fd5b815161263681612ced565b600083516135bb818460208801612d57565b8351908301906135cf818360208801612d57565b01949350505050565b634e487b7160e01b600052601260045260246000fd5b6000826135fd576135fd6135d8565b500490565b600082613611576136116135d8565b500690565b634e487b7160e01b600052602160045260246000fdfea26469706673582212203f5dbf62c6d0f725c1c294efb8ec2f9b68e47aa9c65c3928bfead6e71b04dcdd64736f6c63430008110033697066733a2f2f516d584858505a44565974444832773463374166516547744a6b676b6748554e3161486954446f4179344b696a692fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef

Deployed Bytecode

0x60806040526004361061038c5760003560e01c8063715018a6116101dc578063b76a0df411610102578063f112e0a7116100a0578063fdd4b0f01161006f578063fdd4b0f014610a1a578063fdfd30d214610a39578063ff45cb9514610a4f578063ffc22fa814610a6557600080fd5b8063f112e0a7146109a4578063f2fde38b146109c4578063f5aa406d146109e4578063f8972c8a14610a0457600080fd5b8063dbb84f11116100dc578063dbb84f1114610910578063e36b0b3714610930578063e985e9c514610945578063efe3f3931461098e57600080fd5b8063b76a0df4146108b0578063b88d4fde146108d0578063c87b56dd146108f057600080fd5b8063907097511161017a578063a22cb46511610149578063a22cb4651461083a578063a6d233ff1461085a578063ae47e72b14610880578063b02200151461089657600080fd5b806390709751146107d957806393777fb3146107f9578063949e180a1461080f57806395d89b411461082557600080fd5b80637ff9b596116101b65780637ff9b59614610770578063854d319c146107865780638da5cb5b1461079b5780638ea67909146107b957600080fd5b8063715018a61461072657806379f874fd1461073b5780637b0de0151461075057600080fd5b80633549345e116102c15780635b7633d01161025f57806364ae92eb1161022e57806364ae92eb146106995780636a61e5fc146106b95780636efe28bd146106d957806370a082311461070657600080fd5b80635b7633d01461063057806360033400146106505780636352211e14610666578063641ce1401461068657600080fd5b806342842e0e1161029b57806342842e0e146105ae5780634e99b800146105ce578063522fe98e146105e357806355f804b31461061057600080fd5b80633549345e14610563578063386bfc98146105835780633ccfd60b1461059957600080fd5b806309b2c7f31161032e5780631b2dcfde116103085780631b2dcfde146104e057806323a1baaa1461050057806323b872dd146105165780633164e5e01461053657600080fd5b806309b2c7f31461049b5780630c1c972a146104ae57806318160ddd146104c357600080fd5b806304c98b2b1161036a57806304c98b2b1461040c57806306fdde0314610421578063081812fc14610443578063095ea7b31461047b57600080fd5b80630108bdb71461039157806301ffc9a7146103ba578063046dc166146103ea575b600080fd5b34801561039d57600080fd5b506103a7600c5481565b6040519081526020015b60405180910390f35b3480156103c657600080fd5b506103da6103d5366004612d03565b610a85565b60405190151581526020016103b1565b3480156103f657600080fd5b5061040a610405366004612d3c565b610ad7565b005b34801561041857600080fd5b5061040a610b2c565b34801561042d57600080fd5b50610436610b66565b6040516103b19190612da7565b34801561044f57600080fd5b5061046361045e366004612dba565b610bf8565b6040516001600160a01b0390911681526020016103b1565b34801561048757600080fd5b5061040a610496366004612dd3565b610c3c565b61040a6104a9366004612ec2565b610cc2565b3480156104ba57600080fd5b5061040a610f14565b3480156104cf57600080fd5b5060015460005403600019016103a7565b3480156104ec57600080fd5b5061040a6104fb366004612dba565b610f4f565b34801561050c57600080fd5b506103a7600e5481565b34801561052257600080fd5b5061040a610531366004612f18565b610f7e565b34801561054257600080fd5b506103a7610551366004612dba565b601c6020526000908152604090205481565b34801561056f57600080fd5b5061040a61057e366004612dba565b6110da565b34801561058f57600080fd5b506103a760195481565b3480156105a557600080fd5b5061040a611109565b3480156105ba57600080fd5b5061040a6105c9366004612f18565b611159565b3480156105da57600080fd5b506104366112ca565b3480156105ef57600080fd5b506103a76105fe366004612d3c565b601a6020526000908152604090205481565b34801561061c57600080fd5b5061040a61062b366004612f54565b611358565b34801561063c57600080fd5b50601b54610463906001600160a01b031681565b34801561065c57600080fd5b506103a7600d5481565b34801561067257600080fd5b50610463610681366004612dba565b61138f565b61040a610694366004612ec2565b6113a1565b3480156106a557600080fd5b5061040a6106b4366004613078565b611775565b3480156106c557600080fd5b5061040a6106d4366004612dba565b611a74565b3480156106e557600080fd5b506103a76106f4366004612dba565b6000908152601c602052604090205490565b34801561071257600080fd5b506103a7610721366004612d3c565b611aa3565b34801561073257600080fd5b5061040a611af1565b34801561074757600080fd5b506103a7611b25565b34801561075c57600080fd5b50601354610463906001600160a01b031681565b34801561077c57600080fd5b506103a7600b5481565b34801561079257600080fd5b50610436611b46565b3480156107a757600080fd5b506008546001600160a01b0316610463565b3480156107c557600080fd5b5061040a6107d4366004612d3c565b611b53565b3480156107e557600080fd5b5061040a6107f4366004612f54565b611ba7565b34801561080557600080fd5b506103a7600a5481565b34801561081b57600080fd5b506103a760125481565b34801561083157600080fd5b50610436611bde565b34801561084657600080fd5b5061040a61085536600461312c565b611bed565b34801561086657600080fd5b50601854610463906201000090046001600160a01b031681565b34801561088c57600080fd5b506103a760175481565b3480156108a257600080fd5b506018546103da9060ff1681565b3480156108bc57600080fd5b506103da6108cb366004613163565b611c82565b3480156108dc57600080fd5b5061040a6108eb3660046131b0565b611cd3565b3480156108fc57600080fd5b5061043661090b366004612dba565b611ea2565b34801561091c57600080fd5b5061040a61092b366004612dba565b611ed6565b34801561093c57600080fd5b5061040a611f05565b34801561095157600080fd5b506103da610960366004613217565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561099a57600080fd5b506103a760115481565b3480156109b057600080fd5b5061040a6109bf366004612dba565b611f3c565b3480156109d057600080fd5b5061040a6109df366004612d3c565b611f7a565b3480156109f057600080fd5b5061040a6109ff366004612dba565b612015565b348015610a1057600080fd5b506103a760145481565b348015610a2657600080fd5b506018546103da90610100900460ff1681565b348015610a4557600080fd5b506103a760155481565b348015610a5b57600080fd5b506103a760165481565b348015610a7157600080fd5b5061040a610a80366004612dba565b612044565b60006001600160e01b031982166380ac58cd60e01b1480610ab657506001600160e01b03198216635b5e139f60e01b145b80610ad157506301ffc9a760e01b6001600160e01b03198316145b92915050565b6008546001600160a01b03163314610b0a5760405162461bcd60e51b8152600401610b019061324a565b60405180910390fd5b601b80546001600160a01b0319166001600160a01b0392909216919091179055565b6008546001600160a01b03163314610b565760405162461bcd60e51b8152600401610b019061324a565b6018805461ffff19166001179055565b606060028054610b759061327f565b80601f0160208091040260200160405190810160405280929190818152602001828054610ba19061327f565b8015610bee5780601f10610bc357610100808354040283529160200191610bee565b820191906000526020600020905b815481529060010190602001808311610bd157829003601f168201915b5050505050905090565b6000610c0382612082565b610c20576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610c478261138f565b9050806001600160a01b0316836001600160a01b031603610c7b5760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b03821614610cb257610c958133610960565b610cb2576040516367d9dca160e11b815260040160405180910390fd5b610cbd8383836120bb565b505050565b600260095403610d145760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610b01565b6002600955600c54610d279083906132cf565b341015610d665760405162461bcd60e51b815260206004820152600d60248201526c092dcc6dee4e4cac6e8408aa89609b1b6044820152606401610b01565b601754821115610db85760405162461bcd60e51b815260206004820152601a60248201527f4e6f20746f6b656e73206c65667420666f72206d696e74696e670000000000006044820152606401610b01565b6018546201000090046001600160a01b0316610e165760405162461bcd60e51b815260206004820152601d60248201527f56657269666965722061646472657373206973206e6f742076616c69640000006044820152606401610b01565b6018546040516345f0430f60e11b8152620100009091046001600160a01b0316908190638be0861e90610e51908790879087906004016132e6565b602060405180830381865afa158015610e6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e929190613343565b610ee85760405162461bcd60e51b815260206004820152602160248201527f4e6f7420656c696769626c6520746f206d696e7420626f6e757320746f6b656e6044820152607360f81b6064820152608401610b01565b610ef28484612117565b8260176000828254610f049190613360565b9091555050600160095550505050565b6008546001600160a01b03163314610f3e5760405162461bcd60e51b8152600401610b019061324a565b6018805461ffff1916610101179055565b6008546001600160a01b03163314610f795760405162461bcd60e51b8152600401610b019061324a565b600c55565b826daaeb6d7670e522a718067333cd4e3b156110c957336001600160a01b03821603610fb457610faf848484612135565b6110d4565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611003573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110279190613343565b80156110aa5750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611086573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110aa9190613343565b6110c957604051633b79c77360e21b8152336004820152602401610b01565b6110d4848484612135565b50505050565b6008546001600160a01b031633146111045760405162461bcd60e51b8152600401610b019061324a565b600a55565b6008546001600160a01b031633146111335760405162461bcd60e51b8152600401610b019061324a565b60405133904780156108fc02916000818181858888f1935050505061115757600080fd5b565b826daaeb6d7670e522a718067333cd4e3b156112af57336001600160a01b0382160361119a57610faf84848460405180602001604052806000815250611cd3565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa1580156111e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061120d9190613343565b80156112905750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa15801561126c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112909190613343565b6112af57604051633b79c77360e21b8152336004820152602401610b01565b6110d484848460405180602001604052806000815250611cd3565b601080546112d79061327f565b80601f01602080910402602001604051908101604052809291908181526020018280546113039061327f565b80156113505780601f1061132557610100808354040283529160200191611350565b820191906000526020600020905b81548152906001019060200180831161133357829003601f168201915b505050505081565b6008546001600160a01b031633146113825760405162461bcd60e51b8152600401610b019061324a565b6010610cbd8284836133c1565b600061139a82612320565b5192915050565b6002600954036113f35760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610b01565b60026009556018548290610100900460ff1661141157600a54611415565b600b545b61141f91906132cf565b34101561145e5760405162461bcd60e51b815260206004820152600d60248201526c092dcc6dee4e4cac6e8408aa89609b1b6044820152606401610b01565b60185460ff166114b05760405162461bcd60e51b815260206004820152601a60248201527f43616e6e6f74206d696e74206265666f72652070726573616c650000000000006044820152606401610b01565b6016548211156115025760405162461bcd60e51b815260206004820152601a60248201527f4e6f20746f6b656e73206c65667420666f72206d696e74696e670000000000006044820152606401610b01565b601454600154600054849190036000190161151d9190613480565b11156115815760405162461bcd60e51b815260206004820152602d60248201527f4e6f206d6f726520746f6b656e7320616c6c6f7765642061742074686973207360448201526c3a30b3b29037b31036b4b73a1760991b6064820152608401610b01565b601854610100900460ff161561162057600e546001600160a01b0384166000908152601a60205260409020546115b8908490613480565b111561161b5760405162461bcd60e51b815260206004820152602c60248201527f43616e6e6f74206d696e74206d6f7265207468616e206d617820746f6b656e7360448201526b20706572206164647265737360a01b6064820152608401610b01565b61171b565b61162a8382611c82565b6116805760405162461bcd60e51b815260206004820152602160248201527f4275796572206e6f742077686974656c697374656420666f722070726573616c6044820152606560f81b6064820152608401610b01565b600d546001600160a01b0384166000908152601a60205260409020546116a7908490613480565b111561171b5760405162461bcd60e51b815260206004820152603c60248201527f43616e6e6f74206d696e74206d6f7265207468616e20746865206d617820746f60448201527f6b656e73207065722077686974656c69737465642061646472657373000000006064820152608401610b01565b6117258383612117565b6001600160a01b0383166000908152601a60205260408120805484929061174d908490613480565b9250508190555081601660008282546117669190613360565b90915550506001600955505050565b8584146117de5760405162461bcd60e51b815260206004820152603160248201527f446966666572656e74206e756d626572206f6620746f6b656e7320616e64206960448201527038903837b4b73a39903130ba31b432b99760791b6064820152608401610b01565b6117e88383612442565b6118345760405162461bcd60e51b815260206004820152601c60248201527f44697265637420697120616464206973206e6f7420616c6c6f776564000000006044820152606401610b01565b336000908152601d602052604090205481146118875760405162461bcd60e51b8152602060048201526012602482015271139bdb98d948185b1c9958591e481d5cd95960721b6044820152606401610b01565b6000805b858110156118fe578686828181106118a5576118a5613493565b90506020020135601c60008989858181106118c2576118c2613493565b90506020020135815260200190815260200160002060008282546118e69190613480565b909155508190506118f6816134a9565b91505061188b565b50604080513360601b6bffffffffffffffffffffffff1916602080830191909152603482018490526054808301869052835180840390910181526074830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a333200000000609484015260b0808401919091528351808403909101815260d0909201909252805191012084146119ce5760405162461bcd60e51b8152602060048201526013602482015272090c2e6d040c8decae640dcdee840dac2e8c6d606b1b6044820152606401610b01565b60005b87811015611a44578686828181106119eb576119eb613493565b90506020020135601c60008b8b85818110611a0857611a08613493565b9050602002013581526020019081526020016000206000828254611a2c9190613480565b90915550819050611a3c816134a9565b9150506119d1565b50336000908152601d60205260408120805460019290611a65908490613480565b90915550505050505050505050565b6008546001600160a01b03163314611a9e5760405162461bcd60e51b8152600401610b019061324a565b600b55565b60006001600160a01b038216611acc576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6008546001600160a01b03163314611b1b5760405162461bcd60e51b8152600401610b019061324a565b6111576000612466565b601854600090610100900460ff1615611b3f5750600b5490565b50600a5490565b600f80546112d79061327f565b6008546001600160a01b03163314611b7d5760405162461bcd60e51b8152600401610b019061324a565b601880546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6008546001600160a01b03163314611bd15760405162461bcd60e51b8152600401610b019061324a565b600f610cbd8284836133c1565b606060038054610b759061327f565b336001600160a01b03831603611c165760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6040516bffffffffffffffffffffffff19606084901b1660208201526000908190603401604051602081830303815290604052805190602001209050611ccb83601954836124b8565b949350505050565b836daaeb6d7670e522a718067333cd4e3b15611e5757336001600160a01b03821603611d4257611d04858585612135565b6001600160a01b0384163b15611d3d57611d20858585856124ce565b611d3d576040516368d2bf6b60e11b815260040160405180910390fd5b611e9b565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611d91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db59190613343565b8015611e385750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611e14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e389190613343565b611e5757604051633b79c77360e21b8152336004820152602401610b01565b611e62858585612135565b6001600160a01b0384163b15611e9b57611e7e858585856124ce565b611e9b576040516368d2bf6b60e11b815260040160405180910390fd5b5050505050565b6060611ead826125b9565b600f604051602001611ec09291906134c2565b6040516020818303038152906040529050919050565b6008546001600160a01b03163314611f005760405162461bcd60e51b8152600401610b019061324a565b600e55565b6008546001600160a01b03163314611f2f5760405162461bcd60e51b8152600401610b019061324a565b6018805461ffff19169055565b6008546001600160a01b03163314611f665760405162461bcd60e51b8152600401610b019061324a565b601554811115611f7557600080fd5b601455565b6008546001600160a01b03163314611fa45760405162461bcd60e51b8152600401610b019061324a565b6001600160a01b0381166120095760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b01565b61201281612466565b50565b6008546001600160a01b0316331461203f5760405162461bcd60e51b8152600401610b019061324a565b601955565b6008546001600160a01b0316331461206e5760405162461bcd60e51b8152600401610b019061324a565b600d55565b6001600160a01b03163b151590565b600081600111158015612096575060005482105b8015610ad1575050600090815260046020526040902054600160e01b900460ff161590565b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b61213182826040518060200160405280600081525061263d565b5050565b600061214082612320565b9050836001600160a01b031681600001516001600160a01b0316146121775760405162a1148160e81b815260040160405180910390fd5b6000336001600160a01b038616148061219557506121958533610960565b806121b05750336121a584610bf8565b6001600160a01b0316145b9050806121d057604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b0384166121f757604051633a954ecd60e21b815260040160405180910390fd5b612203600084876120bb565b6001600160a01b038581166000908152600560209081526040808320805467ffffffffffffffff198082166001600160401b0392831660001901831617909255898616808652838620805493841693831660019081018416949094179055898652600490945282852080546001600160e01b031916909417600160a01b429092169190910217835587018084529220805491939091166122d75760005482146122d757805460208601516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038a16171781555b50505082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611e9b565b604080516060810182526000808252602082018190529181019190915281806001116124295760005481101561242957600081815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161515918101829052906124275780516001600160a01b0316156123be579392505050565b5060001901600081815260046020908152604091829020825160608101845290546001600160a01b038116808352600160a01b82046001600160401b031693830193909352600160e01b900460ff1615159281019290925215612422579392505050565b6123be565b505b604051636f96cda160e11b815260040160405180910390fd5b600061244e8383612804565b601b546001600160a01b039182169116149392505050565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000826124c58584612828565b14949350505050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a029061250390339089908890889060040161354f565b6020604051808303816000875af192505050801561253e575060408051601f3d908101601f1916820190925261253b9181019061358c565b60015b61259c573d80801561256c576040519150601f19603f3d011682016040523d82523d6000602084013e612571565b606091505b508051600003612594576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b60606125c482612082565b6125e157604051630a14c4b560e41b815260040160405180910390fd5b60006125eb612894565b9050805160000361260b5760405180602001604052806000815250612636565b80612615846128a3565b6040516020016126269291906135a9565b6040516020818303038152906040525b9392505050565b6000546001600160a01b03841661266657604051622e076360e81b815260040160405180910390fd5b826000036126875760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038416600081815260056020908152604080832080546fffffffffffffffffffffffffffffffff1981166001600160401b038083168b0181169182176801000000000000000067ffffffffffffffff1990941690921783900481168b01811690920217909155858452600490925290912080546001600160e01b0319168317600160a01b42909316929092029190911790558190818501903b156127af575b60405182906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a461277860008784806001019550876124ce565b612795576040516368d2bf6b60e11b815260040160405180910390fd5b80821061272d5782600054146127aa57600080fd5b6127f4565b5b6040516001830192906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a48082106127b0575b5060009081556110d49085838684565b600080600061281385856129a3565b9150915061282081612a11565b509392505050565b600081815b845181101561282057600085828151811061284a5761284a613493565b602002602001015190508083116128705760008381526020829052604090209250612881565b600081815260208490526040902092505b508061288c816134a9565b91505061282d565b606060108054610b759061327f565b6060816000036128ca5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156128f457806128de816134a9565b91506128ed9050600a836135ee565b91506128ce565b6000816001600160401b0381111561290e5761290e612dfd565b6040519080825280601f01601f191660200182016040528015612938576020820181803683370190505b5090505b8415611ccb5761294d600183613360565b915061295a600a86613602565b612965906030613480565b60f81b81838151811061297a5761297a613493565b60200101906001600160f81b031916908160001a90535061299c600a866135ee565b945061293c565b60008082516041036129d95760208301516040840151606085015160001a6129cd87828585612bc7565b94509450505050612a0a565b8251604003612a0257602083015160408401516129f7868383612cb4565b935093505050612a0a565b506000905060025b9250929050565b6000816004811115612a2557612a25613616565b03612a2d5750565b6001816004811115612a4157612a41613616565b03612a8e5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610b01565b6002816004811115612aa257612aa2613616565b03612aef5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610b01565b6003816004811115612b0357612b03613616565b03612b5b5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610b01565b6004816004811115612b6f57612b6f613616565b036120125760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610b01565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612bfe5750600090506003612cab565b8460ff16601b14158015612c1657508460ff16601c14155b15612c275750600090506004612cab565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612c7b573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612ca457600060019250925050612cab565b9150600090505b94509492505050565b6000806001600160ff1b03831681612cd160ff86901c601b613480565b9050612cdf87828885612bc7565b935093505050935093915050565b6001600160e01b03198116811461201257600080fd5b600060208284031215612d1557600080fd5b813561263681612ced565b80356001600160a01b0381168114612d3757600080fd5b919050565b600060208284031215612d4e57600080fd5b61263682612d20565b60005b83811015612d72578181015183820152602001612d5a565b50506000910152565b60008151808452612d93816020860160208601612d57565b601f01601f19169290920160200192915050565b6020815260006126366020830184612d7b565b600060208284031215612dcc57600080fd5b5035919050565b60008060408385031215612de657600080fd5b612def83612d20565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715612e3b57612e3b612dfd565b604052919050565b600082601f830112612e5457600080fd5b813560206001600160401b03821115612e6f57612e6f612dfd565b8160051b612e7e828201612e13565b9283528481018201928281019087851115612e9857600080fd5b83870192505b84831015612eb757823582529183019190830190612e9e565b979650505050505050565b600080600060608486031215612ed757600080fd5b612ee084612d20565b92506020840135915060408401356001600160401b03811115612f0257600080fd5b612f0e86828701612e43565b9150509250925092565b600080600060608486031215612f2d57600080fd5b612f3684612d20565b9250612f4460208501612d20565b9150604084013590509250925092565b60008060208385031215612f6757600080fd5b82356001600160401b0380821115612f7e57600080fd5b818501915085601f830112612f9257600080fd5b813581811115612fa157600080fd5b866020828501011115612fb357600080fd5b60209290920196919550909350505050565b60008083601f840112612fd757600080fd5b5081356001600160401b03811115612fee57600080fd5b6020830191508360208260051b8501011115612a0a57600080fd5b600082601f83011261301a57600080fd5b81356001600160401b0381111561303357613033612dfd565b613046601f8201601f1916602001612e13565b81815284602083860101111561305b57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600080600060a0888a03121561309357600080fd5b87356001600160401b03808211156130aa57600080fd5b6130b68b838c01612fc5565b909950975060208a01359150808211156130cf57600080fd5b6130db8b838c01612fc5565b909750955060408a0135945060608a01359150808211156130fb57600080fd5b506131088a828b01613009565b9250506080880135905092959891949750929550565b801515811461201257600080fd5b6000806040838503121561313f57600080fd5b61314883612d20565b915060208301356131588161311e565b809150509250929050565b6000806040838503121561317657600080fd5b61317f83612d20565b915060208301356001600160401b0381111561319a57600080fd5b6131a685828601612e43565b9150509250929050565b600080600080608085870312156131c657600080fd5b6131cf85612d20565b93506131dd60208601612d20565b92506040850135915060608501356001600160401b038111156131ff57600080fd5b61320b87828801613009565b91505092959194509250565b6000806040838503121561322a57600080fd5b61323383612d20565b915061324160208401612d20565b90509250929050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600181811c9082168061329357607f821691505b6020821081036132b357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610ad157610ad16132b9565b6001600160a01b038416815260208082018490526060604083018190528351908301819052600091848101916080850190845b8181101561333557845183529383019391830191600101613319565b509098975050505050505050565b60006020828403121561335557600080fd5b81516126368161311e565b81810381811115610ad157610ad16132b9565b601f821115610cbd57600081815260208120601f850160051c8101602086101561339a5750805b601f850160051c820191505b818110156133b9578281556001016133a6565b505050505050565b6001600160401b038311156133d8576133d8612dfd565b6133ec836133e6835461327f565b83613373565b6000601f84116001811461342057600085156134085750838201355b600019600387901b1c1916600186901b178355611e9b565b600083815260209020601f19861690835b828110156134515786850135825560209485019460019092019101613431565b508682101561346e5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b80820180821115610ad157610ad16132b9565b634e487b7160e01b600052603260045260246000fd5b6000600182016134bb576134bb6132b9565b5060010190565b6000835160206134d58285838901612d57565b8184019150600085546134e78161327f565b600182811680156134ff576001811461351457613540565b60ff1984168752821515830287019450613540565b896000528560002060005b848110156135385781548982015290830190870161351f565b505082870194505b50929998505050505050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061358290830184612d7b565b9695505050505050565b60006020828403121561359e57600080fd5b815161263681612ced565b600083516135bb818460208801612d57565b8351908301906135cf818360208801612d57565b01949350505050565b634e487b7160e01b600052601260045260246000fd5b6000826135fd576135fd6135d8565b500490565b600082613611576136116135d8565b500690565b634e487b7160e01b600052602160045260246000fdfea26469706673582212203f5dbf62c6d0f725c1c294efb8ec2f9b68e47aa9c65c3928bfead6e71b04dcdd64736f6c63430008110033

Deployed Bytecode Sourcemap

92313:7379:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92552:34;;;;;;;;;;;;;;;;;;;160:25:1;;;148:2;133:18;92552:34:0;;;;;;;;72537:355;;;;;;;;;;-1:-1:-1;72537:355:0;;;;;:::i;:::-;;:::i;:::-;;;747:14:1;;740:22;722:41;;710:2;695:18;72537:355:0;582:187:1;93933:96:0;;;;;;;;;;-1:-1:-1;93933:96:0;;;;;:::i;:::-;;:::i;:::-;;96093:125;;;;;;;;;;;;;:::i;75823:100::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;77448:245::-;;;;;;;;;;-1:-1:-1;77448:245:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2248:32:1;;;2230:51;;2218:2;2203:18;77448:245:0;2084:203:1;76988:394:0;;;;;;;;;;-1:-1:-1;76988:394:0;;;;;:::i;:::-;;:::i;98241:587::-;;;;;;:::i;:::-;;:::i;96226:127::-;;;;;;;;;;;;;:::i;71777:312::-;;;;;;;;;;-1:-1:-1;93916:1:0;72040:12;71830:7;72024:13;:28;-1:-1:-1;;72024:46:0;71777:312;;96566:100;;;;;;;;;;-1:-1:-1;96566:100:0;;;;;:::i;:::-;;:::i;92711:43::-;;;;;;;;;;;;;;;;78436:196;;;;;;;;;;-1:-1:-1;78436:196:0;;;;;:::i;:::-;;:::i;93592:43::-;;;;;;;;;;-1:-1:-1;93592:43:0;;;;;:::i;:::-;;;;;;;;;;;;;;96361:99;;;;;;;;;;-1:-1:-1;96361:99:0;;;;;:::i;:::-;;:::i;93469:28::-;;;;;;;;;;;;;;;;99343:114;;;;;;;;;;;;;:::i;78703:211::-;;;;;;;;;;-1:-1:-1;78703:211:0;;;;;:::i;:::-;;:::i;92810:85::-;;;;;;;;;;;;;:::i;93504:44::-;;;;;;;;;;-1:-1:-1;93504:44:0;;;;;:::i;:::-;;;;;;;;;;;;;;98999:97;;;;;;;;;;-1:-1:-1;98999:97:0;;;;;:::i;:::-;;:::i;93557:28::-;;;;;;;;;;-1:-1:-1;93557:28:0;;;;-1:-1:-1;;;;;93557:28:0;;;92650:54;;;;;;;;;;;;;;;;75631:125;;;;;;;;;;-1:-1:-1;75631:125:0;;;;;:::i;:::-;;:::i;97146:1087::-;;;;;;:::i;:::-;;:::i;94531:801::-;;;;;;;;;;-1:-1:-1;94531:801:0;;;;;:::i;:::-;;:::i;96468:90::-;;;;;;;;;;-1:-1:-1;96468:90:0;;;;;:::i;:::-;;:::i;95340:95::-;;;;;;;;;;-1:-1:-1;95340:95:0;;;;;:::i;:::-;95388:7;95415:12;;;:8;:12;;;;;;;95340:95;72956:206;;;;;;;;;;-1:-1:-1;72956:206:0;;;;;:::i;:::-;;:::i;24328:103::-;;;;;;;;;;;;;:::i;96674:206::-;;;;;;;;;;;;;:::i;92988:86::-;;;;;;;;;;-1:-1:-1;92988:86:0;;;;-1:-1:-1;;;;;92988:86:0;;;92507:38;;;;;;;;;;;;;;;;92767:36;;;;;;;;;;;;;:::i;23677:87::-;;;;;;;;;;-1:-1:-1;23750:6:0;;-1:-1:-1;;;;;23750:6:0;23677:87;;95599:102;;;;;;;;;;-1:-1:-1;95599:102:0;;;;;:::i;:::-;;:::i;99104:107::-;;;;;;;;;;-1:-1:-1;99104:107:0;;;;;:::i;:::-;;:::i;92455:45::-;;;;;;;;;;;;;;;;92942:39;;;;;;;;;;;;;;;;75992:104;;;;;;;;;;;;;:::i;77765:319::-;;;;;;;;;;-1:-1:-1;77765:319:0;;;;;:::i;:::-;;:::i;93428:32::-;;;;;;;;;;-1:-1:-1;93428:32:0;;;;;;;-1:-1:-1;;;;;93428:32:0;;;93274:48;;;;;;;;;;;;;;;;93331:37;;;;;;;;;;-1:-1:-1;93331:37:0;;;;;;;;96888:250;;;;;;;;;;-1:-1:-1;96888:250:0;;;;;:::i;:::-;;:::i;78985:418::-;;;;;;;;;;-1:-1:-1;78985:418:0;;;;;:::i;:::-;;:::i;99465:224::-;;;;;;;;;;-1:-1:-1;99465:224:0;;;;;:::i;:::-;;:::i;95847:108::-;;;;;;;;;;-1:-1:-1;95847:108:0;;;;;:::i;:::-;;:::i;95963:122::-;;;;;;;;;;;;;:::i;78155:214::-;;;;;;;;;;-1:-1:-1;78155:214:0;;;;;:::i;:::-;-1:-1:-1;;;;;78326:25:0;;;78297:4;78326:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;78155:214;92904:31;;;;;;;;;;;;;;;;95443:148;;;;;;;;;;-1:-1:-1;95443:148:0;;;;;:::i;:::-;;:::i;24586:238::-;;;;;;;;;;-1:-1:-1;24586:238:0;;;;;:::i;:::-;;:::i;99219:116::-;;;;;;;;;;-1:-1:-1;99219:116:0;;;;;:::i;:::-;;:::i;93081:38::-;;;;;;;;;;;;;;;;93375:40;;;;;;;;;;-1:-1:-1;93375:40:0;;;;;;;;;;;93126:38;;;;;;;;;;;;;;;;93171:96;;;;;;;;;;;;;;;;95709:130;;;;;;;;;;-1:-1:-1;95709:130:0;;;;;:::i;:::-;;:::i;72537:355::-;72684:4;-1:-1:-1;;;;;;72726:40:0;;-1:-1:-1;;;72726:40:0;;:105;;-1:-1:-1;;;;;;;72783:48:0;;-1:-1:-1;;;72783:48:0;72726:105;:158;;;-1:-1:-1;;;;;;;;;;37114:40:0;;;72848:36;72706:178;72537:355;-1:-1:-1;;72537:355:0:o;93933:96::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;;;;;;;;;94002:13:::1;:19:::0;;-1:-1:-1;;;;;;94002:19:0::1;-1:-1:-1::0;;;;;94002:19:0;;;::::1;::::0;;;::::1;::::0;;93933:96::o;96093:125::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;96147:17:::1;:24:::0;;-1:-1:-1;;96182:28:0;96167:4:::1;96182:28:::0;;;96093:125::o;75823:100::-;75877:13;75910:5;75903:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75823:100;:::o;77448:245::-;77552:7;77582:16;77590:7;77582;:16::i;:::-;77577:64;;77607:34;;-1:-1:-1;;;77607:34:0;;;;;;;;;;;77577:64;-1:-1:-1;77661:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;77661:24:0;;77448:245::o;76988:394::-;77061:13;77077:24;77093:7;77077:15;:24::i;:::-;77061:40;;77122:5;-1:-1:-1;;;;;77116:11:0;:2;-1:-1:-1;;;;;77116:11:0;;77112:48;;77136:24;;-1:-1:-1;;;77136:24:0;;;;;;;;;;;77112:48;22460:10;-1:-1:-1;;;;;77177:21:0;;;77173:161;;77218:37;77235:5;22460:10;78155:214;:::i;77218:37::-;77213:121;;77283:35;;-1:-1:-1;;;77283:35:0;;;;;;;;;;;77213:121;77346:28;77355:2;77359:7;77368:5;77346:8;:28::i;:::-;77050:332;76988:394;;:::o;98241:587::-;6527:1;7125:7;;:19;7117:63;;;;-1:-1:-1;;;7117:63:0;;10118:2:1;7117:63:0;;;10100:21:1;10157:2;10137:18;;;10130:30;10196:33;10176:18;;;10169:61;10247:18;;7117:63:0;9916:355:1;7117:63:0;6527:1;7258:7;:18;98374:15:::1;::::0;:24:::1;::::0;98392:6;;98374:24:::1;:::i;:::-;98361:9;:37;;98353:63;;;::::0;-1:-1:-1;;;98353:63:0;;10783:2:1;98353:63:0::1;::::0;::::1;10765:21:1::0;10822:2;10802:18;;;10795:30;-1:-1:-1;;;10841:18:1;;;10834:43;10894:18;;98353:63:0::1;10581:337:1::0;98353:63:0::1;98445:26;;98435:6;:36;;98427:75;;;::::0;-1:-1:-1;;;98427:75:0;;11125:2:1;98427:75:0::1;::::0;::::1;11107:21:1::0;11164:2;11144:18;;;11137:30;11203:28;11183:18;;;11176:56;11249:18;;98427:75:0::1;10923:350:1::0;98427:75:0::1;98523:17;::::0;;;::::1;-1:-1:-1::0;;;;;98523:17:0::1;98515:73;;;::::0;-1:-1:-1;;;98515:73:0;;11480:2:1;98515:73:0::1;::::0;::::1;11462:21:1::0;11519:2;11499:18;;;11492:30;11558:31;11538:18;;;11531:59;11607:18;;98515:73:0::1;11278:353:1::0;98515:73:0::1;98625:17;::::0;98662:29:::1;::::0;-1:-1:-1;;;98662:29:0;;98625:17;;;::::1;-1:-1:-1::0;;;;;98625:17:0::1;::::0;;;98662:10:::1;::::0;:29:::1;::::0;98673:2;;98677:6;;98685:5;;98662:29:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98654:75;;;::::0;-1:-1:-1;;;98654:75:0;;12894:2:1;98654:75:0::1;::::0;::::1;12876:21:1::0;12933:2;12913:18;;;12906:30;12972:34;12952:18;;;12945:62;-1:-1:-1;;;13023:18:1;;;13016:31;13064:19;;98654:75:0::1;12692:397:1::0;98654:75:0::1;98750:21;98760:2;98764:6;98750:9;:21::i;:::-;98814:6;98784:26;;:36;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;6483:1:0;7437:7;:22;-1:-1:-1;;;;98241:587:0:o;96226:127::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;96283:17:::1;:24:::0;;-1:-1:-1;;96318:27:0;;;;;96226:127::o;96566:100::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;96637:15:::1;:21:::0;96566:100::o;78436:196::-;78579:4;2488:42;3628:43;:47;3624:699;;3915:10;-1:-1:-1;;;;;3907:18:0;;;3903:85;;78596:28:::1;78606:4;78612:2;78616:7;78596:9;:28::i;:::-;3966:7:::0;;3903:85;4048:67;;-1:-1:-1;;;4048:67:0;;4097:4;4048:67;;;13439:34:1;4104:10:0;13489:18:1;;;13482:43;2488:42:0;;4048:40;;13374:18:1;;4048:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:157;;;;-1:-1:-1;4144:61:0;;-1:-1:-1;;;4144:61:0;;4193:4;4144:61;;;13439:34:1;-1:-1:-1;;;;;13509:15:1;;13489:18;;;13482:43;2488:42:0;;4144:40;;13374:18:1;;4144:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4002:310;;4266:30;;-1:-1:-1;;;4266:30:0;;4285:10;4266:30;;;2230:51:1;2203:18;;4266:30:0;2084:203:1;4002:310:0;78596:28:::1;78606:4;78612:2;78616:7;78596:9;:28::i;:::-;78436:196:::0;;;;:::o;96361:99::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;96429:17:::1;:23:::0;96361:99::o;99343:114::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;99401:47:::1;::::0;99409:10:::1;::::0;99426:21:::1;99401:47:::0;::::1;;;::::0;::::1;::::0;;;99426:21;99409:10;99401:47;::::1;;;;;;99393:56;;;::::0;::::1;;99343:114::o:0;78703:211::-;78850:4;2488:42;3628:43;:47;3624:699;;3915:10;-1:-1:-1;;;;;3907:18:0;;;3903:85;;78867:39:::1;78884:4;78890:2;78894:7;78867:39;;;;;;;;;;;::::0;:16:::1;:39::i;3903:85::-:0;4048:67;;-1:-1:-1;;;4048:67:0;;4097:4;4048:67;;;13439:34:1;4104:10:0;13489:18:1;;;13482:43;2488:42:0;;4048:40;;13374:18:1;;4048:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:157;;;;-1:-1:-1;4144:61:0;;-1:-1:-1;;;4144:61:0;;4193:4;4144:61;;;13439:34:1;-1:-1:-1;;;;;13509:15:1;;13489:18;;;13482:43;2488:42:0;;4144:40;;13374:18:1;;4144:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4002:310;;4266:30;;-1:-1:-1;;;4266:30:0;;4285:10;4266:30;;;2230:51:1;2203:18;;4266:30:0;2084:203:1;4002:310:0;78867:39:::1;78884:4;78890:2;78894:7;78867:39;;;;;;;;;;;::::0;:16:::1;:39::i;92810:85::-:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;98999:97::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;99070:12:::1;:18;99085:3:::0;;99070:12;:18:::1;:::i;75631:125::-:0;75695:7;75722:21;75735:7;75722:12;:21::i;:::-;:26;;75631:125;-1:-1:-1;;75631:125:0:o;97146:1087::-;6527:1;7125:7;;:19;7117:63;;;;-1:-1:-1;;;7117:63:0;;10118:2:1;7117:63:0;;;10100:21:1;10157:2;10137:18;;;10130:30;10196:33;10176:18;;;10169:61;10247:18;;7117:63:0;9916:355:1;7117:63:0;6527:1;7258:7;:18;97275:20:::1;::::0;97332:6;;97275:20:::1;::::0;::::1;;;:53;;97311:17;;97275:53;;;97298:10;;97275:53;97274:64;;;;:::i;:::-;97261:9;:77;;97253:103;;;::::0;-1:-1:-1;;;97253:103:0;;10783:2:1;97253:103:0::1;::::0;::::1;10765:21:1::0;10822:2;10802:18;;;10795:30;-1:-1:-1;;;10841:18:1;;;10834:43;10894:18;;97253:103:0::1;10581:337:1::0;97253:103:0::1;97375:17;::::0;::::1;;97367:56;;;::::0;-1:-1:-1;;;97367:56:0;;15796:2:1;97367:56:0::1;::::0;::::1;15778:21:1::0;15835:2;15815:18;;;15808:30;15874:28;15854:18;;;15847:56;15920:18;;97367:56:0::1;15594:350:1::0;97367:56:0::1;97549:17;;97539:6;:27;;97531:66;;;::::0;-1:-1:-1;;;97531:66:0;;11125:2:1;97531:66:0::1;::::0;::::1;11107:21:1::0;11164:2;11144:18;;;11137:30;11203:28;11183:18;;;11176:56;11249:18;;97531:66:0::1;10923:350:1::0;97531:66:0::1;97642:16;::::0;93916:1;72040:12;71830:7;72024:13;97632:6;;72024:28;;-1:-1:-1;;72024:46:0;97616:22:::1;;;;:::i;:::-;:42;;97608:100;;;::::0;-1:-1:-1;;;97608:100:0;;16281:2:1;97608:100:0::1;::::0;::::1;16263:21:1::0;16320:2;16300:18;;;16293:30;16359:34;16339:18;;;16332:62;-1:-1:-1;;;16410:18:1;;;16403:43;16463:19;;97608:100:0::1;16079:409:1::0;97608:100:0::1;97725:20;::::0;::::1;::::0;::::1;;;97721:395;;;97796:19;::::0;-1:-1:-1;;;;;97770:13:0;::::1;;::::0;;;:9:::1;:13;::::0;;;;;:22:::1;::::0;97786:6;;97770:22:::1;:::i;:::-;:45;;97762:102;;;::::0;-1:-1:-1;;;97762:102:0;;16695:2:1;97762:102:0::1;::::0;::::1;16677:21:1::0;16734:2;16714:18;;;16707:30;16773:34;16753:18;;;16746:62;-1:-1:-1;;;16824:18:1;;;16817:42;16876:19;;97762:102:0::1;16493:408:1::0;97762:102:0::1;97721:395;;;97905:17;97912:2;97916:5;97905:6;:17::i;:::-;97897:63;;;::::0;-1:-1:-1;;;97897:63:0;;17108:2:1;97897:63:0::1;::::0;::::1;17090:21:1::0;17147:2;17127:18;;;17120:30;17186:34;17166:18;;;17159:62;-1:-1:-1;;;17237:18:1;;;17230:31;17278:19;;97897:63:0::1;16906:397:1::0;97897:63:0::1;98009:30;::::0;-1:-1:-1;;;;;97983:13:0;::::1;;::::0;;;:9:::1;:13;::::0;;;;;:22:::1;::::0;97999:6;;97983:22:::1;:::i;:::-;:56;;97975:129;;;::::0;-1:-1:-1;;;97975:129:0;;17510:2:1;97975:129:0::1;::::0;::::1;17492:21:1::0;17549:2;17529:18;;;17522:30;17588:34;17568:18;;;17561:62;17659:30;17639:18;;;17632:58;17707:19;;97975:129:0::1;17308:424:1::0;97975:129:0::1;98128:21;98138:2;98142:6;98128:9;:21::i;:::-;-1:-1:-1::0;;;;;98162:13:0;::::1;;::::0;;;:9:::1;:13;::::0;;;;:23;;98179:6;;98162:13;:23:::1;::::0;98179:6;;98162:23:::1;:::i;:::-;;;;;;;;98219:6;98198:17;;:27;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;6483:1:0;7437:7;:22;-1:-1:-1;;;97146:1087:0:o;94531:801::-;94689:32;;;94681:94;;;;-1:-1:-1;;;94681:94:0;;17939:2:1;94681:94:0;;;17921:21:1;17978:2;17958:18;;;17951:30;18017:34;17997:18;;;17990:62;-1:-1:-1;;;18068:18:1;;;18061:47;18125:19;;94681:94:0;17737:413:1;94681:94:0;94794:34;94812:4;94818:9;94794:17;:34::i;:::-;94786:75;;;;-1:-1:-1;;;94786:75:0;;18357:2:1;94786:75:0;;;18339:21:1;18396:2;18376:18;;;18369:30;18435;18415:18;;;18408:58;18483:18;;94786:75:0;18155:352:1;94786:75:0;94900:10;94889:22;;;;:10;:22;;;;;;94880:31;;94872:62;;;;-1:-1:-1;;;94872:62:0;;18714:2:1;94872:62:0;;;18696:21:1;18753:2;18733:18;;;18726:30;-1:-1:-1;;;18772:18:1;;;18765:48;18830:18;;94872:62:0;18512:342:1;94872:62:0;94947:11;94977:9;94973:102;94992:17;;;94973:102;;;95054:6;;95061:1;95054:9;;;;;;;:::i;:::-;;;;;;;95031:8;:19;95040:6;;95047:1;95040:9;;;;;;;:::i;:::-;;;;;;;95031:19;;;;;;;;;;;;:32;;;;;;;:::i;:::-;;;;-1:-1:-1;95011:3:0;;-1:-1:-1;95011:3:0;;;:::i;:::-;;;;94973:102;;;-1:-1:-1;94431:39:0;;;95111:10;21381:2:1;21377:15;-1:-1:-1;;21373:53:1;94431:39:0;;;;21361:66:1;;;;21443:12;;;21436:28;;;21480:12;;;;21473:28;;;94431:39:0;;;;;;;;;;21517:12:1;;;94431:39:0;;94421:50;;;;;;21782:66:1;94341:131:0;;;21770:79:1;21865:12;;;;21858:28;;;;94341:131:0;;;;;;;;;;21902:12:1;;;;94341:131:0;;;94331:152;;;;;95138:4;95095:47;95087:79;;;;-1:-1:-1;;;95087:79:0;;19333:2:1;95087:79:0;;;19315:21:1;19372:2;19352:18;;;19345:30;-1:-1:-1;;;19391:18:1;;;19384:49;19450:18;;95087:79:0;19131:343:1;95087:79:0;95183:9;95179:106;95198:19;;;95179:106;;;95264:6;;95271:1;95264:9;;;;;;;:::i;:::-;;;;;;;95239:8;:21;95248:8;;95257:1;95248:11;;;;;;;:::i;:::-;;;;;;;95239:21;;;;;;;;;;;;:34;;;;;;;:::i;:::-;;;;-1:-1:-1;95219:3:0;;-1:-1:-1;95219:3:0;;;:::i;:::-;;;;95179:106;;;-1:-1:-1;95308:10:0;95297:22;;;;:10;:22;;;;;:27;;95323:1;;95297:22;:27;;95323:1;;95297:27;:::i;:::-;;;;-1:-1:-1;;;;;;;;;;94531:801:0:o;96468:90::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;96534:10:::1;:16:::0;96468:90::o;72956:206::-;73020:7;-1:-1:-1;;;;;73044:19:0;;73040:60;;73072:28;;-1:-1:-1;;;73072:28:0;;;;;;;;;;;73040:60;-1:-1:-1;;;;;;73126:19:0;;;;;:12;:19;;;;;:27;-1:-1:-1;;;;;73126:27:0;;72956:206::o;24328:103::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;24393:30:::1;24420:1;24393:18;:30::i;96674:206::-:0;96750:20;;96726:7;;96750:20;;;;;96746:127;;;-1:-1:-1;96794:10:0;;;96674:206::o;96746:127::-;-1:-1:-1;96844:17:0;;;96674:206::o;92767:36::-;;;;;;;:::i;95599:102::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;95669:17:::1;:24:::0;;-1:-1:-1;;;;;95669:24:0;;::::1;::::0;::::1;-1:-1:-1::0;;;;;;95669:24:0;;::::1;::::0;;;::::1;::::0;;95599:102::o;99104:107::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;99180:17:::1;:23;99200:3:::0;;99180:17;:23:::1;:::i;75992:104::-:0;76048:13;76081:7;76074:14;;;;;:::i;77765:319::-;22460:10;-1:-1:-1;;;;;77896:24:0;;;77892:54;;77929:17;;-1:-1:-1;;;77929:17:0;;;;;;;;;;;77892:54;22460:10;77959:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;77959:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;77959:53:0;;;;;;;;;;78028:48;;722:41:1;;;77959:42:0;;22460:10;78028:48;;695:18:1;78028:48:0;;;;;;;77765:319;;:::o;96888:250::-;97040:25;;-1:-1:-1;;19628:2:1;19624:15;;;19620:53;97040:25:0;;;19608:66:1;96993:4:0;;;;19690:12:1;;97040:25:0;;;;;;;;;;;;97030:36;;;;;;97015:51;;97084:46;97103:5;97110:13;;97125:4;97084:18;:46::i;:::-;97077:53;96888:250;-1:-1:-1;;;;96888:250:0:o;78985:418::-;79161:4;2488:42;3628:43;:47;3624:699;;3915:10;-1:-1:-1;;;;;3907:18:0;;;3903:85;;79178:28:::1;79188:4;79194:2;79198:7;79178:9;:28::i;:::-;-1:-1:-1::0;;;;;79221:13:0;::::1;26708:19:::0;:23;79217:179:::1;;79256:56;79287:4;79293:2;79297:7;79306:5;79256:30;:56::i;:::-;79251:145;;79340:40;;-1:-1:-1::0;;;79340:40:0::1;;;;;;;;;;;79251:145;3966:7:::0;;3903:85;4048:67;;-1:-1:-1;;;4048:67:0;;4097:4;4048:67;;;13439:34:1;4104:10:0;13489:18:1;;;13482:43;2488:42:0;;4048:40;;13374:18:1;;4048:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:157;;;;-1:-1:-1;4144:61:0;;-1:-1:-1;;;4144:61:0;;4193:4;4144:61;;;13439:34:1;-1:-1:-1;;;;;13509:15:1;;13489:18;;;13482:43;2488:42:0;;4144:40;;13374:18:1;;4144:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4002:310;;4266:30;;-1:-1:-1;;;4266:30:0;;4285:10;4266:30;;;2230:51:1;2203:18;;4266:30:0;2084:203:1;4002:310:0;79178:28:::1;79188:4;79194:2;79198:7;79178:9;:28::i;:::-;-1:-1:-1::0;;;;;79221:13:0;::::1;26708:19:::0;:23;79217:179:::1;;79256:56;79287:4;79293:2;79297:7;79306:5;79256:30;:56::i;:::-;79251:145;;79340:40;;-1:-1:-1::0;;;79340:40:0::1;;;;;;;;;;;79251:145;78985:418:::0;;;;;:::o;99465:224::-;99575:13;99637:23;99652:7;99637:14;:23::i;:::-;99662:17;99620:60;;;;;;;;;:::i;:::-;;;;;;;;;;;;;99606:75;;99465:224;;;:::o;95847:108::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;95922:19:::1;:25:::0;95847:108::o;95963:122::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;96013:17:::1;:25:::0;;-1:-1:-1;;96049:28:0;;;95963:122::o;95443:148::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;95533:16:::1;;95526:3;:23;;95518:32;;;::::0;::::1;;95561:16;:22:::0;95443:148::o;24586:238::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;24689:22:0;::::1;24667:110;;;::::0;-1:-1:-1;;;24667:110:0;;20971:2:1;24667:110:0::1;::::0;::::1;20953:21:1::0;21010:2;20990:18;;;20983:30;21049:34;21029:18;;;21022:62;-1:-1:-1;;;21100:18:1;;;21093:36;21146:19;;24667:110:0::1;20769:402:1::0;24667:110:0::1;24788:28;24807:8;24788:18;:28::i;:::-;24586:238:::0;:::o;99219:116::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;99297:13:::1;:30:::0;99219:116::o;95709:130::-;23750:6;;-1:-1:-1;;;;;23750:6:0;22460:10;23897:23;23889:68;;;;-1:-1:-1;;;23889:68:0;;;;;;;:::i;:::-;95795:30:::1;:36:::0;95709:130::o;26413:326::-;-1:-1:-1;;;;;26708:19:0;;:23;;;26413:326::o;79658:213::-;79715:4;79771:7;93916:1;79752:26;;:66;;;;;79805:13;;79795:7;:23;79752:66;:111;;;;-1:-1:-1;;79836:20:0;;;;:11;:20;;;;;:27;-1:-1:-1;;;79836:27:0;;;;79835:28;;79658:213::o;89110:196::-;89225:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;89225:29:0;-1:-1:-1;;;;;89225:29:0;;;;;;;;;89270:28;;89225:24;;89270:28;;;;;;;89110:196;;;:::o;79955:104::-;80024:27;80034:2;80038:8;80024:27;;;;;;;;;;;;:9;:27::i;:::-;79955:104;;:::o;84058:2130::-;84173:35;84211:21;84224:7;84211:12;:21::i;:::-;84173:59;;84271:4;-1:-1:-1;;;;;84249:26:0;:13;:18;;;-1:-1:-1;;;;;84249:26:0;;84245:67;;84284:28;;-1:-1:-1;;;84284:28:0;;;;;;;;;;;84245:67;84325:22;22460:10;-1:-1:-1;;;;;84351:20:0;;;;:73;;-1:-1:-1;84388:36:0;84405:4;22460:10;78155:214;:::i;84388:36::-;84351:126;;;-1:-1:-1;22460:10:0;84441:20;84453:7;84441:11;:20::i;:::-;-1:-1:-1;;;;;84441:36:0;;84351:126;84325:153;;84496:17;84491:66;;84522:35;;-1:-1:-1;;;84522:35:0;;;;;;;;;;;84491:66;-1:-1:-1;;;;;84572:16:0;;84568:52;;84597:23;;-1:-1:-1;;;84597:23:0;;;;;;;;;;;84568:52;84741:35;84758:1;84762:7;84771:4;84741:8;:35::i;:::-;-1:-1:-1;;;;;85072:18:0;;;;;;;:12;:18;;;;;;;;:31;;-1:-1:-1;;85072:31:0;;;-1:-1:-1;;;;;85072:31:0;;;-1:-1:-1;;85072:31:0;;;;;;;85118:16;;;;;;;;;:29;;;;;;;;-1:-1:-1;85118:29:0;;;;;;;;;;;85198:20;;;:11;:20;;;;;;85233:18;;-1:-1:-1;;;;;;85266:49:0;;;;-1:-1:-1;;;85299:15:0;85266:49;;;;;;;;;;85589:11;;85649:24;;;;;85692:13;;85198:20;;85649:24;;85692:13;85688:384;;85902:13;;85887:11;:28;85883:174;;85940:20;;86009:28;;;;-1:-1:-1;;;;;85983:54:0;-1:-1:-1;;;85983:54:0;-1:-1:-1;;;;;;85983:54:0;;;-1:-1:-1;;;;;85940:20:0;;85983:54;;;;85883:174;85047:1036;;;86119:7;86115:2;-1:-1:-1;;;;;86100:27:0;86109:4;-1:-1:-1;;;;;86100:27:0;;;;;;;;;;;86138:42;78436:196;74337:1232;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;74480:7:0;;93916:1;74529:23;74525:977;;74582:13;;74575:4;:20;74571:931;;;74620:31;74654:17;;;:11;:17;;;;;;;;;74620:51;;;;;;;;;-1:-1:-1;;;;;74620:51:0;;;;-1:-1:-1;;;74620:51:0;;-1:-1:-1;;;;;74620:51:0;;;;;;;;-1:-1:-1;;;74620:51:0;;;;;;;;;;;;;;74694:789;;74748:14;;-1:-1:-1;;;;;74748:28:0;;74744:109;;74816:9;74337:1232;-1:-1:-1;;;74337:1232:0:o;74744:109::-;-1:-1:-1;;;75219:6:0;75268:17;;;;:11;:17;;;;;;;;;75256:29;;;;;;;;;-1:-1:-1;;;;;75256:29:0;;;;;-1:-1:-1;;;75256:29:0;;-1:-1:-1;;;;;75256:29:0;;;;;;;;-1:-1:-1;;;75256:29:0;;;;;;;;;;;;;75320:28;75316:117;;75392:9;74337:1232;-1:-1:-1;;;74337:1232:0:o;75316:117::-;75175:285;;;74597:905;74571:931;75530:31;;-1:-1:-1;;;75530:31:0;;;;;;;;;;;94037:158;94123:4;94164:23;:4;94177:9;94164:12;:23::i;:::-;94147:13;;-1:-1:-1;;;;;94147:40:0;;;:13;;:40;;94037:158;-1:-1:-1;;;94037:158:0:o;24984:191::-;25077:6;;;-1:-1:-1;;;;;25094:17:0;;;-1:-1:-1;;;;;;25094:17:0;;;;;;;25127:40;;25077:6;;;25094:17;25077:6;;25127:40;;25058:16;;25127:40;25047:128;24984:191;:::o;8430:190::-;8555:4;8608;8579:25;8592:5;8599:4;8579:12;:25::i;:::-;:33;;8430:190;-1:-1:-1;;;;8430:190:0:o;89798:772::-;89995:155;;-1:-1:-1;;;89995:155:0;;89961:4;;-1:-1:-1;;;;;89995:36:0;;;;;:155;;22460:10;;90081:4;;90104:7;;90130:5;;89995:155;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;89995:155:0;;;;;;;;-1:-1:-1;;89995:155:0;;;;;;;;;;;;:::i;:::-;;;89978:585;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90321:6;:13;90338:1;90321:18;90317:235;;90367:40;;-1:-1:-1;;;90367:40:0;;;;;;;;;;;90317:235;90510:6;90504:13;90495:6;90491:2;90487:15;90480:38;89978:585;-1:-1:-1;;;;;;90206:55:0;-1:-1:-1;;;90206:55:0;;-1:-1:-1;89798:772:0;;;;;;:::o;76167:417::-;76285:13;76321:16;76329:7;76321;:16::i;:::-;76316:59;;76346:29;;-1:-1:-1;;;76346:29:0;;;;;;;;;;;76316:59;76388:21;76412:10;:8;:10::i;:::-;76388:34;;76459:7;76453:21;76478:1;76453:26;:123;;;;;;;;;;;;;;;;;76523:7;76532:20;76533:7;76532:18;:20::i;:::-;76506:47;;;;;;;;;:::i;:::-;;;;;;;;;;;;;76453:123;76433:143;76167:417;-1:-1:-1;;;76167:417:0:o;80432:1940::-;80555:20;80578:13;-1:-1:-1;;;;;80606:16:0;;80602:48;;80631:19;;-1:-1:-1;;;80631:19:0;;;;;;;;;;;80602:48;80665:8;80677:1;80665:13;80661:44;;80687:18;;-1:-1:-1;;;80687:18:0;;;;;;;;;;;80661:44;-1:-1:-1;;;;;81056:16:0;;;;;;:12;:16;;;;;;;;:44;;-1:-1:-1;;81115:49:0;;-1:-1:-1;;;;;81056:44:0;;;;;;;81115:49;;;;-1:-1:-1;;81056:44:0;;;;;;81115:49;;;;;;;;;;;;;;;;81181:25;;;:11;:25;;;;;;:35;;-1:-1:-1;;;;;;81231:66:0;;;-1:-1:-1;;;81281:15:0;81231:66;;;;;;;;;;;;;81181:25;;81378:23;;;;26708:19;:23;81418:822;;81458:504;81489:38;;81514:12;;-1:-1:-1;;;;;81489:38:0;;;81506:1;;81489:38;;81506:1;;81489:38;81581:212;81650:1;81683:2;81716:14;;;;;;81761:5;81581:30;:212::i;:::-;81550:365;;81851:40;;-1:-1:-1;;;81851:40:0;;;;;;;;;;;81550:365;81957:3;81942:12;:18;81458:504;;82043:12;82026:13;;:29;82022:43;;82057:8;;;82022:43;81418:822;;;82106:119;82137:40;;82162:14;;;;;-1:-1:-1;;;;;82137:40:0;;;82154:1;;82137:40;;82154:1;;82137:40;82220:3;82205:12;:18;82106:119;;81418:822;-1:-1:-1;82254:13:0;:28;;;82304:60;;82337:2;82341:12;82355:8;82304:60;:::i;16586:231::-;16664:7;16685:17;16704:18;16726:27;16737:4;16743:9;16726:10;:27::i;:::-;16684:69;;;;16764:18;16776:5;16764:11;:18::i;:::-;-1:-1:-1;16800:9:0;16586:231;-1:-1:-1;;;16586:231:0:o;8982:707::-;9092:7;9140:4;9092:7;9155:497;9179:5;:12;9175:1;:16;9155:497;;;9213:20;9236:5;9242:1;9236:8;;;;;;;;:::i;:::-;;;;;;;9213:31;;9279:12;9263;:28;9259:382;;9792:13;9847:15;;;9883:4;9876:15;;;9930:4;9914:21;;9391:57;;9259:382;;;9792:13;9847:15;;;9883:4;9876:15;;;9930:4;9914:21;;9568:57;;9259:382;-1:-1:-1;9193:3:0;;;;:::i;:::-;;;;9155:497;;98836:155;98933:13;98971:12;98964:19;;;;;:::i;10376:723::-;10432:13;10653:5;10662:1;10653:10;10649:53;;-1:-1:-1;;10680:10:0;;;;;;;;;;;;-1:-1:-1;;;10680:10:0;;;;;10376:723::o;10649:53::-;10727:5;10712:12;10768:78;10775:9;;10768:78;;10801:8;;;;:::i;:::-;;-1:-1:-1;10824:10:0;;-1:-1:-1;10832:2:0;10824:10;;:::i;:::-;;;10768:78;;;10856:19;10888:6;-1:-1:-1;;;;;10878:17:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10878:17:0;;10856:39;;10906:154;10913:10;;10906:154;;10940:11;10950:1;10940:11;;:::i;:::-;;-1:-1:-1;11009:10:0;11017:2;11009:5;:10;:::i;:::-;10996:24;;:2;:24;:::i;:::-;10983:39;;10966:6;10973;10966:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;10966:56:0;;;;;;;;-1:-1:-1;11037:11:0;11046:2;11037:11;;:::i;:::-;;;10906:154;;14476:1308;14557:7;14566:12;14791:9;:16;14811:2;14791:22;14787:990;;15087:4;15072:20;;15066:27;15137:4;15122:20;;15116:27;15195:4;15180:20;;15174:27;14830:9;15166:36;15238:25;15249:4;15166:36;15066:27;15116;15238:10;:25::i;:::-;15231:32;;;;;;;;;14787:990;15285:9;:16;15305:2;15285:22;15281:496;;15560:4;15545:20;;15539:27;15611:4;15596:20;;15590:27;15653:23;15664:4;15539:27;15590;15653:10;:23::i;:::-;15646:30;;;;;;;;15281:496;-1:-1:-1;15725:1:0;;-1:-1:-1;15729:35:0;15281:496;14476:1308;;;;;:::o;12747:643::-;12825:20;12816:5;:29;;;;;;;;:::i;:::-;;12812:571;;12747:643;:::o;12812:571::-;12923:29;12914:5;:38;;;;;;;;:::i;:::-;;12910:473;;12969:34;;-1:-1:-1;;;12969:34:0;;23882:2:1;12969:34:0;;;23864:21:1;23921:2;23901:18;;;23894:30;23960:26;23940:18;;;23933:54;24004:18;;12969:34:0;23680:348:1;12910:473:0;13034:35;13025:5;:44;;;;;;;;:::i;:::-;;13021:362;;13086:41;;-1:-1:-1;;;13086:41:0;;24235:2:1;13086:41:0;;;24217:21:1;24274:2;24254:18;;;24247:30;24313:33;24293:18;;;24286:61;24364:18;;13086:41:0;24033:355:1;13021:362:0;13158:30;13149:5;:39;;;;;;;;:::i;:::-;;13145:238;;13205:44;;-1:-1:-1;;;13205:44:0;;24595:2:1;13205:44:0;;;24577:21:1;24634:2;24614:18;;;24607:30;24673:34;24653:18;;;24646:62;-1:-1:-1;;;24724:18:1;;;24717:32;24766:19;;13205:44:0;24393:398:1;13145:238:0;13280:30;13271:5;:39;;;;;;;;:::i;:::-;;13267:116;;13327:44;;-1:-1:-1;;;13327:44:0;;24998:2:1;13327:44:0;;;24980:21:1;25037:2;25017:18;;;25010:30;25076:34;25056:18;;;25049:62;-1:-1:-1;;;25127:18:1;;;25120:32;25169:19;;13327:44:0;24796:398:1;18038:1632:0;18169:7;;19103:66;19090:79;;19086:163;;;-1:-1:-1;19202:1:0;;-1:-1:-1;19206:30:0;19186:51;;19086:163;19263:1;:7;;19268:2;19263:7;;:18;;;;;19274:1;:7;;19279:2;19274:7;;19263:18;19259:102;;;-1:-1:-1;19314:1:0;;-1:-1:-1;19318:30:0;19298:51;;19259:102;19475:24;;;19458:14;19475:24;;;;;;;;;25426:25:1;;;25499:4;25487:17;;25467:18;;;25460:45;;;;25521:18;;;25514:34;;;25564:18;;;25557:34;;;19475:24:0;;25398:19:1;;19475:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;19475:24:0;;-1:-1:-1;;19475:24:0;;;-1:-1:-1;;;;;;;19514:20:0;;19510:103;;19567:1;19571:29;19551:50;;;;;;;19510:103;19633:6;-1:-1:-1;19641:20:0;;-1:-1:-1;18038:1632:0;;;;;;;;:::o;17080:344::-;17194:7;;-1:-1:-1;;;;;17240:80:0;;17194:7;17347:25;17363:3;17348:18;;;17370:2;17347:25;:::i;:::-;17331:42;;17391:25;17402:4;17408:1;17411;17414;17391:10;:25::i;:::-;17384:32;;;;;;17080:344;;;;;;:::o;196:131:1:-;-1:-1:-1;;;;;;270:32:1;;260:43;;250:71;;317:1;314;307:12;332:245;390:6;443:2;431:9;422:7;418:23;414:32;411:52;;;459:1;456;449:12;411:52;498:9;485:23;517:30;541:5;517:30;:::i;774:173::-;842:20;;-1:-1:-1;;;;;891:31:1;;881:42;;871:70;;937:1;934;927:12;871:70;774:173;;;:::o;952:186::-;1011:6;1064:2;1052:9;1043:7;1039:23;1035:32;1032:52;;;1080:1;1077;1070:12;1032:52;1103:29;1122:9;1103:29;:::i;1143:250::-;1228:1;1238:113;1252:6;1249:1;1246:13;1238:113;;;1328:11;;;1322:18;1309:11;;;1302:39;1274:2;1267:10;1238:113;;;-1:-1:-1;;1385:1:1;1367:16;;1360:27;1143:250::o;1398:271::-;1440:3;1478:5;1472:12;1505:6;1500:3;1493:19;1521:76;1590:6;1583:4;1578:3;1574:14;1567:4;1560:5;1556:16;1521:76;:::i;:::-;1651:2;1630:15;-1:-1:-1;;1626:29:1;1617:39;;;;1658:4;1613:50;;1398:271;-1:-1:-1;;1398:271:1:o;1674:220::-;1823:2;1812:9;1805:21;1786:4;1843:45;1884:2;1873:9;1869:18;1861:6;1843:45;:::i;1899:180::-;1958:6;2011:2;1999:9;1990:7;1986:23;1982:32;1979:52;;;2027:1;2024;2017:12;1979:52;-1:-1:-1;2050:23:1;;1899:180;-1:-1:-1;1899:180:1:o;2292:254::-;2360:6;2368;2421:2;2409:9;2400:7;2396:23;2392:32;2389:52;;;2437:1;2434;2427:12;2389:52;2460:29;2479:9;2460:29;:::i;:::-;2450:39;2536:2;2521:18;;;;2508:32;;-1:-1:-1;;;2292:254:1:o;2551:127::-;2612:10;2607:3;2603:20;2600:1;2593:31;2643:4;2640:1;2633:15;2667:4;2664:1;2657:15;2683:275;2754:2;2748:9;2819:2;2800:13;;-1:-1:-1;;2796:27:1;2784:40;;-1:-1:-1;;;;;2839:34:1;;2875:22;;;2836:62;2833:88;;;2901:18;;:::i;:::-;2937:2;2930:22;2683:275;;-1:-1:-1;2683:275:1:o;2963:712::-;3017:5;3070:3;3063:4;3055:6;3051:17;3047:27;3037:55;;3088:1;3085;3078:12;3037:55;3124:6;3111:20;3150:4;-1:-1:-1;;;;;3169:2:1;3166:26;3163:52;;;3195:18;;:::i;:::-;3241:2;3238:1;3234:10;3264:28;3288:2;3284;3280:11;3264:28;:::i;:::-;3326:15;;;3396;;;3392:24;;;3357:12;;;;3428:15;;;3425:35;;;3456:1;3453;3446:12;3425:35;3492:2;3484:6;3480:15;3469:26;;3504:142;3520:6;3515:3;3512:15;3504:142;;;3586:17;;3574:30;;3537:12;;;;3624;;;;3504:142;;;3664:5;2963:712;-1:-1:-1;;;;;;;2963:712:1:o;3680:490::-;3782:6;3790;3798;3851:2;3839:9;3830:7;3826:23;3822:32;3819:52;;;3867:1;3864;3857:12;3819:52;3890:29;3909:9;3890:29;:::i;:::-;3880:39;;3966:2;3955:9;3951:18;3938:32;3928:42;;4021:2;4010:9;4006:18;3993:32;-1:-1:-1;;;;;4040:6:1;4037:30;4034:50;;;4080:1;4077;4070:12;4034:50;4103:61;4156:7;4147:6;4136:9;4132:22;4103:61;:::i;:::-;4093:71;;;3680:490;;;;;:::o;4175:328::-;4252:6;4260;4268;4321:2;4309:9;4300:7;4296:23;4292:32;4289:52;;;4337:1;4334;4327:12;4289:52;4360:29;4379:9;4360:29;:::i;:::-;4350:39;;4408:38;4442:2;4431:9;4427:18;4408:38;:::i;:::-;4398:48;;4493:2;4482:9;4478:18;4465:32;4455:42;;4175:328;;;;;:::o;4690:592::-;4761:6;4769;4822:2;4810:9;4801:7;4797:23;4793:32;4790:52;;;4838:1;4835;4828:12;4790:52;4878:9;4865:23;-1:-1:-1;;;;;4948:2:1;4940:6;4937:14;4934:34;;;4964:1;4961;4954:12;4934:34;5002:6;4991:9;4987:22;4977:32;;5047:7;5040:4;5036:2;5032:13;5028:27;5018:55;;5069:1;5066;5059:12;5018:55;5109:2;5096:16;5135:2;5127:6;5124:14;5121:34;;;5151:1;5148;5141:12;5121:34;5196:7;5191:2;5182:6;5178:2;5174:15;5170:24;5167:37;5164:57;;;5217:1;5214;5207:12;5164:57;5248:2;5240:11;;;;;5270:6;;-1:-1:-1;4690:592:1;;-1:-1:-1;;;;4690:592:1:o;5287:367::-;5350:8;5360:6;5414:3;5407:4;5399:6;5395:17;5391:27;5381:55;;5432:1;5429;5422:12;5381:55;-1:-1:-1;5455:20:1;;-1:-1:-1;;;;;5487:30:1;;5484:50;;;5530:1;5527;5520:12;5484:50;5567:4;5559:6;5555:17;5543:29;;5627:3;5620:4;5610:6;5607:1;5603:14;5595:6;5591:27;5587:38;5584:47;5581:67;;;5644:1;5641;5634:12;5659:530;5701:5;5754:3;5747:4;5739:6;5735:17;5731:27;5721:55;;5772:1;5769;5762:12;5721:55;5808:6;5795:20;-1:-1:-1;;;;;5830:2:1;5827:26;5824:52;;;5856:18;;:::i;:::-;5900:55;5943:2;5924:13;;-1:-1:-1;;5920:27:1;5949:4;5916:38;5900:55;:::i;:::-;5980:2;5971:7;5964:19;6026:3;6019:4;6014:2;6006:6;6002:15;5998:26;5995:35;5992:55;;;6043:1;6040;6033:12;5992:55;6108:2;6101:4;6093:6;6089:17;6082:4;6073:7;6069:18;6056:55;6156:1;6131:16;;;6149:4;6127:27;6120:38;;;;6135:7;5659:530;-1:-1:-1;;;5659:530:1:o;6194:1109::-;6352:6;6360;6368;6376;6384;6392;6400;6453:3;6441:9;6432:7;6428:23;6424:33;6421:53;;;6470:1;6467;6460:12;6421:53;6510:9;6497:23;-1:-1:-1;;;;;6580:2:1;6572:6;6569:14;6566:34;;;6596:1;6593;6586:12;6566:34;6635:70;6697:7;6688:6;6677:9;6673:22;6635:70;:::i;:::-;6724:8;;-1:-1:-1;6609:96:1;-1:-1:-1;6812:2:1;6797:18;;6784:32;;-1:-1:-1;6828:16:1;;;6825:36;;;6857:1;6854;6847:12;6825:36;6896:72;6960:7;6949:8;6938:9;6934:24;6896:72;:::i;:::-;6987:8;;-1:-1:-1;6870:98:1;-1:-1:-1;7069:2:1;7054:18;;7041:32;;-1:-1:-1;7126:2:1;7111:18;;7098:32;;-1:-1:-1;7142:16:1;;;7139:36;;;7171:1;7168;7161:12;7139:36;;7194:51;7237:7;7226:8;7215:9;7211:24;7194:51;:::i;:::-;7184:61;;;7292:3;7281:9;7277:19;7264:33;7254:43;;6194:1109;;;;;;;;;;:::o;7308:118::-;7394:5;7387:13;7380:21;7373:5;7370:32;7360:60;;7416:1;7413;7406:12;7431:315;7496:6;7504;7557:2;7545:9;7536:7;7532:23;7528:32;7525:52;;;7573:1;7570;7563:12;7525:52;7596:29;7615:9;7596:29;:::i;:::-;7586:39;;7675:2;7664:9;7660:18;7647:32;7688:28;7710:5;7688:28;:::i;:::-;7735:5;7725:15;;;7431:315;;;;;:::o;7751:422::-;7844:6;7852;7905:2;7893:9;7884:7;7880:23;7876:32;7873:52;;;7921:1;7918;7911:12;7873:52;7944:29;7963:9;7944:29;:::i;:::-;7934:39;;8024:2;8013:9;8009:18;7996:32;-1:-1:-1;;;;;8043:6:1;8040:30;8037:50;;;8083:1;8080;8073:12;8037:50;8106:61;8159:7;8150:6;8139:9;8135:22;8106:61;:::i;:::-;8096:71;;;7751:422;;;;;:::o;8178:537::-;8273:6;8281;8289;8297;8350:3;8338:9;8329:7;8325:23;8321:33;8318:53;;;8367:1;8364;8357:12;8318:53;8390:29;8409:9;8390:29;:::i;:::-;8380:39;;8438:38;8472:2;8461:9;8457:18;8438:38;:::i;:::-;8428:48;;8523:2;8512:9;8508:18;8495:32;8485:42;;8578:2;8567:9;8563:18;8550:32;-1:-1:-1;;;;;8597:6:1;8594:30;8591:50;;;8637:1;8634;8627:12;8591:50;8660:49;8701:7;8692:6;8681:9;8677:22;8660:49;:::i;:::-;8650:59;;;8178:537;;;;;;;:::o;8720:260::-;8788:6;8796;8849:2;8837:9;8828:7;8824:23;8820:32;8817:52;;;8865:1;8862;8855:12;8817:52;8888:29;8907:9;8888:29;:::i;:::-;8878:39;;8936:38;8970:2;8959:9;8955:18;8936:38;:::i;:::-;8926:48;;8720:260;;;;;:::o;9170:356::-;9372:2;9354:21;;;9391:18;;;9384:30;9450:34;9445:2;9430:18;;9423:62;9517:2;9502:18;;9170:356::o;9531:380::-;9610:1;9606:12;;;;9653;;;9674:61;;9728:4;9720:6;9716:17;9706:27;;9674:61;9781:2;9773:6;9770:14;9750:18;9747:38;9744:161;;9827:10;9822:3;9818:20;9815:1;9808:31;9862:4;9859:1;9852:15;9890:4;9887:1;9880:15;9744:161;;9531:380;;;:::o;10276:127::-;10337:10;10332:3;10328:20;10325:1;10318:31;10368:4;10365:1;10358:15;10392:4;10389:1;10382:15;10408:168;10481:9;;;10512;;10529:15;;;10523:22;;10509:37;10499:71;;10550:18;;:::i;11636:801::-;-1:-1:-1;;;;;11912:32:1;;11894:51;;11964:2;11982:18;;;11975:34;;;11882:2;12040;12025:18;;12018:30;;;12097:13;;11867:18;;;12119:22;;;11834:4;;12199:15;;;;12172:3;12157:19;;;11834:4;12242:169;12256:6;12253:1;12250:13;12242:169;;;12317:13;;12305:26;;12386:15;;;;12351:12;;;;12278:1;12271:9;12242:169;;;-1:-1:-1;12428:3:1;;11636:801;-1:-1:-1;;;;;;;;11636:801:1:o;12442:245::-;12509:6;12562:2;12550:9;12541:7;12537:23;12533:32;12530:52;;;12578:1;12575;12568:12;12530:52;12610:9;12604:16;12629:28;12651:5;12629:28;:::i;13094:128::-;13161:9;;;13182:11;;;13179:37;;;13196:18;;:::i;13662:545::-;13764:2;13759:3;13756:11;13753:448;;;13800:1;13825:5;13821:2;13814:17;13870:4;13866:2;13856:19;13940:2;13928:10;13924:19;13921:1;13917:27;13911:4;13907:38;13976:4;13964:10;13961:20;13958:47;;;-1:-1:-1;13999:4:1;13958:47;14054:2;14049:3;14045:12;14042:1;14038:20;14032:4;14028:31;14018:41;;14109:82;14127:2;14120:5;14117:13;14109:82;;;14172:17;;;14153:1;14142:13;14109:82;;;14113:3;;;13662:545;;;:::o;14383:1206::-;-1:-1:-1;;;;;14502:3:1;14499:27;14496:53;;;14529:18;;:::i;:::-;14558:94;14648:3;14608:38;14640:4;14634:11;14608:38;:::i;:::-;14602:4;14558:94;:::i;:::-;14678:1;14703:2;14698:3;14695:11;14720:1;14715:616;;;;15375:1;15392:3;15389:93;;;-1:-1:-1;15448:19:1;;;15435:33;15389:93;-1:-1:-1;;14340:1:1;14336:11;;;14332:24;14328:29;14318:40;14364:1;14360:11;;;14315:57;15495:78;;14688:895;;14715:616;13609:1;13602:14;;;13646:4;13633:18;;-1:-1:-1;;14751:17:1;;;14852:9;14874:229;14888:7;14885:1;14882:14;14874:229;;;14977:19;;;14964:33;14949:49;;15084:4;15069:20;;;;15037:1;15025:14;;;;14904:12;14874:229;;;14878:3;15131;15122:7;15119:16;15116:159;;;15255:1;15251:6;15245:3;15239;15236:1;15232:11;15228:21;15224:34;15220:39;15207:9;15202:3;15198:19;15185:33;15181:79;15173:6;15166:95;15116:159;;;15318:1;15312:3;15309:1;15305:11;15301:19;15295:4;15288:33;14688:895;;14383:1206;;;:::o;15949:125::-;16014:9;;;16035:10;;;16032:36;;;16048:18;;:::i;18859:127::-;18920:10;18915:3;18911:20;18908:1;18901:31;18951:4;18948:1;18941:15;18975:4;18972:1;18965:15;18991:135;19030:3;19051:17;;;19048:43;;19071:18;;:::i;:::-;-1:-1:-1;19118:1:1;19107:13;;18991:135::o;19713:1051::-;19889:3;19927:6;19921:13;19953:4;19966:64;20023:6;20018:3;20013:2;20005:6;20001:15;19966:64;:::i;:::-;20061:6;20056:3;20052:16;20039:29;;20088:1;20121:6;20115:13;20153:36;20179:9;20153:36;:::i;:::-;20208:1;20225:18;;;20252:141;;;;20407:1;20402:337;;;;20218:521;;20252:141;-1:-1:-1;;20287:24:1;;20273:39;;20364:16;;20357:24;20343:39;;20332:51;;;-1:-1:-1;20252:141:1;;20402:337;20433:6;20430:1;20423:17;20481:2;20478:1;20468:16;20506:1;20520:169;20534:8;20531:1;20528:15;20520:169;;;20616:14;;20601:13;;;20594:37;20659:16;;;;20551:10;;20520:169;;;20524:3;;20720:8;20713:5;20709:20;20702:27;;20218:521;-1:-1:-1;20755:3:1;;19713:1051;-1:-1:-1;;;;;;;;;19713:1051:1:o;21925:489::-;-1:-1:-1;;;;;22194:15:1;;;22176:34;;22246:15;;22241:2;22226:18;;22219:43;22293:2;22278:18;;22271:34;;;22341:3;22336:2;22321:18;;22314:31;;;22119:4;;22362:46;;22388:19;;22380:6;22362:46;:::i;:::-;22354:54;21925:489;-1:-1:-1;;;;;;21925:489:1:o;22419:249::-;22488:6;22541:2;22529:9;22520:7;22516:23;22512:32;22509:52;;;22557:1;22554;22547:12;22509:52;22589:9;22583:16;22608:30;22632:5;22608:30;:::i;22673:496::-;22852:3;22890:6;22884:13;22906:66;22965:6;22960:3;22953:4;22945:6;22941:17;22906:66;:::i;:::-;23035:13;;22994:16;;;;23057:70;23035:13;22994:16;23104:4;23092:17;;23057:70;:::i;:::-;23143:20;;22673:496;-1:-1:-1;;;;22673:496:1:o;23174:127::-;23235:10;23230:3;23226:20;23223:1;23216:31;23266:4;23263:1;23256:15;23290:4;23287:1;23280:15;23306:120;23346:1;23372;23362:35;;23377:18;;:::i;:::-;-1:-1:-1;23411:9:1;;23306:120::o;23431:112::-;23463:1;23489;23479:35;;23494:18;;:::i;:::-;-1:-1:-1;23528:9:1;;23431:112::o;23548:127::-;23609:10;23604:3;23600:20;23597:1;23590:31;23640:4;23637:1;23630:15;23664:4;23661:1;23654:15

Swarm Source

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