ETH Price: $3,408.36 (-0.72%)

Token

HPTHS777INU TRUMPOS (TRUMPOS)
 

Overview

Max Total Supply

132 TRUMPOS

Holders

32

Total Transfers

-

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
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:
HPTHS777INUTRUMPOS

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-09-13
*/

// SPDX-License-Identifier: MIT

//  ____  ____  _______   _________  ____  ____   ______   _______  _______  _______  _____  ____  _____  _____  _____
// |_   ||   _||_   __ \ |  _   _  ||_   ||   _|.' ____ \ |  ___  ||  ___  ||  ___  ||_   _||_   \|_   _||_   _||_   _|
//   | |__| |    | |__) ||_/ | | \_|  | |__| |  | (___ \_||_/  / / |_/  / / |_/  / /   | |    |   \ | |    | |    | |
//   |  __  |    |  ___/     | |      |  __  |   _.____`.     / /      / /      / /    | |    | |\ \| |    | '    ' |
//  _| |  | |_  _| |_       _| |_    _| |  | |_ | \____) |   / /      / /      / /    _| |_  _| |_\   |_    \ \__/ /
// |____||____||_____|     |_____|  |____||____| \______.'  /_/      /_/      /_/    |_____||_____|\____|    `.__.'
//                  _________  _______  _____  _____  ____    ____  _______     ___     ______
//                 |  _   _  ||_   __ \|_   _||_   _||_   \  /   _||_   __ \  .'   `. .' ____ \
//                 |_/ | | \_|  | |__) | | |    | |    |   \/   |    | |__) |/  .-.  \| (___ \_|
//                     | |      |  __ /  | '    ' |    | |\  /| |    |  ___/ | |   | | _.____`.
//                    _| |_    _| |  \ \_ \ \__/ /    _| |_\/_| |_  _| |_    \  `-'  /| \____) |
//                   |_____|  |____| |___| `.__.'    |_____||_____||_____|    `.___.'  \______.'
//

pragma solidity 0.8.19;

// File @openzeppelin/contracts/utils/[email protected]

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

/**
 * @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/utils/introspection/[email protected]

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

/**
 * @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/interfaces/[email protected]

// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)

/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(
        uint256 tokenId,
        uint256 salePrice
    ) external view returns (address receiver, uint256 royaltyAmount);
}

// File @openzeppelin/contracts/token/ERC721/[email protected]

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

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

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

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

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

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

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

// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]

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

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

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

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

// File @openzeppelin/contracts/token/ERC721/[email protected]

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

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

// File @openzeppelin/contracts/utils/[email protected]

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

/**
 * @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
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [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://consensys.net/diligence/blog/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.8.0/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
            functionCallWithValue(
                target,
                data,
                0,
                "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"
        );
        (bool success, bytes memory returndata) = target.call{value: value}(
            data
        );
        return
            verifyCallResultFromTarget(
                target,
                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) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return
            verifyCallResultFromTarget(
                target,
                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) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return
            verifyCallResultFromTarget(
                target,
                success,
                returndata,
                errorMessage
            );
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or 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 {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(
        bytes memory returndata,
        string memory errorMessage
    ) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

// File @openzeppelin/contracts/utils/introspection/[email protected]

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

/**
 * @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/access/[email protected]

// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)

/**
 * @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;
    address private _deployer;

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(
            owner() == _msgSender() || _deployer == _msgSender(),
            "Ownable: caller is not the owner"
        );
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling 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/math/[email protected]

// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(
        uint256 a,
        Rounding rounding
    ) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return
                result +
                (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(
        uint256 value,
        Rounding rounding
    ) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return
                result +
                (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(
        uint256 value,
        Rounding rounding
    ) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return
                result +
                (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(
        uint256 value,
        Rounding rounding
    ) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return
                result +
                (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

// File @openzeppelin/contracts/utils/math/[email protected]

// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two signed numbers.
     */
    function min(int256 a, int256 b) internal pure returns (int256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

// File @openzeppelin/contracts/utils/[email protected]

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

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return
            string(
                abi.encodePacked(
                    value < 0 ? "-" : "",
                    toString(SignedMath.abs(value))
                )
            );
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @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] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

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

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(
        string memory a,
        string memory b
    ) internal pure returns (bool) {
        return keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

// File @openzeppelin/contracts/token/ERC721/[email protected]

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(
        uint256 tokenId
    ) public view virtual override returns (address) {
        address owner = _ownerOf(tokenId);
        require(owner != address(0), "ERC721: invalid token ID");
        return owner;
    }

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

    /**
     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

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

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

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

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

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

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

        // Check that tokenId was not minted by `_beforeTokenTransfer` hook
        require(!_exists(tokenId), "ERC721: token already minted");

        unchecked {
            // Will not overflow unless all 2**256 token ids are minted to the same owner.
            // Given that tokens are minted one by one, it is impossible in practice that
            // this ever happens. Might change if we allow batch minting.
            // The ERC fails to describe this case.
            _balances[to] += 1;
        }

        _owners[tokenId] = to;

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

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

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     * This is an internal function that does not check if the sender is authorized to operate on the token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

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

        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
        owner = ERC721.ownerOf(tokenId);

        // Clear approvals
        delete _tokenApprovals[tokenId];

        unchecked {
            // Cannot overflow, as that would require more tokens to be burned/transferred
            // out than the owner initially received through minting and transferring in.
            _balances[owner] -= 1;
        }
        delete _owners[tokenId];

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

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

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

        _beforeTokenTransfer(from, to, tokenId, 1);

        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
        require(
            ERC721.ownerOf(tokenId) == from,
            "ERC721: transfer from incorrect owner"
        );

        // Clear approvals from the previous owner
        delete _tokenApprovals[tokenId];

        unchecked {
            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
            // `from`'s balance is the number of token held, which is at least one before the current
            // transfer.
            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
            // all 2**256 token ids to be minted, which in practice is impossible.
            _balances[from] -= 1;
            _balances[to] += 1;
        }
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId, 1);
    }

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

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

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

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

    /**
     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
     * - When `from` is zero, the tokens will be minted for `to`.
     * - When `to` is zero, ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual {}

    /**
     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
     * - When `from` is zero, the tokens were minted for `to`.
     * - When `to` is zero, ``from``'s tokens were burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual {}

    /**
     * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
     *
     * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant
     * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such
     * that `ownerOf(tokenId)` is `a`.
     */
    // solhint-disable-next-line func-name-mixedcase
    function __unsafe_increaseBalance(
        address account,
        uint256 amount
    ) internal {
        _balances[account] += amount;
    }
}

// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]

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

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

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

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

// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]

// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol)

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

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

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

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

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

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

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

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

    /**
     * @dev See {ERC721-_beforeTokenTransfer}.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, firstTokenId, batchSize);

        if (batchSize > 1) {
            // Will only trigger during construction. Batch transferring (minting) is not available afterwards.
            revert("ERC721Enumerable: consecutive transfers not supported");
        }

        uint256 tokenId = firstTokenId;

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

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

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

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

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

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

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

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

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

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

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

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

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

// File contracts/HPTHS777INUTRUMPOS.sol

contract HPTHS777INUTRUMPOS is IERC2981, ERC721Enumerable, Ownable {
    using Strings for uint256;

    uint256 public constant maxSupply = 777; // max supply
    uint256 public price = 0.0777 ether;

    string baseURI;
    string public baseExtension = ".json";

    address public royaltyReceiver;
    uint256 public royaltyBps = 700; // 7%

    uint256 public maxAmountPerMint = 77;

    // random mint
    uint256[777] private _availableTokens;
    uint256 private _numAvailableTokens = 777;

    bool public _mintingSeason = true;

    constructor() ERC721("HPTHS777INU TRUMPOS", "TRUMPOS") {
        royaltyReceiver = msg.sender;
    }

    // royaltyInfo
    function royaltyInfo(
        uint256 _tokenId,
        uint256 _salePrice
    ) external view returns (address receiver, uint256 royaltyAmount) {
        receiver = royaltyReceiver;
        royaltyAmount = (_salePrice * royaltyBps) / 10000;
    }

    function mint(uint256 _mintAmount) public payable {
        require(_mintingSeason, "Now is not minting season!");
        uint256 supply = totalSupply();
        require(
            _mintAmount > 0 && _mintAmount <= maxAmountPerMint,
            "Invalid Mint amount."
        );
        require(supply + _mintAmount <= maxSupply, "There is no NFT to mint.");
        require(msg.value >= price * _mintAmount, "Insufficient ETH amount.");
        _mint(_mintAmount);
    }

    function _mint(uint256 _amount) internal {
        uint256 updatedNumAvailableTokens = _numAvailableTokens;
        for (uint256 i = 0; i < _amount; i++) {
            uint256 newTokenId = useRandomAvailableToken(_amount, i);
            _safeMint(msg.sender, newTokenId);
            updatedNumAvailableTokens--;
        }
        _numAvailableTokens = updatedNumAvailableTokens;
    }

    function burn(uint256[] memory tokenids) public onlyOwner {
        for (uint256 i = 0; i < tokenids.length; i++) {
            require(msg.sender == ownerOf(tokenids[i]), "Token not in wallet.");
            _burn(tokenids[i]);
        }
    }

    function walletOfOwner(
        address _owner
    ) public view returns (uint256[] memory) {
        uint256 ownerTokenCount = balanceOf(_owner);
        uint256[] memory tokenIds = new uint256[](ownerTokenCount);
        for (uint256 i; i < ownerTokenCount; i++) {
            tokenIds[i] = tokenOfOwnerByIndex(_owner, i);
        }
        return tokenIds;
    }

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

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

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

    function setPrice(uint256 _price) external onlyOwner {
        price = _price;
    }

    function setBaseURI(string memory _newBaseURI) external onlyOwner {
        baseURI = _newBaseURI;
    }

    function setBaseExtension(
        string memory _newBaseExtension
    ) external onlyOwner {
        baseExtension = _newBaseExtension;
    }

    function withdraw() external onlyOwner {
        require(!_mintingSeason, "Can't withdraw on minting season!");
        uint256 balance = address(this).balance;
        require(balance > 0, "No funds available for withdrawal");
        payable(owner()).transfer(balance);
    }

    function useRandomAvailableToken(
        uint256 _numToFetch,
        uint256 _i
    ) internal returns (uint256) {
        uint256 randomNum = uint256(
            keccak256(
                abi.encode(
                    msg.sender,
                    tx.gasprice,
                    block.number,
                    block.timestamp,
                    blockhash(block.number - 1),
                    _numToFetch,
                    _i
                )
            )
        );
        uint256 randomIndex = randomNum % _numAvailableTokens;
        return useAvailableTokenAtIndex(randomIndex);
    }

    function useAvailableTokenAtIndex(
        uint256 indexToUse
    ) internal returns (uint256) {
        uint256 valAtIndex = _availableTokens[indexToUse];
        uint256 result;
        if (valAtIndex == 0) {
            result = indexToUse;
        } else {
            result = valAtIndex;
        }

        uint256 lastIndex = _numAvailableTokens - 1;
        if (indexToUse != lastIndex) {
            uint256 lastValInArray = _availableTokens[lastIndex];
            if (lastValInArray == 0) {
                _availableTokens[indexToUse] = lastIndex;
            } else {
                _availableTokens[indexToUse] = lastValInArray;
            }
        }

        _numAvailableTokens--;
        return result;
    }

    function setRoyaltyParams(address _adr, uint256 _bps) external onlyOwner {
        require(_adr != address(0), "Invalid contract");
        royaltyReceiver = _adr;
        royaltyBps = _bps;
    }

    function setMaxAmountPerMint(uint256 _maxAmountPerMint) external onlyOwner {
        maxAmountPerMint = _maxAmountPerMint;
    }

    function setMintingSeason(bool _value) external onlyOwner {
        _mintingSeason = _value;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"_mintingSeason","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenids","type":"uint256[]"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","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":"maxAmountPerMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"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":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"royaltyBps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseExtension","type":"string"}],"name":"setBaseExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxAmountPerMint","type":"uint256"}],"name":"setMaxAmountPerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_value","type":"bool"}],"name":"setMintingSeason","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_adr","type":"address"},{"internalType":"uint256","name":"_bps","type":"uint256"}],"name":"setRoyaltyParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6701140bbd030c4000600c5560c06040526005608090815264173539b7b760d91b60a052600e9062000032908262000217565b506102bc601055604d60115561030961031b5561031c805460ff191660011790553480156200006057600080fd5b506040518060400160405280601381526020017f4850544853373737494e55205452554d504f5300000000000000000000000000815250604051806040016040528060078152602001665452554d504f5360c81b8152508160009081620000c8919062000217565b506001620000d7828262000217565b505050620000f4620000ee6200011c60201b60201c565b62000120565b600b8054336001600160a01b03199182168117909255600f80549091169091179055620002e3565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200019d57607f821691505b602082108103620001be57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200021257600081815260208120601f850160051c81016020861015620001ed5750805b601f850160051c820191505b818110156200020e57828155600101620001f9565b5050505b505050565b81516001600160401b0381111562000233576200023362000172565b6200024b8162000244845462000188565b84620001c4565b602080601f8311600181146200028357600084156200026a5750858301515b600019600386901b1c1916600185901b1785556200020e565b600085815260208120601f198616915b82811015620002b45788860151825594840194600190910190840162000293565b5085821015620002d35787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61291d80620002f36000396000f3fe60806040526004361061021a5760003560e01c8063715018a611610123578063b80f55c9116100ab578063d5abeb011161006f578063d5abeb011461061d578063da3ef23f14610633578063df6efbf714610653578063e985e9c514610673578063f2fde38b146106bc57600080fd5b8063b80f55c914610592578063b88d4fde146105b2578063c63adb2b146105d2578063c6682862146105e8578063c87b56dd146105fd57600080fd5b80639fbc8713116100f25780639fbc871314610509578063a035b1fe14610529578063a0712d681461053f578063a22cb46514610552578063ad8e75aa1461057257600080fd5b8063715018a6146104a15780638da5cb5b146104b657806391b7f5ed146104d457806395d89b41146104f457600080fd5b80632a55205a116101a6578063438b630011610175578063438b6300146103f45780634f6ccce71461042157806355f804b3146104415780636352211e1461046157806370a082311461048157600080fd5b80632a55205a146103605780632f745c591461039f5780633ccfd60b146103bf57806342842e0e146103d457600080fd5b8063095ea7b3116101ed578063095ea7b3146102c95780630bd30e2d146102eb57806318160ddd1461030b57806323b872dd1461032a57806327acc76d1461034a57600080fd5b806301f11b0a1461021f57806301ffc9a71461024f57806306fdde031461026f578063081812fc14610291575b600080fd5b34801561022b57600080fd5b5061031c5461023a9060ff1681565b60405190151581526020015b60405180910390f35b34801561025b57600080fd5b5061023a61026a3660046120af565b6106dc565b34801561027b57600080fd5b50610284610707565b604051610246919061211c565b34801561029d57600080fd5b506102b16102ac36600461212f565b610799565b6040516001600160a01b039091168152602001610246565b3480156102d557600080fd5b506102e96102e4366004612164565b6107c0565b005b3480156102f757600080fd5b506102e961030636600461219e565b6108da565b34801561031757600080fd5b506008545b604051908152602001610246565b34801561033657600080fd5b506102e96103453660046121b9565b6108f6565b34801561035657600080fd5b5061031c60115481565b34801561036c57600080fd5b5061038061037b3660046121f5565b610927565b604080516001600160a01b039093168352602083019190915201610246565b3480156103ab57600080fd5b5061031c6103ba366004612164565b61095d565b3480156103cb57600080fd5b506102e96109f3565b3480156103e057600080fd5b506102e96103ef3660046121b9565b610aef565b34801561040057600080fd5b5061041461040f366004612217565b610b0a565b6040516102469190612232565b34801561042d57600080fd5b5061031c61043c36600461212f565b610bac565b34801561044d57600080fd5b506102e961045c366004612315565b610c3f565b34801561046d57600080fd5b506102b161047c36600461212f565b610c53565b34801561048d57600080fd5b5061031c61049c366004612217565b610cb3565b3480156104ad57600080fd5b506102e9610d39565b3480156104c257600080fd5b50600a546001600160a01b03166102b1565b3480156104e057600080fd5b506102e96104ef36600461212f565b610d4d565b34801561050057600080fd5b50610284610d5a565b34801561051557600080fd5b50600f546102b1906001600160a01b031681565b34801561053557600080fd5b5061031c600c5481565b6102e961054d36600461212f565b610d69565b34801561055e57600080fd5b506102e961056d36600461235e565b610edf565b34801561057e57600080fd5b506102e961058d36600461212f565b610eea565b34801561059e57600080fd5b506102e96105ad366004612388565b610ef7565b3480156105be57600080fd5b506102e96105cd36600461242e565b610fb8565b3480156105de57600080fd5b5061031c60105481565b3480156105f457600080fd5b50610284610ff0565b34801561060957600080fd5b5061028461061836600461212f565b61107e565b34801561062957600080fd5b5061031c61030981565b34801561063f57600080fd5b506102e961064e366004612315565b61115c565b34801561065f57600080fd5b506102e961066e366004612164565b611170565b34801561067f57600080fd5b5061023a61068e3660046124aa565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156106c857600080fd5b506102e96106d7366004612217565b6111e7565b60006001600160e01b0319821663780e9d6360e01b1480610701575061070182611260565b92915050565b606060008054610716906124d4565b80601f0160208091040260200160405190810160405280929190818152602001828054610742906124d4565b801561078f5780601f106107645761010080835404028352916020019161078f565b820191906000526020600020905b81548152906001019060200180831161077257829003601f168201915b5050505050905090565b60006107a4826112b0565b506000908152600460205260409020546001600160a01b031690565b60006107cb82610c53565b9050806001600160a01b0316836001600160a01b03160361083d5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806108595750610859813361068e565b6108cb5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610834565b6108d5838361130f565b505050565b6108e261137d565b61031c805460ff1916911515919091179055565b61090033826113ec565b61091c5760405162461bcd60e51b81526004016108349061250e565b6108d583838361146b565b600f546010546001600160a01b03909116906000906127109061094a9085612571565b610954919061259e565b90509250929050565b600061096883610cb3565b82106109ca5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610834565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6109fb61137d565b61031c5460ff1615610a595760405162461bcd60e51b815260206004820152602160248201527f43616e2774207769746864726177206f6e206d696e74696e6720736561736f6e6044820152602160f81b6064820152608401610834565b4780610ab15760405162461bcd60e51b815260206004820152602160248201527f4e6f2066756e647320617661696c61626c6520666f72207769746864726177616044820152601b60fa1b6064820152608401610834565b600a546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015610aeb573d6000803e3d6000fd5b5050565b6108d583838360405180602001604052806000815250610fb8565b60606000610b1783610cb3565b905060008167ffffffffffffffff811115610b3457610b34612276565b604051908082528060200260200182016040528015610b5d578160200160208202803683370190505b50905060005b82811015610ba457610b75858261095d565b828281518110610b8757610b876125b2565b602090810291909101015280610b9c816125c8565b915050610b63565b509392505050565b6000610bb760085490565b8210610c1a5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610834565b60088281548110610c2d57610c2d6125b2565b90600052602060002001549050919050565b610c4761137d565b600d610aeb828261262f565b6000818152600260205260408120546001600160a01b0316806107015760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610834565b60006001600160a01b038216610d1d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610834565b506001600160a01b031660009081526003602052604090205490565b610d4161137d565b610d4b60006115dc565b565b610d5561137d565b600c55565b606060018054610716906124d4565b61031c5460ff16610dbc5760405162461bcd60e51b815260206004820152601a60248201527f4e6f77206973206e6f74206d696e74696e6720736561736f6e210000000000006044820152606401610834565b6000610dc760085490565b9050600082118015610ddb57506011548211155b610e1e5760405162461bcd60e51b815260206004820152601460248201527324b73b30b634b21026b4b73a1030b6b7bab73a1760611b6044820152606401610834565b610309610e2b83836126ef565b1115610e795760405162461bcd60e51b815260206004820152601860248201527f5468657265206973206e6f204e465420746f206d696e742e00000000000000006044820152606401610834565b81600c54610e879190612571565b341015610ed65760405162461bcd60e51b815260206004820152601860248201527f496e73756666696369656e742045544820616d6f756e742e00000000000000006044820152606401610834565b610aeb8261162e565b610aeb33838361167e565b610ef261137d565b601155565b610eff61137d565b60005b8151811015610aeb57610f2d828281518110610f2057610f206125b2565b6020026020010151610c53565b6001600160a01b0316336001600160a01b031614610f845760405162461bcd60e51b81526020600482015260146024820152732a37b5b2b7103737ba1034b7103bb0b63632ba1760611b6044820152606401610834565b610fa6828281518110610f9957610f996125b2565b602002602001015161174c565b80610fb0816125c8565b915050610f02565b610fc233836113ec565b610fde5760405162461bcd60e51b81526004016108349061250e565b610fea848484846117ef565b50505050565b600e8054610ffd906124d4565b80601f0160208091040260200160405190810160405280929190818152602001828054611029906124d4565b80156110765780601f1061104b57610100808354040283529160200191611076565b820191906000526020600020905b81548152906001019060200180831161105957829003601f168201915b505050505081565b6000818152600260205260409020546060906001600160a01b03166110fd5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610834565b6000611107611822565b905060008151116111275760405180602001604052806000815250611155565b8061113184611831565b600e60405160200161114593929190612702565b6040516020818303038152906040525b9392505050565b61116461137d565b600e610aeb828261262f565b61117861137d565b6001600160a01b0382166111c15760405162461bcd60e51b815260206004820152601060248201526f125b9d985b1a590818dbdb9d1c9858dd60821b6044820152606401610834565b600f80546001600160a01b0319166001600160a01b039390931692909217909155601055565b6111ef61137d565b6001600160a01b0381166112545760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610834565b61125d816115dc565b50565b60006001600160e01b031982166380ac58cd60e01b148061129157506001600160e01b03198216635b5e139f60e01b145b8061070157506301ffc9a760e01b6001600160e01b0319831614610701565b6000818152600260205260409020546001600160a01b031661125d5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610834565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061134482610c53565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600a546001600160a01b03163314806113a05750600b546001600160a01b031633145b610d4b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610834565b6000806113f883610c53565b9050806001600160a01b0316846001600160a01b0316148061143f57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806114635750836001600160a01b031661145884610799565b6001600160a01b0316145b949350505050565b826001600160a01b031661147e82610c53565b6001600160a01b0316146114a45760405162461bcd60e51b8152600401610834906127a2565b6001600160a01b0382166115065760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610834565b61151383838360016118c4565b826001600160a01b031661152682610c53565b6001600160a01b03161461154c5760405162461bcd60e51b8152600401610834906127a2565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61031b5460005b8281101561167657600061164984836119f8565b90506116553382611a89565b8261165f816127e7565b93505050808061166e906125c8565b915050611635565b5061031b5550565b816001600160a01b0316836001600160a01b0316036116df5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610834565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b600061175782610c53565b90506117678160008460016118c4565b61177082610c53565b600083815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526003845282852080546000190190558785526002909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6117fa84848461146b565b61180684848484611aa3565b610fea5760405162461bcd60e51b8152600401610834906127fe565b6060600d8054610716906124d4565b6060600061183e83611ba4565b600101905060008167ffffffffffffffff81111561185e5761185e612276565b6040519080825280601f01601f191660200182016040528015611888576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461189257509392505050565b60018111156119335760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610834565b816001600160a01b03851661198f5761198a81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6119b2565b836001600160a01b0316856001600160a01b0316146119b2576119b28582611c7c565b6001600160a01b0384166119ce576119c981611d19565b6119f1565b846001600160a01b0316846001600160a01b0316146119f1576119f18482611dc8565b5050505050565b600080333a4342611a0a600183612850565b604080516001600160a01b039096166020870152850193909352606084019190915260808301524060a082015260c0810185905260e08101849052610100016040516020818303038152906040528051906020012060001c9050600061031b5482611a759190612863565b9050611a8081611e0c565b95945050505050565b610aeb828260405180602001604052806000815250611ecd565b60006001600160a01b0384163b15611b9957604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611ae7903390899088908890600401612877565b6020604051808303816000875af1925050508015611b22575060408051601f3d908101601f19168201909252611b1f918101906128b4565b60015b611b7f573d808015611b50576040519150601f19603f3d011682016040523d82523d6000602084013e611b55565b606091505b508051600003611b775760405162461bcd60e51b8152600401610834906127fe565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611463565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310611be35772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310611c0f576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310611c2d57662386f26fc10000830492506010015b6305f5e1008310611c45576305f5e100830492506008015b6127108310611c5957612710830492506004015b60648310611c6b576064830492506002015b600a83106107015760010192915050565b60006001611c8984610cb3565b611c939190612850565b600083815260076020526040902054909150808214611ce6576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090611d2b90600190612850565b60008381526009602052604081205460088054939450909284908110611d5357611d536125b2565b906000526020600020015490508060088381548110611d7457611d746125b2565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480611dac57611dac6128d1565b6001900381819060005260206000200160009055905550505050565b6000611dd383610cb3565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6000806012836103098110611e2357611e236125b2565b01549050600081600003611e38575082611e3b565b50805b6000600161031b54611e4d9190612850565b9050808514611eae5760006012826103098110611e6c57611e6c6125b2565b0154905080600003611e9457816012876103098110611e8d57611e8d6125b2565b0155611eac565b806012876103098110611ea957611ea96125b2565b01555b505b61031b8054906000611ebf836127e7565b909155509195945050505050565b611ed78383611f00565b611ee46000848484611aa3565b6108d55760405162461bcd60e51b8152600401610834906127fe565b6001600160a01b038216611f565760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610834565b6000818152600260205260409020546001600160a01b031615611fbb5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610834565b611fc96000838360016118c4565b6000818152600260205260409020546001600160a01b03161561202e5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610834565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160e01b03198116811461125d57600080fd5b6000602082840312156120c157600080fd5b813561115581612099565b60005b838110156120e75781810151838201526020016120cf565b50506000910152565b600081518084526121088160208601602086016120cc565b601f01601f19169290920160200192915050565b60208152600061115560208301846120f0565b60006020828403121561214157600080fd5b5035919050565b80356001600160a01b038116811461215f57600080fd5b919050565b6000806040838503121561217757600080fd5b61218083612148565b946020939093013593505050565b8035801515811461215f57600080fd5b6000602082840312156121b057600080fd5b6111558261218e565b6000806000606084860312156121ce57600080fd5b6121d784612148565b92506121e560208501612148565b9150604084013590509250925092565b6000806040838503121561220857600080fd5b50508035926020909101359150565b60006020828403121561222957600080fd5b61115582612148565b6020808252825182820181905260009190848201906040850190845b8181101561226a5783518352928401929184019160010161224e565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156122b5576122b5612276565b604052919050565b600067ffffffffffffffff8311156122d7576122d7612276565b6122ea601f8401601f191660200161228c565b90508281528383830111156122fe57600080fd5b828260208301376000602084830101529392505050565b60006020828403121561232757600080fd5b813567ffffffffffffffff81111561233e57600080fd5b8201601f8101841361234f57600080fd5b611463848235602084016122bd565b6000806040838503121561237157600080fd5b61237a83612148565b91506109546020840161218e565b6000602080838503121561239b57600080fd5b823567ffffffffffffffff808211156123b357600080fd5b818501915085601f8301126123c757600080fd5b8135818111156123d9576123d9612276565b8060051b91506123ea84830161228c565b818152918301840191848101908884111561240457600080fd5b938501935b8385101561242257843582529385019390850190612409565b98975050505050505050565b6000806000806080858703121561244457600080fd5b61244d85612148565b935061245b60208601612148565b925060408501359150606085013567ffffffffffffffff81111561247e57600080fd5b8501601f8101871361248f57600080fd5b61249e878235602084016122bd565b91505092959194509250565b600080604083850312156124bd57600080fd5b6124c683612148565b915061095460208401612148565b600181811c908216806124e857607f821691505b60208210810361250857634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176107015761070161255b565b634e487b7160e01b600052601260045260246000fd5b6000826125ad576125ad612588565b500490565b634e487b7160e01b600052603260045260246000fd5b6000600182016125da576125da61255b565b5060010190565b601f8211156108d557600081815260208120601f850160051c810160208610156126085750805b601f850160051c820191505b8181101561262757828155600101612614565b505050505050565b815167ffffffffffffffff81111561264957612649612276565b61265d8161265784546124d4565b846125e1565b602080601f831160018114612692576000841561267a5750858301515b600019600386901b1c1916600185901b178555612627565b600085815260208120601f198616915b828110156126c1578886015182559484019460019091019084016126a2565b50858210156126df5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808201808211156107015761070161255b565b6000845160206127158285838a016120cc565b8551918401916127288184848a016120cc565b8554920191600090612739816124d4565b60018281168015612751576001811461276657612792565b60ff1984168752821515830287019450612792565b896000528560002060005b8481101561278a57815489820152908301908701612771565b505082870194505b50929a9950505050505050505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b6000816127f6576127f661255b565b506000190190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b818103818111156107015761070161255b565b60008261287257612872612588565b500690565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906128aa908301846120f0565b9695505050505050565b6000602082840312156128c657600080fd5b815161115581612099565b634e487b7160e01b600052603160045260246000fdfea26469706673582212209a5b707469ae36a0e565911597f57d5160afa2907c926a9cdaad7678163cdfad64736f6c63430008130033

Deployed Bytecode

0x60806040526004361061021a5760003560e01c8063715018a611610123578063b80f55c9116100ab578063d5abeb011161006f578063d5abeb011461061d578063da3ef23f14610633578063df6efbf714610653578063e985e9c514610673578063f2fde38b146106bc57600080fd5b8063b80f55c914610592578063b88d4fde146105b2578063c63adb2b146105d2578063c6682862146105e8578063c87b56dd146105fd57600080fd5b80639fbc8713116100f25780639fbc871314610509578063a035b1fe14610529578063a0712d681461053f578063a22cb46514610552578063ad8e75aa1461057257600080fd5b8063715018a6146104a15780638da5cb5b146104b657806391b7f5ed146104d457806395d89b41146104f457600080fd5b80632a55205a116101a6578063438b630011610175578063438b6300146103f45780634f6ccce71461042157806355f804b3146104415780636352211e1461046157806370a082311461048157600080fd5b80632a55205a146103605780632f745c591461039f5780633ccfd60b146103bf57806342842e0e146103d457600080fd5b8063095ea7b3116101ed578063095ea7b3146102c95780630bd30e2d146102eb57806318160ddd1461030b57806323b872dd1461032a57806327acc76d1461034a57600080fd5b806301f11b0a1461021f57806301ffc9a71461024f57806306fdde031461026f578063081812fc14610291575b600080fd5b34801561022b57600080fd5b5061031c5461023a9060ff1681565b60405190151581526020015b60405180910390f35b34801561025b57600080fd5b5061023a61026a3660046120af565b6106dc565b34801561027b57600080fd5b50610284610707565b604051610246919061211c565b34801561029d57600080fd5b506102b16102ac36600461212f565b610799565b6040516001600160a01b039091168152602001610246565b3480156102d557600080fd5b506102e96102e4366004612164565b6107c0565b005b3480156102f757600080fd5b506102e961030636600461219e565b6108da565b34801561031757600080fd5b506008545b604051908152602001610246565b34801561033657600080fd5b506102e96103453660046121b9565b6108f6565b34801561035657600080fd5b5061031c60115481565b34801561036c57600080fd5b5061038061037b3660046121f5565b610927565b604080516001600160a01b039093168352602083019190915201610246565b3480156103ab57600080fd5b5061031c6103ba366004612164565b61095d565b3480156103cb57600080fd5b506102e96109f3565b3480156103e057600080fd5b506102e96103ef3660046121b9565b610aef565b34801561040057600080fd5b5061041461040f366004612217565b610b0a565b6040516102469190612232565b34801561042d57600080fd5b5061031c61043c36600461212f565b610bac565b34801561044d57600080fd5b506102e961045c366004612315565b610c3f565b34801561046d57600080fd5b506102b161047c36600461212f565b610c53565b34801561048d57600080fd5b5061031c61049c366004612217565b610cb3565b3480156104ad57600080fd5b506102e9610d39565b3480156104c257600080fd5b50600a546001600160a01b03166102b1565b3480156104e057600080fd5b506102e96104ef36600461212f565b610d4d565b34801561050057600080fd5b50610284610d5a565b34801561051557600080fd5b50600f546102b1906001600160a01b031681565b34801561053557600080fd5b5061031c600c5481565b6102e961054d36600461212f565b610d69565b34801561055e57600080fd5b506102e961056d36600461235e565b610edf565b34801561057e57600080fd5b506102e961058d36600461212f565b610eea565b34801561059e57600080fd5b506102e96105ad366004612388565b610ef7565b3480156105be57600080fd5b506102e96105cd36600461242e565b610fb8565b3480156105de57600080fd5b5061031c60105481565b3480156105f457600080fd5b50610284610ff0565b34801561060957600080fd5b5061028461061836600461212f565b61107e565b34801561062957600080fd5b5061031c61030981565b34801561063f57600080fd5b506102e961064e366004612315565b61115c565b34801561065f57600080fd5b506102e961066e366004612164565b611170565b34801561067f57600080fd5b5061023a61068e3660046124aa565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156106c857600080fd5b506102e96106d7366004612217565b6111e7565b60006001600160e01b0319821663780e9d6360e01b1480610701575061070182611260565b92915050565b606060008054610716906124d4565b80601f0160208091040260200160405190810160405280929190818152602001828054610742906124d4565b801561078f5780601f106107645761010080835404028352916020019161078f565b820191906000526020600020905b81548152906001019060200180831161077257829003601f168201915b5050505050905090565b60006107a4826112b0565b506000908152600460205260409020546001600160a01b031690565b60006107cb82610c53565b9050806001600160a01b0316836001600160a01b03160361083d5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806108595750610859813361068e565b6108cb5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610834565b6108d5838361130f565b505050565b6108e261137d565b61031c805460ff1916911515919091179055565b61090033826113ec565b61091c5760405162461bcd60e51b81526004016108349061250e565b6108d583838361146b565b600f546010546001600160a01b03909116906000906127109061094a9085612571565b610954919061259e565b90509250929050565b600061096883610cb3565b82106109ca5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610834565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6109fb61137d565b61031c5460ff1615610a595760405162461bcd60e51b815260206004820152602160248201527f43616e2774207769746864726177206f6e206d696e74696e6720736561736f6e6044820152602160f81b6064820152608401610834565b4780610ab15760405162461bcd60e51b815260206004820152602160248201527f4e6f2066756e647320617661696c61626c6520666f72207769746864726177616044820152601b60fa1b6064820152608401610834565b600a546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015610aeb573d6000803e3d6000fd5b5050565b6108d583838360405180602001604052806000815250610fb8565b60606000610b1783610cb3565b905060008167ffffffffffffffff811115610b3457610b34612276565b604051908082528060200260200182016040528015610b5d578160200160208202803683370190505b50905060005b82811015610ba457610b75858261095d565b828281518110610b8757610b876125b2565b602090810291909101015280610b9c816125c8565b915050610b63565b509392505050565b6000610bb760085490565b8210610c1a5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610834565b60088281548110610c2d57610c2d6125b2565b90600052602060002001549050919050565b610c4761137d565b600d610aeb828261262f565b6000818152600260205260408120546001600160a01b0316806107015760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610834565b60006001600160a01b038216610d1d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610834565b506001600160a01b031660009081526003602052604090205490565b610d4161137d565b610d4b60006115dc565b565b610d5561137d565b600c55565b606060018054610716906124d4565b61031c5460ff16610dbc5760405162461bcd60e51b815260206004820152601a60248201527f4e6f77206973206e6f74206d696e74696e6720736561736f6e210000000000006044820152606401610834565b6000610dc760085490565b9050600082118015610ddb57506011548211155b610e1e5760405162461bcd60e51b815260206004820152601460248201527324b73b30b634b21026b4b73a1030b6b7bab73a1760611b6044820152606401610834565b610309610e2b83836126ef565b1115610e795760405162461bcd60e51b815260206004820152601860248201527f5468657265206973206e6f204e465420746f206d696e742e00000000000000006044820152606401610834565b81600c54610e879190612571565b341015610ed65760405162461bcd60e51b815260206004820152601860248201527f496e73756666696369656e742045544820616d6f756e742e00000000000000006044820152606401610834565b610aeb8261162e565b610aeb33838361167e565b610ef261137d565b601155565b610eff61137d565b60005b8151811015610aeb57610f2d828281518110610f2057610f206125b2565b6020026020010151610c53565b6001600160a01b0316336001600160a01b031614610f845760405162461bcd60e51b81526020600482015260146024820152732a37b5b2b7103737ba1034b7103bb0b63632ba1760611b6044820152606401610834565b610fa6828281518110610f9957610f996125b2565b602002602001015161174c565b80610fb0816125c8565b915050610f02565b610fc233836113ec565b610fde5760405162461bcd60e51b81526004016108349061250e565b610fea848484846117ef565b50505050565b600e8054610ffd906124d4565b80601f0160208091040260200160405190810160405280929190818152602001828054611029906124d4565b80156110765780601f1061104b57610100808354040283529160200191611076565b820191906000526020600020905b81548152906001019060200180831161105957829003601f168201915b505050505081565b6000818152600260205260409020546060906001600160a01b03166110fd5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610834565b6000611107611822565b905060008151116111275760405180602001604052806000815250611155565b8061113184611831565b600e60405160200161114593929190612702565b6040516020818303038152906040525b9392505050565b61116461137d565b600e610aeb828261262f565b61117861137d565b6001600160a01b0382166111c15760405162461bcd60e51b815260206004820152601060248201526f125b9d985b1a590818dbdb9d1c9858dd60821b6044820152606401610834565b600f80546001600160a01b0319166001600160a01b039390931692909217909155601055565b6111ef61137d565b6001600160a01b0381166112545760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610834565b61125d816115dc565b50565b60006001600160e01b031982166380ac58cd60e01b148061129157506001600160e01b03198216635b5e139f60e01b145b8061070157506301ffc9a760e01b6001600160e01b0319831614610701565b6000818152600260205260409020546001600160a01b031661125d5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610834565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061134482610c53565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600a546001600160a01b03163314806113a05750600b546001600160a01b031633145b610d4b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610834565b6000806113f883610c53565b9050806001600160a01b0316846001600160a01b0316148061143f57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806114635750836001600160a01b031661145884610799565b6001600160a01b0316145b949350505050565b826001600160a01b031661147e82610c53565b6001600160a01b0316146114a45760405162461bcd60e51b8152600401610834906127a2565b6001600160a01b0382166115065760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610834565b61151383838360016118c4565b826001600160a01b031661152682610c53565b6001600160a01b03161461154c5760405162461bcd60e51b8152600401610834906127a2565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61031b5460005b8281101561167657600061164984836119f8565b90506116553382611a89565b8261165f816127e7565b93505050808061166e906125c8565b915050611635565b5061031b5550565b816001600160a01b0316836001600160a01b0316036116df5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610834565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b600061175782610c53565b90506117678160008460016118c4565b61177082610c53565b600083815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526003845282852080546000190190558785526002909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6117fa84848461146b565b61180684848484611aa3565b610fea5760405162461bcd60e51b8152600401610834906127fe565b6060600d8054610716906124d4565b6060600061183e83611ba4565b600101905060008167ffffffffffffffff81111561185e5761185e612276565b6040519080825280601f01601f191660200182016040528015611888576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461189257509392505050565b60018111156119335760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610834565b816001600160a01b03851661198f5761198a81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6119b2565b836001600160a01b0316856001600160a01b0316146119b2576119b28582611c7c565b6001600160a01b0384166119ce576119c981611d19565b6119f1565b846001600160a01b0316846001600160a01b0316146119f1576119f18482611dc8565b5050505050565b600080333a4342611a0a600183612850565b604080516001600160a01b039096166020870152850193909352606084019190915260808301524060a082015260c0810185905260e08101849052610100016040516020818303038152906040528051906020012060001c9050600061031b5482611a759190612863565b9050611a8081611e0c565b95945050505050565b610aeb828260405180602001604052806000815250611ecd565b60006001600160a01b0384163b15611b9957604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611ae7903390899088908890600401612877565b6020604051808303816000875af1925050508015611b22575060408051601f3d908101601f19168201909252611b1f918101906128b4565b60015b611b7f573d808015611b50576040519150601f19603f3d011682016040523d82523d6000602084013e611b55565b606091505b508051600003611b775760405162461bcd60e51b8152600401610834906127fe565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611463565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310611be35772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310611c0f576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310611c2d57662386f26fc10000830492506010015b6305f5e1008310611c45576305f5e100830492506008015b6127108310611c5957612710830492506004015b60648310611c6b576064830492506002015b600a83106107015760010192915050565b60006001611c8984610cb3565b611c939190612850565b600083815260076020526040902054909150808214611ce6576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090611d2b90600190612850565b60008381526009602052604081205460088054939450909284908110611d5357611d536125b2565b906000526020600020015490508060088381548110611d7457611d746125b2565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480611dac57611dac6128d1565b6001900381819060005260206000200160009055905550505050565b6000611dd383610cb3565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6000806012836103098110611e2357611e236125b2565b01549050600081600003611e38575082611e3b565b50805b6000600161031b54611e4d9190612850565b9050808514611eae5760006012826103098110611e6c57611e6c6125b2565b0154905080600003611e9457816012876103098110611e8d57611e8d6125b2565b0155611eac565b806012876103098110611ea957611ea96125b2565b01555b505b61031b8054906000611ebf836127e7565b909155509195945050505050565b611ed78383611f00565b611ee46000848484611aa3565b6108d55760405162461bcd60e51b8152600401610834906127fe565b6001600160a01b038216611f565760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610834565b6000818152600260205260409020546001600160a01b031615611fbb5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610834565b611fc96000838360016118c4565b6000818152600260205260409020546001600160a01b03161561202e5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610834565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160e01b03198116811461125d57600080fd5b6000602082840312156120c157600080fd5b813561115581612099565b60005b838110156120e75781810151838201526020016120cf565b50506000910152565b600081518084526121088160208601602086016120cc565b601f01601f19169290920160200192915050565b60208152600061115560208301846120f0565b60006020828403121561214157600080fd5b5035919050565b80356001600160a01b038116811461215f57600080fd5b919050565b6000806040838503121561217757600080fd5b61218083612148565b946020939093013593505050565b8035801515811461215f57600080fd5b6000602082840312156121b057600080fd5b6111558261218e565b6000806000606084860312156121ce57600080fd5b6121d784612148565b92506121e560208501612148565b9150604084013590509250925092565b6000806040838503121561220857600080fd5b50508035926020909101359150565b60006020828403121561222957600080fd5b61115582612148565b6020808252825182820181905260009190848201906040850190845b8181101561226a5783518352928401929184019160010161224e565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156122b5576122b5612276565b604052919050565b600067ffffffffffffffff8311156122d7576122d7612276565b6122ea601f8401601f191660200161228c565b90508281528383830111156122fe57600080fd5b828260208301376000602084830101529392505050565b60006020828403121561232757600080fd5b813567ffffffffffffffff81111561233e57600080fd5b8201601f8101841361234f57600080fd5b611463848235602084016122bd565b6000806040838503121561237157600080fd5b61237a83612148565b91506109546020840161218e565b6000602080838503121561239b57600080fd5b823567ffffffffffffffff808211156123b357600080fd5b818501915085601f8301126123c757600080fd5b8135818111156123d9576123d9612276565b8060051b91506123ea84830161228c565b818152918301840191848101908884111561240457600080fd5b938501935b8385101561242257843582529385019390850190612409565b98975050505050505050565b6000806000806080858703121561244457600080fd5b61244d85612148565b935061245b60208601612148565b925060408501359150606085013567ffffffffffffffff81111561247e57600080fd5b8501601f8101871361248f57600080fd5b61249e878235602084016122bd565b91505092959194509250565b600080604083850312156124bd57600080fd5b6124c683612148565b915061095460208401612148565b600181811c908216806124e857607f821691505b60208210810361250857634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176107015761070161255b565b634e487b7160e01b600052601260045260246000fd5b6000826125ad576125ad612588565b500490565b634e487b7160e01b600052603260045260246000fd5b6000600182016125da576125da61255b565b5060010190565b601f8211156108d557600081815260208120601f850160051c810160208610156126085750805b601f850160051c820191505b8181101561262757828155600101612614565b505050505050565b815167ffffffffffffffff81111561264957612649612276565b61265d8161265784546124d4565b846125e1565b602080601f831160018114612692576000841561267a5750858301515b600019600386901b1c1916600185901b178555612627565b600085815260208120601f198616915b828110156126c1578886015182559484019460019091019084016126a2565b50858210156126df5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808201808211156107015761070161255b565b6000845160206127158285838a016120cc565b8551918401916127288184848a016120cc565b8554920191600090612739816124d4565b60018281168015612751576001811461276657612792565b60ff1984168752821515830287019450612792565b896000528560002060005b8481101561278a57815489820152908301908701612771565b505082870194505b50929a9950505050505050505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b6000816127f6576127f661255b565b506000190190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b818103818111156107015761070161255b565b60008261287257612872612588565b500690565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906128aa908301846120f0565b9695505050505050565b6000602082840312156128c657600080fd5b815161115581612099565b634e487b7160e01b600052603160045260246000fdfea26469706673582212209a5b707469ae36a0e565911597f57d5160afa2907c926a9cdaad7678163cdfad64736f6c63430008130033

Deployed Bytecode Sourcemap

69586:5717:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70107:33;;;;;;;;;;-1:-1:-1;70107:33:0;;;;;;;;;;;179:14:1;;172:22;154:41;;142:2;127:18;70107:33:0;;;;;;;;63425:266;;;;;;;;;;-1:-1:-1;63425:266:0;;;;;:::i;:::-;;:::i;45508:100::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;47083:187::-;;;;;;;;;;-1:-1:-1;47083:187:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1697:32:1;;;1679:51;;1667:2;1652:18;47083:187:0;1533:203:1;46601:416:0;;;;;;;;;;-1:-1:-1;46601:416:0;;;;;:::i;:::-;;:::i;:::-;;75200:100;;;;;;;;;;-1:-1:-1;75200:100:0;;;;;:::i;:::-;;:::i;64169:113::-;;;;;;;;;;-1:-1:-1;64257:10:0;:17;64169:113;;;2674:25:1;;;2662:2;2647:18;64169:113:0;2528:177:1;47849:372:0;;;;;;;;;;-1:-1:-1;47849:372:0;;;;;:::i;:::-;;:::i;69948:36::-;;;;;;;;;;;;;;;;70279:253;;;;;;;;;;-1:-1:-1;70279:253:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;3488:32:1;;;3470:51;;3552:2;3537:18;;3530:34;;;;3443:18;70279:253:0;3296:274:1;63775:318:0;;;;;;;;;;-1:-1:-1;63775:318:0;;;;;:::i;:::-;;:::i;73167:282::-;;;;;;;;;;;;;:::i;48292:185::-;;;;;;;;;;-1:-1:-1;48292:185:0;;;;;:::i;:::-;;:::i;71691:374::-;;;;;;;;;;-1:-1:-1;71691:374:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;64359:286::-;;;;;;;;;;-1:-1:-1;64359:286:0;;;;;:::i;:::-;;:::i;72899:106::-;;;;;;;;;;-1:-1:-1;72899:106:0;;;;;:::i;:::-;;:::i;45202:239::-;;;;;;;;;;-1:-1:-1;45202:239:0;;;;;:::i;:::-;;:::i;44880:260::-;;;;;;;;;;-1:-1:-1;44880:260:0;;;;;:::i;:::-;;:::i;24553:103::-;;;;;;;;;;;;;:::i;23846:87::-;;;;;;;;;;-1:-1:-1;23919:6:0;;-1:-1:-1;;;;;23919:6:0;23846:87;;72805:86;;;;;;;;;;-1:-1:-1;72805:86:0;;;;;:::i;:::-;;:::i;45677:104::-;;;;;;;;;;;;;:::i;69865:30::-;;;;;;;;;;-1:-1:-1;69865:30:0;;;;-1:-1:-1;;;;;69865:30:0;;;69754:35;;;;;;;;;;;;;;;;70540:484;;;;;;:::i;:::-;;:::i;47342:180::-;;;;;;;;;;-1:-1:-1;47342:180:0;;;;;:::i;:::-;;:::i;75062:130::-;;;;;;;;;;-1:-1:-1;75062:130:0;;;;;:::i;:::-;;:::i;71434:249::-;;;;;;;;;;-1:-1:-1;71434:249:0;;;;;:::i;:::-;;:::i;48548:359::-;;;;;;;;;;-1:-1:-1;48548:359:0;;;;;:::i;:::-;;:::i;69902:31::-;;;;;;;;;;;;;;;;69819:37;;;;;;;;;;;;;:::i;72189:608::-;;;;;;;;;;-1:-1:-1;72189:608:0;;;;;:::i;:::-;;:::i;69694:39::-;;;;;;;;;;;;69730:3;69694:39;;73013:146;;;;;;;;;;-1:-1:-1;73013:146:0;;;;;:::i;:::-;;:::i;74854:200::-;;;;;;;;;;-1:-1:-1;74854:200:0;;;;;:::i;:::-;;:::i;47593:189::-;;;;;;;;;;-1:-1:-1;47593:189:0;;;;;:::i;:::-;-1:-1:-1;;;;;47739:25:0;;;47715:4;47739:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;47593:189;24811:238;;;;;;;;;;-1:-1:-1;24811:238:0;;;;;:::i;:::-;;:::i;63425:266::-;63543:4;-1:-1:-1;;;;;;63580:50:0;;-1:-1:-1;;;63580:50:0;;:103;;;63647:36;63671:11;63647:23;:36::i;:::-;63560:123;63425:266;-1:-1:-1;;63425:266:0:o;45508:100::-;45562:13;45595:5;45588:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45508:100;:::o;47083:187::-;47175:7;47195:23;47210:7;47195:14;:23::i;:::-;-1:-1:-1;47238:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;47238:24:0;;47083:187::o;46601:416::-;46682:13;46698:23;46713:7;46698:14;:23::i;:::-;46682:39;;46746:5;-1:-1:-1;;;;;46740:11:0;:2;-1:-1:-1;;;;;46740:11:0;;46732:57;;;;-1:-1:-1;;;46732:57:0;;8417:2:1;46732:57:0;;;8399:21:1;8456:2;8436:18;;;8429:30;8495:34;8475:18;;;8468:62;-1:-1:-1;;;8546:18:1;;;8539:31;8587:19;;46732:57:0;;;;;;;;;2102:10;-1:-1:-1;;;;;46824:21:0;;;;:62;;-1:-1:-1;46849:37:0;46866:5;2102:10;47593:189;:::i;46849:37::-;46802:173;;;;-1:-1:-1;;;46802:173:0;;8819:2:1;46802:173:0;;;8801:21:1;8858:2;8838:18;;;8831:30;8897:34;8877:18;;;8870:62;8968:31;8948:18;;;8941:59;9017:19;;46802:173:0;8617:425:1;46802:173:0;46988:21;46997:2;47001:7;46988:8;:21::i;:::-;46671:346;46601:416;;:::o;75200:100::-;23732:13;:11;:13::i;:::-;75269:14:::1;:23:::0;;-1:-1:-1;;75269:23:0::1;::::0;::::1;;::::0;;;::::1;::::0;;75200:100::o;47849:372::-;48058:41;2102:10;48091:7;48058:18;:41::i;:::-;48036:136;;;;-1:-1:-1;;;48036:136:0;;;;;;;:::i;:::-;48185:28;48195:4;48201:2;48205:7;48185:9;:28::i;70279:253::-;70449:15;;70505:10;;-1:-1:-1;;;;;70449:15:0;;;;70386:16;;70519:5;;70492:23;;:10;:23;:::i;:::-;70491:33;;;;:::i;:::-;70475:49;;70279:253;;;;;:::o;63775:318::-;63897:7;63947:23;63964:5;63947:16;:23::i;:::-;63939:5;:31;63917:124;;;;-1:-1:-1;;;63917:124:0;;10225:2:1;63917:124:0;;;10207:21:1;10264:2;10244:18;;;10237:30;10303:34;10283:18;;;10276:62;-1:-1:-1;;;10354:18:1;;;10347:41;10405:19;;63917:124:0;10023:407:1;63917:124:0;-1:-1:-1;;;;;;64059:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;63775:318::o;73167:282::-;23732:13;:11;:13::i;:::-;73226:14:::1;::::0;::::1;;73225:15;73217:61;;;::::0;-1:-1:-1;;;73217:61:0;;10637:2:1;73217:61:0::1;::::0;::::1;10619:21:1::0;10676:2;10656:18;;;10649:30;10715:34;10695:18;;;10688:62;-1:-1:-1;;;10766:18:1;;;10759:31;10807:19;;73217:61:0::1;10435:397:1::0;73217:61:0::1;73307:21;73347:11:::0;73339:57:::1;;;::::0;-1:-1:-1;;;73339:57:0;;11039:2:1;73339:57:0::1;::::0;::::1;11021:21:1::0;11078:2;11058:18;;;11051:30;11117:34;11097:18;;;11090:62;-1:-1:-1;;;11168:18:1;;;11161:31;11209:19;;73339:57:0::1;10837:397:1::0;73339:57:0::1;23919:6:::0;;73407:34:::1;::::0;-1:-1:-1;;;;;23919:6:0;;;;73407:34;::::1;;;::::0;73433:7;;73407:34:::1;::::0;;;73433:7;23919:6;73407:34;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;73206:243;73167:282::o:0;48292:185::-;48430:39;48447:4;48453:2;48457:7;48430:39;;;;;;;;;;;;:16;:39::i;71691:374::-;71767:16;71796:23;71822:17;71832:6;71822:9;:17::i;:::-;71796:43;;71850:25;71892:15;71878:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;71878:30:0;;71850:58;;71924:9;71919:113;71939:15;71935:1;:19;71919:113;;;71990:30;72010:6;72018:1;71990:19;:30::i;:::-;71976:8;71985:1;71976:11;;;;;;;;:::i;:::-;;;;;;;;;;:44;71956:3;;;;:::i;:::-;;;;71919:113;;;-1:-1:-1;72049:8:0;71691:374;-1:-1:-1;;;71691:374:0:o;64359:286::-;64450:7;64500:30;64257:10;:17;;64169:113;64500:30;64492:5;:38;64470:132;;;;-1:-1:-1;;;64470:132:0;;11713:2:1;64470:132:0;;;11695:21:1;11752:2;11732:18;;;11725:30;11791:34;11771:18;;;11764:62;-1:-1:-1;;;11842:18:1;;;11835:42;11894:19;;64470:132:0;11511:408:1;64470:132:0;64620:10;64631:5;64620:17;;;;;;;;:::i;:::-;;;;;;;;;64613:24;;64359:286;;;:::o;72899:106::-;23732:13;:11;:13::i;:::-;72976:7:::1;:21;72986:11:::0;72976:7;:21:::1;:::i;45202:239::-:0;45290:7;50345:16;;;:7;:16;;;;;;-1:-1:-1;;;;;50345:16:0;;45354:56;;;;-1:-1:-1;;;45354:56:0;;14330:2:1;45354:56:0;;;14312:21:1;14369:2;14349:18;;;14342:30;-1:-1:-1;;;14388:18:1;;;14381:54;14452:18;;45354:56:0;14128:348:1;44880:260:0;44968:7;-1:-1:-1;;;;;45010:19:0;;44988:110;;;;-1:-1:-1;;;44988:110:0;;14683:2:1;44988:110:0;;;14665:21:1;14722:2;14702:18;;;14695:30;14761:34;14741:18;;;14734:62;-1:-1:-1;;;14812:18:1;;;14805:39;14861:19;;44988:110:0;14481:405:1;44988:110:0;-1:-1:-1;;;;;;45116:16:0;;;;;:9;:16;;;;;;;44880:260::o;24553:103::-;23732:13;:11;:13::i;:::-;24618:30:::1;24645:1;24618:18;:30::i;:::-;24553:103::o:0;72805:86::-;23732:13;:11;:13::i;:::-;72869:5:::1;:14:::0;72805:86::o;45677:104::-;45733:13;45766:7;45759:14;;;;;:::i;70540:484::-;70609:14;;;;70601:53;;;;-1:-1:-1;;;70601:53:0;;15093:2:1;70601:53:0;;;15075:21:1;15132:2;15112:18;;;15105:30;15171:28;15151:18;;;15144:56;15217:18;;70601:53:0;14891:350:1;70601:53:0;70665:14;70682:13;64257:10;:17;;64169:113;70682:13;70665:30;;70742:1;70728:11;:15;:50;;;;;70762:16;;70747:11;:31;;70728:50;70706:120;;;;-1:-1:-1;;;70706:120:0;;15448:2:1;70706:120:0;;;15430:21:1;15487:2;15467:18;;;15460:30;-1:-1:-1;;;15506:18:1;;;15499:50;15566:18;;70706:120:0;15246:344:1;70706:120:0;69730:3;70845:20;70854:11;70845:6;:20;:::i;:::-;:33;;70837:70;;;;-1:-1:-1;;;70837:70:0;;15927:2:1;70837:70:0;;;15909:21:1;15966:2;15946:18;;;15939:30;16005:26;15985:18;;;15978:54;16049:18;;70837:70:0;15725:348:1;70837:70:0;70947:11;70939:5;;:19;;;;:::i;:::-;70926:9;:32;;70918:69;;;;-1:-1:-1;;;70918:69:0;;16280:2:1;70918:69:0;;;16262:21:1;16319:2;16299:18;;;16292:30;16358:26;16338:18;;;16331:54;16402:18;;70918:69:0;16078:348:1;70918:69:0;70998:18;71004:11;70998:5;:18::i;47342:180::-;47462:52;2102:10;47495:8;47505;47462:18;:52::i;75062:130::-;23732:13;:11;:13::i;:::-;75148:16:::1;:36:::0;75062:130::o;71434:249::-;23732:13;:11;:13::i;:::-;71508:9:::1;71503:173;71527:8;:15;71523:1;:19;71503:173;;;71586:20;71594:8;71603:1;71594:11;;;;;;;;:::i;:::-;;;;;;;71586:7;:20::i;:::-;-1:-1:-1::0;;;;;71572:34:0::1;:10;-1:-1:-1::0;;;;;71572:34:0::1;;71564:67;;;::::0;-1:-1:-1;;;71564:67:0;;16633:2:1;71564:67:0::1;::::0;::::1;16615:21:1::0;16672:2;16652:18;;;16645:30;-1:-1:-1;;;16691:18:1;;;16684:50;16751:18;;71564:67:0::1;16431:344:1::0;71564:67:0::1;71646:18;71652:8;71661:1;71652:11;;;;;;;;:::i;:::-;;;;;;;71646:5;:18::i;:::-;71544:3:::0;::::1;::::0;::::1;:::i;:::-;;;;71503:173;;48548:359:::0;48736:41;2102:10;48769:7;48736:18;:41::i;:::-;48714:136;;;;-1:-1:-1;;;48714:136:0;;;;;;;:::i;:::-;48861:38;48875:4;48881:2;48885:7;48894:4;48861:13;:38::i;:::-;48548:359;;;;:::o;69819:37::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;72189:608::-;50747:4;50345:16;;;:7;:16;;;;;;72278:13;;-1:-1:-1;;;;;50345:16:0;72304:113;;;;-1:-1:-1;;;72304:113:0;;16982:2:1;72304:113:0;;;16964:21:1;17021:2;17001:18;;;16994:30;17060:34;17040:18;;;17033:62;-1:-1:-1;;;17111:18:1;;;17104:45;17166:19;;72304:113:0;16780:411:1;72304:113:0;72430:28;72461:10;:8;:10::i;:::-;72430:41;;72533:1;72508:14;72502:28;:32;:287;;;;;;;;;;;;;;;;;72626:14;72667:18;:7;:16;:18::i;:::-;72712:13;72583:165;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;72502:287;72482:307;72189:608;-1:-1:-1;;;72189:608:0:o;73013:146::-;23732:13;:11;:13::i;:::-;73118::::1;:33;73134:17:::0;73118:13;:33:::1;:::i;74854:200::-:0;23732:13;:11;:13::i;:::-;-1:-1:-1;;;;;74946:18:0;::::1;74938:47;;;::::0;-1:-1:-1;;;74938:47:0;;18659:2:1;74938:47:0::1;::::0;::::1;18641:21:1::0;18698:2;18678:18;;;18671:30;-1:-1:-1;;;18717:18:1;;;18710:46;18773:18;;74938:47:0::1;18457:340:1::0;74938:47:0::1;74996:15;:22:::0;;-1:-1:-1;;;;;;74996:22:0::1;-1:-1:-1::0;;;;;74996:22:0;;;::::1;::::0;;;::::1;::::0;;;75029:10:::1;:17:::0;74854:200::o;24811:238::-;23732:13;:11;:13::i;:::-;-1:-1:-1;;;;;24914:22:0;::::1;24892:110;;;::::0;-1:-1:-1;;;24892:110:0;;19004:2:1;24892:110:0::1;::::0;::::1;18986:21:1::0;19043:2;19023:18;;;19016:30;19082:34;19062:18;;;19055:62;-1:-1:-1;;;19133:18:1;;;19126:36;19179:19;;24892:110:0::1;18802:402:1::0;24892:110:0::1;25013:28;25032:8;25013:18;:28::i;:::-;24811:238:::0;:::o;44495:321::-;44613:4;-1:-1:-1;;;;;;44650:40:0;;-1:-1:-1;;;44650:40:0;;:105;;-1:-1:-1;;;;;;;44707:48:0;;-1:-1:-1;;;44707:48:0;44650:105;:158;;;-1:-1:-1;;;;;;;;;;22489:40:0;;;44772:36;22364:173;57204:135;50747:4;50345:16;;;:7;:16;;;;;;-1:-1:-1;;;;;50345:16:0;57278:53;;;;-1:-1:-1;;;57278:53:0;;14330:2:1;57278:53:0;;;14312:21:1;14369:2;14349:18;;;14342:30;-1:-1:-1;;;14388:18:1;;;14381:54;14452:18;;57278:53:0;14128:348:1;56483:174:0;56558:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;56558:29:0;-1:-1:-1;;;;;56558:29:0;;;;;;;;:24;;56612:23;56558:24;56612:14;:23::i;:::-;-1:-1:-1;;;;;56603:46:0;;;;;;;;;;;56483:174;;:::o;24011:198::-;23919:6;;-1:-1:-1;;;;;23919:6:0;2102:10;24089:23;;:52;;-1:-1:-1;24116:9:0;;-1:-1:-1;;;;;24116:9:0;2102:10;24116:25;24089:52;24067:134;;;;-1:-1:-1;;;24067:134:0;;19411:2:1;24067:134:0;;;19393:21:1;;;19430:18;;;19423:30;19489:34;19469:18;;;19462:62;19541:18;;24067:134:0;19209:356:1;50977:315:0;51095:4;51112:13;51128:23;51143:7;51128:14;:23::i;:::-;51112:39;;51181:5;-1:-1:-1;;;;;51170:16:0;:7;-1:-1:-1;;;;;51170:16:0;;:65;;;-1:-1:-1;;;;;;47739:25:0;;;47715:4;47739:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;51203:32;51170:113;;;;51276:7;-1:-1:-1;;;;;51252:31:0;:20;51264:7;51252:11;:20::i;:::-;-1:-1:-1;;;;;51252:31:0;;51170:113;51162:122;50977:315;-1:-1:-1;;;;50977:315:0:o;55027:1337::-;55200:4;-1:-1:-1;;;;;55173:31:0;:23;55188:7;55173:14;:23::i;:::-;-1:-1:-1;;;;;55173:31:0;;55151:118;;;;-1:-1:-1;;;55151:118:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;55288:16:0;;55280:65;;;;-1:-1:-1;;;55280:65:0;;20178:2:1;55280:65:0;;;20160:21:1;20217:2;20197:18;;;20190:30;20256:34;20236:18;;;20229:62;-1:-1:-1;;;20307:18:1;;;20300:34;20351:19;;55280:65:0;19976:400:1;55280:65:0;55358:42;55379:4;55385:2;55389:7;55398:1;55358:20;:42::i;:::-;55544:4;-1:-1:-1;;;;;55517:31:0;:23;55532:7;55517:14;:23::i;:::-;-1:-1:-1;;;;;55517:31:0;;55495:118;;;;-1:-1:-1;;;55495:118:0;;;;;;;:::i;:::-;55685:24;;;;:15;:24;;;;;;;;55678:31;;-1:-1:-1;;;;;;55678:31:0;;;;;;-1:-1:-1;;;;;56161:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;56161:20:0;;;56196:13;;;;;;;;;:18;;55678:31;56196:18;;;56236:16;;;:7;:16;;;;;;:21;;;;;;;;;;56275:27;;55701:7;;56275:27;;;46671:346;46601:416;;:::o;25209:191::-;25302:6;;;-1:-1:-1;;;;;25319:17:0;;;-1:-1:-1;;;;;;25319:17:0;;;;;;;25352:40;;25302:6;;;25319:17;25302:6;;25352:40;;25283:16;;25352:40;25272:128;25209:191;:::o;71032:394::-;71120:19;;71084:33;71150:211;71174:7;71170:1;:11;71150:211;;;71203:18;71224:35;71248:7;71257:1;71224:23;:35::i;:::-;71203:56;;71274:33;71284:10;71296;71274:9;:33::i;:::-;71322:27;;;;:::i;:::-;;;;71188:173;71183:3;;;;;:::i;:::-;;;;71150:211;;;-1:-1:-1;71371:19:0;:47;-1:-1:-1;71032:394:0:o;56800:315::-;56955:8;-1:-1:-1;;;;;56946:17:0;:5;-1:-1:-1;;;;;56946:17:0;;56938:55;;;;-1:-1:-1;;;56938:55:0;;20724:2:1;56938:55:0;;;20706:21:1;20763:2;20743:18;;;20736:30;20802:27;20782:18;;;20775:55;20847:18;;56938:55:0;20522:349:1;56938:55:0;-1:-1:-1;;;;;57004:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;57004:46:0;;;;;;;;;;57066:41;;154::1;;;57066::0;;127:18:1;57066:41:0;;;;;;;56800:315;;;:::o;53907:783::-;53967:13;53983:23;53998:7;53983:14;:23::i;:::-;53967:39;;54019:51;54040:5;54055:1;54059:7;54068:1;54019:20;:51::i;:::-;54183:23;54198:7;54183:14;:23::i;:::-;54254:24;;;;:15;:24;;;;;;;;54247:31;;-1:-1:-1;;;;;;54247:31:0;;;;;;-1:-1:-1;;;;;54499:16:0;;;;;:9;:16;;;;;:21;;-1:-1:-1;;54499:21:0;;;54549:16;;;:7;:16;;;;;;54542:23;;;;;;;54583:36;54175:31;;-1:-1:-1;54270:7:0;;54583:36;;54254:24;;54583:36;73407:34:::1;73206:243;73167:282::o:0;49788:350::-;49944:28;49954:4;49960:2;49964:7;49944:9;:28::i;:::-;50005:47;50028:4;50034:2;50038:7;50047:4;50005:22;:47::i;:::-;49983:147;;;;-1:-1:-1;;;49983:147:0;;;;;;;:::i;72073:108::-;72133:13;72166:7;72159:14;;;;;:::i;40567:716::-;40623:13;40674:14;40691:17;40702:5;40691:10;:17::i;:::-;40711:1;40691:21;40674:38;;40727:20;40761:6;40750:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40750:18:0;-1:-1:-1;40727:41:0;-1:-1:-1;40892:28:0;;;40908:2;40892:28;40949:288;-1:-1:-1;;40981:5:0;-1:-1:-1;;;41118:2:0;41107:14;;41102:30;40981:5;41089:44;41179:2;41170:11;;;-1:-1:-1;41200:21:0;40949:288;41200:21;-1:-1:-1;41258:6:0;40567:716;-1:-1:-1;;;40567:716:0:o;64719:915::-;64986:1;64974:9;:13;64970:222;;;65117:63;;-1:-1:-1;;;65117:63:0;;21497:2:1;65117:63:0;;;21479:21:1;21536:2;21516:18;;;21509:30;21575:34;21555:18;;;21548:62;-1:-1:-1;;;21626:18:1;;;21619:51;21687:19;;65117:63:0;21295:417:1;64970:222:0;65222:12;-1:-1:-1;;;;;65251:18:0;;65247:187;;65286:40;65318:7;66461:10;:17;;66434:24;;;;:15;:24;;;;;:44;;;66489:24;;;;;;;;;;;;66357:164;65286:40;65247:187;;;65356:2;-1:-1:-1;;;;;65348:10:0;:4;-1:-1:-1;;;;;65348:10:0;;65344:90;;65375:47;65408:4;65414:7;65375:32;:47::i;:::-;-1:-1:-1;;;;;65448:16:0;;65444:183;;65481:45;65518:7;65481:36;:45::i;:::-;65444:183;;;65554:4;-1:-1:-1;;;;;65548:10:0;:2;-1:-1:-1;;;;;65548:10:0;;65544:83;;65575:40;65603:2;65607:7;65575:27;:40::i;:::-;64885:749;64719:915;;;;:::o;73457:630::-;73566:7;;73689:10;73722:11;73756:12;73791:15;73839:16;73854:1;73756:12;73839:16;:::i;:::-;73656:278;;;-1:-1:-1;;;;;22183:32:1;;;73656:278:0;;;22165:51:1;22232:18;;22225:34;;;;22275:18;;;22268:34;;;;22318:18;;;22311:34;73829:27:0;22361:19:1;;;22354:35;22405:19;;;22398:35;;;22449:19;;;22442:35;;;22137:19;;73656:278:0;;;;;;;;;;;;73628:321;;;;;;73606:354;;73586:374;;73971:19;74005;;73993:9;:31;;;;:::i;:::-;73971:53;;74042:37;74067:11;74042:24;:37::i;:::-;74035:44;73457:630;-1:-1:-1;;;;;73457:630:0:o;51634:110::-;51710:26;51720:2;51724:7;51710:26;;;;;;;;;;;;:9;:26::i;57903:1034::-;58057:4;-1:-1:-1;;;;;58078:13:0;;12753:19;:23;58074:856;;58131:174;;-1:-1:-1;;;58131:174:0;;-1:-1:-1;;;;;58131:36:0;;;;;:174;;2102:10;;58225:4;;58252:7;;58282:4;;58131:174;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;58131:174:0;;;;;;;;-1:-1:-1;;58131:174:0;;;;;;;;;;;;:::i;:::-;;;58110:765;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58488:6;:13;58505:1;58488:18;58484:376;;58531:108;;-1:-1:-1;;;58531:108:0;;;;;;;:::i;58484:376::-;58810:6;58804:13;58795:6;58791:2;58787:15;58780:38;58110:765;-1:-1:-1;;;;;;58369:51:0;-1:-1:-1;;;58369:51:0;;-1:-1:-1;58362:58:0;;58074:856;-1:-1:-1;58914:4:0;57903:1034;;;;;;:::o;35994:948::-;36047:7;;-1:-1:-1;;;36125:17:0;;36121:106;;-1:-1:-1;;;36163:17:0;;;-1:-1:-1;36209:2:0;36199:12;36121:106;36254:8;36245:5;:17;36241:106;;36292:8;36283:17;;;-1:-1:-1;36329:2:0;36319:12;36241:106;36374:8;36365:5;:17;36361:106;;36412:8;36403:17;;;-1:-1:-1;36449:2:0;36439:12;36361:106;36494:7;36485:5;:16;36481:103;;36531:7;36522:16;;;-1:-1:-1;36567:1:0;36557:11;36481:103;36611:7;36602:5;:16;36598:103;;36648:7;36639:16;;;-1:-1:-1;36684:1:0;36674:11;36598:103;36728:7;36719:5;:16;36715:103;;36765:7;36756:16;;;-1:-1:-1;36801:1:0;36791:11;36715:103;36845:7;36836:5;:16;36832:68;;36883:1;36873:11;36928:6;35994:948;-1:-1:-1;;35994:948:0:o;67148:1013::-;67439:22;67489:1;67464:22;67481:4;67464:16;:22::i;:::-;:26;;;;:::i;:::-;67501:18;67522:26;;;:17;:26;;;;;;67439:51;;-1:-1:-1;67655:28:0;;;67651:328;;-1:-1:-1;;;;;67722:18:0;;67700:19;67722:18;;;:12;:18;;;;;;;;:34;;;;;;;;;67773:30;;;;;;:44;;;67890:30;;:17;:30;;;;;:43;;;67651:328;-1:-1:-1;68075:26:0;;;;:17;:26;;;;;;;;68068:33;;;-1:-1:-1;;;;;68119:18:0;;;;;:12;:18;;;;;:34;;;;;;;68112:41;67148:1013::o;68456:1079::-;68734:10;:17;68709:22;;68734:21;;68754:1;;68734:21;:::i;:::-;68766:18;68787:24;;;:15;:24;;;;;;69160:10;:26;;68709:46;;-1:-1:-1;68787:24:0;;68709:46;;69160:26;;;;;;:::i;:::-;;;;;;;;;69138:48;;69224:11;69199:10;69210;69199:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;69304:28;;;:15;:28;;;;;;;:41;;;69476:24;;;;;69469:31;69511:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;68527:1008;;;68456:1079;:::o;65935:221::-;66020:14;66037:20;66054:2;66037:16;:20::i;:::-;-1:-1:-1;;;;;66068:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;66113:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;65935:221:0:o;74095:751::-;74183:7;74203:18;74224:16;74241:10;74224:28;;;;;;;:::i;:::-;;;74203:49;;74263:14;74292:10;74306:1;74292:15;74288:119;;-1:-1:-1;74333:10:0;74288:119;;;-1:-1:-1;74385:10:0;74288:119;74419:17;74461:1;74439:19;;:23;;;;:::i;:::-;74419:43;;74491:9;74477:10;:23;74473:308;;74517:22;74542:16;74559:9;74542:27;;;;;;;:::i;:::-;;;74517:52;;74588:14;74606:1;74588:19;74584:186;;74659:9;74628:16;74645:10;74628:28;;;;;;;:::i;:::-;;:40;74584:186;;;74740:14;74709:16;74726:10;74709:28;;;;;;;:::i;:::-;;:45;74584:186;74502:279;74473:308;74793:19;:21;;;:19;:21;;;:::i;:::-;;;;-1:-1:-1;74832:6:0;;74095:751;-1:-1:-1;;;;;74095:751:0:o;51971:319::-;52100:18;52106:2;52110:7;52100:5;:18::i;:::-;52151:53;52182:1;52186:2;52190:7;52199:4;52151:22;:53::i;:::-;52129:153;;;;-1:-1:-1;;;52129:153:0;;;;;;;:::i;52626:942::-;-1:-1:-1;;;;;52706:16:0;;52698:61;;;;-1:-1:-1;;;52698:61:0;;23687:2:1;52698:61:0;;;23669:21:1;;;23706:18;;;23699:30;23765:34;23745:18;;;23738:62;23817:18;;52698:61:0;23485:356:1;52698:61:0;50747:4;50345:16;;;:7;:16;;;;;;-1:-1:-1;;;;;50345:16:0;50771:31;52770:58;;;;-1:-1:-1;;;52770:58:0;;24048:2:1;52770:58:0;;;24030:21:1;24087:2;24067:18;;;24060:30;24126;24106:18;;;24099:58;24174:18;;52770:58:0;23846:352:1;52770:58:0;52841:48;52870:1;52874:2;52878:7;52887:1;52841:20;:48::i;:::-;50747:4;50345:16;;;:7;:16;;;;;;-1:-1:-1;;;;;50345:16:0;50771:31;52979:58;;;;-1:-1:-1;;;52979:58:0;;24048:2:1;52979:58:0;;;24030:21:1;24087:2;24067:18;;;24060:30;24126;24106:18;;;24099:58;24174:18;;52979:58:0;23846:352:1;52979:58:0;-1:-1:-1;;;;;53386:13:0;;;;;;:9;:13;;;;;;;;:18;;53403:1;53386:18;;;53428:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;53428:21:0;;;;;53467:33;53436:7;;53386:13;;53467:33;;53386:13;;53467:33;73407:34:::1;73206:243;73167:282::o:0;206:131:1:-;-1:-1:-1;;;;;;280:32:1;;270:43;;260:71;;327:1;324;317:12;342:245;400:6;453:2;441:9;432:7;428:23;424:32;421:52;;;469:1;466;459:12;421:52;508:9;495:23;527:30;551:5;527:30;:::i;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:1;816:16;;809:27;592:250::o;847:271::-;889:3;927:5;921:12;954:6;949:3;942:19;970:76;1039:6;1032:4;1027:3;1023:14;1016:4;1009:5;1005:16;970:76;:::i;:::-;1100:2;1079:15;-1:-1:-1;;1075:29:1;1066:39;;;;1107:4;1062:50;;847:271;-1:-1:-1;;847:271:1:o;1123:220::-;1272:2;1261:9;1254:21;1235:4;1292:45;1333:2;1322:9;1318:18;1310:6;1292:45;:::i;1348:180::-;1407:6;1460:2;1448:9;1439:7;1435:23;1431:32;1428:52;;;1476:1;1473;1466:12;1428:52;-1:-1:-1;1499:23:1;;1348:180;-1:-1:-1;1348:180:1:o;1741:173::-;1809:20;;-1:-1:-1;;;;;1858:31:1;;1848:42;;1838:70;;1904:1;1901;1894:12;1838:70;1741:173;;;:::o;1919:254::-;1987:6;1995;2048:2;2036:9;2027:7;2023:23;2019:32;2016:52;;;2064:1;2061;2054:12;2016:52;2087:29;2106:9;2087:29;:::i;:::-;2077:39;2163:2;2148:18;;;;2135:32;;-1:-1:-1;;;1919:254:1:o;2178:160::-;2243:20;;2299:13;;2292:21;2282:32;;2272:60;;2328:1;2325;2318:12;2343:180;2399:6;2452:2;2440:9;2431:7;2427:23;2423:32;2420:52;;;2468:1;2465;2458:12;2420:52;2491:26;2507:9;2491:26;:::i;2710:328::-;2787:6;2795;2803;2856:2;2844:9;2835:7;2831:23;2827:32;2824:52;;;2872:1;2869;2862:12;2824:52;2895:29;2914:9;2895:29;:::i;:::-;2885:39;;2943:38;2977:2;2966:9;2962:18;2943:38;:::i;:::-;2933:48;;3028:2;3017:9;3013:18;3000:32;2990:42;;2710:328;;;;;:::o;3043:248::-;3111:6;3119;3172:2;3160:9;3151:7;3147:23;3143:32;3140:52;;;3188:1;3185;3178:12;3140:52;-1:-1:-1;;3211:23:1;;;3281:2;3266:18;;;3253:32;;-1:-1:-1;3043:248:1:o;3575:186::-;3634:6;3687:2;3675:9;3666:7;3662:23;3658:32;3655:52;;;3703:1;3700;3693:12;3655:52;3726:29;3745:9;3726:29;:::i;3766:632::-;3937:2;3989:21;;;4059:13;;3962:18;;;4081:22;;;3908:4;;3937:2;4160:15;;;;4134:2;4119:18;;;3908:4;4203:169;4217:6;4214:1;4211:13;4203:169;;;4278:13;;4266:26;;4347:15;;;;4312:12;;;;4239:1;4232:9;4203:169;;;-1:-1:-1;4389:3:1;;3766:632;-1:-1:-1;;;;;;3766:632:1:o;4403:127::-;4464:10;4459:3;4455:20;4452:1;4445:31;4495:4;4492:1;4485:15;4519:4;4516:1;4509:15;4535:275;4606:2;4600:9;4671:2;4652:13;;-1:-1:-1;;4648:27:1;4636:40;;4706:18;4691:34;;4727:22;;;4688:62;4685:88;;;4753:18;;:::i;:::-;4789:2;4782:22;4535:275;;-1:-1:-1;4535:275:1:o;4815:407::-;4880:5;4914:18;4906:6;4903:30;4900:56;;;4936:18;;:::i;:::-;4974:57;5019:2;4998:15;;-1:-1:-1;;4994:29:1;5025:4;4990:40;4974:57;:::i;:::-;4965:66;;5054:6;5047:5;5040:21;5094:3;5085:6;5080:3;5076:16;5073:25;5070:45;;;5111:1;5108;5101:12;5070:45;5160:6;5155:3;5148:4;5141:5;5137:16;5124:43;5214:1;5207:4;5198:6;5191:5;5187:18;5183:29;5176:40;4815:407;;;;;:::o;5227:451::-;5296:6;5349:2;5337:9;5328:7;5324:23;5320:32;5317:52;;;5365:1;5362;5355:12;5317:52;5405:9;5392:23;5438:18;5430:6;5427:30;5424:50;;;5470:1;5467;5460:12;5424:50;5493:22;;5546:4;5538:13;;5534:27;-1:-1:-1;5524:55:1;;5575:1;5572;5565:12;5524:55;5598:74;5664:7;5659:2;5646:16;5641:2;5637;5633:11;5598:74;:::i;5683:254::-;5748:6;5756;5809:2;5797:9;5788:7;5784:23;5780:32;5777:52;;;5825:1;5822;5815:12;5777:52;5848:29;5867:9;5848:29;:::i;:::-;5838:39;;5896:35;5927:2;5916:9;5912:18;5896:35;:::i;5942:946::-;6026:6;6057:2;6100;6088:9;6079:7;6075:23;6071:32;6068:52;;;6116:1;6113;6106:12;6068:52;6156:9;6143:23;6185:18;6226:2;6218:6;6215:14;6212:34;;;6242:1;6239;6232:12;6212:34;6280:6;6269:9;6265:22;6255:32;;6325:7;6318:4;6314:2;6310:13;6306:27;6296:55;;6347:1;6344;6337:12;6296:55;6383:2;6370:16;6405:2;6401;6398:10;6395:36;;;6411:18;;:::i;:::-;6457:2;6454:1;6450:10;6440:20;;6480:28;6504:2;6500;6496:11;6480:28;:::i;:::-;6542:15;;;6612:11;;;6608:20;;;6573:12;;;;6640:19;;;6637:39;;;6672:1;6669;6662:12;6637:39;6696:11;;;;6716:142;6732:6;6727:3;6724:15;6716:142;;;6798:17;;6786:30;;6749:12;;;;6836;;;;6716:142;;;6877:5;5942:946;-1:-1:-1;;;;;;;;5942:946:1:o;6893:667::-;6988:6;6996;7004;7012;7065:3;7053:9;7044:7;7040:23;7036:33;7033:53;;;7082:1;7079;7072:12;7033:53;7105:29;7124:9;7105:29;:::i;:::-;7095:39;;7153:38;7187:2;7176:9;7172:18;7153:38;:::i;:::-;7143:48;;7238:2;7227:9;7223:18;7210:32;7200:42;;7293:2;7282:9;7278:18;7265:32;7320:18;7312:6;7309:30;7306:50;;;7352:1;7349;7342:12;7306:50;7375:22;;7428:4;7420:13;;7416:27;-1:-1:-1;7406:55:1;;7457:1;7454;7447:12;7406:55;7480:74;7546:7;7541:2;7528:16;7523:2;7519;7515:11;7480:74;:::i;:::-;7470:84;;;6893:667;;;;;;;:::o;7565:260::-;7633:6;7641;7694:2;7682:9;7673:7;7669:23;7665:32;7662:52;;;7710:1;7707;7700:12;7662:52;7733:29;7752:9;7733:29;:::i;:::-;7723:39;;7781:38;7815:2;7804:9;7800:18;7781:38;:::i;7830:380::-;7909:1;7905:12;;;;7952;;;7973:61;;8027:4;8019:6;8015:17;8005:27;;7973:61;8080:2;8072:6;8069:14;8049:18;8046:38;8043:161;;8126:10;8121:3;8117:20;8114:1;8107:31;8161:4;8158:1;8151:15;8189:4;8186:1;8179:15;8043:161;;7830:380;;;:::o;9047:409::-;9249:2;9231:21;;;9288:2;9268:18;;;9261:30;9327:34;9322:2;9307:18;;9300:62;-1:-1:-1;;;9393:2:1;9378:18;;9371:43;9446:3;9431:19;;9047:409::o;9461:127::-;9522:10;9517:3;9513:20;9510:1;9503:31;9553:4;9550:1;9543:15;9577:4;9574:1;9567:15;9593:168;9666:9;;;9697;;9714:15;;;9708:22;;9694:37;9684:71;;9735:18;;:::i;9766:127::-;9827:10;9822:3;9818:20;9815:1;9808:31;9858:4;9855:1;9848:15;9882:4;9879:1;9872:15;9898:120;9938:1;9964;9954:35;;9969:18;;:::i;:::-;-1:-1:-1;10003:9:1;;9898:120::o;11239:127::-;11300:10;11295:3;11291:20;11288:1;11281:31;11331:4;11328:1;11321:15;11355:4;11352:1;11345:15;11371:135;11410:3;11431:17;;;11428:43;;11451:18;;:::i;:::-;-1:-1:-1;11498:1:1;11487:13;;11371:135::o;12050:545::-;12152:2;12147:3;12144:11;12141:448;;;12188:1;12213:5;12209:2;12202:17;12258:4;12254:2;12244:19;12328:2;12316:10;12312:19;12309:1;12305:27;12299:4;12295:38;12364:4;12352:10;12349:20;12346:47;;;-1:-1:-1;12387:4:1;12346:47;12442:2;12437:3;12433:12;12430:1;12426:20;12420:4;12416:31;12406:41;;12497:82;12515:2;12508:5;12505:13;12497:82;;;12560:17;;;12541:1;12530:13;12497:82;;;12501:3;;;12050:545;;;:::o;12771:1352::-;12897:3;12891:10;12924:18;12916:6;12913:30;12910:56;;;12946:18;;:::i;:::-;12975:97;13065:6;13025:38;13057:4;13051:11;13025:38;:::i;:::-;13019:4;12975:97;:::i;:::-;13127:4;;13191:2;13180:14;;13208:1;13203:663;;;;13910:1;13927:6;13924:89;;;-1:-1:-1;13979:19:1;;;13973:26;13924:89;-1:-1:-1;;12728:1:1;12724:11;;;12720:24;12716:29;12706:40;12752:1;12748:11;;;12703:57;14026:81;;13173:944;;13203:663;11997:1;11990:14;;;12034:4;12021:18;;-1:-1:-1;;13239:20:1;;;13357:236;13371:7;13368:1;13365:14;13357:236;;;13460:19;;;13454:26;13439:42;;13552:27;;;;13520:1;13508:14;;;;13387:19;;13357:236;;;13361:3;13621:6;13612:7;13609:19;13606:201;;;13682:19;;;13676:26;-1:-1:-1;;13765:1:1;13761:14;;;13777:3;13757:24;13753:37;13749:42;13734:58;13719:74;;13606:201;-1:-1:-1;;;;;13853:1:1;13837:14;;;13833:22;13820:36;;-1:-1:-1;12771:1352:1:o;15595:125::-;15660:9;;;15681:10;;;15678:36;;;15694:18;;:::i;17196:1256::-;17420:3;17458:6;17452:13;17484:4;17497:64;17554:6;17549:3;17544:2;17536:6;17532:15;17497:64;:::i;:::-;17624:13;;17583:16;;;;17646:68;17624:13;17583:16;17681:15;;;17646:68;:::i;:::-;17803:13;;17736:20;;;17776:1;;17841:36;17803:13;17841:36;:::i;:::-;17896:1;17913:18;;;17940:141;;;;18095:1;18090:337;;;;17906:521;;17940:141;-1:-1:-1;;17975:24:1;;17961:39;;18052:16;;18045:24;18031:39;;18020:51;;;-1:-1:-1;17940:141:1;;18090:337;18121:6;18118:1;18111:17;18169:2;18166:1;18156:16;18194:1;18208:169;18222:8;18219:1;18216:15;18208:169;;;18304:14;;18289:13;;;18282:37;18347:16;;;;18239:10;;18208:169;;;18212:3;;18408:8;18401:5;18397:20;18390:27;;17906:521;-1:-1:-1;18443:3:1;;17196:1256;-1:-1:-1;;;;;;;;;;17196:1256:1:o;19570:401::-;19772:2;19754:21;;;19811:2;19791:18;;;19784:30;19850:34;19845:2;19830:18;;19823:62;-1:-1:-1;;;19916:2:1;19901:18;;19894:35;19961:3;19946:19;;19570:401::o;20381:136::-;20420:3;20448:5;20438:39;;20457:18;;:::i;:::-;-1:-1:-1;;;20493:18:1;;20381:136::o;20876:414::-;21078:2;21060:21;;;21117:2;21097:18;;;21090:30;21156:34;21151:2;21136:18;;21129:62;-1:-1:-1;;;21222:2:1;21207:18;;21200:48;21280:3;21265:19;;20876:414::o;21717:128::-;21784:9;;;21805:11;;;21802:37;;;21819:18;;:::i;22488:112::-;22520:1;22546;22536:35;;22551:18;;:::i;:::-;-1:-1:-1;22585:9:1;;22488:112::o;22605:489::-;-1:-1:-1;;;;;22874:15:1;;;22856:34;;22926:15;;22921:2;22906:18;;22899:43;22973:2;22958:18;;22951:34;;;23021:3;23016:2;23001:18;;22994:31;;;22799:4;;23042:46;;23068:19;;23060:6;23042:46;:::i;:::-;23034:54;22605:489;-1:-1:-1;;;;;;22605:489:1:o;23099:249::-;23168:6;23221:2;23209:9;23200:7;23196:23;23192:32;23189:52;;;23237:1;23234;23227:12;23189:52;23269:9;23263:16;23288:30;23312:5;23288:30;:::i;23353:127::-;23414:10;23409:3;23405:20;23402:1;23395:31;23445:4;23442:1;23435:15;23469:4;23466:1;23459:15

Swarm Source

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