ETH Price: $2,554.74 (-2.24%)

Token

DraculaKEY (KEY)
 

Overview

Max Total Supply

247 KEY

Holders

58

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
1 KEY
0x6af2a1d682facc7be94ed27b1479ebddd392c03f
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:
DraculaKEY

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-04-21
*/

// 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 v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

        return (signer, RecoverError.NoError);
    }

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

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

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

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

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


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

pragma solidity ^0.8.0;

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;


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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

// File: contracts/ERC721A.sol


// Creator: Chiru Labs

pragma solidity ^0.8.4;








error ApprovalCallerNotOwnerNorApproved();
error ApprovalQueryForNonexistentToken();
error ApproveToCaller();
error ApprovalToCurrentOwner();
error BalanceQueryForZeroAddress();
error MintToZeroAddress();
error MintZeroQuantity();
error OwnerQueryForNonexistentToken();
error TransferCallerNotOwnerNorApproved();
error TransferFromIncorrectOwner();
error TransferToNonERC721ReceiverImplementer();
error TransferToZeroAddress();
error URIQueryForNonexistentToken();

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return uint256(_addressData[owner].balance);
    }

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

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

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

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

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

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public override {
        address owner = ERC721A.ownerOf(tokenId);
        if (to == owner) revert ApprovalToCurrentOwner();

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

        _approve(to, tokenId, owner);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

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

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

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        _transfer(from, to, tokenId);
        if (to.isContract() && !_checkContractOnERC721Received(from, to, tokenId, _data)) {
            revert TransferToNonERC721ReceiverImplementer();
        }
    }

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

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, '');
    }

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

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

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

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

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

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

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

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

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

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

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

            do {
                emit Transfer(address(0), to, updatedIndex++);
            } while (updatedIndex != end);

            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) private {
        TokenOwnership memory prevOwnership = _ownershipOf(tokenId);

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

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

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

        _beforeTokenTransfers(from, to, tokenId, 1);

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

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

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

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

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

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

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

        address from = prevOwnership.addr;

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

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

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

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

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

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

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

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

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

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

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

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

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



pragma solidity ^0.8.0;








contract DraculaKEY is ERC721A, Ownable, ReentrancyGuard {
	using Address for address;
	using Strings for uint256;
    using ECDSA for bytes32;

	uint64 public _maxSupply = 8888;
    address private signer;
    string public metadataIpfsCid;
    mapping(address => uint256) public mintRecord;

	constructor() ERC721A("DraculaKEY", "KEY") {
	}


    function setMetadataIpfsCid(string calldata _metadataIpfsCid) external onlyOwner {
        metadataIpfsCid = _metadataIpfsCid;
    }


    function setSigner(address _signer) external onlyOwner {
        signer = _signer;
    }


    function mint(uint256 quantity, uint32 _maxTimestamp, uint maxMints, bytes calldata _signature) external payable nonReentrant {
        require(verifyOwnerSignature(keccak256(abi.encode(address(this), msg.sender, _maxTimestamp, maxMints, quantity, msg.value)), _signature), "Invalid signature");
        require(msg.sender == tx.origin, "Claim from wallet only");
        require(block.timestamp <= _maxTimestamp, "Signature expired");
        require(mintRecord[msg.sender] + quantity <= maxMints, "Exceeds the maximum number of coins that an individual can mint");
        require(totalSupply() + quantity <= _maxSupply, "Maximum supply exceeded");
        mintRecord[msg.sender] = mintRecord[msg.sender] + quantity;
        _safeMint(msg.sender, quantity);
    }

	function withdraw() public onlyOwner {
        Address.sendValue(payable(msg.sender), address(this).balance);
    }
    

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
        return string(abi.encodePacked("ipfs://", metadataIpfsCid, "/", tokenId.toString(), ".json"));
        
    }


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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"_maxSupply","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metadataIpfsCid","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint32","name":"_maxTimestamp","type":"uint32"},{"internalType":"uint256","name":"maxMints","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintRecord","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"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":"_metadataIpfsCid","type":"string"}],"name":"setMetadataIpfsCid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"setSigner","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":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526122b8600a60006101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055503480156200003c57600080fd5b506040518060400160405280600a81526020017f44726163756c614b4559000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f4b455900000000000000000000000000000000000000000000000000000000008152508160029080519060200190620000c1929190620001f4565b508060039080519060200190620000da929190620001f4565b50620000eb6200012160201b60201c565b600081905550505062000113620001076200012660201b60201c565b6200012e60201b60201c565b600160098190555062000308565b600090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8280546200020290620002d3565b90600052602060002090601f01602090048101928262000226576000855562000272565b82601f106200024157805160ff191683800117855562000272565b8280016001018555821562000272579182015b828111156200027157825182559160200191906001019062000254565b5b50905062000281919062000285565b5090565b5b80821115620002a057600081600090555060010162000286565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620002ec57607f821691505b602082108103620003025762000301620002a4565b5b50919050565b6141b980620003186000396000f3fe60806040526004361061014b5760003560e01c80636c19e783116100b6578063a22cb4651161006f578063a22cb4651461047e578063b88d4fde146104a7578063c2120363146104d0578063c87b56dd146104ec578063e985e9c514610529578063f2fde38b146105665761014b565b80636c19e7831461038057806370a08231146103a9578063715018a6146103e65780638da5cb5b146103fd57806395d89b411461042857806395e34e86146104535761014b565b806322f4596f1161010857806322f4596f1461027257806323b872dd1461029d5780633074d754146102c65780633ccfd60b1461030357806342842e0e1461031a5780636352211e146103435761014b565b806301ffc9a71461015057806306fdde031461018d578063081812fc146101b8578063095ea7b3146101f557806318160ddd1461021e5780631986651714610249575b600080fd5b34801561015c57600080fd5b5061017760048036038101906101729190612c00565b61058f565b6040516101849190612c48565b60405180910390f35b34801561019957600080fd5b506101a2610671565b6040516101af9190612cfc565b60405180910390f35b3480156101c457600080fd5b506101df60048036038101906101da9190612d54565b610703565b6040516101ec9190612dc2565b60405180910390f35b34801561020157600080fd5b5061021c60048036038101906102179190612e09565b61077f565b005b34801561022a57600080fd5b50610233610889565b6040516102409190612e58565b60405180910390f35b34801561025557600080fd5b50610270600480360381019061026b9190612ed8565b6108a0565b005b34801561027e57600080fd5b50610287610932565b6040516102949190612f48565b60405180910390f35b3480156102a957600080fd5b506102c460048036038101906102bf9190612f63565b61094c565b005b3480156102d257600080fd5b506102ed60048036038101906102e89190612fb6565b61095c565b6040516102fa9190612e58565b60405180910390f35b34801561030f57600080fd5b50610318610974565b005b34801561032657600080fd5b50610341600480360381019061033c9190612f63565b6109fc565b005b34801561034f57600080fd5b5061036a60048036038101906103659190612d54565b610a1c565b6040516103779190612dc2565b60405180910390f35b34801561038c57600080fd5b506103a760048036038101906103a29190612fb6565b610a32565b005b3480156103b557600080fd5b506103d060048036038101906103cb9190612fb6565b610af2565b6040516103dd9190612e58565b60405180910390f35b3480156103f257600080fd5b506103fb610bc1565b005b34801561040957600080fd5b50610412610c49565b60405161041f9190612dc2565b60405180910390f35b34801561043457600080fd5b5061043d610c73565b60405161044a9190612cfc565b60405180910390f35b34801561045f57600080fd5b50610468610d05565b6040516104759190612cfc565b60405180910390f35b34801561048a57600080fd5b506104a560048036038101906104a0919061300f565b610d93565b005b3480156104b357600080fd5b506104ce60048036038101906104c9919061317f565b610f0a565b005b6104ea60048036038101906104e59190613294565b610f86565b005b3480156104f857600080fd5b50610513600480360381019061050e9190612d54565b6112ad565b6040516105209190612cfc565b60405180910390f35b34801561053557600080fd5b50610550600480360381019061054b919061331c565b611329565b60405161055d9190612c48565b60405180910390f35b34801561057257600080fd5b5061058d60048036038101906105889190612fb6565b6113bd565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061065a57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061066a5750610669826114b4565b5b9050919050565b6060600280546106809061338b565b80601f01602080910402602001604051908101604052809291908181526020018280546106ac9061338b565b80156106f95780601f106106ce576101008083540402835291602001916106f9565b820191906000526020600020905b8154815290600101906020018083116106dc57829003601f168201915b5050505050905090565b600061070e8261151e565b610744576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061078a82610a1c565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036107f1576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661081061156c565b73ffffffffffffffffffffffffffffffffffffffff161415801561084257506108408161083b61156c565b611329565b155b15610879576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610884838383611574565b505050565b6000610893611626565b6001546000540303905090565b6108a861156c565b73ffffffffffffffffffffffffffffffffffffffff166108c6610c49565b73ffffffffffffffffffffffffffffffffffffffff161461091c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091390613408565b60405180910390fd5b8181600b919061092d929190612aae565b505050565b600a60009054906101000a900467ffffffffffffffff1681565b61095783838361162b565b505050565b600c6020528060005260406000206000915090505481565b61097c61156c565b73ffffffffffffffffffffffffffffffffffffffff1661099a610c49565b73ffffffffffffffffffffffffffffffffffffffff16146109f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e790613408565b60405180910390fd5b6109fa3347611adf565b565b610a1783838360405180602001604052806000815250610f0a565b505050565b6000610a2782611bd3565b600001519050919050565b610a3a61156c565b73ffffffffffffffffffffffffffffffffffffffff16610a58610c49565b73ffffffffffffffffffffffffffffffffffffffff1614610aae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa590613408565b60405180910390fd5b80600a60086101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610b59576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b610bc961156c565b73ffffffffffffffffffffffffffffffffffffffff16610be7610c49565b73ffffffffffffffffffffffffffffffffffffffff1614610c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3490613408565b60405180910390fd5b610c476000611e62565b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054610c829061338b565b80601f0160208091040260200160405190810160405280929190818152602001828054610cae9061338b565b8015610cfb5780601f10610cd057610100808354040283529160200191610cfb565b820191906000526020600020905b815481529060010190602001808311610cde57829003601f168201915b5050505050905090565b600b8054610d129061338b565b80601f0160208091040260200160405190810160405280929190818152602001828054610d3e9061338b565b8015610d8b5780601f10610d6057610100808354040283529160200191610d8b565b820191906000526020600020905b815481529060010190602001808311610d6e57829003601f168201915b505050505081565b610d9b61156c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610dff576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060076000610e0c61156c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16610eb961156c565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610efe9190612c48565b60405180910390a35050565b610f1584848461162b565b610f348373ffffffffffffffffffffffffffffffffffffffff16611f28565b8015610f495750610f4784848484611f4b565b155b15610f80576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b600260095403610fcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fc290613474565b60405180910390fd5b600260098190555061100e303386868934604051602001610ff1969594939291906134a3565b60405160208183030381529060405280519060200120838361209b565b61104d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104490613550565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b2906135bc565b60405180910390fd5b8363ffffffff16421115611104576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110fb90613628565b60405180910390fd5b8285600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546111509190613677565b1115611191576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111889061373f565b60405180910390fd5b600a60009054906101000a900467ffffffffffffffff1667ffffffffffffffff16856111bb610889565b6111c59190613677565b1115611206576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111fd906137ab565b60405180910390fd5b84600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546112519190613677565b600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061129e3386612155565b60016009819055505050505050565b60606112b88261151e565b6112f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ee9061383d565b60405180910390fd5b600b61130283612173565b604051602001611313929190613a11565b6040516020818303038152906040529050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6113c561156c565b73ffffffffffffffffffffffffffffffffffffffff166113e3610c49565b73ffffffffffffffffffffffffffffffffffffffff1614611439576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143090613408565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149f90613ac8565b60405180910390fd5b6114b181611e62565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600081611529611626565b11158015611538575060005482105b8015611565575060046000838152602001908152602001600020600001601c9054906101000a900460ff16155b9050919050565b600033905090565b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600090565b600061163682611bd3565b90508373ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16146116a1576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff166116c261156c565b73ffffffffffffffffffffffffffffffffffffffff1614806116f157506116f0856116eb61156c565b611329565b5b8061173657506116ff61156c565b73ffffffffffffffffffffffffffffffffffffffff1661171e84610703565b73ffffffffffffffffffffffffffffffffffffffff16145b90508061176f576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036117d5576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6117e285858560016122d3565b6117ee60008487611574565b6001600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160392506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600460008581526020019081526020016000209050848160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550428160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060006001850190506000600460008381526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603611a6d576000548214611a6c57878160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084602001518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b505050828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611ad885858560016122d9565b5050505050565b80471015611b22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1990613b34565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff1682604051611b4890613b85565b60006040518083038185875af1925050503d8060008114611b85576040519150601f19603f3d011682016040523d82523d6000602084013e611b8a565b606091505b5050905080611bce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bc590613c0c565b60405180910390fd5b505050565b611bdb612b34565b600082905080611be9611626565b11158015611bf8575060005481105b15611e2b576000600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff16151515158152505090508060400151611e2957600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614611d0d578092505050611e5d565b5b600115611e2857818060019003925050600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614611e23578092505050611e5d565b611d0e565b5b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611f7161156c565b8786866040518563ffffffff1660e01b8152600401611f939493929190613c81565b6020604051808303816000875af1925050508015611fcf57506040513d601f19601f82011682018060405250810190611fcc9190613ce2565b60015b612048573d8060008114611fff576040519150601f19603f3d011682016040523d82523d6000602084013e612004565b606091505b506000815103612040576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6000600a60089054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661213584848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612127876122df565b61230f90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff161490509392505050565b61216f828260405180602001604052806000815250612336565b5050565b6060600082036121ba576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506122ce565b600082905060005b600082146121ec5780806121d590613d0f565b915050600a826121e59190613d86565b91506121c2565b60008167ffffffffffffffff81111561220857612207613054565b5b6040519080825280601f01601f19166020018201604052801561223a5781602001600182028036833780820191505090505b5090505b600085146122c7576001826122539190613db7565b9150600a856122629190613deb565b603061226e9190613677565b60f81b81838151811061228457612283613e1c565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856122c09190613d86565b945061223e565b8093505050505b919050565b50505050565b50505050565b6000816040516020016122f29190613ec2565b604051602081830303815290604052805190602001209050919050565b600080600061231e85856126f6565b9150915061232b81612777565b819250505092915050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036123a2576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083036123dc576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123e960008583866122d3565b82600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555082600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550836004600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426004600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000819050600084820190506125aa8673ffffffffffffffffffffffffffffffffffffffff16611f28565b1561266f575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461261f6000878480600101955087611f4b565b612655576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8082036125b057826000541461266a57600080fd5b6126da565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808203612670575b8160008190555050506126f060008583866122d9565b50505050565b60008060418351036127375760008060006020860151925060408601519150606086015160001a905061272b87828585612943565b94509450505050612770565b604083510361276757600080602085015191506040850151905061275c868383612a4f565b935093505050612770565b60006002915091505b9250929050565b6000600481111561278b5761278a613ee8565b5b81600481111561279e5761279d613ee8565b5b031561294057600160048111156127b8576127b7613ee8565b5b8160048111156127cb576127ca613ee8565b5b0361280b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161280290613f63565b60405180910390fd5b6002600481111561281f5761281e613ee8565b5b81600481111561283257612831613ee8565b5b03612872576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161286990613fcf565b60405180910390fd5b6003600481111561288657612885613ee8565b5b81600481111561289957612898613ee8565b5b036128d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128d090614061565b60405180910390fd5b6004808111156128ec576128eb613ee8565b5b8160048111156128ff576128fe613ee8565b5b0361293f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612936906140f3565b60405180910390fd5b5b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c111561297e576000600391509150612a46565b601b8560ff16141580156129965750601c8560ff1614155b156129a8576000600491509150612a46565b6000600187878787604051600081526020016040526040516129cd949392919061413e565b6020604051602081039080840390855afa1580156129ef573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612a3d57600060019250925050612a46565b80600092509250505b94509492505050565b60008060007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60001b841690506000601b60ff8660001c901c612a929190613677565b9050612aa087828885612943565b935093505050935093915050565b828054612aba9061338b565b90600052602060002090601f016020900481019282612adc5760008555612b23565b82601f10612af557803560ff1916838001178555612b23565b82800160010185558215612b23579182015b82811115612b22578235825591602001919060010190612b07565b5b509050612b309190612b77565b5090565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681526020016000151581525090565b5b80821115612b90576000816000905550600101612b78565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612bdd81612ba8565b8114612be857600080fd5b50565b600081359050612bfa81612bd4565b92915050565b600060208284031215612c1657612c15612b9e565b5b6000612c2484828501612beb565b91505092915050565b60008115159050919050565b612c4281612c2d565b82525050565b6000602082019050612c5d6000830184612c39565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612c9d578082015181840152602081019050612c82565b83811115612cac576000848401525b50505050565b6000601f19601f8301169050919050565b6000612cce82612c63565b612cd88185612c6e565b9350612ce8818560208601612c7f565b612cf181612cb2565b840191505092915050565b60006020820190508181036000830152612d168184612cc3565b905092915050565b6000819050919050565b612d3181612d1e565b8114612d3c57600080fd5b50565b600081359050612d4e81612d28565b92915050565b600060208284031215612d6a57612d69612b9e565b5b6000612d7884828501612d3f565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612dac82612d81565b9050919050565b612dbc81612da1565b82525050565b6000602082019050612dd76000830184612db3565b92915050565b612de681612da1565b8114612df157600080fd5b50565b600081359050612e0381612ddd565b92915050565b60008060408385031215612e2057612e1f612b9e565b5b6000612e2e85828601612df4565b9250506020612e3f85828601612d3f565b9150509250929050565b612e5281612d1e565b82525050565b6000602082019050612e6d6000830184612e49565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112612e9857612e97612e73565b5b8235905067ffffffffffffffff811115612eb557612eb4612e78565b5b602083019150836001820283011115612ed157612ed0612e7d565b5b9250929050565b60008060208385031215612eef57612eee612b9e565b5b600083013567ffffffffffffffff811115612f0d57612f0c612ba3565b5b612f1985828601612e82565b92509250509250929050565b600067ffffffffffffffff82169050919050565b612f4281612f25565b82525050565b6000602082019050612f5d6000830184612f39565b92915050565b600080600060608486031215612f7c57612f7b612b9e565b5b6000612f8a86828701612df4565b9350506020612f9b86828701612df4565b9250506040612fac86828701612d3f565b9150509250925092565b600060208284031215612fcc57612fcb612b9e565b5b6000612fda84828501612df4565b91505092915050565b612fec81612c2d565b8114612ff757600080fd5b50565b60008135905061300981612fe3565b92915050565b6000806040838503121561302657613025612b9e565b5b600061303485828601612df4565b925050602061304585828601612ffa565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61308c82612cb2565b810181811067ffffffffffffffff821117156130ab576130aa613054565b5b80604052505050565b60006130be612b94565b90506130ca8282613083565b919050565b600067ffffffffffffffff8211156130ea576130e9613054565b5b6130f382612cb2565b9050602081019050919050565b82818337600083830152505050565b600061312261311d846130cf565b6130b4565b90508281526020810184848401111561313e5761313d61304f565b5b613149848285613100565b509392505050565b600082601f83011261316657613165612e73565b5b813561317684826020860161310f565b91505092915050565b6000806000806080858703121561319957613198612b9e565b5b60006131a787828801612df4565b94505060206131b887828801612df4565b93505060406131c987828801612d3f565b925050606085013567ffffffffffffffff8111156131ea576131e9612ba3565b5b6131f687828801613151565b91505092959194509250565b600063ffffffff82169050919050565b61321b81613202565b811461322657600080fd5b50565b60008135905061323881613212565b92915050565b60008083601f84011261325457613253612e73565b5b8235905067ffffffffffffffff81111561327157613270612e78565b5b60208301915083600182028301111561328d5761328c612e7d565b5b9250929050565b6000806000806000608086880312156132b0576132af612b9e565b5b60006132be88828901612d3f565b95505060206132cf88828901613229565b94505060406132e088828901612d3f565b935050606086013567ffffffffffffffff81111561330157613300612ba3565b5b61330d8882890161323e565b92509250509295509295909350565b6000806040838503121561333357613332612b9e565b5b600061334185828601612df4565b925050602061335285828601612df4565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806133a357607f821691505b6020821081036133b6576133b561335c565b5b50919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006133f2602083612c6e565b91506133fd826133bc565b602082019050919050565b60006020820190508181036000830152613421816133e5565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b600061345e601f83612c6e565b915061346982613428565b602082019050919050565b6000602082019050818103600083015261348d81613451565b9050919050565b61349d81613202565b82525050565b600060c0820190506134b86000830189612db3565b6134c56020830188612db3565b6134d26040830187613494565b6134df6060830186612e49565b6134ec6080830185612e49565b6134f960a0830184612e49565b979650505050505050565b7f496e76616c6964207369676e6174757265000000000000000000000000000000600082015250565b600061353a601183612c6e565b915061354582613504565b602082019050919050565b600060208201905081810360008301526135698161352d565b9050919050565b7f436c61696d2066726f6d2077616c6c6574206f6e6c7900000000000000000000600082015250565b60006135a6601683612c6e565b91506135b182613570565b602082019050919050565b600060208201905081810360008301526135d581613599565b9050919050565b7f5369676e61747572652065787069726564000000000000000000000000000000600082015250565b6000613612601183612c6e565b915061361d826135dc565b602082019050919050565b6000602082019050818103600083015261364181613605565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061368282612d1e565b915061368d83612d1e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156136c2576136c1613648565b5b828201905092915050565b7f4578636565647320746865206d6178696d756d206e756d626572206f6620636f60008201527f696e73207468617420616e20696e646976696475616c2063616e206d696e7400602082015250565b6000613729603f83612c6e565b9150613734826136cd565b604082019050919050565b600060208201905081810360008301526137588161371c565b9050919050565b7f4d6178696d756d20737570706c79206578636565646564000000000000000000600082015250565b6000613795601783612c6e565b91506137a08261375f565b602082019050919050565b600060208201905081810360008301526137c481613788565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000613827602f83612c6e565b9150613832826137cb565b604082019050919050565b600060208201905081810360008301526138568161381a565b9050919050565b600081905092915050565b7f697066733a2f2f00000000000000000000000000000000000000000000000000600082015250565b600061389e60078361385d565b91506138a982613868565b600782019050919050565b60008190508160005260206000209050919050565b600081546138d68161338b565b6138e0818661385d565b945060018216600081146138fb576001811461390c5761393f565b60ff1983168652818601935061393f565b613915856138b4565b60005b8381101561393757815481890152600182019150602081019050613918565b838801955050505b50505092915050565b7f2f00000000000000000000000000000000000000000000000000000000000000600082015250565b600061397e60018361385d565b915061398982613948565b600182019050919050565b600061399f82612c63565b6139a9818561385d565b93506139b9818560208601612c7f565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b60006139fb60058361385d565b9150613a06826139c5565b600582019050919050565b6000613a1c82613891565b9150613a2882856138c9565b9150613a3382613971565b9150613a3f8284613994565b9150613a4a826139ee565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613ab2602683612c6e565b9150613abd82613a56565b604082019050919050565b60006020820190508181036000830152613ae181613aa5565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b6000613b1e601d83612c6e565b9150613b2982613ae8565b602082019050919050565b60006020820190508181036000830152613b4d81613b11565b9050919050565b600081905092915050565b50565b6000613b6f600083613b54565b9150613b7a82613b5f565b600082019050919050565b6000613b9082613b62565b9150819050919050565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b6000613bf6603a83612c6e565b9150613c0182613b9a565b604082019050919050565b60006020820190508181036000830152613c2581613be9565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000613c5382613c2c565b613c5d8185613c37565b9350613c6d818560208601612c7f565b613c7681612cb2565b840191505092915050565b6000608082019050613c966000830187612db3565b613ca36020830186612db3565b613cb06040830185612e49565b8181036060830152613cc28184613c48565b905095945050505050565b600081519050613cdc81612bd4565b92915050565b600060208284031215613cf857613cf7612b9e565b5b6000613d0684828501613ccd565b91505092915050565b6000613d1a82612d1e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613d4c57613d4b613648565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613d9182612d1e565b9150613d9c83612d1e565b925082613dac57613dab613d57565b5b828204905092915050565b6000613dc282612d1e565b9150613dcd83612d1e565b925082821015613de057613ddf613648565b5b828203905092915050565b6000613df682612d1e565b9150613e0183612d1e565b925082613e1157613e10613d57565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000613e81601c8361385d565b9150613e8c82613e4b565b601c82019050919050565b6000819050919050565b6000819050919050565b613ebc613eb782613e97565b613ea1565b82525050565b6000613ecd82613e74565b9150613ed98284613eab565b60208201915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000613f4d601883612c6e565b9150613f5882613f17565b602082019050919050565b60006020820190508181036000830152613f7c81613f40565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000613fb9601f83612c6e565b9150613fc482613f83565b602082019050919050565b60006020820190508181036000830152613fe881613fac565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b600061404b602283612c6e565b915061405682613fef565b604082019050919050565b6000602082019050818103600083015261407a8161403e565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b60006140dd602283612c6e565b91506140e882614081565b604082019050919050565b6000602082019050818103600083015261410c816140d0565b9050919050565b61411c81613e97565b82525050565b600060ff82169050919050565b61413881614122565b82525050565b60006080820190506141536000830187614113565b614160602083018661412f565b61416d6040830185614113565b61417a6060830184614113565b9594505050505056fea264697066735822122045b3a019da23099a8dbea7fcd0c09b8e30c727c3aa67bc07f19f47738d4d6be764736f6c634300080d0033

Deployed Bytecode

0x60806040526004361061014b5760003560e01c80636c19e783116100b6578063a22cb4651161006f578063a22cb4651461047e578063b88d4fde146104a7578063c2120363146104d0578063c87b56dd146104ec578063e985e9c514610529578063f2fde38b146105665761014b565b80636c19e7831461038057806370a08231146103a9578063715018a6146103e65780638da5cb5b146103fd57806395d89b411461042857806395e34e86146104535761014b565b806322f4596f1161010857806322f4596f1461027257806323b872dd1461029d5780633074d754146102c65780633ccfd60b1461030357806342842e0e1461031a5780636352211e146103435761014b565b806301ffc9a71461015057806306fdde031461018d578063081812fc146101b8578063095ea7b3146101f557806318160ddd1461021e5780631986651714610249575b600080fd5b34801561015c57600080fd5b5061017760048036038101906101729190612c00565b61058f565b6040516101849190612c48565b60405180910390f35b34801561019957600080fd5b506101a2610671565b6040516101af9190612cfc565b60405180910390f35b3480156101c457600080fd5b506101df60048036038101906101da9190612d54565b610703565b6040516101ec9190612dc2565b60405180910390f35b34801561020157600080fd5b5061021c60048036038101906102179190612e09565b61077f565b005b34801561022a57600080fd5b50610233610889565b6040516102409190612e58565b60405180910390f35b34801561025557600080fd5b50610270600480360381019061026b9190612ed8565b6108a0565b005b34801561027e57600080fd5b50610287610932565b6040516102949190612f48565b60405180910390f35b3480156102a957600080fd5b506102c460048036038101906102bf9190612f63565b61094c565b005b3480156102d257600080fd5b506102ed60048036038101906102e89190612fb6565b61095c565b6040516102fa9190612e58565b60405180910390f35b34801561030f57600080fd5b50610318610974565b005b34801561032657600080fd5b50610341600480360381019061033c9190612f63565b6109fc565b005b34801561034f57600080fd5b5061036a60048036038101906103659190612d54565b610a1c565b6040516103779190612dc2565b60405180910390f35b34801561038c57600080fd5b506103a760048036038101906103a29190612fb6565b610a32565b005b3480156103b557600080fd5b506103d060048036038101906103cb9190612fb6565b610af2565b6040516103dd9190612e58565b60405180910390f35b3480156103f257600080fd5b506103fb610bc1565b005b34801561040957600080fd5b50610412610c49565b60405161041f9190612dc2565b60405180910390f35b34801561043457600080fd5b5061043d610c73565b60405161044a9190612cfc565b60405180910390f35b34801561045f57600080fd5b50610468610d05565b6040516104759190612cfc565b60405180910390f35b34801561048a57600080fd5b506104a560048036038101906104a0919061300f565b610d93565b005b3480156104b357600080fd5b506104ce60048036038101906104c9919061317f565b610f0a565b005b6104ea60048036038101906104e59190613294565b610f86565b005b3480156104f857600080fd5b50610513600480360381019061050e9190612d54565b6112ad565b6040516105209190612cfc565b60405180910390f35b34801561053557600080fd5b50610550600480360381019061054b919061331c565b611329565b60405161055d9190612c48565b60405180910390f35b34801561057257600080fd5b5061058d60048036038101906105889190612fb6565b6113bd565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061065a57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061066a5750610669826114b4565b5b9050919050565b6060600280546106809061338b565b80601f01602080910402602001604051908101604052809291908181526020018280546106ac9061338b565b80156106f95780601f106106ce576101008083540402835291602001916106f9565b820191906000526020600020905b8154815290600101906020018083116106dc57829003601f168201915b5050505050905090565b600061070e8261151e565b610744576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061078a82610a1c565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036107f1576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661081061156c565b73ffffffffffffffffffffffffffffffffffffffff161415801561084257506108408161083b61156c565b611329565b155b15610879576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610884838383611574565b505050565b6000610893611626565b6001546000540303905090565b6108a861156c565b73ffffffffffffffffffffffffffffffffffffffff166108c6610c49565b73ffffffffffffffffffffffffffffffffffffffff161461091c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091390613408565b60405180910390fd5b8181600b919061092d929190612aae565b505050565b600a60009054906101000a900467ffffffffffffffff1681565b61095783838361162b565b505050565b600c6020528060005260406000206000915090505481565b61097c61156c565b73ffffffffffffffffffffffffffffffffffffffff1661099a610c49565b73ffffffffffffffffffffffffffffffffffffffff16146109f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e790613408565b60405180910390fd5b6109fa3347611adf565b565b610a1783838360405180602001604052806000815250610f0a565b505050565b6000610a2782611bd3565b600001519050919050565b610a3a61156c565b73ffffffffffffffffffffffffffffffffffffffff16610a58610c49565b73ffffffffffffffffffffffffffffffffffffffff1614610aae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa590613408565b60405180910390fd5b80600a60086101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610b59576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b610bc961156c565b73ffffffffffffffffffffffffffffffffffffffff16610be7610c49565b73ffffffffffffffffffffffffffffffffffffffff1614610c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3490613408565b60405180910390fd5b610c476000611e62565b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054610c829061338b565b80601f0160208091040260200160405190810160405280929190818152602001828054610cae9061338b565b8015610cfb5780601f10610cd057610100808354040283529160200191610cfb565b820191906000526020600020905b815481529060010190602001808311610cde57829003601f168201915b5050505050905090565b600b8054610d129061338b565b80601f0160208091040260200160405190810160405280929190818152602001828054610d3e9061338b565b8015610d8b5780601f10610d6057610100808354040283529160200191610d8b565b820191906000526020600020905b815481529060010190602001808311610d6e57829003601f168201915b505050505081565b610d9b61156c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610dff576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060076000610e0c61156c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16610eb961156c565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610efe9190612c48565b60405180910390a35050565b610f1584848461162b565b610f348373ffffffffffffffffffffffffffffffffffffffff16611f28565b8015610f495750610f4784848484611f4b565b155b15610f80576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b600260095403610fcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fc290613474565b60405180910390fd5b600260098190555061100e303386868934604051602001610ff1969594939291906134a3565b60405160208183030381529060405280519060200120838361209b565b61104d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104490613550565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b2906135bc565b60405180910390fd5b8363ffffffff16421115611104576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110fb90613628565b60405180910390fd5b8285600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546111509190613677565b1115611191576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111889061373f565b60405180910390fd5b600a60009054906101000a900467ffffffffffffffff1667ffffffffffffffff16856111bb610889565b6111c59190613677565b1115611206576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111fd906137ab565b60405180910390fd5b84600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546112519190613677565b600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061129e3386612155565b60016009819055505050505050565b60606112b88261151e565b6112f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ee9061383d565b60405180910390fd5b600b61130283612173565b604051602001611313929190613a11565b6040516020818303038152906040529050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6113c561156c565b73ffffffffffffffffffffffffffffffffffffffff166113e3610c49565b73ffffffffffffffffffffffffffffffffffffffff1614611439576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143090613408565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149f90613ac8565b60405180910390fd5b6114b181611e62565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600081611529611626565b11158015611538575060005482105b8015611565575060046000838152602001908152602001600020600001601c9054906101000a900460ff16155b9050919050565b600033905090565b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600090565b600061163682611bd3565b90508373ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16146116a1576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff166116c261156c565b73ffffffffffffffffffffffffffffffffffffffff1614806116f157506116f0856116eb61156c565b611329565b5b8061173657506116ff61156c565b73ffffffffffffffffffffffffffffffffffffffff1661171e84610703565b73ffffffffffffffffffffffffffffffffffffffff16145b90508061176f576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036117d5576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6117e285858560016122d3565b6117ee60008487611574565b6001600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160392506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600460008581526020019081526020016000209050848160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550428160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060006001850190506000600460008381526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603611a6d576000548214611a6c57878160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084602001518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b505050828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611ad885858560016122d9565b5050505050565b80471015611b22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1990613b34565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff1682604051611b4890613b85565b60006040518083038185875af1925050503d8060008114611b85576040519150601f19603f3d011682016040523d82523d6000602084013e611b8a565b606091505b5050905080611bce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bc590613c0c565b60405180910390fd5b505050565b611bdb612b34565b600082905080611be9611626565b11158015611bf8575060005481105b15611e2b576000600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff16151515158152505090508060400151611e2957600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614611d0d578092505050611e5d565b5b600115611e2857818060019003925050600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614611e23578092505050611e5d565b611d0e565b5b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611f7161156c565b8786866040518563ffffffff1660e01b8152600401611f939493929190613c81565b6020604051808303816000875af1925050508015611fcf57506040513d601f19601f82011682018060405250810190611fcc9190613ce2565b60015b612048573d8060008114611fff576040519150601f19603f3d011682016040523d82523d6000602084013e612004565b606091505b506000815103612040576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6000600a60089054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661213584848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612127876122df565b61230f90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff161490509392505050565b61216f828260405180602001604052806000815250612336565b5050565b6060600082036121ba576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506122ce565b600082905060005b600082146121ec5780806121d590613d0f565b915050600a826121e59190613d86565b91506121c2565b60008167ffffffffffffffff81111561220857612207613054565b5b6040519080825280601f01601f19166020018201604052801561223a5781602001600182028036833780820191505090505b5090505b600085146122c7576001826122539190613db7565b9150600a856122629190613deb565b603061226e9190613677565b60f81b81838151811061228457612283613e1c565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856122c09190613d86565b945061223e565b8093505050505b919050565b50505050565b50505050565b6000816040516020016122f29190613ec2565b604051602081830303815290604052805190602001209050919050565b600080600061231e85856126f6565b9150915061232b81612777565b819250505092915050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036123a2576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083036123dc576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123e960008583866122d3565b82600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555082600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550836004600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426004600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000819050600084820190506125aa8673ffffffffffffffffffffffffffffffffffffffff16611f28565b1561266f575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461261f6000878480600101955087611f4b565b612655576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8082036125b057826000541461266a57600080fd5b6126da565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808203612670575b8160008190555050506126f060008583866122d9565b50505050565b60008060418351036127375760008060006020860151925060408601519150606086015160001a905061272b87828585612943565b94509450505050612770565b604083510361276757600080602085015191506040850151905061275c868383612a4f565b935093505050612770565b60006002915091505b9250929050565b6000600481111561278b5761278a613ee8565b5b81600481111561279e5761279d613ee8565b5b031561294057600160048111156127b8576127b7613ee8565b5b8160048111156127cb576127ca613ee8565b5b0361280b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161280290613f63565b60405180910390fd5b6002600481111561281f5761281e613ee8565b5b81600481111561283257612831613ee8565b5b03612872576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161286990613fcf565b60405180910390fd5b6003600481111561288657612885613ee8565b5b81600481111561289957612898613ee8565b5b036128d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128d090614061565b60405180910390fd5b6004808111156128ec576128eb613ee8565b5b8160048111156128ff576128fe613ee8565b5b0361293f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612936906140f3565b60405180910390fd5b5b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c111561297e576000600391509150612a46565b601b8560ff16141580156129965750601c8560ff1614155b156129a8576000600491509150612a46565b6000600187878787604051600081526020016040526040516129cd949392919061413e565b6020604051602081039080840390855afa1580156129ef573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612a3d57600060019250925050612a46565b80600092509250505b94509492505050565b60008060007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60001b841690506000601b60ff8660001c901c612a929190613677565b9050612aa087828885612943565b935093505050935093915050565b828054612aba9061338b565b90600052602060002090601f016020900481019282612adc5760008555612b23565b82601f10612af557803560ff1916838001178555612b23565b82800160010185558215612b23579182015b82811115612b22578235825591602001919060010190612b07565b5b509050612b309190612b77565b5090565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681526020016000151581525090565b5b80821115612b90576000816000905550600101612b78565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612bdd81612ba8565b8114612be857600080fd5b50565b600081359050612bfa81612bd4565b92915050565b600060208284031215612c1657612c15612b9e565b5b6000612c2484828501612beb565b91505092915050565b60008115159050919050565b612c4281612c2d565b82525050565b6000602082019050612c5d6000830184612c39565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612c9d578082015181840152602081019050612c82565b83811115612cac576000848401525b50505050565b6000601f19601f8301169050919050565b6000612cce82612c63565b612cd88185612c6e565b9350612ce8818560208601612c7f565b612cf181612cb2565b840191505092915050565b60006020820190508181036000830152612d168184612cc3565b905092915050565b6000819050919050565b612d3181612d1e565b8114612d3c57600080fd5b50565b600081359050612d4e81612d28565b92915050565b600060208284031215612d6a57612d69612b9e565b5b6000612d7884828501612d3f565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612dac82612d81565b9050919050565b612dbc81612da1565b82525050565b6000602082019050612dd76000830184612db3565b92915050565b612de681612da1565b8114612df157600080fd5b50565b600081359050612e0381612ddd565b92915050565b60008060408385031215612e2057612e1f612b9e565b5b6000612e2e85828601612df4565b9250506020612e3f85828601612d3f565b9150509250929050565b612e5281612d1e565b82525050565b6000602082019050612e6d6000830184612e49565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112612e9857612e97612e73565b5b8235905067ffffffffffffffff811115612eb557612eb4612e78565b5b602083019150836001820283011115612ed157612ed0612e7d565b5b9250929050565b60008060208385031215612eef57612eee612b9e565b5b600083013567ffffffffffffffff811115612f0d57612f0c612ba3565b5b612f1985828601612e82565b92509250509250929050565b600067ffffffffffffffff82169050919050565b612f4281612f25565b82525050565b6000602082019050612f5d6000830184612f39565b92915050565b600080600060608486031215612f7c57612f7b612b9e565b5b6000612f8a86828701612df4565b9350506020612f9b86828701612df4565b9250506040612fac86828701612d3f565b9150509250925092565b600060208284031215612fcc57612fcb612b9e565b5b6000612fda84828501612df4565b91505092915050565b612fec81612c2d565b8114612ff757600080fd5b50565b60008135905061300981612fe3565b92915050565b6000806040838503121561302657613025612b9e565b5b600061303485828601612df4565b925050602061304585828601612ffa565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61308c82612cb2565b810181811067ffffffffffffffff821117156130ab576130aa613054565b5b80604052505050565b60006130be612b94565b90506130ca8282613083565b919050565b600067ffffffffffffffff8211156130ea576130e9613054565b5b6130f382612cb2565b9050602081019050919050565b82818337600083830152505050565b600061312261311d846130cf565b6130b4565b90508281526020810184848401111561313e5761313d61304f565b5b613149848285613100565b509392505050565b600082601f83011261316657613165612e73565b5b813561317684826020860161310f565b91505092915050565b6000806000806080858703121561319957613198612b9e565b5b60006131a787828801612df4565b94505060206131b887828801612df4565b93505060406131c987828801612d3f565b925050606085013567ffffffffffffffff8111156131ea576131e9612ba3565b5b6131f687828801613151565b91505092959194509250565b600063ffffffff82169050919050565b61321b81613202565b811461322657600080fd5b50565b60008135905061323881613212565b92915050565b60008083601f84011261325457613253612e73565b5b8235905067ffffffffffffffff81111561327157613270612e78565b5b60208301915083600182028301111561328d5761328c612e7d565b5b9250929050565b6000806000806000608086880312156132b0576132af612b9e565b5b60006132be88828901612d3f565b95505060206132cf88828901613229565b94505060406132e088828901612d3f565b935050606086013567ffffffffffffffff81111561330157613300612ba3565b5b61330d8882890161323e565b92509250509295509295909350565b6000806040838503121561333357613332612b9e565b5b600061334185828601612df4565b925050602061335285828601612df4565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806133a357607f821691505b6020821081036133b6576133b561335c565b5b50919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006133f2602083612c6e565b91506133fd826133bc565b602082019050919050565b60006020820190508181036000830152613421816133e5565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b600061345e601f83612c6e565b915061346982613428565b602082019050919050565b6000602082019050818103600083015261348d81613451565b9050919050565b61349d81613202565b82525050565b600060c0820190506134b86000830189612db3565b6134c56020830188612db3565b6134d26040830187613494565b6134df6060830186612e49565b6134ec6080830185612e49565b6134f960a0830184612e49565b979650505050505050565b7f496e76616c6964207369676e6174757265000000000000000000000000000000600082015250565b600061353a601183612c6e565b915061354582613504565b602082019050919050565b600060208201905081810360008301526135698161352d565b9050919050565b7f436c61696d2066726f6d2077616c6c6574206f6e6c7900000000000000000000600082015250565b60006135a6601683612c6e565b91506135b182613570565b602082019050919050565b600060208201905081810360008301526135d581613599565b9050919050565b7f5369676e61747572652065787069726564000000000000000000000000000000600082015250565b6000613612601183612c6e565b915061361d826135dc565b602082019050919050565b6000602082019050818103600083015261364181613605565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061368282612d1e565b915061368d83612d1e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156136c2576136c1613648565b5b828201905092915050565b7f4578636565647320746865206d6178696d756d206e756d626572206f6620636f60008201527f696e73207468617420616e20696e646976696475616c2063616e206d696e7400602082015250565b6000613729603f83612c6e565b9150613734826136cd565b604082019050919050565b600060208201905081810360008301526137588161371c565b9050919050565b7f4d6178696d756d20737570706c79206578636565646564000000000000000000600082015250565b6000613795601783612c6e565b91506137a08261375f565b602082019050919050565b600060208201905081810360008301526137c481613788565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000613827602f83612c6e565b9150613832826137cb565b604082019050919050565b600060208201905081810360008301526138568161381a565b9050919050565b600081905092915050565b7f697066733a2f2f00000000000000000000000000000000000000000000000000600082015250565b600061389e60078361385d565b91506138a982613868565b600782019050919050565b60008190508160005260206000209050919050565b600081546138d68161338b565b6138e0818661385d565b945060018216600081146138fb576001811461390c5761393f565b60ff1983168652818601935061393f565b613915856138b4565b60005b8381101561393757815481890152600182019150602081019050613918565b838801955050505b50505092915050565b7f2f00000000000000000000000000000000000000000000000000000000000000600082015250565b600061397e60018361385d565b915061398982613948565b600182019050919050565b600061399f82612c63565b6139a9818561385d565b93506139b9818560208601612c7f565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b60006139fb60058361385d565b9150613a06826139c5565b600582019050919050565b6000613a1c82613891565b9150613a2882856138c9565b9150613a3382613971565b9150613a3f8284613994565b9150613a4a826139ee565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613ab2602683612c6e565b9150613abd82613a56565b604082019050919050565b60006020820190508181036000830152613ae181613aa5565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b6000613b1e601d83612c6e565b9150613b2982613ae8565b602082019050919050565b60006020820190508181036000830152613b4d81613b11565b9050919050565b600081905092915050565b50565b6000613b6f600083613b54565b9150613b7a82613b5f565b600082019050919050565b6000613b9082613b62565b9150819050919050565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b6000613bf6603a83612c6e565b9150613c0182613b9a565b604082019050919050565b60006020820190508181036000830152613c2581613be9565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000613c5382613c2c565b613c5d8185613c37565b9350613c6d818560208601612c7f565b613c7681612cb2565b840191505092915050565b6000608082019050613c966000830187612db3565b613ca36020830186612db3565b613cb06040830185612e49565b8181036060830152613cc28184613c48565b905095945050505050565b600081519050613cdc81612bd4565b92915050565b600060208284031215613cf857613cf7612b9e565b5b6000613d0684828501613ccd565b91505092915050565b6000613d1a82612d1e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613d4c57613d4b613648565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613d9182612d1e565b9150613d9c83612d1e565b925082613dac57613dab613d57565b5b828204905092915050565b6000613dc282612d1e565b9150613dcd83612d1e565b925082821015613de057613ddf613648565b5b828203905092915050565b6000613df682612d1e565b9150613e0183612d1e565b925082613e1157613e10613d57565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000613e81601c8361385d565b9150613e8c82613e4b565b601c82019050919050565b6000819050919050565b6000819050919050565b613ebc613eb782613e97565b613ea1565b82525050565b6000613ecd82613e74565b9150613ed98284613eab565b60208201915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000613f4d601883612c6e565b9150613f5882613f17565b602082019050919050565b60006020820190508181036000830152613f7c81613f40565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000613fb9601f83612c6e565b9150613fc482613f83565b602082019050919050565b60006020820190508181036000830152613fe881613fac565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b600061404b602283612c6e565b915061405682613fef565b604082019050919050565b6000602082019050818103600083015261407a8161403e565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b60006140dd602283612c6e565b91506140e882614081565b604082019050919050565b6000602082019050818103600083015261410c816140d0565b9050919050565b61411c81613e97565b82525050565b600060ff82169050919050565b61413881614122565b82525050565b60006080820190506141536000830187614113565b614160602083018661412f565b61416d6040830185614113565b61417a6060830184614113565b9594505050505056fea264697066735822122045b3a019da23099a8dbea7fcd0c09b8e30c727c3aa67bc07f19f47738d4d6be764736f6c634300080d0033

Deployed Bytecode Sourcemap

58151:2007:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39257:305;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42370:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43873:204;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43436:371;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;38506:303;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58514:134;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58302:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44738:170;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58405:45;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59536:117;;;;;;;;;;;;;:::i;:::-;;44979:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;42178:125;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58658:90;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;39626:206;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17023:103;;;;;;;;;;;;;:::i;:::-;;16372:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42539:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58369:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44149:287;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;45235:369;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58758:773;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;59667:297;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44507:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17281:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;39257:305;39359:4;39411:25;39396:40;;;:11;:40;;;;:105;;;;39468:33;39453:48;;;:11;:48;;;;39396:105;:158;;;;39518:36;39542:11;39518:23;:36::i;:::-;39396:158;39376:178;;39257:305;;;:::o;42370:100::-;42424:13;42457:5;42450:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42370:100;:::o;43873:204::-;43941:7;43966:16;43974:7;43966;:16::i;:::-;43961:64;;43991:34;;;;;;;;;;;;;;43961:64;44045:15;:24;44061:7;44045:24;;;;;;;;;;;;;;;;;;;;;44038:31;;43873:204;;;:::o;43436:371::-;43509:13;43525:24;43541:7;43525:15;:24::i;:::-;43509:40;;43570:5;43564:11;;:2;:11;;;43560:48;;43584:24;;;;;;;;;;;;;;43560:48;43641:5;43625:21;;:12;:10;:12::i;:::-;:21;;;;:63;;;;;43651:37;43668:5;43675:12;:10;:12::i;:::-;43651:16;:37::i;:::-;43650:38;43625:63;43621:138;;;43712:35;;;;;;;;;;;;;;43621:138;43771:28;43780:2;43784:7;43793:5;43771:8;:28::i;:::-;43498:309;43436:371;;:::o;38506:303::-;38550:7;38775:15;:13;:15::i;:::-;38760:12;;38744:13;;:28;:46;38737:53;;38506:303;:::o;58514:134::-;16603:12;:10;:12::i;:::-;16592:23;;:7;:5;:7::i;:::-;:23;;;16584:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;58624:16:::1;;58606:15;:34;;;;;;;:::i;:::-;;58514:134:::0;;:::o;58302:31::-;;;;;;;;;;;;;:::o;44738:170::-;44872:28;44882:4;44888:2;44892:7;44872:9;:28::i;:::-;44738:170;;;:::o;58405:45::-;;;;;;;;;;;;;;;;;:::o;59536:117::-;16603:12;:10;:12::i;:::-;16592:23;;:7;:5;:7::i;:::-;:23;;;16584:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;59584:61:::1;59610:10;59623:21;59584:17;:61::i;:::-;59536:117::o:0;44979:185::-;45117:39;45134:4;45140:2;45144:7;45117:39;;;;;;;;;;;;:16;:39::i;:::-;44979:185;;;:::o;42178:125::-;42242:7;42269:21;42282:7;42269:12;:21::i;:::-;:26;;;42262:33;;42178:125;;;:::o;58658:90::-;16603:12;:10;:12::i;:::-;16592:23;;:7;:5;:7::i;:::-;:23;;;16584:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;58733:7:::1;58724:6;;:16;;;;;;;;;;;;;;;;;;58658:90:::0;:::o;39626:206::-;39690:7;39731:1;39714:19;;:5;:19;;;39710:60;;39742:28;;;;;;;;;;;;;;39710:60;39796:12;:19;39809:5;39796:19;;;;;;;;;;;;;;;:27;;;;;;;;;;;;39788:36;;39781:43;;39626:206;;;:::o;17023:103::-;16603:12;:10;:12::i;:::-;16592:23;;:7;:5;:7::i;:::-;:23;;;16584:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;17088:30:::1;17115:1;17088:18;:30::i;:::-;17023:103::o:0;16372:87::-;16418:7;16445:6;;;;;;;;;;;16438:13;;16372:87;:::o;42539:104::-;42595:13;42628:7;42621:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42539:104;:::o;58369:29::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;44149:287::-;44260:12;:10;:12::i;:::-;44248:24;;:8;:24;;;44244:54;;44281:17;;;;;;;;;;;;;;44244:54;44356:8;44311:18;:32;44330:12;:10;:12::i;:::-;44311:32;;;;;;;;;;;;;;;:42;44344:8;44311:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;44409:8;44380:48;;44395:12;:10;:12::i;:::-;44380:48;;;44419:8;44380:48;;;;;;:::i;:::-;;;;;;;;44149:287;;:::o;45235:369::-;45402:28;45412:4;45418:2;45422:7;45402:9;:28::i;:::-;45445:15;:2;:13;;;:15::i;:::-;:76;;;;;45465:56;45496:4;45502:2;45506:7;45515:5;45465:30;:56::i;:::-;45464:57;45445:76;45441:156;;;45545:40;;;;;;;;;;;;;;45441:156;45235:369;;;;:::o;58758:773::-;1812:1;2410:7;;:19;2402:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;1812:1;2543:7;:18;;;;58903:128:::1;58953:4;58960:10;58972:13;58987:8;58997;59007:9;58934:83;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;58924:94;;;;;;59020:10;;58903:20;:128::i;:::-;58895:158;;;;;;;;;;;;:::i;:::-;;;;;;;;;59086:9;59072:23;;:10;:23;;;59064:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;59160:13;59141:32;;:15;:32;;59133:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;59251:8;59239;59214:10;:22;59225:10;59214:22;;;;;;;;;;;;;;;;:33;;;;:::i;:::-;:45;;59206:121;;;;;;;;;;;;:::i;:::-;;;;;;;;;59374:10;;;;;;;;;;;59346:38;;59362:8;59346:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:38;;59338:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;59473:8;59448:10;:22;59459:10;59448:22;;;;;;;;;;;;;;;;:33;;;;:::i;:::-;59423:10;:22;59434:10;59423:22;;;;;;;;;;;;;;;:58;;;;59492:31;59502:10;59514:8;59492:9;:31::i;:::-;1768:1:::0;2722:7;:22;;;;58758:773;;;;;:::o;59667:297::-;59740:13;59774:16;59782:7;59774;:16::i;:::-;59766:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;59895:15;59917:18;:7;:16;:18::i;:::-;59867:78;;;;;;;;;:::i;:::-;;;;;;;;;;;;;59853:93;;59667:297;;;:::o;44507:164::-;44604:4;44628:18;:25;44647:5;44628:25;;;;;;;;;;;;;;;:35;44654:8;44628:35;;;;;;;;;;;;;;;;;;;;;;;;;44621:42;;44507:164;;;;:::o;17281:201::-;16603:12;:10;:12::i;:::-;16592:23;;:7;:5;:7::i;:::-;:23;;;16584:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;17390:1:::1;17370:22;;:8;:22;;::::0;17362:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;17446:28;17465:8;17446:18;:28::i;:::-;17281:201:::0;:::o;29156:157::-;29241:4;29280:25;29265:40;;;:11;:40;;;;29258:47;;29156:157;;;:::o;45859:174::-;45916:4;45959:7;45940:15;:13;:15::i;:::-;:26;;:53;;;;;45980:13;;45970:7;:23;45940:53;:85;;;;;45998:11;:20;46010:7;45998:20;;;;;;;;;;;:27;;;;;;;;;;;;45997:28;45940:85;45933:92;;45859:174;;;:::o;15096:98::-;15149:7;15176:10;15169:17;;15096:98;:::o;55085:196::-;55227:2;55200:15;:24;55216:7;55200:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;55265:7;55261:2;55245:28;;55254:5;55245:28;;;;;;;;;;;;55085:196;;;:::o;38280:92::-;38336:7;38280:92;:::o;50033:2130::-;50148:35;50186:21;50199:7;50186:12;:21::i;:::-;50148:59;;50246:4;50224:26;;:13;:18;;;:26;;;50220:67;;50259:28;;;;;;;;;;;;;;50220:67;50300:22;50342:4;50326:20;;:12;:10;:12::i;:::-;:20;;;:73;;;;50363:36;50380:4;50386:12;:10;:12::i;:::-;50363:16;:36::i;:::-;50326:73;:126;;;;50440:12;:10;:12::i;:::-;50416:36;;:20;50428:7;50416:11;:20::i;:::-;:36;;;50326:126;50300:153;;50471:17;50466:66;;50497:35;;;;;;;;;;;;;;50466:66;50561:1;50547:16;;:2;:16;;;50543:52;;50572:23;;;;;;;;;;;;;;50543:52;50608:43;50630:4;50636:2;50640:7;50649:1;50608:21;:43::i;:::-;50716:35;50733:1;50737:7;50746:4;50716:8;:35::i;:::-;51077:1;51047:12;:18;51060:4;51047:18;;;;;;;;;;;;;;;:26;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51121:1;51093:12;:16;51106:2;51093:16;;;;;;;;;;;;;;;:24;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51139:31;51173:11;:20;51185:7;51173:20;;;;;;;;;;;51139:54;;51224:2;51208:8;:13;;;:18;;;;;;;;;;;;;;;;;;51274:15;51241:8;:23;;;:49;;;;;;;;;;;;;;;;;;51542:19;51574:1;51564:7;:11;51542:33;;51590:31;51624:11;:24;51636:11;51624:24;;;;;;;;;;;51590:58;;51692:1;51667:27;;:8;:13;;;;;;;;;;;;:27;;;51663:384;;51877:13;;51862:11;:28;51858:174;;51931:4;51915:8;:13;;;:20;;;;;;;;;;;;;;;;;;51984:13;:28;;;51958:8;:23;;;:54;;;;;;;;;;;;;;;;;;51858:174;51663:384;51022:1036;;;52094:7;52090:2;52075:27;;52084:4;52075:27;;;;;;;;;;;;52113:42;52134:4;52140:2;52144:7;52153:1;52113:20;:42::i;:::-;50137:2026;;50033:2130;;;:::o;20334:317::-;20449:6;20424:21;:31;;20416:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;20503:12;20521:9;:14;;20543:6;20521:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20502:52;;;20573:7;20565:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;20405:246;20334:317;;:::o;41007:1109::-;41069:21;;:::i;:::-;41103:12;41118:7;41103:22;;41186:4;41167:15;:13;:15::i;:::-;:23;;:47;;;;;41201:13;;41194:4;:20;41167:47;41163:886;;;41235:31;41269:11;:17;41281:4;41269:17;;;;;;;;;;;41235:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41310:9;:16;;;41305:729;;41381:1;41355:28;;:9;:14;;;:28;;;41351:101;;41419:9;41412:16;;;;;;41351:101;41754:261;41761:4;41754:261;;;41794:6;;;;;;;;41839:11;:17;41851:4;41839:17;;;;;;;;;;;41827:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41913:1;41887:28;;:9;:14;;;:28;;;41883:109;;41955:9;41948:16;;;;;;41883:109;41754:261;;;41305:729;41216:833;41163:886;42077:31;;;;;;;;;;;;;;41007:1109;;;;:::o;17642:191::-;17716:16;17735:6;;;;;;;;;;;17716:25;;17761:8;17752:6;;:17;;;;;;;;;;;;;;;;;;17816:8;17785:40;;17806:8;17785:40;;;;;;;;;;;;17705:128;17642:191;:::o;19073:326::-;19133:4;19390:1;19368:7;:19;;;:23;19361:30;;19073:326;;;:::o;55773:667::-;55936:4;55973:2;55957:36;;;55994:12;:10;:12::i;:::-;56008:4;56014:7;56023:5;55957:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;55953:480;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56208:1;56191:6;:13;:18;56187:235;;56237:40;;;;;;;;;;;;;;56187:235;56380:6;56374:13;56365:6;56361:2;56357:15;56350:38;55953:480;56086:45;;;56076:55;;;:6;:55;;;;56069:62;;;55773:667;;;;;;:::o;59974:181::-;60065:4;60141:6;;;;;;;;;;;60089:58;;:48;60127:9;;60089:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:29;:4;:27;:29::i;:::-;:37;;:48;;;;:::i;:::-;:58;;;60082:65;;59974:181;;;;;:::o;46117:104::-;46186:27;46196:2;46200:8;46186:27;;;;;;;;;;;;:9;:27::i;:::-;46117:104;;:::o;3124:723::-;3180:13;3410:1;3401:5;:10;3397:53;;3428:10;;;;;;;;;;;;;;;;;;;;;3397:53;3460:12;3475:5;3460:20;;3491:14;3516:78;3531:1;3523:4;:9;3516:78;;3549:8;;;;;:::i;:::-;;;;3580:2;3572:10;;;;;:::i;:::-;;;3516:78;;;3604:19;3636:6;3626:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3604:39;;3654:154;3670:1;3661:5;:10;3654:154;;3698:1;3688:11;;;;;:::i;:::-;;;3765:2;3757:5;:10;;;;:::i;:::-;3744:2;:24;;;;:::i;:::-;3731:39;;3714:6;3721;3714:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;3794:2;3785:11;;;;;:::i;:::-;;;3654:154;;;3832:6;3818:21;;;;;3124:723;;;;:::o;57088:159::-;;;;;:::o;57906:158::-;;;;;:::o;13102:269::-;13171:7;13357:4;13304:58;;;;;;;;:::i;:::-;;;;;;;;;;;;;13294:69;;;;;;13287:76;;13102:269;;;:::o;9300:231::-;9378:7;9399:17;9418:18;9440:27;9451:4;9457:9;9440:10;:27::i;:::-;9398:69;;;;9478:18;9490:5;9478:11;:18::i;:::-;9514:9;9507:16;;;;9300:231;;;;:::o;46595:1751::-;46718:20;46741:13;;46718:36;;46783:1;46769:16;;:2;:16;;;46765:48;;46794:19;;;;;;;;;;;;;;46765:48;46840:1;46828:8;:13;46824:44;;46850:18;;;;;;;;;;;;;;46824:44;46881:61;46911:1;46915:2;46919:12;46933:8;46881:21;:61::i;:::-;47254:8;47219:12;:16;47232:2;47219:16;;;;;;;;;;;;;;;:24;;;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47318:8;47278:12;:16;47291:2;47278:16;;;;;;;;;;;;;;;:29;;;:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47377:2;47344:11;:25;47356:12;47344:25;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;47444:15;47394:11;:25;47406:12;47394:25;;;;;;;;;;;:40;;;:66;;;;;;;;;;;;;;;;;;47477:20;47500:12;47477:35;;47527:11;47556:8;47541:12;:23;47527:37;;47585:15;:2;:13;;;:15::i;:::-;47581:633;;;47621:314;47677:12;47673:2;47652:38;;47669:1;47652:38;;;;;;;;;;;;47718:69;47757:1;47761:2;47765:14;;;;;;47781:5;47718:30;:69::i;:::-;47713:174;;47823:40;;;;;;;;;;;;;;47713:174;47930:3;47914:12;:19;47621:314;;48016:12;47999:13;;:29;47995:43;;48030:8;;;47995:43;47581:633;;;48079:120;48135:14;;;;;;48131:2;48110:40;;48127:1;48110:40;;;;;;;;;;;;48194:3;48178:12;:19;48079:120;;47581:633;48244:12;48228:13;:28;;;;47194:1074;;48278:60;48307:1;48311:2;48315:12;48329:8;48278:20;:60::i;:::-;46707:1639;46595:1751;;;:::o;7190:1308::-;7271:7;7280:12;7525:2;7505:9;:16;:22;7501:990;;7544:9;7568;7592:7;7801:4;7790:9;7786:20;7780:27;7775:32;;7851:4;7840:9;7836:20;7830:27;7825:32;;7909:4;7898:9;7894:20;7888:27;7885:1;7880:36;7875:41;;7952:25;7963:4;7969:1;7972;7975;7952:10;:25::i;:::-;7945:32;;;;;;;;;7501:990;8019:2;7999:9;:16;:22;7995:496;;8038:9;8062:10;8274:4;8263:9;8259:20;8253:27;8248:32;;8325:4;8314:9;8310:20;8304:27;8298:33;;8367:23;8378:4;8384:1;8387:2;8367:10;:23::i;:::-;8360:30;;;;;;;;7995:496;8439:1;8443:35;8423:56;;;;7190:1308;;;;;;:::o;5461:643::-;5539:20;5530:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;5526:571;5576:7;5526:571;5637:29;5628:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;5624:473;;5683:34;;;;;;;;;;:::i;:::-;;;;;;;;5624:473;5748:35;5739:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;5735:362;;5800:41;;;;;;;;;;:::i;:::-;;;;;;;;5735:362;5872:30;5863:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;5859:238;;5919:44;;;;;;;;;;:::i;:::-;;;;;;;;5859:238;5994:30;5985:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;5981:116;;6041:44;;;;;;;;;;:::i;:::-;;;;;;;;5981:116;5461:643;;:::o;10752:1632::-;10883:7;10892:12;11817:66;11812:1;11804:10;;:79;11800:163;;;11916:1;11920:30;11900:51;;;;;;11800:163;11982:2;11977:1;:7;;;;:18;;;;;11993:2;11988:1;:7;;;;11977:18;11973:102;;;12028:1;12032:30;12012:51;;;;;;11973:102;12172:14;12189:24;12199:4;12205:1;12208;12211;12189:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12172:41;;12246:1;12228:20;;:6;:20;;;12224:103;;12281:1;12285:29;12265:50;;;;;;;12224:103;12347:6;12355:20;12339:37;;;;;10752:1632;;;;;;;;:::o;9794:344::-;9908:7;9917:12;9942:9;9967:66;9959:75;;9954:2;:80;9942:92;;10045:7;10084:2;10077:3;10070:2;10062:11;;:18;;10061:25;;;;:::i;:::-;10045:42;;10105:25;10116:4;10122:1;10125;10128;10105:10;:25::i;:::-;10098:32;;;;;;9794:344;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:307::-;1866:1;1876:113;1890:6;1887:1;1884:13;1876:113;;;1975:1;1970:3;1966:11;1960:18;1956:1;1951:3;1947:11;1940:39;1912:2;1909:1;1905:10;1900:15;;1876:113;;;2007:6;2004:1;2001:13;1998:101;;;2087:1;2078:6;2073:3;2069:16;2062:27;1998:101;1847:258;1798:307;;;:::o;2111:102::-;2152:6;2203:2;2199:7;2194:2;2187:5;2183:14;2179:28;2169:38;;2111:102;;;:::o;2219:364::-;2307:3;2335:39;2368:5;2335:39;:::i;:::-;2390:71;2454:6;2449:3;2390:71;:::i;:::-;2383:78;;2470:52;2515:6;2510:3;2503:4;2496:5;2492:16;2470:52;:::i;:::-;2547:29;2569:6;2547:29;:::i;:::-;2542:3;2538:39;2531:46;;2311:272;2219:364;;;;:::o;2589:313::-;2702:4;2740:2;2729:9;2725:18;2717:26;;2789:9;2783:4;2779:20;2775:1;2764:9;2760:17;2753:47;2817:78;2890:4;2881:6;2817:78;:::i;:::-;2809:86;;2589:313;;;;:::o;2908:77::-;2945:7;2974:5;2963:16;;2908:77;;;:::o;2991:122::-;3064:24;3082:5;3064:24;:::i;:::-;3057:5;3054:35;3044:63;;3103:1;3100;3093:12;3044:63;2991:122;:::o;3119:139::-;3165:5;3203:6;3190:20;3181:29;;3219:33;3246:5;3219:33;:::i;:::-;3119:139;;;;:::o;3264:329::-;3323:6;3372:2;3360:9;3351:7;3347:23;3343:32;3340:119;;;3378:79;;:::i;:::-;3340:119;3498:1;3523:53;3568:7;3559:6;3548:9;3544:22;3523:53;:::i;:::-;3513:63;;3469:117;3264:329;;;;:::o;3599:126::-;3636:7;3676:42;3669:5;3665:54;3654:65;;3599:126;;;:::o;3731:96::-;3768:7;3797:24;3815:5;3797:24;:::i;:::-;3786:35;;3731:96;;;:::o;3833:118::-;3920:24;3938:5;3920:24;:::i;:::-;3915:3;3908:37;3833:118;;:::o;3957:222::-;4050:4;4088:2;4077:9;4073:18;4065:26;;4101:71;4169:1;4158:9;4154:17;4145:6;4101:71;:::i;:::-;3957:222;;;;:::o;4185:122::-;4258:24;4276:5;4258:24;:::i;:::-;4251:5;4248:35;4238:63;;4297:1;4294;4287:12;4238:63;4185:122;:::o;4313:139::-;4359:5;4397:6;4384:20;4375:29;;4413:33;4440:5;4413:33;:::i;:::-;4313:139;;;;:::o;4458:474::-;4526:6;4534;4583:2;4571:9;4562:7;4558:23;4554:32;4551:119;;;4589:79;;:::i;:::-;4551:119;4709:1;4734:53;4779:7;4770:6;4759:9;4755:22;4734:53;:::i;:::-;4724:63;;4680:117;4836:2;4862:53;4907:7;4898:6;4887:9;4883:22;4862:53;:::i;:::-;4852:63;;4807:118;4458:474;;;;;:::o;4938:118::-;5025:24;5043:5;5025:24;:::i;:::-;5020:3;5013:37;4938:118;;:::o;5062:222::-;5155:4;5193:2;5182:9;5178:18;5170:26;;5206:71;5274:1;5263:9;5259:17;5250:6;5206:71;:::i;:::-;5062:222;;;;:::o;5290:117::-;5399:1;5396;5389:12;5413:117;5522:1;5519;5512:12;5536:117;5645:1;5642;5635:12;5673:553;5731:8;5741:6;5791:3;5784:4;5776:6;5772:17;5768:27;5758:122;;5799:79;;:::i;:::-;5758:122;5912:6;5899:20;5889:30;;5942:18;5934:6;5931:30;5928:117;;;5964:79;;:::i;:::-;5928:117;6078:4;6070:6;6066:17;6054:29;;6132:3;6124:4;6116:6;6112:17;6102:8;6098:32;6095:41;6092:128;;;6139:79;;:::i;:::-;6092:128;5673:553;;;;;:::o;6232:529::-;6303:6;6311;6360:2;6348:9;6339:7;6335:23;6331:32;6328:119;;;6366:79;;:::i;:::-;6328:119;6514:1;6503:9;6499:17;6486:31;6544:18;6536:6;6533:30;6530:117;;;6566:79;;:::i;:::-;6530:117;6679:65;6736:7;6727:6;6716:9;6712:22;6679:65;:::i;:::-;6661:83;;;;6457:297;6232:529;;;;;:::o;6767:101::-;6803:7;6843:18;6836:5;6832:30;6821:41;;6767:101;;;:::o;6874:115::-;6959:23;6976:5;6959:23;:::i;:::-;6954:3;6947:36;6874:115;;:::o;6995:218::-;7086:4;7124:2;7113:9;7109:18;7101:26;;7137:69;7203:1;7192:9;7188:17;7179:6;7137:69;:::i;:::-;6995:218;;;;:::o;7219:619::-;7296:6;7304;7312;7361:2;7349:9;7340:7;7336:23;7332:32;7329:119;;;7367:79;;:::i;:::-;7329:119;7487:1;7512:53;7557:7;7548:6;7537:9;7533:22;7512:53;:::i;:::-;7502:63;;7458:117;7614:2;7640:53;7685:7;7676:6;7665:9;7661:22;7640:53;:::i;:::-;7630:63;;7585:118;7742:2;7768:53;7813:7;7804:6;7793:9;7789:22;7768:53;:::i;:::-;7758:63;;7713:118;7219:619;;;;;:::o;7844:329::-;7903:6;7952:2;7940:9;7931:7;7927:23;7923:32;7920:119;;;7958:79;;:::i;:::-;7920:119;8078:1;8103:53;8148:7;8139:6;8128:9;8124:22;8103:53;:::i;:::-;8093:63;;8049:117;7844:329;;;;:::o;8179:116::-;8249:21;8264:5;8249:21;:::i;:::-;8242:5;8239:32;8229:60;;8285:1;8282;8275:12;8229:60;8179:116;:::o;8301:133::-;8344:5;8382:6;8369:20;8360:29;;8398:30;8422:5;8398:30;:::i;:::-;8301:133;;;;:::o;8440:468::-;8505:6;8513;8562:2;8550:9;8541:7;8537:23;8533:32;8530:119;;;8568:79;;:::i;:::-;8530:119;8688:1;8713:53;8758:7;8749:6;8738:9;8734:22;8713:53;:::i;:::-;8703:63;;8659:117;8815:2;8841:50;8883:7;8874:6;8863:9;8859:22;8841:50;:::i;:::-;8831:60;;8786:115;8440:468;;;;;:::o;8914:117::-;9023:1;9020;9013:12;9037:180;9085:77;9082:1;9075:88;9182:4;9179:1;9172:15;9206:4;9203:1;9196:15;9223:281;9306:27;9328:4;9306:27;:::i;:::-;9298:6;9294:40;9436:6;9424:10;9421:22;9400:18;9388:10;9385:34;9382:62;9379:88;;;9447:18;;:::i;:::-;9379:88;9487:10;9483:2;9476:22;9266:238;9223:281;;:::o;9510:129::-;9544:6;9571:20;;:::i;:::-;9561:30;;9600:33;9628:4;9620:6;9600:33;:::i;:::-;9510:129;;;:::o;9645:307::-;9706:4;9796:18;9788:6;9785:30;9782:56;;;9818:18;;:::i;:::-;9782:56;9856:29;9878:6;9856:29;:::i;:::-;9848:37;;9940:4;9934;9930:15;9922:23;;9645:307;;;:::o;9958:154::-;10042:6;10037:3;10032;10019:30;10104:1;10095:6;10090:3;10086:16;10079:27;9958:154;;;:::o;10118:410::-;10195:5;10220:65;10236:48;10277:6;10236:48;:::i;:::-;10220:65;:::i;:::-;10211:74;;10308:6;10301:5;10294:21;10346:4;10339:5;10335:16;10384:3;10375:6;10370:3;10366:16;10363:25;10360:112;;;10391:79;;:::i;:::-;10360:112;10481:41;10515:6;10510:3;10505;10481:41;:::i;:::-;10201:327;10118:410;;;;;:::o;10547:338::-;10602:5;10651:3;10644:4;10636:6;10632:17;10628:27;10618:122;;10659:79;;:::i;:::-;10618:122;10776:6;10763:20;10801:78;10875:3;10867:6;10860:4;10852:6;10848:17;10801:78;:::i;:::-;10792:87;;10608:277;10547:338;;;;:::o;10891:943::-;10986:6;10994;11002;11010;11059:3;11047:9;11038:7;11034:23;11030:33;11027:120;;;11066:79;;:::i;:::-;11027:120;11186:1;11211:53;11256:7;11247:6;11236:9;11232:22;11211:53;:::i;:::-;11201:63;;11157:117;11313:2;11339:53;11384:7;11375:6;11364:9;11360:22;11339:53;:::i;:::-;11329:63;;11284:118;11441:2;11467:53;11512:7;11503:6;11492:9;11488:22;11467:53;:::i;:::-;11457:63;;11412:118;11597:2;11586:9;11582:18;11569:32;11628:18;11620:6;11617:30;11614:117;;;11650:79;;:::i;:::-;11614:117;11755:62;11809:7;11800:6;11789:9;11785:22;11755:62;:::i;:::-;11745:72;;11540:287;10891:943;;;;;;;:::o;11840:93::-;11876:7;11916:10;11909:5;11905:22;11894:33;;11840:93;;;:::o;11939:120::-;12011:23;12028:5;12011:23;:::i;:::-;12004:5;12001:34;11991:62;;12049:1;12046;12039:12;11991:62;11939:120;:::o;12065:137::-;12110:5;12148:6;12135:20;12126:29;;12164:32;12190:5;12164:32;:::i;:::-;12065:137;;;;:::o;12221:552::-;12278:8;12288:6;12338:3;12331:4;12323:6;12319:17;12315:27;12305:122;;12346:79;;:::i;:::-;12305:122;12459:6;12446:20;12436:30;;12489:18;12481:6;12478:30;12475:117;;;12511:79;;:::i;:::-;12475:117;12625:4;12617:6;12613:17;12601:29;;12679:3;12671:4;12663:6;12659:17;12649:8;12645:32;12642:41;12639:128;;;12686:79;;:::i;:::-;12639:128;12221:552;;;;;:::o;12779:961::-;12875:6;12883;12891;12899;12907;12956:3;12944:9;12935:7;12931:23;12927:33;12924:120;;;12963:79;;:::i;:::-;12924:120;13083:1;13108:53;13153:7;13144:6;13133:9;13129:22;13108:53;:::i;:::-;13098:63;;13054:117;13210:2;13236:52;13280:7;13271:6;13260:9;13256:22;13236:52;:::i;:::-;13226:62;;13181:117;13337:2;13363:53;13408:7;13399:6;13388:9;13384:22;13363:53;:::i;:::-;13353:63;;13308:118;13493:2;13482:9;13478:18;13465:32;13524:18;13516:6;13513:30;13510:117;;;13546:79;;:::i;:::-;13510:117;13659:64;13715:7;13706:6;13695:9;13691:22;13659:64;:::i;:::-;13641:82;;;;13436:297;12779:961;;;;;;;;:::o;13746:474::-;13814:6;13822;13871:2;13859:9;13850:7;13846:23;13842:32;13839:119;;;13877:79;;:::i;:::-;13839:119;13997:1;14022:53;14067:7;14058:6;14047:9;14043:22;14022:53;:::i;:::-;14012:63;;13968:117;14124:2;14150:53;14195:7;14186:6;14175:9;14171:22;14150:53;:::i;:::-;14140:63;;14095:118;13746:474;;;;;:::o;14226:180::-;14274:77;14271:1;14264:88;14371:4;14368:1;14361:15;14395:4;14392:1;14385:15;14412:320;14456:6;14493:1;14487:4;14483:12;14473:22;;14540:1;14534:4;14530:12;14561:18;14551:81;;14617:4;14609:6;14605:17;14595:27;;14551:81;14679:2;14671:6;14668:14;14648:18;14645:38;14642:84;;14698:18;;:::i;:::-;14642:84;14463:269;14412:320;;;:::o;14738:182::-;14878:34;14874:1;14866:6;14862:14;14855:58;14738:182;:::o;14926:366::-;15068:3;15089:67;15153:2;15148:3;15089:67;:::i;:::-;15082:74;;15165:93;15254:3;15165:93;:::i;:::-;15283:2;15278:3;15274:12;15267:19;;14926:366;;;:::o;15298:419::-;15464:4;15502:2;15491:9;15487:18;15479:26;;15551:9;15545:4;15541:20;15537:1;15526:9;15522:17;15515:47;15579:131;15705:4;15579:131;:::i;:::-;15571:139;;15298:419;;;:::o;15723:181::-;15863:33;15859:1;15851:6;15847:14;15840:57;15723:181;:::o;15910:366::-;16052:3;16073:67;16137:2;16132:3;16073:67;:::i;:::-;16066:74;;16149:93;16238:3;16149:93;:::i;:::-;16267:2;16262:3;16258:12;16251:19;;15910:366;;;:::o;16282:419::-;16448:4;16486:2;16475:9;16471:18;16463:26;;16535:9;16529:4;16525:20;16521:1;16510:9;16506:17;16499:47;16563:131;16689:4;16563:131;:::i;:::-;16555:139;;16282:419;;;:::o;16707:115::-;16792:23;16809:5;16792:23;:::i;:::-;16787:3;16780:36;16707:115;;:::o;16828:771::-;17059:4;17097:3;17086:9;17082:19;17074:27;;17111:71;17179:1;17168:9;17164:17;17155:6;17111:71;:::i;:::-;17192:72;17260:2;17249:9;17245:18;17236:6;17192:72;:::i;:::-;17274:70;17340:2;17329:9;17325:18;17316:6;17274:70;:::i;:::-;17354:72;17422:2;17411:9;17407:18;17398:6;17354:72;:::i;:::-;17436:73;17504:3;17493:9;17489:19;17480:6;17436:73;:::i;:::-;17519;17587:3;17576:9;17572:19;17563:6;17519:73;:::i;:::-;16828:771;;;;;;;;;:::o;17605:167::-;17745:19;17741:1;17733:6;17729:14;17722:43;17605:167;:::o;17778:366::-;17920:3;17941:67;18005:2;18000:3;17941:67;:::i;:::-;17934:74;;18017:93;18106:3;18017:93;:::i;:::-;18135:2;18130:3;18126:12;18119:19;;17778:366;;;:::o;18150:419::-;18316:4;18354:2;18343:9;18339:18;18331:26;;18403:9;18397:4;18393:20;18389:1;18378:9;18374:17;18367:47;18431:131;18557:4;18431:131;:::i;:::-;18423:139;;18150:419;;;:::o;18575:172::-;18715:24;18711:1;18703:6;18699:14;18692:48;18575:172;:::o;18753:366::-;18895:3;18916:67;18980:2;18975:3;18916:67;:::i;:::-;18909:74;;18992:93;19081:3;18992:93;:::i;:::-;19110:2;19105:3;19101:12;19094:19;;18753:366;;;:::o;19125:419::-;19291:4;19329:2;19318:9;19314:18;19306:26;;19378:9;19372:4;19368:20;19364:1;19353:9;19349:17;19342:47;19406:131;19532:4;19406:131;:::i;:::-;19398:139;;19125:419;;;:::o;19550:167::-;19690:19;19686:1;19678:6;19674:14;19667:43;19550:167;:::o;19723:366::-;19865:3;19886:67;19950:2;19945:3;19886:67;:::i;:::-;19879:74;;19962:93;20051:3;19962:93;:::i;:::-;20080:2;20075:3;20071:12;20064:19;;19723:366;;;:::o;20095:419::-;20261:4;20299:2;20288:9;20284:18;20276:26;;20348:9;20342:4;20338:20;20334:1;20323:9;20319:17;20312:47;20376:131;20502:4;20376:131;:::i;:::-;20368:139;;20095:419;;;:::o;20520:180::-;20568:77;20565:1;20558:88;20665:4;20662:1;20655:15;20689:4;20686:1;20679:15;20706:305;20746:3;20765:20;20783:1;20765:20;:::i;:::-;20760:25;;20799:20;20817:1;20799:20;:::i;:::-;20794:25;;20953:1;20885:66;20881:74;20878:1;20875:81;20872:107;;;20959:18;;:::i;:::-;20872:107;21003:1;21000;20996:9;20989:16;;20706:305;;;;:::o;21017:250::-;21157:34;21153:1;21145:6;21141:14;21134:58;21226:33;21221:2;21213:6;21209:15;21202:58;21017:250;:::o;21273:366::-;21415:3;21436:67;21500:2;21495:3;21436:67;:::i;:::-;21429:74;;21512:93;21601:3;21512:93;:::i;:::-;21630:2;21625:3;21621:12;21614:19;;21273:366;;;:::o;21645:419::-;21811:4;21849:2;21838:9;21834:18;21826:26;;21898:9;21892:4;21888:20;21884:1;21873:9;21869:17;21862:47;21926:131;22052:4;21926:131;:::i;:::-;21918:139;;21645:419;;;:::o;22070:173::-;22210:25;22206:1;22198:6;22194:14;22187:49;22070:173;:::o;22249:366::-;22391:3;22412:67;22476:2;22471:3;22412:67;:::i;:::-;22405:74;;22488:93;22577:3;22488:93;:::i;:::-;22606:2;22601:3;22597:12;22590:19;;22249:366;;;:::o;22621:419::-;22787:4;22825:2;22814:9;22810:18;22802:26;;22874:9;22868:4;22864:20;22860:1;22849:9;22845:17;22838:47;22902:131;23028:4;22902:131;:::i;:::-;22894:139;;22621:419;;;:::o;23046:234::-;23186:34;23182:1;23174:6;23170:14;23163:58;23255:17;23250:2;23242:6;23238:15;23231:42;23046:234;:::o;23286:366::-;23428:3;23449:67;23513:2;23508:3;23449:67;:::i;:::-;23442:74;;23525:93;23614:3;23525:93;:::i;:::-;23643:2;23638:3;23634:12;23627:19;;23286:366;;;:::o;23658:419::-;23824:4;23862:2;23851:9;23847:18;23839:26;;23911:9;23905:4;23901:20;23897:1;23886:9;23882:17;23875:47;23939:131;24065:4;23939:131;:::i;:::-;23931:139;;23658:419;;;:::o;24083:148::-;24185:11;24222:3;24207:18;;24083:148;;;;:::o;24237:161::-;24377:9;24373:1;24365:6;24361:14;24354:33;24237:161;:::o;24408:416::-;24568:3;24593:84;24675:1;24670:3;24593:84;:::i;:::-;24586:91;;24690:93;24779:3;24690:93;:::i;:::-;24812:1;24807:3;24803:11;24796:18;;24408:416;;;:::o;24834:157::-;24883:4;24910:3;24902:11;;24937:3;24934:1;24927:14;24975:4;24972:1;24962:18;24954:26;;24834:157;;;:::o;25029:925::-;25132:3;25173:5;25167:12;25206:36;25232:9;25206:36;:::i;:::-;25262:89;25344:6;25339:3;25262:89;:::i;:::-;25255:96;;25386:1;25375:9;25371:17;25406:1;25401:153;;;;25572:1;25567:377;;;;25364:580;;25401:153;25493:4;25489:9;25478;25474:25;25469:3;25462:38;25533:6;25528:3;25524:16;25517:23;;25401:153;;25567:377;25642:38;25674:5;25642:38;:::i;:::-;25706:1;25724:166;25738:6;25735:1;25732:13;25724:166;;;25816:7;25810:14;25806:1;25801:3;25797:11;25790:35;25870:1;25861:7;25857:15;25846:26;;25760:4;25757:1;25753:12;25748:17;;25724:166;;;25923:6;25918:3;25914:16;25907:23;;25574:370;;25364:580;;25136:818;;25029:925;;;;:::o;25964:159::-;26108:3;26104:1;26096:6;26092:14;26085:27;25964:159;:::o;26133:416::-;26293:3;26318:84;26400:1;26395:3;26318:84;:::i;:::-;26311:91;;26415:93;26504:3;26415:93;:::i;:::-;26537:1;26532:3;26528:11;26521:18;;26133:416;;;:::o;26559:397::-;26665:3;26697:39;26730:5;26697:39;:::i;:::-;26756:89;26838:6;26833:3;26756:89;:::i;:::-;26749:96;;26858:52;26903:6;26898:3;26891:4;26884:5;26880:16;26858:52;:::i;:::-;26939:6;26934:3;26930:16;26923:23;;26669:287;26559:397;;;;:::o;26966:163::-;27110:7;27106:1;27098:6;27094:14;27087:31;26966:163;:::o;27139:416::-;27299:3;27324:84;27406:1;27401:3;27324:84;:::i;:::-;27317:91;;27421:93;27510:3;27421:93;:::i;:::-;27543:1;27538:3;27534:11;27527:18;;27139:416;;;:::o;27565:1255::-;28045:3;28071:148;28215:3;28071:148;:::i;:::-;28064:155;;28240:92;28328:3;28319:6;28240:92;:::i;:::-;28233:99;;28353:148;28497:3;28353:148;:::i;:::-;28346:155;;28522:95;28613:3;28604:6;28522:95;:::i;:::-;28515:102;;28638:148;28782:3;28638:148;:::i;:::-;28631:155;;28807:3;28800:10;;27565:1255;;;;;:::o;28830:237::-;28974:34;28970:1;28962:6;28958:14;28951:58;29047:8;29042:2;29034:6;29030:15;29023:33;28830:237;:::o;29077:382::-;29219:3;29244:67;29308:2;29303:3;29244:67;:::i;:::-;29237:74;;29324:93;29413:3;29324:93;:::i;:::-;29446:2;29441:3;29437:12;29430:19;;29077:382;;;:::o;29469:435::-;29635:4;29677:2;29666:9;29662:18;29654:26;;29730:9;29724:4;29720:20;29716:1;29705:9;29701:17;29694:47;29762:131;29888:4;29762:131;:::i;:::-;29754:139;;29469:435;;;:::o;29914:187::-;30058:31;30054:1;30046:6;30042:14;30035:55;29914:187;:::o;30111:382::-;30253:3;30278:67;30342:2;30337:3;30278:67;:::i;:::-;30271:74;;30358:93;30447:3;30358:93;:::i;:::-;30480:2;30475:3;30471:12;30464:19;;30111:382;;;:::o;30503:435::-;30669:4;30711:2;30700:9;30696:18;30688:26;;30764:9;30758:4;30754:20;30750:1;30739:9;30735:17;30728:47;30796:131;30922:4;30796:131;:::i;:::-;30788:139;;30503:435;;;:::o;30948:155::-;31049:11;31090:3;31075:18;;30948:155;;;;:::o;31113:118::-;;:::o;31241:414::-;31400:3;31425:83;31506:1;31501:3;31425:83;:::i;:::-;31418:90;;31521:93;31610:3;31521:93;:::i;:::-;31643:1;31638:3;31634:11;31627:18;;31241:414;;;:::o;31665:391::-;31849:3;31875:147;32018:3;31875:147;:::i;:::-;31868:154;;32043:3;32036:10;;31665:391;;;:::o;32066:257::-;32210:34;32206:1;32198:6;32194:14;32187:58;32283:28;32278:2;32270:6;32266:15;32259:53;32066:257;:::o;32333:382::-;32475:3;32500:67;32564:2;32559:3;32500:67;:::i;:::-;32493:74;;32580:93;32669:3;32580:93;:::i;:::-;32702:2;32697:3;32693:12;32686:19;;32333:382;;;:::o;32725:435::-;32891:4;32933:2;32922:9;32918:18;32910:26;;32986:9;32980:4;32976:20;32972:1;32961:9;32957:17;32950:47;33018:131;33144:4;33018:131;:::i;:::-;33010:139;;32725:435;;;:::o;33170:106::-;33221:6;33259:5;33253:12;33243:22;;33170:106;;;:::o;33286:180::-;33369:11;33407:6;33402:3;33395:19;33451:4;33446:3;33442:14;33427:29;;33286:180;;;;:::o;33476:380::-;33562:3;33594:38;33626:5;33594:38;:::i;:::-;33652:70;33715:6;33710:3;33652:70;:::i;:::-;33645:77;;33735:52;33780:6;33775:3;33768:4;33761:5;33757:16;33735:52;:::i;:::-;33816:29;33838:6;33816:29;:::i;:::-;33811:3;33807:39;33800:46;;33566:290;33476:380;;;;:::o;33866:668::-;34061:4;34103:3;34092:9;34088:19;34080:27;;34121:71;34189:1;34178:9;34174:17;34165:6;34121:71;:::i;:::-;34206:72;34274:2;34263:9;34259:18;34250:6;34206:72;:::i;:::-;34292;34360:2;34349:9;34345:18;34336:6;34292:72;:::i;:::-;34415:9;34409:4;34405:20;34400:2;34389:9;34385:18;34378:48;34447:76;34518:4;34509:6;34447:76;:::i;:::-;34439:84;;33866:668;;;;;;;:::o;34544:153::-;34600:5;34635:6;34629:13;34620:22;;34655:32;34681:5;34655:32;:::i;:::-;34544:153;;;;:::o;34707:373::-;34776:6;34829:2;34817:9;34808:7;34804:23;34800:32;34797:119;;;34835:79;;:::i;:::-;34797:119;34963:1;34992:63;35047:7;35038:6;35027:9;35023:22;34992:63;:::i;:::-;34982:73;;34930:139;34707:373;;;;:::o;35090:249::-;35129:3;35156:24;35174:5;35156:24;:::i;:::-;35147:33;;35206:66;35199:5;35196:77;35193:103;;35276:18;;:::i;:::-;35193:103;35327:1;35320:5;35316:13;35309:20;;35090:249;;;:::o;35349:196::-;35401:77;35398:1;35391:88;35502:4;35499:1;35492:15;35530:4;35527:1;35520:15;35555:205;35595:1;35616:20;35634:1;35616:20;:::i;:::-;35611:25;;35654:20;35672:1;35654:20;:::i;:::-;35649:25;;35697:1;35687:35;;35702:18;;:::i;:::-;35687:35;35748:1;35745;35741:9;35736:14;;35555:205;;;;:::o;35770:211::-;35810:4;35834:20;35852:1;35834:20;:::i;:::-;35829:25;;35872:20;35890:1;35872:20;:::i;:::-;35867:25;;35915:1;35912;35909:8;35906:34;;;35920:18;;:::i;:::-;35906:34;35969:1;35966;35962:9;35954:17;;35770:211;;;;:::o;35991:196::-;36023:1;36044:20;36062:1;36044:20;:::i;:::-;36039:25;;36082:20;36100:1;36082:20;:::i;:::-;36077:25;;36125:1;36115:35;;36130:18;;:::i;:::-;36115:35;36175:1;36172;36168:9;36163:14;;35991:196;;;;:::o;36197:::-;36249:77;36246:1;36239:88;36350:4;36347:1;36340:15;36378:4;36375:1;36368:15;36403:222;36547:66;36543:1;36535:6;36531:14;36524:90;36403:222;:::o;36635:418::-;36795:3;36820:85;36902:2;36897:3;36820:85;:::i;:::-;36813:92;;36918:93;37007:3;36918:93;:::i;:::-;37040:2;37035:3;37031:12;37024:19;;36635:418;;;:::o;37063:85::-;37100:7;37133:5;37122:16;;37063:85;;;:::o;37158:87::-;37197:7;37230:5;37219:16;;37158:87;;;:::o;37255:165::-;37364:45;37384:24;37402:5;37384:24;:::i;:::-;37364:45;:::i;:::-;37359:3;37352:58;37255:165;;:::o;37430:542::-;37643:3;37669:148;37813:3;37669:148;:::i;:::-;37662:155;;37831:75;37902:3;37893:6;37831:75;:::i;:::-;37935:2;37930:3;37926:12;37919:19;;37959:3;37952:10;;37430:542;;;;:::o;37982:196::-;38034:77;38031:1;38024:88;38135:4;38132:1;38125:15;38163:4;38160:1;38153:15;38188:182;38332:26;38328:1;38320:6;38316:14;38309:50;38188:182;:::o;38380:382::-;38522:3;38547:67;38611:2;38606:3;38547:67;:::i;:::-;38540:74;;38627:93;38716:3;38627:93;:::i;:::-;38749:2;38744:3;38740:12;38733:19;;38380:382;;;:::o;38772:435::-;38938:4;38980:2;38969:9;38965:18;38957:26;;39033:9;39027:4;39023:20;39019:1;39008:9;39004:17;38997:47;39065:131;39191:4;39065:131;:::i;:::-;39057:139;;38772:435;;;:::o;39217:189::-;39361:33;39357:1;39349:6;39345:14;39338:57;39217:189;:::o;39416:382::-;39558:3;39583:67;39647:2;39642:3;39583:67;:::i;:::-;39576:74;;39663:93;39752:3;39663:93;:::i;:::-;39785:2;39780:3;39776:12;39769:19;;39416:382;;;:::o;39808:435::-;39974:4;40016:2;40005:9;40001:18;39993:26;;40069:9;40063:4;40059:20;40055:1;40044:9;40040:17;40033:47;40101:131;40227:4;40101:131;:::i;:::-;40093:139;;39808:435;;;:::o;40253:233::-;40397:34;40393:1;40385:6;40381:14;40374:58;40470:4;40465:2;40457:6;40453:15;40446:29;40253:233;:::o;40496:382::-;40638:3;40663:67;40727:2;40722:3;40663:67;:::i;:::-;40656:74;;40743:93;40832:3;40743:93;:::i;:::-;40865:2;40860:3;40856:12;40849:19;;40496:382;;;:::o;40888:435::-;41054:4;41096:2;41085:9;41081:18;41073:26;;41149:9;41143:4;41139:20;41135:1;41124:9;41120:17;41113:47;41181:131;41307:4;41181:131;:::i;:::-;41173:139;;40888:435;;;:::o;41333:233::-;41477:34;41473:1;41465:6;41461:14;41454:58;41550:4;41545:2;41537:6;41533:15;41526:29;41333:233;:::o;41576:382::-;41718:3;41743:67;41807:2;41802:3;41743:67;:::i;:::-;41736:74;;41823:93;41912:3;41823:93;:::i;:::-;41945:2;41940:3;41936:12;41929:19;;41576:382;;;:::o;41968:435::-;42134:4;42176:2;42165:9;42161:18;42153:26;;42229:9;42223:4;42219:20;42215:1;42204:9;42200:17;42193:47;42261:131;42387:4;42261:131;:::i;:::-;42253:139;;41968:435;;;:::o;42413:126::-;42504:24;42522:5;42504:24;:::i;:::-;42499:3;42492:37;42413:126;;:::o;42549:94::-;42584:7;42628:4;42621:5;42617:16;42606:27;;42549:94;;;:::o;42653:120::-;42740:22;42756:5;42740:22;:::i;:::-;42735:3;42728:35;42653:120;;:::o;42783:569::-;42956:4;42998:3;42987:9;42983:19;42975:27;;43016:71;43084:1;43073:9;43069:17;43060:6;43016:71;:::i;:::-;43101:68;43165:2;43154:9;43150:18;43141:6;43101:68;:::i;:::-;43183:72;43251:2;43240:9;43236:18;43227:6;43183:72;:::i;:::-;43269;43337:2;43326:9;43322:18;43313:6;43269:72;:::i;:::-;42783:569;;;;;;;:::o

Swarm Source

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