ETH Price: $3,108.38 (-0.43%)

Token

8SIAN MERCH (8SIANMerch)
 

Overview

Max Total Supply

134 8SIANMerch

Holders

99

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
thaonft.eth
Balance
1 8SIANMerch
0xfe82d0e50868745d92e732937725925c33186de4
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:
_8sian_Merch_

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
Yes with 8888 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-08-20
*/

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


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

pragma solidity ^0.8.0;

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

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

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

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

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

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


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

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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

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


// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

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


// OpenZeppelin Contracts (last updated v4.7.3) (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) {
        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.
            /// @solidity memory-safe-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 {
            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 (last updated v4.7.0) (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 Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        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/security/Pausable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;


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

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

    bool private _paused;

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

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

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

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

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

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

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

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


// OpenZeppelin Contracts (last updated v4.7.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
                /// @solidity memory-safe-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 (last updated v4.6.0) (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 `IERC721Receiver.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 (last updated v4.7.0) (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`.
     *
     * 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;

    /**
     * @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 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 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 the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

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

// 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.7.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: address zero is not a valid owner");
        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: invalid token ID");
        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) {
        _requireMinted(tokenId);

        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 overridden 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 token owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        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: caller is not token 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: caller is not token 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) {
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == 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 an {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 an {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 Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

    /**
     * @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 {
                    /// @solidity memory-safe-assembly
                    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();
    }
}

// File: contracts/8sian_merch.sol


pragma solidity ^0.8.16;








/**
 * @title 8sian Merch Contract
 * @author Aditya Kaushik (https://twitter.com/adityakaushik38)
 * @notice This contract handles minting 8sian merch tokens.
 */
contract _8sian_Merch_ is ERC721Enumerable, ReentrancyGuard, Ownable, Pausable {
    using ECDSA for bytes32;
    using Strings for uint256;
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    string public baseTokenURI;

    uint256 public constant publicPrice = 0.055 ether;
    uint256 public constant holderPrice = 0.044 ether;
    uint256 public immutable maxSupply;

    /**
     * @notice Construct a 8sian merch instance
     * @param name Token name
     * @param symbol Token symbol
     * @param baseTokenURI_ Base URI for all tokens
     */
    constructor(
        string memory name,
        string memory symbol,
        string memory baseTokenURI_,
        uint256 maxSupply_
    ) ERC721(name, symbol) {
        require(maxSupply_ > 0, "INVALID_SUPPLY");
        baseTokenURI = baseTokenURI_;
        maxSupply = maxSupply_;

        // Start token IDs at 1
        _tokenIds.increment();
    }

    // Used to validate authorized mint addresses
    address private signerAddress = 0x354A0CAf872729a9FaF037b34FCdA5E20119218d;

    mapping (address => uint256) public totalMintsPerAddress;
    mapping (uint256 => uint256) public tokenMerchMapping;

    bool public isSaleActive = false;
    bool public isFreeMintActive = false;

    /**
     * To be used to fetch metadata json
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "URI query for nonexistent token");

        return string(abi.encodePacked(_baseURI(), tokenId.toString(), ".json"));
    }

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

    /**
     * To be updated by contract owner to allow for the members to mint
     */
    function setSaleActiveState(bool _saleActiveState) public onlyOwner {
        require(isSaleActive != _saleActiveState, "NEW_STATE_IDENTICAL_TO_OLD_STATE");
        isSaleActive = _saleActiveState;
    }

    /**
     * Allow for free mint
     * Can also be activated by contract owner to begin free mint
     */
    function setFreeMintActiveState(bool _freeMintActiveState) public onlyOwner {
        require(isFreeMintActive != _freeMintActiveState, "NEW_STATE_IDENTICAL_TO_OLD_STATE");
        isFreeMintActive = _freeMintActiveState;
    }

    /**
     * Setting the signer address.
     * Signer will be used to authorise the 
     */
    function setSignerAddress(address _signerAddress) external onlyOwner {
        require(_signerAddress != address(0));
        signerAddress = _signerAddress;
    }

    /**
     * Returns all the token ids owned by a given address
     */
    function ownedTokensByAddress(address owner) external view returns (uint256[] memory) {
        uint256 totalTokensOwned = balanceOf(owner);
        uint256[] memory allTokenIds = new uint256[](totalTokensOwned);
        for (uint256 i = 0; i < totalTokensOwned; i++) {
            allTokenIds[i] = (tokenOfOwnerByIndex(owner, i));
        }
        return allTokenIds;
    }

    /**
     * Update the base token URI
     */
    function setBaseURI(string calldata _newBaseURI) external onlyOwner {
        baseTokenURI = _newBaseURI;
    }

    function pause() public onlyOwner {
        _pause();
    }

    function unpause() public onlyOwner {
        _unpause();
    }
    
    /**
     * When the contract is paused, all token transfers are prevented in case of emergency.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal whenNotPaused override {
        super._beforeTokenTransfer(from, to, tokenId);
    }

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

    function hashMessage(address sender, uint256 maximumAllowedMints) private pure returns (bytes32) {
        return keccak256(abi.encode(sender, maximumAllowedMints));
    }

    function publicMint(
        uint256 merchNumber,
        uint256 mintNumber
    ) external payable virtual nonReentrant {
        require(isSaleActive, "SALE_IS_NOT_ACTIVE");
        require((1 <= merchNumber) && (merchNumber <= 9), "INVALID_MERCH_NUMBER");

        // Imprecise floats are scary. Front-end should utilize BigNumber for safe precision, but adding margin just to be safe to not fail txs
        // Suggestion from : Mai Akiyoshi & Ben Yu (https://twitter.com/mai_on_chain & https://twitter.com/intenex)
        require(msg.value >= ((publicPrice * mintNumber) - 0.0001 ether) && msg.value <= ((publicPrice * mintNumber) + 0.0001 ether), "INVALID_PRICE");

        uint256 currentSupply = totalSupply();

        require(currentSupply + mintNumber <= maxSupply, "NOT_ENOUGH_MINTS_AVAILABLE");
        
        totalMintsPerAddress[msg.sender] += mintNumber;

        for (uint256 i = 0; i < mintNumber; i++) {
            _safeMint(msg.sender, _tokenIds.current());
            tokenMerchMapping[_tokenIds.current()] = merchNumber;
            _tokenIds.increment();
        }

        if (isSaleActive && (currentSupply + mintNumber >= maxSupply)) {
            isSaleActive = false;
        }
    }

    /**
     * @notice Allow for minting of tokens up to the maximum allowed for a given address.
     * The address of the sender and the number of mints allowed are hashed and signed
     * with the server's private key and verified here to prove token holder status.
     */
    function mint(
        bytes32 messageHash,
        bytes calldata signature,
        uint256 merchNumber,
        uint256 mintNumber,
        uint256 maximumAllowedMints
    ) external payable virtual nonReentrant {
        require(isSaleActive, "SALE_IS_NOT_ACTIVE");
        require(totalMintsPerAddress[msg.sender] + mintNumber <= maximumAllowedMints, "MINT_TOO_LARGE");
        require((merchNumber >= 1) && (merchNumber <= 9), "INVALID_MERCH_NUMBER");
        require(hashMessage(msg.sender, maximumAllowedMints) == messageHash, "MESSAGE_INVALID");
        require(verifyAddressSigner(messageHash, signature), "SIGNATURE_VALIDATION_FAILED");
        /*
         * Need to ensure people don't pay when free mint is active
         */
        require((isFreeMintActive && msg.value == 0 ether) || (!isFreeMintActive && (msg.value >= ((holderPrice * mintNumber) - 0.0001 ether) && msg.value <= ((holderPrice * mintNumber) + 0.0001 ether))), "INVALID_PRICE");

        uint256 currentSupply = totalSupply();

        require(currentSupply + mintNumber <= maxSupply, "NOT_ENOUGH_MINTS_AVAILABLE");
        
        totalMintsPerAddress[msg.sender] += mintNumber;

        for (uint256 i = 0; i < mintNumber; i++) {
            _safeMint(msg.sender, _tokenIds.current());
            tokenMerchMapping[_tokenIds.current()] = merchNumber;
            _tokenIds.increment();
        }

        if (isSaleActive && (currentSupply + mintNumber >= maxSupply)) {
            isSaleActive = false;
        }
    }

    /**
     * @notice Allow owner to send `mintNumber` tokens without cost to multiple addresses
     */
    function gift(address[] calldata receivers, uint256 mintNumber) external onlyOwner {
        require((totalSupply() + (receivers.length * mintNumber)) <= maxSupply, "MINT_TOO_LARGE");

        for (uint256 i = 0; i < receivers.length; i++) {
            for (uint256 j = 0; j < mintNumber; j++) {
                _safeMint(receivers[i], _tokenIds.current());
                _tokenIds.increment();
            }
        }
    }

    /**
     * @notice Allow contract owner to withdraw funds.
     */
    function withdrawFunds() external onlyOwner {
        payable(owner()).transfer(address(this).balance);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"baseTokenURI_","type":"string"},{"internalType":"uint256","name":"maxSupply_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"receivers","type":"address[]"},{"internalType":"uint256","name":"mintNumber","type":"uint256"}],"name":"gift","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"holderPrice","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":"isFreeMintActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSaleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256","name":"merchNumber","type":"uint256"},{"internalType":"uint256","name":"mintNumber","type":"uint256"},{"internalType":"uint256","name":"maximumAllowedMints","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ownedTokensByAddress","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"merchNumber","type":"uint256"},{"internalType":"uint256","name":"mintNumber","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"publicPrice","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":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_freeMintActiveState","type":"bool"}],"name":"setFreeMintActiveState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_saleActiveState","type":"bool"}],"name":"setSaleActiveState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signerAddress","type":"address"}],"name":"setSignerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenMerchMapping","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalMintsPerAddress","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":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a0604052600e80546001600160a01b03191673354a0caf872729a9faf037b34fcda5e20119218d1790556011805461ffff191690553480156200004257600080fd5b5060405162003b9038038062003b9083398101604081905262000065916200023f565b8383600062000075838262000367565b50600162000084828262000367565b50506001600a555062000097336200011f565b600b805460ff60a01b1916905580620000e75760405162461bcd60e51b815260206004820152600e60248201526d494e56414c49445f535550504c5960901b604482015260640160405180910390fd5b600d620000f5838262000367565b50806080818152505062000115600c6200017160201b62001af31760201c565b5050505062000433565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80546001019055565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001a257600080fd5b81516001600160401b0380821115620001bf57620001bf6200017a565b604051601f8301601f19908116603f01168101908282118183101715620001ea57620001ea6200017a565b816040528381526020925086838588010111156200020757600080fd5b600091505b838210156200022b57858201830151818301840152908201906200020c565b600093810190920192909252949350505050565b600080600080608085870312156200025657600080fd5b84516001600160401b03808211156200026e57600080fd5b6200027c8883890162000190565b955060208701519150808211156200029357600080fd5b620002a18883890162000190565b94506040870151915080821115620002b857600080fd5b50620002c78782880162000190565b606096909601519497939650505050565b600181811c90821680620002ed57607f821691505b6020821081036200030e57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200036257600081815260208120601f850160051c810160208610156200033d5750805b601f850160051c820191505b818110156200035e5782815560010162000349565b5050505b505050565b81516001600160401b038111156200038357620003836200017a565b6200039b81620003948454620002d8565b8462000314565b602080601f831160018114620003d35760008415620003ba5750858301515b600019600386901b1c1916600185901b1785556200035e565b600085815260208120601f198616915b828110156200040457888601518255948401946001909101908401620003e3565b5085821015620004235787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805161371e620004726000396000818161070201528181610daa01528181610eb20152818161158a0152818161168d0152611798015261371e6000f3fe6080604052600436106102a05760003560e01c80637046f3401161016e578063a945bf80116100cb578063d547cfb71161007f578063dba028c211610064578063dba028c214610724578063e985e9c514610751578063f2fde38b1461079a57600080fd5b8063d547cfb7146106db578063d5abeb01146106f057600080fd5b8063b9bd2801116100b0578063b9bd28011461066e578063c0f4af701461069b578063c87b56dd146106bb57600080fd5b8063a945bf8014610633578063b88d4fde1461064e57600080fd5b80638456cb591161012257806395d89b411161010757806395d89b41146105eb57806398ae99a814610600578063a22cb4651461061357600080fd5b80638456cb59146105b85780638da5cb5b146105cd57600080fd5b8063715018a611610153578063715018a6146105645780637a1d005d146105795780637a5b85c11461059957600080fd5b80637046f3401461052457806370a082311461054457600080fd5b80632f745c591161021c57806355f804b3116101d05780635c975abb116101b55780635c975abb146104a75780636352211e146104d75780636839b841146104f757600080fd5b806355f804b31461046d578063564566a81461048d57600080fd5b806342842e0e1161020157806342842e0e146104125780634f6ccce71461043257806355ea73281461045257600080fd5b80632f745c59146103dd5780633f4ba83a146103fd57600080fd5b8063095ea7b3116102735780631c346885116102585780631c3468851461039557806323b872dd146103a857806324600fc3146103c857600080fd5b8063095ea7b31461035657806318160ddd1461037657600080fd5b806301ffc9a7146102a5578063046dc166146102da57806306fdde03146102fc578063081812fc1461031e575b600080fd5b3480156102b157600080fd5b506102c56102c0366004612e51565b6107ba565b60405190151581526020015b60405180910390f35b3480156102e657600080fd5b506102fa6102f5366004612e91565b610816565b005b34801561030857600080fd5b5061031161086b565b6040516102d19190612efc565b34801561032a57600080fd5b5061033e610339366004612f0f565b6108fd565b6040516001600160a01b0390911681526020016102d1565b34801561036257600080fd5b506102fa610371366004612f28565b610924565b34801561038257600080fd5b506008545b6040519081526020016102d1565b6102fa6103a3366004612f94565b610a5a565b3480156103b457600080fd5b506102fa6103c3366004612ffa565b610f1a565b3480156103d457600080fd5b506102fa610fa1565b3480156103e957600080fd5b506103876103f8366004612f28565b610fe5565b34801561040957600080fd5b506102fa61108d565b34801561041e57600080fd5b506102fa61042d366004612ffa565b61109f565b34801561043e57600080fd5b5061038761044d366004612f0f565b6110ba565b34801561045e57600080fd5b50610387669c51c4521e000081565b34801561047957600080fd5b506102fa610488366004613036565b61115e565b34801561049957600080fd5b506011546102c59060ff1681565b3480156104b357600080fd5b50600b5474010000000000000000000000000000000000000000900460ff166102c5565b3480156104e357600080fd5b5061033e6104f2366004612f0f565b611173565b34801561050357600080fd5b50610387610512366004612f0f565b60106020526000908152604090205481565b34801561053057600080fd5b506102fa61053f366004613088565b6111d8565b34801561055057600080fd5b5061038761055f366004612e91565b61126b565b34801561057057600080fd5b506102fa611305565b34801561058557600080fd5b506102fa610594366004613088565b611317565b3480156105a557600080fd5b506011546102c590610100900460ff1681565b3480156105c457600080fd5b506102fa6113b8565b3480156105d957600080fd5b50600b546001600160a01b031661033e565b3480156105f757600080fd5b506103116113c8565b6102fa61060e3660046130a3565b6113d7565b34801561061f57600080fd5b506102fa61062e3660046130c5565b6116f1565b34801561063f57600080fd5b5061038766c3663566a5800081565b34801561065a57600080fd5b506102fa610669366004613127565b611700565b34801561067a57600080fd5b50610387610689366004612e91565b600f6020526000908152604090205481565b3480156106a757600080fd5b506102fa6106b6366004613203565b61178e565b3480156106c757600080fd5b506103116106d6366004612f0f565b611897565b3480156106e757600080fd5b50610311611936565b3480156106fc57600080fd5b506103877f000000000000000000000000000000000000000000000000000000000000000081565b34801561073057600080fd5b5061074461073f366004612e91565b6119c4565b6040516102d1919061327e565b34801561075d57600080fd5b506102c561076c3660046132c2565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156107a657600080fd5b506102fa6107b5366004612e91565b611a66565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d63000000000000000000000000000000000000000000000000000000001480610810575061081082611afc565b92915050565b61081e611bdf565b6001600160a01b03811661083157600080fd5b600e80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b60606000805461087a906132ec565b80601f01602080910402602001604051908101604052809291908181526020018280546108a6906132ec565b80156108f35780601f106108c8576101008083540402835291602001916108f3565b820191906000526020600020905b8154815290600101906020018083116108d657829003601f168201915b5050505050905090565b600061090882611c39565b506000908152600460205260409020546001600160a01b031690565b600061092f82611173565b9050806001600160a01b0316836001600160a01b0316036109bd5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b336001600160a01b03821614806109d957506109d9813361076c565b610a4b5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c000060648201526084016109b4565b610a558383611c9d565b505050565b6002600a5403610aac5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b4565b6002600a5560115460ff16610b035760405162461bcd60e51b815260206004820152601260248201527f53414c455f49535f4e4f545f414354495645000000000000000000000000000060448201526064016109b4565b336000908152600f60205260409020548190610b2090849061336e565b1115610b6e5760405162461bcd60e51b815260206004820152600e60248201527f4d494e545f544f4f5f4c4152474500000000000000000000000000000000000060448201526064016109b4565b60018310158015610b80575060098311155b610bcc5760405162461bcd60e51b815260206004820152601460248201527f494e56414c49445f4d455243485f4e554d42455200000000000000000000000060448201526064016109b4565b6040805133602080830191909152818301849052825180830384018152606090920190925280519101208614610c445760405162461bcd60e51b815260206004820152600f60248201527f4d4553534147455f494e56414c4944000000000000000000000000000000000060448201526064016109b4565b610c848686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611d2392505050565b610cd05760405162461bcd60e51b815260206004820152601b60248201527f5349474e41545552455f56414c49444154494f4e5f4641494c4544000000000060448201526064016109b4565b601154610100900460ff168015610ce5575034155b80610d4f5750601154610100900460ff16158015610d4f5750655af3107a4000610d1683669c51c4521e0000613381565b610d2091906133be565b3410158015610d4f5750610d3b82669c51c4521e0000613381565b610d4b90655af3107a400061336e565b3411155b610d9b5760405162461bcd60e51b815260206004820152600d60248201527f494e56414c49445f50524943450000000000000000000000000000000000000060448201526064016109b4565b6000610da660085490565b90507f0000000000000000000000000000000000000000000000000000000000000000610dd3848361336e565b1115610e215760405162461bcd60e51b815260206004820152601a60248201527f4e4f545f454e4f5547485f4d494e54535f415641494c41424c4500000000000060448201526064016109b4565b336000908152600f602052604081208054859290610e4090849061336e565b90915550600090505b83811015610ea257610e6333610e5e600c5490565b611d9e565b8460106000610e71600c5490565b8152602081019190915260400160002055610e90600c80546001019055565b80610e9a816133d1565b915050610e49565b5060115460ff168015610ede57507f0000000000000000000000000000000000000000000000000000000000000000610edb848361336e565b10155b15610f0c57601180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b50506001600a555050505050565b610f243382611db8565b610f965760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f76656400000000000000000000000000000000000060648201526084016109b4565b610a55838383611e37565b610fa9611bdf565b600b546040516001600160a01b03909116904780156108fc02916000818181858888f19350505050158015610fe2573d6000803e3d6000fd5b50565b6000610ff08361126b565b82106110645760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e647300000000000000000000000000000000000000000060648201526084016109b4565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b611095611bdf565b61109d612027565b565b610a5583838360405180602001604052806000815250611700565b60006110c560085490565b82106111395760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e6473000000000000000000000000000000000000000060648201526084016109b4565b6008828154811061114c5761114c613409565b90600052602060002001549050919050565b611166611bdf565b600d610a55828483613486565b6000818152600260205260408120546001600160a01b0316806108105760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e204944000000000000000060448201526064016109b4565b6111e0611bdf565b60115481151560ff90911615150361123a5760405162461bcd60e51b815260206004820181905260248201527f4e45575f53544154455f4944454e544943414c5f544f5f4f4c445f535441544560448201526064016109b4565b601180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b60006001600160a01b0382166112e95760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e6572000000000000000000000000000000000000000000000060648201526084016109b4565b506001600160a01b031660009081526003602052604090205490565b61130d611bdf565b61109d6000612097565b61131f611bdf565b801515601160019054906101000a900460ff161515036113815760405162461bcd60e51b815260206004820181905260248201527f4e45575f53544154455f4944454e544943414c5f544f5f4f4c445f535441544560448201526064016109b4565b60118054911515610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909216919091179055565b6113c0611bdf565b61109d612101565b60606001805461087a906132ec565b6002600a54036114295760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b4565b6002600a5560115460ff166114805760405162461bcd60e51b815260206004820152601260248201527f53414c455f49535f4e4f545f414354495645000000000000000000000000000060448201526064016109b4565b81600111158015611492575060098211155b6114de5760405162461bcd60e51b815260206004820152601460248201527f494e56414c49445f4d455243485f4e554d42455200000000000000000000000060448201526064016109b4565b655af3107a40006114f68266c3663566a58000613381565b61150091906133be565b341015801561152f575061151b8166c3663566a58000613381565b61152b90655af3107a400061336e565b3411155b61157b5760405162461bcd60e51b815260206004820152600d60248201527f494e56414c49445f50524943450000000000000000000000000000000000000060448201526064016109b4565b600061158660085490565b90507f00000000000000000000000000000000000000000000000000000000000000006115b3838361336e565b11156116015760405162461bcd60e51b815260206004820152601a60248201527f4e4f545f454e4f5547485f4d494e54535f415641494c41424c4500000000000060448201526064016109b4565b336000908152600f60205260408120805484929061162090849061336e565b90915550600090505b8281101561167d5761163e33610e5e600c5490565b836010600061164c600c5490565b815260208101919091526040016000205561166b600c80546001019055565b80611675816133d1565b915050611629565b5060115460ff1680156116b957507f00000000000000000000000000000000000000000000000000000000000000006116b6838361336e565b10155b156116e757601180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b50506001600a5550565b6116fc338383612170565b5050565b61170a3383611db8565b61177c5760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f76656400000000000000000000000000000000000060648201526084016109b4565b6117888484848461225c565b50505050565b611796611bdf565b7f00000000000000000000000000000000000000000000000000000000000000006117c18284613381565b6008546117ce919061336e565b111561181c5760405162461bcd60e51b815260206004820152600e60248201527f4d494e545f544f4f5f4c4152474500000000000000000000000000000000000060448201526064016109b4565b60005b828110156117885760005b828110156118845761186485858481811061184757611847613409565b905060200201602081019061185c9190612e91565b600c54611d9e565b611872600c80546001019055565b8061187c816133d1565b91505061182a565b508061188f816133d1565b91505061181f565b6000818152600260205260409020546060906001600160a01b03166118fe5760405162461bcd60e51b815260206004820152601f60248201527f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e0060448201526064016109b4565b6119066122e5565b61190f836122f4565b604051602001611920929190613583565b6040516020818303038152906040529050919050565b600d8054611943906132ec565b80601f016020809104026020016040519081016040528092919081815260200182805461196f906132ec565b80156119bc5780601f10611991576101008083540402835291602001916119bc565b820191906000526020600020905b81548152906001019060200180831161199f57829003601f168201915b505050505081565b606060006119d18361126b565b905060008167ffffffffffffffff8111156119ee576119ee6130f8565b604051908082528060200260200182016040528015611a17578160200160208202803683370190505b50905060005b82811015611a5e57611a2f8582610fe5565b828281518110611a4157611a41613409565b602090810291909101015280611a56816133d1565b915050611a1d565b509392505050565b611a6e611bdf565b6001600160a01b038116611aea5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016109b4565b610fe281612097565b80546001019055565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd000000000000000000000000000000000000000000000000000000001480611b8f57507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061081057507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610810565b600b546001600160a01b0316331461109d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109b4565b6000818152600260205260409020546001600160a01b0316610fe25760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e204944000000000000000060448201526064016109b4565b600081815260046020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384169081179091558190611cea82611173565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611d8682611d80856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90612429565b600e546001600160a01b039182169116149392505050565b6116fc828260405180602001604052806000815250612445565b600080611dc483611173565b9050806001600160a01b0316846001600160a01b03161480611e0b57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80611e2f5750836001600160a01b0316611e24846108fd565b6001600160a01b0316145b949350505050565b826001600160a01b0316611e4a82611173565b6001600160a01b031614611ec65760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e657200000000000000000000000000000000000000000000000000000060648201526084016109b4565b6001600160a01b038216611f415760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016109b4565b611f4c8383836124ce565b611f57600082611c9d565b6001600160a01b0383166000908152600360205260408120805460019290611f809084906133be565b90915550506001600160a01b0382166000908152600360205260408120805460019290611fae90849061336e565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61202f6124e1565b600b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600b80546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61210961254b565b600b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861207a3390565b816001600160a01b0316836001600160a01b0316036121d15760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016109b4565b6001600160a01b0383811660008181526005602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612267848484611e37565b612273848484846125b6565b6117885760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016109b4565b6060600d805461087a906132ec565b60608160000361233757505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115612361578061234b816133d1565b915061235a9050600a83613609565b915061233b565b60008167ffffffffffffffff81111561237c5761237c6130f8565b6040519080825280601f01601f1916602001820160405280156123a6576020820181803683370190505b5090505b8415611e2f576123bb6001836133be565b91506123c8600a8661361d565b6123d390603061336e565b60f81b8183815181106123e8576123e8613409565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612422600a86613609565b94506123aa565b60008060006124388585612757565b91509150611a5e8161279c565b61244f8383612988565b61245c60008484846125b6565b610a555760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016109b4565b6124d661254b565b610a55838383612aee565b600b5474010000000000000000000000000000000000000000900460ff1661109d5760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016109b4565b600b5474010000000000000000000000000000000000000000900460ff161561109d5760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016109b4565b60006001600160a01b0384163b1561274c576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063150b7a0290612613903390899088908890600401613631565b6020604051808303816000875af192505050801561264e575060408051601f3d908101601f1916820190925261264b9181019061366d565b60015b612701573d80801561267c576040519150601f19603f3d011682016040523d82523d6000602084013e612681565b606091505b5080516000036126f95760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016109b4565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050611e2f565b506001949350505050565b600080825160410361278d5760208301516040840151606085015160001a61278187828585612ba6565b94509450505050612795565b506000905060025b9250929050565b60008160048111156127b0576127b061368a565b036127b85750565b60018160048111156127cc576127cc61368a565b036128195760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016109b4565b600281600481111561282d5761282d61368a565b0361287a5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016109b4565b600381600481111561288e5761288e61368a565b036129015760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016109b4565b60048160048111156129155761291561368a565b03610fe25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016109b4565b6001600160a01b0382166129de5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016109b4565b6000818152600260205260409020546001600160a01b031615612a435760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109b4565b612a4f600083836124ce565b6001600160a01b0382166000908152600360205260408120805460019290612a7890849061336e565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160a01b038316612b4957612b4481600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612b6c565b816001600160a01b0316836001600160a01b031614612b6c57612b6c8382612c93565b6001600160a01b038216612b8357610a5581612d30565b826001600160a01b0316826001600160a01b031614610a5557610a558282612ddf565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612bdd5750600090506003612c8a565b8460ff16601b14158015612bf557508460ff16601c14155b15612c065750600090506004612c8a565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612c5a573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612c8357600060019250925050612c8a565b9150600090505b94509492505050565b60006001612ca08461126b565b612caa91906133be565b600083815260076020526040902054909150808214612cfd576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612d42906001906133be565b60008381526009602052604081205460088054939450909284908110612d6a57612d6a613409565b906000526020600020015490508060088381548110612d8b57612d8b613409565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612dc357612dc36136b9565b6001900381819060005260206000200160009055905550505050565b6000612dea8361126b565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114610fe257600080fd5b600060208284031215612e6357600080fd5b8135612e6e81612e23565b9392505050565b80356001600160a01b0381168114612e8c57600080fd5b919050565b600060208284031215612ea357600080fd5b612e6e82612e75565b60005b83811015612ec7578181015183820152602001612eaf565b50506000910152565b60008151808452612ee8816020860160208601612eac565b601f01601f19169290920160200192915050565b602081526000612e6e6020830184612ed0565b600060208284031215612f2157600080fd5b5035919050565b60008060408385031215612f3b57600080fd5b612f4483612e75565b946020939093013593505050565b60008083601f840112612f6457600080fd5b50813567ffffffffffffffff811115612f7c57600080fd5b60208301915083602082850101111561279557600080fd5b60008060008060008060a08789031215612fad57600080fd5b86359550602087013567ffffffffffffffff811115612fcb57600080fd5b612fd789828a01612f52565b979a90995096976040810135976060820135975060809091013595509350505050565b60008060006060848603121561300f57600080fd5b61301884612e75565b925061302660208501612e75565b9150604084013590509250925092565b6000806020838503121561304957600080fd5b823567ffffffffffffffff81111561306057600080fd5b61306c85828601612f52565b90969095509350505050565b80358015158114612e8c57600080fd5b60006020828403121561309a57600080fd5b612e6e82613078565b600080604083850312156130b657600080fd5b50508035926020909101359150565b600080604083850312156130d857600080fd5b6130e183612e75565b91506130ef60208401613078565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806080858703121561313d57600080fd5b61314685612e75565b935061315460208601612e75565b925060408501359150606085013567ffffffffffffffff8082111561317857600080fd5b818701915087601f83011261318c57600080fd5b81358181111561319e5761319e6130f8565b604051601f8201601f19908116603f011681019083821181831017156131c6576131c66130f8565b816040528281528a60208487010111156131df57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060006040848603121561321857600080fd5b833567ffffffffffffffff8082111561323057600080fd5b818601915086601f83011261324457600080fd5b81358181111561325357600080fd5b8760208260051b850101111561326857600080fd5b6020928301989097509590910135949350505050565b6020808252825182820181905260009190848201906040850190845b818110156132b65783518352928401929184019160010161329a565b50909695505050505050565b600080604083850312156132d557600080fd5b6132de83612e75565b91506130ef60208401612e75565b600181811c9082168061330057607f821691505b602082108103613339577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156108105761081061333f565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156133b9576133b961333f565b500290565b818103818111156108105761081061333f565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036134025761340261333f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b601f821115610a5557600081815260208120601f850160051c8101602086101561345f5750805b601f850160051c820191505b8181101561347e5782815560010161346b565b505050505050565b67ffffffffffffffff83111561349e5761349e6130f8565b6134b2836134ac83546132ec565b83613438565b6000601f84116001811461350457600085156134ce5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561357c565b600083815260209020601f19861690835b828110156135355786850135825560209485019460019092019101613515565b5086821015613570577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60008351613595818460208801612eac565b8351908301906135a9818360208801612eac565b7f2e6a736f6e0000000000000000000000000000000000000000000000000000009101908152600501949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613618576136186135da565b500490565b60008261362c5761362c6135da565b500690565b60006001600160a01b038087168352808616602084015250836040830152608060608301526136636080830184612ed0565b9695505050505050565b60006020828403121561367f57600080fd5b8151612e6e81612e23565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212202e7474a040164da6c975ce20cb56d60b96bf333606f7a31c7ed4d33e636c011864736f6c63430008100033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000022b8000000000000000000000000000000000000000000000000000000000000000b385349414e204d45524348000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a385349414e4d65726368000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036697066733a2f2f516d594163347968703432563733556e46597350626a5650764657626e43577277787363554b6b45626931346b412f00000000000000000000

Deployed Bytecode

0x6080604052600436106102a05760003560e01c80637046f3401161016e578063a945bf80116100cb578063d547cfb71161007f578063dba028c211610064578063dba028c214610724578063e985e9c514610751578063f2fde38b1461079a57600080fd5b8063d547cfb7146106db578063d5abeb01146106f057600080fd5b8063b9bd2801116100b0578063b9bd28011461066e578063c0f4af701461069b578063c87b56dd146106bb57600080fd5b8063a945bf8014610633578063b88d4fde1461064e57600080fd5b80638456cb591161012257806395d89b411161010757806395d89b41146105eb57806398ae99a814610600578063a22cb4651461061357600080fd5b80638456cb59146105b85780638da5cb5b146105cd57600080fd5b8063715018a611610153578063715018a6146105645780637a1d005d146105795780637a5b85c11461059957600080fd5b80637046f3401461052457806370a082311461054457600080fd5b80632f745c591161021c57806355f804b3116101d05780635c975abb116101b55780635c975abb146104a75780636352211e146104d75780636839b841146104f757600080fd5b806355f804b31461046d578063564566a81461048d57600080fd5b806342842e0e1161020157806342842e0e146104125780634f6ccce71461043257806355ea73281461045257600080fd5b80632f745c59146103dd5780633f4ba83a146103fd57600080fd5b8063095ea7b3116102735780631c346885116102585780631c3468851461039557806323b872dd146103a857806324600fc3146103c857600080fd5b8063095ea7b31461035657806318160ddd1461037657600080fd5b806301ffc9a7146102a5578063046dc166146102da57806306fdde03146102fc578063081812fc1461031e575b600080fd5b3480156102b157600080fd5b506102c56102c0366004612e51565b6107ba565b60405190151581526020015b60405180910390f35b3480156102e657600080fd5b506102fa6102f5366004612e91565b610816565b005b34801561030857600080fd5b5061031161086b565b6040516102d19190612efc565b34801561032a57600080fd5b5061033e610339366004612f0f565b6108fd565b6040516001600160a01b0390911681526020016102d1565b34801561036257600080fd5b506102fa610371366004612f28565b610924565b34801561038257600080fd5b506008545b6040519081526020016102d1565b6102fa6103a3366004612f94565b610a5a565b3480156103b457600080fd5b506102fa6103c3366004612ffa565b610f1a565b3480156103d457600080fd5b506102fa610fa1565b3480156103e957600080fd5b506103876103f8366004612f28565b610fe5565b34801561040957600080fd5b506102fa61108d565b34801561041e57600080fd5b506102fa61042d366004612ffa565b61109f565b34801561043e57600080fd5b5061038761044d366004612f0f565b6110ba565b34801561045e57600080fd5b50610387669c51c4521e000081565b34801561047957600080fd5b506102fa610488366004613036565b61115e565b34801561049957600080fd5b506011546102c59060ff1681565b3480156104b357600080fd5b50600b5474010000000000000000000000000000000000000000900460ff166102c5565b3480156104e357600080fd5b5061033e6104f2366004612f0f565b611173565b34801561050357600080fd5b50610387610512366004612f0f565b60106020526000908152604090205481565b34801561053057600080fd5b506102fa61053f366004613088565b6111d8565b34801561055057600080fd5b5061038761055f366004612e91565b61126b565b34801561057057600080fd5b506102fa611305565b34801561058557600080fd5b506102fa610594366004613088565b611317565b3480156105a557600080fd5b506011546102c590610100900460ff1681565b3480156105c457600080fd5b506102fa6113b8565b3480156105d957600080fd5b50600b546001600160a01b031661033e565b3480156105f757600080fd5b506103116113c8565b6102fa61060e3660046130a3565b6113d7565b34801561061f57600080fd5b506102fa61062e3660046130c5565b6116f1565b34801561063f57600080fd5b5061038766c3663566a5800081565b34801561065a57600080fd5b506102fa610669366004613127565b611700565b34801561067a57600080fd5b50610387610689366004612e91565b600f6020526000908152604090205481565b3480156106a757600080fd5b506102fa6106b6366004613203565b61178e565b3480156106c757600080fd5b506103116106d6366004612f0f565b611897565b3480156106e757600080fd5b50610311611936565b3480156106fc57600080fd5b506103877f00000000000000000000000000000000000000000000000000000000000022b881565b34801561073057600080fd5b5061074461073f366004612e91565b6119c4565b6040516102d1919061327e565b34801561075d57600080fd5b506102c561076c3660046132c2565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156107a657600080fd5b506102fa6107b5366004612e91565b611a66565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d63000000000000000000000000000000000000000000000000000000001480610810575061081082611afc565b92915050565b61081e611bdf565b6001600160a01b03811661083157600080fd5b600e80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b60606000805461087a906132ec565b80601f01602080910402602001604051908101604052809291908181526020018280546108a6906132ec565b80156108f35780601f106108c8576101008083540402835291602001916108f3565b820191906000526020600020905b8154815290600101906020018083116108d657829003601f168201915b5050505050905090565b600061090882611c39565b506000908152600460205260409020546001600160a01b031690565b600061092f82611173565b9050806001600160a01b0316836001600160a01b0316036109bd5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b336001600160a01b03821614806109d957506109d9813361076c565b610a4b5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c000060648201526084016109b4565b610a558383611c9d565b505050565b6002600a5403610aac5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b4565b6002600a5560115460ff16610b035760405162461bcd60e51b815260206004820152601260248201527f53414c455f49535f4e4f545f414354495645000000000000000000000000000060448201526064016109b4565b336000908152600f60205260409020548190610b2090849061336e565b1115610b6e5760405162461bcd60e51b815260206004820152600e60248201527f4d494e545f544f4f5f4c4152474500000000000000000000000000000000000060448201526064016109b4565b60018310158015610b80575060098311155b610bcc5760405162461bcd60e51b815260206004820152601460248201527f494e56414c49445f4d455243485f4e554d42455200000000000000000000000060448201526064016109b4565b6040805133602080830191909152818301849052825180830384018152606090920190925280519101208614610c445760405162461bcd60e51b815260206004820152600f60248201527f4d4553534147455f494e56414c4944000000000000000000000000000000000060448201526064016109b4565b610c848686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611d2392505050565b610cd05760405162461bcd60e51b815260206004820152601b60248201527f5349474e41545552455f56414c49444154494f4e5f4641494c4544000000000060448201526064016109b4565b601154610100900460ff168015610ce5575034155b80610d4f5750601154610100900460ff16158015610d4f5750655af3107a4000610d1683669c51c4521e0000613381565b610d2091906133be565b3410158015610d4f5750610d3b82669c51c4521e0000613381565b610d4b90655af3107a400061336e565b3411155b610d9b5760405162461bcd60e51b815260206004820152600d60248201527f494e56414c49445f50524943450000000000000000000000000000000000000060448201526064016109b4565b6000610da660085490565b90507f00000000000000000000000000000000000000000000000000000000000022b8610dd3848361336e565b1115610e215760405162461bcd60e51b815260206004820152601a60248201527f4e4f545f454e4f5547485f4d494e54535f415641494c41424c4500000000000060448201526064016109b4565b336000908152600f602052604081208054859290610e4090849061336e565b90915550600090505b83811015610ea257610e6333610e5e600c5490565b611d9e565b8460106000610e71600c5490565b8152602081019190915260400160002055610e90600c80546001019055565b80610e9a816133d1565b915050610e49565b5060115460ff168015610ede57507f00000000000000000000000000000000000000000000000000000000000022b8610edb848361336e565b10155b15610f0c57601180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b50506001600a555050505050565b610f243382611db8565b610f965760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f76656400000000000000000000000000000000000060648201526084016109b4565b610a55838383611e37565b610fa9611bdf565b600b546040516001600160a01b03909116904780156108fc02916000818181858888f19350505050158015610fe2573d6000803e3d6000fd5b50565b6000610ff08361126b565b82106110645760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e647300000000000000000000000000000000000000000060648201526084016109b4565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b611095611bdf565b61109d612027565b565b610a5583838360405180602001604052806000815250611700565b60006110c560085490565b82106111395760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e6473000000000000000000000000000000000000000060648201526084016109b4565b6008828154811061114c5761114c613409565b90600052602060002001549050919050565b611166611bdf565b600d610a55828483613486565b6000818152600260205260408120546001600160a01b0316806108105760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e204944000000000000000060448201526064016109b4565b6111e0611bdf565b60115481151560ff90911615150361123a5760405162461bcd60e51b815260206004820181905260248201527f4e45575f53544154455f4944454e544943414c5f544f5f4f4c445f535441544560448201526064016109b4565b601180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b60006001600160a01b0382166112e95760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e6572000000000000000000000000000000000000000000000060648201526084016109b4565b506001600160a01b031660009081526003602052604090205490565b61130d611bdf565b61109d6000612097565b61131f611bdf565b801515601160019054906101000a900460ff161515036113815760405162461bcd60e51b815260206004820181905260248201527f4e45575f53544154455f4944454e544943414c5f544f5f4f4c445f535441544560448201526064016109b4565b60118054911515610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909216919091179055565b6113c0611bdf565b61109d612101565b60606001805461087a906132ec565b6002600a54036114295760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b4565b6002600a5560115460ff166114805760405162461bcd60e51b815260206004820152601260248201527f53414c455f49535f4e4f545f414354495645000000000000000000000000000060448201526064016109b4565b81600111158015611492575060098211155b6114de5760405162461bcd60e51b815260206004820152601460248201527f494e56414c49445f4d455243485f4e554d42455200000000000000000000000060448201526064016109b4565b655af3107a40006114f68266c3663566a58000613381565b61150091906133be565b341015801561152f575061151b8166c3663566a58000613381565b61152b90655af3107a400061336e565b3411155b61157b5760405162461bcd60e51b815260206004820152600d60248201527f494e56414c49445f50524943450000000000000000000000000000000000000060448201526064016109b4565b600061158660085490565b90507f00000000000000000000000000000000000000000000000000000000000022b86115b3838361336e565b11156116015760405162461bcd60e51b815260206004820152601a60248201527f4e4f545f454e4f5547485f4d494e54535f415641494c41424c4500000000000060448201526064016109b4565b336000908152600f60205260408120805484929061162090849061336e565b90915550600090505b8281101561167d5761163e33610e5e600c5490565b836010600061164c600c5490565b815260208101919091526040016000205561166b600c80546001019055565b80611675816133d1565b915050611629565b5060115460ff1680156116b957507f00000000000000000000000000000000000000000000000000000000000022b86116b6838361336e565b10155b156116e757601180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b50506001600a5550565b6116fc338383612170565b5050565b61170a3383611db8565b61177c5760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f76656400000000000000000000000000000000000060648201526084016109b4565b6117888484848461225c565b50505050565b611796611bdf565b7f00000000000000000000000000000000000000000000000000000000000022b86117c18284613381565b6008546117ce919061336e565b111561181c5760405162461bcd60e51b815260206004820152600e60248201527f4d494e545f544f4f5f4c4152474500000000000000000000000000000000000060448201526064016109b4565b60005b828110156117885760005b828110156118845761186485858481811061184757611847613409565b905060200201602081019061185c9190612e91565b600c54611d9e565b611872600c80546001019055565b8061187c816133d1565b91505061182a565b508061188f816133d1565b91505061181f565b6000818152600260205260409020546060906001600160a01b03166118fe5760405162461bcd60e51b815260206004820152601f60248201527f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e0060448201526064016109b4565b6119066122e5565b61190f836122f4565b604051602001611920929190613583565b6040516020818303038152906040529050919050565b600d8054611943906132ec565b80601f016020809104026020016040519081016040528092919081815260200182805461196f906132ec565b80156119bc5780601f10611991576101008083540402835291602001916119bc565b820191906000526020600020905b81548152906001019060200180831161199f57829003601f168201915b505050505081565b606060006119d18361126b565b905060008167ffffffffffffffff8111156119ee576119ee6130f8565b604051908082528060200260200182016040528015611a17578160200160208202803683370190505b50905060005b82811015611a5e57611a2f8582610fe5565b828281518110611a4157611a41613409565b602090810291909101015280611a56816133d1565b915050611a1d565b509392505050565b611a6e611bdf565b6001600160a01b038116611aea5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016109b4565b610fe281612097565b80546001019055565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd000000000000000000000000000000000000000000000000000000001480611b8f57507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061081057507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610810565b600b546001600160a01b0316331461109d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109b4565b6000818152600260205260409020546001600160a01b0316610fe25760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e204944000000000000000060448201526064016109b4565b600081815260046020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384169081179091558190611cea82611173565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611d8682611d80856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90612429565b600e546001600160a01b039182169116149392505050565b6116fc828260405180602001604052806000815250612445565b600080611dc483611173565b9050806001600160a01b0316846001600160a01b03161480611e0b57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80611e2f5750836001600160a01b0316611e24846108fd565b6001600160a01b0316145b949350505050565b826001600160a01b0316611e4a82611173565b6001600160a01b031614611ec65760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e657200000000000000000000000000000000000000000000000000000060648201526084016109b4565b6001600160a01b038216611f415760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016109b4565b611f4c8383836124ce565b611f57600082611c9d565b6001600160a01b0383166000908152600360205260408120805460019290611f809084906133be565b90915550506001600160a01b0382166000908152600360205260408120805460019290611fae90849061336e565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61202f6124e1565b600b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600b80546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61210961254b565b600b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861207a3390565b816001600160a01b0316836001600160a01b0316036121d15760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016109b4565b6001600160a01b0383811660008181526005602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612267848484611e37565b612273848484846125b6565b6117885760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016109b4565b6060600d805461087a906132ec565b60608160000361233757505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115612361578061234b816133d1565b915061235a9050600a83613609565b915061233b565b60008167ffffffffffffffff81111561237c5761237c6130f8565b6040519080825280601f01601f1916602001820160405280156123a6576020820181803683370190505b5090505b8415611e2f576123bb6001836133be565b91506123c8600a8661361d565b6123d390603061336e565b60f81b8183815181106123e8576123e8613409565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612422600a86613609565b94506123aa565b60008060006124388585612757565b91509150611a5e8161279c565b61244f8383612988565b61245c60008484846125b6565b610a555760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016109b4565b6124d661254b565b610a55838383612aee565b600b5474010000000000000000000000000000000000000000900460ff1661109d5760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016109b4565b600b5474010000000000000000000000000000000000000000900460ff161561109d5760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016109b4565b60006001600160a01b0384163b1561274c576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063150b7a0290612613903390899088908890600401613631565b6020604051808303816000875af192505050801561264e575060408051601f3d908101601f1916820190925261264b9181019061366d565b60015b612701573d80801561267c576040519150601f19603f3d011682016040523d82523d6000602084013e612681565b606091505b5080516000036126f95760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016109b4565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050611e2f565b506001949350505050565b600080825160410361278d5760208301516040840151606085015160001a61278187828585612ba6565b94509450505050612795565b506000905060025b9250929050565b60008160048111156127b0576127b061368a565b036127b85750565b60018160048111156127cc576127cc61368a565b036128195760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016109b4565b600281600481111561282d5761282d61368a565b0361287a5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016109b4565b600381600481111561288e5761288e61368a565b036129015760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016109b4565b60048160048111156129155761291561368a565b03610fe25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016109b4565b6001600160a01b0382166129de5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016109b4565b6000818152600260205260409020546001600160a01b031615612a435760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109b4565b612a4f600083836124ce565b6001600160a01b0382166000908152600360205260408120805460019290612a7890849061336e565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160a01b038316612b4957612b4481600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612b6c565b816001600160a01b0316836001600160a01b031614612b6c57612b6c8382612c93565b6001600160a01b038216612b8357610a5581612d30565b826001600160a01b0316826001600160a01b031614610a5557610a558282612ddf565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612bdd5750600090506003612c8a565b8460ff16601b14158015612bf557508460ff16601c14155b15612c065750600090506004612c8a565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612c5a573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612c8357600060019250925050612c8a565b9150600090505b94509492505050565b60006001612ca08461126b565b612caa91906133be565b600083815260076020526040902054909150808214612cfd576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612d42906001906133be565b60008381526009602052604081205460088054939450909284908110612d6a57612d6a613409565b906000526020600020015490508060088381548110612d8b57612d8b613409565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612dc357612dc36136b9565b6001900381819060005260206000200160009055905550505050565b6000612dea8361126b565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114610fe257600080fd5b600060208284031215612e6357600080fd5b8135612e6e81612e23565b9392505050565b80356001600160a01b0381168114612e8c57600080fd5b919050565b600060208284031215612ea357600080fd5b612e6e82612e75565b60005b83811015612ec7578181015183820152602001612eaf565b50506000910152565b60008151808452612ee8816020860160208601612eac565b601f01601f19169290920160200192915050565b602081526000612e6e6020830184612ed0565b600060208284031215612f2157600080fd5b5035919050565b60008060408385031215612f3b57600080fd5b612f4483612e75565b946020939093013593505050565b60008083601f840112612f6457600080fd5b50813567ffffffffffffffff811115612f7c57600080fd5b60208301915083602082850101111561279557600080fd5b60008060008060008060a08789031215612fad57600080fd5b86359550602087013567ffffffffffffffff811115612fcb57600080fd5b612fd789828a01612f52565b979a90995096976040810135976060820135975060809091013595509350505050565b60008060006060848603121561300f57600080fd5b61301884612e75565b925061302660208501612e75565b9150604084013590509250925092565b6000806020838503121561304957600080fd5b823567ffffffffffffffff81111561306057600080fd5b61306c85828601612f52565b90969095509350505050565b80358015158114612e8c57600080fd5b60006020828403121561309a57600080fd5b612e6e82613078565b600080604083850312156130b657600080fd5b50508035926020909101359150565b600080604083850312156130d857600080fd5b6130e183612e75565b91506130ef60208401613078565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806080858703121561313d57600080fd5b61314685612e75565b935061315460208601612e75565b925060408501359150606085013567ffffffffffffffff8082111561317857600080fd5b818701915087601f83011261318c57600080fd5b81358181111561319e5761319e6130f8565b604051601f8201601f19908116603f011681019083821181831017156131c6576131c66130f8565b816040528281528a60208487010111156131df57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060006040848603121561321857600080fd5b833567ffffffffffffffff8082111561323057600080fd5b818601915086601f83011261324457600080fd5b81358181111561325357600080fd5b8760208260051b850101111561326857600080fd5b6020928301989097509590910135949350505050565b6020808252825182820181905260009190848201906040850190845b818110156132b65783518352928401929184019160010161329a565b50909695505050505050565b600080604083850312156132d557600080fd5b6132de83612e75565b91506130ef60208401612e75565b600181811c9082168061330057607f821691505b602082108103613339577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156108105761081061333f565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156133b9576133b961333f565b500290565b818103818111156108105761081061333f565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036134025761340261333f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b601f821115610a5557600081815260208120601f850160051c8101602086101561345f5750805b601f850160051c820191505b8181101561347e5782815560010161346b565b505050505050565b67ffffffffffffffff83111561349e5761349e6130f8565b6134b2836134ac83546132ec565b83613438565b6000601f84116001811461350457600085156134ce5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561357c565b600083815260209020601f19861690835b828110156135355786850135825560209485019460019092019101613515565b5086821015613570577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60008351613595818460208801612eac565b8351908301906135a9818360208801612eac565b7f2e6a736f6e0000000000000000000000000000000000000000000000000000009101908152600501949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613618576136186135da565b500490565b60008261362c5761362c6135da565b500690565b60006001600160a01b038087168352808616602084015250836040830152608060608301526136636080830184612ed0565b9695505050505050565b60006020828403121561367f57600080fd5b8151612e6e81612e23565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212202e7474a040164da6c975ce20cb56d60b96bf333606f7a31c7ed4d33e636c011864736f6c63430008100033

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

000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000022b8000000000000000000000000000000000000000000000000000000000000000b385349414e204d45524348000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a385349414e4d65726368000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036697066733a2f2f516d594163347968703432563733556e46597350626a5650764657626e43577277787363554b6b45626931346b412f00000000000000000000

-----Decoded View---------------
Arg [0] : name (string): 8SIAN MERCH
Arg [1] : symbol (string): 8SIANMerch
Arg [2] : baseTokenURI_ (string): ipfs://QmYAc4yhp42V73UnFYsPbjVPvFWbnCWrwxscUKkEbi14kA/
Arg [3] : maxSupply_ (uint256): 8888

-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [3] : 00000000000000000000000000000000000000000000000000000000000022b8
Arg [4] : 000000000000000000000000000000000000000000000000000000000000000b
Arg [5] : 385349414e204d45524348000000000000000000000000000000000000000000
Arg [6] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [7] : 385349414e4d6572636800000000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000036
Arg [9] : 697066733a2f2f516d594163347968703432563733556e46597350626a565076
Arg [10] : 4657626e43577277787363554b6b45626931346b412f00000000000000000000


Deployed Bytecode Sourcemap

62261:8014:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55862:224;;;;;;;;;;-1:-1:-1;55862:224:0;;;;;:::i;:::-;;:::i;:::-;;;611:14:1;;604:22;586:41;;574:2;559:18;55862:224:0;;;;;;;;64784:166;;;;;;;;;;-1:-1:-1;64784:166:0;;;;;:::i;:::-;;:::i;:::-;;42596:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;44109:171::-;;;;;;;;;;-1:-1:-1;44109:171:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2194:55:1;;;2176:74;;2164:2;2149:18;44109:171:0;2030:226:1;43626:417:0;;;;;;;;;;-1:-1:-1;43626:417:0;;;;;:::i;:::-;;:::i;56502:113::-;;;;;;;;;;-1:-1:-1;56590:10:0;:17;56502:113;;;2666:25:1;;;2654:2;2639:18;56502:113:0;2520:177:1;67988:1538:0;;;;;;:::i;:::-;;:::i;44809:336::-;;;;;;;;;;-1:-1:-1;44809:336:0;;;;;:::i;:::-;;:::i;70161:111::-;;;;;;;;;;;;;:::i;56170:256::-;;;;;;;;;;-1:-1:-1;56170:256:0;;;;;:::i;:::-;;:::i;65667:65::-;;;;;;;;;;;;;:::i;45216:185::-;;;;;;;;;;-1:-1:-1;45216:185:0;;;;;:::i;:::-;;:::i;56692:233::-;;;;;;;;;;-1:-1:-1;56692:233:0;;;;;:::i;:::-;;:::i;62585:49::-;;;;;;;;;;;;62623:11;62585:49;;65477:113;;;;;;;;;;-1:-1:-1;65477:113:0;;;;;:::i;:::-;;:::i;63503:32::-;;;;;;;;;;-1:-1:-1;63503:32:0;;;;;;;;20960:86;;;;;;;;;;-1:-1:-1;21031:7:0;;;;;;;20960:86;;42307:222;;;;;;;;;;-1:-1:-1;42307:222:0;;;;;:::i;:::-;;:::i;63441:53::-;;;;;;;;;;-1:-1:-1;63441:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;64119:206;;;;;;;;;;-1:-1:-1;64119:206:0;;;;;:::i;:::-;;:::i;42038:207::-;;;;;;;;;;-1:-1:-1;42038:207:0;;;;;:::i;:::-;;:::i;18470:103::-;;;;;;;;;;;;;:::i;64446:230::-;;;;;;;;;;-1:-1:-1;64446:230:0;;;;;:::i;:::-;;:::i;63542:36::-;;;;;;;;;;-1:-1:-1;63542:36:0;;;;;;;;;;;65598:61;;;;;;;;;;;;;:::i;17822:87::-;;;;;;;;;;-1:-1:-1;17895:6:0;;-1:-1:-1;;;;;17895:6:0;17822:87;;42765:104;;;;;;;;;;;;;:::i;66455:1242::-;;;;;;:::i;:::-;;:::i;44352:155::-;;;;;;;;;;-1:-1:-1;44352:155:0;;;;;:::i;:::-;;:::i;62529:49::-;;;;;;;;;;;;62567:11;62529:49;;45472:323;;;;;;;;;;-1:-1:-1;45472:323:0;;;;;:::i;:::-;;:::i;63378:56::-;;;;;;;;;;-1:-1:-1;63378:56:0;;;;;:::i;:::-;;;;;;;;;;;;;;69643:436;;;;;;;;;;-1:-1:-1;69643:436:0;;;;;:::i;:::-;;:::i;63647:252::-;;;;;;;;;;-1:-1:-1;63647:252:0;;;;;:::i;:::-;;:::i;62494:26::-;;;;;;;;;;;;;:::i;62641:34::-;;;;;;;;;;;;;;;65035:382;;;;;;;;;;-1:-1:-1;65035:382:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;44578:164::-;;;;;;;;;;-1:-1:-1;44578:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;44699:25:0;;;44675:4;44699:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;44578:164;18728:201;;;;;;;;;;-1:-1:-1;18728:201:0;;;;;:::i;:::-;;:::i;55862:224::-;55964:4;55988:50;;;56003:35;55988:50;;:90;;;56042:36;56066:11;56042:23;:36::i;:::-;55981:97;55862:224;-1:-1:-1;;55862:224:0:o;64784:166::-;17708:13;:11;:13::i;:::-;-1:-1:-1;;;;;64872:28:0;::::1;64864:37;;;::::0;::::1;;64912:13;:30:::0;;;::::1;-1:-1:-1::0;;;;;64912:30:0;;;::::1;::::0;;;::::1;::::0;;64784:166::o;42596:100::-;42650:13;42683:5;42676:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42596:100;:::o;44109:171::-;44185:7;44205:23;44220:7;44205:14;:23::i;:::-;-1:-1:-1;44248:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;44248:24:0;;44109:171::o;43626:417::-;43707:13;43723:23;43738:7;43723:14;:23::i;:::-;43707:39;;43771:5;-1:-1:-1;;;;;43765:11:0;:2;-1:-1:-1;;;;;43765:11:0;;43757:57;;;;-1:-1:-1;;;43757:57:0;;8983:2:1;43757:57:0;;;8965:21:1;9022:2;9002:18;;;8995:30;9061:34;9041:18;;;9034:62;9132:3;9112:18;;;9105:31;9153:19;;43757:57:0;;;;;;;;;16453:10;-1:-1:-1;;;;;43849:21:0;;;;:62;;-1:-1:-1;43874:37:0;43891:5;16453:10;44578:164;:::i;43874:37::-;43827:174;;;;-1:-1:-1;;;43827:174:0;;9385:2:1;43827:174:0;;;9367:21:1;9424:2;9404:18;;;9397:30;9463:34;9443:18;;;9436:62;9534:32;9514:18;;;9507:60;9584:19;;43827:174:0;9183:426:1;43827:174:0;44014:21;44023:2;44027:7;44014:8;:21::i;:::-;43696:347;43626:417;;:::o;67988:1538::-;3277:1;3875:7;;:19;3867:63;;;;-1:-1:-1;;;3867:63:0;;9816:2:1;3867:63:0;;;9798:21:1;9855:2;9835:18;;;9828:30;9894:33;9874:18;;;9867:61;9945:18;;3867:63:0;9614:355:1;3867:63:0;3277:1;4008:7;:18;68228:12:::1;::::0;::::1;;68220:43;;;::::0;-1:-1:-1;;;68220:43:0;;10176:2:1;68220:43:0::1;::::0;::::1;10158:21:1::0;10215:2;10195:18;;;10188:30;10254:20;10234:18;;;10227:48;10292:18;;68220:43:0::1;9974:342:1::0;68220:43:0::1;68303:10;68282:32;::::0;;;:20:::1;:32;::::0;;;;;68331:19;;68282:45:::1;::::0;68317:10;;68282:45:::1;:::i;:::-;:68;;68274:95;;;::::0;-1:-1:-1;;;68274:95:0;;10842:2:1;68274:95:0::1;::::0;::::1;10824:21:1::0;10881:2;10861:18;;;10854:30;10920:16;10900:18;;;10893:44;10954:18;;68274:95:0::1;10640:338:1::0;68274:95:0::1;68404:1;68389:11;:16;;68388:40;;;;;68426:1;68411:11;:16;;68388:40;68380:73;;;::::0;-1:-1:-1;;;68380:73:0;;11185:2:1;68380:73:0::1;::::0;::::1;11167:21:1::0;11224:2;11204:18;;;11197:30;11263:22;11243:18;;;11236:50;11303:18;;68380:73:0::1;10983:344:1::0;68380:73:0::1;66399:39:::0;;;68484:10:::1;66399:39:::0;;;;20055:74:1;;;;20145:18;;;20138:34;;;66399:39:0;;;;;;;;;20028:18:1;;;;66399:39:0;;;66389:50;;;;;68520:11;68472:59:::1;68464:87;;;::::0;-1:-1:-1;;;68464:87:0;;11534:2:1;68464:87:0::1;::::0;::::1;11516:21:1::0;11573:2;11553:18;;;11546:30;11612:17;11592:18;;;11585:45;11647:18;;68464:87:0::1;11332:339:1::0;68464:87:0::1;68570:43;68590:11;68603:9;;68570:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;68570:19:0::1;::::0;-1:-1:-1;;;68570:43:0:i:1;:::-;68562:83;;;::::0;-1:-1:-1;;;68562:83:0;;11878:2:1;68562:83:0::1;::::0;::::1;11860:21:1::0;11917:2;11897:18;;;11890:30;11956:29;11936:18;;;11929:57;12003:18;;68562:83:0::1;11676:351:1::0;68562:83:0::1;68759:16;::::0;::::1;::::0;::::1;;;:40:::0;::::1;;;-1:-1:-1::0;68779:9:0::1;:20:::0;68759:40:::1;68758:187;;;-1:-1:-1::0;68806:16:0::1;::::0;::::1;::::0;::::1;;;68805:17;:139:::0;::::1;;;-1:-1:-1::0;68870:12:0::1;68842:24;68856:10:::0;62623:11:::1;68842:24;:::i;:::-;68841:41;;;;:::i;:::-;68827:9;:56;;:116;;;;-1:-1:-1::0;68902:24:0::1;68916:10:::0;62623:11:::1;68902:24;:::i;:::-;68901:41;::::0;68930:12:::1;68901:41;:::i;:::-;68887:9;:56;;68827:116;68750:213;;;::::0;-1:-1:-1;;;68750:213:0;;12600:2:1;68750:213:0::1;::::0;::::1;12582:21:1::0;12639:2;12619:18;;;12612:30;12678:15;12658:18;;;12651:43;12711:18;;68750:213:0::1;12398:337:1::0;68750:213:0::1;68976:21;69000:13;56590:10:::0;:17;;56502:113;69000:13:::1;68976:37:::0;-1:-1:-1;69064:9:0::1;69034:26;69050:10:::0;68976:37;69034:26:::1;:::i;:::-;:39;;69026:78;;;::::0;-1:-1:-1;;;69026:78:0;;12942:2:1;69026:78:0::1;::::0;::::1;12924:21:1::0;12981:2;12961:18;;;12954:30;13020:28;13000:18;;;12993:56;13066:18;;69026:78:0::1;12740:350:1::0;69026:78:0::1;69146:10;69125:32;::::0;;;:20:::1;:32;::::0;;;;:46;;69161:10;;69125:32;:46:::1;::::0;69161:10;;69125:46:::1;:::i;:::-;::::0;;;-1:-1:-1;69189:9:0::1;::::0;-1:-1:-1;69184:213:0::1;69208:10;69204:1;:14;69184:213;;;69240:42;69250:10;69262:19;:9;964:14:::0;;872:114;69262:19:::1;69240:9;:42::i;:::-;69338:11;69297:17;:38;69315:19;:9;964:14:::0;;872:114;69315:19:::1;69297:38:::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;69297:38:0;:52;69364:21:::1;:9;1083:19:::0;;1101:1;1083:19;;;994:127;69364:21:::1;69220:3:::0;::::1;::::0;::::1;:::i;:::-;;;;69184:213;;;-1:-1:-1::0;69413:12:0::1;::::0;::::1;;:57:::0;::::1;;;-1:-1:-1::0;69460:9:0::1;69430:26;69446:10:::0;69430:13;:26:::1;:::i;:::-;:39;;69413:57;69409:110;;;69487:12;:20:::0;;;::::1;::::0;;69409:110:::1;-1:-1:-1::0;;3233:1:0;4187:7;:22;-1:-1:-1;;;;;67988:1538:0:o;44809:336::-;45004:41;16453:10;45037:7;45004:18;:41::i;:::-;44996:100;;;;-1:-1:-1;;;44996:100:0;;13497:2:1;44996:100:0;;;13479:21:1;13536:2;13516:18;;;13509:30;13575:34;13555:18;;;13548:62;13646:16;13626:18;;;13619:44;13680:19;;44996:100:0;13295:410:1;44996:100:0;45109:28;45119:4;45125:2;45129:7;45109:9;:28::i;70161:111::-;17708:13;:11;:13::i;:::-;17895:6;;70216:48:::1;::::0;-1:-1:-1;;;;;17895:6:0;;;;70242:21:::1;70216:48:::0;::::1;;;::::0;::::1;::::0;;;70242:21;17895:6;70216:48;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;70161:111::o:0;56170:256::-;56267:7;56303:23;56320:5;56303:16;:23::i;:::-;56295:5;:31;56287:87;;;;-1:-1:-1;;;56287:87:0;;13912:2:1;56287:87:0;;;13894:21:1;13951:2;13931:18;;;13924:30;13990:34;13970:18;;;13963:62;14061:13;14041:18;;;14034:41;14092:19;;56287:87:0;13710:407:1;56287:87:0;-1:-1:-1;;;;;;56392:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;56170:256::o;65667:65::-;17708:13;:11;:13::i;:::-;65714:10:::1;:8;:10::i;:::-;65667:65::o:0;45216:185::-;45354:39;45371:4;45377:2;45381:7;45354:39;;;;;;;;;;;;:16;:39::i;56692:233::-;56767:7;56803:30;56590:10;:17;;56502:113;56803:30;56795:5;:38;56787:95;;;;-1:-1:-1;;;56787:95:0;;14324:2:1;56787:95:0;;;14306:21:1;14363:2;14343:18;;;14336:30;14402:34;14382:18;;;14375:62;14473:14;14453:18;;;14446:42;14505:19;;56787:95:0;14122:408:1;56787:95:0;56900:10;56911:5;56900:17;;;;;;;;:::i;:::-;;;;;;;;;56893:24;;56692:233;;;:::o;65477:113::-;17708:13;:11;:13::i;:::-;65556:12:::1;:26;65571:11:::0;;65556:12;:26:::1;:::i;42307:222::-:0;42379:7;42415:16;;;:7;:16;;;;;;-1:-1:-1;;;;;42415:16:0;;42442:56;;;;-1:-1:-1;;;42442:56:0;;17163:2:1;42442:56:0;;;17145:21:1;17202:2;17182:18;;;17175:30;17241:26;17221:18;;;17214:54;17285:18;;42442:56:0;16961:348:1;64119:206:0;17708:13;:11;:13::i;:::-;64206:12:::1;::::0;:32;::::1;;:12;::::0;;::::1;:32;;::::0;64198:77:::1;;;::::0;-1:-1:-1;;;64198:77:0;;17516:2:1;64198:77:0::1;::::0;::::1;17498:21:1::0;;;17535:18;;;17528:30;17594:34;17574:18;;;17567:62;17646:18;;64198:77:0::1;17314:356:1::0;64198:77:0::1;64286:12;:31:::0;;;::::1;::::0;::::1;;::::0;;;::::1;::::0;;64119:206::o;42038:207::-;42110:7;-1:-1:-1;;;;;42138:19:0;;42130:73;;;;-1:-1:-1;;;42130:73:0;;17877:2:1;42130:73:0;;;17859:21:1;17916:2;17896:18;;;17889:30;17955:34;17935:18;;;17928:62;18026:11;18006:18;;;17999:39;18055:19;;42130:73:0;17675:405:1;42130:73:0;-1:-1:-1;;;;;;42221:16:0;;;;;:9;:16;;;;;;;42038:207::o;18470:103::-;17708:13;:11;:13::i;:::-;18535:30:::1;18562:1;18535:18;:30::i;64446:230::-:0;17708:13;:11;:13::i;:::-;64561:20:::1;64541:40;;:16;;;;;;;;;;;:40;;::::0;64533:85:::1;;;::::0;-1:-1:-1;;;64533:85:0;;17516:2:1;64533:85:0::1;::::0;::::1;17498:21:1::0;;;17535:18;;;17528:30;17594:34;17574:18;;;17567:62;17646:18;;64533:85:0::1;17314:356:1::0;64533:85:0::1;64629:16;:39:::0;;;::::1;;;;::::0;;;::::1;::::0;;;::::1;::::0;;64446:230::o;65598:61::-;17708:13;:11;:13::i;:::-;65643:8:::1;:6;:8::i;42765:104::-:0;42821:13;42854:7;42847:14;;;;;:::i;66455:1242::-;3277:1;3875:7;;:19;3867:63;;;;-1:-1:-1;;;3867:63:0;;9816:2:1;3867:63:0;;;9798:21:1;9855:2;9835:18;;;9828:30;9894:33;9874:18;;;9867:61;9945:18;;3867:63:0;9614:355:1;3867:63:0;3277:1;4008:7;:18;66598:12:::1;::::0;::::1;;66590:43;;;::::0;-1:-1:-1;;;66590:43:0;;10176:2:1;66590:43:0::1;::::0;::::1;10158:21:1::0;10215:2;10195:18;;;10188:30;10254:20;10234:18;;;10227:48;10292:18;;66590:43:0::1;9974:342:1::0;66590:43:0::1;66658:11;66653:1;:16;;66652:40;;;;;66690:1;66675:11;:16;;66652:40;66644:73;;;::::0;-1:-1:-1;;;66644:73:0;;11185:2:1;66644:73:0::1;::::0;::::1;11167:21:1::0;11224:2;11204:18;;;11197:30;11263:22;11243:18;;;11236:50;11303:18;;66644:73:0::1;10983:344:1::0;66644:73:0::1;67043:12;67015:24;67029:10:::0;62567:11:::1;67015:24;:::i;:::-;67014:41;;;;:::i;:::-;67000:9;:56;;:116;;;;-1:-1:-1::0;67075:24:0::1;67089:10:::0;62567:11:::1;67075:24;:::i;:::-;67074:41;::::0;67103:12:::1;67074:41;:::i;:::-;67060:9;:56;;67000:116;66992:142;;;::::0;-1:-1:-1;;;66992:142:0;;12600:2:1;66992:142:0::1;::::0;::::1;12582:21:1::0;12639:2;12619:18;;;12612:30;12678:15;12658:18;;;12651:43;12711:18;;66992:142:0::1;12398:337:1::0;66992:142:0::1;67147:21;67171:13;56590:10:::0;:17;;56502:113;67171:13:::1;67147:37:::0;-1:-1:-1;67235:9:0::1;67205:26;67221:10:::0;67147:37;67205:26:::1;:::i;:::-;:39;;67197:78;;;::::0;-1:-1:-1;;;67197:78:0;;12942:2:1;67197:78:0::1;::::0;::::1;12924:21:1::0;12981:2;12961:18;;;12954:30;13020:28;13000:18;;;12993:56;13066:18;;67197:78:0::1;12740:350:1::0;67197:78:0::1;67317:10;67296:32;::::0;;;:20:::1;:32;::::0;;;;:46;;67332:10;;67296:32;:46:::1;::::0;67332:10;;67296:46:::1;:::i;:::-;::::0;;;-1:-1:-1;67360:9:0::1;::::0;-1:-1:-1;67355:213:0::1;67379:10;67375:1;:14;67355:213;;;67411:42;67421:10;67433:19;:9;964:14:::0;;872:114;67411:42:::1;67509:11;67468:17;:38;67486:19;:9;964:14:::0;;872:114;67486:19:::1;67468:38:::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;67468:38:0;:52;67535:21:::1;:9;1083:19:::0;;1101:1;1083:19;;;994:127;67535:21:::1;67391:3:::0;::::1;::::0;::::1;:::i;:::-;;;;67355:213;;;-1:-1:-1::0;67584:12:0::1;::::0;::::1;;:57:::0;::::1;;;-1:-1:-1::0;67631:9:0::1;67601:26;67617:10:::0;67601:13;:26:::1;:::i;:::-;:39;;67584:57;67580:110;;;67658:12;:20:::0;;;::::1;::::0;;67580:110:::1;-1:-1:-1::0;;3233:1:0;4187:7;:22;-1:-1:-1;66455:1242:0:o;44352:155::-;44447:52;16453:10;44480:8;44490;44447:18;:52::i;:::-;44352:155;;:::o;45472:323::-;45646:41;16453:10;45679:7;45646:18;:41::i;:::-;45638:100;;;;-1:-1:-1;;;45638:100:0;;13497:2:1;45638:100:0;;;13479:21:1;13536:2;13516:18;;;13509:30;13575:34;13555:18;;;13548:62;13646:16;13626:18;;;13619:44;13680:19;;45638:100:0;13295:410:1;45638:100:0;45749:38;45763:4;45769:2;45773:7;45782:4;45749:13;:38::i;:::-;45472:323;;;;:::o;69643:436::-;17708:13;:11;:13::i;:::-;69798:9:::1;69763:29;69782:10:::0;69763:9;:29:::1;:::i;:::-;56590:10:::0;:17;69746:47:::1;;;;:::i;:::-;69745:62;;69737:89;;;::::0;-1:-1:-1;;;69737:89:0;;10842:2:1;69737:89:0::1;::::0;::::1;10824:21:1::0;10881:2;10861:18;;;10854:30;10920:16;10900:18;;;10893:44;10954:18;;69737:89:0::1;10640:338:1::0;69737:89:0::1;69844:9;69839:233;69859:20:::0;;::::1;69839:233;;;69906:9;69901:160;69925:10;69921:1;:14;69901:160;;;69961:44;69971:9;;69981:1;69971:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;69985:9;964:14:::0;69240:9:::1;:42::i;69961:44::-;70024:21;:9;1083:19:::0;;1101:1;1083:19;;;994:127;70024:21:::1;69937:3:::0;::::1;::::0;::::1;:::i;:::-;;;;69901:160;;;-1:-1:-1::0;69881:3:0;::::1;::::0;::::1;:::i;:::-;;;;69839:233;;63647:252:::0;47367:4;47391:16;;;:7;:16;;;;;;63720:13;;-1:-1:-1;;;;;47391:16:0;63746:60;;;;-1:-1:-1;;;63746:60:0;;18287:2:1;63746:60:0;;;18269:21:1;18326:2;18306:18;;;18299:30;18365:33;18345:18;;;18338:61;18416:18;;63746:60:0;18085:355:1;63746:60:0;63850:10;:8;:10::i;:::-;63862:18;:7;:16;:18::i;:::-;63833:57;;;;;;;;;:::i;:::-;;;;;;;;;;;;;63819:72;;63647:252;;;:::o;62494:26::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;65035:382::-;65103:16;65132:24;65159:16;65169:5;65159:9;:16::i;:::-;65132:43;;65186:28;65231:16;65217:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65217:31:0;;65186:62;;65264:9;65259:122;65283:16;65279:1;:20;65259:122;;;65339:29;65359:5;65366:1;65339:19;:29::i;:::-;65321:11;65333:1;65321:14;;;;;;;;:::i;:::-;;;;;;;;;;:48;65301:3;;;;:::i;:::-;;;;65259:122;;;-1:-1:-1;65398:11:0;65035:382;-1:-1:-1;;;65035:382:0:o;18728:201::-;17708:13;:11;:13::i;:::-;-1:-1:-1;;;;;18817:22:0;::::1;18809:73;;;::::0;-1:-1:-1;;;18809:73:0;;19315:2:1;18809:73:0::1;::::0;::::1;19297:21:1::0;19354:2;19334:18;;;19327:30;19393:34;19373:18;;;19366:62;19464:8;19444:18;;;19437:36;19490:19;;18809:73:0::1;19113:402:1::0;18809:73:0::1;18893:28;18912:8;18893:18;:28::i;994:127::-:0;1083:19;;1101:1;1083:19;;;994:127::o;41669:305::-;41771:4;41808:40;;;41823:25;41808:40;;:105;;-1:-1:-1;41865:48:0;;;41880:33;41865:48;41808:105;:158;;;-1:-1:-1;33455:25:0;33440:40;;;;41930:36;33331:157;17987:132;17895:6;;-1:-1:-1;;;;;17895:6:0;16453:10;18051:23;18043:68;;;;-1:-1:-1;;;18043:68:0;;19722:2:1;18043:68:0;;;19704:21:1;;;19741:18;;;19734:30;19800:34;19780:18;;;19773:62;19852:18;;18043:68:0;19520:356:1;52084:135:0;47367:4;47391:16;;;:7;:16;;;;;;-1:-1:-1;;;;;47391:16:0;52158:53;;;;-1:-1:-1;;;52158:53:0;;17163:2:1;52158:53:0;;;17145:21:1;17202:2;17182:18;;;17175:30;17241:26;17221:18;;;17214:54;17285:18;;52158:53:0;16961:348:1;51363:174:0;51438:24;;;;:15;:24;;;;;:29;;;;-1:-1:-1;;;;;51438:29:0;;;;;;;;:24;;51492:23;51438:24;51492:14;:23::i;:::-;-1:-1:-1;;;;;51483:46:0;;;;;;;;;;;51363:174;;:::o;66066:200::-;66162:4;66203:55;66248:9;66203:36;:11;14581:58;;22440:66:1;14581:58:0;;;22428:79:1;22523:12;;;22516:28;;;14448:7:0;;22560:12:1;;14581:58:0;;;;;;;;;;;;14571:69;;;;;;14564:76;;14379:269;;;;66203:36;:44;;:55::i;:::-;66186:13;;-1:-1:-1;;;;;66186:72:0;;;:13;;:72;;66066:200;-1:-1:-1;;;66066:200:0:o;48202:110::-;48278:26;48288:2;48292:7;48278:26;;;;;;;;;;;;:9;:26::i;47596:264::-;47689:4;47706:13;47722:23;47737:7;47722:14;:23::i;:::-;47706:39;;47775:5;-1:-1:-1;;;;;47764:16:0;:7;-1:-1:-1;;;;;47764:16:0;;:52;;;-1:-1:-1;;;;;;44699:25:0;;;44675:4;44699:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;47784:32;47764:87;;;;47844:7;-1:-1:-1;;;;;47820:31:0;:20;47832:7;47820:11;:20::i;:::-;-1:-1:-1;;;;;47820:31:0;;47764:87;47756:96;47596:264;-1:-1:-1;;;;47596:264:0:o;50619:625::-;50778:4;-1:-1:-1;;;;;50751:31:0;:23;50766:7;50751:14;:23::i;:::-;-1:-1:-1;;;;;50751:31:0;;50743:81;;;;-1:-1:-1;;;50743:81:0;;20385:2:1;50743:81:0;;;20367:21:1;20424:2;20404:18;;;20397:30;20463:34;20443:18;;;20436:62;20534:7;20514:18;;;20507:35;20559:19;;50743:81:0;20183:401:1;50743:81:0;-1:-1:-1;;;;;50843:16:0;;50835:65;;;;-1:-1:-1;;;50835:65:0;;20791:2:1;50835:65:0;;;20773:21:1;20830:2;20810:18;;;20803:30;20869:34;20849:18;;;20842:62;20940:6;20920:18;;;20913:34;20964:19;;50835:65:0;20589:400:1;50835:65:0;50913:39;50934:4;50940:2;50944:7;50913:20;:39::i;:::-;51017:29;51034:1;51038:7;51017:8;:29::i;:::-;-1:-1:-1;;;;;51059:15:0;;;;;;:9;:15;;;;;:20;;51078:1;;51059:15;:20;;51078:1;;51059:20;:::i;:::-;;;;-1:-1:-1;;;;;;;51090:13:0;;;;;;:9;:13;;;;;:18;;51107:1;;51090:13;:18;;51107:1;;51090:18;:::i;:::-;;;;-1:-1:-1;;51119:16:0;;;;:7;:16;;;;;;:21;;;;-1:-1:-1;;;;;51119:21:0;;;;;;;;;51158:27;;51119:16;;51158:27;;;;;;;43696:347;43626:417;;:::o;21815:120::-;20824:16;:14;:16::i;:::-;21874:7:::1;:15:::0;;;::::1;::::0;;21905:22:::1;16453:10:::0;21914:12:::1;21905:22;::::0;-1:-1:-1;;;;;2194:55:1;;;2176:74;;2164:2;2149:18;21905:22:0::1;;;;;;;21815:120::o:0;19089:191::-;19182:6;;;-1:-1:-1;;;;;19199:17:0;;;;;;;;;;;19232:40;;19182:6;;;19199:17;19182:6;;19232:40;;19163:16;;19232:40;19152:128;19089:191;:::o;21556:118::-;20565:19;:17;:19::i;:::-;21616:7:::1;:14:::0;;;::::1;::::0;::::1;::::0;;21646:20:::1;21653:12;16453:10:::0;;16373:98;51680:315;51835:8;-1:-1:-1;;;;;51826:17:0;:5;-1:-1:-1;;;;;51826:17:0;;51818:55;;;;-1:-1:-1;;;51818:55:0;;21196:2:1;51818:55:0;;;21178:21:1;21235:2;21215:18;;;21208:30;21274:27;21254:18;;;21247:55;21319:18;;51818:55:0;20994:349:1;51818:55:0;-1:-1:-1;;;;;51884:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;;;;;;;;;;;;51946:41;;586::1;;;51946::0;;559:18:1;51946:41:0;;;;;;;51680:315;;;:::o;46676:313::-;46832:28;46842:4;46848:2;46852:7;46832:9;:28::i;:::-;46879:47;46902:4;46908:2;46912:7;46921:4;46879:22;:47::i;:::-;46871:110;;;;-1:-1:-1;;;46871:110:0;;21550:2:1;46871:110:0;;;21532:21:1;21589:2;21569:18;;;21562:30;21628:34;21608:18;;;21601:62;21699:20;21679:18;;;21672:48;21737:19;;46871:110:0;21348:414:1;63907:113:0;63967:13;64000:12;63993:19;;;;;:::i;4654:723::-;4710:13;4931:5;4940:1;4931:10;4927:53;;-1:-1:-1;;4958:10:0;;;;;;;;;;;;;;;;;;4654:723::o;4927:53::-;5005:5;4990:12;5046:78;5053:9;;5046:78;;5079:8;;;;:::i;:::-;;-1:-1:-1;5102:10:0;;-1:-1:-1;5110:2:0;5102:10;;:::i;:::-;;;5046:78;;;5134:19;5166:6;5156:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5156:17:0;;5134:39;;5184:154;5191:10;;5184:154;;5218:11;5228:1;5218:11;;:::i;:::-;;-1:-1:-1;5287:10:0;5295:2;5287:5;:10;:::i;:::-;5274:24;;:2;:24;:::i;:::-;5261:39;;5244:6;5251;5244:14;;;;;;;;:::i;:::-;;;;:56;;;;;;;;;;-1:-1:-1;5315:11:0;5324:2;5315:11;;:::i;:::-;;;5184:154;;10577:231;10655:7;10676:17;10695:18;10717:27;10728:4;10734:9;10717:10;:27::i;:::-;10675:69;;;;10755:18;10767:5;10755:11;:18::i;48539:319::-;48668:18;48674:2;48678:7;48668:5;:18::i;:::-;48719:53;48750:1;48754:2;48758:7;48767:4;48719:22;:53::i;:::-;48697:153;;;;-1:-1:-1;;;48697:153:0;;21550:2:1;48697:153:0;;;21532:21:1;21589:2;21569:18;;;21562:30;21628:34;21608:18;;;21601:62;21699:20;21679:18;;;21672:48;21737:19;;48697:153:0;21348:414:1;65855:203:0;20565:19;:17;:19::i;:::-;66005:45:::1;66032:4;66038:2;66042:7;66005:26;:45::i;21304:108::-:0;21031:7;;;;;;;21363:41;;;;-1:-1:-1;;;21363:41:0;;22785:2:1;21363:41:0;;;22767:21:1;22824:2;22804:18;;;22797:30;22863:22;22843:18;;;22836:50;22903:18;;21363:41:0;22583:344:1;21119:108:0;21031:7;;;;;;;21189:9;21181:38;;;;-1:-1:-1;;;21181:38:0;;23134:2:1;21181:38:0;;;23116:21:1;23173:2;23153:18;;;23146:30;23212:18;23192;;;23185:46;23248:18;;21181:38:0;22932:340:1;52783:853:0;52937:4;-1:-1:-1;;;;;52958:13:0;;23470:19;:23;52954:675;;52994:71;;;;;-1:-1:-1;;;;;52994:36:0;;;;;:71;;16453:10;;53045:4;;53051:7;;53060:4;;52994:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;52994:71:0;;;;;;;;-1:-1:-1;;52994:71:0;;;;;;;;;;;;:::i;:::-;;;52990:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53235:6;:13;53252:1;53235:18;53231:328;;53278:60;;-1:-1:-1;;;53278:60:0;;21550:2:1;53278:60:0;;;21532:21:1;21589:2;21569:18;;;21562:30;21628:34;21608:18;;;21601:62;21699:20;21679:18;;;21672:48;21737:19;;53278:60:0;21348:414:1;53231:328:0;53509:6;53503:13;53494:6;53490:2;53486:15;53479:38;52990:584;53116:51;;53126:41;53116:51;;-1:-1:-1;53109:58:0;;52954:675;-1:-1:-1;53613:4:0;52783:853;;;;;;:::o;9028:747::-;9109:7;9118:12;9147:9;:16;9167:2;9147:22;9143:625;;9491:4;9476:20;;9470:27;9541:4;9526:20;;9520:27;9599:4;9584:20;;9578:27;9186:9;9570:36;9642:25;9653:4;9570:36;9470:27;9520;9642:10;:25::i;:::-;9635:32;;;;;;;;;9143:625;-1:-1:-1;9716:1:0;;-1:-1:-1;9720:35:0;9143:625;9028:747;;;;;:::o;7299:643::-;7377:20;7368:5;:29;;;;;;;;:::i;:::-;;7364:571;;7299:643;:::o;7364:571::-;7475:29;7466:5;:38;;;;;;;;:::i;:::-;;7462:473;;7521:34;;-1:-1:-1;;;7521:34:0;;24439:2:1;7521:34:0;;;24421:21:1;24478:2;24458:18;;;24451:30;24517:26;24497:18;;;24490:54;24561:18;;7521:34:0;24237:348:1;7462:473:0;7586:35;7577:5;:44;;;;;;;;:::i;:::-;;7573:362;;7638:41;;-1:-1:-1;;;7638:41:0;;24792:2:1;7638:41:0;;;24774:21:1;24831:2;24811:18;;;24804:30;24870:33;24850:18;;;24843:61;24921:18;;7638:41:0;24590:355:1;7573:362:0;7710:30;7701:5;:39;;;;;;;;:::i;:::-;;7697:238;;7757:44;;-1:-1:-1;;;7757:44:0;;25152:2:1;7757:44:0;;;25134:21:1;25191:2;25171:18;;;25164:30;25230:34;25210:18;;;25203:62;25301:4;25281:18;;;25274:32;25323:19;;7757:44:0;24950:398:1;7697:238:0;7832:30;7823:5;:39;;;;;;;;:::i;:::-;;7819:116;;7879:44;;-1:-1:-1;;;7879:44:0;;25555:2:1;7879:44:0;;;25537:21:1;25594:2;25574:18;;;25567:30;25633:34;25613:18;;;25606:62;25704:4;25684:18;;;25677:32;25726:19;;7879:44:0;25353:398:1;49194:439:0;-1:-1:-1;;;;;49274:16:0;;49266:61;;;;-1:-1:-1;;;49266:61:0;;25958:2:1;49266:61:0;;;25940:21:1;;;25977:18;;;25970:30;26036:34;26016:18;;;26009:62;26088:18;;49266:61:0;25756:356:1;49266:61:0;47367:4;47391:16;;;:7;:16;;;;;;-1:-1:-1;;;;;47391:16:0;:30;49338:58;;;;-1:-1:-1;;;49338:58:0;;26319:2:1;49338:58:0;;;26301:21:1;26358:2;26338:18;;;26331:30;26397;26377:18;;;26370:58;26445:18;;49338:58:0;26117:352:1;49338:58:0;49409:45;49438:1;49442:2;49446:7;49409:20;:45::i;:::-;-1:-1:-1;;;;;49467:13:0;;;;;;:9;:13;;;;;:18;;49484:1;;49467:13;:18;;49484:1;;49467:18;:::i;:::-;;;;-1:-1:-1;;49496:16:0;;;;:7;:16;;;;;;:21;;;;-1:-1:-1;;;;;49496:21:0;;;;;;;;49535:33;;49496:16;;;49535:33;;49496:16;;49535:33;44352:155;;:::o;57538:589::-;-1:-1:-1;;;;;57744:18:0;;57740:187;;57779:40;57811:7;58954:10;:17;;58927:24;;;;:15;:24;;;;;:44;;;58982:24;;;;;;;;;;;;58850:164;57779:40;57740:187;;;57849:2;-1:-1:-1;;;;;57841:10:0;:4;-1:-1:-1;;;;;57841:10:0;;57837:90;;57868:47;57901:4;57907:7;57868:32;:47::i;:::-;-1:-1:-1;;;;;57941:16:0;;57937:183;;57974:45;58011:7;57974:36;:45::i;57937:183::-;58047:4;-1:-1:-1;;;;;58041:10:0;:2;-1:-1:-1;;;;;58041:10:0;;58037:83;;58068:40;58096:2;58100:7;58068:27;:40::i;12029:1632::-;12160:7;;13094:66;13081:79;;13077:163;;;-1:-1:-1;13193:1:0;;-1:-1:-1;13197:30:0;13177:51;;13077:163;13254:1;:7;;13259:2;13254:7;;:18;;;;;13265:1;:7;;13270:2;13265:7;;13254:18;13250:102;;;-1:-1:-1;13305:1:0;;-1:-1:-1;13309:30:0;13289:51;;13250:102;13466:24;;;13449:14;13466:24;;;;;;;;;26701:25:1;;;26774:4;26762:17;;26742:18;;;26735:45;;;;26796:18;;;26789:34;;;26839:18;;;26832:34;;;13466:24:0;;26673:19:1;;13466:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;13466:24:0;;-1:-1:-1;;13466:24:0;;;-1:-1:-1;;;;;;;13505:20:0;;13501:103;;13558:1;13562:29;13542:50;;;;;;;13501:103;13624:6;-1:-1:-1;13632:20:0;;-1:-1:-1;12029:1632:0;;;;;;;;:::o;59641:988::-;59907:22;59957:1;59932:22;59949:4;59932:16;:22::i;:::-;:26;;;;:::i;:::-;59969:18;59990:26;;;:17;:26;;;;;;59907:51;;-1:-1:-1;60123:28:0;;;60119:328;;-1:-1:-1;;;;;60190:18:0;;60168:19;60190:18;;;:12;:18;;;;;;;;:34;;;;;;;;;60241:30;;;;;;:44;;;60358:30;;:17;:30;;;;;:43;;;60119:328;-1:-1:-1;60543:26:0;;;;:17;:26;;;;;;;;60536:33;;;-1:-1:-1;;;;;60587:18:0;;;;;:12;:18;;;;;:34;;;;;;;60580:41;59641:988::o;60924:1079::-;61202:10;:17;61177:22;;61202:21;;61222:1;;61202:21;:::i;:::-;61234:18;61255:24;;;:15;:24;;;;;;61628:10;:26;;61177:46;;-1:-1:-1;61255:24:0;;61177:46;;61628:26;;;;;;:::i;:::-;;;;;;;;;61606:48;;61692:11;61667:10;61678;61667:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;61772:28;;;:15;:28;;;;;;;:41;;;61944:24;;;;;61937:31;61979:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;60995:1008;;;60924:1079;:::o;58428:221::-;58513:14;58530:20;58547:2;58530:16;:20::i;:::-;-1:-1:-1;;;;;58561:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;58606:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;58428:221:0:o;14:177:1:-;99:66;92:5;88:78;81:5;78:89;68:117;;181:1;178;171:12;196:245;254:6;307:2;295:9;286:7;282:23;278:32;275:52;;;323:1;320;313:12;275:52;362:9;349:23;381:30;405:5;381:30;:::i;:::-;430:5;196:245;-1:-1:-1;;;196:245:1:o;638:196::-;706:20;;-1:-1:-1;;;;;755:54:1;;745:65;;735:93;;824:1;821;814:12;735:93;638:196;;;:::o;839:186::-;898:6;951:2;939:9;930:7;926:23;922:32;919:52;;;967:1;964;957:12;919:52;990:29;1009:9;990:29;:::i;1030:250::-;1115:1;1125:113;1139:6;1136:1;1133:13;1125:113;;;1215:11;;;1209:18;1196:11;;;1189:39;1161:2;1154:10;1125:113;;;-1:-1:-1;;1272:1:1;1254:16;;1247:27;1030:250::o;1285:330::-;1327:3;1365:5;1359:12;1392:6;1387:3;1380:19;1408:76;1477:6;1470:4;1465:3;1461:14;1454:4;1447:5;1443:16;1408:76;:::i;:::-;1529:2;1517:15;-1:-1:-1;;1513:88:1;1504:98;;;;1604:4;1500:109;;1285:330;-1:-1:-1;;1285:330:1:o;1620:220::-;1769:2;1758:9;1751:21;1732:4;1789:45;1830:2;1819:9;1815:18;1807:6;1789:45;:::i;1845:180::-;1904:6;1957:2;1945:9;1936:7;1932:23;1928:32;1925:52;;;1973:1;1970;1963:12;1925:52;-1:-1:-1;1996:23:1;;1845:180;-1:-1:-1;1845:180:1:o;2261:254::-;2329:6;2337;2390:2;2378:9;2369:7;2365:23;2361:32;2358:52;;;2406:1;2403;2396:12;2358:52;2429:29;2448:9;2429:29;:::i;:::-;2419:39;2505:2;2490:18;;;;2477:32;;-1:-1:-1;;;2261:254:1:o;2702:347::-;2753:8;2763:6;2817:3;2810:4;2802:6;2798:17;2794:27;2784:55;;2835:1;2832;2825:12;2784:55;-1:-1:-1;2858:20:1;;2901:18;2890:30;;2887:50;;;2933:1;2930;2923:12;2887:50;2970:4;2962:6;2958:17;2946:29;;3022:3;3015:4;3006:6;2998;2994:19;2990:30;2987:39;2984:59;;;3039:1;3036;3029:12;3054:683;3160:6;3168;3176;3184;3192;3200;3253:3;3241:9;3232:7;3228:23;3224:33;3221:53;;;3270:1;3267;3260:12;3221:53;3306:9;3293:23;3283:33;;3367:2;3356:9;3352:18;3339:32;3394:18;3386:6;3383:30;3380:50;;;3426:1;3423;3416:12;3380:50;3465:58;3515:7;3506:6;3495:9;3491:22;3465:58;:::i;:::-;3054:683;;3542:8;;-1:-1:-1;3439:84:1;;3624:2;3609:18;;3596:32;;3675:2;3660:18;;3647:32;;-1:-1:-1;3726:3:1;3711:19;;;3698:33;;-1:-1:-1;3054:683:1;-1:-1:-1;;;;3054:683:1:o;3742:328::-;3819:6;3827;3835;3888:2;3876:9;3867:7;3863:23;3859:32;3856:52;;;3904:1;3901;3894:12;3856:52;3927:29;3946:9;3927:29;:::i;:::-;3917:39;;3975:38;4009:2;3998:9;3994:18;3975:38;:::i;:::-;3965:48;;4060:2;4049:9;4045:18;4032:32;4022:42;;3742:328;;;;;:::o;4075:410::-;4146:6;4154;4207:2;4195:9;4186:7;4182:23;4178:32;4175:52;;;4223:1;4220;4213:12;4175:52;4263:9;4250:23;4296:18;4288:6;4285:30;4282:50;;;4328:1;4325;4318:12;4282:50;4367:58;4417:7;4408:6;4397:9;4393:22;4367:58;:::i;:::-;4444:8;;4341:84;;-1:-1:-1;4075:410:1;-1:-1:-1;;;;4075:410:1:o;4490:160::-;4555:20;;4611:13;;4604:21;4594:32;;4584:60;;4640:1;4637;4630:12;4655:180;4711:6;4764:2;4752:9;4743:7;4739:23;4735:32;4732:52;;;4780:1;4777;4770:12;4732:52;4803:26;4819:9;4803:26;:::i;4840:248::-;4908:6;4916;4969:2;4957:9;4948:7;4944:23;4940:32;4937:52;;;4985:1;4982;4975:12;4937:52;-1:-1:-1;;5008:23:1;;;5078:2;5063:18;;;5050:32;;-1:-1:-1;4840:248:1:o;5093:254::-;5158:6;5166;5219:2;5207:9;5198:7;5194:23;5190:32;5187:52;;;5235:1;5232;5225:12;5187:52;5258:29;5277:9;5258:29;:::i;:::-;5248:39;;5306:35;5337:2;5326:9;5322:18;5306:35;:::i;:::-;5296:45;;5093:254;;;;;:::o;5352:184::-;5404:77;5401:1;5394:88;5501:4;5498:1;5491:15;5525:4;5522:1;5515:15;5541:1197;5636:6;5644;5652;5660;5713:3;5701:9;5692:7;5688:23;5684:33;5681:53;;;5730:1;5727;5720:12;5681:53;5753:29;5772:9;5753:29;:::i;:::-;5743:39;;5801:38;5835:2;5824:9;5820:18;5801:38;:::i;:::-;5791:48;;5886:2;5875:9;5871:18;5858:32;5848:42;;5941:2;5930:9;5926:18;5913:32;5964:18;6005:2;5997:6;5994:14;5991:34;;;6021:1;6018;6011:12;5991:34;6059:6;6048:9;6044:22;6034:32;;6104:7;6097:4;6093:2;6089:13;6085:27;6075:55;;6126:1;6123;6116:12;6075:55;6162:2;6149:16;6184:2;6180;6177:10;6174:36;;;6190:18;;:::i;:::-;6324:2;6318:9;6386:4;6378:13;;-1:-1:-1;;6374:22:1;;;6398:2;6370:31;6366:40;6354:53;;;6422:18;;;6442:22;;;6419:46;6416:72;;;6468:18;;:::i;:::-;6508:10;6504:2;6497:22;6543:2;6535:6;6528:18;6583:7;6578:2;6573;6569;6565:11;6561:20;6558:33;6555:53;;;6604:1;6601;6594:12;6555:53;6660:2;6655;6651;6647:11;6642:2;6634:6;6630:15;6617:46;6705:1;6700:2;6695;6687:6;6683:15;6679:24;6672:35;6726:6;6716:16;;;;;;;5541:1197;;;;;;;:::o;6743:689::-;6838:6;6846;6854;6907:2;6895:9;6886:7;6882:23;6878:32;6875:52;;;6923:1;6920;6913:12;6875:52;6963:9;6950:23;6992:18;7033:2;7025:6;7022:14;7019:34;;;7049:1;7046;7039:12;7019:34;7087:6;7076:9;7072:22;7062:32;;7132:7;7125:4;7121:2;7117:13;7113:27;7103:55;;7154:1;7151;7144:12;7103:55;7194:2;7181:16;7220:2;7212:6;7209:14;7206:34;;;7236:1;7233;7226:12;7206:34;7291:7;7284:4;7274:6;7271:1;7267:14;7263:2;7259:23;7255:34;7252:47;7249:67;;;7312:1;7309;7302:12;7249:67;7343:4;7335:13;;;;7367:6;;-1:-1:-1;7405:20:1;;;;7392:34;;6743:689;-1:-1:-1;;;;6743:689:1:o;7437:632::-;7608:2;7660:21;;;7730:13;;7633:18;;;7752:22;;;7579:4;;7608:2;7831:15;;;;7805:2;7790:18;;;7579:4;7874:169;7888:6;7885:1;7882:13;7874:169;;;7949:13;;7937:26;;8018:15;;;;7983:12;;;;7910:1;7903:9;7874:169;;;-1:-1:-1;8060:3:1;;7437:632;-1:-1:-1;;;;;;7437:632:1:o;8074:260::-;8142:6;8150;8203:2;8191:9;8182:7;8178:23;8174:32;8171:52;;;8219:1;8216;8209:12;8171:52;8242:29;8261:9;8242:29;:::i;:::-;8232:39;;8290:38;8324:2;8313:9;8309:18;8290:38;:::i;8339:437::-;8418:1;8414:12;;;;8461;;;8482:61;;8536:4;8528:6;8524:17;8514:27;;8482:61;8589:2;8581:6;8578:14;8558:18;8555:38;8552:218;;8626:77;8623:1;8616:88;8727:4;8724:1;8717:15;8755:4;8752:1;8745:15;8552:218;;8339:437;;;:::o;10321:184::-;10373:77;10370:1;10363:88;10470:4;10467:1;10460:15;10494:4;10491:1;10484:15;10510:125;10575:9;;;10596:10;;;10593:36;;;10609:18;;:::i;12032:228::-;12072:7;12198:1;12130:66;12126:74;12123:1;12120:81;12115:1;12108:9;12101:17;12097:105;12094:131;;;12205:18;;:::i;:::-;-1:-1:-1;12245:9:1;;12032:228::o;12265:128::-;12332:9;;;12353:11;;;12350:37;;;12367:18;;:::i;13095:195::-;13134:3;13165:66;13158:5;13155:77;13152:103;;13235:18;;:::i;:::-;-1:-1:-1;13282:1:1;13271:13;;13095:195::o;14535:184::-;14587:77;14584:1;14577:88;14684:4;14681:1;14674:15;14708:4;14705:1;14698:15;14850:545;14952:2;14947:3;14944:11;14941:448;;;14988:1;15013:5;15009:2;15002:17;15058:4;15054:2;15044:19;15128:2;15116:10;15112:19;15109:1;15105:27;15099:4;15095:38;15164:4;15152:10;15149:20;15146:47;;;-1:-1:-1;15187:4:1;15146:47;15242:2;15237:3;15233:12;15230:1;15226:20;15220:4;15216:31;15206:41;;15297:82;15315:2;15308:5;15305:13;15297:82;;;15360:17;;;15341:1;15330:13;15297:82;;;15301:3;;;14850:545;;;:::o;15631:1325::-;15755:18;15750:3;15747:27;15744:53;;;15777:18;;:::i;:::-;15806:94;15896:3;15856:38;15888:4;15882:11;15856:38;:::i;:::-;15850:4;15806:94;:::i;:::-;15926:1;15951:2;15946:3;15943:11;15968:1;15963:735;;;;16742:1;16759:3;16756:93;;;-1:-1:-1;16815:19:1;;;16802:33;16756:93;15537:66;15528:1;15524:11;;;15520:84;15516:89;15506:100;15612:1;15608:11;;;15503:117;16862:78;;15936:1014;;15963:735;14797:1;14790:14;;;14834:4;14821:18;;-1:-1:-1;;15999:76:1;;;16159:9;16181:229;16195:7;16192:1;16189:14;16181:229;;;16284:19;;;16271:33;16256:49;;16391:4;16376:20;;;;16344:1;16332:14;;;;16211:12;16181:229;;;16185:3;16438;16429:7;16426:16;16423:219;;;16558:66;16552:3;16546;16543:1;16539:11;16535:21;16531:94;16527:99;16514:9;16509:3;16505:19;16492:33;16488:139;16480:6;16473:155;16423:219;;;16685:1;16679:3;16676:1;16672:11;16668:19;16662:4;16655:33;15936:1014;;;15631:1325;;;:::o;18445:663::-;18725:3;18763:6;18757:13;18779:66;18838:6;18833:3;18826:4;18818:6;18814:17;18779:66;:::i;:::-;18908:13;;18867:16;;;;18930:70;18908:13;18867:16;18977:4;18965:17;;18930:70;:::i;:::-;19065:7;19022:20;;19051:22;;;19100:1;19089:13;;18445:663;-1:-1:-1;;;;18445:663:1:o;21767:184::-;21819:77;21816:1;21809:88;21916:4;21913:1;21906:15;21940:4;21937:1;21930:15;21956:120;21996:1;22022;22012:35;;22027:18;;:::i;:::-;-1:-1:-1;22061:9:1;;21956:120::o;22081:112::-;22113:1;22139;22129:35;;22144:18;;:::i;:::-;-1:-1:-1;22178:9:1;;22081:112::o;23277:512::-;23471:4;-1:-1:-1;;;;;23581:2:1;23573:6;23569:15;23558:9;23551:34;23633:2;23625:6;23621:15;23616:2;23605:9;23601:18;23594:43;;23673:6;23668:2;23657:9;23653:18;23646:34;23716:3;23711:2;23700:9;23696:18;23689:31;23737:46;23778:3;23767:9;23763:19;23755:6;23737:46;:::i;:::-;23729:54;23277:512;-1:-1:-1;;;;;;23277:512:1:o;23794:249::-;23863:6;23916:2;23904:9;23895:7;23891:23;23887:32;23884:52;;;23932:1;23929;23922:12;23884:52;23964:9;23958:16;23983:30;24007:5;23983:30;:::i;24048:184::-;24100:77;24097:1;24090:88;24197:4;24194:1;24187:15;24221:4;24218:1;24211:15;26877:184;26929:77;26926:1;26919:88;27026:4;27023:1;27016:15;27050:4;27047:1;27040:15

Swarm Source

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