ETH Price: $2,147.29 (+9.08%)
 

Overview

Max Total Supply

3 DDZA

Holders

1

Transfers

-
0

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
Dudenzas

Compiler Version
v0.8.0+commit.c7dfd78e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license
/**
 *Submitted for verification at Etherscan.io on 2021-10-25
*/

/**
 *Submitted for verification at Etherscan.io on 2021-08-12
 */

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

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN 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 memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

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

pragma solidity ^0.8.0;

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

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

pragma solidity >=0.6.2 <0.9.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity >=0.6.2 <0.9.0;

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

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

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

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

pragma solidity >=0.6.2 <0.9.0;

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

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

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

pragma solidity ^0.8.0;

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

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

pragma solidity ^0.8.0;

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
abstract contract ERC165 is IERC165 {
    /*
     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
     */
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor() {
        // Derived contracts need only register support for their own interfaces,
        // we register support for ERC165 itself here
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     *
     * Time complexity O(1), guaranteed to always use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override
        returns (bool)
    {
        return _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal virtual {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

// File: @openzeppelin/contracts/math/SafeMath.sol

pragma solidity ^0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b)
        internal
        pure
        returns (bool, uint256)
    {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b)
        internal
        pure
        returns (bool, uint256)
    {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b)
        internal
        pure
        returns (bool, uint256)
    {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b)
        internal
        pure
        returns (bool, uint256)
    {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b)
        internal
        pure
        returns (bool, uint256)
    {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}

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

pragma solidity >=0.6.2 <0.9.0;

/**
 * @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;
        // solhint-disable-next-line no-inline-assembly
        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"
        );

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) private 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

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            bytes32 lastvalue = set._values[lastIndex];

            // Move the last value to the index where the value to delete is
            set._values[toDeleteIndex] = lastvalue;
            // Update the index for the moved value
            set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value)
        private
        view
        returns (bool)
    {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index)
        private
        view
        returns (bytes32)
    {
        require(
            set._values.length > index,
            "EnumerableSet: index out of bounds"
        );
        return set._values[index];
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value)
        internal
        returns (bool)
    {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value)
        internal
        returns (bool)
    {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value)
        internal
        view
        returns (bool)
    {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index)
        internal
        view
        returns (bytes32)
    {
        return _at(set._inner, index);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value)
        internal
        returns (bool)
    {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value)
        internal
        returns (bool)
    {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value)
        internal
        view
        returns (bool)
    {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index)
        internal
        view
        returns (address)
    {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value)
        internal
        returns (bool)
    {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value)
        internal
        view
        returns (bool)
    {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index)
        internal
        view
        returns (uint256)
    {
        return uint256(_at(set._inner, index));
    }
}

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

pragma solidity ^0.8.0;

/**
 * @dev Library for managing an enumerable variant of Solidity's
 * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
 * type.
 *
 * Maps have the following properties:
 *
 * - Entries are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Entries are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableMap for EnumerableMap.UintToAddressMap;
 *
 *     // Declare a set state variable
 *     EnumerableMap.UintToAddressMap private myMap;
 * }
 * ```
 *
 * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are
 * supported.
 */
library EnumerableMap {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Map type with
    // bytes32 keys and values.
    // The Map implementation uses private functions, and user-facing
    // implementations (such as Uint256ToAddressMap) are just wrappers around
    // the underlying Map.
    // This means that we can only create new EnumerableMaps for types that fit
    // in bytes32.

    struct MapEntry {
        bytes32 _key;
        bytes32 _value;
    }

    struct Map {
        // Storage of map keys and values
        MapEntry[] _entries;
        // Position of the entry defined by a key in the `entries` array, plus 1
        // because index 0 means a key is not in the map.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function _set(
        Map storage map,
        bytes32 key,
        bytes32 value
    ) private returns (bool) {
        // We read and store the key's index to prevent multiple reads from the same storage slot
        uint256 keyIndex = map._indexes[key];

        if (keyIndex == 0) {
            // Equivalent to !contains(map, key)
            map._entries.push(MapEntry({_key: key, _value: value}));
            // The entry is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            map._indexes[key] = map._entries.length;
            return true;
        } else {
            map._entries[keyIndex - 1]._value = value;
            return false;
        }
    }

    /**
     * @dev Removes a key-value pair from a map. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function _remove(Map storage map, bytes32 key) private returns (bool) {
        // We read and store the key's index to prevent multiple reads from the same storage slot
        uint256 keyIndex = map._indexes[key];

        if (keyIndex != 0) {
            // Equivalent to contains(map, key)
            // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one
            // in the array, and then remove the last entry (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = keyIndex - 1;
            uint256 lastIndex = map._entries.length - 1;

            // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            MapEntry storage lastEntry = map._entries[lastIndex];

            // Move the last entry to the index where the entry to delete is
            map._entries[toDeleteIndex] = lastEntry;
            // Update the index for the moved entry
            map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved entry was stored
            map._entries.pop();

            // Delete the index for the deleted slot
            delete map._indexes[key];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function _contains(Map storage map, bytes32 key)
        private
        view
        returns (bool)
    {
        return map._indexes[key] != 0;
    }

    /**
     * @dev Returns the number of key-value pairs in the map. O(1).
     */
    function _length(Map storage map) private view returns (uint256) {
        return map._entries.length;
    }

    /**
     * @dev Returns the key-value pair stored at position `index` in the map. O(1).
     *
     * Note that there are no guarantees on the ordering of entries inside the
     * array, and it may change when more entries are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Map storage map, uint256 index)
        private
        view
        returns (bytes32, bytes32)
    {
        require(
            map._entries.length > index,
            "EnumerableMap: index out of bounds"
        );

        MapEntry storage entry = map._entries[index];
        return (entry._key, entry._value);
    }

    /**
     * @dev Tries to returns the value associated with `key`.  O(1).
     * Does not revert if `key` is not in the map.
     */
    function _tryGet(Map storage map, bytes32 key)
        private
        view
        returns (bool, bytes32)
    {
        uint256 keyIndex = map._indexes[key];
        if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)
        return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based
    }

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function _get(Map storage map, bytes32 key) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    /**
     * @dev Same as {_get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {_tryGet}.
     */
    function _get(
        Map storage map,
        bytes32 key,
        string memory errorMessage
    ) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    // UintToAddressMap

    struct UintToAddressMap {
        Map _inner;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(
        UintToAddressMap storage map,
        uint256 key,
        address value
    ) internal returns (bool) {
        return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function remove(UintToAddressMap storage map, uint256 key)
        internal
        returns (bool)
    {
        return _remove(map._inner, bytes32(key));
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function contains(UintToAddressMap storage map, uint256 key)
        internal
        view
        returns (bool)
    {
        return _contains(map._inner, bytes32(key));
    }

    /**
     * @dev Returns the number of elements in the map. O(1).
     */
    function length(UintToAddressMap storage map)
        internal
        view
        returns (uint256)
    {
        return _length(map._inner);
    }

    /**
     * @dev Returns the element stored at position `index` in the set. O(1).
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintToAddressMap storage map, uint256 index)
        internal
        view
        returns (uint256, address)
    {
        (bytes32 key, bytes32 value) = _at(map._inner, index);
        return (uint256(key), address(uint160(uint256(value))));
    }

    /**
     * @dev Tries to returns the value associated with `key`.  O(1).
     * Does not revert if `key` is not in the map.
     *
     * _Available since v3.4._
     */
    function tryGet(UintToAddressMap storage map, uint256 key)
        internal
        view
        returns (bool, address)
    {
        (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));
        return (success, address(uint160(uint256(value))));
    }

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(UintToAddressMap storage map, uint256 key)
        internal
        view
        returns (address)
    {
        return address(uint160(uint256(_get(map._inner, bytes32(key)))));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(
        UintToAddressMap storage map,
        uint256 key,
        string memory errorMessage
    ) internal view returns (address) {
        return
            address(
                uint160(uint256(_get(map._inner, bytes32(key), errorMessage)))
            );
    }
}

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

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    /**
     * @dev Converts a `uint256` to its ASCII `string` 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);
        uint256 index = digits - 1;
        temp = value;
        while (temp != 0) {
            buffer[index--] = bytes1(uint8(48 + (temp % 10)));
            temp /= 10;
        }
        return string(buffer);
    }
}

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

pragma solidity ^0.8.0;

/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721 is
    Context,
    ERC165,
    IERC721,
    IERC721Metadata,
    IERC721Enumerable
{
    using SafeMath for uint256;
    using Address for address;
    using EnumerableSet for EnumerableSet.UintSet;
    using EnumerableMap for EnumerableMap.UintToAddressMap;
    using Strings for uint256;

    // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

    // Mapping from holder address to their (enumerable) set of owned tokens
    mapping(address => EnumerableSet.UintSet) private _holderTokens;

    // Enumerable mapping from token ids to their owners
    EnumerableMap.UintToAddressMap private _tokenOwners;

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Optional mapping for token URIs
    mapping(uint256 => string) internal _tokenURIs;

    // Base URI
    string internal _baseURI;

    /*
     *     bytes4(keccak256('balanceOf(address)')) == 0x70a08231
     *     bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
     *     bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
     *     bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
     *     bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
     *
     *     => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
     *        0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
     */
    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;

    /*
     *     bytes4(keccak256('name()')) == 0x06fdde03
     *     bytes4(keccak256('symbol()')) == 0x95d89b41
     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
     *
     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
     */
    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;

    /*
     *     bytes4(keccak256('totalSupply()')) == 0x18160ddd
     *     bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
     *     bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
     *
     *     => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
     */
    bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;

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

        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721);
        _registerInterface(_INTERFACE_ID_ERC721_METADATA);
        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
    }

    /**
     * @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 _holderTokens[owner].length();
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId)
        public
        view
        virtual
        override
        returns (address)
    {
        return
            _tokenOwners.get(
                tokenId,
                "ERC721: owner query for nonexistent token"
            );
    }

    /**
     * @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 _tokenURI = _tokenURIs[tokenId];
        string memory base = baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }
        // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
        return string(abi.encodePacked(base, tokenId.toString()));
    }

    /**
     * @dev Returns the base URI set via {_setBaseURI}. This will be
     * automatically added as a prefix in {tokenURI} to each token's URI, or
     * to the token ID if no specific URI is set for that token ID.
     */
    function baseURI() public view virtual returns (string memory) {
        return _baseURI;
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index)
        public
        view
        virtual
        override
        returns (uint256)
    {
        return _holderTokens[owner].at(index);
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds
        return _tokenOwners.length();
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index)
        public
        view
        virtual
        override
        returns (uint256)
    {
        (uint256 tokenId, ) = _tokenOwners.at(index);
        return tokenId;
    }

    /**
     * @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 ||
                ERC721.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
    {
        require(operator != _msgSender(), "ERC721: approve to caller");

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

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //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 _tokenOwners.contains(tokenId);
    }

    /**
     * @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 ||
            ERC721.isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     d*
     * - `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);

        _holderTokens[to].add(tokenId);

        _tokenOwners.set(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); // internal owner

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

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

        // Clear metadata (if any)
        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }

        _holderTokens[owner].remove(tokenId);

        _tokenOwners.remove(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"
        ); // internal 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);

        _holderTokens[from].remove(tokenId);
        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI)
        internal
        virtual
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI set of nonexistent token"
        );
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev Internal function to set the base URI for all token IDs. It is
     * automatically added as a prefix to the value returned in {tokenURI},
     * or to the token ID if {tokenURI} is empty.
     */
    function _setBaseURI(string memory baseURI_) internal virtual {
        _baseURI = baseURI_;
    }

    /**
     * @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()) {
            return true;
        }
        bytes memory returndata = to.functionCall(
            abi.encodeWithSelector(
                IERC721Receiver(to).onERC721Received.selector,
                _msgSender(),
                from,
                tokenId,
                _data
            ),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
        bytes4 retval = abi.decode(returndata, (bytes4));
        return (retval == _ERC721_RECEIVED);
    }

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

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

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

pragma solidity ^0.8.0;

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), 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 {
        emit OwnershipTransferred(_owner, address(0));
        _owner = 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"
        );
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol
pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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

pragma solidity ^0.8.0;

interface Dudes is IERC721 {
    function dudes(uint256 tokenid) external view returns (string memory);
}

// File: contracts/Dudenzas.sol

pragma solidity ^0.8.0;

/**
 * @title Dudenzas contract
 * @dev Extends ERC721 Non-Fungible Token Standard basic implementation
 */
contract Dudenzas is ERC721, Ownable, ReentrancyGuard {
    Dudes dudes = Dudes(0xB0cf7Da8dc482997525BE8488B9caD4F44315422);
    // Dudes dudes = Dudes(0x6d4b8A6508A89c01155875928fe03088dE114223);
    using SafeMath for uint256;
    using Strings for uint256;

    uint256 public mintPrice = 51200000000000000; // 0.0512 ETH

    constructor() ERC721("Dudenzas", "DDZA") {}

    function withdraw() public onlyOwner {
        uint256 balance = address(this).balance;
        payable(owner()).transfer(balance);
    }

    function claimForDude(uint256 tokenId) public payable nonReentrant {
        require(tokenId >= 0 && tokenId < 512, "Token ID invalid");
        require(dudes.ownerOf(tokenId) == msg.sender, "Not Dude owner");
        require(
            msg.value >= mintPrice,
            "Ether value sent is not correct dude!"
        );
        _safeMint(_msgSender(), tokenId);
    }

    function setBaseURI(string memory baseURI) public onlyOwner {
        _setBaseURI(baseURI);
    }

    function setMintPrice(uint256 newPrice) public onlyOwner {
        mintPrice = newPrice;
    }

    /**
     * @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 _tokenURI = _tokenURIs[tokenId];
        string memory base = baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return dudes.dudes(tokenId);
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, dudes.dudes(tokenId)));
        }
        // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
        return string(abi.encodePacked(base, dudes.dudes(tokenId)));
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"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":"uint256","name":"tokenId","type":"uint256"}],"name":"claimForDude","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405273b0cf7da8dc482997525be8488b9cad4f44315422600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555066b5e620f4800000600d553480156200007157600080fd5b506040518060400160405280600881526020017f447564656e7a61730000000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f44445a4100000000000000000000000000000000000000000000000000000000815250620000f66301ffc9a760e01b6200023160201b60201c565b81600690805190602001906200010e92919062000311565b5080600790805190602001906200012792919062000311565b50620001406380ac58cd60e01b6200023160201b60201c565b62000158635b5e139f60e01b6200023160201b60201c565b6200017063780e9d6360e01b6200023160201b60201c565b50506000620001846200030960201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3506001600b819055506200049b565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156200029d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002949062000403565b60405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b8280546200031f9062000436565b90600052602060002090601f0160209004810192826200034357600085556200038f565b82601f106200035e57805160ff19168380011785556200038f565b828001600101855582156200038f579182015b828111156200038e57825182559160200191906001019062000371565b5b5090506200039e9190620003a2565b5090565b5b80821115620003bd576000816000905550600101620003a3565b5090565b6000620003d0601c8362000425565b91507f4552433136353a20696e76616c696420696e74657266616365206964000000006000830152602082019050919050565b600060208201905081810360008301526200041e81620003c1565b9050919050565b600082825260208201905092915050565b600060028204905060018216806200044f57607f821691505b602082108114156200046657620004656200046c565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b613e7380620004ab6000396000f3fe6080604052600436106101665760003560e01c80636817c76c116100d1578063973519351161008a578063c87b56dd11610064578063c87b56dd1461051b578063e985e9c514610558578063f2fde38b14610595578063f4a0a528146105be57610166565b806397351935146104ad578063a22cb465146104c9578063b88d4fde146104f257610166565b80636817c76c146103ad5780636c0360eb146103d857806370a0823114610403578063715018a6146104405780638da5cb5b1461045757806395d89b411461048257610166565b80632f745c59116101235780632f745c591461028d5780633ccfd60b146102ca57806342842e0e146102e15780634f6ccce71461030a57806355f804b3146103475780636352211e1461037057610166565b806301ffc9a71461016b57806306fdde03146101a8578063081812fc146101d3578063095ea7b31461021057806318160ddd1461023957806323b872dd14610264575b600080fd5b34801561017757600080fd5b50610192600480360381019061018d9190612cc5565b6105e7565b60405161019f919061375f565b60405180910390f35b3480156101b457600080fd5b506101bd61064e565b6040516101ca919061377a565b60405180910390f35b3480156101df57600080fd5b506101fa60048036038101906101f59190612d99565b6106e0565b60405161020791906136f8565b60405180910390f35b34801561021c57600080fd5b5061023760048036038101906102329190612c89565b610765565b005b34801561024557600080fd5b5061024e61087d565b60405161025b9190613a7c565b60405180910390f35b34801561027057600080fd5b5061028b60048036038101906102869190612b83565b61088e565b005b34801561029957600080fd5b506102b460048036038101906102af9190612c89565b6108ee565b6040516102c19190613a7c565b60405180910390f35b3480156102d657600080fd5b506102df610949565b005b3480156102ed57600080fd5b5061030860048036038101906103039190612b83565b610a1b565b005b34801561031657600080fd5b50610331600480360381019061032c9190612d99565b610a3b565b60405161033e9190613a7c565b60405180910390f35b34801561035357600080fd5b5061036e60048036038101906103699190612d17565b610a5e565b005b34801561037c57600080fd5b5061039760048036038101906103929190612d99565b610ae6565b6040516103a491906136f8565b60405180910390f35b3480156103b957600080fd5b506103c2610b1d565b6040516103cf9190613a7c565b60405180910390f35b3480156103e457600080fd5b506103ed610b23565b6040516103fa919061377a565b60405180910390f35b34801561040f57600080fd5b5061042a60048036038101906104259190612af5565b610bb5565b6040516104379190613a7c565b60405180910390f35b34801561044c57600080fd5b50610455610c74565b005b34801561046357600080fd5b5061046c610db1565b60405161047991906136f8565b60405180910390f35b34801561048e57600080fd5b50610497610ddb565b6040516104a4919061377a565b60405180910390f35b6104c760048036038101906104c29190612d99565b610e6d565b005b3480156104d557600080fd5b506104f060048036038101906104eb9190612c4d565b611085565b005b3480156104fe57600080fd5b5061051960048036038101906105149190612bd2565b611206565b005b34801561052757600080fd5b50610542600480360381019061053d9190612d99565b611268565b60405161054f919061377a565b60405180910390f35b34801561056457600080fd5b5061057f600480360381019061057a9190612b47565b6115e0565b60405161058c919061375f565b60405180910390f35b3480156105a157600080fd5b506105bc60048036038101906105b79190612af5565b611674565b005b3480156105ca57600080fd5b506105e560048036038101906105e09190612d99565b611820565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b60606006805461065d90613cb6565b80601f016020809104026020016040519081016040528092919081815260200182805461068990613cb6565b80156106d65780601f106106ab576101008083540402835291602001916106d6565b820191906000526020600020905b8154815290600101906020018083116106b957829003601f168201915b5050505050905090565b60006106eb826118a6565b61072a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107219061393c565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061077082610ae6565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156107e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107d8906139fc565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166108006118c3565b73ffffffffffffffffffffffffffffffffffffffff16148061082f575061082e816108296118c3565b6115e0565b5b61086e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610865906138bc565b60405180910390fd5b61087883836118cb565b505050565b60006108896002611984565b905090565b61089f6108996118c3565b82611999565b6108de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d590613a1c565b60405180910390fd5b6108e9838383611a77565b505050565b600061094182600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611c8e90919063ffffffff16565b905092915050565b6109516118c3565b73ffffffffffffffffffffffffffffffffffffffff1661096f610db1565b73ffffffffffffffffffffffffffffffffffffffff16146109c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109bc9061397c565b60405180910390fd5b60004790506109d2610db1565b73ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610a17573d6000803e3d6000fd5b5050565b610a3683838360405180602001604052806000815250611206565b505050565b600080610a52836002611ca890919063ffffffff16565b50905080915050919050565b610a666118c3565b73ffffffffffffffffffffffffffffffffffffffff16610a84610db1565b73ffffffffffffffffffffffffffffffffffffffff1614610ada576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ad19061397c565b60405180910390fd5b610ae381611cd4565b50565b6000610b1682604051806060016040528060298152602001613e15602991396002611cee9092919063ffffffff16565b9050919050565b600d5481565b606060098054610b3290613cb6565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5e90613cb6565b8015610bab5780601f10610b8057610100808354040283529160200191610bab565b820191906000526020600020905b815481529060010190602001808311610b8e57829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610c26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1d906138dc565b60405180910390fd5b610c6d600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611d0d565b9050919050565b610c7c6118c3565b73ffffffffffffffffffffffffffffffffffffffff16610c9a610db1565b73ffffffffffffffffffffffffffffffffffffffff1614610cf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce79061397c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060078054610dea90613cb6565b80601f0160208091040260200160405190810160405280929190818152602001828054610e1690613cb6565b8015610e635780601f10610e3857610100808354040283529160200191610e63565b820191906000526020600020905b815481529060010190602001808311610e4657829003601f168201915b5050505050905090565b6002600b541415610eb3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eaa90613a5c565b60405180910390fd5b6002600b8190555060008110158015610ecd575061020081105b610f0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f039061399c565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610f7e9190613a7c565b60206040518083038186803b158015610f9657600080fd5b505afa158015610faa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fce9190612b1e565b73ffffffffffffffffffffffffffffffffffffffff1614611024576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101b9061381c565b60405180910390fd5b600d54341015611069576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110609061395c565b60405180910390fd5b61107a6110746118c3565b82611d22565b6001600b8190555050565b61108d6118c3565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156110fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f29061385c565b60405180910390fd5b80600560006111086118c3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166111b56118c3565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516111fa919061375f565b60405180910390a35050565b6112176112116118c3565b83611999565b611256576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124d90613a1c565b60405180910390fd5b61126284848484611d40565b50505050565b6060611273826118a6565b6112b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112a9906139dc565b60405180910390fd5b60006008600084815260200190815260200160002080546112d290613cb6565b80601f01602080910402602001604051908101604052809291908181526020018280546112fe90613cb6565b801561134b5780601f106113205761010080835404028352916020019161134b565b820191906000526020600020905b81548152906001019060200180831161132e57829003601f168201915b50505050509050600061135c610b23565b905060008151141561142157600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166368633620856040518263ffffffff1660e01b81526004016113c39190613a7c565b60006040518083038186803b1580156113db57600080fd5b505afa1580156113ef573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906114189190612d58565b925050506115db565b6000825111156115055780600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166368633620866040518263ffffffff1660e01b81526004016114879190613a7c565b60006040518083038186803b15801561149f57600080fd5b505afa1580156114b3573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906114dc9190612d58565b6040516020016114ed9291906136d4565b604051602081830303815290604052925050506115db565b80600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166368633620866040518263ffffffff1660e01b81526004016115619190613a7c565b60006040518083038186803b15801561157957600080fd5b505afa15801561158d573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906115b69190612d58565b6040516020016115c79291906136d4565b604051602081830303815290604052925050505b919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61167c6118c3565b73ffffffffffffffffffffffffffffffffffffffff1661169a610db1565b73ffffffffffffffffffffffffffffffffffffffff16146116f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e79061397c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611760576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611757906137dc565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6118286118c3565b73ffffffffffffffffffffffffffffffffffffffff16611846610db1565b73ffffffffffffffffffffffffffffffffffffffff161461189c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118939061397c565b60405180910390fd5b80600d8190555050565b60006118bc826002611d9c90919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff1661193e83610ae6565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061199282600001611db6565b9050919050565b60006119a4826118a6565b6119e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119da9061389c565b60405180910390fd5b60006119ee83610ae6565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611a5d57508373ffffffffffffffffffffffffffffffffffffffff16611a45846106e0565b73ffffffffffffffffffffffffffffffffffffffff16145b80611a6e5750611a6d81856115e0565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611a9782610ae6565b73ffffffffffffffffffffffffffffffffffffffff1614611aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ae4906139bc565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b549061383c565b60405180910390fd5b611b68838383611dc7565b611b736000826118cb565b611bc481600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611dcc90919063ffffffff16565b50611c1681600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611de690919063ffffffff16565b50611c2d81836002611e009092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000611c9d8360000183611e35565b60001c905092915050565b600080600080611cbb8660000186611ecf565b915091508160001c8160001c9350935050509250929050565b8060099080519060200190611cea92919061289c565b5050565b6000611d01846000018460001b84611f7f565b60001c90509392505050565b6000611d1b82600001612046565b9050919050565b611d3c828260405180602001604052806000815250612057565b5050565b611d4b848484611a77565b611d57848484846120b2565b611d96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d8d906137bc565b60405180910390fd5b50505050565b6000611dae836000018360001b612216565b905092915050565b600081600001805490509050919050565b505050565b6000611dde836000018360001b612239565b905092915050565b6000611df8836000018360001b6123c3565b905092915050565b6000611e2c846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612433565b90509392505050565b600081836000018054905011611e80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e779061379c565b60405180910390fd5b826000018281548110611ebc577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b60008082846000018054905011611f1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f12906138fc565b60405180910390fd5b6000846000018481548110611f59577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008084600101600085815260200190815260200160002054905060008114158390611fe1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fd8919061377a565b60405180910390fd5b5084600001600182611ff39190613bcc565b8154811061202a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b6120618383612545565b61206e60008484846120b2565b6120ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a4906137bc565b60405180910390fd5b505050565b60006120d38473ffffffffffffffffffffffffffffffffffffffff166126d3565b6120e0576001905061220e565b60006121a763150b7a0260e01b6120f56118c3565b88878760405160240161210b9493929190613713565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051806060016040528060328152602001613de3603291398773ffffffffffffffffffffffffffffffffffffffff166126e69092919063ffffffff16565b90506000818060200190518101906121bf9190612cee565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b600080836001016000848152602001908152602001600020549050600081146123b757600060018261226b9190613bcc565b90506000600186600001805490506122839190613bcc565b905060008660000182815481106122c3577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015490508087600001848154811061230d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055506001836123289190613b76565b876001016000838152602001908152602001600020819055508660000180548061237b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506123bd565b60009150505b92915050565b60006123cf83836126fe565b61242857826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061242d565b600090505b92915050565b60008084600101600085815260200190815260200160002054905060008114156124da5784600001604051806040016040528086815260200185815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000155602082015181600101555050846000018054905085600101600086815260200190815260200160002081905550600191505061253e565b82856000016001836124ec9190613bcc565b81548110612523577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600202016001018190555060009150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156125b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ac9061391c565b60405180910390fd5b6125be816118a6565b156125fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f5906137fc565b60405180910390fd5b61260a60008383611dc7565b61265b81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611de690919063ffffffff16565b5061267281836002611e009092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b60606126f58484600085612721565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b606082471015612766576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161275d9061387c565b60405180910390fd5b61276f856126d3565b6127ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127a590613a3c565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516127d791906136bd565b60006040518083038185875af1925050503d8060008114612814576040519150601f19603f3d011682016040523d82523d6000602084013e612819565b606091505b5091509150612829828286612835565b92505050949350505050565b6060831561284557829050612895565b6000835111156128585782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161288c919061377a565b60405180910390fd5b9392505050565b8280546128a890613cb6565b90600052602060002090601f0160209004810192826128ca5760008555612911565b82601f106128e357805160ff1916838001178555612911565b82800160010185558215612911579182015b828111156129105782518255916020019190600101906128f5565b5b50905061291e9190612922565b5090565b5b8082111561293b576000816000905550600101612923565b5090565b600061295261294d84613ac8565b613a97565b90508281526020810184848401111561296a57600080fd5b612975848285613c74565b509392505050565b600061299061298b84613af8565b613a97565b9050828152602081018484840111156129a857600080fd5b6129b3848285613c74565b509392505050565b60006129ce6129c984613af8565b613a97565b9050828152602081018484840111156129e657600080fd5b6129f1848285613c83565b509392505050565b600081359050612a0881613d86565b92915050565b600081519050612a1d81613d86565b92915050565b600081359050612a3281613d9d565b92915050565b600081359050612a4781613db4565b92915050565b600081519050612a5c81613db4565b92915050565b600082601f830112612a7357600080fd5b8135612a8384826020860161293f565b91505092915050565b600082601f830112612a9d57600080fd5b8135612aad84826020860161297d565b91505092915050565b600082601f830112612ac757600080fd5b8151612ad78482602086016129bb565b91505092915050565b600081359050612aef81613dcb565b92915050565b600060208284031215612b0757600080fd5b6000612b15848285016129f9565b91505092915050565b600060208284031215612b3057600080fd5b6000612b3e84828501612a0e565b91505092915050565b60008060408385031215612b5a57600080fd5b6000612b68858286016129f9565b9250506020612b79858286016129f9565b9150509250929050565b600080600060608486031215612b9857600080fd5b6000612ba6868287016129f9565b9350506020612bb7868287016129f9565b9250506040612bc886828701612ae0565b9150509250925092565b60008060008060808587031215612be857600080fd5b6000612bf6878288016129f9565b9450506020612c07878288016129f9565b9350506040612c1887828801612ae0565b925050606085013567ffffffffffffffff811115612c3557600080fd5b612c4187828801612a62565b91505092959194509250565b60008060408385031215612c6057600080fd5b6000612c6e858286016129f9565b9250506020612c7f85828601612a23565b9150509250929050565b60008060408385031215612c9c57600080fd5b6000612caa858286016129f9565b9250506020612cbb85828601612ae0565b9150509250929050565b600060208284031215612cd757600080fd5b6000612ce584828501612a38565b91505092915050565b600060208284031215612d0057600080fd5b6000612d0e84828501612a4d565b91505092915050565b600060208284031215612d2957600080fd5b600082013567ffffffffffffffff811115612d4357600080fd5b612d4f84828501612a8c565b91505092915050565b600060208284031215612d6a57600080fd5b600082015167ffffffffffffffff811115612d8457600080fd5b612d9084828501612ab6565b91505092915050565b600060208284031215612dab57600080fd5b6000612db984828501612ae0565b91505092915050565b612dcb81613c00565b82525050565b612dda81613c12565b82525050565b6000612deb82613b28565b612df58185613b3e565b9350612e05818560208601613c83565b612e0e81613d75565b840191505092915050565b6000612e2482613b28565b612e2e8185613b4f565b9350612e3e818560208601613c83565b80840191505092915050565b6000612e5582613b33565b612e5f8185613b5a565b9350612e6f818560208601613c83565b612e7881613d75565b840191505092915050565b6000612e8e82613b33565b612e988185613b6b565b9350612ea8818560208601613c83565b80840191505092915050565b6000612ec1602283613b5a565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612f27603283613b5a565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b6000612f8d602683613b5a565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612ff3601c83613b5a565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b6000613033600e83613b5a565b91507f4e6f742044756465206f776e65720000000000000000000000000000000000006000830152602082019050919050565b6000613073602483613b5a565b91507f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006130d9601983613b5a565b91507f4552433732313a20617070726f766520746f2063616c6c6572000000000000006000830152602082019050919050565b6000613119602683613b5a565b91507f416464726573733a20696e73756666696369656e742062616c616e636520666f60008301527f722063616c6c00000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061317f602c83613b5a565b91507f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b60006131e5603883613b5a565b91507f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008301527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006020830152604082019050919050565b600061324b602a83613b5a565b91507f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008301527f726f2061646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b60006132b1602283613b5a565b91507f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613317602083613b5a565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b6000613357602c83613b5a565b91507f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b60006133bd602583613b5a565b91507f45746865722076616c75652073656e74206973206e6f7420636f72726563742060008301527f64756465210000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613423602083613b5a565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000613463601083613b5a565b91507f546f6b656e20494420696e76616c6964000000000000000000000000000000006000830152602082019050919050565b60006134a3602983613b5a565b91507f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008301527f73206e6f74206f776e00000000000000000000000000000000000000000000006020830152604082019050919050565b6000613509602f83613b5a565b91507f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008301527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006020830152604082019050919050565b600061356f602183613b5a565b91507f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006135d5603183613b5a565b91507f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008301527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020830152604082019050919050565b600061363b601d83613b5a565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b600061367b601f83613b5a565b91507f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006000830152602082019050919050565b6136b781613c6a565b82525050565b60006136c98284612e19565b915081905092915050565b60006136e08285612e83565b91506136ec8284612e83565b91508190509392505050565b600060208201905061370d6000830184612dc2565b92915050565b60006080820190506137286000830187612dc2565b6137356020830186612dc2565b61374260408301856136ae565b81810360608301526137548184612de0565b905095945050505050565b60006020820190506137746000830184612dd1565b92915050565b600060208201905081810360008301526137948184612e4a565b905092915050565b600060208201905081810360008301526137b581612eb4565b9050919050565b600060208201905081810360008301526137d581612f1a565b9050919050565b600060208201905081810360008301526137f581612f80565b9050919050565b6000602082019050818103600083015261381581612fe6565b9050919050565b6000602082019050818103600083015261383581613026565b9050919050565b6000602082019050818103600083015261385581613066565b9050919050565b60006020820190508181036000830152613875816130cc565b9050919050565b600060208201905081810360008301526138958161310c565b9050919050565b600060208201905081810360008301526138b581613172565b9050919050565b600060208201905081810360008301526138d5816131d8565b9050919050565b600060208201905081810360008301526138f58161323e565b9050919050565b60006020820190508181036000830152613915816132a4565b9050919050565b600060208201905081810360008301526139358161330a565b9050919050565b600060208201905081810360008301526139558161334a565b9050919050565b60006020820190508181036000830152613975816133b0565b9050919050565b6000602082019050818103600083015261399581613416565b9050919050565b600060208201905081810360008301526139b581613456565b9050919050565b600060208201905081810360008301526139d581613496565b9050919050565b600060208201905081810360008301526139f5816134fc565b9050919050565b60006020820190508181036000830152613a1581613562565b9050919050565b60006020820190508181036000830152613a35816135c8565b9050919050565b60006020820190508181036000830152613a558161362e565b9050919050565b60006020820190508181036000830152613a758161366e565b9050919050565b6000602082019050613a9160008301846136ae565b92915050565b6000604051905081810181811067ffffffffffffffff82111715613abe57613abd613d46565b5b8060405250919050565b600067ffffffffffffffff821115613ae357613ae2613d46565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115613b1357613b12613d46565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000613b8182613c6a565b9150613b8c83613c6a565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613bc157613bc0613ce8565b5b828201905092915050565b6000613bd782613c6a565b9150613be283613c6a565b925082821015613bf557613bf4613ce8565b5b828203905092915050565b6000613c0b82613c4a565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015613ca1578082015181840152602081019050613c86565b83811115613cb0576000848401525b50505050565b60006002820490506001821680613cce57607f821691505b60208210811415613ce257613ce1613d17565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b613d8f81613c00565b8114613d9a57600080fd5b50565b613da681613c12565b8114613db157600080fd5b50565b613dbd81613c1e565b8114613dc857600080fd5b50565b613dd481613c6a565b8114613ddf57600080fd5b5056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220599e9ce16df6ec3eac8806c77c7efbe6672e577afc7ca9db2281b1ed6f4b6a9e64736f6c63430008000033

Deployed Bytecode

0x6080604052600436106101665760003560e01c80636817c76c116100d1578063973519351161008a578063c87b56dd11610064578063c87b56dd1461051b578063e985e9c514610558578063f2fde38b14610595578063f4a0a528146105be57610166565b806397351935146104ad578063a22cb465146104c9578063b88d4fde146104f257610166565b80636817c76c146103ad5780636c0360eb146103d857806370a0823114610403578063715018a6146104405780638da5cb5b1461045757806395d89b411461048257610166565b80632f745c59116101235780632f745c591461028d5780633ccfd60b146102ca57806342842e0e146102e15780634f6ccce71461030a57806355f804b3146103475780636352211e1461037057610166565b806301ffc9a71461016b57806306fdde03146101a8578063081812fc146101d3578063095ea7b31461021057806318160ddd1461023957806323b872dd14610264575b600080fd5b34801561017757600080fd5b50610192600480360381019061018d9190612cc5565b6105e7565b60405161019f919061375f565b60405180910390f35b3480156101b457600080fd5b506101bd61064e565b6040516101ca919061377a565b60405180910390f35b3480156101df57600080fd5b506101fa60048036038101906101f59190612d99565b6106e0565b60405161020791906136f8565b60405180910390f35b34801561021c57600080fd5b5061023760048036038101906102329190612c89565b610765565b005b34801561024557600080fd5b5061024e61087d565b60405161025b9190613a7c565b60405180910390f35b34801561027057600080fd5b5061028b60048036038101906102869190612b83565b61088e565b005b34801561029957600080fd5b506102b460048036038101906102af9190612c89565b6108ee565b6040516102c19190613a7c565b60405180910390f35b3480156102d657600080fd5b506102df610949565b005b3480156102ed57600080fd5b5061030860048036038101906103039190612b83565b610a1b565b005b34801561031657600080fd5b50610331600480360381019061032c9190612d99565b610a3b565b60405161033e9190613a7c565b60405180910390f35b34801561035357600080fd5b5061036e60048036038101906103699190612d17565b610a5e565b005b34801561037c57600080fd5b5061039760048036038101906103929190612d99565b610ae6565b6040516103a491906136f8565b60405180910390f35b3480156103b957600080fd5b506103c2610b1d565b6040516103cf9190613a7c565b60405180910390f35b3480156103e457600080fd5b506103ed610b23565b6040516103fa919061377a565b60405180910390f35b34801561040f57600080fd5b5061042a60048036038101906104259190612af5565b610bb5565b6040516104379190613a7c565b60405180910390f35b34801561044c57600080fd5b50610455610c74565b005b34801561046357600080fd5b5061046c610db1565b60405161047991906136f8565b60405180910390f35b34801561048e57600080fd5b50610497610ddb565b6040516104a4919061377a565b60405180910390f35b6104c760048036038101906104c29190612d99565b610e6d565b005b3480156104d557600080fd5b506104f060048036038101906104eb9190612c4d565b611085565b005b3480156104fe57600080fd5b5061051960048036038101906105149190612bd2565b611206565b005b34801561052757600080fd5b50610542600480360381019061053d9190612d99565b611268565b60405161054f919061377a565b60405180910390f35b34801561056457600080fd5b5061057f600480360381019061057a9190612b47565b6115e0565b60405161058c919061375f565b60405180910390f35b3480156105a157600080fd5b506105bc60048036038101906105b79190612af5565b611674565b005b3480156105ca57600080fd5b506105e560048036038101906105e09190612d99565b611820565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b60606006805461065d90613cb6565b80601f016020809104026020016040519081016040528092919081815260200182805461068990613cb6565b80156106d65780601f106106ab576101008083540402835291602001916106d6565b820191906000526020600020905b8154815290600101906020018083116106b957829003601f168201915b5050505050905090565b60006106eb826118a6565b61072a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107219061393c565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061077082610ae6565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156107e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107d8906139fc565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166108006118c3565b73ffffffffffffffffffffffffffffffffffffffff16148061082f575061082e816108296118c3565b6115e0565b5b61086e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610865906138bc565b60405180910390fd5b61087883836118cb565b505050565b60006108896002611984565b905090565b61089f6108996118c3565b82611999565b6108de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d590613a1c565b60405180910390fd5b6108e9838383611a77565b505050565b600061094182600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611c8e90919063ffffffff16565b905092915050565b6109516118c3565b73ffffffffffffffffffffffffffffffffffffffff1661096f610db1565b73ffffffffffffffffffffffffffffffffffffffff16146109c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109bc9061397c565b60405180910390fd5b60004790506109d2610db1565b73ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610a17573d6000803e3d6000fd5b5050565b610a3683838360405180602001604052806000815250611206565b505050565b600080610a52836002611ca890919063ffffffff16565b50905080915050919050565b610a666118c3565b73ffffffffffffffffffffffffffffffffffffffff16610a84610db1565b73ffffffffffffffffffffffffffffffffffffffff1614610ada576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ad19061397c565b60405180910390fd5b610ae381611cd4565b50565b6000610b1682604051806060016040528060298152602001613e15602991396002611cee9092919063ffffffff16565b9050919050565b600d5481565b606060098054610b3290613cb6565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5e90613cb6565b8015610bab5780601f10610b8057610100808354040283529160200191610bab565b820191906000526020600020905b815481529060010190602001808311610b8e57829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610c26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1d906138dc565b60405180910390fd5b610c6d600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611d0d565b9050919050565b610c7c6118c3565b73ffffffffffffffffffffffffffffffffffffffff16610c9a610db1565b73ffffffffffffffffffffffffffffffffffffffff1614610cf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce79061397c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060078054610dea90613cb6565b80601f0160208091040260200160405190810160405280929190818152602001828054610e1690613cb6565b8015610e635780601f10610e3857610100808354040283529160200191610e63565b820191906000526020600020905b815481529060010190602001808311610e4657829003601f168201915b5050505050905090565b6002600b541415610eb3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eaa90613a5c565b60405180910390fd5b6002600b8190555060008110158015610ecd575061020081105b610f0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f039061399c565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610f7e9190613a7c565b60206040518083038186803b158015610f9657600080fd5b505afa158015610faa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fce9190612b1e565b73ffffffffffffffffffffffffffffffffffffffff1614611024576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101b9061381c565b60405180910390fd5b600d54341015611069576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110609061395c565b60405180910390fd5b61107a6110746118c3565b82611d22565b6001600b8190555050565b61108d6118c3565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156110fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f29061385c565b60405180910390fd5b80600560006111086118c3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166111b56118c3565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516111fa919061375f565b60405180910390a35050565b6112176112116118c3565b83611999565b611256576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124d90613a1c565b60405180910390fd5b61126284848484611d40565b50505050565b6060611273826118a6565b6112b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112a9906139dc565b60405180910390fd5b60006008600084815260200190815260200160002080546112d290613cb6565b80601f01602080910402602001604051908101604052809291908181526020018280546112fe90613cb6565b801561134b5780601f106113205761010080835404028352916020019161134b565b820191906000526020600020905b81548152906001019060200180831161132e57829003601f168201915b50505050509050600061135c610b23565b905060008151141561142157600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166368633620856040518263ffffffff1660e01b81526004016113c39190613a7c565b60006040518083038186803b1580156113db57600080fd5b505afa1580156113ef573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906114189190612d58565b925050506115db565b6000825111156115055780600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166368633620866040518263ffffffff1660e01b81526004016114879190613a7c565b60006040518083038186803b15801561149f57600080fd5b505afa1580156114b3573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906114dc9190612d58565b6040516020016114ed9291906136d4565b604051602081830303815290604052925050506115db565b80600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166368633620866040518263ffffffff1660e01b81526004016115619190613a7c565b60006040518083038186803b15801561157957600080fd5b505afa15801561158d573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906115b69190612d58565b6040516020016115c79291906136d4565b604051602081830303815290604052925050505b919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61167c6118c3565b73ffffffffffffffffffffffffffffffffffffffff1661169a610db1565b73ffffffffffffffffffffffffffffffffffffffff16146116f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e79061397c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611760576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611757906137dc565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6118286118c3565b73ffffffffffffffffffffffffffffffffffffffff16611846610db1565b73ffffffffffffffffffffffffffffffffffffffff161461189c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118939061397c565b60405180910390fd5b80600d8190555050565b60006118bc826002611d9c90919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff1661193e83610ae6565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061199282600001611db6565b9050919050565b60006119a4826118a6565b6119e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119da9061389c565b60405180910390fd5b60006119ee83610ae6565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611a5d57508373ffffffffffffffffffffffffffffffffffffffff16611a45846106e0565b73ffffffffffffffffffffffffffffffffffffffff16145b80611a6e5750611a6d81856115e0565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611a9782610ae6565b73ffffffffffffffffffffffffffffffffffffffff1614611aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ae4906139bc565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b549061383c565b60405180910390fd5b611b68838383611dc7565b611b736000826118cb565b611bc481600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611dcc90919063ffffffff16565b50611c1681600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611de690919063ffffffff16565b50611c2d81836002611e009092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000611c9d8360000183611e35565b60001c905092915050565b600080600080611cbb8660000186611ecf565b915091508160001c8160001c9350935050509250929050565b8060099080519060200190611cea92919061289c565b5050565b6000611d01846000018460001b84611f7f565b60001c90509392505050565b6000611d1b82600001612046565b9050919050565b611d3c828260405180602001604052806000815250612057565b5050565b611d4b848484611a77565b611d57848484846120b2565b611d96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d8d906137bc565b60405180910390fd5b50505050565b6000611dae836000018360001b612216565b905092915050565b600081600001805490509050919050565b505050565b6000611dde836000018360001b612239565b905092915050565b6000611df8836000018360001b6123c3565b905092915050565b6000611e2c846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612433565b90509392505050565b600081836000018054905011611e80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e779061379c565b60405180910390fd5b826000018281548110611ebc577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b60008082846000018054905011611f1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f12906138fc565b60405180910390fd5b6000846000018481548110611f59577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008084600101600085815260200190815260200160002054905060008114158390611fe1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fd8919061377a565b60405180910390fd5b5084600001600182611ff39190613bcc565b8154811061202a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b6120618383612545565b61206e60008484846120b2565b6120ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a4906137bc565b60405180910390fd5b505050565b60006120d38473ffffffffffffffffffffffffffffffffffffffff166126d3565b6120e0576001905061220e565b60006121a763150b7a0260e01b6120f56118c3565b88878760405160240161210b9493929190613713565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051806060016040528060328152602001613de3603291398773ffffffffffffffffffffffffffffffffffffffff166126e69092919063ffffffff16565b90506000818060200190518101906121bf9190612cee565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b600080836001016000848152602001908152602001600020549050600081146123b757600060018261226b9190613bcc565b90506000600186600001805490506122839190613bcc565b905060008660000182815481106122c3577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015490508087600001848154811061230d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055506001836123289190613b76565b876001016000838152602001908152602001600020819055508660000180548061237b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506123bd565b60009150505b92915050565b60006123cf83836126fe565b61242857826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061242d565b600090505b92915050565b60008084600101600085815260200190815260200160002054905060008114156124da5784600001604051806040016040528086815260200185815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000155602082015181600101555050846000018054905085600101600086815260200190815260200160002081905550600191505061253e565b82856000016001836124ec9190613bcc565b81548110612523577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600202016001018190555060009150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156125b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ac9061391c565b60405180910390fd5b6125be816118a6565b156125fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f5906137fc565b60405180910390fd5b61260a60008383611dc7565b61265b81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611de690919063ffffffff16565b5061267281836002611e009092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b60606126f58484600085612721565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b606082471015612766576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161275d9061387c565b60405180910390fd5b61276f856126d3565b6127ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127a590613a3c565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516127d791906136bd565b60006040518083038185875af1925050503d8060008114612814576040519150601f19603f3d011682016040523d82523d6000602084013e612819565b606091505b5091509150612829828286612835565b92505050949350505050565b6060831561284557829050612895565b6000835111156128585782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161288c919061377a565b60405180910390fd5b9392505050565b8280546128a890613cb6565b90600052602060002090601f0160209004810192826128ca5760008555612911565b82601f106128e357805160ff1916838001178555612911565b82800160010185558215612911579182015b828111156129105782518255916020019190600101906128f5565b5b50905061291e9190612922565b5090565b5b8082111561293b576000816000905550600101612923565b5090565b600061295261294d84613ac8565b613a97565b90508281526020810184848401111561296a57600080fd5b612975848285613c74565b509392505050565b600061299061298b84613af8565b613a97565b9050828152602081018484840111156129a857600080fd5b6129b3848285613c74565b509392505050565b60006129ce6129c984613af8565b613a97565b9050828152602081018484840111156129e657600080fd5b6129f1848285613c83565b509392505050565b600081359050612a0881613d86565b92915050565b600081519050612a1d81613d86565b92915050565b600081359050612a3281613d9d565b92915050565b600081359050612a4781613db4565b92915050565b600081519050612a5c81613db4565b92915050565b600082601f830112612a7357600080fd5b8135612a8384826020860161293f565b91505092915050565b600082601f830112612a9d57600080fd5b8135612aad84826020860161297d565b91505092915050565b600082601f830112612ac757600080fd5b8151612ad78482602086016129bb565b91505092915050565b600081359050612aef81613dcb565b92915050565b600060208284031215612b0757600080fd5b6000612b15848285016129f9565b91505092915050565b600060208284031215612b3057600080fd5b6000612b3e84828501612a0e565b91505092915050565b60008060408385031215612b5a57600080fd5b6000612b68858286016129f9565b9250506020612b79858286016129f9565b9150509250929050565b600080600060608486031215612b9857600080fd5b6000612ba6868287016129f9565b9350506020612bb7868287016129f9565b9250506040612bc886828701612ae0565b9150509250925092565b60008060008060808587031215612be857600080fd5b6000612bf6878288016129f9565b9450506020612c07878288016129f9565b9350506040612c1887828801612ae0565b925050606085013567ffffffffffffffff811115612c3557600080fd5b612c4187828801612a62565b91505092959194509250565b60008060408385031215612c6057600080fd5b6000612c6e858286016129f9565b9250506020612c7f85828601612a23565b9150509250929050565b60008060408385031215612c9c57600080fd5b6000612caa858286016129f9565b9250506020612cbb85828601612ae0565b9150509250929050565b600060208284031215612cd757600080fd5b6000612ce584828501612a38565b91505092915050565b600060208284031215612d0057600080fd5b6000612d0e84828501612a4d565b91505092915050565b600060208284031215612d2957600080fd5b600082013567ffffffffffffffff811115612d4357600080fd5b612d4f84828501612a8c565b91505092915050565b600060208284031215612d6a57600080fd5b600082015167ffffffffffffffff811115612d8457600080fd5b612d9084828501612ab6565b91505092915050565b600060208284031215612dab57600080fd5b6000612db984828501612ae0565b91505092915050565b612dcb81613c00565b82525050565b612dda81613c12565b82525050565b6000612deb82613b28565b612df58185613b3e565b9350612e05818560208601613c83565b612e0e81613d75565b840191505092915050565b6000612e2482613b28565b612e2e8185613b4f565b9350612e3e818560208601613c83565b80840191505092915050565b6000612e5582613b33565b612e5f8185613b5a565b9350612e6f818560208601613c83565b612e7881613d75565b840191505092915050565b6000612e8e82613b33565b612e988185613b6b565b9350612ea8818560208601613c83565b80840191505092915050565b6000612ec1602283613b5a565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612f27603283613b5a565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b6000612f8d602683613b5a565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612ff3601c83613b5a565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b6000613033600e83613b5a565b91507f4e6f742044756465206f776e65720000000000000000000000000000000000006000830152602082019050919050565b6000613073602483613b5a565b91507f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006130d9601983613b5a565b91507f4552433732313a20617070726f766520746f2063616c6c6572000000000000006000830152602082019050919050565b6000613119602683613b5a565b91507f416464726573733a20696e73756666696369656e742062616c616e636520666f60008301527f722063616c6c00000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061317f602c83613b5a565b91507f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b60006131e5603883613b5a565b91507f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008301527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006020830152604082019050919050565b600061324b602a83613b5a565b91507f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008301527f726f2061646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b60006132b1602283613b5a565b91507f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613317602083613b5a565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b6000613357602c83613b5a565b91507f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b60006133bd602583613b5a565b91507f45746865722076616c75652073656e74206973206e6f7420636f72726563742060008301527f64756465210000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613423602083613b5a565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000613463601083613b5a565b91507f546f6b656e20494420696e76616c6964000000000000000000000000000000006000830152602082019050919050565b60006134a3602983613b5a565b91507f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008301527f73206e6f74206f776e00000000000000000000000000000000000000000000006020830152604082019050919050565b6000613509602f83613b5a565b91507f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008301527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006020830152604082019050919050565b600061356f602183613b5a565b91507f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006135d5603183613b5a565b91507f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008301527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020830152604082019050919050565b600061363b601d83613b5a565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b600061367b601f83613b5a565b91507f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006000830152602082019050919050565b6136b781613c6a565b82525050565b60006136c98284612e19565b915081905092915050565b60006136e08285612e83565b91506136ec8284612e83565b91508190509392505050565b600060208201905061370d6000830184612dc2565b92915050565b60006080820190506137286000830187612dc2565b6137356020830186612dc2565b61374260408301856136ae565b81810360608301526137548184612de0565b905095945050505050565b60006020820190506137746000830184612dd1565b92915050565b600060208201905081810360008301526137948184612e4a565b905092915050565b600060208201905081810360008301526137b581612eb4565b9050919050565b600060208201905081810360008301526137d581612f1a565b9050919050565b600060208201905081810360008301526137f581612f80565b9050919050565b6000602082019050818103600083015261381581612fe6565b9050919050565b6000602082019050818103600083015261383581613026565b9050919050565b6000602082019050818103600083015261385581613066565b9050919050565b60006020820190508181036000830152613875816130cc565b9050919050565b600060208201905081810360008301526138958161310c565b9050919050565b600060208201905081810360008301526138b581613172565b9050919050565b600060208201905081810360008301526138d5816131d8565b9050919050565b600060208201905081810360008301526138f58161323e565b9050919050565b60006020820190508181036000830152613915816132a4565b9050919050565b600060208201905081810360008301526139358161330a565b9050919050565b600060208201905081810360008301526139558161334a565b9050919050565b60006020820190508181036000830152613975816133b0565b9050919050565b6000602082019050818103600083015261399581613416565b9050919050565b600060208201905081810360008301526139b581613456565b9050919050565b600060208201905081810360008301526139d581613496565b9050919050565b600060208201905081810360008301526139f5816134fc565b9050919050565b60006020820190508181036000830152613a1581613562565b9050919050565b60006020820190508181036000830152613a35816135c8565b9050919050565b60006020820190508181036000830152613a558161362e565b9050919050565b60006020820190508181036000830152613a758161366e565b9050919050565b6000602082019050613a9160008301846136ae565b92915050565b6000604051905081810181811067ffffffffffffffff82111715613abe57613abd613d46565b5b8060405250919050565b600067ffffffffffffffff821115613ae357613ae2613d46565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115613b1357613b12613d46565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000613b8182613c6a565b9150613b8c83613c6a565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613bc157613bc0613ce8565b5b828201905092915050565b6000613bd782613c6a565b9150613be283613c6a565b925082821015613bf557613bf4613ce8565b5b828203905092915050565b6000613c0b82613c4a565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015613ca1578082015181840152602081019050613c86565b83811115613cb0576000848401525b50505050565b60006002820490506001821680613cce57607f821691505b60208210811415613ce257613ce1613d17565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b613d8f81613c00565b8114613d9a57600080fd5b50565b613da681613c12565b8114613db157600080fd5b50565b613dbd81613c1e565b8114613dc857600080fd5b50565b613dd481613c6a565b8114613ddf57600080fd5b5056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220599e9ce16df6ec3eac8806c77c7efbe6672e577afc7ca9db2281b1ed6f4b6a9e64736f6c63430008000033

Deployed Bytecode Sourcemap

73376:2106:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10546:200;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53986:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56994:308;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56493:435;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55921:211;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58053:376;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55633:212;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73765:140;;;;;;;;;;;;;:::i;:::-;;58500:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;56209:222;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74302:99;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53630:289;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73647:44;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55452:97;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53260:308;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69785:148;;;;;;;;;;;;;:::i;:::-;;69134:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54155:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73913:381;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57374:327;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58756:365;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74576:903;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57772:214;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70088:281;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74409:96;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;10546:200;10676:4;10705:20;:33;10726:11;10705:33;;;;;;;;;;;;;;;;;;;;;;;;;;;10698:40;;10546:200;;;:::o;53986:100::-;54040:13;54073:5;54066:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53986:100;:::o;56994:308::-;57115:7;57162:16;57170:7;57162;:16::i;:::-;57140:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;57270:15;:24;57286:7;57270:24;;;;;;;;;;;;;;;;;;;;;57263:31;;56994:308;;;:::o;56493:435::-;56574:13;56590:23;56605:7;56590:14;:23::i;:::-;56574:39;;56638:5;56632:11;;:2;:11;;;;56624:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;56732:5;56716:21;;:12;:10;:12::i;:::-;:21;;;:86;;;;56758:44;56782:5;56789:12;:10;:12::i;:::-;56758:23;:44::i;:::-;56716:86;56694:192;;;;;;;;;;;;:::i;:::-;;;;;;;;;56899:21;56908:2;56912:7;56899:8;:21::i;:::-;56493:435;;;:::o;55921:211::-;55982:7;56103:21;:12;:19;:21::i;:::-;56096:28;;55921:211;:::o;58053:376::-;58262:41;58281:12;:10;:12::i;:::-;58295:7;58262:18;:41::i;:::-;58240:140;;;;;;;;;;;;:::i;:::-;;;;;;;;;58393:28;58403:4;58409:2;58413:7;58393:9;:28::i;:::-;58053:376;;;:::o;55633:212::-;55775:7;55807:30;55831:5;55807:13;:20;55821:5;55807:20;;;;;;;;;;;;;;;:23;;:30;;;;:::i;:::-;55800:37;;55633:212;;;;:::o;73765:140::-;69365:12;:10;:12::i;:::-;69354:23;;:7;:5;:7::i;:::-;:23;;;69346:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;73813:15:::1;73831:21;73813:39;;73871:7;:5;:7::i;:::-;73863:25;;:34;73889:7;73863:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;69425:1;73765:140::o:0;58500:185::-;58638:39;58655:4;58661:2;58665:7;58638:39;;;;;;;;;;;;:16;:39::i;:::-;58500:185;;;:::o;56209:222::-;56329:7;56355:15;56376:22;56392:5;56376:12;:15;;:22;;;;:::i;:::-;56354:44;;;56416:7;56409:14;;;56209:222;;;:::o;74302:99::-;69365:12;:10;:12::i;:::-;69354:23;;:7;:5;:7::i;:::-;:23;;;69346:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;74373:20:::1;74385:7;74373:11;:20::i;:::-;74302:99:::0;:::o;53630:289::-;53747:7;53792:119;53827:7;53792:119;;;;;;;;;;;;;;;;;:12;:16;;:119;;;;;:::i;:::-;53772:139;;53630:289;;;:::o;73647:44::-;;;;:::o;55452:97::-;55500:13;55533:8;55526:15;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55452:97;:::o;53260:308::-;53377:7;53441:1;53424:19;;:5;:19;;;;53402:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;53531:29;:13;:20;53545:5;53531:20;;;;;;;;;;;;;;;:27;:29::i;:::-;53524:36;;53260:308;;;:::o;69785:148::-;69365:12;:10;:12::i;:::-;69354:23;;:7;:5;:7::i;:::-;:23;;;69346:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;69892:1:::1;69855:40;;69876:6;;;;;;;;;;;69855:40;;;;;;;;;;;;69923:1;69906:6;;:19;;;;;;;;;;;;;;;;;;69785:148::o:0;69134:87::-;69180:7;69207:6;;;;;;;;;;;69200:13;;69134:87;:::o;54155:104::-;54211:13;54244:7;54237:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54155:104;:::o;73913:381::-;72117:1;72715:7;;:19;;72707:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;72117:1;72848:7;:18;;;;74010:1:::1;73999:7;:12;;:29;;;;;74025:3;74015:7;:13;73999:29;73991:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;74094:10;74068:36;;:5;;;;;;;;;;;:13;;;74082:7;74068:22;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:36;;;74060:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;74169:9;;74156;:22;;74134:109;;;;;;;;;;;;:::i;:::-;;;;;;;;;74254:32;74264:12;:10;:12::i;:::-;74278:7;74254:9;:32::i;:::-;72073:1:::0;73027:7;:22;;;;73913:381;:::o;57374:327::-;57521:12;:10;:12::i;:::-;57509:24;;:8;:24;;;;57501:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;57621:8;57576:18;:32;57595:12;:10;:12::i;:::-;57576:32;;;;;;;;;;;;;;;:42;57609:8;57576:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;57674:8;57645:48;;57660:12;:10;:12::i;:::-;57645:48;;;57684:8;57645:48;;;;;;:::i;:::-;;;;;;;;57374:327;;:::o;58756:365::-;58945:41;58964:12;:10;:12::i;:::-;58978:7;58945:18;:41::i;:::-;58923:140;;;;;;;;;;;;:::i;:::-;;;;;;;;;59074:39;59088:4;59094:2;59098:7;59107:5;59074:13;:39::i;:::-;58756:365;;;;:::o;74576:903::-;74694:13;74747:16;74755:7;74747;:16::i;:::-;74725:113;;;;;;;;;;;;:::i;:::-;;;;;;;;;74851:23;74877:10;:19;74888:7;74877:19;;;;;;;;;;;74851:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74907:18;74928:9;:7;:9::i;:::-;74907:30;;75035:1;75019:4;75013:18;:23;75009:83;;;75060:5;;;;;;;;;;;:11;;;75072:7;75060:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75053:27;;;;;;75009:83;75222:1;75202:9;75196:23;:27;75192:119;;;75271:4;75277:5;;;;;;;;;;;:11;;;75289:7;75277:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75254:44;;;;;;;;;:::i;:::-;;;;;;;;;;;;;75240:59;;;;;;75192:119;75443:4;75449:5;;;;;;;;;;;:11;;;75461:7;75449:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75426:44;;;;;;;;;:::i;:::-;;;;;;;;;;;;;75412:59;;;;74576:903;;;;:::o;57772:214::-;57914:4;57943:18;:25;57962:5;57943:25;;;;;;;;;;;;;;;:35;57969:8;57943:35;;;;;;;;;;;;;;;;;;;;;;;;;57936:42;;57772:214;;;;:::o;70088:281::-;69365:12;:10;:12::i;:::-;69354:23;;:7;:5;:7::i;:::-;:23;;;69346:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;70211:1:::1;70191:22;;:8;:22;;;;70169:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;70324:8;70295:38;;70316:6;;;;;;;;;;;70295:38;;;;;;;;;;;;70353:8;70344:6;;:17;;;;;;;;;;;;;;;;;;70088:281:::0;:::o;74409:96::-;69365:12;:10;:12::i;:::-;69354:23;;:7;:5;:7::i;:::-;:23;;;69346:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;74489:8:::1;74477:9;:20;;;;74409:96:::0;:::o;60668:127::-;60733:4;60757:30;60779:7;60757:12;:21;;:30;;;;:::i;:::-;60750:37;;60668:127;;;:::o;731:98::-;784:7;811:10;804:17;;731:98;:::o;67082:192::-;67184:2;67157:15;:24;67173:7;67157:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;67240:7;67236:2;67202:46;;67211:23;67226:7;67211:14;:23::i;:::-;67202:46;;;;;;;;;;;;67082:192;;:::o;46339:155::-;46435:7;46467:19;46475:3;:10;;46467:7;:19::i;:::-;46460:26;;46339:155;;;:::o;60962:459::-;61091:4;61135:16;61143:7;61135;:16::i;:::-;61113:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;61234:13;61250:23;61265:7;61250:14;:23::i;:::-;61234:39;;61303:5;61292:16;;:7;:16;;;:64;;;;61349:7;61325:31;;:20;61337:7;61325:11;:20::i;:::-;:31;;;61292:64;:120;;;;61373:39;61397:5;61404:7;61373:23;:39::i;:::-;61292:120;61284:129;;;60962:459;;;;:::o;64273:670::-;64446:4;64419:31;;:23;64434:7;64419:14;:23::i;:::-;:31;;;64397:122;;;;;;;;;;;;:::i;:::-;;;;;;;;;64570:1;64556:16;;:2;:16;;;;64548:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;64626:39;64647:4;64653:2;64657:7;64626:20;:39::i;:::-;64730:29;64747:1;64751:7;64730:8;:29::i;:::-;64772:35;64799:7;64772:13;:19;64786:4;64772:19;;;;;;;;;;;;;;;:26;;:35;;;;:::i;:::-;;64818:30;64840:7;64818:13;:17;64832:2;64818:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;64861:29;64878:7;64887:2;64861:12;:16;;:29;;;;;:::i;:::-;;64927:7;64923:2;64908:27;;64917:4;64908:27;;;;;;;;;;;;64273:670;;;:::o;37789:169::-;37887:7;37927:22;37931:3;:10;;37943:5;37927:3;:22::i;:::-;37919:31;;37912:38;;37789:169;;;;:::o;46842:268::-;46949:7;46958;46984:11;46997:13;47014:22;47018:3;:10;;47030:5;47014:3;:22::i;:::-;46983:53;;;;47063:3;47055:12;;47093:5;47085:14;;47047:55;;;;;;46842:268;;;;;:::o;65604:100::-;65688:8;65677;:19;;;;;;;;;;;;:::i;:::-;;65604:100;:::o;48224:292::-;48365:7;48447:44;48452:3;:10;;48472:3;48464:12;;48478;48447:4;:44::i;:::-;48439:53;;48385:123;;48224:292;;;;;:::o;37321:114::-;37381:7;37408:19;37416:3;:10;;37408:7;:19::i;:::-;37401:26;;37321:114;;;:::o;61764:110::-;61840:26;61850:2;61854:7;61840:26;;;;;;;;;;;;:9;:26::i;:::-;61764:110;;:::o;60003:352::-;60160:28;60170:4;60176:2;60180:7;60160:9;:28::i;:::-;60221:48;60244:4;60250:2;60254:7;60263:5;60221:22;:48::i;:::-;60199:148;;;;;;;;;;;;:::i;:::-;;;;;;;;;60003:352;;;;:::o;46068:183::-;46179:4;46208:35;46218:3;:10;;46238:3;46230:12;;46208:9;:35::i;:::-;46201:42;;46068:183;;;;:::o;42684:110::-;42740:7;42767:3;:12;;:19;;;;42760:26;;42684:110;;;:::o;67887:126::-;;;;:::o;36811:160::-;36899:4;36928:35;36936:3;:10;;36956:5;36948:14;;36928:7;:35::i;:::-;36921:42;;36811:160;;;;:::o;36504:131::-;36571:4;36595:32;36600:3;:10;;36620:5;36612:14;;36595:4;:32::i;:::-;36588:39;;36504:131;;;;:::o;45434:219::-;45557:4;45581:64;45586:3;:10;;45606:3;45598:12;;45636:5;45620:23;;45612:32;;45581:4;:64::i;:::-;45574:71;;45434:219;;;;;:::o;32455:273::-;32549:7;32617:5;32596:3;:11;;:18;;;;:26;32574:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;32702:3;:11;;32714:5;32702:18;;;;;;;;;;;;;;;;;;;;;;;;32695:25;;32455:273;;;;:::o;43159:348::-;43253:7;43262;43331:5;43309:3;:12;;:19;;;;:27;43287:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;43411:22;43436:3;:12;;43449:5;43436:19;;;;;;;;;;;;;;;;;;;;;;;;;;43411:44;;43474:5;:10;;;43486:5;:12;;;43466:33;;;;;43159:348;;;;;:::o;44757:353::-;44885:7;44905:16;44924:3;:12;;:17;44937:3;44924:17;;;;;;;;;;;;44905:36;;44972:1;44960:8;:13;;44975:12;44952:36;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;45042:3;:12;;45066:1;45055:8;:12;;;;:::i;:::-;45042:26;;;;;;;;;;;;;;;;;;;;;;;;;;:33;;;45035:40;;;44757:353;;;;;:::o;31992:109::-;32048:7;32075:3;:11;;:18;;;;32068:25;;31992:109;;;:::o;62101:321::-;62231:18;62237:2;62241:7;62231:5;:18::i;:::-;62282:54;62313:1;62317:2;62321:7;62330:5;62282:22;:54::i;:::-;62260:154;;;;;;;;;;;;:::i;:::-;;;;;;;;;62101:321;;;:::o;66269:694::-;66424:4;66446:15;:2;:13;;;:15::i;:::-;66441:60;;66485:4;66478:11;;;;66441:60;66511:23;66537:313;66608:45;;;66672:12;:10;:12::i;:::-;66703:4;66726:7;66752:5;66567:205;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66537:313;;;;;;;;;;;;;;;;;:2;:15;;;;:313;;;;;:::i;:::-;66511:339;;66861:13;66888:10;66877:32;;;;;;;;;;;;:::i;:::-;66861:48;;50268:10;66938:16;;66928:26;;;:6;:26;;;;66920:35;;;;66269:694;;;;;;;:::o;42432:157::-;42530:4;42580:1;42559:3;:12;;:17;42572:3;42559:17;;;;;;;;;;;;:22;;42552:29;;42432:157;;;;:::o;30102:1557::-;30168:4;30286:18;30307:3;:12;;:19;30320:5;30307:19;;;;;;;;;;;;30286:40;;30357:1;30343:10;:15;30339:1313;;30718:21;30755:1;30742:10;:14;;;;:::i;:::-;30718:38;;30771:17;30812:1;30791:3;:11;;:18;;;;:22;;;;:::i;:::-;30771:42;;31058:17;31078:3;:11;;31090:9;31078:22;;;;;;;;;;;;;;;;;;;;;;;;31058:42;;31224:9;31195:3;:11;;31207:13;31195:26;;;;;;;;;;;;;;;;;;;;;;;:38;;;;31343:1;31327:13;:17;;;;:::i;:::-;31301:3;:12;;:23;31314:9;31301:23;;;;;;;;;;;:43;;;;31453:3;:11;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31548:3;:12;;:19;31561:5;31548:19;;;;;;;;;;;31541:26;;;31591:4;31584:11;;;;;;;;30339:1313;31635:5;31628:12;;;30102:1557;;;;;:::o;29512:414::-;29575:4;29597:21;29607:3;29612:5;29597:9;:21::i;:::-;29592:327;;29635:3;:11;;29652:5;29635:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29818:3;:11;;:18;;;;29796:3;:12;;:19;29809:5;29796:19;;;;;;;;;;;:40;;;;29858:4;29851:11;;;;29592:327;29902:5;29895:12;;29512:414;;;;;:::o;39874:737::-;39984:4;40100:16;40119:3;:12;;:17;40132:3;40119:17;;;;;;;;;;;;40100:36;;40165:1;40153:8;:13;40149:455;;;40233:3;:12;;40251:36;;;;;;;;40267:3;40251:36;;;;40280:5;40251:36;;;40233:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40446:3;:12;;:19;;;;40426:3;:12;;:17;40439:3;40426:17;;;;;;;;;;;:39;;;;40487:4;40480:11;;;;;40149:455;40560:5;40524:3;:12;;40548:1;40537:8;:12;;;;:::i;:::-;40524:26;;;;;;;;;;;;;;;;;;;;;;;;;;:33;;:41;;;;40587:5;40580:12;;;39874:737;;;;;;:::o;62758:404::-;62852:1;62838:16;;:2;:16;;;;62830:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;62911:16;62919:7;62911;:16::i;:::-;62910:17;62902:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;62973:45;63002:1;63006:2;63010:7;62973:20;:45::i;:::-;63031:30;63053:7;63031:13;:17;63045:2;63031:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;63074:29;63091:7;63100:2;63074:12;:16;;:29;;;;;:::i;:::-;;63146:7;63142:2;63121:33;;63138:1;63121:33;;;;;;;;;;;;62758:404;;:::o;19845:444::-;19905:4;20113:12;20237:7;20225:20;20217:28;;20280:1;20273:4;:8;20266:15;;;19845:444;;;:::o;22882:229::-;23019:12;23051:52;23073:6;23081:4;23087:1;23090:12;23051:21;:52::i;:::-;23044:59;;22882:229;;;;;:::o;31745:161::-;31845:4;31897:1;31874:3;:12;;:19;31887:5;31874:19;;;;;;;;;;;;:24;;31867:31;;31745:161;;;;:::o;24098:632::-;24268:12;24340:5;24315:21;:30;;24293:118;;;;;;;;;;;;:::i;:::-;;;;;;;;;24430:18;24441:6;24430:10;:18::i;:::-;24422:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;24556:12;24570:23;24597:6;:11;;24616:5;24637:4;24597:55;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24555:97;;;;24670:52;24688:7;24697:10;24709:12;24670:17;:52::i;:::-;24663:59;;;;24098:632;;;;;;:::o;27021:777::-;27171:12;27200:7;27196:595;;;27231:10;27224:17;;;;27196:595;27365:1;27345:10;:17;:21;27341:439;;;27608:10;27602:17;27669:15;27656:10;27652:2;27648:19;27641:44;27556:148;27751:12;27744:20;;;;;;;;;;;:::i;:::-;;;;;;;;27021:777;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:342:1:-;;109:64;124:48;165:6;124:48;:::i;:::-;109:64;:::i;:::-;100:73;;196:6;189:5;182:21;234:4;227:5;223:16;272:3;263:6;258:3;254:16;251:25;248:2;;;289:1;286;279:12;248:2;302:41;336:6;331:3;326;302:41;:::i;:::-;90:259;;;;;;:::o;355:344::-;;458:65;473:49;515:6;473:49;:::i;:::-;458:65;:::i;:::-;449:74;;546:6;539:5;532:21;584:4;577:5;573:16;622:3;613:6;608:3;604:16;601:25;598:2;;;639:1;636;629:12;598:2;652:41;686:6;681:3;676;652:41;:::i;:::-;439:260;;;;;;:::o;705:353::-;;819:65;834:49;876:6;834:49;:::i;:::-;819:65;:::i;:::-;810:74;;907:6;900:5;893:21;945:4;938:5;934:16;983:3;974:6;969:3;965:16;962:25;959:2;;;1000:1;997;990:12;959:2;1013:39;1045:6;1040:3;1035;1013:39;:::i;:::-;800:258;;;;;;:::o;1064:139::-;;1148:6;1135:20;1126:29;;1164:33;1191:5;1164:33;:::i;:::-;1116:87;;;;:::o;1209:143::-;;1297:6;1291:13;1282:22;;1313:33;1340:5;1313:33;:::i;:::-;1272:80;;;;:::o;1358:133::-;;1439:6;1426:20;1417:29;;1455:30;1479:5;1455:30;:::i;:::-;1407:84;;;;:::o;1497:137::-;;1580:6;1567:20;1558:29;;1596:32;1622:5;1596:32;:::i;:::-;1548:86;;;;:::o;1640:141::-;;1727:6;1721:13;1712:22;;1743:32;1769:5;1743:32;:::i;:::-;1702:79;;;;:::o;1800:271::-;;1904:3;1897:4;1889:6;1885:17;1881:27;1871:2;;1922:1;1919;1912:12;1871:2;1962:6;1949:20;1987:78;2061:3;2053:6;2046:4;2038:6;2034:17;1987:78;:::i;:::-;1978:87;;1861:210;;;;;:::o;2091:273::-;;2196:3;2189:4;2181:6;2177:17;2173:27;2163:2;;2214:1;2211;2204:12;2163:2;2254:6;2241:20;2279:79;2354:3;2346:6;2339:4;2331:6;2327:17;2279:79;:::i;:::-;2270:88;;2153:211;;;;;:::o;2384:288::-;;2500:3;2493:4;2485:6;2481:17;2477:27;2467:2;;2518:1;2515;2508:12;2467:2;2551:6;2545:13;2576:90;2662:3;2654:6;2647:4;2639:6;2635:17;2576:90;:::i;:::-;2567:99;;2457:215;;;;;:::o;2678:139::-;;2762:6;2749:20;2740:29;;2778:33;2805:5;2778:33;:::i;:::-;2730:87;;;;:::o;2823:262::-;;2931:2;2919:9;2910:7;2906:23;2902:32;2899:2;;;2947:1;2944;2937:12;2899:2;2990:1;3015:53;3060:7;3051:6;3040:9;3036:22;3015:53;:::i;:::-;3005:63;;2961:117;2889:196;;;;:::o;3091:284::-;;3210:2;3198:9;3189:7;3185:23;3181:32;3178:2;;;3226:1;3223;3216:12;3178:2;3269:1;3294:64;3350:7;3341:6;3330:9;3326:22;3294:64;:::i;:::-;3284:74;;3240:128;3168:207;;;;:::o;3381:407::-;;;3506:2;3494:9;3485:7;3481:23;3477:32;3474:2;;;3522:1;3519;3512:12;3474:2;3565:1;3590:53;3635:7;3626:6;3615:9;3611:22;3590:53;:::i;:::-;3580:63;;3536:117;3692:2;3718:53;3763:7;3754:6;3743:9;3739:22;3718:53;:::i;:::-;3708:63;;3663:118;3464:324;;;;;:::o;3794:552::-;;;;3936:2;3924:9;3915:7;3911:23;3907:32;3904:2;;;3952:1;3949;3942:12;3904:2;3995:1;4020:53;4065:7;4056:6;4045:9;4041:22;4020:53;:::i;:::-;4010:63;;3966:117;4122:2;4148:53;4193:7;4184:6;4173:9;4169:22;4148:53;:::i;:::-;4138:63;;4093:118;4250:2;4276:53;4321:7;4312:6;4301:9;4297:22;4276:53;:::i;:::-;4266:63;;4221:118;3894:452;;;;;:::o;4352:809::-;;;;;4520:3;4508:9;4499:7;4495:23;4491:33;4488:2;;;4537:1;4534;4527:12;4488:2;4580:1;4605:53;4650:7;4641:6;4630:9;4626:22;4605:53;:::i;:::-;4595:63;;4551:117;4707:2;4733:53;4778:7;4769:6;4758:9;4754:22;4733:53;:::i;:::-;4723:63;;4678:118;4835:2;4861:53;4906:7;4897:6;4886:9;4882:22;4861:53;:::i;:::-;4851:63;;4806:118;4991:2;4980:9;4976:18;4963:32;5022:18;5014:6;5011:30;5008:2;;;5054:1;5051;5044:12;5008:2;5082:62;5136:7;5127:6;5116:9;5112:22;5082:62;:::i;:::-;5072:72;;4934:220;4478:683;;;;;;;:::o;5167:401::-;;;5289:2;5277:9;5268:7;5264:23;5260:32;5257:2;;;5305:1;5302;5295:12;5257:2;5348:1;5373:53;5418:7;5409:6;5398:9;5394:22;5373:53;:::i;:::-;5363:63;;5319:117;5475:2;5501:50;5543:7;5534:6;5523:9;5519:22;5501:50;:::i;:::-;5491:60;;5446:115;5247:321;;;;;:::o;5574:407::-;;;5699:2;5687:9;5678:7;5674:23;5670:32;5667:2;;;5715:1;5712;5705:12;5667:2;5758:1;5783:53;5828:7;5819:6;5808:9;5804:22;5783:53;:::i;:::-;5773:63;;5729:117;5885:2;5911:53;5956:7;5947:6;5936:9;5932:22;5911:53;:::i;:::-;5901:63;;5856:118;5657:324;;;;;:::o;5987:260::-;;6094:2;6082:9;6073:7;6069:23;6065:32;6062:2;;;6110:1;6107;6100:12;6062:2;6153:1;6178:52;6222:7;6213:6;6202:9;6198:22;6178:52;:::i;:::-;6168:62;;6124:116;6052:195;;;;:::o;6253:282::-;;6371:2;6359:9;6350:7;6346:23;6342:32;6339:2;;;6387:1;6384;6377:12;6339:2;6430:1;6455:63;6510:7;6501:6;6490:9;6486:22;6455:63;:::i;:::-;6445:73;;6401:127;6329:206;;;;:::o;6541:375::-;;6659:2;6647:9;6638:7;6634:23;6630:32;6627:2;;;6675:1;6672;6665:12;6627:2;6746:1;6735:9;6731:17;6718:31;6776:18;6768:6;6765:30;6762:2;;;6808:1;6805;6798:12;6762:2;6836:63;6891:7;6882:6;6871:9;6867:22;6836:63;:::i;:::-;6826:73;;6689:220;6617:299;;;;:::o;6922:390::-;;7051:2;7039:9;7030:7;7026:23;7022:32;7019:2;;;7067:1;7064;7057:12;7019:2;7131:1;7120:9;7116:17;7110:24;7161:18;7153:6;7150:30;7147:2;;;7193:1;7190;7183:12;7147:2;7221:74;7287:7;7278:6;7267:9;7263:22;7221:74;:::i;:::-;7211:84;;7081:224;7009:303;;;;:::o;7318:262::-;;7426:2;7414:9;7405:7;7401:23;7397:32;7394:2;;;7442:1;7439;7432:12;7394:2;7485:1;7510:53;7555:7;7546:6;7535:9;7531:22;7510:53;:::i;:::-;7500:63;;7456:117;7384:196;;;;:::o;7586:118::-;7673:24;7691:5;7673:24;:::i;:::-;7668:3;7661:37;7651:53;;:::o;7710:109::-;7791:21;7806:5;7791:21;:::i;:::-;7786:3;7779:34;7769:50;;:::o;7825:360::-;;7939:38;7971:5;7939:38;:::i;:::-;7993:70;8056:6;8051:3;7993:70;:::i;:::-;7986:77;;8072:52;8117:6;8112:3;8105:4;8098:5;8094:16;8072:52;:::i;:::-;8149:29;8171:6;8149:29;:::i;:::-;8144:3;8140:39;8133:46;;7915:270;;;;;:::o;8191:373::-;;8323:38;8355:5;8323:38;:::i;:::-;8377:88;8458:6;8453:3;8377:88;:::i;:::-;8370:95;;8474:52;8519:6;8514:3;8507:4;8500:5;8496:16;8474:52;:::i;:::-;8551:6;8546:3;8542:16;8535:23;;8299:265;;;;;:::o;8570:364::-;;8686:39;8719:5;8686:39;:::i;:::-;8741:71;8805:6;8800:3;8741:71;:::i;:::-;8734:78;;8821:52;8866:6;8861:3;8854:4;8847:5;8843:16;8821:52;:::i;:::-;8898:29;8920:6;8898:29;:::i;:::-;8893:3;8889:39;8882:46;;8662:272;;;;;:::o;8940:377::-;;9074:39;9107:5;9074:39;:::i;:::-;9129:89;9211:6;9206:3;9129:89;:::i;:::-;9122:96;;9227:52;9272:6;9267:3;9260:4;9253:5;9249:16;9227:52;:::i;:::-;9304:6;9299:3;9295:16;9288:23;;9050:267;;;;;:::o;9323:366::-;;9486:67;9550:2;9545:3;9486:67;:::i;:::-;9479:74;;9583:34;9579:1;9574:3;9570:11;9563:55;9649:4;9644:2;9639:3;9635:12;9628:26;9680:2;9675:3;9671:12;9664:19;;9469:220;;;:::o;9695:382::-;;9858:67;9922:2;9917:3;9858:67;:::i;:::-;9851:74;;9955:34;9951:1;9946:3;9942:11;9935:55;10021:20;10016:2;10011:3;10007:12;10000:42;10068:2;10063:3;10059:12;10052:19;;9841:236;;;:::o;10083:370::-;;10246:67;10310:2;10305:3;10246:67;:::i;:::-;10239:74;;10343:34;10339:1;10334:3;10330:11;10323:55;10409:8;10404:2;10399:3;10395:12;10388:30;10444:2;10439:3;10435:12;10428:19;;10229:224;;;:::o;10459:326::-;;10622:67;10686:2;10681:3;10622:67;:::i;:::-;10615:74;;10719:30;10715:1;10710:3;10706:11;10699:51;10776:2;10771:3;10767:12;10760:19;;10605:180;;;:::o;10791:312::-;;10954:67;11018:2;11013:3;10954:67;:::i;:::-;10947:74;;11051:16;11047:1;11042:3;11038:11;11031:37;11094:2;11089:3;11085:12;11078:19;;10937:166;;;:::o;11109:368::-;;11272:67;11336:2;11331:3;11272:67;:::i;:::-;11265:74;;11369:34;11365:1;11360:3;11356:11;11349:55;11435:6;11430:2;11425:3;11421:12;11414:28;11468:2;11463:3;11459:12;11452:19;;11255:222;;;:::o;11483:323::-;;11646:67;11710:2;11705:3;11646:67;:::i;:::-;11639:74;;11743:27;11739:1;11734:3;11730:11;11723:48;11797:2;11792:3;11788:12;11781:19;;11629:177;;;:::o;11812:370::-;;11975:67;12039:2;12034:3;11975:67;:::i;:::-;11968:74;;12072:34;12068:1;12063:3;12059:11;12052:55;12138:8;12133:2;12128:3;12124:12;12117:30;12173:2;12168:3;12164:12;12157:19;;11958:224;;;:::o;12188:376::-;;12351:67;12415:2;12410:3;12351:67;:::i;:::-;12344:74;;12448:34;12444:1;12439:3;12435:11;12428:55;12514:14;12509:2;12504:3;12500:12;12493:36;12555:2;12550:3;12546:12;12539:19;;12334:230;;;:::o;12570:388::-;;12733:67;12797:2;12792:3;12733:67;:::i;:::-;12726:74;;12830:34;12826:1;12821:3;12817:11;12810:55;12896:26;12891:2;12886:3;12882:12;12875:48;12949:2;12944:3;12940:12;12933:19;;12716:242;;;:::o;12964:374::-;;13127:67;13191:2;13186:3;13127:67;:::i;:::-;13120:74;;13224:34;13220:1;13215:3;13211:11;13204:55;13290:12;13285:2;13280:3;13276:12;13269:34;13329:2;13324:3;13320:12;13313:19;;13110:228;;;:::o;13344:366::-;;13507:67;13571:2;13566:3;13507:67;:::i;:::-;13500:74;;13604:34;13600:1;13595:3;13591:11;13584:55;13670:4;13665:2;13660:3;13656:12;13649:26;13701:2;13696:3;13692:12;13685:19;;13490:220;;;:::o;13716:330::-;;13879:67;13943:2;13938:3;13879:67;:::i;:::-;13872:74;;13976:34;13972:1;13967:3;13963:11;13956:55;14037:2;14032:3;14028:12;14021:19;;13862:184;;;:::o;14052:376::-;;14215:67;14279:2;14274:3;14215:67;:::i;:::-;14208:74;;14312:34;14308:1;14303:3;14299:11;14292:55;14378:14;14373:2;14368:3;14364:12;14357:36;14419:2;14414:3;14410:12;14403:19;;14198:230;;;:::o;14434:369::-;;14597:67;14661:2;14656:3;14597:67;:::i;:::-;14590:74;;14694:34;14690:1;14685:3;14681:11;14674:55;14760:7;14755:2;14750:3;14746:12;14739:29;14794:2;14789:3;14785:12;14778:19;;14580:223;;;:::o;14809:330::-;;14972:67;15036:2;15031:3;14972:67;:::i;:::-;14965:74;;15069:34;15065:1;15060:3;15056:11;15049:55;15130:2;15125:3;15121:12;15114:19;;14955:184;;;:::o;15145:314::-;;15308:67;15372:2;15367:3;15308:67;:::i;:::-;15301:74;;15405:18;15401:1;15396:3;15392:11;15385:39;15450:2;15445:3;15441:12;15434:19;;15291:168;;;:::o;15465:373::-;;15628:67;15692:2;15687:3;15628:67;:::i;:::-;15621:74;;15725:34;15721:1;15716:3;15712:11;15705:55;15791:11;15786:2;15781:3;15777:12;15770:33;15829:2;15824:3;15820:12;15813:19;;15611:227;;;:::o;15844:379::-;;16007:67;16071:2;16066:3;16007:67;:::i;:::-;16000:74;;16104:34;16100:1;16095:3;16091:11;16084:55;16170:17;16165:2;16160:3;16156:12;16149:39;16214:2;16209:3;16205:12;16198:19;;15990:233;;;:::o;16229:365::-;;16392:67;16456:2;16451:3;16392:67;:::i;:::-;16385:74;;16489:34;16485:1;16480:3;16476:11;16469:55;16555:3;16550:2;16545:3;16541:12;16534:25;16585:2;16580:3;16576:12;16569:19;;16375:219;;;:::o;16600:381::-;;16763:67;16827:2;16822:3;16763:67;:::i;:::-;16756:74;;16860:34;16856:1;16851:3;16847:11;16840:55;16926:19;16921:2;16916:3;16912:12;16905:41;16972:2;16967:3;16963:12;16956:19;;16746:235;;;:::o;16987:327::-;;17150:67;17214:2;17209:3;17150:67;:::i;:::-;17143:74;;17247:31;17243:1;17238:3;17234:11;17227:52;17305:2;17300:3;17296:12;17289:19;;17133:181;;;:::o;17320:329::-;;17483:67;17547:2;17542:3;17483:67;:::i;:::-;17476:74;;17580:33;17576:1;17571:3;17567:11;17560:54;17640:2;17635:3;17631:12;17624:19;;17466:183;;;:::o;17655:118::-;17742:24;17760:5;17742:24;:::i;:::-;17737:3;17730:37;17720:53;;:::o;17779:271::-;;17931:93;18020:3;18011:6;17931:93;:::i;:::-;17924:100;;18041:3;18034:10;;17913:137;;;;:::o;18056:435::-;;18258:95;18349:3;18340:6;18258:95;:::i;:::-;18251:102;;18370:95;18461:3;18452:6;18370:95;:::i;:::-;18363:102;;18482:3;18475:10;;18240:251;;;;;:::o;18497:222::-;;18628:2;18617:9;18613:18;18605:26;;18641:71;18709:1;18698:9;18694:17;18685:6;18641:71;:::i;:::-;18595:124;;;;:::o;18725:640::-;;18958:3;18947:9;18943:19;18935:27;;18972:71;19040:1;19029:9;19025:17;19016:6;18972:71;:::i;:::-;19053:72;19121:2;19110:9;19106:18;19097:6;19053:72;:::i;:::-;19135;19203:2;19192:9;19188:18;19179:6;19135:72;:::i;:::-;19254:9;19248:4;19244:20;19239:2;19228:9;19224:18;19217:48;19282:76;19353:4;19344:6;19282:76;:::i;:::-;19274:84;;18925:440;;;;;;;:::o;19371:210::-;;19496:2;19485:9;19481:18;19473:26;;19509:65;19571:1;19560:9;19556:17;19547:6;19509:65;:::i;:::-;19463:118;;;;:::o;19587:313::-;;19738:2;19727:9;19723:18;19715:26;;19787:9;19781:4;19777:20;19773:1;19762:9;19758:17;19751:47;19815:78;19888:4;19879:6;19815:78;:::i;:::-;19807:86;;19705:195;;;;:::o;19906:419::-;;20110:2;20099:9;20095:18;20087:26;;20159:9;20153:4;20149:20;20145:1;20134:9;20130:17;20123:47;20187:131;20313:4;20187:131;:::i;:::-;20179:139;;20077:248;;;:::o;20331:419::-;;20535:2;20524:9;20520:18;20512:26;;20584:9;20578:4;20574:20;20570:1;20559:9;20555:17;20548:47;20612:131;20738:4;20612:131;:::i;:::-;20604:139;;20502:248;;;:::o;20756:419::-;;20960:2;20949:9;20945:18;20937:26;;21009:9;21003:4;20999:20;20995:1;20984:9;20980:17;20973:47;21037:131;21163:4;21037:131;:::i;:::-;21029:139;;20927:248;;;:::o;21181:419::-;;21385:2;21374:9;21370:18;21362:26;;21434:9;21428:4;21424:20;21420:1;21409:9;21405:17;21398:47;21462:131;21588:4;21462:131;:::i;:::-;21454:139;;21352:248;;;:::o;21606:419::-;;21810:2;21799:9;21795:18;21787:26;;21859:9;21853:4;21849:20;21845:1;21834:9;21830:17;21823:47;21887:131;22013:4;21887:131;:::i;:::-;21879:139;;21777:248;;;:::o;22031:419::-;;22235:2;22224:9;22220:18;22212:26;;22284:9;22278:4;22274:20;22270:1;22259:9;22255:17;22248:47;22312:131;22438:4;22312:131;:::i;:::-;22304:139;;22202:248;;;:::o;22456:419::-;;22660:2;22649:9;22645:18;22637:26;;22709:9;22703:4;22699:20;22695:1;22684:9;22680:17;22673:47;22737:131;22863:4;22737:131;:::i;:::-;22729:139;;22627:248;;;:::o;22881:419::-;;23085:2;23074:9;23070:18;23062:26;;23134:9;23128:4;23124:20;23120:1;23109:9;23105:17;23098:47;23162:131;23288:4;23162:131;:::i;:::-;23154:139;;23052:248;;;:::o;23306:419::-;;23510:2;23499:9;23495:18;23487:26;;23559:9;23553:4;23549:20;23545:1;23534:9;23530:17;23523:47;23587:131;23713:4;23587:131;:::i;:::-;23579:139;;23477:248;;;:::o;23731:419::-;;23935:2;23924:9;23920:18;23912:26;;23984:9;23978:4;23974:20;23970:1;23959:9;23955:17;23948:47;24012:131;24138:4;24012:131;:::i;:::-;24004:139;;23902:248;;;:::o;24156:419::-;;24360:2;24349:9;24345:18;24337:26;;24409:9;24403:4;24399:20;24395:1;24384:9;24380:17;24373:47;24437:131;24563:4;24437:131;:::i;:::-;24429:139;;24327:248;;;:::o;24581:419::-;;24785:2;24774:9;24770:18;24762:26;;24834:9;24828:4;24824:20;24820:1;24809:9;24805:17;24798:47;24862:131;24988:4;24862:131;:::i;:::-;24854:139;;24752:248;;;:::o;25006:419::-;;25210:2;25199:9;25195:18;25187:26;;25259:9;25253:4;25249:20;25245:1;25234:9;25230:17;25223:47;25287:131;25413:4;25287:131;:::i;:::-;25279:139;;25177:248;;;:::o;25431:419::-;;25635:2;25624:9;25620:18;25612:26;;25684:9;25678:4;25674:20;25670:1;25659:9;25655:17;25648:47;25712:131;25838:4;25712:131;:::i;:::-;25704:139;;25602:248;;;:::o;25856:419::-;;26060:2;26049:9;26045:18;26037:26;;26109:9;26103:4;26099:20;26095:1;26084:9;26080:17;26073:47;26137:131;26263:4;26137:131;:::i;:::-;26129:139;;26027:248;;;:::o;26281:419::-;;26485:2;26474:9;26470:18;26462:26;;26534:9;26528:4;26524:20;26520:1;26509:9;26505:17;26498:47;26562:131;26688:4;26562:131;:::i;:::-;26554:139;;26452:248;;;:::o;26706:419::-;;26910:2;26899:9;26895:18;26887:26;;26959:9;26953:4;26949:20;26945:1;26934:9;26930:17;26923:47;26987:131;27113:4;26987:131;:::i;:::-;26979:139;;26877:248;;;:::o;27131:419::-;;27335:2;27324:9;27320:18;27312:26;;27384:9;27378:4;27374:20;27370:1;27359:9;27355:17;27348:47;27412:131;27538:4;27412:131;:::i;:::-;27404:139;;27302:248;;;:::o;27556:419::-;;27760:2;27749:9;27745:18;27737:26;;27809:9;27803:4;27799:20;27795:1;27784:9;27780:17;27773:47;27837:131;27963:4;27837:131;:::i;:::-;27829:139;;27727:248;;;:::o;27981:419::-;;28185:2;28174:9;28170:18;28162:26;;28234:9;28228:4;28224:20;28220:1;28209:9;28205:17;28198:47;28262:131;28388:4;28262:131;:::i;:::-;28254:139;;28152:248;;;:::o;28406:419::-;;28610:2;28599:9;28595:18;28587:26;;28659:9;28653:4;28649:20;28645:1;28634:9;28630:17;28623:47;28687:131;28813:4;28687:131;:::i;:::-;28679:139;;28577:248;;;:::o;28831:419::-;;29035:2;29024:9;29020:18;29012:26;;29084:9;29078:4;29074:20;29070:1;29059:9;29055:17;29048:47;29112:131;29238:4;29112:131;:::i;:::-;29104:139;;29002:248;;;:::o;29256:419::-;;29460:2;29449:9;29445:18;29437:26;;29509:9;29503:4;29499:20;29495:1;29484:9;29480:17;29473:47;29537:131;29663:4;29537:131;:::i;:::-;29529:139;;29427:248;;;:::o;29681:222::-;;29812:2;29801:9;29797:18;29789:26;;29825:71;29893:1;29882:9;29878:17;29869:6;29825:71;:::i;:::-;29779:124;;;;:::o;29909:283::-;;29975:2;29969:9;29959:19;;30017:4;30009:6;30005:17;30124:6;30112:10;30109:22;30088:18;30076:10;30073:34;30070:62;30067:2;;;30135:18;;:::i;:::-;30067:2;30175:10;30171:2;30164:22;29949:243;;;;:::o;30198:331::-;;30349:18;30341:6;30338:30;30335:2;;;30371:18;;:::i;:::-;30335:2;30456:4;30452:9;30445:4;30437:6;30433:17;30429:33;30421:41;;30517:4;30511;30507:15;30499:23;;30264:265;;;:::o;30535:332::-;;30687:18;30679:6;30676:30;30673:2;;;30709:18;;:::i;:::-;30673:2;30794:4;30790:9;30783:4;30775:6;30771:17;30767:33;30759:41;;30855:4;30849;30845:15;30837:23;;30602:265;;;:::o;30873:98::-;;30958:5;30952:12;30942:22;;30931:40;;;:::o;30977:99::-;;31063:5;31057:12;31047:22;;31036:40;;;:::o;31082:168::-;;31199:6;31194:3;31187:19;31239:4;31234:3;31230:14;31215:29;;31177:73;;;;:::o;31256:147::-;;31394:3;31379:18;;31369:34;;;;:::o;31409:169::-;;31527:6;31522:3;31515:19;31567:4;31562:3;31558:14;31543:29;;31505:73;;;;:::o;31584:148::-;;31723:3;31708:18;;31698:34;;;;:::o;31738:305::-;;31797:20;31815:1;31797:20;:::i;:::-;31792:25;;31831:20;31849:1;31831:20;:::i;:::-;31826:25;;31985:1;31917:66;31913:74;31910:1;31907:81;31904:2;;;31991:18;;:::i;:::-;31904:2;32035:1;32032;32028:9;32021:16;;31782:261;;;;:::o;32049:191::-;;32109:20;32127:1;32109:20;:::i;:::-;32104:25;;32143:20;32161:1;32143:20;:::i;:::-;32138:25;;32182:1;32179;32176:8;32173:2;;;32187:18;;:::i;:::-;32173:2;32232:1;32229;32225:9;32217:17;;32094:146;;;;:::o;32246:96::-;;32312:24;32330:5;32312:24;:::i;:::-;32301:35;;32291:51;;;:::o;32348:90::-;;32425:5;32418:13;32411:21;32400:32;;32390:48;;;:::o;32444:149::-;;32520:66;32513:5;32509:78;32498:89;;32488:105;;;:::o;32599:126::-;;32676:42;32669:5;32665:54;32654:65;;32644:81;;;:::o;32731:77::-;;32797:5;32786:16;;32776:32;;;:::o;32814:154::-;32898:6;32893:3;32888;32875:30;32960:1;32951:6;32946:3;32942:16;32935:27;32865:103;;;:::o;32974:307::-;33042:1;33052:113;33066:6;33063:1;33060:13;33052:113;;;33151:1;33146:3;33142:11;33136:18;33132:1;33127:3;33123:11;33116:39;33088:2;33085:1;33081:10;33076:15;;33052:113;;;33183:6;33180:1;33177:13;33174:2;;;33263:1;33254:6;33249:3;33245:16;33238:27;33174:2;33023:258;;;;:::o;33287:320::-;;33368:1;33362:4;33358:12;33348:22;;33415:1;33409:4;33405:12;33436:18;33426:2;;33492:4;33484:6;33480:17;33470:27;;33426:2;33554;33546:6;33543:14;33523:18;33520:38;33517:2;;;33573:18;;:::i;:::-;33517:2;33338:269;;;;:::o;33613:180::-;33661:77;33658:1;33651:88;33758:4;33755:1;33748:15;33782:4;33779:1;33772:15;33799:180;33847:77;33844:1;33837:88;33944:4;33941:1;33934:15;33968:4;33965:1;33958:15;33985:180;34033:77;34030:1;34023:88;34130:4;34127:1;34120:15;34154:4;34151:1;34144:15;34171:102;;34263:2;34259:7;34254:2;34247:5;34243:14;34239:28;34229:38;;34219:54;;;:::o;34279:122::-;34352:24;34370:5;34352:24;:::i;:::-;34345:5;34342:35;34332:2;;34391:1;34388;34381:12;34332:2;34322:79;:::o;34407:116::-;34477:21;34492:5;34477:21;:::i;:::-;34470:5;34467:32;34457:2;;34513:1;34510;34503:12;34457:2;34447:76;:::o;34529:120::-;34601:23;34618:5;34601:23;:::i;:::-;34594:5;34591:34;34581:2;;34639:1;34636;34629:12;34581:2;34571:78;:::o;34655:122::-;34728:24;34746:5;34728:24;:::i;:::-;34721:5;34718:35;34708:2;;34767:1;34764;34757:12;34708:2;34698:79;:::o

Swarm Source

ipfs://599e9ce16df6ec3eac8806c77c7efbe6672e577afc7ca9db2281b1ed6f4b6a9e
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.