ETH Price: $3,330.77 (-4.22%)
Gas: 6.12 Gwei

Token

Odd Ogres (Ogre)
 

Overview

Max Total Supply

965 Ogre

Holders

474

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 Ogre
0x3F69a6192F032549062D513D8Fa6eD5Bb31b6825
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:
OddOgres

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

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

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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 payable) {
        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.6.0 <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.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity >=0.6.2 <0.8.0;

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

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

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

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

pragma solidity >=0.6.2 <0.8.0;

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

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

    // Base URI
    string private _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_) public {
        _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.6.0 <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() internal {
        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;
    }
}

pragma solidity ^0.7.0;
pragma abicoder v2;

/**
 * @title Odd Ogres contract
 * @dev Extends ERC721 Non-Fungible Token Standard basic implementation
 */

contract OddOgres is ERC721, Ownable {
  using SafeMath for uint256;

  bool public saleIsActive = false; // current status of sale, default is inactive
  string public NFT_PROVENANCE = ''; // hash representing ownership history of the NFT
  uint256 public NFTPrice = 33000000000000000; // 0.033 ETH
  uint256 public NFTReserve = 200; // Reserve amount of NFTs
  uint256 public constant maxNFTPurchase = 20; // max no. of tokens that can be bought at a time
  uint256 public constant MAX_NFTS = 9999; // max total supply of NFTs

  constructor() ERC721('Odd Ogres', 'Ogre') {}

  // Withdraws entire balance of contract (ETH) to owner account (owner-only)
  function withdraw() public onlyOwner {
    uint256 balance = address(this).balance;
    msg.sender.transfer(balance);
  }

  // Withdraws amount specified (ETH) from balance of contract to owner account (owner-only)
  function withdrawPartial(address payable _recipient, uint256 _amount)
    public
    onlyOwner
  {
    // Check that amount is not more than total contract balance
    require(
      _amount > 0 && _amount <= address(this).balance,
      'Withdraw amount must be positive and not exceed total contract balance'
    );
    _recipient.transfer(_amount);
  }

  // Sets a new price for the NFT (owner-only)
  function setNFTPrice(uint256 newPrice) public onlyOwner {
    NFTPrice = newPrice;
  }

  /**
   * Mints specified amount of new tokens for the recipient from the reserve
   * reduces the reserve by this amount (owner-only)
   */
  function reserveNFTs(address _to, uint256 _reserveAmount) public onlyOwner {
    uint256 supply = totalSupply();
    // Checks that there is sufficient reserve supply of tokens for the transaction
    require(
      _reserveAmount > 0 && _reserveAmount <= NFTReserve,
      'Not enough reserve left'
    );
    for (uint256 i = 0; i < _reserveAmount; i++) {
      _safeMint(_to, supply + i);
    }
    NFTReserve = NFTReserve.sub(_reserveAmount);
  }

  // Sets the provenance (ownership history) of the NFT (owner-only). The information is encoded by its hash value.
  function setProvenanceHash(string memory provenanceHash) public onlyOwner {
    NFT_PROVENANCE = provenanceHash;
  }

  /**
   * Sets 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. Identical to internal function _setBaseURI, but with public
   * visibility, and can be called by owner only.
   */
  function setBaseURI(string memory baseURI) public onlyOwner {
    _setBaseURI(baseURI);
  }

  // Toggle the current status of the sale between active/inactive (owner-only)
  function flipSaleState() public onlyOwner {
    saleIsActive = !saleIsActive;
  }

  // Returns an array of all tokens belonging to an owner (if any), indexed by their token ID
  function tokensOfOwner(address _owner)
    external
    view
    returns (uint256[] memory)
  {
    uint256 tokenCount = balanceOf(_owner);
    if (tokenCount == 0) {
      // Return an empty array
      return new uint256[](0);
    } else {
      uint256[] memory result = new uint256[](tokenCount);
      uint256 index;
      for (index = 0; index < tokenCount; index++) {
        result[index] = tokenOfOwnerByIndex(_owner, index);
      }
      return result;
    }
  }

  // Mints specified number of NFTs for the receiver and accepts payment (ETH) in return
  function mintNFT(uint256 numberOfTokens) public payable {
    // Checks that sale is currently active
    require(saleIsActive, 'Sale must be active to mint NFT');
    // Checks that requested number of tokens is positive and not more than the max purchase limit
    require(
      numberOfTokens > 0 && numberOfTokens <= maxNFTPurchase,
      'Exceeded max token purchase'
    );
    // Checks that final total supply of tokens (if sale occurs) would not exceed the max supply limit
    require(
      totalSupply().add(numberOfTokens) <= MAX_NFTS,
      'Purchase would exceed max supply of NFTs'
    );
    /**
         Checks that the buyer sends at least the total price of the transaction (ETH), calculated as number 
        * of tokens times the token price
        */
    require(
      msg.value >= NFTPrice.mul(numberOfTokens),
      'ETH value sent is not correct'
    );

    for (uint256 i = 0; i < numberOfTokens; i++) {
      uint256 mintIndex = totalSupply();
      if (totalSupply() < MAX_NFTS) {
        _safeMint(msg.sender, mintIndex);
      }
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_NFTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NFTPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NFTReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NFT_PROVENANCE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flipSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxNFTPurchase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"mintNFT","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_reserveAmount","type":"uint256"}],"name":"reserveNFTs","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":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"setNFTPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"provenanceHash","type":"string"}],"name":"setProvenanceHash","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":[{"internalType":"address","name":"_owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawPartial","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526000600a60146101000a81548160ff02191690831515021790555060405180602001604052806000815250600b908051906020019062000046929190620002fc565b5066753d533d968000600c5560c8600d553480156200006457600080fd5b506040518060400160405280600981526020017f4f6464204f6772657300000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f4f67726500000000000000000000000000000000000000000000000000000000815250620000e96301ffc9a760e01b6200021c60201b60201c565b816006908051906020019062000101929190620002fc565b5080600790805190602001906200011a929190620002fc565b50620001336380ac58cd60e01b6200021c60201b60201c565b6200014b635b5e139f60e01b6200021c60201b60201c565b6200016363780e9d6360e01b6200021c60201b60201c565b5050600062000177620002f460201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35062000427565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141562000288576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200027f90620003f4565b60405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928262000334576000855562000380565b82601f106200034f57805160ff191683800117855562000380565b8280016001018555821562000380579182015b828111156200037f57825182559160200191906001019062000362565b5b5090506200038f919062000393565b5090565b5b80821115620003ae57600081600090555060010162000394565b5090565b6000620003c1601c8362000416565b91507f4552433136353a20696e76616c696420696e74657266616365206964000000006000830152602082019050919050565b600060208201905081810360008301526200040f81620003b2565b9050919050565b600082825260208201905092915050565b61462280620004376000396000f3fe6080604052600436106102045760003560e01c80636c0360eb1161011857806395d89b41116100a0578063c87b56dd1161006f578063c87b56dd14610732578063cf1073001461076f578063e985e9c51461079a578063eb8d2444146107d7578063f2fde38b1461080257610204565b806395d89b411461068a578063a22cb465146106b5578063a38bffda146106de578063b88d4fde1461070957610204565b806381530b68116100e757806381530b68146105b457806384522aec146105dd5780638462151c146106065780638da5cb5b14610643578063926427441461066e57610204565b80636c0360eb1461050c57806370a082311461053757806370a8de8614610574578063715018a61461059d57610204565b80631bc347271161019b5780633ccfd60b1161016a5780633ccfd60b1461042957806342842e0e146104405780634f6ccce71461046957806355f804b3146104a65780636352211e146104cf57610204565b80631bc347271461038157806323b872dd146103ac5780632f745c59146103d557806334918dfd1461041257610204565b8063095ea7b3116101d7578063095ea7b3146102d9578063109695231461030257806318160ddd1461032b578063189f92bd1461035657610204565b806301ffc9a71461020957806306fdde0314610246578063081812fc14610271578063093d8c64146102ae575b600080fd5b34801561021557600080fd5b50610230600480360381019061022b9190613292565b61082b565b60405161023d9190613f53565b60405180910390f35b34801561025257600080fd5b5061025b610892565b6040516102689190613f6e565b60405180910390f35b34801561027d57600080fd5b5061029860048036038101906102939190613325565b610934565b6040516102a59190613eca565b60405180910390f35b3480156102ba57600080fd5b506102c36109b9565b6040516102d09190614310565b60405180910390f35b3480156102e557600080fd5b5061030060048036038101906102fb9190613256565b6109bf565b005b34801561030e57600080fd5b50610329600480360381019061032491906132e4565b610ad7565b005b34801561033757600080fd5b50610340610b6d565b60405161034d9190614310565b60405180910390f35b34801561036257600080fd5b5061036b610b7e565b6040516103789190614310565b60405180910390f35b34801561038d57600080fd5b50610396610b83565b6040516103a39190613f6e565b60405180910390f35b3480156103b857600080fd5b506103d360048036038101906103ce9190613150565b610c21565b005b3480156103e157600080fd5b506103fc60048036038101906103f79190613256565b610c81565b6040516104099190614310565b60405180910390f35b34801561041e57600080fd5b50610427610cdc565b005b34801561043557600080fd5b5061043e610d84565b005b34801561044c57600080fd5b5061046760048036038101906104629190613150565b610e4f565b005b34801561047557600080fd5b50610490600480360381019061048b9190613325565b610e6f565b60405161049d9190614310565b60405180910390f35b3480156104b257600080fd5b506104cd60048036038101906104c891906132e4565b610e92565b005b3480156104db57600080fd5b506104f660048036038101906104f19190613325565b610f1a565b6040516105039190613eca565b60405180910390f35b34801561051857600080fd5b50610521610f51565b60405161052e9190613f6e565b60405180910390f35b34801561054357600080fd5b5061055e600480360381019061055991906130af565b610ff3565b60405161056b9190614310565b60405180910390f35b34801561058057600080fd5b5061059b60048036038101906105969190613256565b6110b2565b005b3480156105a957600080fd5b506105b26111d0565b005b3480156105c057600080fd5b506105db60048036038101906105d69190613325565b61130d565b005b3480156105e957600080fd5b5061060460048036038101906105ff91906130d8565b611393565b005b34801561061257600080fd5b5061062d600480360381019061062891906130af565b6114a9565b60405161063a9190613f31565b60405180910390f35b34801561064f57600080fd5b506106586115a2565b6040516106659190613eca565b60405180910390f35b61068860048036038101906106839190613325565b6115cc565b005b34801561069657600080fd5b5061069f611765565b6040516106ac9190613f6e565b60405180910390f35b3480156106c157600080fd5b506106dc60048036038101906106d7919061321a565b611807565b005b3480156106ea57600080fd5b506106f3611988565b6040516107009190614310565b60405180910390f35b34801561071557600080fd5b50610730600480360381019061072b919061319f565b61198e565b005b34801561073e57600080fd5b5061075960048036038101906107549190613325565b6119f0565b6040516107669190613f6e565b60405180910390f35b34801561077b57600080fd5b50610784611b73565b6040516107919190614310565b60405180910390f35b3480156107a657600080fd5b506107c160048036038101906107bc9190613114565b611b79565b6040516107ce9190613f53565b60405180910390f35b3480156107e357600080fd5b506107ec611c0d565b6040516107f99190613f53565b60405180910390f35b34801561080e57600080fd5b50610829600480360381019061082491906130af565b611c20565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561092a5780601f106108ff5761010080835404028352916020019161092a565b820191906000526020600020905b81548152906001019060200180831161090d57829003601f168201915b5050505050905090565b600061093f82611dcc565b61097e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610975906141b0565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b61270f81565b60006109ca82610f1a565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3290614250565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a5a611de9565b73ffffffffffffffffffffffffffffffffffffffff161480610a895750610a8881610a83611de9565b611b79565b5b610ac8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610abf90614110565b60405180910390fd5b610ad28383611df1565b505050565b610adf611de9565b73ffffffffffffffffffffffffffffffffffffffff16610afd6115a2565b73ffffffffffffffffffffffffffffffffffffffff1614610b53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4a906141d0565b60405180910390fd5b80600b9080519060200190610b69929190612eb6565b5050565b6000610b796002611eaa565b905090565b601481565b600b8054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610c195780601f10610bee57610100808354040283529160200191610c19565b820191906000526020600020905b815481529060010190602001808311610bfc57829003601f168201915b505050505081565b610c32610c2c611de9565b82611ebf565b610c71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6890614290565b60405180910390fd5b610c7c838383611f9d565b505050565b6000610cd482600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206121b490919063ffffffff16565b905092915050565b610ce4611de9565b73ffffffffffffffffffffffffffffffffffffffff16610d026115a2565b73ffffffffffffffffffffffffffffffffffffffff1614610d58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4f906141d0565b60405180910390fd5b600a60149054906101000a900460ff1615600a60146101000a81548160ff021916908315150217905550565b610d8c611de9565b73ffffffffffffffffffffffffffffffffffffffff16610daa6115a2565b73ffffffffffffffffffffffffffffffffffffffff1614610e00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df7906141d0565b60405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610e4b573d6000803e3d6000fd5b5050565b610e6a8383836040518060200160405280600081525061198e565b505050565b600080610e868360026121ce90919063ffffffff16565b50905080915050919050565b610e9a611de9565b73ffffffffffffffffffffffffffffffffffffffff16610eb86115a2565b73ffffffffffffffffffffffffffffffffffffffff1614610f0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f05906141d0565b60405180910390fd5b610f17816121fa565b50565b6000610f4a826040518060600160405280602981526020016145c46029913960026122149092919063ffffffff16565b9050919050565b606060098054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610fe95780601f10610fbe57610100808354040283529160200191610fe9565b820191906000526020600020905b815481529060010190602001808311610fcc57829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611064576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105b90614130565b60405180910390fd5b6110ab600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612233565b9050919050565b6110ba611de9565b73ffffffffffffffffffffffffffffffffffffffff166110d86115a2565b73ffffffffffffffffffffffffffffffffffffffff161461112e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611125906141d0565b60405180910390fd5b6000611138610b6d565b905060008211801561114c5750600d548211155b61118b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118290614230565b60405180910390fd5b60005b828110156111af576111a284828401612248565b808060010191505061118e565b506111c582600d5461226690919063ffffffff16565b600d81905550505050565b6111d8611de9565b73ffffffffffffffffffffffffffffffffffffffff166111f66115a2565b73ffffffffffffffffffffffffffffffffffffffff161461124c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611243906141d0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b611315611de9565b73ffffffffffffffffffffffffffffffffffffffff166113336115a2565b73ffffffffffffffffffffffffffffffffffffffff1614611389576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611380906141d0565b60405180910390fd5b80600c8190555050565b61139b611de9565b73ffffffffffffffffffffffffffffffffffffffff166113b96115a2565b73ffffffffffffffffffffffffffffffffffffffff161461140f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611406906141d0565b60405180910390fd5b60008111801561141f5750478111155b61145e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611455906142d0565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156114a4573d6000803e3d6000fd5b505050565b606060006114b683610ff3565b9050600081141561151157600067ffffffffffffffff811180156114d957600080fd5b506040519080825280602002602001820160405280156115085781602001602082028036833780820191505090505b5091505061159d565b60008167ffffffffffffffff8111801561152a57600080fd5b506040519080825280602002602001820160405280156115595781602001602082028036833780820191505090505b50905060005b82811015611596576115718582610c81565b82828151811061157d57fe5b602002602001018181525050808060010191505061155f565b8193505050505b919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600a60149054906101000a900460ff1661161b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161290613fb0565b60405180910390fd5b60008111801561162c575060148111155b61166b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166290614270565b60405180910390fd5b61270f6116888261167a610b6d565b6122b690919063ffffffff16565b11156116c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c090613ff0565b60405180910390fd5b6116de81600c5461230b90919063ffffffff16565b341015611720576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611717906142f0565b60405180910390fd5b60005b81811015611761576000611735610b6d565b905061270f611742610b6d565b1015611753576117523382612248565b5b508080600101915050611723565b5050565b606060078054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156117fd5780601f106117d2576101008083540402835291602001916117fd565b820191906000526020600020905b8154815290600101906020018083116117e057829003601f168201915b5050505050905090565b61180f611de9565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561187d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187490614090565b60405180910390fd5b806005600061188a611de9565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611937611de9565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161197c9190613f53565b60405180910390a35050565b600c5481565b61199f611999611de9565b83611ebf565b6119de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d590614290565b60405180910390fd5b6119ea8484848461237b565b50505050565b60606119fb82611dcc565b611a3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3190614210565b60405180910390fd5b6000600860008481526020019081526020016000208054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611ae35780601f10611ab857610100808354040283529160200191611ae3565b820191906000526020600020905b815481529060010190602001808311611ac657829003601f168201915b505050505090506000611af4610f51565b9050600081511415611b0a578192505050611b6e565b600082511115611b3f578082604051602001611b27929190613ea6565b60405160208183030381529060405292505050611b6e565b80611b49856123d7565b604051602001611b5a929190613ea6565b604051602081830303815290604052925050505b919050565b600d5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600a60149054906101000a900460ff1681565b611c28611de9565b73ffffffffffffffffffffffffffffffffffffffff16611c466115a2565b73ffffffffffffffffffffffffffffffffffffffff1614611c9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c93906141d0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611d0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d0390614010565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000611de282600261251e90919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611e6483610f1a565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611eb882600001612538565b9050919050565b6000611eca82611dcc565b611f09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f00906140f0565b60405180910390fd5b6000611f1483610f1a565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611f8357508373ffffffffffffffffffffffffffffffffffffffff16611f6b84610934565b73ffffffffffffffffffffffffffffffffffffffff16145b80611f945750611f938185611b79565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611fbd82610f1a565b73ffffffffffffffffffffffffffffffffffffffff1614612013576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161200a906141f0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612083576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207a90614070565b60405180910390fd5b61208e838383612549565b612099600082611df1565b6120ea81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061254e90919063ffffffff16565b5061213c81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061256890919063ffffffff16565b50612153818360026125829092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006121c383600001836125b7565b60001c905092915050565b6000806000806121e18660000186612624565b915091508160001c8160001c9350935050509250929050565b8060099080519060200190612210929190612eb6565b5050565b6000612227846000018460001b846126a7565b60001c90509392505050565b600061224182600001612738565b9050919050565b612262828260405180602001604052806000815250612749565b5050565b6000828211156122ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122a2906140b0565b60405180910390fd5b818303905092915050565b600080828401905083811015612301576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122f890614050565b60405180910390fd5b8091505092915050565b60008083141561231e5760009050612375565b600082840290508284828161232f57fe5b0414612370576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236790614190565b60405180910390fd5b809150505b92915050565b612386848484611f9d565b612392848484846127a4565b6123d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123c890613fd0565b60405180910390fd5b50505050565b6060600082141561241f576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612519565b600082905060005b60008214612449578080600101915050600a828161244157fe5b049150612427565b60008167ffffffffffffffff8111801561246257600080fd5b506040519080825280601f01601f1916602001820160405280156124955781602001600182028036833780820191505090505b50905060006001830390508593505b6000841461251157600a84816124b657fe5b0660300160f81b828280600190039350815181106124d057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a848161250957fe5b0493506124a4565b819450505050505b919050565b6000612530836000018360001b612908565b905092915050565b600081600001805490509050919050565b505050565b6000612560836000018360001b61292b565b905092915050565b600061257a836000018360001b612a13565b905092915050565b60006125ae846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612a83565b90509392505050565b600081836000018054905011612602576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f990613f90565b60405180910390fd5b82600001828154811061261157fe5b9060005260206000200154905092915050565b60008082846000018054905011612670576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161266790614150565b60405180910390fd5b600084600001848154811061268157fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008084600101600085815260200190815260200160002054905060008114158390612709576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127009190613f6e565b60405180910390fd5b5084600001600182038154811061271c57fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b6127538383612b5f565b61276060008484846127a4565b61279f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279690613fd0565b60405180910390fd5b505050565b60006127c58473ffffffffffffffffffffffffffffffffffffffff16612ced565b6127d25760019050612900565b600061289963150b7a0260e01b6127e7611de9565b8887876040516024016127fd9493929190613ee5565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051806060016040528060328152602001614592603291398773ffffffffffffffffffffffffffffffffffffffff16612d009092919063ffffffff16565b90506000818060200190518101906128b191906132bb565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612a07576000600182039050600060018660000180549050039050600086600001828154811061297657fe5b906000526020600020015490508087600001848154811061299357fe5b90600052602060002001819055506001830187600101600083815260200190815260200160002081905550866000018054806129cb57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050612a0d565b60009150505b92915050565b6000612a1f8383612d18565b612a78578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612a7d565b600090505b92915050565b6000808460010160008581526020019081526020016000205490506000811415612b2a57846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050612b58565b82856000016001830381548110612b3d57fe5b90600052602060002090600202016001018190555060009150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612bcf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bc690614170565b60405180910390fd5b612bd881611dcc565b15612c18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c0f90614030565b60405180910390fd5b612c2460008383612549565b612c7581600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061256890919063ffffffff16565b50612c8c818360026125829092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b6060612d0f8484600085612d3b565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b606082471015612d80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d77906140d0565b60405180910390fd5b612d8985612ced565b612dc8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dbf906142b0565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612df19190613e8f565b60006040518083038185875af1925050503d8060008114612e2e576040519150601f19603f3d011682016040523d82523d6000602084013e612e33565b606091505b5091509150612e43828286612e4f565b92505050949350505050565b60608315612e5f57829050612eaf565b600083511115612e725782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ea69190613f6e565b60405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282612eec5760008555612f33565b82601f10612f0557805160ff1916838001178555612f33565b82800160010185558215612f33579182015b82811115612f32578251825591602001919060010190612f17565b5b509050612f409190612f44565b5090565b5b80821115612f5d576000816000905550600101612f45565b5090565b6000612f74612f6f8461435c565b61432b565b905082815260208101848484011115612f8c57600080fd5b612f978482856144c9565b509392505050565b6000612fb2612fad8461438c565b61432b565b905082815260208101848484011115612fca57600080fd5b612fd58482856144c9565b509392505050565b600081359050612fec8161451e565b92915050565b60008135905061300181614535565b92915050565b6000813590506130168161454c565b92915050565b60008135905061302b81614563565b92915050565b60008151905061304081614563565b92915050565b600082601f83011261305757600080fd5b8135613067848260208601612f61565b91505092915050565b600082601f83011261308157600080fd5b8135613091848260208601612f9f565b91505092915050565b6000813590506130a98161457a565b92915050565b6000602082840312156130c157600080fd5b60006130cf84828501612fdd565b91505092915050565b600080604083850312156130eb57600080fd5b60006130f985828601612ff2565b925050602061310a8582860161309a565b9150509250929050565b6000806040838503121561312757600080fd5b600061313585828601612fdd565b925050602061314685828601612fdd565b9150509250929050565b60008060006060848603121561316557600080fd5b600061317386828701612fdd565b935050602061318486828701612fdd565b92505060406131958682870161309a565b9150509250925092565b600080600080608085870312156131b557600080fd5b60006131c387828801612fdd565b94505060206131d487828801612fdd565b93505060406131e58782880161309a565b925050606085013567ffffffffffffffff81111561320257600080fd5b61320e87828801613046565b91505092959194509250565b6000806040838503121561322d57600080fd5b600061323b85828601612fdd565b925050602061324c85828601613007565b9150509250929050565b6000806040838503121561326957600080fd5b600061327785828601612fdd565b92505060206132888582860161309a565b9150509250929050565b6000602082840312156132a457600080fd5b60006132b28482850161301c565b91505092915050565b6000602082840312156132cd57600080fd5b60006132db84828501613031565b91505092915050565b6000602082840312156132f657600080fd5b600082013567ffffffffffffffff81111561331057600080fd5b61331c84828501613070565b91505092915050565b60006020828403121561333757600080fd5b60006133458482850161309a565b91505092915050565b600061335a8383613e71565b60208301905092915050565b61336f81614455565b82525050565b61337e81614443565b82525050565b600061338f826143cc565b61339981856143fa565b93506133a4836143bc565b8060005b838110156133d55781516133bc888261334e565b97506133c7836143ed565b9250506001810190506133a8565b5085935050505092915050565b6133eb81614467565b82525050565b60006133fc826143d7565b613406818561440b565b93506134168185602086016144d8565b61341f8161450d565b840191505092915050565b6000613435826143d7565b61343f818561441c565b935061344f8185602086016144d8565b80840191505092915050565b6000613466826143e2565b6134708185614427565b93506134808185602086016144d8565b6134898161450d565b840191505092915050565b600061349f826143e2565b6134a98185614438565b93506134b98185602086016144d8565b80840191505092915050565b60006134d2602283614427565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613538601f83614427565b91507f53616c65206d7573742062652061637469766520746f206d696e74204e4654006000830152602082019050919050565b6000613578603283614427565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b60006135de602883614427565b91507f507572636861736520776f756c6420657863656564206d617820737570706c7960008301527f206f66204e4654730000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613644602683614427565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006136aa601c83614427565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b60006136ea601b83614427565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b600061372a602483614427565b91507f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613790601983614427565b91507f4552433732313a20617070726f766520746f2063616c6c6572000000000000006000830152602082019050919050565b60006137d0601e83614427565b91507f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006000830152602082019050919050565b6000613810602683614427565b91507f416464726573733a20696e73756666696369656e742062616c616e636520666f60008301527f722063616c6c00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613876602c83614427565b91507f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b60006138dc603883614427565b91507f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008301527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006020830152604082019050919050565b6000613942602a83614427565b91507f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008301527f726f2061646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b60006139a8602283614427565b91507f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a0e602083614427565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b6000613a4e602183614427565b91507f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60008301527f77000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613ab4602c83614427565b91507f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613b1a602083614427565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000613b5a602983614427565b91507f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008301527f73206e6f74206f776e00000000000000000000000000000000000000000000006020830152604082019050919050565b6000613bc0602f83614427565b91507f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008301527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006020830152604082019050919050565b6000613c26601783614427565b91507f4e6f7420656e6f7567682072657365727665206c6566740000000000000000006000830152602082019050919050565b6000613c66602183614427565b91507f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613ccc601b83614427565b91507f4578636565646564206d617820746f6b656e20707572636861736500000000006000830152602082019050919050565b6000613d0c603183614427565b91507f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008301527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020830152604082019050919050565b6000613d72601d83614427565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b6000613db2604683614427565b91507f576974686472617720616d6f756e74206d75737420626520706f73697469766560008301527f20616e64206e6f742065786365656420746f74616c20636f6e7472616374206260208301527f616c616e636500000000000000000000000000000000000000000000000000006040830152606082019050919050565b6000613e3e601d83614427565b91507f4554482076616c75652073656e74206973206e6f7420636f72726563740000006000830152602082019050919050565b613e7a816144bf565b82525050565b613e89816144bf565b82525050565b6000613e9b828461342a565b915081905092915050565b6000613eb28285613494565b9150613ebe8284613494565b91508190509392505050565b6000602082019050613edf6000830184613375565b92915050565b6000608082019050613efa6000830187613366565b613f076020830186613375565b613f146040830185613e80565b8181036060830152613f2681846133f1565b905095945050505050565b60006020820190508181036000830152613f4b8184613384565b905092915050565b6000602082019050613f6860008301846133e2565b92915050565b60006020820190508181036000830152613f88818461345b565b905092915050565b60006020820190508181036000830152613fa9816134c5565b9050919050565b60006020820190508181036000830152613fc98161352b565b9050919050565b60006020820190508181036000830152613fe98161356b565b9050919050565b60006020820190508181036000830152614009816135d1565b9050919050565b6000602082019050818103600083015261402981613637565b9050919050565b600060208201905081810360008301526140498161369d565b9050919050565b60006020820190508181036000830152614069816136dd565b9050919050565b600060208201905081810360008301526140898161371d565b9050919050565b600060208201905081810360008301526140a981613783565b9050919050565b600060208201905081810360008301526140c9816137c3565b9050919050565b600060208201905081810360008301526140e981613803565b9050919050565b6000602082019050818103600083015261410981613869565b9050919050565b60006020820190508181036000830152614129816138cf565b9050919050565b6000602082019050818103600083015261414981613935565b9050919050565b600060208201905081810360008301526141698161399b565b9050919050565b6000602082019050818103600083015261418981613a01565b9050919050565b600060208201905081810360008301526141a981613a41565b9050919050565b600060208201905081810360008301526141c981613aa7565b9050919050565b600060208201905081810360008301526141e981613b0d565b9050919050565b6000602082019050818103600083015261420981613b4d565b9050919050565b6000602082019050818103600083015261422981613bb3565b9050919050565b6000602082019050818103600083015261424981613c19565b9050919050565b6000602082019050818103600083015261426981613c59565b9050919050565b6000602082019050818103600083015261428981613cbf565b9050919050565b600060208201905081810360008301526142a981613cff565b9050919050565b600060208201905081810360008301526142c981613d65565b9050919050565b600060208201905081810360008301526142e981613da5565b9050919050565b6000602082019050818103600083015261430981613e31565b9050919050565b60006020820190506143256000830184613e80565b92915050565b6000604051905081810181811067ffffffffffffffff821117156143525761435161450b565b5b8060405250919050565b600067ffffffffffffffff8211156143775761437661450b565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff8211156143a7576143a661450b565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600061444e8261449f565b9050919050565b60006144608261449f565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156144f65780820151818401526020810190506144db565b83811115614505576000848401525b50505050565bfe5b6000601f19601f8301169050919050565b61452781614443565b811461453257600080fd5b50565b61453e81614455565b811461454957600080fd5b50565b61455581614467565b811461456057600080fd5b50565b61456c81614473565b811461457757600080fd5b50565b614583816144bf565b811461458e57600080fd5b5056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220bb2d605c38d50590dd1d8e829a8360830b3a5e7f30fa843bc1343a1201b5787c64736f6c63430007060033

Deployed Bytecode

0x6080604052600436106102045760003560e01c80636c0360eb1161011857806395d89b41116100a0578063c87b56dd1161006f578063c87b56dd14610732578063cf1073001461076f578063e985e9c51461079a578063eb8d2444146107d7578063f2fde38b1461080257610204565b806395d89b411461068a578063a22cb465146106b5578063a38bffda146106de578063b88d4fde1461070957610204565b806381530b68116100e757806381530b68146105b457806384522aec146105dd5780638462151c146106065780638da5cb5b14610643578063926427441461066e57610204565b80636c0360eb1461050c57806370a082311461053757806370a8de8614610574578063715018a61461059d57610204565b80631bc347271161019b5780633ccfd60b1161016a5780633ccfd60b1461042957806342842e0e146104405780634f6ccce71461046957806355f804b3146104a65780636352211e146104cf57610204565b80631bc347271461038157806323b872dd146103ac5780632f745c59146103d557806334918dfd1461041257610204565b8063095ea7b3116101d7578063095ea7b3146102d9578063109695231461030257806318160ddd1461032b578063189f92bd1461035657610204565b806301ffc9a71461020957806306fdde0314610246578063081812fc14610271578063093d8c64146102ae575b600080fd5b34801561021557600080fd5b50610230600480360381019061022b9190613292565b61082b565b60405161023d9190613f53565b60405180910390f35b34801561025257600080fd5b5061025b610892565b6040516102689190613f6e565b60405180910390f35b34801561027d57600080fd5b5061029860048036038101906102939190613325565b610934565b6040516102a59190613eca565b60405180910390f35b3480156102ba57600080fd5b506102c36109b9565b6040516102d09190614310565b60405180910390f35b3480156102e557600080fd5b5061030060048036038101906102fb9190613256565b6109bf565b005b34801561030e57600080fd5b50610329600480360381019061032491906132e4565b610ad7565b005b34801561033757600080fd5b50610340610b6d565b60405161034d9190614310565b60405180910390f35b34801561036257600080fd5b5061036b610b7e565b6040516103789190614310565b60405180910390f35b34801561038d57600080fd5b50610396610b83565b6040516103a39190613f6e565b60405180910390f35b3480156103b857600080fd5b506103d360048036038101906103ce9190613150565b610c21565b005b3480156103e157600080fd5b506103fc60048036038101906103f79190613256565b610c81565b6040516104099190614310565b60405180910390f35b34801561041e57600080fd5b50610427610cdc565b005b34801561043557600080fd5b5061043e610d84565b005b34801561044c57600080fd5b5061046760048036038101906104629190613150565b610e4f565b005b34801561047557600080fd5b50610490600480360381019061048b9190613325565b610e6f565b60405161049d9190614310565b60405180910390f35b3480156104b257600080fd5b506104cd60048036038101906104c891906132e4565b610e92565b005b3480156104db57600080fd5b506104f660048036038101906104f19190613325565b610f1a565b6040516105039190613eca565b60405180910390f35b34801561051857600080fd5b50610521610f51565b60405161052e9190613f6e565b60405180910390f35b34801561054357600080fd5b5061055e600480360381019061055991906130af565b610ff3565b60405161056b9190614310565b60405180910390f35b34801561058057600080fd5b5061059b60048036038101906105969190613256565b6110b2565b005b3480156105a957600080fd5b506105b26111d0565b005b3480156105c057600080fd5b506105db60048036038101906105d69190613325565b61130d565b005b3480156105e957600080fd5b5061060460048036038101906105ff91906130d8565b611393565b005b34801561061257600080fd5b5061062d600480360381019061062891906130af565b6114a9565b60405161063a9190613f31565b60405180910390f35b34801561064f57600080fd5b506106586115a2565b6040516106659190613eca565b60405180910390f35b61068860048036038101906106839190613325565b6115cc565b005b34801561069657600080fd5b5061069f611765565b6040516106ac9190613f6e565b60405180910390f35b3480156106c157600080fd5b506106dc60048036038101906106d7919061321a565b611807565b005b3480156106ea57600080fd5b506106f3611988565b6040516107009190614310565b60405180910390f35b34801561071557600080fd5b50610730600480360381019061072b919061319f565b61198e565b005b34801561073e57600080fd5b5061075960048036038101906107549190613325565b6119f0565b6040516107669190613f6e565b60405180910390f35b34801561077b57600080fd5b50610784611b73565b6040516107919190614310565b60405180910390f35b3480156107a657600080fd5b506107c160048036038101906107bc9190613114565b611b79565b6040516107ce9190613f53565b60405180910390f35b3480156107e357600080fd5b506107ec611c0d565b6040516107f99190613f53565b60405180910390f35b34801561080e57600080fd5b50610829600480360381019061082491906130af565b611c20565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561092a5780601f106108ff5761010080835404028352916020019161092a565b820191906000526020600020905b81548152906001019060200180831161090d57829003601f168201915b5050505050905090565b600061093f82611dcc565b61097e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610975906141b0565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b61270f81565b60006109ca82610f1a565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3290614250565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a5a611de9565b73ffffffffffffffffffffffffffffffffffffffff161480610a895750610a8881610a83611de9565b611b79565b5b610ac8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610abf90614110565b60405180910390fd5b610ad28383611df1565b505050565b610adf611de9565b73ffffffffffffffffffffffffffffffffffffffff16610afd6115a2565b73ffffffffffffffffffffffffffffffffffffffff1614610b53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4a906141d0565b60405180910390fd5b80600b9080519060200190610b69929190612eb6565b5050565b6000610b796002611eaa565b905090565b601481565b600b8054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610c195780601f10610bee57610100808354040283529160200191610c19565b820191906000526020600020905b815481529060010190602001808311610bfc57829003601f168201915b505050505081565b610c32610c2c611de9565b82611ebf565b610c71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6890614290565b60405180910390fd5b610c7c838383611f9d565b505050565b6000610cd482600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206121b490919063ffffffff16565b905092915050565b610ce4611de9565b73ffffffffffffffffffffffffffffffffffffffff16610d026115a2565b73ffffffffffffffffffffffffffffffffffffffff1614610d58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4f906141d0565b60405180910390fd5b600a60149054906101000a900460ff1615600a60146101000a81548160ff021916908315150217905550565b610d8c611de9565b73ffffffffffffffffffffffffffffffffffffffff16610daa6115a2565b73ffffffffffffffffffffffffffffffffffffffff1614610e00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df7906141d0565b60405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610e4b573d6000803e3d6000fd5b5050565b610e6a8383836040518060200160405280600081525061198e565b505050565b600080610e868360026121ce90919063ffffffff16565b50905080915050919050565b610e9a611de9565b73ffffffffffffffffffffffffffffffffffffffff16610eb86115a2565b73ffffffffffffffffffffffffffffffffffffffff1614610f0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f05906141d0565b60405180910390fd5b610f17816121fa565b50565b6000610f4a826040518060600160405280602981526020016145c46029913960026122149092919063ffffffff16565b9050919050565b606060098054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610fe95780601f10610fbe57610100808354040283529160200191610fe9565b820191906000526020600020905b815481529060010190602001808311610fcc57829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611064576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105b90614130565b60405180910390fd5b6110ab600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612233565b9050919050565b6110ba611de9565b73ffffffffffffffffffffffffffffffffffffffff166110d86115a2565b73ffffffffffffffffffffffffffffffffffffffff161461112e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611125906141d0565b60405180910390fd5b6000611138610b6d565b905060008211801561114c5750600d548211155b61118b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118290614230565b60405180910390fd5b60005b828110156111af576111a284828401612248565b808060010191505061118e565b506111c582600d5461226690919063ffffffff16565b600d81905550505050565b6111d8611de9565b73ffffffffffffffffffffffffffffffffffffffff166111f66115a2565b73ffffffffffffffffffffffffffffffffffffffff161461124c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611243906141d0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b611315611de9565b73ffffffffffffffffffffffffffffffffffffffff166113336115a2565b73ffffffffffffffffffffffffffffffffffffffff1614611389576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611380906141d0565b60405180910390fd5b80600c8190555050565b61139b611de9565b73ffffffffffffffffffffffffffffffffffffffff166113b96115a2565b73ffffffffffffffffffffffffffffffffffffffff161461140f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611406906141d0565b60405180910390fd5b60008111801561141f5750478111155b61145e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611455906142d0565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156114a4573d6000803e3d6000fd5b505050565b606060006114b683610ff3565b9050600081141561151157600067ffffffffffffffff811180156114d957600080fd5b506040519080825280602002602001820160405280156115085781602001602082028036833780820191505090505b5091505061159d565b60008167ffffffffffffffff8111801561152a57600080fd5b506040519080825280602002602001820160405280156115595781602001602082028036833780820191505090505b50905060005b82811015611596576115718582610c81565b82828151811061157d57fe5b602002602001018181525050808060010191505061155f565b8193505050505b919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600a60149054906101000a900460ff1661161b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161290613fb0565b60405180910390fd5b60008111801561162c575060148111155b61166b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166290614270565b60405180910390fd5b61270f6116888261167a610b6d565b6122b690919063ffffffff16565b11156116c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c090613ff0565b60405180910390fd5b6116de81600c5461230b90919063ffffffff16565b341015611720576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611717906142f0565b60405180910390fd5b60005b81811015611761576000611735610b6d565b905061270f611742610b6d565b1015611753576117523382612248565b5b508080600101915050611723565b5050565b606060078054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156117fd5780601f106117d2576101008083540402835291602001916117fd565b820191906000526020600020905b8154815290600101906020018083116117e057829003601f168201915b5050505050905090565b61180f611de9565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561187d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187490614090565b60405180910390fd5b806005600061188a611de9565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611937611de9565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161197c9190613f53565b60405180910390a35050565b600c5481565b61199f611999611de9565b83611ebf565b6119de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d590614290565b60405180910390fd5b6119ea8484848461237b565b50505050565b60606119fb82611dcc565b611a3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3190614210565b60405180910390fd5b6000600860008481526020019081526020016000208054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611ae35780601f10611ab857610100808354040283529160200191611ae3565b820191906000526020600020905b815481529060010190602001808311611ac657829003601f168201915b505050505090506000611af4610f51565b9050600081511415611b0a578192505050611b6e565b600082511115611b3f578082604051602001611b27929190613ea6565b60405160208183030381529060405292505050611b6e565b80611b49856123d7565b604051602001611b5a929190613ea6565b604051602081830303815290604052925050505b919050565b600d5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600a60149054906101000a900460ff1681565b611c28611de9565b73ffffffffffffffffffffffffffffffffffffffff16611c466115a2565b73ffffffffffffffffffffffffffffffffffffffff1614611c9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c93906141d0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611d0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d0390614010565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000611de282600261251e90919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611e6483610f1a565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611eb882600001612538565b9050919050565b6000611eca82611dcc565b611f09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f00906140f0565b60405180910390fd5b6000611f1483610f1a565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611f8357508373ffffffffffffffffffffffffffffffffffffffff16611f6b84610934565b73ffffffffffffffffffffffffffffffffffffffff16145b80611f945750611f938185611b79565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611fbd82610f1a565b73ffffffffffffffffffffffffffffffffffffffff1614612013576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161200a906141f0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612083576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207a90614070565b60405180910390fd5b61208e838383612549565b612099600082611df1565b6120ea81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061254e90919063ffffffff16565b5061213c81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061256890919063ffffffff16565b50612153818360026125829092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006121c383600001836125b7565b60001c905092915050565b6000806000806121e18660000186612624565b915091508160001c8160001c9350935050509250929050565b8060099080519060200190612210929190612eb6565b5050565b6000612227846000018460001b846126a7565b60001c90509392505050565b600061224182600001612738565b9050919050565b612262828260405180602001604052806000815250612749565b5050565b6000828211156122ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122a2906140b0565b60405180910390fd5b818303905092915050565b600080828401905083811015612301576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122f890614050565b60405180910390fd5b8091505092915050565b60008083141561231e5760009050612375565b600082840290508284828161232f57fe5b0414612370576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236790614190565b60405180910390fd5b809150505b92915050565b612386848484611f9d565b612392848484846127a4565b6123d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123c890613fd0565b60405180910390fd5b50505050565b6060600082141561241f576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612519565b600082905060005b60008214612449578080600101915050600a828161244157fe5b049150612427565b60008167ffffffffffffffff8111801561246257600080fd5b506040519080825280601f01601f1916602001820160405280156124955781602001600182028036833780820191505090505b50905060006001830390508593505b6000841461251157600a84816124b657fe5b0660300160f81b828280600190039350815181106124d057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a848161250957fe5b0493506124a4565b819450505050505b919050565b6000612530836000018360001b612908565b905092915050565b600081600001805490509050919050565b505050565b6000612560836000018360001b61292b565b905092915050565b600061257a836000018360001b612a13565b905092915050565b60006125ae846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612a83565b90509392505050565b600081836000018054905011612602576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f990613f90565b60405180910390fd5b82600001828154811061261157fe5b9060005260206000200154905092915050565b60008082846000018054905011612670576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161266790614150565b60405180910390fd5b600084600001848154811061268157fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008084600101600085815260200190815260200160002054905060008114158390612709576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127009190613f6e565b60405180910390fd5b5084600001600182038154811061271c57fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b6127538383612b5f565b61276060008484846127a4565b61279f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279690613fd0565b60405180910390fd5b505050565b60006127c58473ffffffffffffffffffffffffffffffffffffffff16612ced565b6127d25760019050612900565b600061289963150b7a0260e01b6127e7611de9565b8887876040516024016127fd9493929190613ee5565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051806060016040528060328152602001614592603291398773ffffffffffffffffffffffffffffffffffffffff16612d009092919063ffffffff16565b90506000818060200190518101906128b191906132bb565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612a07576000600182039050600060018660000180549050039050600086600001828154811061297657fe5b906000526020600020015490508087600001848154811061299357fe5b90600052602060002001819055506001830187600101600083815260200190815260200160002081905550866000018054806129cb57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050612a0d565b60009150505b92915050565b6000612a1f8383612d18565b612a78578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612a7d565b600090505b92915050565b6000808460010160008581526020019081526020016000205490506000811415612b2a57846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050612b58565b82856000016001830381548110612b3d57fe5b90600052602060002090600202016001018190555060009150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612bcf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bc690614170565b60405180910390fd5b612bd881611dcc565b15612c18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c0f90614030565b60405180910390fd5b612c2460008383612549565b612c7581600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061256890919063ffffffff16565b50612c8c818360026125829092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b6060612d0f8484600085612d3b565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b606082471015612d80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d77906140d0565b60405180910390fd5b612d8985612ced565b612dc8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dbf906142b0565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612df19190613e8f565b60006040518083038185875af1925050503d8060008114612e2e576040519150601f19603f3d011682016040523d82523d6000602084013e612e33565b606091505b5091509150612e43828286612e4f565b92505050949350505050565b60608315612e5f57829050612eaf565b600083511115612e725782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ea69190613f6e565b60405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282612eec5760008555612f33565b82601f10612f0557805160ff1916838001178555612f33565b82800160010185558215612f33579182015b82811115612f32578251825591602001919060010190612f17565b5b509050612f409190612f44565b5090565b5b80821115612f5d576000816000905550600101612f45565b5090565b6000612f74612f6f8461435c565b61432b565b905082815260208101848484011115612f8c57600080fd5b612f978482856144c9565b509392505050565b6000612fb2612fad8461438c565b61432b565b905082815260208101848484011115612fca57600080fd5b612fd58482856144c9565b509392505050565b600081359050612fec8161451e565b92915050565b60008135905061300181614535565b92915050565b6000813590506130168161454c565b92915050565b60008135905061302b81614563565b92915050565b60008151905061304081614563565b92915050565b600082601f83011261305757600080fd5b8135613067848260208601612f61565b91505092915050565b600082601f83011261308157600080fd5b8135613091848260208601612f9f565b91505092915050565b6000813590506130a98161457a565b92915050565b6000602082840312156130c157600080fd5b60006130cf84828501612fdd565b91505092915050565b600080604083850312156130eb57600080fd5b60006130f985828601612ff2565b925050602061310a8582860161309a565b9150509250929050565b6000806040838503121561312757600080fd5b600061313585828601612fdd565b925050602061314685828601612fdd565b9150509250929050565b60008060006060848603121561316557600080fd5b600061317386828701612fdd565b935050602061318486828701612fdd565b92505060406131958682870161309a565b9150509250925092565b600080600080608085870312156131b557600080fd5b60006131c387828801612fdd565b94505060206131d487828801612fdd565b93505060406131e58782880161309a565b925050606085013567ffffffffffffffff81111561320257600080fd5b61320e87828801613046565b91505092959194509250565b6000806040838503121561322d57600080fd5b600061323b85828601612fdd565b925050602061324c85828601613007565b9150509250929050565b6000806040838503121561326957600080fd5b600061327785828601612fdd565b92505060206132888582860161309a565b9150509250929050565b6000602082840312156132a457600080fd5b60006132b28482850161301c565b91505092915050565b6000602082840312156132cd57600080fd5b60006132db84828501613031565b91505092915050565b6000602082840312156132f657600080fd5b600082013567ffffffffffffffff81111561331057600080fd5b61331c84828501613070565b91505092915050565b60006020828403121561333757600080fd5b60006133458482850161309a565b91505092915050565b600061335a8383613e71565b60208301905092915050565b61336f81614455565b82525050565b61337e81614443565b82525050565b600061338f826143cc565b61339981856143fa565b93506133a4836143bc565b8060005b838110156133d55781516133bc888261334e565b97506133c7836143ed565b9250506001810190506133a8565b5085935050505092915050565b6133eb81614467565b82525050565b60006133fc826143d7565b613406818561440b565b93506134168185602086016144d8565b61341f8161450d565b840191505092915050565b6000613435826143d7565b61343f818561441c565b935061344f8185602086016144d8565b80840191505092915050565b6000613466826143e2565b6134708185614427565b93506134808185602086016144d8565b6134898161450d565b840191505092915050565b600061349f826143e2565b6134a98185614438565b93506134b98185602086016144d8565b80840191505092915050565b60006134d2602283614427565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613538601f83614427565b91507f53616c65206d7573742062652061637469766520746f206d696e74204e4654006000830152602082019050919050565b6000613578603283614427565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b60006135de602883614427565b91507f507572636861736520776f756c6420657863656564206d617820737570706c7960008301527f206f66204e4654730000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613644602683614427565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006136aa601c83614427565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b60006136ea601b83614427565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b600061372a602483614427565b91507f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613790601983614427565b91507f4552433732313a20617070726f766520746f2063616c6c6572000000000000006000830152602082019050919050565b60006137d0601e83614427565b91507f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006000830152602082019050919050565b6000613810602683614427565b91507f416464726573733a20696e73756666696369656e742062616c616e636520666f60008301527f722063616c6c00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613876602c83614427565b91507f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b60006138dc603883614427565b91507f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008301527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006020830152604082019050919050565b6000613942602a83614427565b91507f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008301527f726f2061646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b60006139a8602283614427565b91507f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a0e602083614427565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b6000613a4e602183614427565b91507f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60008301527f77000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613ab4602c83614427565b91507f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613b1a602083614427565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000613b5a602983614427565b91507f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008301527f73206e6f74206f776e00000000000000000000000000000000000000000000006020830152604082019050919050565b6000613bc0602f83614427565b91507f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008301527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006020830152604082019050919050565b6000613c26601783614427565b91507f4e6f7420656e6f7567682072657365727665206c6566740000000000000000006000830152602082019050919050565b6000613c66602183614427565b91507f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613ccc601b83614427565b91507f4578636565646564206d617820746f6b656e20707572636861736500000000006000830152602082019050919050565b6000613d0c603183614427565b91507f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008301527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020830152604082019050919050565b6000613d72601d83614427565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b6000613db2604683614427565b91507f576974686472617720616d6f756e74206d75737420626520706f73697469766560008301527f20616e64206e6f742065786365656420746f74616c20636f6e7472616374206260208301527f616c616e636500000000000000000000000000000000000000000000000000006040830152606082019050919050565b6000613e3e601d83614427565b91507f4554482076616c75652073656e74206973206e6f7420636f72726563740000006000830152602082019050919050565b613e7a816144bf565b82525050565b613e89816144bf565b82525050565b6000613e9b828461342a565b915081905092915050565b6000613eb28285613494565b9150613ebe8284613494565b91508190509392505050565b6000602082019050613edf6000830184613375565b92915050565b6000608082019050613efa6000830187613366565b613f076020830186613375565b613f146040830185613e80565b8181036060830152613f2681846133f1565b905095945050505050565b60006020820190508181036000830152613f4b8184613384565b905092915050565b6000602082019050613f6860008301846133e2565b92915050565b60006020820190508181036000830152613f88818461345b565b905092915050565b60006020820190508181036000830152613fa9816134c5565b9050919050565b60006020820190508181036000830152613fc98161352b565b9050919050565b60006020820190508181036000830152613fe98161356b565b9050919050565b60006020820190508181036000830152614009816135d1565b9050919050565b6000602082019050818103600083015261402981613637565b9050919050565b600060208201905081810360008301526140498161369d565b9050919050565b60006020820190508181036000830152614069816136dd565b9050919050565b600060208201905081810360008301526140898161371d565b9050919050565b600060208201905081810360008301526140a981613783565b9050919050565b600060208201905081810360008301526140c9816137c3565b9050919050565b600060208201905081810360008301526140e981613803565b9050919050565b6000602082019050818103600083015261410981613869565b9050919050565b60006020820190508181036000830152614129816138cf565b9050919050565b6000602082019050818103600083015261414981613935565b9050919050565b600060208201905081810360008301526141698161399b565b9050919050565b6000602082019050818103600083015261418981613a01565b9050919050565b600060208201905081810360008301526141a981613a41565b9050919050565b600060208201905081810360008301526141c981613aa7565b9050919050565b600060208201905081810360008301526141e981613b0d565b9050919050565b6000602082019050818103600083015261420981613b4d565b9050919050565b6000602082019050818103600083015261422981613bb3565b9050919050565b6000602082019050818103600083015261424981613c19565b9050919050565b6000602082019050818103600083015261426981613c59565b9050919050565b6000602082019050818103600083015261428981613cbf565b9050919050565b600060208201905081810360008301526142a981613cff565b9050919050565b600060208201905081810360008301526142c981613d65565b9050919050565b600060208201905081810360008301526142e981613da5565b9050919050565b6000602082019050818103600083015261430981613e31565b9050919050565b60006020820190506143256000830184613e80565b92915050565b6000604051905081810181811067ffffffffffffffff821117156143525761435161450b565b5b8060405250919050565b600067ffffffffffffffff8211156143775761437661450b565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff8211156143a7576143a661450b565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600061444e8261449f565b9050919050565b60006144608261449f565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156144f65780820151818401526020810190506144db565b83811115614505576000848401525b50505050565bfe5b6000601f19601f8301169050919050565b61452781614443565b811461453257600080fd5b50565b61453e81614455565b811461454957600080fd5b50565b61455581614467565b811461456057600080fd5b50565b61456c81614473565b811461457757600080fd5b50565b614583816144bf565b811461458e57600080fd5b5056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220bb2d605c38d50590dd1d8e829a8360830b3a5e7f30fa843bc1343a1201b5787c64736f6c63430007060033

Deployed Bytecode Sourcemap

70580:4609:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10523:200;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54010:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57018:308;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71048:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56517:435;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72718:118;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55945:211;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70950:43;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70739:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58077:376;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55657:212;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73314:83;;;;;;;;;;;;;:::i;:::-;;71251:124;;;;;;;;;;;;;:::i;:::-;;58524:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;56233:222;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73134:93;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53654:289;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55476:97;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53284:308;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72134:461;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69826:148;;;;;;;;;;;;;:::i;:::-;;71894:88;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71475:365;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73498:490;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69175:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74084:1102;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;54179:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57398:327;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70827:43;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58780:365;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;54354:879;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70888:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57796:214;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70655:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70129:281;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;10523:200;10653:4;10682:20;:33;10703:11;10682:33;;;;;;;;;;;;;;;;;;;;;;;;;;;10675:40;;10523:200;;;:::o;54010:100::-;54064:13;54097:5;54090:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54010:100;:::o;57018:308::-;57139:7;57186:16;57194:7;57186;:16::i;:::-;57164:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;57294:15;:24;57310:7;57294:24;;;;;;;;;;;;;;;;;;;;;57287:31;;57018:308;;;:::o;71048:39::-;71083:4;71048:39;:::o;56517:435::-;56598:13;56614:23;56629:7;56614:14;:23::i;:::-;56598:39;;56662:5;56656:11;;:2;:11;;;;56648:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;56756:5;56740:21;;:12;:10;:12::i;:::-;:21;;;:86;;;;56782:44;56806:5;56813:12;:10;:12::i;:::-;56782:23;:44::i;:::-;56740:86;56718:192;;;;;;;;;;;;:::i;:::-;;;;;;;;;56923:21;56932:2;56936:7;56923:8;:21::i;:::-;56517:435;;;:::o;72718:118::-;69406:12;:10;:12::i;:::-;69395:23;;:7;:5;:7::i;:::-;:23;;;69387:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;72816:14:::1;72799;:31;;;;;;;;;;;;:::i;:::-;;72718:118:::0;:::o;55945:211::-;56006:7;56127:21;:12;:19;:21::i;:::-;56120:28;;55945:211;:::o;70950:43::-;70991:2;70950:43;:::o;70739:33::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;58077:376::-;58286:41;58305:12;:10;:12::i;:::-;58319:7;58286:18;:41::i;:::-;58264:140;;;;;;;;;;;;:::i;:::-;;;;;;;;;58417:28;58427:4;58433:2;58437:7;58417:9;:28::i;:::-;58077:376;;;:::o;55657:212::-;55799:7;55831:30;55855:5;55831:13;:20;55845:5;55831:20;;;;;;;;;;;;;;;:23;;:30;;;;:::i;:::-;55824:37;;55657:212;;;;:::o;73314:83::-;69406:12;:10;:12::i;:::-;69395:23;;:7;:5;:7::i;:::-;:23;;;69387:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;73379:12:::1;;;;;;;;;;;73378:13;73363:12;;:28;;;;;;;;;;;;;;;;;;73314:83::o:0;71251:124::-;69406:12;:10;:12::i;:::-;69395:23;;:7;:5;:7::i;:::-;:23;;;69387:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;71295:15:::1;71313:21;71295:39;;71341:10;:19;;:28;71361:7;71341:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;69466:1;71251:124::o:0;58524:185::-;58662:39;58679:4;58685:2;58689:7;58662:39;;;;;;;;;;;;:16;:39::i;:::-;58524:185;;;:::o;56233:222::-;56353:7;56379:15;56400:22;56416:5;56400:12;:15;;:22;;;;:::i;:::-;56378:44;;;56440:7;56433:14;;;56233:222;;;:::o;73134:93::-;69406:12;:10;:12::i;:::-;69395:23;;:7;:5;:7::i;:::-;:23;;;69387:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;73201:20:::1;73213:7;73201:11;:20::i;:::-;73134:93:::0;:::o;53654:289::-;53771:7;53816:119;53851:7;53816:119;;;;;;;;;;;;;;;;;:12;:16;;:119;;;;;:::i;:::-;53796:139;;53654:289;;;:::o;55476:97::-;55524:13;55557:8;55550:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55476:97;:::o;53284:308::-;53401:7;53465:1;53448:19;;:5;:19;;;;53426:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;53555:29;:13;:20;53569:5;53555:20;;;;;;;;;;;;;;;:27;:29::i;:::-;53548:36;;53284:308;;;:::o;72134:461::-;69406:12;:10;:12::i;:::-;69395:23;;:7;:5;:7::i;:::-;:23;;;69387:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;72216:14:::1;72233:13;:11;:13::i;:::-;72216:30;;72371:1;72354:14;:18;:50;;;;;72394:10;;72376:14;:28;;72354:50;72338:107;;;;;;;;;;;;:::i;:::-;;;;;;;;;72457:9;72452:88;72476:14;72472:1;:18;72452:88;;;72506:26;72516:3;72530:1;72521:6;:10;72506:9;:26::i;:::-;72492:3;;;;;;;72452:88;;;;72559:30;72574:14;72559:10;;:14;;:30;;;;:::i;:::-;72546:10;:43;;;;69466:1;72134:461:::0;;:::o;69826:148::-;69406:12;:10;:12::i;:::-;69395:23;;:7;:5;:7::i;:::-;:23;;;69387:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;69933:1:::1;69896:40;;69917:6;;;;;;;;;;;69896:40;;;;;;;;;;;;69964:1;69947:6;;:19;;;;;;;;;;;;;;;;;;69826:148::o:0;71894:88::-;69406:12;:10;:12::i;:::-;69395:23;;:7;:5;:7::i;:::-;:23;;;69387:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;71968:8:::1;71957;:19;;;;71894:88:::0;:::o;71475:365::-;69406:12;:10;:12::i;:::-;69395:23;;:7;:5;:7::i;:::-;:23;;;69387:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;71674:1:::1;71664:7;:11;:47;;;;;71690:21;71679:7;:32;;71664:47;71648:151;;;;;;;;;;;;:::i;:::-;;;;;;;;;71806:10;:19;;:28;71826:7;71806:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;71475:365:::0;;:::o;73498:490::-;73575:16;73603:18;73624:17;73634:6;73624:9;:17::i;:::-;73603:38;;73666:1;73652:10;:15;73648:335;;;73731:1;73717:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73710:23;;;;;73648:335;73756:23;73796:10;73782:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73756:51;;73816:13;73838:116;73862:10;73854:5;:18;73838:116;;;73910:34;73930:6;73938:5;73910:19;:34::i;:::-;73894:6;73901:5;73894:13;;;;;;;;;;;;;:50;;;;;73874:7;;;;;;;73838:116;;;73969:6;73962:13;;;;;73498:490;;;;:::o;69175:87::-;69221:7;69248:6;;;;;;;;;;;69241:13;;69175:87;:::o;74084:1102::-;74200:12;;;;;;;;;;;74192:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;74388:1;74371:14;:18;:54;;;;;70991:2;74393:14;:32;;74371:54;74355:115;;;;;;;;;;;;:::i;:::-;;;;;;;;;71083:4;74597:33;74615:14;74597:13;:11;:13::i;:::-;:17;;:33;;;;:::i;:::-;:45;;74581:119;;;;;;;;;;;;:::i;:::-;;;;;;;;;74911:28;74924:14;74911:8;;:12;;:28;;;;:::i;:::-;74898:9;:41;;74882:104;;;;;;;;;;;;:::i;:::-;;;;;;;;;75000:9;74995:186;75019:14;75015:1;:18;74995:186;;;75049:17;75069:13;:11;:13::i;:::-;75049:33;;71083:4;75095:13;:11;:13::i;:::-;:24;75091:83;;;75132:32;75142:10;75154:9;75132;:32::i;:::-;75091:83;74995:186;75035:3;;;;;;;74995:186;;;;74084:1102;:::o;54179:104::-;54235:13;54268:7;54261:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54179:104;:::o;57398:327::-;57545:12;:10;:12::i;:::-;57533:24;;:8;:24;;;;57525:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;57645:8;57600:18;:32;57619:12;:10;:12::i;:::-;57600:32;;;;;;;;;;;;;;;:42;57633:8;57600:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;57698:8;57669:48;;57684:12;:10;:12::i;:::-;57669:48;;;57708:8;57669:48;;;;;;:::i;:::-;;;;;;;;57398:327;;:::o;70827:43::-;;;;:::o;58780:365::-;58969:41;58988:12;:10;:12::i;:::-;59002:7;58969:18;:41::i;:::-;58947:140;;;;;;;;;;;;:::i;:::-;;;;;;;;;59098:39;59112:4;59118:2;59122:7;59131:5;59098:13;:39::i;:::-;58780:365;;;;:::o;54354:879::-;54472:13;54525:16;54533:7;54525;:16::i;:::-;54503:113;;;;;;;;;;;;:::i;:::-;;;;;;;;;54629:23;54655:10;:19;54666:7;54655:19;;;;;;;;;;;54629:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54685:18;54706:9;:7;:9::i;:::-;54685:30;;54813:1;54797:4;54791:18;:23;54787:72;;;54838:9;54831:16;;;;;;54787:72;54989:1;54969:9;54963:23;:27;54959:108;;;55038:4;55044:9;55021:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;55007:48;;;;;;54959:108;55199:4;55205:18;:7;:16;:18::i;:::-;55182:42;;;;;;;;;:::i;:::-;;;;;;;;;;;;;55168:57;;;;54354:879;;;;:::o;70888:31::-;;;;:::o;57796:214::-;57938:4;57967:18;:25;57986:5;57967:25;;;;;;;;;;;;;;;:35;57993:8;57967:35;;;;;;;;;;;;;;;;;;;;;;;;;57960:42;;57796:214;;;;:::o;70655:32::-;;;;;;;;;;;;;:::o;70129:281::-;69406:12;:10;:12::i;:::-;69395:23;;:7;:5;:7::i;:::-;:23;;;69387:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;70252:1:::1;70232:22;;:8;:22;;;;70210:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;70365:8;70336:38;;70357:6;;;;;;;;;;;70336:38;;;;;;;;;;;;70394:8;70385:6;;:17;;;;;;;;;;;;;;;;;;70129:281:::0;:::o;60692:127::-;60757:4;60781:30;60803:7;60781:12;:21;;:30;;;;:::i;:::-;60774:37;;60692:127;;;:::o;667:106::-;720:15;755:10;748:17;;667:106;:::o;67106:192::-;67208:2;67181:15;:24;67197:7;67181:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;67264:7;67260:2;67226:46;;67235:23;67250:7;67235:14;:23::i;:::-;67226:46;;;;;;;;;;;;67106:192;;:::o;46340:155::-;46436:7;46468:19;46476:3;:10;;46468:7;:19::i;:::-;46461:26;;46340:155;;;:::o;60986:459::-;61115:4;61159:16;61167:7;61159;:16::i;:::-;61137:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;61258:13;61274:23;61289:7;61274:14;:23::i;:::-;61258:39;;61327:5;61316:16;;:7;:16;;;:64;;;;61373:7;61349:31;;:20;61361:7;61349:11;:20::i;:::-;:31;;;61316:64;:120;;;;61397:39;61421:5;61428:7;61397:23;:39::i;:::-;61316:120;61308:129;;;60986:459;;;;:::o;64297:670::-;64470:4;64443:31;;:23;64458:7;64443:14;:23::i;:::-;:31;;;64421:122;;;;;;;;;;;;:::i;:::-;;;;;;;;;64594:1;64580:16;;:2;:16;;;;64572:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;64650:39;64671:4;64677:2;64681:7;64650:20;:39::i;:::-;64754:29;64771:1;64775:7;64754:8;:29::i;:::-;64796:35;64823:7;64796:13;:19;64810:4;64796:19;;;;;;;;;;;;;;;:26;;:35;;;;:::i;:::-;;64842:30;64864:7;64842:13;:17;64856:2;64842:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;64885:29;64902:7;64911:2;64885:12;:16;;:29;;;;;:::i;:::-;;64951:7;64947:2;64932:27;;64941:4;64932:27;;;;;;;;;;;;64297:670;;;:::o;37782:169::-;37880:7;37920:22;37924:3;:10;;37936:5;37920:3;:22::i;:::-;37912:31;;37905:38;;37782:169;;;;:::o;46843:268::-;46950:7;46959;46985:11;46998:13;47015:22;47019:3;:10;;47031:5;47015:3;:22::i;:::-;46984:53;;;;47064:3;47056:12;;47094:5;47086:14;;47048:55;;;;;;46843:268;;;;;:::o;65628:100::-;65712:8;65701;:19;;;;;;;;;;;;:::i;:::-;;65628:100;:::o;48225:292::-;48366:7;48448:44;48453:3;:10;;48473:3;48465:12;;48479;48448:4;:44::i;:::-;48440:53;;48386:123;;48225:292;;;;;:::o;37314:114::-;37374:7;37401:19;37409:3;:10;;37401:7;:19::i;:::-;37394:26;;37314:114;;;:::o;61788:110::-;61864:26;61874:2;61878:7;61864:26;;;;;;;;;;;;:9;:26::i;:::-;61788:110;;:::o;14753:158::-;14811:7;14844:1;14839;:6;;14831:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;14902:1;14898;:5;14891:12;;14753:158;;;;:::o;14291:179::-;14349:7;14369:9;14385:1;14381;:5;14369:17;;14410:1;14405;:6;;14397:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;14461:1;14454:8;;;14291:179;;;;:::o;15170:220::-;15228:7;15257:1;15252;:6;15248:20;;;15267:1;15260:8;;;;15248:20;15279:9;15295:1;15291;:5;15279:17;;15324:1;15319;15315;:5;;;;;;:10;15307:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;15381:1;15374:8;;;15170:220;;;;;:::o;60027:352::-;60184:28;60194:4;60200:2;60204:7;60184:9;:28::i;:::-;60245:48;60268:4;60274:2;60278:7;60287:5;60245:22;:48::i;:::-;60223:148;;;;;;;;;;;;:::i;:::-;;;;;;;;;60027:352;;;;:::o;48764:748::-;48820:13;49050:1;49041:5;:10;49037:53;;;49068:10;;;;;;;;;;;;;;;;;;;;;49037:53;49100:12;49115:5;49100:20;;49131:14;49156:78;49171:1;49163:4;:9;49156:78;;49189:8;;;;;;;49220:2;49212:10;;;;;;;;;49156:78;;;49244:19;49276:6;49266:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49244:39;;49294:13;49319:1;49310:6;:10;49294:26;;49338:5;49331:12;;49354:119;49369:1;49361:4;:9;49354:119;;49431:2;49424:4;:9;;;;;;49418:2;:16;49405:31;;49387:6;49394:7;;;;;;;49387:15;;;;;;;;;;;:49;;;;;;;;;;;49459:2;49451:10;;;;;;;;;49354:119;;;49497:6;49483:21;;;;;;48764:748;;;;:::o;46069:183::-;46180:4;46209:35;46219:3;:10;;46239:3;46231:12;;46209:9;:35::i;:::-;46202:42;;46069:183;;;;:::o;42685:110::-;42741:7;42768:3;:12;;:19;;;;42761:26;;42685:110;;;:::o;67911:126::-;;;;:::o;36804:160::-;36892:4;36921:35;36929:3;:10;;36949:5;36941:14;;36921:7;:35::i;:::-;36914:42;;36804:160;;;;:::o;36497:131::-;36564:4;36588:32;36593:3;:10;;36613:5;36605:14;;36588:4;:32::i;:::-;36581:39;;36497:131;;;;:::o;45435:219::-;45558:4;45582:64;45587:3;:10;;45607:3;45599:12;;45637:5;45621:23;;45613:32;;45582:4;:64::i;:::-;45575:71;;45435:219;;;;;:::o;32448:273::-;32542:7;32610:5;32589:3;:11;;:18;;;;:26;32567:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;32695:3;:11;;32707:5;32695:18;;;;;;;;;;;;;;;;32688:25;;32448:273;;;;:::o;43160:348::-;43254:7;43263;43332:5;43310:3;:12;;:19;;;;:27;43288:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;43412:22;43437:3;:12;;43450:5;43437:19;;;;;;;;;;;;;;;;;;43412:44;;43475:5;:10;;;43487:5;:12;;;43467:33;;;;;43160:348;;;;;:::o;44758:353::-;44886:7;44906:16;44925:3;:12;;:17;44938:3;44925:17;;;;;;;;;;;;44906:36;;44973:1;44961:8;:13;;44976:12;44953:36;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;45043:3;:12;;45067:1;45056:8;:12;45043:26;;;;;;;;;;;;;;;;;;:33;;;45036:40;;;44758:353;;;;;:::o;31985:109::-;32041:7;32068:3;:11;;:18;;;;32061:25;;31985:109;;;:::o;62125:321::-;62255:18;62261:2;62265:7;62255:5;:18::i;:::-;62306:54;62337:1;62341:2;62345:7;62354:5;62306:22;:54::i;:::-;62284:154;;;;;;;;;;;;:::i;:::-;;;;;;;;;62125:321;;;:::o;66293:694::-;66448:4;66470:15;:2;:13;;;:15::i;:::-;66465:60;;66509:4;66502:11;;;;66465:60;66535:23;66561:313;66632:45;;;66696:12;:10;:12::i;:::-;66727:4;66750:7;66776:5;66591:205;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66561:313;;;;;;;;;;;;;;;;;:2;:15;;;;:313;;;;;:::i;:::-;66535:339;;66885:13;66912:10;66901:32;;;;;;;;;;;;:::i;:::-;66885:48;;50287:10;66962:16;;66952:26;;;:6;:26;;;;66944:35;;;;66293:694;;;;;;;:::o;42433:157::-;42531:4;42581:1;42560:3;:12;;:17;42573:3;42560:17;;;;;;;;;;;;:22;;42553:29;;42433:157;;;;:::o;30095:1557::-;30161:4;30279:18;30300:3;:12;;:19;30313:5;30300:19;;;;;;;;;;;;30279:40;;30350:1;30336:10;:15;30332:1313;;30711:21;30748:1;30735:10;:14;30711:38;;30764:17;30805:1;30784:3;:11;;:18;;;;:22;30764:42;;31051:17;31071:3;:11;;31083:9;31071:22;;;;;;;;;;;;;;;;31051:42;;31217:9;31188:3;:11;;31200:13;31188:26;;;;;;;;;;;;;;;:38;;;;31336:1;31320:13;:17;31294:3;:12;;:23;31307:9;31294:23;;;;;;;;;;;:43;;;;31446:3;:11;;:17;;;;;;;;;;;;;;;;;;;;;;;;31541:3;:12;;:19;31554:5;31541:19;;;;;;;;;;;31534:26;;;31584:4;31577:11;;;;;;;;30332:1313;31628:5;31621:12;;;30095:1557;;;;;:::o;29505:414::-;29568:4;29590:21;29600:3;29605:5;29590:9;:21::i;:::-;29585:327;;29628:3;:11;;29645:5;29628:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29811:3;:11;;:18;;;;29789:3;:12;;:19;29802:5;29789:19;;;;;;;;;;;:40;;;;29851:4;29844:11;;;;29585:327;29895:5;29888:12;;29505:414;;;;;:::o;39875:737::-;39985:4;40101:16;40120:3;:12;;:17;40133:3;40120:17;;;;;;;;;;;;40101:36;;40166:1;40154:8;:13;40150:455;;;40234:3;:12;;40252:36;;;;;;;;40268:3;40252:36;;;;40281:5;40252:36;;;40234:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40447:3;:12;;:19;;;;40427:3;:12;;:17;40440:3;40427:17;;;;;;;;;;;:39;;;;40488:4;40481:11;;;;;40150:455;40561:5;40525:3;:12;;40549:1;40538:8;:12;40525:26;;;;;;;;;;;;;;;;;;:33;;:41;;;;40588:5;40581:12;;;39875:737;;;;;;:::o;62782:404::-;62876:1;62862:16;;:2;:16;;;;62854:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;62935:16;62943:7;62935;:16::i;:::-;62934:17;62926:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;62997:45;63026:1;63030:2;63034:7;62997:20;:45::i;:::-;63055:30;63077:7;63055:13;:17;63069:2;63055:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;63098:29;63115:7;63124:2;63098:12;:16;;:29;;;;;:::i;:::-;;63170:7;63166:2;63145:33;;63162:1;63145:33;;;;;;;;;;;;62782:404;;:::o;19830:444::-;19890:4;20098:12;20222:7;20210:20;20202:28;;20265:1;20258:4;:8;20251:15;;;19830:444;;;:::o;22867:229::-;23004:12;23036:52;23058:6;23066:4;23072:1;23075:12;23036:21;:52::i;:::-;23029:59;;22867:229;;;;;:::o;31738:161::-;31838:4;31890:1;31867:3;:12;;:19;31880:5;31867:19;;;;;;;;;;;;:24;;31860:31;;31738:161;;;;:::o;24083:632::-;24253:12;24325:5;24300:21;:30;;24278:118;;;;;;;;;;;;:::i;:::-;;;;;;;;;24415:18;24426:6;24415:10;:18::i;:::-;24407:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;24541:12;24555:23;24582:6;:11;;24601:5;24622:4;24582:55;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24540:97;;;;24655:52;24673:7;24682:10;24694:12;24655:17;:52::i;:::-;24648:59;;;;24083:632;;;;;;:::o;27006:777::-;27156:12;27185:7;27181:595;;;27216:10;27209:17;;;;27181:595;27350:1;27330:10;:17;:21;27326:439;;;27593:10;27587:17;27654:15;27641:10;27637:2;27633:19;27626:44;27541:148;27736:12;27729:20;;;;;;;;;;;:::i;:::-;;;;;;;;27006:777;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::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:139::-;;789:6;776:20;767:29;;805:33;832:5;805:33;:::i;:::-;757:87;;;;:::o;850:155::-;;942:6;929:20;920:29;;958:41;993:5;958:41;:::i;:::-;910:95;;;;:::o;1011:133::-;;1092:6;1079:20;1070:29;;1108:30;1132:5;1108:30;:::i;:::-;1060:84;;;;:::o;1150:137::-;;1233:6;1220:20;1211:29;;1249:32;1275:5;1249:32;:::i;:::-;1201:86;;;;:::o;1293:141::-;;1380:6;1374:13;1365:22;;1396:32;1422:5;1396:32;:::i;:::-;1355:79;;;;:::o;1453:271::-;;1557:3;1550:4;1542:6;1538:17;1534:27;1524:2;;1575:1;1572;1565:12;1524:2;1615:6;1602:20;1640:78;1714:3;1706:6;1699:4;1691:6;1687:17;1640:78;:::i;:::-;1631:87;;1514:210;;;;;:::o;1744:273::-;;1849:3;1842:4;1834:6;1830:17;1826:27;1816:2;;1867:1;1864;1857:12;1816:2;1907:6;1894:20;1932:79;2007:3;1999:6;1992:4;1984:6;1980:17;1932:79;:::i;:::-;1923:88;;1806:211;;;;;:::o;2023:139::-;;2107:6;2094:20;2085:29;;2123:33;2150:5;2123:33;:::i;:::-;2075:87;;;;:::o;2168:262::-;;2276:2;2264:9;2255:7;2251:23;2247:32;2244:2;;;2292:1;2289;2282:12;2244:2;2335:1;2360:53;2405:7;2396:6;2385:9;2381:22;2360:53;:::i;:::-;2350:63;;2306:117;2234:196;;;;:::o;2436:423::-;;;2569:2;2557:9;2548:7;2544:23;2540:32;2537:2;;;2585:1;2582;2575:12;2537:2;2628:1;2653:61;2706:7;2697:6;2686:9;2682:22;2653:61;:::i;:::-;2643:71;;2599:125;2763:2;2789:53;2834:7;2825:6;2814:9;2810:22;2789:53;:::i;:::-;2779:63;;2734:118;2527:332;;;;;:::o;2865:407::-;;;2990:2;2978:9;2969:7;2965:23;2961:32;2958:2;;;3006:1;3003;2996:12;2958:2;3049:1;3074:53;3119:7;3110:6;3099:9;3095:22;3074:53;:::i;:::-;3064:63;;3020:117;3176:2;3202:53;3247:7;3238:6;3227:9;3223:22;3202:53;:::i;:::-;3192:63;;3147:118;2948:324;;;;;:::o;3278:552::-;;;;3420:2;3408:9;3399:7;3395:23;3391:32;3388:2;;;3436:1;3433;3426:12;3388:2;3479:1;3504:53;3549:7;3540:6;3529:9;3525:22;3504:53;:::i;:::-;3494:63;;3450:117;3606:2;3632:53;3677:7;3668:6;3657:9;3653:22;3632:53;:::i;:::-;3622:63;;3577:118;3734:2;3760:53;3805:7;3796:6;3785:9;3781:22;3760:53;:::i;:::-;3750:63;;3705:118;3378:452;;;;;:::o;3836:809::-;;;;;4004:3;3992:9;3983:7;3979:23;3975:33;3972:2;;;4021:1;4018;4011:12;3972:2;4064:1;4089:53;4134:7;4125:6;4114:9;4110:22;4089:53;:::i;:::-;4079:63;;4035:117;4191:2;4217:53;4262:7;4253:6;4242:9;4238:22;4217:53;:::i;:::-;4207:63;;4162:118;4319:2;4345:53;4390:7;4381:6;4370:9;4366:22;4345:53;:::i;:::-;4335:63;;4290:118;4475:2;4464:9;4460:18;4447:32;4506:18;4498:6;4495:30;4492:2;;;4538:1;4535;4528:12;4492:2;4566:62;4620:7;4611:6;4600:9;4596:22;4566:62;:::i;:::-;4556:72;;4418:220;3962:683;;;;;;;:::o;4651:401::-;;;4773:2;4761:9;4752:7;4748:23;4744:32;4741:2;;;4789:1;4786;4779:12;4741:2;4832:1;4857:53;4902:7;4893:6;4882:9;4878:22;4857:53;:::i;:::-;4847:63;;4803:117;4959:2;4985:50;5027:7;5018:6;5007:9;5003:22;4985:50;:::i;:::-;4975:60;;4930:115;4731:321;;;;;:::o;5058:407::-;;;5183:2;5171:9;5162:7;5158:23;5154:32;5151:2;;;5199:1;5196;5189:12;5151:2;5242:1;5267:53;5312:7;5303:6;5292:9;5288:22;5267:53;:::i;:::-;5257:63;;5213:117;5369:2;5395:53;5440:7;5431:6;5420:9;5416:22;5395:53;:::i;:::-;5385:63;;5340:118;5141:324;;;;;:::o;5471:260::-;;5578:2;5566:9;5557:7;5553:23;5549:32;5546:2;;;5594:1;5591;5584:12;5546:2;5637:1;5662:52;5706:7;5697:6;5686:9;5682:22;5662:52;:::i;:::-;5652:62;;5608:116;5536:195;;;;:::o;5737:282::-;;5855:2;5843:9;5834:7;5830:23;5826:32;5823:2;;;5871:1;5868;5861:12;5823:2;5914:1;5939:63;5994:7;5985:6;5974:9;5970:22;5939:63;:::i;:::-;5929:73;;5885:127;5813:206;;;;:::o;6025:375::-;;6143:2;6131:9;6122:7;6118:23;6114:32;6111:2;;;6159:1;6156;6149:12;6111:2;6230:1;6219:9;6215:17;6202:31;6260:18;6252:6;6249:30;6246:2;;;6292:1;6289;6282:12;6246:2;6320:63;6375:7;6366:6;6355:9;6351:22;6320:63;:::i;:::-;6310:73;;6173:220;6101:299;;;;:::o;6406:262::-;;6514:2;6502:9;6493:7;6489:23;6485:32;6482:2;;;6530:1;6527;6520:12;6482:2;6573:1;6598:53;6643:7;6634:6;6623:9;6619:22;6598:53;:::i;:::-;6588:63;;6544:117;6472:196;;;;:::o;6674:179::-;;6764:46;6806:3;6798:6;6764:46;:::i;:::-;6842:4;6837:3;6833:14;6819:28;;6754:99;;;;:::o;6859:142::-;6962:32;6988:5;6962:32;:::i;:::-;6957:3;6950:45;6940:61;;:::o;7007:118::-;7094:24;7112:5;7094:24;:::i;:::-;7089:3;7082:37;7072:53;;:::o;7161:732::-;;7309:54;7357:5;7309:54;:::i;:::-;7379:86;7458:6;7453:3;7379:86;:::i;:::-;7372:93;;7489:56;7539:5;7489:56;:::i;:::-;7568:7;7599:1;7584:284;7609:6;7606:1;7603:13;7584:284;;;7685:6;7679:13;7712:63;7771:3;7756:13;7712:63;:::i;:::-;7705:70;;7798:60;7851:6;7798:60;:::i;:::-;7788:70;;7644:224;7631:1;7628;7624:9;7619:14;;7584:284;;;7588:14;7884:3;7877:10;;7285:608;;;;;;;:::o;7899:109::-;7980:21;7995:5;7980:21;:::i;:::-;7975:3;7968:34;7958:50;;:::o;8014:360::-;;8128:38;8160:5;8128:38;:::i;:::-;8182:70;8245:6;8240:3;8182:70;:::i;:::-;8175:77;;8261:52;8306:6;8301:3;8294:4;8287:5;8283:16;8261:52;:::i;:::-;8338:29;8360:6;8338:29;:::i;:::-;8333:3;8329:39;8322:46;;8104:270;;;;;:::o;8380:373::-;;8512:38;8544:5;8512:38;:::i;:::-;8566:88;8647:6;8642:3;8566:88;:::i;:::-;8559:95;;8663:52;8708:6;8703:3;8696:4;8689:5;8685:16;8663:52;:::i;:::-;8740:6;8735:3;8731:16;8724:23;;8488:265;;;;;:::o;8759:364::-;;8875:39;8908:5;8875:39;:::i;:::-;8930:71;8994:6;8989:3;8930:71;:::i;:::-;8923:78;;9010:52;9055:6;9050:3;9043:4;9036:5;9032:16;9010:52;:::i;:::-;9087:29;9109:6;9087:29;:::i;:::-;9082:3;9078:39;9071:46;;8851:272;;;;;:::o;9129:377::-;;9263:39;9296:5;9263:39;:::i;:::-;9318:89;9400:6;9395:3;9318:89;:::i;:::-;9311:96;;9416:52;9461:6;9456:3;9449:4;9442:5;9438:16;9416:52;:::i;:::-;9493:6;9488:3;9484:16;9477:23;;9239:267;;;;;:::o;9512:366::-;;9675:67;9739:2;9734:3;9675:67;:::i;:::-;9668:74;;9772:34;9768:1;9763:3;9759:11;9752:55;9838:4;9833:2;9828:3;9824:12;9817:26;9869:2;9864:3;9860:12;9853:19;;9658:220;;;:::o;9884:329::-;;10047:67;10111:2;10106:3;10047:67;:::i;:::-;10040:74;;10144:33;10140:1;10135:3;10131:11;10124:54;10204:2;10199:3;10195:12;10188:19;;10030:183;;;:::o;10219:382::-;;10382:67;10446:2;10441:3;10382:67;:::i;:::-;10375:74;;10479:34;10475:1;10470:3;10466:11;10459:55;10545:20;10540:2;10535:3;10531:12;10524:42;10592:2;10587:3;10583:12;10576:19;;10365:236;;;:::o;10607:372::-;;10770:67;10834:2;10829:3;10770:67;:::i;:::-;10763:74;;10867:34;10863:1;10858:3;10854:11;10847:55;10933:10;10928:2;10923:3;10919:12;10912:32;10970:2;10965:3;10961:12;10954:19;;10753:226;;;:::o;10985:370::-;;11148:67;11212:2;11207:3;11148:67;:::i;:::-;11141:74;;11245:34;11241:1;11236:3;11232:11;11225:55;11311:8;11306:2;11301:3;11297:12;11290:30;11346:2;11341:3;11337:12;11330:19;;11131:224;;;:::o;11361:326::-;;11524:67;11588:2;11583:3;11524:67;:::i;:::-;11517:74;;11621:30;11617:1;11612:3;11608:11;11601:51;11678:2;11673:3;11669:12;11662:19;;11507:180;;;:::o;11693:325::-;;11856:67;11920:2;11915:3;11856:67;:::i;:::-;11849:74;;11953:29;11949:1;11944:3;11940:11;11933:50;12009:2;12004:3;12000:12;11993:19;;11839:179;;;:::o;12024:368::-;;12187:67;12251:2;12246:3;12187:67;:::i;:::-;12180:74;;12284:34;12280:1;12275:3;12271:11;12264:55;12350:6;12345:2;12340:3;12336:12;12329:28;12383:2;12378:3;12374:12;12367:19;;12170:222;;;:::o;12398:323::-;;12561:67;12625:2;12620:3;12561:67;:::i;:::-;12554:74;;12658:27;12654:1;12649:3;12645:11;12638:48;12712:2;12707:3;12703:12;12696:19;;12544:177;;;:::o;12727:328::-;;12890:67;12954:2;12949:3;12890:67;:::i;:::-;12883:74;;12987:32;12983:1;12978:3;12974:11;12967:53;13046:2;13041:3;13037:12;13030:19;;12873:182;;;:::o;13061:370::-;;13224:67;13288:2;13283:3;13224:67;:::i;:::-;13217:74;;13321:34;13317:1;13312:3;13308:11;13301:55;13387:8;13382:2;13377:3;13373:12;13366:30;13422:2;13417:3;13413:12;13406:19;;13207:224;;;:::o;13437:376::-;;13600:67;13664:2;13659:3;13600:67;:::i;:::-;13593:74;;13697:34;13693:1;13688:3;13684:11;13677:55;13763:14;13758:2;13753:3;13749:12;13742:36;13804:2;13799:3;13795:12;13788:19;;13583:230;;;:::o;13819:388::-;;13982:67;14046:2;14041:3;13982:67;:::i;:::-;13975:74;;14079:34;14075:1;14070:3;14066:11;14059:55;14145:26;14140:2;14135:3;14131:12;14124:48;14198:2;14193:3;14189:12;14182:19;;13965:242;;;:::o;14213:374::-;;14376:67;14440:2;14435:3;14376:67;:::i;:::-;14369:74;;14473:34;14469:1;14464:3;14460:11;14453:55;14539:12;14534:2;14529:3;14525:12;14518:34;14578:2;14573:3;14569:12;14562:19;;14359:228;;;:::o;14593:366::-;;14756:67;14820:2;14815:3;14756:67;:::i;:::-;14749:74;;14853:34;14849:1;14844:3;14840:11;14833:55;14919:4;14914:2;14909:3;14905:12;14898:26;14950:2;14945:3;14941:12;14934:19;;14739:220;;;:::o;14965:330::-;;15128:67;15192:2;15187:3;15128:67;:::i;:::-;15121:74;;15225:34;15221:1;15216:3;15212:11;15205:55;15286:2;15281:3;15277:12;15270:19;;15111:184;;;:::o;15301:365::-;;15464:67;15528:2;15523:3;15464:67;:::i;:::-;15457:74;;15561:34;15557:1;15552:3;15548:11;15541:55;15627:3;15622:2;15617:3;15613:12;15606:25;15657:2;15652:3;15648:12;15641:19;;15447:219;;;:::o;15672:376::-;;15835:67;15899:2;15894:3;15835:67;:::i;:::-;15828:74;;15932:34;15928:1;15923:3;15919:11;15912:55;15998:14;15993:2;15988:3;15984:12;15977:36;16039:2;16034:3;16030:12;16023:19;;15818:230;;;:::o;16054:330::-;;16217:67;16281:2;16276:3;16217:67;:::i;:::-;16210:74;;16314:34;16310:1;16305:3;16301:11;16294:55;16375:2;16370:3;16366:12;16359:19;;16200:184;;;:::o;16390:373::-;;16553:67;16617:2;16612:3;16553:67;:::i;:::-;16546:74;;16650:34;16646:1;16641:3;16637:11;16630:55;16716:11;16711:2;16706:3;16702:12;16695:33;16754:2;16749:3;16745:12;16738:19;;16536:227;;;:::o;16769:379::-;;16932:67;16996:2;16991:3;16932:67;:::i;:::-;16925:74;;17029:34;17025:1;17020:3;17016:11;17009:55;17095:17;17090:2;17085:3;17081:12;17074:39;17139:2;17134:3;17130:12;17123:19;;16915:233;;;:::o;17154:321::-;;17317:67;17381:2;17376:3;17317:67;:::i;:::-;17310:74;;17414:25;17410:1;17405:3;17401:11;17394:46;17466:2;17461:3;17457:12;17450:19;;17300:175;;;:::o;17481:365::-;;17644:67;17708:2;17703:3;17644:67;:::i;:::-;17637:74;;17741:34;17737:1;17732:3;17728:11;17721:55;17807:3;17802:2;17797:3;17793:12;17786:25;17837:2;17832:3;17828:12;17821:19;;17627:219;;;:::o;17852:325::-;;18015:67;18079:2;18074:3;18015:67;:::i;:::-;18008:74;;18112:29;18108:1;18103:3;18099:11;18092:50;18168:2;18163:3;18159:12;18152:19;;17998:179;;;:::o;18183:381::-;;18346:67;18410:2;18405:3;18346:67;:::i;:::-;18339:74;;18443:34;18439:1;18434:3;18430:11;18423:55;18509:19;18504:2;18499:3;18495:12;18488:41;18555:2;18550:3;18546:12;18539:19;;18329:235;;;:::o;18570:327::-;;18733:67;18797:2;18792:3;18733:67;:::i;:::-;18726:74;;18830:31;18826:1;18821:3;18817:11;18810:52;18888:2;18883:3;18879:12;18872:19;;18716:181;;;:::o;18903:436::-;;19066:67;19130:2;19125:3;19066:67;:::i;:::-;19059:74;;19163:34;19159:1;19154:3;19150:11;19143:55;19229:34;19224:2;19219:3;19215:12;19208:56;19295:8;19290:2;19285:3;19281:12;19274:30;19330:2;19325:3;19321:12;19314:19;;19049:290;;;:::o;19345:327::-;;19508:67;19572:2;19567:3;19508:67;:::i;:::-;19501:74;;19605:31;19601:1;19596:3;19592:11;19585:52;19663:2;19658:3;19654:12;19647:19;;19491:181;;;:::o;19678:108::-;19755:24;19773:5;19755:24;:::i;:::-;19750:3;19743:37;19733:53;;:::o;19792:118::-;19879:24;19897:5;19879:24;:::i;:::-;19874:3;19867:37;19857:53;;:::o;19916:271::-;;20068:93;20157:3;20148:6;20068:93;:::i;:::-;20061:100;;20178:3;20171:10;;20050:137;;;;:::o;20193:435::-;;20395:95;20486:3;20477:6;20395:95;:::i;:::-;20388:102;;20507:95;20598:3;20589:6;20507:95;:::i;:::-;20500:102;;20619:3;20612:10;;20377:251;;;;;:::o;20634:222::-;;20765:2;20754:9;20750:18;20742:26;;20778:71;20846:1;20835:9;20831:17;20822:6;20778:71;:::i;:::-;20732:124;;;;:::o;20862:672::-;;21111:3;21100:9;21096:19;21088:27;;21125:87;21209:1;21198:9;21194:17;21185:6;21125:87;:::i;:::-;21222:72;21290:2;21279:9;21275:18;21266:6;21222:72;:::i;:::-;21304;21372:2;21361:9;21357:18;21348:6;21304:72;:::i;:::-;21423:9;21417:4;21413:20;21408:2;21397:9;21393:18;21386:48;21451:76;21522:4;21513:6;21451:76;:::i;:::-;21443:84;;21078:456;;;;;;;:::o;21540:373::-;;21721:2;21710:9;21706:18;21698:26;;21770:9;21764:4;21760:20;21756:1;21745:9;21741:17;21734:47;21798:108;21901:4;21892:6;21798:108;:::i;:::-;21790:116;;21688:225;;;;:::o;21919:210::-;;22044:2;22033:9;22029:18;22021:26;;22057:65;22119:1;22108:9;22104:17;22095:6;22057:65;:::i;:::-;22011:118;;;;:::o;22135:313::-;;22286:2;22275:9;22271:18;22263:26;;22335:9;22329:4;22325:20;22321:1;22310:9;22306:17;22299:47;22363:78;22436:4;22427:6;22363:78;:::i;:::-;22355:86;;22253:195;;;;:::o;22454:419::-;;22658:2;22647:9;22643:18;22635:26;;22707:9;22701:4;22697:20;22693:1;22682:9;22678:17;22671:47;22735:131;22861:4;22735:131;:::i;:::-;22727:139;;22625:248;;;:::o;22879:419::-;;23083:2;23072:9;23068:18;23060:26;;23132:9;23126:4;23122:20;23118:1;23107:9;23103:17;23096:47;23160:131;23286:4;23160:131;:::i;:::-;23152:139;;23050:248;;;:::o;23304:419::-;;23508:2;23497:9;23493:18;23485:26;;23557:9;23551:4;23547:20;23543:1;23532:9;23528:17;23521:47;23585:131;23711:4;23585:131;:::i;:::-;23577:139;;23475:248;;;:::o;23729:419::-;;23933:2;23922:9;23918:18;23910:26;;23982:9;23976:4;23972:20;23968:1;23957:9;23953:17;23946:47;24010:131;24136:4;24010:131;:::i;:::-;24002:139;;23900:248;;;:::o;24154:419::-;;24358:2;24347:9;24343:18;24335:26;;24407:9;24401:4;24397:20;24393:1;24382:9;24378:17;24371:47;24435:131;24561:4;24435:131;:::i;:::-;24427:139;;24325:248;;;:::o;24579:419::-;;24783:2;24772:9;24768:18;24760:26;;24832:9;24826:4;24822:20;24818:1;24807:9;24803:17;24796:47;24860:131;24986:4;24860:131;:::i;:::-;24852:139;;24750:248;;;:::o;25004:419::-;;25208:2;25197:9;25193:18;25185:26;;25257:9;25251:4;25247:20;25243:1;25232:9;25228:17;25221:47;25285:131;25411:4;25285:131;:::i;:::-;25277:139;;25175:248;;;:::o;25429:419::-;;25633:2;25622:9;25618:18;25610:26;;25682:9;25676:4;25672:20;25668:1;25657:9;25653:17;25646:47;25710:131;25836:4;25710:131;:::i;:::-;25702:139;;25600:248;;;:::o;25854:419::-;;26058:2;26047:9;26043:18;26035:26;;26107:9;26101:4;26097:20;26093:1;26082:9;26078:17;26071:47;26135:131;26261:4;26135:131;:::i;:::-;26127:139;;26025:248;;;:::o;26279:419::-;;26483:2;26472:9;26468:18;26460:26;;26532:9;26526:4;26522:20;26518:1;26507:9;26503:17;26496:47;26560:131;26686:4;26560:131;:::i;:::-;26552:139;;26450:248;;;:::o;26704:419::-;;26908:2;26897:9;26893:18;26885:26;;26957:9;26951:4;26947:20;26943:1;26932:9;26928:17;26921:47;26985:131;27111:4;26985:131;:::i;:::-;26977:139;;26875:248;;;:::o;27129:419::-;;27333:2;27322:9;27318:18;27310:26;;27382:9;27376:4;27372:20;27368:1;27357:9;27353:17;27346:47;27410:131;27536:4;27410:131;:::i;:::-;27402:139;;27300:248;;;:::o;27554:419::-;;27758:2;27747:9;27743:18;27735:26;;27807:9;27801:4;27797:20;27793:1;27782:9;27778:17;27771:47;27835:131;27961:4;27835:131;:::i;:::-;27827:139;;27725:248;;;:::o;27979:419::-;;28183:2;28172:9;28168:18;28160:26;;28232:9;28226:4;28222:20;28218:1;28207:9;28203:17;28196:47;28260:131;28386:4;28260:131;:::i;:::-;28252:139;;28150:248;;;:::o;28404:419::-;;28608:2;28597:9;28593:18;28585:26;;28657:9;28651:4;28647:20;28643:1;28632:9;28628:17;28621:47;28685:131;28811:4;28685:131;:::i;:::-;28677:139;;28575:248;;;:::o;28829:419::-;;29033:2;29022:9;29018:18;29010:26;;29082:9;29076:4;29072:20;29068:1;29057:9;29053:17;29046:47;29110:131;29236:4;29110:131;:::i;:::-;29102:139;;29000:248;;;:::o;29254:419::-;;29458:2;29447:9;29443:18;29435:26;;29507:9;29501:4;29497:20;29493:1;29482:9;29478:17;29471:47;29535:131;29661:4;29535:131;:::i;:::-;29527:139;;29425:248;;;:::o;29679:419::-;;29883:2;29872:9;29868:18;29860:26;;29932:9;29926:4;29922:20;29918:1;29907:9;29903:17;29896:47;29960:131;30086:4;29960:131;:::i;:::-;29952:139;;29850:248;;;:::o;30104:419::-;;30308:2;30297:9;30293:18;30285:26;;30357:9;30351:4;30347:20;30343:1;30332:9;30328:17;30321:47;30385:131;30511:4;30385:131;:::i;:::-;30377:139;;30275:248;;;:::o;30529:419::-;;30733:2;30722:9;30718:18;30710:26;;30782:9;30776:4;30772:20;30768:1;30757:9;30753:17;30746:47;30810:131;30936:4;30810:131;:::i;:::-;30802:139;;30700:248;;;:::o;30954:419::-;;31158:2;31147:9;31143:18;31135:26;;31207:9;31201:4;31197:20;31193:1;31182:9;31178:17;31171:47;31235:131;31361:4;31235:131;:::i;:::-;31227:139;;31125:248;;;:::o;31379:419::-;;31583:2;31572:9;31568:18;31560:26;;31632:9;31626:4;31622:20;31618:1;31607:9;31603:17;31596:47;31660:131;31786:4;31660:131;:::i;:::-;31652:139;;31550:248;;;:::o;31804:419::-;;32008:2;31997:9;31993:18;31985:26;;32057:9;32051:4;32047:20;32043:1;32032:9;32028:17;32021:47;32085:131;32211:4;32085:131;:::i;:::-;32077:139;;31975:248;;;:::o;32229:419::-;;32433:2;32422:9;32418:18;32410:26;;32482:9;32476:4;32472:20;32468:1;32457:9;32453:17;32446:47;32510:131;32636:4;32510:131;:::i;:::-;32502:139;;32400:248;;;:::o;32654:419::-;;32858:2;32847:9;32843:18;32835:26;;32907:9;32901:4;32897:20;32893:1;32882:9;32878:17;32871:47;32935:131;33061:4;32935:131;:::i;:::-;32927:139;;32825:248;;;:::o;33079:419::-;;33283:2;33272:9;33268:18;33260:26;;33332:9;33326:4;33322:20;33318:1;33307:9;33303:17;33296:47;33360:131;33486:4;33360:131;:::i;:::-;33352:139;;33250:248;;;:::o;33504:419::-;;33708:2;33697:9;33693:18;33685:26;;33757:9;33751:4;33747:20;33743:1;33732:9;33728:17;33721:47;33785:131;33911:4;33785:131;:::i;:::-;33777:139;;33675:248;;;:::o;33929:419::-;;34133:2;34122:9;34118:18;34110:26;;34182:9;34176:4;34172:20;34168:1;34157:9;34153:17;34146:47;34210:131;34336:4;34210:131;:::i;:::-;34202:139;;34100:248;;;:::o;34354:222::-;;34485:2;34474:9;34470:18;34462:26;;34498:71;34566:1;34555:9;34551:17;34542:6;34498:71;:::i;:::-;34452:124;;;;:::o;34582:278::-;;34648:2;34642:9;34632:19;;34690:4;34682:6;34678:17;34797:6;34785:10;34782:22;34761:18;34749:10;34746:34;34743:62;34740:2;;;34808:13;;:::i;:::-;34740:2;34843:10;34839:2;34832:22;34622:238;;;;:::o;34866:326::-;;35017:18;35009:6;35006:30;35003:2;;;35039:13;;:::i;:::-;35003:2;35119:4;35115:9;35108:4;35100:6;35096:17;35092:33;35084:41;;35180:4;35174;35170:15;35162:23;;34932:260;;;:::o;35198:327::-;;35350:18;35342:6;35339:30;35336:2;;;35372:13;;:::i;:::-;35336:2;35452:4;35448:9;35441:4;35433:6;35429:17;35425:33;35417:41;;35513:4;35507;35503:15;35495:23;;35265:260;;;:::o;35531:132::-;;35621:3;35613:11;;35651:4;35646:3;35642:14;35634:22;;35603:60;;;:::o;35669:114::-;;35770:5;35764:12;35754:22;;35743:40;;;:::o;35789:98::-;;35874:5;35868:12;35858:22;;35847:40;;;:::o;35893:99::-;;35979:5;35973:12;35963:22;;35952:40;;;:::o;35998:113::-;;36100:4;36095:3;36091:14;36083:22;;36073:38;;;:::o;36117:184::-;;36250:6;36245:3;36238:19;36290:4;36285:3;36281:14;36266:29;;36228:73;;;;:::o;36307:168::-;;36424:6;36419:3;36412:19;36464:4;36459:3;36455:14;36440:29;;36402:73;;;;:::o;36481:147::-;;36619:3;36604:18;;36594:34;;;;:::o;36634:169::-;;36752:6;36747:3;36740:19;36792:4;36787:3;36783:14;36768:29;;36730:73;;;;:::o;36809:148::-;;36948:3;36933:18;;36923:34;;;;:::o;36963:96::-;;37029:24;37047:5;37029:24;:::i;:::-;37018:35;;37008:51;;;:::o;37065:104::-;;37139:24;37157:5;37139:24;:::i;:::-;37128:35;;37118:51;;;:::o;37175:90::-;;37252:5;37245:13;37238:21;37227:32;;37217:48;;;:::o;37271:149::-;;37347:66;37340:5;37336:78;37325:89;;37315:105;;;:::o;37426:126::-;;37503:42;37496:5;37492:54;37481:65;;37471:81;;;:::o;37558:77::-;;37624:5;37613:16;;37603:32;;;:::o;37641:154::-;37725:6;37720:3;37715;37702:30;37787:1;37778:6;37773:3;37769:16;37762:27;37692:103;;;:::o;37801:307::-;37869:1;37879:113;37893:6;37890:1;37887:13;37879:113;;;37978:1;37973:3;37969:11;37963:18;37959:1;37954:3;37950:11;37943:39;37915:2;37912:1;37908:10;37903:15;;37879:113;;;38010:6;38007:1;38004:13;38001:2;;;38090:1;38081:6;38076:3;38072:16;38065:27;38001:2;37850:258;;;;:::o;38114:48::-;38147:9;38168:102;;38260:2;38256:7;38251:2;38244:5;38240:14;38236:28;38226:38;;38216:54;;;:::o;38276:122::-;38349:24;38367:5;38349:24;:::i;:::-;38342:5;38339:35;38329:2;;38388:1;38385;38378:12;38329:2;38319:79;:::o;38404:138::-;38485:32;38511:5;38485:32;:::i;:::-;38478:5;38475:43;38465:2;;38532:1;38529;38522:12;38465:2;38455:87;:::o;38548:116::-;38618:21;38633:5;38618:21;:::i;:::-;38611:5;38608:32;38598:2;;38654:1;38651;38644:12;38598:2;38588:76;:::o;38670:120::-;38742:23;38759:5;38742:23;:::i;:::-;38735:5;38732:34;38722:2;;38780:1;38777;38770:12;38722:2;38712:78;:::o;38796:122::-;38869:24;38887:5;38869:24;:::i;:::-;38862:5;38859:35;38849:2;;38908:1;38905;38898:12;38849:2;38839:79;:::o

Swarm Source

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