Token Gold Partner Collection

Overview CRC721

Total Supply:
300 GPV2

Holders:
150 addresses
Balance
4 GPV2
0xd156f87ea9f25b7820582b460553ee621eddc258
Loading
[ Download CSV Export  ] 
Loading
[ Download CSV Export  ] 
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
GoldPartnerCollection

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at cronoscan.com on 2023-04-12
*/

pragma solidity ^0.8.0;

// SPDX-License-Identifier: MIT
// 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;
    }
}

// OpenZeppelin Contracts v4.4.1 (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;

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

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

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

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

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

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

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

// OpenZeppelin Contracts v4.4.1 (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
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// OpenZeppelin Contracts v4.4.1 (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 `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

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

// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)
/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

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

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

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

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

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

// OpenZeppelin Contracts v4.4.1 (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: balance query for the zero address"
        );
        return _balances[owner];
    }

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @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 of token that is not own"
        );
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);
    }

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

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

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

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

// OpenZeppelin Contracts v4.4.1 (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 tokenId);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension. This does random batch minting.
 */
contract ERC721r is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    mapping(uint256 => uint256) private _availableTokens;
    uint256 private _numAvailableTokens;
    uint256 immutable _maxSupply;
    // 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_,
        uint256 maxSupply_
    ) {
        _name = name_;
        _symbol = symbol_;
        _maxSupply = maxSupply_;
        _numAvailableTokens = maxSupply_;
    }

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

    function totalSupply() public view virtual returns (uint256) {
        return _maxSupply - _numAvailableTokens;
    }

    function maxSupply() public view virtual returns (uint256) {
        return _maxSupply;
    }

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

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

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

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

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

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

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be 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 = ERC721r.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

    function _mintIdWithoutBalanceUpdate(address to, uint256 tokenId) private {
        _beforeTokenTransfer(address(0), to, tokenId);

        _owners[tokenId] = to;

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

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

    function _mintRandom(address to, uint256 _numToMint) internal virtual {
        require(_msgSender() == tx.origin, "Contracts cannot mint");
        require(to != address(0), "ERC721: mint to the zero address");
        require(_numToMint > 0, "ERC721r: need to mint at least one token");

        // TODO: Probably don't need this as it will underflow and revert automatically in this case
        require(
            _numAvailableTokens >= _numToMint,
            "ERC721r: minting more tokens than available"
        );

        uint256 updatedNumAvailableTokens = _numAvailableTokens;
        for (uint256 i; i < _numToMint; ++i) {
            // Do this ++ unchecked?
            uint256 tokenId = getRandomAvailableTokenId(
                to,
                updatedNumAvailableTokens
            );

            _mintIdWithoutBalanceUpdate(to, tokenId);

            --updatedNumAvailableTokens;
        }

        _numAvailableTokens = updatedNumAvailableTokens;
        _balances[to] += _numToMint;
    }

    function getRandomAvailableTokenId(
        address to,
        uint256 updatedNumAvailableTokens
    ) internal returns (uint256) {
        uint256 randomNum = uint256(
            keccak256(
                abi.encode(
                    to,
                    tx.gasprice,
                    block.number,
                    block.timestamp,
                    block.difficulty,
                    blockhash(block.number - 1),
                    address(this),
                    updatedNumAvailableTokens
                )
            )
        );
        uint256 randomIndex = randomNum % updatedNumAvailableTokens;
        return getAvailableTokenAtIndex(randomIndex, updatedNumAvailableTokens);
    }

    // Implements https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle. Code taken from CryptoPhunksV2
    function getAvailableTokenAtIndex(
        uint256 indexToUse,
        uint256 updatedNumAvailableTokens
    ) internal returns (uint256) {
        uint256 valAtIndex = _availableTokens[indexToUse];
        uint256 result;
        if (valAtIndex == 0) {
            // This means the index itself is still an available token
            result = indexToUse;
        } else {
            // This means the index itself is not an available token, but the val at that index is.
            result = valAtIndex;
        }

        uint256 lastIndex = updatedNumAvailableTokens - 1;
        if (indexToUse != lastIndex) {
            // Replace the value at indexToUse, now that it's been used.
            // Replace it with the data from the last index in the array, since we are going to decrease the array size afterwards.
            uint256 lastValInArray = _availableTokens[lastIndex];
            if (lastValInArray == 0) {
                // This means the index itself is still an available token
                _availableTokens[indexToUse] = lastIndex;
            } else {
                // This means the index itself is not an available token, but the val at that index is.
                _availableTokens[indexToUse] = lastValInArray;
                // Gas refund courtsey of @dievardump
                delete _availableTokens[lastIndex];
            }
        }

        return result;
    }

    // Not as good as minting a specific tokenId, but will behave the same at the start
    // allowing you to explicitly mint some tokens at launch.
    function _mintAtIndex(address to, uint256 index) internal virtual {
        require(_msgSender() == tx.origin, "Contracts cannot mint");
        require(to != address(0), "ERC721: mint to the zero address");
        require(
            _numAvailableTokens >= 1,
            "ERC721r: minting more tokens than available"
        );

        uint256 tokenId = getAvailableTokenAtIndex(index, _numAvailableTokens);
        --_numAvailableTokens;

        _mintIdWithoutBalanceUpdate(to, tokenId);

        _balances[to] += 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(
            ERC721r.ownerOf(tokenId) == from,
            "ERC721: transfer from incorrect owner"
        );
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

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

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

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

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

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

contract GoldPartnerCollection is Ownable, ERC721r {
    using Address for address;

    // @notice total minted NFT number
    string public baseURI;

    // @notice total minted NFT number
    uint256 public nftPrice;

    /**
     * uint256 wallet address
     * uint256 the count which minted the nft from now.
     */
    mapping(address => uint256) public mintedCountMap;

    /**
     * uint256 whitelist primary index
     * uint256 whitelist wallet address
     */
    mapping(uint256 => address) public whitelistMap;

    // @notice whitelist length
    uint256 public whitelistMapLength;

    // @notice discount pros
    uint256 public discount;

    event mintGoldPartnerCollection(uint256 indexed nftId, address indexed owner);

    /**
     * @notice Constructor inherits GoldPartnerCollection
     * @param _baseURIParam ERC721 token baseURI
     */
    constructor(string memory _baseURIParam)
        ERC721r("Gold Partner Collection", "GPV2", 300)
    {
        baseURI = _baseURIParam;
        nftPrice = 100 * 10**18;
        discount = 85;
        whitelistMapLength = 0;
    }

    /**
     * @dev Mint GoldPartnerCollections.
     * @param _mintNum the amount which mint per once
     */
    function MintGoldPartnerCollection(uint256 _mintNum) external payable {
        require(_mintNum <= 5 && _mintNum >= 1, "mintNum err");
        require(mintedCountMap[msg.sender] + _mintNum <= 20, "too many minted");

        uint256 paidAmount = nftPrice * _mintNum;
        for (uint256 i = 0; i < whitelistMapLength; i++) {
            if (msg.sender == whitelistMap[i]) {
                paidAmount = (paidAmount * discount) / 100;
            }
        }
        require(msg.value >= paidAmount, "Not enough MATIC");

        _mintRandom(msg.sender, _mintNum);
    }

    /**
     * @dev Mint GoldPartnerCollections.
     */
    function MintGoldPartnerCollectionByOwner(address _buyer, uint256 _qty)
        external
        onlyOwner
    {
        require(_buyer != address(0), "buyer param err");
        require(_qty > 0, "_qty param err");
        _mintRandom(_buyer, _qty);
    }

    function checkWhiteList(address _addr) external view returns (uint256) {
        for (uint256 i = 0; i < whitelistMapLength; i++) {
            if (_addr == whitelistMap[i]) {
                return 1;
            }
        }
        return 0;
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override
        returns (string memory)
    {
        require(_exists(tokenId), "Token does not exist.");
        return
            string(
                abi.encodePacked(
                    string(
                        abi.encodePacked(baseURI, Strings.toString(tokenId))
                    ),
                    ".json"
                )
            );
    }

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

    /**
     * @dev set baseURI for primary ipfs path
     * @param _baseURIParam new baseURI
     */
    function setBaseURI(string memory _baseURIParam) external onlyOwner {
        baseURI = _baseURIParam;
    }

    /**
     * @dev set new mintable NFT number
     * @param _newNftPrice new mintable NFT number
     */
    function setNewNftPrice(uint256 _newNftPrice) external onlyOwner {
        nftPrice = _newNftPrice;
    }

    /**
     * @notice set discount value
     * @param _discount discount value
     */
    function setDiscount(uint256 _discount) external onlyOwner {
        discount = _discount;
    }

    /**
     * @notice add, update, remove whitelistMap.
     * @param _whitelistAddr whitelist address
     * @param _index the number which will operate
     * @param _mode 0: add 1: update 2: remove
     */
    function manageWhiteList(
        address _whitelistAddr,
        uint256 _index,
        uint16 _mode
    ) external onlyOwner {
        if (_mode == 0) {
            whitelistMap[whitelistMapLength++] = _whitelistAddr;
        } else if (_mode == 1) {
            require(_index < whitelistMapLength, "_index is not valid");
            whitelistMap[_index] = _whitelistAddr;
        } else if (_mode == 2) {
            require(_index < whitelistMapLength, "_index is not valid");
            for (uint256 i = _index; i < whitelistMapLength; i++) {
                whitelistMap[i] = whitelistMap[i + 1];
            }
            whitelistMapLength--;
        }
    }

    function addWhiteList(address[] calldata accounts) public onlyOwner {
        for (uint256 i = 0; i < accounts.length; i++) {
            whitelistMap[whitelistMapLength++] = accounts[i];
        }
    }

    /// @notice withdraw the bnb of the amount (uint256 amount)
    function withdraw() external onlyOwner {
        payable(address(uint160(msg.sender))).transfer(address(this).balance);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_baseURIParam","type":"string"}],"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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"nftId","type":"uint256"},{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"mintGoldPartnerCollection","type":"event"},{"inputs":[{"internalType":"uint256","name":"_mintNum","type":"uint256"}],"name":"MintGoldPartnerCollection","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_buyer","type":"address"},{"internalType":"uint256","name":"_qty","type":"uint256"}],"name":"MintGoldPartnerCollectionByOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"addWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"checkWhiteList","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"discount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_whitelistAddr","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint16","name":"_mode","type":"uint16"}],"name":"manageWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintedCountMap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"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":"_baseURIParam","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_discount","type":"uint256"}],"name":"setDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newNftPrice","type":"uint256"}],"name":"setNewNftPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"whitelistMap","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistMapLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040523480156200001157600080fd5b50604051620027933803806200279383398101604081905262000034916200021e565b6040518060400160405280601781526020017f476f6c6420506172746e657220436f6c6c656374696f6e0000000000000000008152506040518060400160405280600481526020016323a82b1960e11b81525061012c620000a46200009e6200010e60201b60201c565b62000112565b8251620000b990600190602086019062000162565b508151620000cf90600290602085019062000162565b50608081905260045550508051620000ef90600990602084019062000162565b505068056bc75e2d63100000600a556055600e556000600d5562000337565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8280546200017090620002fa565b90600052602060002090601f016020900481019282620001945760008555620001df565b82601f10620001af57805160ff1916838001178555620001df565b82800160010185558215620001df579182015b82811115620001df578251825591602001919060010190620001c2565b50620001ed929150620001f1565b5090565b5b80821115620001ed5760008155600101620001f2565b634e487b7160e01b600052604160045260246000fd5b600060208083850312156200023257600080fd5b82516001600160401b03808211156200024a57600080fd5b818501915085601f8301126200025f57600080fd5b81518181111562000274576200027462000208565b604051601f8201601f19908116603f011681019083821181831017156200029f576200029f62000208565b816040528281528886848701011115620002b857600080fd5b600093505b82841015620002dc5784840186015181850187015292850192620002bd565b82841115620002ee5760008684830101525b98975050505050505050565b600181811c908216806200030f57607f821691505b602082108114156200033157634e487b7160e01b600052602260045260246000fd5b50919050565b6080516124396200035a6000396000818161054a01526108e801526124396000f3fe6080604052600436106101ee5760003560e01c806370a082311161010d578063b88d4fde116100a0578063dabd27191161006f578063dabd27191461056e578063e37ae5541461058e578063e985e9c5146105c4578063ed0817cd1461060d578063f2fde38b1461062d57600080fd5b8063b88d4fde146104ce578063c87b56dd146104ee578063d1cf257d1461050e578063d5abeb011461053b57600080fd5b806395d89b41116100dc57806395d89b41146104665780639cce37c61461047b578063a22cb4651461049b578063a3cfe612146104bb57600080fd5b806370a08231146103f3578063715018a6146104135780638da5cb5b146104285780639008602b1461044657600080fd5b806338cb9c22116101855780635e1045ec116101545780635e1045ec146103885780636352211e146103a85780636b6f4a9d146103c85780636c0360eb146103de57600080fd5b806338cb9c22146103135780633ccfd60b1461033357806342842e0e1461034857806355f804b31461036857600080fd5b80630d39fc81116101c15780630d39fc81146102a457806318160ddd146102c857806323b872dd146102dd578063258105be146102fd57600080fd5b806301ffc9a7146101f357806306fdde0314610228578063081812fc1461024a578063095ea7b314610282575b600080fd5b3480156101ff57600080fd5b5061021361020e366004611d08565b61064d565b60405190151581526020015b60405180910390f35b34801561023457600080fd5b5061023d61069f565b60405161021f9190611d84565b34801561025657600080fd5b5061026a610265366004611d97565b610731565b6040516001600160a01b03909116815260200161021f565b34801561028e57600080fd5b506102a261029d366004611dcc565b6107cb565b005b3480156102b057600080fd5b506102ba600a5481565b60405190815260200161021f565b3480156102d457600080fd5b506102ba6108e1565b3480156102e957600080fd5b506102a26102f8366004611df6565b610916565b34801561030957600080fd5b506102ba600d5481565b34801561031f57600080fd5b506102a261032e366004611e32565b610947565b34801561033f57600080fd5b506102a2610b25565b34801561035457600080fd5b506102a2610363366004611df6565b610b7e565b34801561037457600080fd5b506102a2610383366004611f05565b610b99565b34801561039457600080fd5b506102a26103a3366004611f4e565b610bda565b3480156103b457600080fd5b5061026a6103c3366004611d97565b610c8f565b3480156103d457600080fd5b506102ba600e5481565b3480156103ea57600080fd5b5061023d610d06565b3480156103ff57600080fd5b506102ba61040e366004611fc3565b610d94565b34801561041f57600080fd5b506102a2610e1b565b34801561043457600080fd5b506000546001600160a01b031661026a565b34801561045257600080fd5b506102a2610461366004611dcc565b610e51565b34801561047257600080fd5b5061023d610f0e565b34801561048757600080fd5b506102ba610496366004611fc3565b610f1d565b3480156104a757600080fd5b506102a26104b6366004611fde565b610f71565b6102a26104c9366004611d97565b610f7c565b3480156104da57600080fd5b506102a26104e936600461201a565b6110e1565b3480156104fa57600080fd5b5061023d610509366004611d97565b611119565b34801561051a57600080fd5b506102ba610529366004611fc3565b600b6020526000908152604090205481565b34801561054757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102ba565b34801561057a57600080fd5b506102a2610589366004611d97565b6111c7565b34801561059a57600080fd5b5061026a6105a9366004611d97565b600c602052600090815260409020546001600160a01b031681565b3480156105d057600080fd5b506102136105df366004612096565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205460ff1690565b34801561061957600080fd5b506102a2610628366004611d97565b6111f6565b34801561063957600080fd5b506102a2610648366004611fc3565b611225565b60006001600160e01b031982166380ac58cd60e01b148061067e57506001600160e01b03198216635b5e139f60e01b145b8061069957506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600180546106ae906120c9565b80601f01602080910402602001604051908101604052809291908181526020018280546106da906120c9565b80156107275780601f106106fc57610100808354040283529160200191610727565b820191906000526020600020905b81548152906001019060200180831161070a57829003601f168201915b5050505050905090565b6000818152600560205260408120546001600160a01b03166107af5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600760205260409020546001600160a01b031690565b60006107d682610c8f565b9050806001600160a01b0316836001600160a01b031614156108445760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016107a6565b336001600160a01b0382161480610860575061086081336105df565b6108d25760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016107a6565b6108dc83836112bd565b505050565b60006004547f0000000000000000000000000000000000000000000000000000000000000000610911919061211a565b905090565b610920338261132b565b61093c5760405162461bcd60e51b81526004016107a690612131565b6108dc838383611422565b6000546001600160a01b031633146109715760405162461bcd60e51b81526004016107a690612182565b61ffff81166109cb57600d80548491600c9160009182610990836121b7565b91905055815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550505050565b8061ffff1660011415610a4d57600d548210610a1f5760405162461bcd60e51b815260206004820152601360248201527217da5b99195e081a5cc81b9bdd081d985b1a59606a1b60448201526064016107a6565b6000828152600c6020526040902080546001600160a01b0385166001600160a01b0319909116179055505050565b8061ffff16600214156108dc57600d548210610aa15760405162461bcd60e51b815260206004820152601360248201527217da5b99195e081a5cc81b9bdd081d985b1a59606a1b60448201526064016107a6565b815b600d54811015610b0a57600c6000610abc8360016121d2565b81526020808201929092526040908101600090812054848252600c9093522080546001600160a01b0319166001600160a01b0390921691909117905580610b02816121b7565b915050610aa3565b50600d8054906000610b1b836121ea565b9190505550505050565b6000546001600160a01b03163314610b4f5760405162461bcd60e51b81526004016107a690612182565b60405133904780156108fc02916000818181858888f19350505050158015610b7b573d6000803e3d6000fd5b50565b6108dc838383604051806020016040528060008152506110e1565b6000546001600160a01b03163314610bc35760405162461bcd60e51b81526004016107a690612182565b8051610bd6906009906020840190611c59565b5050565b6000546001600160a01b03163314610c045760405162461bcd60e51b81526004016107a690612182565b60005b818110156108dc57828282818110610c2157610c21612201565b9050602002016020810190610c369190611fc3565b600d8054600c916000919082610c4b836121b7565b909155508152602081019190915260400160002080546001600160a01b0319166001600160a01b039290921691909117905580610c87816121b7565b915050610c07565b6000818152600560205260408120546001600160a01b0316806106995760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016107a6565b60098054610d13906120c9565b80601f0160208091040260200160405190810160405280929190818152602001828054610d3f906120c9565b8015610d8c5780601f10610d6157610100808354040283529160200191610d8c565b820191906000526020600020905b815481529060010190602001808311610d6f57829003601f168201915b505050505081565b60006001600160a01b038216610dff5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016107a6565b506001600160a01b031660009081526006602052604090205490565b6000546001600160a01b03163314610e455760405162461bcd60e51b81526004016107a690612182565b610e4f60006115be565b565b6000546001600160a01b03163314610e7b5760405162461bcd60e51b81526004016107a690612182565b6001600160a01b038216610ec35760405162461bcd60e51b815260206004820152600f60248201526e313abcb2b9103830b930b69032b93960891b60448201526064016107a6565b60008111610f045760405162461bcd60e51b815260206004820152600e60248201526d2fb8ba3c903830b930b69032b93960911b60448201526064016107a6565b610bd6828261160e565b6060600280546106ae906120c9565b6000805b600d54811015610f68576000818152600c60205260409020546001600160a01b0384811691161415610f565750600192915050565b80610f60816121b7565b915050610f21565b50600092915050565b610bd63383836117ed565b60058111158015610f8e575060018110155b610fc85760405162461bcd60e51b815260206004820152600b60248201526a36b4b73a273ab69032b93960a91b60448201526064016107a6565b336000908152600b6020526040902054601490610fe69083906121d2565b11156110265760405162461bcd60e51b815260206004820152600f60248201526e1d1bdbc81b585b9e481b5a5b9d1959608a1b60448201526064016107a6565b600081600a546110369190612217565b905060005b600d54811015611093576000818152600c60205260409020546001600160a01b0316331415611081576064600e54836110749190612217565b61107e919061224c565b91505b8061108b816121b7565b91505061103b565b50803410156110d75760405162461bcd60e51b815260206004820152601060248201526f4e6f7420656e6f756768204d4154494360801b60448201526064016107a6565b610bd6338361160e565b6110eb338361132b565b6111075760405162461bcd60e51b81526004016107a690612131565b611113848484846118bc565b50505050565b6000818152600560205260409020546060906001600160a01b03166111785760405162461bcd60e51b81526020600482015260156024820152742a37b5b2b7103237b2b9903737ba1032bc34b9ba1760591b60448201526064016107a6565b6009611183836118ef565b60405160200161119492919061227c565b60408051601f19818403018152908290526111b19160200161231a565b6040516020818303038152906040529050919050565b6000546001600160a01b031633146111f15760405162461bcd60e51b81526004016107a690612182565b600e55565b6000546001600160a01b031633146112205760405162461bcd60e51b81526004016107a690612182565b600a55565b6000546001600160a01b0316331461124f5760405162461bcd60e51b81526004016107a690612182565b6001600160a01b0381166112b45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107a6565b610b7b816115be565b600081815260076020526040902080546001600160a01b0319166001600160a01b03841690811790915581906112f282610c8f565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600560205260408120546001600160a01b03166113a45760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016107a6565b60006113af83610c8f565b9050806001600160a01b0316846001600160a01b031614806113ea5750836001600160a01b03166113df84610731565b6001600160a01b0316145b8061141a57506001600160a01b0380821660009081526008602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661143582610c8f565b6001600160a01b0316146114995760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016107a6565b6001600160a01b0382166114fb5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016107a6565b6115066000826112bd565b6001600160a01b038316600090815260066020526040812080546001929061152f90849061211a565b90915550506001600160a01b038216600090815260066020526040812080546001929061155d9084906121d2565b909155505060008181526005602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b3332146116555760405162461bcd60e51b815260206004820152601560248201527410dbdb9d1c9858dd1cc818d85b9b9bdd081b5a5b9d605a1b60448201526064016107a6565b6001600160a01b0382166116ab5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016107a6565b6000811161170c5760405162461bcd60e51b815260206004820152602860248201527f455243373231723a206e65656420746f206d696e74206174206c65617374206f6044820152673732903a37b5b2b760c11b60648201526084016107a6565b8060045410156117725760405162461bcd60e51b815260206004820152602b60248201527f455243373231723a206d696e74696e67206d6f726520746f6b656e732074686160448201526a6e20617661696c61626c6560a81b60648201526084016107a6565b60045460005b828110156117b557600061178c85846119ed565b90506117988582611a7f565b6117a1836121ea565b925050806117ae906121b7565b9050611778565b5060048190556001600160a01b038316600090815260066020526040812080548492906117e39084906121d2565b9091555050505050565b816001600160a01b0316836001600160a01b0316141561184f5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016107a6565b6001600160a01b03838116600081815260086020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6118c7848484611422565b6118d384848484611ad8565b6111135760405162461bcd60e51b81526004016107a690612343565b6060816119135750506040805180820190915260018152600360fc1b602082015290565b8160005b811561193d5780611927816121b7565b91506119369050600a8361224c565b9150611917565b60008167ffffffffffffffff81111561195857611958611e79565b6040519080825280601f01601f191660200182016040528015611982576020820181803683370190505b5090505b841561141a5761199760018361211a565b91506119a4600a86612395565b6119af9060306121d2565b60f81b8183815181106119c4576119c4612201565b60200101906001600160f81b031916908160001a9053506119e6600a8661224c565b9450611986565b600080833a434244611a0060018461211a565b604080516001600160a01b0390971660208801528601949094526060850192909252608084015260a08301524060c08201523060e082015261010081018490526101200160408051601f19818403018152919052805160209091012090506000611a6a8483612395565b9050611a768185611bd6565b95945050505050565b60008181526005602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160a01b0384163b15611bcb57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611b1c9033908990889088906004016123a9565b6020604051808303816000875af1925050508015611b57575060408051601f3d908101601f19168201909252611b54918101906123e6565b60015b611bb1573d808015611b85576040519150601f19603f3d011682016040523d82523d6000602084013e611b8a565b606091505b508051611ba95760405162461bcd60e51b81526004016107a690612343565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061141a565b506001949350505050565b6000828152600360205260408120548181611bf2575083611bf5565b50805b6000611c0260018661211a565b9050808614611c505760008181526003602052604090205480611c35576000878152600360205260409020829055611c4e565b6000878152600360205260408082208390558382528120555b505b50949350505050565b828054611c65906120c9565b90600052602060002090601f016020900481019282611c875760008555611ccd565b82601f10611ca057805160ff1916838001178555611ccd565b82800160010185558215611ccd579182015b82811115611ccd578251825591602001919060010190611cb2565b50611cd9929150611cdd565b5090565b5b80821115611cd95760008155600101611cde565b6001600160e01b031981168114610b7b57600080fd5b600060208284031215611d1a57600080fd5b8135611d2581611cf2565b9392505050565b60005b83811015611d47578181015183820152602001611d2f565b838111156111135750506000910152565b60008151808452611d70816020860160208601611d2c565b601f01601f19169290920160200192915050565b602081526000611d256020830184611d58565b600060208284031215611da957600080fd5b5035919050565b80356001600160a01b0381168114611dc757600080fd5b919050565b60008060408385031215611ddf57600080fd5b611de883611db0565b946020939093013593505050565b600080600060608486031215611e0b57600080fd5b611e1484611db0565b9250611e2260208501611db0565b9150604084013590509250925092565b600080600060608486031215611e4757600080fd5b611e5084611db0565b925060208401359150604084013561ffff81168114611e6e57600080fd5b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115611eaa57611eaa611e79565b604051601f8501601f19908116603f01168101908282118183101715611ed257611ed2611e79565b81604052809350858152868686011115611eeb57600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215611f1757600080fd5b813567ffffffffffffffff811115611f2e57600080fd5b8201601f81018413611f3f57600080fd5b61141a84823560208401611e8f565b60008060208385031215611f6157600080fd5b823567ffffffffffffffff80821115611f7957600080fd5b818501915085601f830112611f8d57600080fd5b813581811115611f9c57600080fd5b8660208260051b8501011115611fb157600080fd5b60209290920196919550909350505050565b600060208284031215611fd557600080fd5b611d2582611db0565b60008060408385031215611ff157600080fd5b611ffa83611db0565b91506020830135801515811461200f57600080fd5b809150509250929050565b6000806000806080858703121561203057600080fd5b61203985611db0565b935061204760208601611db0565b925060408501359150606085013567ffffffffffffffff81111561206a57600080fd5b8501601f8101871361207b57600080fd5b61208a87823560208401611e8f565b91505092959194509250565b600080604083850312156120a957600080fd5b6120b283611db0565b91506120c060208401611db0565b90509250929050565b600181811c908216806120dd57607f821691505b602082108114156120fe57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60008282101561212c5761212c612104565b500390565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60006000198214156121cb576121cb612104565b5060010190565b600082198211156121e5576121e5612104565b500190565b6000816121f9576121f9612104565b506000190190565b634e487b7160e01b600052603260045260246000fd5b600081600019048311821515161561223157612231612104565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261225b5761225b612236565b500490565b60008151612272818560208601611d2c565b9290920192915050565b600080845481600182811c91508083168061229857607f831692505b60208084108214156122b857634e487b7160e01b86526022600452602486fd5b8180156122cc57600181146122dd5761230a565b60ff1986168952848901965061230a565b60008b81526020902060005b868110156123025781548b8201529085019083016122e9565b505084890196505b505050505050611a768185612260565b6000825161232c818460208701611d2c565b64173539b7b760d91b920191825250600501919050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000826123a4576123a4612236565b500690565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906123dc90830184611d58565b9695505050505050565b6000602082840312156123f857600080fd5b8151611d2581611cf256fea2646970667358221220134a6b91a34adf3f3ff53dc99b77a3af2a3849a788828d6d2e8a36c4b47ec03c64736f6c634300080a003300000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106101ee5760003560e01c806370a082311161010d578063b88d4fde116100a0578063dabd27191161006f578063dabd27191461056e578063e37ae5541461058e578063e985e9c5146105c4578063ed0817cd1461060d578063f2fde38b1461062d57600080fd5b8063b88d4fde146104ce578063c87b56dd146104ee578063d1cf257d1461050e578063d5abeb011461053b57600080fd5b806395d89b41116100dc57806395d89b41146104665780639cce37c61461047b578063a22cb4651461049b578063a3cfe612146104bb57600080fd5b806370a08231146103f3578063715018a6146104135780638da5cb5b146104285780639008602b1461044657600080fd5b806338cb9c22116101855780635e1045ec116101545780635e1045ec146103885780636352211e146103a85780636b6f4a9d146103c85780636c0360eb146103de57600080fd5b806338cb9c22146103135780633ccfd60b1461033357806342842e0e1461034857806355f804b31461036857600080fd5b80630d39fc81116101c15780630d39fc81146102a457806318160ddd146102c857806323b872dd146102dd578063258105be146102fd57600080fd5b806301ffc9a7146101f357806306fdde0314610228578063081812fc1461024a578063095ea7b314610282575b600080fd5b3480156101ff57600080fd5b5061021361020e366004611d08565b61064d565b60405190151581526020015b60405180910390f35b34801561023457600080fd5b5061023d61069f565b60405161021f9190611d84565b34801561025657600080fd5b5061026a610265366004611d97565b610731565b6040516001600160a01b03909116815260200161021f565b34801561028e57600080fd5b506102a261029d366004611dcc565b6107cb565b005b3480156102b057600080fd5b506102ba600a5481565b60405190815260200161021f565b3480156102d457600080fd5b506102ba6108e1565b3480156102e957600080fd5b506102a26102f8366004611df6565b610916565b34801561030957600080fd5b506102ba600d5481565b34801561031f57600080fd5b506102a261032e366004611e32565b610947565b34801561033f57600080fd5b506102a2610b25565b34801561035457600080fd5b506102a2610363366004611df6565b610b7e565b34801561037457600080fd5b506102a2610383366004611f05565b610b99565b34801561039457600080fd5b506102a26103a3366004611f4e565b610bda565b3480156103b457600080fd5b5061026a6103c3366004611d97565b610c8f565b3480156103d457600080fd5b506102ba600e5481565b3480156103ea57600080fd5b5061023d610d06565b3480156103ff57600080fd5b506102ba61040e366004611fc3565b610d94565b34801561041f57600080fd5b506102a2610e1b565b34801561043457600080fd5b506000546001600160a01b031661026a565b34801561045257600080fd5b506102a2610461366004611dcc565b610e51565b34801561047257600080fd5b5061023d610f0e565b34801561048757600080fd5b506102ba610496366004611fc3565b610f1d565b3480156104a757600080fd5b506102a26104b6366004611fde565b610f71565b6102a26104c9366004611d97565b610f7c565b3480156104da57600080fd5b506102a26104e936600461201a565b6110e1565b3480156104fa57600080fd5b5061023d610509366004611d97565b611119565b34801561051a57600080fd5b506102ba610529366004611fc3565b600b6020526000908152604090205481565b34801561054757600080fd5b507f000000000000000000000000000000000000000000000000000000000000012c6102ba565b34801561057a57600080fd5b506102a2610589366004611d97565b6111c7565b34801561059a57600080fd5b5061026a6105a9366004611d97565b600c602052600090815260409020546001600160a01b031681565b3480156105d057600080fd5b506102136105df366004612096565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205460ff1690565b34801561061957600080fd5b506102a2610628366004611d97565b6111f6565b34801561063957600080fd5b506102a2610648366004611fc3565b611225565b60006001600160e01b031982166380ac58cd60e01b148061067e57506001600160e01b03198216635b5e139f60e01b145b8061069957506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600180546106ae906120c9565b80601f01602080910402602001604051908101604052809291908181526020018280546106da906120c9565b80156107275780601f106106fc57610100808354040283529160200191610727565b820191906000526020600020905b81548152906001019060200180831161070a57829003601f168201915b5050505050905090565b6000818152600560205260408120546001600160a01b03166107af5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600760205260409020546001600160a01b031690565b60006107d682610c8f565b9050806001600160a01b0316836001600160a01b031614156108445760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016107a6565b336001600160a01b0382161480610860575061086081336105df565b6108d25760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016107a6565b6108dc83836112bd565b505050565b60006004547f000000000000000000000000000000000000000000000000000000000000012c610911919061211a565b905090565b610920338261132b565b61093c5760405162461bcd60e51b81526004016107a690612131565b6108dc838383611422565b6000546001600160a01b031633146109715760405162461bcd60e51b81526004016107a690612182565b61ffff81166109cb57600d80548491600c9160009182610990836121b7565b91905055815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550505050565b8061ffff1660011415610a4d57600d548210610a1f5760405162461bcd60e51b815260206004820152601360248201527217da5b99195e081a5cc81b9bdd081d985b1a59606a1b60448201526064016107a6565b6000828152600c6020526040902080546001600160a01b0385166001600160a01b0319909116179055505050565b8061ffff16600214156108dc57600d548210610aa15760405162461bcd60e51b815260206004820152601360248201527217da5b99195e081a5cc81b9bdd081d985b1a59606a1b60448201526064016107a6565b815b600d54811015610b0a57600c6000610abc8360016121d2565b81526020808201929092526040908101600090812054848252600c9093522080546001600160a01b0319166001600160a01b0390921691909117905580610b02816121b7565b915050610aa3565b50600d8054906000610b1b836121ea565b9190505550505050565b6000546001600160a01b03163314610b4f5760405162461bcd60e51b81526004016107a690612182565b60405133904780156108fc02916000818181858888f19350505050158015610b7b573d6000803e3d6000fd5b50565b6108dc838383604051806020016040528060008152506110e1565b6000546001600160a01b03163314610bc35760405162461bcd60e51b81526004016107a690612182565b8051610bd6906009906020840190611c59565b5050565b6000546001600160a01b03163314610c045760405162461bcd60e51b81526004016107a690612182565b60005b818110156108dc57828282818110610c2157610c21612201565b9050602002016020810190610c369190611fc3565b600d8054600c916000919082610c4b836121b7565b909155508152602081019190915260400160002080546001600160a01b0319166001600160a01b039290921691909117905580610c87816121b7565b915050610c07565b6000818152600560205260408120546001600160a01b0316806106995760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016107a6565b60098054610d13906120c9565b80601f0160208091040260200160405190810160405280929190818152602001828054610d3f906120c9565b8015610d8c5780601f10610d6157610100808354040283529160200191610d8c565b820191906000526020600020905b815481529060010190602001808311610d6f57829003601f168201915b505050505081565b60006001600160a01b038216610dff5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016107a6565b506001600160a01b031660009081526006602052604090205490565b6000546001600160a01b03163314610e455760405162461bcd60e51b81526004016107a690612182565b610e4f60006115be565b565b6000546001600160a01b03163314610e7b5760405162461bcd60e51b81526004016107a690612182565b6001600160a01b038216610ec35760405162461bcd60e51b815260206004820152600f60248201526e313abcb2b9103830b930b69032b93960891b60448201526064016107a6565b60008111610f045760405162461bcd60e51b815260206004820152600e60248201526d2fb8ba3c903830b930b69032b93960911b60448201526064016107a6565b610bd6828261160e565b6060600280546106ae906120c9565b6000805b600d54811015610f68576000818152600c60205260409020546001600160a01b0384811691161415610f565750600192915050565b80610f60816121b7565b915050610f21565b50600092915050565b610bd63383836117ed565b60058111158015610f8e575060018110155b610fc85760405162461bcd60e51b815260206004820152600b60248201526a36b4b73a273ab69032b93960a91b60448201526064016107a6565b336000908152600b6020526040902054601490610fe69083906121d2565b11156110265760405162461bcd60e51b815260206004820152600f60248201526e1d1bdbc81b585b9e481b5a5b9d1959608a1b60448201526064016107a6565b600081600a546110369190612217565b905060005b600d54811015611093576000818152600c60205260409020546001600160a01b0316331415611081576064600e54836110749190612217565b61107e919061224c565b91505b8061108b816121b7565b91505061103b565b50803410156110d75760405162461bcd60e51b815260206004820152601060248201526f4e6f7420656e6f756768204d4154494360801b60448201526064016107a6565b610bd6338361160e565b6110eb338361132b565b6111075760405162461bcd60e51b81526004016107a690612131565b611113848484846118bc565b50505050565b6000818152600560205260409020546060906001600160a01b03166111785760405162461bcd60e51b81526020600482015260156024820152742a37b5b2b7103237b2b9903737ba1032bc34b9ba1760591b60448201526064016107a6565b6009611183836118ef565b60405160200161119492919061227c565b60408051601f19818403018152908290526111b19160200161231a565b6040516020818303038152906040529050919050565b6000546001600160a01b031633146111f15760405162461bcd60e51b81526004016107a690612182565b600e55565b6000546001600160a01b031633146112205760405162461bcd60e51b81526004016107a690612182565b600a55565b6000546001600160a01b0316331461124f5760405162461bcd60e51b81526004016107a690612182565b6001600160a01b0381166112b45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107a6565b610b7b816115be565b600081815260076020526040902080546001600160a01b0319166001600160a01b03841690811790915581906112f282610c8f565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600560205260408120546001600160a01b03166113a45760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016107a6565b60006113af83610c8f565b9050806001600160a01b0316846001600160a01b031614806113ea5750836001600160a01b03166113df84610731565b6001600160a01b0316145b8061141a57506001600160a01b0380821660009081526008602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661143582610c8f565b6001600160a01b0316146114995760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016107a6565b6001600160a01b0382166114fb5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016107a6565b6115066000826112bd565b6001600160a01b038316600090815260066020526040812080546001929061152f90849061211a565b90915550506001600160a01b038216600090815260066020526040812080546001929061155d9084906121d2565b909155505060008181526005602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b3332146116555760405162461bcd60e51b815260206004820152601560248201527410dbdb9d1c9858dd1cc818d85b9b9bdd081b5a5b9d605a1b60448201526064016107a6565b6001600160a01b0382166116ab5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016107a6565b6000811161170c5760405162461bcd60e51b815260206004820152602860248201527f455243373231723a206e65656420746f206d696e74206174206c65617374206f6044820152673732903a37b5b2b760c11b60648201526084016107a6565b8060045410156117725760405162461bcd60e51b815260206004820152602b60248201527f455243373231723a206d696e74696e67206d6f726520746f6b656e732074686160448201526a6e20617661696c61626c6560a81b60648201526084016107a6565b60045460005b828110156117b557600061178c85846119ed565b90506117988582611a7f565b6117a1836121ea565b925050806117ae906121b7565b9050611778565b5060048190556001600160a01b038316600090815260066020526040812080548492906117e39084906121d2565b9091555050505050565b816001600160a01b0316836001600160a01b0316141561184f5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016107a6565b6001600160a01b03838116600081815260086020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6118c7848484611422565b6118d384848484611ad8565b6111135760405162461bcd60e51b81526004016107a690612343565b6060816119135750506040805180820190915260018152600360fc1b602082015290565b8160005b811561193d5780611927816121b7565b91506119369050600a8361224c565b9150611917565b60008167ffffffffffffffff81111561195857611958611e79565b6040519080825280601f01601f191660200182016040528015611982576020820181803683370190505b5090505b841561141a5761199760018361211a565b91506119a4600a86612395565b6119af9060306121d2565b60f81b8183815181106119c4576119c4612201565b60200101906001600160f81b031916908160001a9053506119e6600a8661224c565b9450611986565b600080833a434244611a0060018461211a565b604080516001600160a01b0390971660208801528601949094526060850192909252608084015260a08301524060c08201523060e082015261010081018490526101200160408051601f19818403018152919052805160209091012090506000611a6a8483612395565b9050611a768185611bd6565b95945050505050565b60008181526005602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160a01b0384163b15611bcb57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611b1c9033908990889088906004016123a9565b6020604051808303816000875af1925050508015611b57575060408051601f3d908101601f19168201909252611b54918101906123e6565b60015b611bb1573d808015611b85576040519150601f19603f3d011682016040523d82523d6000602084013e611b8a565b606091505b508051611ba95760405162461bcd60e51b81526004016107a690612343565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061141a565b506001949350505050565b6000828152600360205260408120548181611bf2575083611bf5565b50805b6000611c0260018661211a565b9050808614611c505760008181526003602052604090205480611c35576000878152600360205260409020829055611c4e565b6000878152600360205260408082208390558382528120555b505b50949350505050565b828054611c65906120c9565b90600052602060002090601f016020900481019282611c875760008555611ccd565b82601f10611ca057805160ff1916838001178555611ccd565b82800160010185558215611ccd579182015b82811115611ccd578251825591602001919060010190611cb2565b50611cd9929150611cdd565b5090565b5b80821115611cd95760008155600101611cde565b6001600160e01b031981168114610b7b57600080fd5b600060208284031215611d1a57600080fd5b8135611d2581611cf2565b9392505050565b60005b83811015611d47578181015183820152602001611d2f565b838111156111135750506000910152565b60008151808452611d70816020860160208601611d2c565b601f01601f19169290920160200192915050565b602081526000611d256020830184611d58565b600060208284031215611da957600080fd5b5035919050565b80356001600160a01b0381168114611dc757600080fd5b919050565b60008060408385031215611ddf57600080fd5b611de883611db0565b946020939093013593505050565b600080600060608486031215611e0b57600080fd5b611e1484611db0565b9250611e2260208501611db0565b9150604084013590509250925092565b600080600060608486031215611e4757600080fd5b611e5084611db0565b925060208401359150604084013561ffff81168114611e6e57600080fd5b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115611eaa57611eaa611e79565b604051601f8501601f19908116603f01168101908282118183101715611ed257611ed2611e79565b81604052809350858152868686011115611eeb57600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215611f1757600080fd5b813567ffffffffffffffff811115611f2e57600080fd5b8201601f81018413611f3f57600080fd5b61141a84823560208401611e8f565b60008060208385031215611f6157600080fd5b823567ffffffffffffffff80821115611f7957600080fd5b818501915085601f830112611f8d57600080fd5b813581811115611f9c57600080fd5b8660208260051b8501011115611fb157600080fd5b60209290920196919550909350505050565b600060208284031215611fd557600080fd5b611d2582611db0565b60008060408385031215611ff157600080fd5b611ffa83611db0565b91506020830135801515811461200f57600080fd5b809150509250929050565b6000806000806080858703121561203057600080fd5b61203985611db0565b935061204760208601611db0565b925060408501359150606085013567ffffffffffffffff81111561206a57600080fd5b8501601f8101871361207b57600080fd5b61208a87823560208401611e8f565b91505092959194509250565b600080604083850312156120a957600080fd5b6120b283611db0565b91506120c060208401611db0565b90509250929050565b600181811c908216806120dd57607f821691505b602082108114156120fe57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60008282101561212c5761212c612104565b500390565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60006000198214156121cb576121cb612104565b5060010190565b600082198211156121e5576121e5612104565b500190565b6000816121f9576121f9612104565b506000190190565b634e487b7160e01b600052603260045260246000fd5b600081600019048311821515161561223157612231612104565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261225b5761225b612236565b500490565b60008151612272818560208601611d2c565b9290920192915050565b600080845481600182811c91508083168061229857607f831692505b60208084108214156122b857634e487b7160e01b86526022600452602486fd5b8180156122cc57600181146122dd5761230a565b60ff1986168952848901965061230a565b60008b81526020902060005b868110156123025781548b8201529085019083016122e9565b505084890196505b505050505050611a768185612260565b6000825161232c818460208701611d2c565b64173539b7b760d91b920191825250600501919050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000826123a4576123a4612236565b500690565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906123dc90830184611d58565b9695505050505050565b6000602082840312156123f857600080fd5b8151611d2581611cf256fea2646970667358221220134a6b91a34adf3f3ff53dc99b77a3af2a3849a788828d6d2e8a36c4b47ec03c64736f6c634300080a0033

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

00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _baseURIParam (string):

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000


Deployed ByteCode Sourcemap

63001:5232:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46777:355;;;;;;;;;;-1:-1:-1;46777:355:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;46777:355:0;;;;;;;;48176:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;49871:308::-;;;;;;;;;;-1:-1:-1;49871:308:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1714:32:1;;;1696:51;;1684:2;1669:18;49871:308:0;1550:203:1;49393:412:0;;;;;;;;;;-1:-1:-1;49393:412:0;;;;;:::i;:::-;;:::i;:::-;;63203:23;;;;;;;;;;;;;;;;;;;2341:25:1;;;2329:2;2314:18;63203:23:0;2195:177:1;47140:119:0;;;;;;;;;;;;;:::i;50790:376::-;;;;;;;;;;-1:-1:-1;50790:376:0;;;;;:::i;:::-;;:::i;63587:33::-;;;;;;;;;;;;;;;;67128:687;;;;;;;;;;-1:-1:-1;67128:687:0;;;;;:::i;:::-;;:::i;68103:127::-;;;;;;;;;;;;;:::i;51237:185::-;;;;;;;;;;-1:-1:-1;51237:185:0;;;;;:::i;:::-;;:::i;66369:110::-;;;;;;;;;;-1:-1:-1;66369:110:0;;;;;:::i;:::-;;:::i;67823:207::-;;;;;;;;;;-1:-1:-1;67823:207:0;;;;;:::i;:::-;;:::i;47783:326::-;;;;;;;;;;-1:-1:-1;47783:326:0;;;;;:::i;:::-;;:::i;63659:23::-;;;;;;;;;;;;;;;;63133:21;;;;;;;;;;;;;:::i;47426:295::-;;;;;;;;;;-1:-1:-1;47426:295:0;;;;;:::i;:::-;;:::i;2518:103::-;;;;;;;;;;;;;:::i;1867:87::-;;;;;;;;;;-1:-1:-1;1913:7:0;1940:6;-1:-1:-1;;;;;1940:6:0;1867:87;;64915:263;;;;;;;;;;-1:-1:-1;64915:263:0;;;;;:::i;:::-;;:::i;48345:104::-;;;;;;;;;;;;;:::i;65186:256::-;;;;;;;;;;-1:-1:-1;65186:256:0;;;;;:::i;:::-;;:::i;50251:187::-;;;;;;;;;;-1:-1:-1;50251:187:0;;;;;:::i;:::-;;:::i;64263:584::-;;;;;;:::i;:::-;;:::i;51493:365::-;;;;;;;;;;-1:-1:-1;51493:365:0;;;;;:::i;:::-;;:::i;65450:457::-;;;;;;;;;;-1:-1:-1;65450:457:0;;;;;:::i;:::-;;:::i;63341:49::-;;;;;;;;;;-1:-1:-1;63341:49:0;;;;;:::i;:::-;;;;;;;;;;;;;;47267:95;;;;;;;;;;-1:-1:-1;47344:10:0;47267:95;;66806:98;;;;;;;;;;-1:-1:-1;66806:98:0;;;;;:::i;:::-;;:::i;63498:47::-;;;;;;;;;;-1:-1:-1;63498:47:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;63498:47:0;;;50509:214;;;;;;;;;;-1:-1:-1;50509:214:0;;;;;:::i;:::-;-1:-1:-1;;;;;50680:25:0;;;50651:4;50680:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;50509:214;66598:107;;;;;;;;;;-1:-1:-1;66598:107:0;;;;;:::i;:::-;;:::i;2776:238::-;;;;;;;;;;-1:-1:-1;2776:238:0;;;;;:::i;:::-;;:::i;46777:355::-;46924:4;-1:-1:-1;;;;;;46966:40:0;;-1:-1:-1;;;46966:40:0;;:105;;-1:-1:-1;;;;;;;47023:48:0;;-1:-1:-1;;;47023:48:0;46966:105;:158;;;-1:-1:-1;;;;;;;;;;22273:40:0;;;47088:36;46946:178;46777:355;-1:-1:-1;;46777:355:0:o;48176:100::-;48230:13;48263:5;48256:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48176:100;:::o;49871:308::-;49992:7;53494:16;;;:7;:16;;;;;;-1:-1:-1;;;;;53494:16:0;50017:110;;;;-1:-1:-1;;;50017:110:0;;7041:2:1;50017:110:0;;;7023:21:1;7080:2;7060:18;;;7053:30;7119:34;7099:18;;;7092:62;-1:-1:-1;;;7170:18:1;;;7163:42;7222:19;;50017:110:0;;;;;;;;;-1:-1:-1;50147:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;50147:24:0;;49871:308::o;49393:412::-;49474:13;49490:24;49506:7;49490:15;:24::i;:::-;49474:40;;49539:5;-1:-1:-1;;;;;49533:11:0;:2;-1:-1:-1;;;;;49533:11:0;;;49525:57;;;;-1:-1:-1;;;49525:57:0;;7454:2:1;49525:57:0;;;7436:21:1;7493:2;7473:18;;;7466:30;7532:34;7512:18;;;7505:62;-1:-1:-1;;;7583:18:1;;;7576:31;7624:19;;49525:57:0;7252:397:1;49525:57:0;734:10;-1:-1:-1;;;;;49617:21:0;;;;:62;;-1:-1:-1;49642:37:0;49659:5;734:10;50509:214;:::i;49642:37::-;49595:168;;;;-1:-1:-1;;;49595:168:0;;7856:2:1;49595:168:0;;;7838:21:1;7895:2;7875:18;;;7868:30;7934:34;7914:18;;;7907:62;8005:26;7985:18;;;7978:54;8049:19;;49595:168:0;7654:420:1;49595:168:0;49776:21;49785:2;49789:7;49776:8;:21::i;:::-;49463:342;49393:412;;:::o;47140:119::-;47192:7;47232:19;;47219:10;:32;;;;:::i;:::-;47212:39;;47140:119;:::o;50790:376::-;50999:41;734:10;51032:7;50999:18;:41::i;:::-;50977:140;;;;-1:-1:-1;;;50977:140:0;;;;;;;:::i;:::-;51130:28;51140:4;51146:2;51150:7;51130:9;:28::i;67128:687::-;1913:7;1940:6;-1:-1:-1;;;;;1940:6:0;734:10;2087:23;2079:68;;;;-1:-1:-1;;;2079:68:0;;;;;;;:::i;:::-;67275:10:::1;::::0;::::1;67271:537;;67315:18;:20:::0;;67339:14;;67302:12:::1;::::0;:34:::1;::::0;;67315:20:::1;::::0;::::1;:::i;:::-;;;;;67302:34;;;;;;;;;;;;:51;;;;;-1:-1:-1::0;;;;;67302:51:0::1;;;;;-1:-1:-1::0;;;;;67302:51:0::1;;;;;;49463:342:::0;49393:412;;:::o;67271:537::-:1;67375:5;:10;;67384:1;67375:10;67371:437;;;67419:18;;67410:6;:27;67402:59;;;::::0;-1:-1:-1;;;67402:59:0;;9462:2:1;67402:59:0::1;::::0;::::1;9444:21:1::0;9501:2;9481:18;;;9474:30;-1:-1:-1;;;9520:18:1;;;9513:49;9579:18;;67402:59:0::1;9260:343:1::0;67402:59:0::1;67476:20;::::0;;;:12:::1;:20;::::0;;;;:37;;-1:-1:-1;;;;;67476:37:0;::::1;-1:-1:-1::0;;;;;;67476:37:0;;::::1;;::::0;;49463:342;49393:412;;:::o;67371:437::-:1;67535:5;:10;;67544:1;67535:10;67531:277;;;67579:18;;67570:6;:27;67562:59;;;::::0;-1:-1:-1;;;67562:59:0;;9462:2:1;67562:59:0::1;::::0;::::1;9444:21:1::0;9501:2;9481:18;;;9474:30;-1:-1:-1;;;9520:18:1;;;9513:49;9579:18;;67562:59:0::1;9260:343:1::0;67562:59:0::1;67653:6:::0;67636:126:::1;67665:18;;67661:1;:22;67636:126;;;67727:12;:19;67740:5;:1:::0;67744::::1;67740:5;:::i;:::-;67727:19:::0;;::::1;::::0;;::::1;::::0;;;;;;;;-1:-1:-1;67727:19:0;;;;67709:15;;;:12:::1;:15:::0;;;;:37;;-1:-1:-1;;;;;;67709:37:0::1;-1:-1:-1::0;;;;;67727:19:0;;::::1;67709:37:::0;;;::::1;::::0;;67722:1;67685:3:::1;67722:1:::0;67685:3:::1;:::i;:::-;;;;67636:126;;;-1:-1:-1::0;67776:18:0::1;:20:::0;;;:18:::1;:20;::::0;::::1;:::i;:::-;;;;;;67128:687:::0;;;:::o;68103:127::-;1913:7;1940:6;-1:-1:-1;;;;;1940:6:0;734:10;2087:23;2079:68;;;;-1:-1:-1;;;2079:68:0;;;;;;;:::i;:::-;68153:69:::1;::::0;68177:10:::1;::::0;68200:21:::1;68153:69:::0;::::1;;;::::0;::::1;::::0;;;68200:21;68177:10;68153:69;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;68103:127::o:0;51237:185::-;51375:39;51392:4;51398:2;51402:7;51375:39;;;;;;;;;;;;:16;:39::i;66369:110::-;1913:7;1940:6;-1:-1:-1;;;;;1940:6:0;734:10;2087:23;2079:68;;;;-1:-1:-1;;;2079:68:0;;;;;;;:::i;:::-;66448:23;;::::1;::::0;:7:::1;::::0;:23:::1;::::0;::::1;::::0;::::1;:::i;:::-;;66369:110:::0;:::o;67823:207::-;1913:7;1940:6;-1:-1:-1;;;;;1940:6:0;734:10;2087:23;2079:68;;;;-1:-1:-1;;;2079:68:0;;;;;;;:::i;:::-;67907:9:::1;67902:121;67922:19:::0;;::::1;67902:121;;;68000:8;;68009:1;68000:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;67976:18;:20:::0;;67963:12:::1;::::0;:34:::1;::::0;67976:20;67963:34;67976:20:::1;::::0;::::1;:::i;:::-;::::0;;;-1:-1:-1;67963:34:0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;67963:34:0;:48;;-1:-1:-1;;;;;;67963:48:0::1;-1:-1:-1::0;;;;;67963:48:0;;;::::1;::::0;;;::::1;::::0;;67943:3;::::1;::::0;::::1;:::i;:::-;;;;67902:121;;47783:326:::0;47900:7;47941:16;;;:7;:16;;;;;;-1:-1:-1;;;;;47941:16:0;47990:19;47968:110;;;;-1:-1:-1;;;47968:110:0;;10216:2:1;47968:110:0;;;10198:21:1;10255:2;10235:18;;;10228:30;10294:34;10274:18;;;10267:62;-1:-1:-1;;;10345:18:1;;;10338:39;10394:19;;47968:110:0;10014:405:1;63133:21:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;47426:295::-;47543:7;-1:-1:-1;;;;;47590:19:0;;47568:111;;;;-1:-1:-1;;;47568:111:0;;10626:2:1;47568:111:0;;;10608:21:1;10665:2;10645:18;;;10638:30;10704:34;10684:18;;;10677:62;-1:-1:-1;;;10755:18:1;;;10748:40;10805:19;;47568:111:0;10424:406:1;47568:111:0;-1:-1:-1;;;;;;47697:16:0;;;;;:9;:16;;;;;;;47426:295::o;2518:103::-;1913:7;1940:6;-1:-1:-1;;;;;1940:6:0;734:10;2087:23;2079:68;;;;-1:-1:-1;;;2079:68:0;;;;;;;:::i;:::-;2583:30:::1;2610:1;2583:18;:30::i;:::-;2518:103::o:0;64915:263::-;1913:7;1940:6;-1:-1:-1;;;;;1940:6:0;734:10;2087:23;2079:68;;;;-1:-1:-1;;;2079:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;65048:20:0;::::1;65040:48;;;::::0;-1:-1:-1;;;65040:48:0;;11037:2:1;65040:48:0::1;::::0;::::1;11019:21:1::0;11076:2;11056:18;;;11049:30;-1:-1:-1;;;11095:18:1;;;11088:45;11150:18;;65040:48:0::1;10835:339:1::0;65040:48:0::1;65114:1;65107:4;:8;65099:35;;;::::0;-1:-1:-1;;;65099:35:0;;11381:2:1;65099:35:0::1;::::0;::::1;11363:21:1::0;11420:2;11400:18;;;11393:30;-1:-1:-1;;;11439:18:1;;;11432:44;11493:18;;65099:35:0::1;11179:338:1::0;65099:35:0::1;65145:25;65157:6;65165:4;65145:11;:25::i;48345:104::-:0;48401:13;48434:7;48427:14;;;;;:::i;65186:256::-;65248:7;;65268:148;65292:18;;65288:1;:22;65268:148;;;65345:15;;;;:12;:15;;;;;;-1:-1:-1;;;;;65336:24:0;;;65345:15;;65336:24;65332:73;;;-1:-1:-1;65388:1:0;;65186:256;-1:-1:-1;;65186:256:0:o;65332:73::-;65312:3;;;;:::i;:::-;;;;65268:148;;;-1:-1:-1;65433:1:0;;65186:256;-1:-1:-1;;65186:256:0:o;50251:187::-;50378:52;734:10;50411:8;50421;50378:18;:52::i;64263:584::-;64364:1;64352:8;:13;;:30;;;;;64381:1;64369:8;:13;;64352:30;64344:54;;;;-1:-1:-1;;;64344:54:0;;11724:2:1;64344:54:0;;;11706:21:1;11763:2;11743:18;;;11736:30;-1:-1:-1;;;11782:18:1;;;11775:41;11833:18;;64344:54:0;11522:335:1;64344:54:0;64432:10;64417:26;;;;:14;:26;;;;;;64458:2;;64417:37;;64446:8;;64417:37;:::i;:::-;:43;;64409:71;;;;-1:-1:-1;;;64409:71:0;;12064:2:1;64409:71:0;;;12046:21:1;12103:2;12083:18;;;12076:30;-1:-1:-1;;;12122:18:1;;;12115:45;12177:18;;64409:71:0;11862:339:1;64409:71:0;64493:18;64525:8;64514;;:19;;;;:::i;:::-;64493:40;;64549:9;64544:187;64568:18;;64564:1;:22;64544:187;;;64626:15;;;;:12;:15;;;;;;-1:-1:-1;;;;;64626:15:0;64612:10;:29;64608:112;;;64701:3;64689:8;;64676:10;:21;;;;:::i;:::-;64675:29;;;;:::i;:::-;64662:42;;64608:112;64588:3;;;;:::i;:::-;;;;64544:187;;;;64762:10;64749:9;:23;;64741:52;;;;-1:-1:-1;;;64741:52:0;;12838:2:1;64741:52:0;;;12820:21:1;12877:2;12857:18;;;12850:30;-1:-1:-1;;;12896:18:1;;;12889:46;12952:18;;64741:52:0;12636:340:1;64741:52:0;64806:33;64818:10;64830:8;64806:11;:33::i;51493:365::-;51682:41;734:10;51715:7;51682:18;:41::i;:::-;51660:140;;;;-1:-1:-1;;;51660:140:0;;;;;;;:::i;:::-;51811:39;51825:4;51831:2;51835:7;51844:5;51811:13;:39::i;:::-;51493:365;;;;:::o;65450:457::-;53470:4;53494:16;;;:7;:16;;;;;;65551:13;;-1:-1:-1;;;;;53494:16:0;65582:50;;;;-1:-1:-1;;;65582:50:0;;13183:2:1;65582:50:0;;;13165:21:1;13222:2;13202:18;;;13195:30;-1:-1:-1;;;13241:18:1;;;13234:51;13302:18;;65582:50:0;12981:345:1;65582:50:0;65777:7;65786:25;65803:7;65786:16;:25::i;:::-;65760:52;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;65760:52:0;;;;;;;;;;65688:196;;65760:52;65688:196;;:::i;:::-;;;;;;;;;;;;;65643:256;;65450:457;;;:::o;66806:98::-;1913:7;1940:6;-1:-1:-1;;;;;1940:6:0;734:10;2087:23;2079:68;;;;-1:-1:-1;;;2079:68:0;;;;;;;:::i;:::-;66876:8:::1;:20:::0;66806:98::o;66598:107::-;1913:7;1940:6;-1:-1:-1;;;;;1940:6:0;734:10;2087:23;2079:68;;;;-1:-1:-1;;;2079:68:0;;;;;;;:::i;:::-;66674:8:::1;:23:::0;66598:107::o;2776:238::-;1913:7;1940:6;-1:-1:-1;;;;;1940:6:0;734:10;2087:23;2079:68;;;;-1:-1:-1;;;2079:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;2879:22:0;::::1;2857:110;;;::::0;-1:-1:-1;;;2857:110:0;;15476:2:1;2857:110:0::1;::::0;::::1;15458:21:1::0;15515:2;15495:18;;;15488:30;15554:34;15534:18;;;15527:62;-1:-1:-1;;;15605:18:1;;;15598:36;15651:19;;2857:110:0::1;15274:402:1::0;2857:110:0::1;2978:28;2997:8;2978:18;:28::i;59609:175::-:0;59684:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;59684:29:0;-1:-1:-1;;;;;59684:29:0;;;;;;;;:24;;59738;59684;59738:15;:24::i;:::-;-1:-1:-1;;;;;59729:47:0;;;;;;;;;;;59609:175;;:::o;53699:453::-;53828:4;53494:16;;;:7;:16;;;;;;-1:-1:-1;;;;;53494:16:0;53850:110;;;;-1:-1:-1;;;53850:110:0;;15883:2:1;53850:110:0;;;15865:21:1;15922:2;15902:18;;;15895:30;15961:34;15941:18;;;15934:62;-1:-1:-1;;;16012:18:1;;;16005:42;16064:19;;53850:110:0;15681:408:1;53850:110:0;53971:13;53987:24;54003:7;53987:15;:24::i;:::-;53971:40;;54041:5;-1:-1:-1;;;;;54030:16:0;:7;-1:-1:-1;;;;;54030:16:0;;:64;;;;54087:7;-1:-1:-1;;;;;54063:31:0;:20;54075:7;54063:11;:20::i;:::-;-1:-1:-1;;;;;54063:31:0;;54030:64;:113;;;-1:-1:-1;;;;;;50680:25:0;;;50651:4;50680:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;54111:32;54022:122;53699:453;-1:-1:-1;;;;53699:453:0:o;58828:663::-;59002:4;-1:-1:-1;;;;;58974:32:0;:24;58990:7;58974:15;:24::i;:::-;-1:-1:-1;;;;;58974:32:0;;58952:119;;;;-1:-1:-1;;;58952:119:0;;16296:2:1;58952:119:0;;;16278:21:1;16335:2;16315:18;;;16308:30;16374:34;16354:18;;;16347:62;-1:-1:-1;;;16425:18:1;;;16418:35;16470:19;;58952:119:0;16094:401:1;58952:119:0;-1:-1:-1;;;;;59090:16:0;;59082:65;;;;-1:-1:-1;;;59082:65:0;;16702:2:1;59082:65:0;;;16684:21:1;16741:2;16721:18;;;16714:30;16780:34;16760:18;;;16753:62;-1:-1:-1;;;16831:18:1;;;16824:34;16875:19;;59082:65:0;16500:400:1;59082:65:0;59264:29;59281:1;59285:7;59264:8;:29::i;:::-;-1:-1:-1;;;;;59306:15:0;;;;;;:9;:15;;;;;:20;;59325:1;;59306:15;:20;;59325:1;;59306:20;:::i;:::-;;;;-1:-1:-1;;;;;;;59337:13:0;;;;;;:9;:13;;;;;:18;;59354:1;;59337:13;:18;;59354:1;;59337:18;:::i;:::-;;;;-1:-1:-1;;59366:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;59366:21:0;-1:-1:-1;;;;;59366:21:0;;;;;;;;;59405:27;;59366:16;;59405:27;;;;;;;49463:342;49393:412;;:::o;3174:191::-;3248:16;3267:6;;-1:-1:-1;;;;;3284:17:0;;;-1:-1:-1;;;;;;3284:17:0;;;;;;3317:40;;3267:6;;;;;;;3317:40;;3248:16;3317:40;3237:128;3174:191;:::o;54448:1041::-;734:10;54553:9;54537:25;54529:59;;;;-1:-1:-1;;;54529:59:0;;17107:2:1;54529:59:0;;;17089:21:1;17146:2;17126:18;;;17119:30;-1:-1:-1;;;17165:18:1;;;17158:51;17226:18;;54529:59:0;16905:345:1;54529:59:0;-1:-1:-1;;;;;54607:16:0;;54599:61;;;;-1:-1:-1;;;54599:61:0;;17457:2:1;54599:61:0;;;17439:21:1;;;17476:18;;;17469:30;17535:34;17515:18;;;17508:62;17587:18;;54599:61:0;17255:356:1;54599:61:0;54692:1;54679:10;:14;54671:67;;;;-1:-1:-1;;;54671:67:0;;17818:2:1;54671:67:0;;;17800:21:1;17857:2;17837:18;;;17830:30;17896:34;17876:18;;;17869:62;-1:-1:-1;;;17947:18:1;;;17940:38;17995:19;;54671:67:0;17616:404:1;54671:67:0;54898:10;54875:19;;:33;;54853:126;;;;-1:-1:-1;;;54853:126:0;;18227:2:1;54853:126:0;;;18209:21:1;18266:2;18246:18;;;18239:30;18305:34;18285:18;;;18278:62;-1:-1:-1;;;18356:18:1;;;18349:41;18407:19;;54853:126:0;18025:407:1;54853:126:0;55028:19;;54992:33;55058:326;55078:10;55074:1;:14;55058:326;;;55148:15;55166:105;55210:2;55231:25;55166;:105::i;:::-;55148:123;;55288:40;55316:2;55320:7;55288:27;:40::i;:::-;55345:27;;;:::i;:::-;;;55095:289;55090:3;;;;:::i;:::-;;;55058:326;;;-1:-1:-1;55396:19:0;:47;;;-1:-1:-1;;;;;55454:13:0;;;;;;:9;:13;;;;;:27;;55471:10;;55454:13;:27;;55471:10;;55454:27;:::i;:::-;;;;-1:-1:-1;;;;;54448:1041:0:o;59926:315::-;60081:8;-1:-1:-1;;;;;60072:17:0;:5;-1:-1:-1;;;;;60072:17:0;;;60064:55;;;;-1:-1:-1;;;60064:55:0;;18639:2:1;60064:55:0;;;18621:21:1;18678:2;18658:18;;;18651:30;18717:27;18697:18;;;18690:55;18762:18;;60064:55:0;18437:349:1;60064:55:0;-1:-1:-1;;;;;60130:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;60130:46:0;;;;;;;;;;60192:41;;540::1;;;60192::0;;513:18:1;60192:41:0;;;;;;;59926:315;;;:::o;52740:352::-;52897:28;52907:4;52913:2;52917:7;52897:9;:28::i;:::-;52958:48;52981:4;52987:2;52991:7;53000:5;52958:22;:48::i;:::-;52936:148;;;;-1:-1:-1;;;52936:148:0;;;;;;;:::i;19558:723::-;19614:13;19835:10;19831:53;;-1:-1:-1;;19862:10:0;;;;;;;;;;;;-1:-1:-1;;;19862:10:0;;;;;19558:723::o;19831:53::-;19909:5;19894:12;19950:78;19957:9;;19950:78;;19983:8;;;;:::i;:::-;;-1:-1:-1;20006:10:0;;-1:-1:-1;20014:2:0;20006:10;;:::i;:::-;;;19950:78;;;20038:19;20070:6;20060:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20060:17:0;;20038:39;;20088:154;20095:10;;20088:154;;20122:11;20132:1;20122:11;;:::i;:::-;;-1:-1:-1;20191:10:0;20199:2;20191:5;:10;:::i;:::-;20178:24;;:2;:24;:::i;:::-;20165:39;;20148:6;20155;20148:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;20148:56:0;;;;;;;;-1:-1:-1;20219:11:0;20228:2;20219:11;;:::i;:::-;;;20088:154;;55497:735;55622:7;;55745:2;55770:11;55804:12;55839:15;55877:16;55926;55941:1;55804:12;55926:16;:::i;:::-;55712:334;;;-1:-1:-1;;;;;19726:15:1;;;55712:334:0;;;19708:34:1;19758:18;;19751:34;;;;19801:18;;;19794:34;;;;19844:18;;;19837:34;19887:19;;;19880:35;55916:27:0;19931:19:1;;;19924:35;55974:4:0;19975:19:1;;;19968:44;20028:19;;;20021:35;;;19642:19;;55712:334:0;;;-1:-1:-1;;55712:334:0;;;;;;;;;55684:377;;55712:334;55684:377;;;;;-1:-1:-1;55662:410:0;56105:37;56117:25;55684:377;56105:37;:::i;:::-;56083:59;;56160:64;56185:11;56198:25;56160:24;:64::i;:::-;56153:71;55497:735;-1:-1:-1;;;;;55497:735:0:o;54160:280::-;54303:16;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;54303:21:0;-1:-1:-1;;;;;54303:21:0;;;;;;;;54342:33;;54303:16;;;54342:33;;54303:16;;54342:33;66448:23:::1;66369:110:::0;:::o;60806:980::-;60961:4;-1:-1:-1;;;;;60982:13:0;;4430:20;4478:8;60978:801;;61035:175;;-1:-1:-1;;;61035:175:0;;-1:-1:-1;;;;;61035:36:0;;;;;:175;;734:10;;61129:4;;61156:7;;61186:5;;61035:175;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61035:175:0;;;;;;;;-1:-1:-1;;61035:175:0;;;;;;;;;;;;:::i;:::-;;;61014:710;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61393:13:0;;61389:320;;61436:108;;-1:-1:-1;;;61436:108:0;;;;;;;:::i;61389:320::-;61659:6;61653:13;61644:6;61640:2;61636:15;61629:38;61014:710;-1:-1:-1;;;;;;61274:51:0;-1:-1:-1;;;61274:51:0;;-1:-1:-1;61267:58:0;;60978:801;-1:-1:-1;61763:4:0;60806:980;;;;;;:::o;56350:1438::-;56482:7;56523:28;;;:16;:28;;;;;;56482:7;56591:15;56587:292;;-1:-1:-1;56704:10:0;56587:292;;;-1:-1:-1;56857:10:0;56587:292;56891:17;56911:29;56939:1;56911:25;:29;:::i;:::-;56891:49;;56969:9;56955:10;:23;56951:804;;57202:22;57227:27;;;:16;:27;;;;;;57273:19;57269:475;;57389:28;;;;:16;:28;;;;;:40;;;57269:475;;;57575:28;;;;:16;:28;;;;;;:45;;;57701:27;;;;;57694:34;57269:475;56980:775;56951:804;-1:-1:-1;57774:6:0;56350:1438;-1:-1:-1;;;;56350:1438:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;:::-;384:5;150:245;-1:-1:-1;;;150:245:1:o;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:269::-;908:3;946:5;940:12;973:6;968:3;961:19;989:63;1045:6;1038:4;1033:3;1029:14;1022:4;1015:5;1011:16;989:63;:::i;:::-;1106:2;1085:15;-1:-1:-1;;1081:29:1;1072:39;;;;1113:4;1068:50;;855:269;-1:-1:-1;;855:269:1:o;1129:231::-;1278:2;1267:9;1260:21;1241:4;1298:56;1350:2;1339:9;1335:18;1327:6;1298:56;:::i;1365:180::-;1424:6;1477:2;1465:9;1456:7;1452:23;1448:32;1445:52;;;1493:1;1490;1483:12;1445:52;-1:-1:-1;1516:23:1;;1365:180;-1:-1:-1;1365:180:1:o;1758:173::-;1826:20;;-1:-1:-1;;;;;1875:31:1;;1865:42;;1855:70;;1921:1;1918;1911:12;1855:70;1758:173;;;:::o;1936:254::-;2004:6;2012;2065:2;2053:9;2044:7;2040:23;2036:32;2033:52;;;2081:1;2078;2071:12;2033:52;2104:29;2123:9;2104:29;:::i;:::-;2094:39;2180:2;2165:18;;;;2152:32;;-1:-1:-1;;;1936:254:1:o;2377:328::-;2454:6;2462;2470;2523:2;2511:9;2502:7;2498:23;2494:32;2491:52;;;2539:1;2536;2529:12;2491:52;2562:29;2581:9;2562:29;:::i;:::-;2552:39;;2610:38;2644:2;2633:9;2629:18;2610:38;:::i;:::-;2600:48;;2695:2;2684:9;2680:18;2667:32;2657:42;;2377:328;;;;;:::o;2710:414::-;2786:6;2794;2802;2855:2;2843:9;2834:7;2830:23;2826:32;2823:52;;;2871:1;2868;2861:12;2823:52;2894:29;2913:9;2894:29;:::i;:::-;2884:39;;2970:2;2959:9;2955:18;2942:32;2932:42;;3024:2;3013:9;3009:18;2996:32;3068:6;3061:5;3057:18;3050:5;3047:29;3037:57;;3090:1;3087;3080:12;3037:57;3113:5;3103:15;;;2710:414;;;;;:::o;3129:127::-;3190:10;3185:3;3181:20;3178:1;3171:31;3221:4;3218:1;3211:15;3245:4;3242:1;3235:15;3261:632;3326:5;3356:18;3397:2;3389:6;3386:14;3383:40;;;3403:18;;:::i;:::-;3478:2;3472:9;3446:2;3532:15;;-1:-1:-1;;3528:24:1;;;3554:2;3524:33;3520:42;3508:55;;;3578:18;;;3598:22;;;3575:46;3572:72;;;3624:18;;:::i;:::-;3664:10;3660:2;3653:22;3693:6;3684:15;;3723:6;3715;3708:22;3763:3;3754:6;3749:3;3745:16;3742:25;3739:45;;;3780:1;3777;3770:12;3739:45;3830:6;3825:3;3818:4;3810:6;3806:17;3793:44;3885:1;3878:4;3869:6;3861;3857:19;3853:30;3846:41;;;;3261:632;;;;;:::o;3898:451::-;3967:6;4020:2;4008:9;3999:7;3995:23;3991:32;3988:52;;;4036:1;4033;4026:12;3988:52;4076:9;4063:23;4109:18;4101:6;4098:30;4095:50;;;4141:1;4138;4131:12;4095:50;4164:22;;4217:4;4209:13;;4205:27;-1:-1:-1;4195:55:1;;4246:1;4243;4236:12;4195:55;4269:74;4335:7;4330:2;4317:16;4312:2;4308;4304:11;4269:74;:::i;4354:615::-;4440:6;4448;4501:2;4489:9;4480:7;4476:23;4472:32;4469:52;;;4517:1;4514;4507:12;4469:52;4557:9;4544:23;4586:18;4627:2;4619:6;4616:14;4613:34;;;4643:1;4640;4633:12;4613:34;4681:6;4670:9;4666:22;4656:32;;4726:7;4719:4;4715:2;4711:13;4707:27;4697:55;;4748:1;4745;4738:12;4697:55;4788:2;4775:16;4814:2;4806:6;4803:14;4800:34;;;4830:1;4827;4820:12;4800:34;4883:7;4878:2;4868:6;4865:1;4861:14;4857:2;4853:23;4849:32;4846:45;4843:65;;;4904:1;4901;4894:12;4843:65;4935:2;4927:11;;;;;4957:6;;-1:-1:-1;4354:615:1;;-1:-1:-1;;;;4354:615:1:o;4974:186::-;5033:6;5086:2;5074:9;5065:7;5061:23;5057:32;5054:52;;;5102:1;5099;5092:12;5054:52;5125:29;5144:9;5125:29;:::i;5165:347::-;5230:6;5238;5291:2;5279:9;5270:7;5266:23;5262:32;5259:52;;;5307:1;5304;5297:12;5259:52;5330:29;5349:9;5330:29;:::i;:::-;5320:39;;5409:2;5398:9;5394:18;5381:32;5456:5;5449:13;5442:21;5435:5;5432:32;5422:60;;5478:1;5475;5468:12;5422:60;5501:5;5491:15;;;5165:347;;;;;:::o;5517:667::-;5612:6;5620;5628;5636;5689:3;5677:9;5668:7;5664:23;5660:33;5657:53;;;5706:1;5703;5696:12;5657:53;5729:29;5748:9;5729:29;:::i;:::-;5719:39;;5777:38;5811:2;5800:9;5796:18;5777:38;:::i;:::-;5767:48;;5862:2;5851:9;5847:18;5834:32;5824:42;;5917:2;5906:9;5902:18;5889:32;5944:18;5936:6;5933:30;5930:50;;;5976:1;5973;5966:12;5930:50;5999:22;;6052:4;6044:13;;6040:27;-1:-1:-1;6030:55:1;;6081:1;6078;6071:12;6030:55;6104:74;6170:7;6165:2;6152:16;6147:2;6143;6139:11;6104:74;:::i;:::-;6094:84;;;5517:667;;;;;;;:::o;6189:260::-;6257:6;6265;6318:2;6306:9;6297:7;6293:23;6289:32;6286:52;;;6334:1;6331;6324:12;6286:52;6357:29;6376:9;6357:29;:::i;:::-;6347:39;;6405:38;6439:2;6428:9;6424:18;6405:38;:::i;:::-;6395:48;;6189:260;;;;;:::o;6454:380::-;6533:1;6529:12;;;;6576;;;6597:61;;6651:4;6643:6;6639:17;6629:27;;6597:61;6704:2;6696:6;6693:14;6673:18;6670:38;6667:161;;;6750:10;6745:3;6741:20;6738:1;6731:31;6785:4;6782:1;6775:15;6813:4;6810:1;6803:15;6667:161;;6454:380;;;:::o;8079:127::-;8140:10;8135:3;8131:20;8128:1;8121:31;8171:4;8168:1;8161:15;8195:4;8192:1;8185:15;8211:125;8251:4;8279:1;8276;8273:8;8270:34;;;8284:18;;:::i;:::-;-1:-1:-1;8321:9:1;;8211:125::o;8341:413::-;8543:2;8525:21;;;8582:2;8562:18;;;8555:30;8621:34;8616:2;8601:18;;8594:62;-1:-1:-1;;;8687:2:1;8672:18;;8665:47;8744:3;8729:19;;8341:413::o;8759:356::-;8961:2;8943:21;;;8980:18;;;8973:30;9039:34;9034:2;9019:18;;9012:62;9106:2;9091:18;;8759:356::o;9120:135::-;9159:3;-1:-1:-1;;9180:17:1;;9177:43;;;9200:18;;:::i;:::-;-1:-1:-1;9247:1:1;9236:13;;9120:135::o;9608:128::-;9648:3;9679:1;9675:6;9672:1;9669:13;9666:39;;;9685:18;;:::i;:::-;-1:-1:-1;9721:9:1;;9608:128::o;9741:136::-;9780:3;9808:5;9798:39;;9817:18;;:::i;:::-;-1:-1:-1;;;9853:18:1;;9741:136::o;9882:127::-;9943:10;9938:3;9934:20;9931:1;9924:31;9974:4;9971:1;9964:15;9998:4;9995:1;9988:15;12206:168;12246:7;12312:1;12308;12304:6;12300:14;12297:1;12294:21;12289:1;12282:9;12275:17;12271:45;12268:71;;;12319:18;;:::i;:::-;-1:-1:-1;12359:9:1;;12206:168::o;12379:127::-;12440:10;12435:3;12431:20;12428:1;12421:31;12471:4;12468:1;12461:15;12495:4;12492:1;12485:15;12511:120;12551:1;12577;12567:35;;12582:18;;:::i;:::-;-1:-1:-1;12616:9:1;;12511:120::o;13457:185::-;13499:3;13537:5;13531:12;13552:52;13597:6;13592:3;13585:4;13578:5;13574:16;13552:52;:::i;:::-;13620:16;;;;;13457:185;-1:-1:-1;;13457:185:1:o;13647:1174::-;13823:3;13852:1;13885:6;13879:13;13915:3;13937:1;13965:9;13961:2;13957:18;13947:28;;14025:2;14014:9;14010:18;14047;14037:61;;14091:4;14083:6;14079:17;14069:27;;14037:61;14117:2;14165;14157:6;14154:14;14134:18;14131:38;14128:165;;;-1:-1:-1;;;14192:33:1;;14248:4;14245:1;14238:15;14278:4;14199:3;14266:17;14128:165;14309:18;14336:104;;;;14454:1;14449:320;;;;14302:467;;14336:104;-1:-1:-1;;14369:24:1;;14357:37;;14414:16;;;;-1:-1:-1;14336:104:1;;14449:320;13404:1;13397:14;;;13441:4;13428:18;;14544:1;14558:165;14572:6;14569:1;14566:13;14558:165;;;14650:14;;14637:11;;;14630:35;14693:16;;;;14587:10;;14558:165;;;14562:3;;14752:6;14747:3;14743:16;14736:23;;14302:467;;;;;;;14785:30;14811:3;14803:6;14785:30;:::i;14826:443::-;15058:3;15096:6;15090:13;15112:53;15158:6;15153:3;15146:4;15138:6;15134:17;15112:53;:::i;:::-;-1:-1:-1;;;15187:16:1;;15212:22;;;-1:-1:-1;15261:1:1;15250:13;;14826:443;-1:-1:-1;14826:443:1:o;18791:414::-;18993:2;18975:21;;;19032:2;19012:18;;;19005:30;19071:34;19066:2;19051:18;;19044:62;-1:-1:-1;;;19137:2:1;19122:18;;19115:48;19195:3;19180:19;;18791:414::o;19210:112::-;19242:1;19268;19258:35;;19273:18;;:::i;:::-;-1:-1:-1;19307:9:1;;19210:112::o;20067:500::-;-1:-1:-1;;;;;20336:15:1;;;20318:34;;20388:15;;20383:2;20368:18;;20361:43;20435:2;20420:18;;20413:34;;;20483:3;20478:2;20463:18;;20456:31;;;20261:4;;20504:57;;20541:19;;20533:6;20504:57;:::i;:::-;20496:65;20067:500;-1:-1:-1;;;;;;20067:500:1:o;20572:249::-;20641:6;20694:2;20682:9;20673:7;20669:23;20665:32;20662:52;;;20710:1;20707;20700:12;20662:52;20742:9;20736:16;20761:30;20785:5;20761:30;:::i

Swarm Source

ipfs://134a6b91a34adf3f3ff53dc99b77a3af2a3849a788828d6d2e8a36c4b47ec03c
Loading