ETH Price: $3,414.14 (+1.78%)

Token

Cupcat NFT (CUPCAT)
 

Overview

Max Total Supply

5,024 CUPCAT

Holders

1,700

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
hinata.eth
Balance
1 CUPCAT
0xbdc2bd2a0011d918cabb389ae739212c46e0ee91
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Welcome to CUPCAT, The experimental collection. A cup of soft cream is recommended if you're finding something to drink and a cup of Jelly candy to sweet your mouth.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
cupcat

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-09-18
*/

/**
 *Submitted for verification at Etherscan.io on 2021-09-15
*/

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

/**
 *Submitted for verification at Etherscan.io on 2021-09-11
*/

// SPDX-License-Identifier: MIT
 
// File: @openzeppelin/contracts/utils/Context.sol

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

// @openzeppelin/contracts/cryptography/MerkleProof.sol

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        bytes32 computedHash = leaf;

        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];

            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }
        }

        // Check if the computed hash (root) is equal to the provided root
        return computedHash == root;
    }
}

pragma solidity ^0.7.0;
pragma abicoder v2;

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

    string public CUPCAT_PROVENANCE = "";
    string public LICENSE_TEXT = ""; 
    bool licenseLocked = false; 

    address private owner_;
    bytes32 public merkleRoot;

    uint256 public constant cupcatPrice = 20000000000000000;
    uint public constant maxCupCatPurchase = 3;
    uint256 public constant MAX_CUPCAT = 5000;
    uint public cupcatReserve = 100;

    bool public saleIsActive = false;
    mapping(address => bool) private whitelisted_minters;
    mapping(address => uint) private max_mints_per_address;
    event WhitelistedMint(address minter);
    event MerkleRootUpdated(bytes32 new_merkle_root);
    

    constructor() ERC721("Cupcat NFT", "CUPCAT") { }
    
    function withdraw() public onlyOwner {
        uint balance = address(this).balance;
        msg.sender.transfer(balance);
    }

    function reserveCupcat(address _to, uint256 _reserveAmount) public onlyOwner {        
        uint supply = totalSupply();
        require(_reserveAmount > 0 && _reserveAmount <= cupcatReserve, "Not enough reserve");
        for (uint i = 0; i < _reserveAmount; i++) {
            _safeMint(_to, supply + i);
        }
        cupcatReserve = cupcatReserve.sub(_reserveAmount);
    }


    function setProvenanceHash(string memory provenanceHash) public onlyOwner {
        CUPCAT_PROVENANCE = provenanceHash;
    }

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


    function flipSaleState() public onlyOwner {
        saleIsActive = !saleIsActive;
    }
    
    
    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;
        }
    }
    
    
    
     function mintCupCat(uint numberOfTokens) public payable {
        require(saleIsActive, "Sale must be active to mint Cupcat");
        require(!isContract(msg.sender), "Mint via contract not allowed");
        require(numberOfTokens > 0 && numberOfTokens <= maxCupCatPurchase, "Can only mint 3 tokens at a time");
        require(msg.value == cupcatPrice.mul(numberOfTokens), "Ether value sent is not correct");
        require(max_mints_per_address[msg.sender].add(numberOfTokens) <= 3,"Max 3 mints per wallet allowed");
        
        for(uint i = 0; i < numberOfTokens; i++) {
            if (totalSupply() < MAX_CUPCAT) {
                _safeMint(msg.sender, totalSupply());
                max_mints_per_address[msg.sender] = max_mints_per_address[msg.sender].add(1);
            } else {
               saleIsActive = !saleIsActive;
                msg.sender.transfer(numberOfTokens.sub(i).mul(cupcatPrice));
                break;
            }
        }
    }
   function isContract(address account) internal view returns (bool) {
        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    } 

   
   // to set the merkle proof
    function updateMerkleRoot(bytes32 newmerkleRoot) external onlyOwner {
        merkleRoot = newmerkleRoot;
        emit MerkleRootUpdated(merkleRoot);
    }


    function whitelistedMints( bytes32[] calldata merkleProof ) payable external  {
        address user_ = msg.sender;

        require(msg.value == cupcatPrice,"Exactly 0.02 ETH is needed for mint" );
        require(totalSupply().add(1) <= MAX_CUPCAT, "Mint would exceed max supply of Cupcats");
        require(!whitelisted_minters[user_],"Already Claimed the whitelisted mint");

        // Verify the merkle proof
        require(MerkleProof.verify(merkleProof, merkleRoot,  keccak256(abi.encodePacked(user_))  ), "Invalid proof");

        // Mark it claimed
        whitelisted_minters[user_] = true;

        // Mint 1 CupCat NFT for the user
       _safeMint(user_, totalSupply());

        emit WhitelistedMint(user_);
    }
}

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":false,"internalType":"bytes32","name":"new_merkle_root","type":"bytes32"}],"name":"MerkleRootUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"minter","type":"address"}],"name":"WhitelistedMint","type":"event"},{"inputs":[],"name":"CUPCAT_PROVENANCE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LICENSE_TEXT","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_CUPCAT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"cupcatPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cupcatReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"maxCupCatPurchase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"mintCupCat","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":"reserveCupcat","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":"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":[{"internalType":"bytes32","name":"newmerkleRoot","type":"bytes32"}],"name":"updateMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"whitelistedMints","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260405180602001604052806000815250600b90805190602001906200002b92919062000334565b5060405180602001604052806000815250600c90805190602001906200005392919062000334565b506000600d60006101000a81548160ff0219169083151502179055506064600f556000601060006101000a81548160ff0219169083151502179055503480156200009c57600080fd5b506040518060400160405280600a81526020017f437570636174204e4654000000000000000000000000000000000000000000008152506040518060400160405280600681526020017f4355504341540000000000000000000000000000000000000000000000000000815250620001216301ffc9a760e01b6200025460201b60201c565b81600690805190602001906200013992919062000334565b5080600790805190602001906200015292919062000334565b506200016b6380ac58cd60e01b6200025460201b60201c565b62000183635b5e139f60e01b6200025460201b60201c565b6200019b63780e9d6360e01b6200025460201b60201c565b50506000620001af6200032c60201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3506200045f565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415620002c0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002b7906200042c565b60405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200036c5760008555620003b8565b82601f106200038757805160ff1916838001178555620003b8565b82800160010185558215620003b8579182015b82811115620003b75782518255916020019190600101906200039a565b5b509050620003c79190620003cb565b5090565b5b80821115620003e6576000816000905550600101620003cc565b5090565b6000620003f9601c836200044e565b91507f4552433136353a20696e76616c696420696e74657266616365206964000000006000830152602082019050919050565b600060208201905081810360008301526200044781620003ea565b9050919050565b600082825260208201905092915050565b614e5a806200046f6000396000f3fe60806040526004361061021a5760003560e01c80636c0360eb116101235780639c3e72bd116100ab578063e27441ca1161006f578063e27441ca146107b2578063e985e9c5146107dd578063eb8d24441461081a578063f2fde38b14610845578063f647a45a1461086e5761021a565b80639c3e72bd146106cd578063a22cb465146106f8578063af6ed0f914610721578063b88d4fde1461074c578063c87b56dd146107755761021a565b80637ed81d93116100f25780637ed81d93146105f557806380f85473146106115780638462151c1461063a5780638da5cb5b1461067757806395d89b41146106a25761021a565b80636c0360eb1461054b57806370a0823114610576578063715018a6146105b3578063738bb60e146105ca5761021a565b80632f745c59116101a65780634783f0ef116101755780634783f0ef146104545780634f6ccce71461047d57806355f804b3146104ba5780636352211e146104e35780636566a8d6146105205761021a565b80632f745c59146103c057806334918dfd146103fd5780633ccfd60b1461041457806342842e0e1461042b5761021a565b80630ce75937116101ed5780630ce75937146102ed578063109695231461031857806318160ddd1461034157806323b872dd1461036c5780632eb4a7ab146103955761021a565b806301ffc9a71461021f57806306fdde031461025c578063081812fc14610287578063095ea7b3146102c4575b600080fd5b34801561022b57600080fd5b5061024660048036038101906102419190613840565b61088a565b60405161025391906146ab565b60405180910390f35b34801561026857600080fd5b506102716108f1565b60405161027e91906146e1565b60405180910390f35b34801561029357600080fd5b506102ae60048036038101906102a991906138d3565b610993565b6040516102bb9190614622565b60405180910390f35b3480156102d057600080fd5b506102eb60048036038101906102e69190613796565b610a18565b005b3480156102f957600080fd5b50610302610b30565b60405161030f9190614b03565b60405180910390f35b34801561032457600080fd5b5061033f600480360381019061033a9190613892565b610b3b565b005b34801561034d57600080fd5b50610356610bd1565b6040516103639190614b03565b60405180910390f35b34801561037857600080fd5b50610393600480360381019061038e9190613690565b610be2565b005b3480156103a157600080fd5b506103aa610c42565b6040516103b791906146c6565b60405180910390f35b3480156103cc57600080fd5b506103e760048036038101906103e29190613796565b610c48565b6040516103f49190614b03565b60405180910390f35b34801561040957600080fd5b50610412610ca3565b005b34801561042057600080fd5b50610429610d4b565b005b34801561043757600080fd5b50610452600480360381019061044d9190613690565b610e16565b005b34801561046057600080fd5b5061047b60048036038101906104769190613817565b610e36565b005b34801561048957600080fd5b506104a4600480360381019061049f91906138d3565b610ef5565b6040516104b19190614b03565b60405180910390f35b3480156104c657600080fd5b506104e160048036038101906104dc9190613892565b610f18565b005b3480156104ef57600080fd5b5061050a600480360381019061050591906138d3565b610fa0565b6040516105179190614622565b60405180910390f35b34801561052c57600080fd5b50610535610fd7565b60405161054291906146e1565b60405180910390f35b34801561055757600080fd5b50610560611075565b60405161056d91906146e1565b60405180910390f35b34801561058257600080fd5b5061059d6004803603810190610598919061362b565b611117565b6040516105aa9190614b03565b60405180910390f35b3480156105bf57600080fd5b506105c86111d6565b005b3480156105d657600080fd5b506105df611313565b6040516105ec9190614b03565b60405180910390f35b61060f600480360381019061060a91906137d2565b611319565b005b34801561061d57600080fd5b5061063860048036038101906106339190613796565b6115ab565b005b34801561064657600080fd5b50610661600480360381019061065c919061362b565b6116c9565b60405161066e9190614689565b60405180910390f35b34801561068357600080fd5b5061068c6117c2565b6040516106999190614622565b60405180910390f35b3480156106ae57600080fd5b506106b76117ec565b6040516106c491906146e1565b60405180910390f35b3480156106d957600080fd5b506106e261188e565b6040516106ef91906146e1565b60405180910390f35b34801561070457600080fd5b5061071f600480360381019061071a919061375a565b61192c565b005b34801561072d57600080fd5b50610736611aad565b6040516107439190614b03565b60405180910390f35b34801561075857600080fd5b50610773600480360381019061076e91906136df565b611ab2565b005b34801561078157600080fd5b5061079c600480360381019061079791906138d3565b611b14565b6040516107a991906146e1565b60405180910390f35b3480156107be57600080fd5b506107c7611c97565b6040516107d49190614b03565b60405180910390f35b3480156107e957600080fd5b5061080460048036038101906107ff9190613654565b611c9d565b60405161081191906146ab565b60405180910390f35b34801561082657600080fd5b5061082f611d31565b60405161083c91906146ab565b60405180910390f35b34801561085157600080fd5b5061086c6004803603810190610867919061362b565b611d44565b005b610888600480360381019061088391906138d3565b611ef0565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109895780601f1061095e57610100808354040283529160200191610989565b820191906000526020600020905b81548152906001019060200180831161096c57829003601f168201915b5050505050905090565b600061099e82612242565b6109dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d490614963565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a2382610fa0565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610a94576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8b90614a23565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610ab361225f565b73ffffffffffffffffffffffffffffffffffffffff161480610ae25750610ae181610adc61225f565b611c9d565b5b610b21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b18906148c3565b60405180910390fd5b610b2b8383612267565b505050565b66470de4df82000081565b610b4361225f565b73ffffffffffffffffffffffffffffffffffffffff16610b616117c2565b73ffffffffffffffffffffffffffffffffffffffff1614610bb7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bae90614983565b60405180910390fd5b80600b9080519060200190610bcd9291906133e8565b5050565b6000610bdd6002612320565b905090565b610bf3610bed61225f565b82612335565b610c32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2990614a63565b60405180910390fd5b610c3d838383612413565b505050565b600e5481565b6000610c9b82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061262a90919063ffffffff16565b905092915050565b610cab61225f565b73ffffffffffffffffffffffffffffffffffffffff16610cc96117c2565b73ffffffffffffffffffffffffffffffffffffffff1614610d1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1690614983565b60405180910390fd5b601060009054906101000a900460ff1615601060006101000a81548160ff021916908315150217905550565b610d5361225f565b73ffffffffffffffffffffffffffffffffffffffff16610d716117c2565b73ffffffffffffffffffffffffffffffffffffffff1614610dc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dbe90614983565b60405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610e12573d6000803e3d6000fd5b5050565b610e3183838360405180602001604052806000815250611ab2565b505050565b610e3e61225f565b73ffffffffffffffffffffffffffffffffffffffff16610e5c6117c2565b73ffffffffffffffffffffffffffffffffffffffff1614610eb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea990614983565b60405180910390fd5b80600e819055507f90004c04698bc3322499a575ed3752dd4abf33e0a7294c06a787a0fe01bea941600e54604051610eea91906146c6565b60405180910390a150565b600080610f0c83600261264490919063ffffffff16565b50905080915050919050565b610f2061225f565b73ffffffffffffffffffffffffffffffffffffffff16610f3e6117c2565b73ffffffffffffffffffffffffffffffffffffffff1614610f94576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8b90614983565b60405180910390fd5b610f9d81612670565b50565b6000610fd082604051806060016040528060298152602001614dfc60299139600261268a9092919063ffffffff16565b9050919050565b600b8054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561106d5780601f106110425761010080835404028352916020019161106d565b820191906000526020600020905b81548152906001019060200180831161105057829003601f168201915b505050505081565b606060098054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561110d5780601f106110e25761010080835404028352916020019161110d565b820191906000526020600020905b8154815290600101906020018083116110f057829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117f906148e3565b60405180910390fd5b6111cf600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206126a9565b9050919050565b6111de61225f565b73ffffffffffffffffffffffffffffffffffffffff166111fc6117c2565b73ffffffffffffffffffffffffffffffffffffffff1614611252576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124990614983565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600f5481565b600033905066470de4df8200003414611367576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135e90614883565b60405180910390fd5b6113886113856001611377610bd1565b6126be90919063ffffffff16565b11156113c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113bd906147a3565b60405180910390fd5b601160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144a906149a3565b60405180910390fd5b6114c7838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600e54836040516020016114ac91906145a0565b60405160208183030381529060405280519060200120612713565b611506576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114fd90614ae3565b60405180910390fd5b6001601160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061156f8161156a610bd1565b6127bc565b7f67c400238edbf2cfe078e9c46b03af4a14f535dafde7829c4ebd8ffc76448bee8160405161159e9190614622565b60405180910390a1505050565b6115b361225f565b73ffffffffffffffffffffffffffffffffffffffff166115d16117c2565b73ffffffffffffffffffffffffffffffffffffffff1614611627576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161e90614983565b60405180910390fd5b6000611631610bd1565b90506000821180156116455750600f548211155b611684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167b90614a03565b60405180910390fd5b60005b828110156116a85761169b848284016127bc565b8080600101915050611687565b506116be82600f546127da90919063ffffffff16565b600f81905550505050565b606060006116d683611117565b9050600081141561173157600067ffffffffffffffff811180156116f957600080fd5b506040519080825280602002602001820160405280156117285781602001602082028036833780820191505090505b509150506117bd565b60008167ffffffffffffffff8111801561174a57600080fd5b506040519080825280602002602001820160405280156117795781602001602082028036833780820191505090505b50905060005b828110156117b6576117918582610c48565b82828151811061179d57fe5b602002602001018181525050808060010191505061177f565b8193505050505b919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060078054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156118845780601f1061185957610100808354040283529160200191611884565b820191906000526020600020905b81548152906001019060200180831161186757829003601f168201915b5050505050905090565b600c8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156119245780601f106118f957610100808354040283529160200191611924565b820191906000526020600020905b81548152906001019060200180831161190757829003601f168201915b505050505081565b61193461225f565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156119a2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611999906147e3565b60405180910390fd5b80600560006119af61225f565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611a5c61225f565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611aa191906146ab565b60405180910390a35050565b600381565b611ac3611abd61225f565b83612335565b611b02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611af990614a63565b60405180910390fd5b611b0e8484848461282a565b50505050565b6060611b1f82612242565b611b5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b55906149e3565b60405180910390fd5b6000600860008481526020019081526020016000208054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611c075780601f10611bdc57610100808354040283529160200191611c07565b820191906000526020600020905b815481529060010190602001808311611bea57829003601f168201915b505050505090506000611c18611075565b9050600081511415611c2e578192505050611c92565b600082511115611c63578082604051602001611c4b9291906145fe565b60405160208183030381529060405292505050611c92565b80611c6d85612886565b604051602001611c7e9291906145fe565b604051602081830303815290604052925050505b919050565b61138881565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b601060009054906101000a900460ff1681565b611d4c61225f565b73ffffffffffffffffffffffffffffffffffffffff16611d6a6117c2565b73ffffffffffffffffffffffffffffffffffffffff1614611dc0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611db790614983565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611e30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e2790614743565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b601060009054906101000a900460ff16611f3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3690614aa3565b60405180910390fd5b611f48336129cd565b15611f88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f7f90614ac3565b60405180910390fd5b600081118015611f99575060038111155b611fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fcf90614a43565b60405180910390fd5b611ff28166470de4df8200006129e090919063ffffffff16565b3414612033576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202a90614803565b60405180910390fd5b600361208782601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546126be90919063ffffffff16565b11156120c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120bf906148a3565b60405180910390fd5b60005b8181101561223e576113886120de610bd1565b1015612190576120f5336120f0610bd1565b6127bc565b6121486001601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546126be90919063ffffffff16565b601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612231565b601060009054906101000a900460ff1615601060006101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff166108fc61220066470de4df8200006121f285876127da90919063ffffffff16565b6129e090919063ffffffff16565b9081150290604051600060405180830381858888f1935050505015801561222b573d6000803e3d6000fd5b5061223e565b80806001019150506120cb565b5050565b6000612258826002612a5090919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166122da83610fa0565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061232e82600001612a6a565b9050919050565b600061234082612242565b61237f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161237690614863565b60405180910390fd5b600061238a83610fa0565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806123f957508373ffffffffffffffffffffffffffffffffffffffff166123e184610993565b73ffffffffffffffffffffffffffffffffffffffff16145b8061240a57506124098185611c9d565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661243382610fa0565b73ffffffffffffffffffffffffffffffffffffffff1614612489576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612480906149c3565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156124f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124f0906147c3565b60405180910390fd5b612504838383612a7b565b61250f600082612267565b61256081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612a8090919063ffffffff16565b506125b281600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612a9a90919063ffffffff16565b506125c981836002612ab49092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006126398360000183612ae9565b60001c905092915050565b6000806000806126578660000186612b56565b915091508160001c8160001c9350935050509250929050565b80600990805190602001906126869291906133e8565b5050565b600061269d846000018460001b84612bd9565b60001c90509392505050565b60006126b782600001612c6a565b9050919050565b600080828401905083811015612709576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161270090614783565b60405180910390fd5b8091505092915050565b60008082905060005b85518110156127ae57600086828151811061273357fe5b602002602001015190508083116127745782816040516020016127579291906145bb565b6040516020818303038152906040528051906020012092506127a0565b80836040516020016127879291906145bb565b6040516020818303038152906040528051906020012092505b50808060010191505061271c565b508381149150509392505050565b6127d6828260405180602001604052806000815250612c7b565b5050565b60008282111561281f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161281690614823565b60405180910390fd5b818303905092915050565b612835848484612413565b61284184848484612cd6565b612880576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161287790614723565b60405180910390fd5b50505050565b606060008214156128ce576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506129c8565b600082905060005b600082146128f8578080600101915050600a82816128f057fe5b0491506128d6565b60008167ffffffffffffffff8111801561291157600080fd5b506040519080825280601f01601f1916602001820160405280156129445781602001600182028036833780820191505090505b50905060006001830390508593505b600084146129c057600a848161296557fe5b0660300160f81b8282806001900393508151811061297f57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a84816129b857fe5b049350612953565b819450505050505b919050565b600080823b905060008111915050919050565b6000808314156129f35760009050612a4a565b6000828402905082848281612a0457fe5b0414612a45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a3c90614943565b60405180910390fd5b809150505b92915050565b6000612a62836000018360001b612e3a565b905092915050565b600081600001805490509050919050565b505050565b6000612a92836000018360001b612e5d565b905092915050565b6000612aac836000018360001b612f45565b905092915050565b6000612ae0846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612fb5565b90509392505050565b600081836000018054905011612b34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b2b90614703565b60405180910390fd5b826000018281548110612b4357fe5b9060005260206000200154905092915050565b60008082846000018054905011612ba2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b9990614903565b60405180910390fd5b6000846000018481548110612bb357fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008084600101600085815260200190815260200160002054905060008114158390612c3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c3291906146e1565b60405180910390fd5b50846000016001820381548110612c4e57fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b612c858383613091565b612c926000848484612cd6565b612cd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cc890614723565b60405180910390fd5b505050565b6000612cf78473ffffffffffffffffffffffffffffffffffffffff1661321f565b612d045760019050612e32565b6000612dcb63150b7a0260e01b612d1961225f565b888787604051602401612d2f949392919061463d565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051806060016040528060328152602001614dca603291398773ffffffffffffffffffffffffffffffffffffffff166132329092919063ffffffff16565b9050600081806020019051810190612de39190613869565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612f395760006001820390506000600186600001805490500390506000866000018281548110612ea857fe5b9060005260206000200154905080876000018481548110612ec557fe5b9060005260206000200181905550600183018760010160008381526020019081526020016000208190555086600001805480612efd57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050612f3f565b60009150505b92915050565b6000612f51838361324a565b612faa578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612faf565b600090505b92915050565b600080846001016000858152602001908152602001600020549050600081141561305c5784600001604051806040016040528086815260200185815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000155602082015181600101555050846000018054905085600101600086815260200190815260200160002081905550600191505061308a565b8285600001600183038154811061306f57fe5b90600052602060002090600202016001018190555060009150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613101576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130f890614923565b60405180910390fd5b61310a81612242565b1561314a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161314190614763565b60405180910390fd5b61315660008383612a7b565b6131a781600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612a9a90919063ffffffff16565b506131be81836002612ab49092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b6060613241848460008561326d565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b6060824710156132b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132a990614843565b60405180910390fd5b6132bb8561321f565b6132fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132f190614a83565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161332391906145e7565b60006040518083038185875af1925050503d8060008114613360576040519150601f19603f3d011682016040523d82523d6000602084013e613365565b606091505b5091509150613375828286613381565b92505050949350505050565b60608315613391578290506133e1565b6000835111156133a45782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133d891906146e1565b60405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261341e5760008555613465565b82601f1061343757805160ff1916838001178555613465565b82800160010185558215613465579182015b82811115613464578251825591602001919060010190613449565b5b5090506134729190613476565b5090565b5b8082111561348f576000816000905550600101613477565b5090565b60006134a66134a184614b4f565b614b1e565b9050828152602081018484840111156134be57600080fd5b6134c9848285614cc6565b509392505050565b60006134e46134df84614b7f565b614b1e565b9050828152602081018484840111156134fc57600080fd5b613507848285614cc6565b509392505050565b60008135905061351e81614d56565b92915050565b60008083601f84011261353657600080fd5b8235905067ffffffffffffffff81111561354f57600080fd5b60208301915083602082028301111561356757600080fd5b9250929050565b60008135905061357d81614d6d565b92915050565b60008135905061359281614d84565b92915050565b6000813590506135a781614d9b565b92915050565b6000815190506135bc81614d9b565b92915050565b600082601f8301126135d357600080fd5b81356135e3848260208601613493565b91505092915050565b600082601f8301126135fd57600080fd5b813561360d8482602086016134d1565b91505092915050565b60008135905061362581614db2565b92915050565b60006020828403121561363d57600080fd5b600061364b8482850161350f565b91505092915050565b6000806040838503121561366757600080fd5b60006136758582860161350f565b92505060206136868582860161350f565b9150509250929050565b6000806000606084860312156136a557600080fd5b60006136b38682870161350f565b93505060206136c48682870161350f565b92505060406136d586828701613616565b9150509250925092565b600080600080608085870312156136f557600080fd5b60006137038782880161350f565b94505060206137148782880161350f565b935050604061372587828801613616565b925050606085013567ffffffffffffffff81111561374257600080fd5b61374e878288016135c2565b91505092959194509250565b6000806040838503121561376d57600080fd5b600061377b8582860161350f565b925050602061378c8582860161356e565b9150509250929050565b600080604083850312156137a957600080fd5b60006137b78582860161350f565b92505060206137c885828601613616565b9150509250929050565b600080602083850312156137e557600080fd5b600083013567ffffffffffffffff8111156137ff57600080fd5b61380b85828601613524565b92509250509250929050565b60006020828403121561382957600080fd5b600061383784828501613583565b91505092915050565b60006020828403121561385257600080fd5b600061386084828501613598565b91505092915050565b60006020828403121561387b57600080fd5b6000613889848285016135ad565b91505092915050565b6000602082840312156138a457600080fd5b600082013567ffffffffffffffff8111156138be57600080fd5b6138ca848285016135ec565b91505092915050565b6000602082840312156138e557600080fd5b60006138f384828501613616565b91505092915050565b60006139088383614582565b60208301905092915050565b61391d81614c48565b82525050565b61392c81614c36565b82525050565b61394361393e82614c36565b614d08565b82525050565b600061395482614bbf565b61395e8185614bed565b935061396983614baf565b8060005b8381101561399a57815161398188826138fc565b975061398c83614be0565b92505060018101905061396d565b5085935050505092915050565b6139b081614c5a565b82525050565b6139bf81614c66565b82525050565b6139d66139d182614c66565b614d1a565b82525050565b60006139e782614bca565b6139f18185614bfe565b9350613a01818560208601614cd5565b613a0a81614d38565b840191505092915050565b6000613a2082614bca565b613a2a8185614c0f565b9350613a3a818560208601614cd5565b80840191505092915050565b6000613a5182614bd5565b613a5b8185614c1a565b9350613a6b818560208601614cd5565b613a7481614d38565b840191505092915050565b6000613a8a82614bd5565b613a948185614c2b565b9350613aa4818560208601614cd5565b80840191505092915050565b6000613abd602283614c1a565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613b23603283614c1a565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b6000613b89602683614c1a565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613bef601c83614c1a565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b6000613c2f601b83614c1a565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b6000613c6f602783614c1a565b91507f4d696e7420776f756c6420657863656564206d617820737570706c79206f662060008301527f43757063617473000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613cd5602483614c1a565b91507f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613d3b601983614c1a565b91507f4552433732313a20617070726f766520746f2063616c6c6572000000000000006000830152602082019050919050565b6000613d7b601f83614c1a565b91507f45746865722076616c75652073656e74206973206e6f7420636f7272656374006000830152602082019050919050565b6000613dbb601e83614c1a565b91507f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006000830152602082019050919050565b6000613dfb602683614c1a565b91507f416464726573733a20696e73756666696369656e742062616c616e636520666f60008301527f722063616c6c00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613e61602c83614c1a565b91507f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613ec7602383614c1a565b91507f45786163746c7920302e303220455448206973206e656564656420666f72206d60008301527f696e7400000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613f2d601e83614c1a565b91507f4d61782033206d696e7473207065722077616c6c657420616c6c6f77656400006000830152602082019050919050565b6000613f6d603883614c1a565b91507f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008301527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006020830152604082019050919050565b6000613fd3602a83614c1a565b91507f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008301527f726f2061646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b6000614039602283614c1a565b91507f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061409f602083614c1a565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b60006140df602183614c1a565b91507f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60008301527f77000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614145602c83614c1a565b91507f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b60006141ab602083614c1a565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b60006141eb602483614c1a565b91507f416c726561647920436c61696d6564207468652077686974656c69737465642060008301527f6d696e74000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614251602983614c1a565b91507f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008301527f73206e6f74206f776e00000000000000000000000000000000000000000000006020830152604082019050919050565b60006142b7602f83614c1a565b91507f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008301527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006020830152604082019050919050565b600061431d601283614c1a565b91507f4e6f7420656e6f756768207265736572766500000000000000000000000000006000830152602082019050919050565b600061435d602183614c1a565b91507f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006143c3602083614c1a565b91507f43616e206f6e6c79206d696e74203320746f6b656e7320617420612074696d656000830152602082019050919050565b6000614403603183614c1a565b91507f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008301527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020830152604082019050919050565b6000614469601d83614c1a565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b60006144a9602283614c1a565b91507f53616c65206d7573742062652061637469766520746f206d696e74204375706360008301527f61740000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061450f601d83614c1a565b91507f4d696e742076696120636f6e7472616374206e6f7420616c6c6f7765640000006000830152602082019050919050565b600061454f600d83614c1a565b91507f496e76616c69642070726f6f66000000000000000000000000000000000000006000830152602082019050919050565b61458b81614cbc565b82525050565b61459a81614cbc565b82525050565b60006145ac8284613932565b60148201915081905092915050565b60006145c782856139c5565b6020820191506145d782846139c5565b6020820191508190509392505050565b60006145f38284613a15565b915081905092915050565b600061460a8285613a7f565b91506146168284613a7f565b91508190509392505050565b60006020820190506146376000830184613923565b92915050565b60006080820190506146526000830187613914565b61465f6020830186613923565b61466c6040830185614591565b818103606083015261467e81846139dc565b905095945050505050565b600060208201905081810360008301526146a38184613949565b905092915050565b60006020820190506146c060008301846139a7565b92915050565b60006020820190506146db60008301846139b6565b92915050565b600060208201905081810360008301526146fb8184613a46565b905092915050565b6000602082019050818103600083015261471c81613ab0565b9050919050565b6000602082019050818103600083015261473c81613b16565b9050919050565b6000602082019050818103600083015261475c81613b7c565b9050919050565b6000602082019050818103600083015261477c81613be2565b9050919050565b6000602082019050818103600083015261479c81613c22565b9050919050565b600060208201905081810360008301526147bc81613c62565b9050919050565b600060208201905081810360008301526147dc81613cc8565b9050919050565b600060208201905081810360008301526147fc81613d2e565b9050919050565b6000602082019050818103600083015261481c81613d6e565b9050919050565b6000602082019050818103600083015261483c81613dae565b9050919050565b6000602082019050818103600083015261485c81613dee565b9050919050565b6000602082019050818103600083015261487c81613e54565b9050919050565b6000602082019050818103600083015261489c81613eba565b9050919050565b600060208201905081810360008301526148bc81613f20565b9050919050565b600060208201905081810360008301526148dc81613f60565b9050919050565b600060208201905081810360008301526148fc81613fc6565b9050919050565b6000602082019050818103600083015261491c8161402c565b9050919050565b6000602082019050818103600083015261493c81614092565b9050919050565b6000602082019050818103600083015261495c816140d2565b9050919050565b6000602082019050818103600083015261497c81614138565b9050919050565b6000602082019050818103600083015261499c8161419e565b9050919050565b600060208201905081810360008301526149bc816141de565b9050919050565b600060208201905081810360008301526149dc81614244565b9050919050565b600060208201905081810360008301526149fc816142aa565b9050919050565b60006020820190508181036000830152614a1c81614310565b9050919050565b60006020820190508181036000830152614a3c81614350565b9050919050565b60006020820190508181036000830152614a5c816143b6565b9050919050565b60006020820190508181036000830152614a7c816143f6565b9050919050565b60006020820190508181036000830152614a9c8161445c565b9050919050565b60006020820190508181036000830152614abc8161449c565b9050919050565b60006020820190508181036000830152614adc81614502565b9050919050565b60006020820190508181036000830152614afc81614542565b9050919050565b6000602082019050614b186000830184614591565b92915050565b6000604051905081810181811067ffffffffffffffff82111715614b4557614b44614d36565b5b8060405250919050565b600067ffffffffffffffff821115614b6a57614b69614d36565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115614b9a57614b99614d36565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000614c4182614c9c565b9050919050565b6000614c5382614c9c565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015614cf3578082015181840152602081019050614cd8565b83811115614d02576000848401525b50505050565b6000614d1382614d24565b9050919050565b6000819050919050565b6000614d2f82614d49565b9050919050565bfe5b6000601f19601f8301169050919050565b60008160601b9050919050565b614d5f81614c36565b8114614d6a57600080fd5b50565b614d7681614c5a565b8114614d8157600080fd5b50565b614d8d81614c66565b8114614d9857600080fd5b50565b614da481614c70565b8114614daf57600080fd5b50565b614dbb81614cbc565b8114614dc657600080fd5b5056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea26469706673582212201eeb8ee7963b104f3656793967c2f4d6c64d48d1140a7dfbb2631fd9f9d41f3c64736f6c63430007060033

Deployed Bytecode

0x60806040526004361061021a5760003560e01c80636c0360eb116101235780639c3e72bd116100ab578063e27441ca1161006f578063e27441ca146107b2578063e985e9c5146107dd578063eb8d24441461081a578063f2fde38b14610845578063f647a45a1461086e5761021a565b80639c3e72bd146106cd578063a22cb465146106f8578063af6ed0f914610721578063b88d4fde1461074c578063c87b56dd146107755761021a565b80637ed81d93116100f25780637ed81d93146105f557806380f85473146106115780638462151c1461063a5780638da5cb5b1461067757806395d89b41146106a25761021a565b80636c0360eb1461054b57806370a0823114610576578063715018a6146105b3578063738bb60e146105ca5761021a565b80632f745c59116101a65780634783f0ef116101755780634783f0ef146104545780634f6ccce71461047d57806355f804b3146104ba5780636352211e146104e35780636566a8d6146105205761021a565b80632f745c59146103c057806334918dfd146103fd5780633ccfd60b1461041457806342842e0e1461042b5761021a565b80630ce75937116101ed5780630ce75937146102ed578063109695231461031857806318160ddd1461034157806323b872dd1461036c5780632eb4a7ab146103955761021a565b806301ffc9a71461021f57806306fdde031461025c578063081812fc14610287578063095ea7b3146102c4575b600080fd5b34801561022b57600080fd5b5061024660048036038101906102419190613840565b61088a565b60405161025391906146ab565b60405180910390f35b34801561026857600080fd5b506102716108f1565b60405161027e91906146e1565b60405180910390f35b34801561029357600080fd5b506102ae60048036038101906102a991906138d3565b610993565b6040516102bb9190614622565b60405180910390f35b3480156102d057600080fd5b506102eb60048036038101906102e69190613796565b610a18565b005b3480156102f957600080fd5b50610302610b30565b60405161030f9190614b03565b60405180910390f35b34801561032457600080fd5b5061033f600480360381019061033a9190613892565b610b3b565b005b34801561034d57600080fd5b50610356610bd1565b6040516103639190614b03565b60405180910390f35b34801561037857600080fd5b50610393600480360381019061038e9190613690565b610be2565b005b3480156103a157600080fd5b506103aa610c42565b6040516103b791906146c6565b60405180910390f35b3480156103cc57600080fd5b506103e760048036038101906103e29190613796565b610c48565b6040516103f49190614b03565b60405180910390f35b34801561040957600080fd5b50610412610ca3565b005b34801561042057600080fd5b50610429610d4b565b005b34801561043757600080fd5b50610452600480360381019061044d9190613690565b610e16565b005b34801561046057600080fd5b5061047b60048036038101906104769190613817565b610e36565b005b34801561048957600080fd5b506104a4600480360381019061049f91906138d3565b610ef5565b6040516104b19190614b03565b60405180910390f35b3480156104c657600080fd5b506104e160048036038101906104dc9190613892565b610f18565b005b3480156104ef57600080fd5b5061050a600480360381019061050591906138d3565b610fa0565b6040516105179190614622565b60405180910390f35b34801561052c57600080fd5b50610535610fd7565b60405161054291906146e1565b60405180910390f35b34801561055757600080fd5b50610560611075565b60405161056d91906146e1565b60405180910390f35b34801561058257600080fd5b5061059d6004803603810190610598919061362b565b611117565b6040516105aa9190614b03565b60405180910390f35b3480156105bf57600080fd5b506105c86111d6565b005b3480156105d657600080fd5b506105df611313565b6040516105ec9190614b03565b60405180910390f35b61060f600480360381019061060a91906137d2565b611319565b005b34801561061d57600080fd5b5061063860048036038101906106339190613796565b6115ab565b005b34801561064657600080fd5b50610661600480360381019061065c919061362b565b6116c9565b60405161066e9190614689565b60405180910390f35b34801561068357600080fd5b5061068c6117c2565b6040516106999190614622565b60405180910390f35b3480156106ae57600080fd5b506106b76117ec565b6040516106c491906146e1565b60405180910390f35b3480156106d957600080fd5b506106e261188e565b6040516106ef91906146e1565b60405180910390f35b34801561070457600080fd5b5061071f600480360381019061071a919061375a565b61192c565b005b34801561072d57600080fd5b50610736611aad565b6040516107439190614b03565b60405180910390f35b34801561075857600080fd5b50610773600480360381019061076e91906136df565b611ab2565b005b34801561078157600080fd5b5061079c600480360381019061079791906138d3565b611b14565b6040516107a991906146e1565b60405180910390f35b3480156107be57600080fd5b506107c7611c97565b6040516107d49190614b03565b60405180910390f35b3480156107e957600080fd5b5061080460048036038101906107ff9190613654565b611c9d565b60405161081191906146ab565b60405180910390f35b34801561082657600080fd5b5061082f611d31565b60405161083c91906146ab565b60405180910390f35b34801561085157600080fd5b5061086c6004803603810190610867919061362b565b611d44565b005b610888600480360381019061088391906138d3565b611ef0565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109895780601f1061095e57610100808354040283529160200191610989565b820191906000526020600020905b81548152906001019060200180831161096c57829003601f168201915b5050505050905090565b600061099e82612242565b6109dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d490614963565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a2382610fa0565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610a94576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8b90614a23565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610ab361225f565b73ffffffffffffffffffffffffffffffffffffffff161480610ae25750610ae181610adc61225f565b611c9d565b5b610b21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b18906148c3565b60405180910390fd5b610b2b8383612267565b505050565b66470de4df82000081565b610b4361225f565b73ffffffffffffffffffffffffffffffffffffffff16610b616117c2565b73ffffffffffffffffffffffffffffffffffffffff1614610bb7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bae90614983565b60405180910390fd5b80600b9080519060200190610bcd9291906133e8565b5050565b6000610bdd6002612320565b905090565b610bf3610bed61225f565b82612335565b610c32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2990614a63565b60405180910390fd5b610c3d838383612413565b505050565b600e5481565b6000610c9b82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061262a90919063ffffffff16565b905092915050565b610cab61225f565b73ffffffffffffffffffffffffffffffffffffffff16610cc96117c2565b73ffffffffffffffffffffffffffffffffffffffff1614610d1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1690614983565b60405180910390fd5b601060009054906101000a900460ff1615601060006101000a81548160ff021916908315150217905550565b610d5361225f565b73ffffffffffffffffffffffffffffffffffffffff16610d716117c2565b73ffffffffffffffffffffffffffffffffffffffff1614610dc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dbe90614983565b60405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610e12573d6000803e3d6000fd5b5050565b610e3183838360405180602001604052806000815250611ab2565b505050565b610e3e61225f565b73ffffffffffffffffffffffffffffffffffffffff16610e5c6117c2565b73ffffffffffffffffffffffffffffffffffffffff1614610eb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea990614983565b60405180910390fd5b80600e819055507f90004c04698bc3322499a575ed3752dd4abf33e0a7294c06a787a0fe01bea941600e54604051610eea91906146c6565b60405180910390a150565b600080610f0c83600261264490919063ffffffff16565b50905080915050919050565b610f2061225f565b73ffffffffffffffffffffffffffffffffffffffff16610f3e6117c2565b73ffffffffffffffffffffffffffffffffffffffff1614610f94576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8b90614983565b60405180910390fd5b610f9d81612670565b50565b6000610fd082604051806060016040528060298152602001614dfc60299139600261268a9092919063ffffffff16565b9050919050565b600b8054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561106d5780601f106110425761010080835404028352916020019161106d565b820191906000526020600020905b81548152906001019060200180831161105057829003601f168201915b505050505081565b606060098054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561110d5780601f106110e25761010080835404028352916020019161110d565b820191906000526020600020905b8154815290600101906020018083116110f057829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117f906148e3565b60405180910390fd5b6111cf600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206126a9565b9050919050565b6111de61225f565b73ffffffffffffffffffffffffffffffffffffffff166111fc6117c2565b73ffffffffffffffffffffffffffffffffffffffff1614611252576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124990614983565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600f5481565b600033905066470de4df8200003414611367576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135e90614883565b60405180910390fd5b6113886113856001611377610bd1565b6126be90919063ffffffff16565b11156113c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113bd906147a3565b60405180910390fd5b601160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144a906149a3565b60405180910390fd5b6114c7838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600e54836040516020016114ac91906145a0565b60405160208183030381529060405280519060200120612713565b611506576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114fd90614ae3565b60405180910390fd5b6001601160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061156f8161156a610bd1565b6127bc565b7f67c400238edbf2cfe078e9c46b03af4a14f535dafde7829c4ebd8ffc76448bee8160405161159e9190614622565b60405180910390a1505050565b6115b361225f565b73ffffffffffffffffffffffffffffffffffffffff166115d16117c2565b73ffffffffffffffffffffffffffffffffffffffff1614611627576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161e90614983565b60405180910390fd5b6000611631610bd1565b90506000821180156116455750600f548211155b611684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167b90614a03565b60405180910390fd5b60005b828110156116a85761169b848284016127bc565b8080600101915050611687565b506116be82600f546127da90919063ffffffff16565b600f81905550505050565b606060006116d683611117565b9050600081141561173157600067ffffffffffffffff811180156116f957600080fd5b506040519080825280602002602001820160405280156117285781602001602082028036833780820191505090505b509150506117bd565b60008167ffffffffffffffff8111801561174a57600080fd5b506040519080825280602002602001820160405280156117795781602001602082028036833780820191505090505b50905060005b828110156117b6576117918582610c48565b82828151811061179d57fe5b602002602001018181525050808060010191505061177f565b8193505050505b919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060078054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156118845780601f1061185957610100808354040283529160200191611884565b820191906000526020600020905b81548152906001019060200180831161186757829003601f168201915b5050505050905090565b600c8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156119245780601f106118f957610100808354040283529160200191611924565b820191906000526020600020905b81548152906001019060200180831161190757829003601f168201915b505050505081565b61193461225f565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156119a2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611999906147e3565b60405180910390fd5b80600560006119af61225f565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611a5c61225f565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611aa191906146ab565b60405180910390a35050565b600381565b611ac3611abd61225f565b83612335565b611b02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611af990614a63565b60405180910390fd5b611b0e8484848461282a565b50505050565b6060611b1f82612242565b611b5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b55906149e3565b60405180910390fd5b6000600860008481526020019081526020016000208054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611c075780601f10611bdc57610100808354040283529160200191611c07565b820191906000526020600020905b815481529060010190602001808311611bea57829003601f168201915b505050505090506000611c18611075565b9050600081511415611c2e578192505050611c92565b600082511115611c63578082604051602001611c4b9291906145fe565b60405160208183030381529060405292505050611c92565b80611c6d85612886565b604051602001611c7e9291906145fe565b604051602081830303815290604052925050505b919050565b61138881565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b601060009054906101000a900460ff1681565b611d4c61225f565b73ffffffffffffffffffffffffffffffffffffffff16611d6a6117c2565b73ffffffffffffffffffffffffffffffffffffffff1614611dc0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611db790614983565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611e30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e2790614743565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b601060009054906101000a900460ff16611f3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3690614aa3565b60405180910390fd5b611f48336129cd565b15611f88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f7f90614ac3565b60405180910390fd5b600081118015611f99575060038111155b611fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fcf90614a43565b60405180910390fd5b611ff28166470de4df8200006129e090919063ffffffff16565b3414612033576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202a90614803565b60405180910390fd5b600361208782601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546126be90919063ffffffff16565b11156120c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120bf906148a3565b60405180910390fd5b60005b8181101561223e576113886120de610bd1565b1015612190576120f5336120f0610bd1565b6127bc565b6121486001601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546126be90919063ffffffff16565b601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612231565b601060009054906101000a900460ff1615601060006101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff166108fc61220066470de4df8200006121f285876127da90919063ffffffff16565b6129e090919063ffffffff16565b9081150290604051600060405180830381858888f1935050505015801561222b573d6000803e3d6000fd5b5061223e565b80806001019150506120cb565b5050565b6000612258826002612a5090919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166122da83610fa0565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061232e82600001612a6a565b9050919050565b600061234082612242565b61237f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161237690614863565b60405180910390fd5b600061238a83610fa0565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806123f957508373ffffffffffffffffffffffffffffffffffffffff166123e184610993565b73ffffffffffffffffffffffffffffffffffffffff16145b8061240a57506124098185611c9d565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661243382610fa0565b73ffffffffffffffffffffffffffffffffffffffff1614612489576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612480906149c3565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156124f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124f0906147c3565b60405180910390fd5b612504838383612a7b565b61250f600082612267565b61256081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612a8090919063ffffffff16565b506125b281600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612a9a90919063ffffffff16565b506125c981836002612ab49092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006126398360000183612ae9565b60001c905092915050565b6000806000806126578660000186612b56565b915091508160001c8160001c9350935050509250929050565b80600990805190602001906126869291906133e8565b5050565b600061269d846000018460001b84612bd9565b60001c90509392505050565b60006126b782600001612c6a565b9050919050565b600080828401905083811015612709576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161270090614783565b60405180910390fd5b8091505092915050565b60008082905060005b85518110156127ae57600086828151811061273357fe5b602002602001015190508083116127745782816040516020016127579291906145bb565b6040516020818303038152906040528051906020012092506127a0565b80836040516020016127879291906145bb565b6040516020818303038152906040528051906020012092505b50808060010191505061271c565b508381149150509392505050565b6127d6828260405180602001604052806000815250612c7b565b5050565b60008282111561281f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161281690614823565b60405180910390fd5b818303905092915050565b612835848484612413565b61284184848484612cd6565b612880576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161287790614723565b60405180910390fd5b50505050565b606060008214156128ce576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506129c8565b600082905060005b600082146128f8578080600101915050600a82816128f057fe5b0491506128d6565b60008167ffffffffffffffff8111801561291157600080fd5b506040519080825280601f01601f1916602001820160405280156129445781602001600182028036833780820191505090505b50905060006001830390508593505b600084146129c057600a848161296557fe5b0660300160f81b8282806001900393508151811061297f57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a84816129b857fe5b049350612953565b819450505050505b919050565b600080823b905060008111915050919050565b6000808314156129f35760009050612a4a565b6000828402905082848281612a0457fe5b0414612a45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a3c90614943565b60405180910390fd5b809150505b92915050565b6000612a62836000018360001b612e3a565b905092915050565b600081600001805490509050919050565b505050565b6000612a92836000018360001b612e5d565b905092915050565b6000612aac836000018360001b612f45565b905092915050565b6000612ae0846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612fb5565b90509392505050565b600081836000018054905011612b34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b2b90614703565b60405180910390fd5b826000018281548110612b4357fe5b9060005260206000200154905092915050565b60008082846000018054905011612ba2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b9990614903565b60405180910390fd5b6000846000018481548110612bb357fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008084600101600085815260200190815260200160002054905060008114158390612c3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c3291906146e1565b60405180910390fd5b50846000016001820381548110612c4e57fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b612c858383613091565b612c926000848484612cd6565b612cd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cc890614723565b60405180910390fd5b505050565b6000612cf78473ffffffffffffffffffffffffffffffffffffffff1661321f565b612d045760019050612e32565b6000612dcb63150b7a0260e01b612d1961225f565b888787604051602401612d2f949392919061463d565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051806060016040528060328152602001614dca603291398773ffffffffffffffffffffffffffffffffffffffff166132329092919063ffffffff16565b9050600081806020019051810190612de39190613869565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612f395760006001820390506000600186600001805490500390506000866000018281548110612ea857fe5b9060005260206000200154905080876000018481548110612ec557fe5b9060005260206000200181905550600183018760010160008381526020019081526020016000208190555086600001805480612efd57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050612f3f565b60009150505b92915050565b6000612f51838361324a565b612faa578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612faf565b600090505b92915050565b600080846001016000858152602001908152602001600020549050600081141561305c5784600001604051806040016040528086815260200185815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000155602082015181600101555050846000018054905085600101600086815260200190815260200160002081905550600191505061308a565b8285600001600183038154811061306f57fe5b90600052602060002090600202016001018190555060009150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613101576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130f890614923565b60405180910390fd5b61310a81612242565b1561314a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161314190614763565b60405180910390fd5b61315660008383612a7b565b6131a781600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612a9a90919063ffffffff16565b506131be81836002612ab49092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b6060613241848460008561326d565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b6060824710156132b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132a990614843565b60405180910390fd5b6132bb8561321f565b6132fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132f190614a83565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161332391906145e7565b60006040518083038185875af1925050503d8060008114613360576040519150601f19603f3d011682016040523d82523d6000602084013e613365565b606091505b5091509150613375828286613381565b92505050949350505050565b60608315613391578290506133e1565b6000835111156133a45782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133d891906146e1565b60405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261341e5760008555613465565b82601f1061343757805160ff1916838001178555613465565b82800160010185558215613465579182015b82811115613464578251825591602001919060010190613449565b5b5090506134729190613476565b5090565b5b8082111561348f576000816000905550600101613477565b5090565b60006134a66134a184614b4f565b614b1e565b9050828152602081018484840111156134be57600080fd5b6134c9848285614cc6565b509392505050565b60006134e46134df84614b7f565b614b1e565b9050828152602081018484840111156134fc57600080fd5b613507848285614cc6565b509392505050565b60008135905061351e81614d56565b92915050565b60008083601f84011261353657600080fd5b8235905067ffffffffffffffff81111561354f57600080fd5b60208301915083602082028301111561356757600080fd5b9250929050565b60008135905061357d81614d6d565b92915050565b60008135905061359281614d84565b92915050565b6000813590506135a781614d9b565b92915050565b6000815190506135bc81614d9b565b92915050565b600082601f8301126135d357600080fd5b81356135e3848260208601613493565b91505092915050565b600082601f8301126135fd57600080fd5b813561360d8482602086016134d1565b91505092915050565b60008135905061362581614db2565b92915050565b60006020828403121561363d57600080fd5b600061364b8482850161350f565b91505092915050565b6000806040838503121561366757600080fd5b60006136758582860161350f565b92505060206136868582860161350f565b9150509250929050565b6000806000606084860312156136a557600080fd5b60006136b38682870161350f565b93505060206136c48682870161350f565b92505060406136d586828701613616565b9150509250925092565b600080600080608085870312156136f557600080fd5b60006137038782880161350f565b94505060206137148782880161350f565b935050604061372587828801613616565b925050606085013567ffffffffffffffff81111561374257600080fd5b61374e878288016135c2565b91505092959194509250565b6000806040838503121561376d57600080fd5b600061377b8582860161350f565b925050602061378c8582860161356e565b9150509250929050565b600080604083850312156137a957600080fd5b60006137b78582860161350f565b92505060206137c885828601613616565b9150509250929050565b600080602083850312156137e557600080fd5b600083013567ffffffffffffffff8111156137ff57600080fd5b61380b85828601613524565b92509250509250929050565b60006020828403121561382957600080fd5b600061383784828501613583565b91505092915050565b60006020828403121561385257600080fd5b600061386084828501613598565b91505092915050565b60006020828403121561387b57600080fd5b6000613889848285016135ad565b91505092915050565b6000602082840312156138a457600080fd5b600082013567ffffffffffffffff8111156138be57600080fd5b6138ca848285016135ec565b91505092915050565b6000602082840312156138e557600080fd5b60006138f384828501613616565b91505092915050565b60006139088383614582565b60208301905092915050565b61391d81614c48565b82525050565b61392c81614c36565b82525050565b61394361393e82614c36565b614d08565b82525050565b600061395482614bbf565b61395e8185614bed565b935061396983614baf565b8060005b8381101561399a57815161398188826138fc565b975061398c83614be0565b92505060018101905061396d565b5085935050505092915050565b6139b081614c5a565b82525050565b6139bf81614c66565b82525050565b6139d66139d182614c66565b614d1a565b82525050565b60006139e782614bca565b6139f18185614bfe565b9350613a01818560208601614cd5565b613a0a81614d38565b840191505092915050565b6000613a2082614bca565b613a2a8185614c0f565b9350613a3a818560208601614cd5565b80840191505092915050565b6000613a5182614bd5565b613a5b8185614c1a565b9350613a6b818560208601614cd5565b613a7481614d38565b840191505092915050565b6000613a8a82614bd5565b613a948185614c2b565b9350613aa4818560208601614cd5565b80840191505092915050565b6000613abd602283614c1a565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613b23603283614c1a565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b6000613b89602683614c1a565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613bef601c83614c1a565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b6000613c2f601b83614c1a565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b6000613c6f602783614c1a565b91507f4d696e7420776f756c6420657863656564206d617820737570706c79206f662060008301527f43757063617473000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613cd5602483614c1a565b91507f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613d3b601983614c1a565b91507f4552433732313a20617070726f766520746f2063616c6c6572000000000000006000830152602082019050919050565b6000613d7b601f83614c1a565b91507f45746865722076616c75652073656e74206973206e6f7420636f7272656374006000830152602082019050919050565b6000613dbb601e83614c1a565b91507f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006000830152602082019050919050565b6000613dfb602683614c1a565b91507f416464726573733a20696e73756666696369656e742062616c616e636520666f60008301527f722063616c6c00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613e61602c83614c1a565b91507f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613ec7602383614c1a565b91507f45786163746c7920302e303220455448206973206e656564656420666f72206d60008301527f696e7400000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613f2d601e83614c1a565b91507f4d61782033206d696e7473207065722077616c6c657420616c6c6f77656400006000830152602082019050919050565b6000613f6d603883614c1a565b91507f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008301527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006020830152604082019050919050565b6000613fd3602a83614c1a565b91507f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008301527f726f2061646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b6000614039602283614c1a565b91507f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061409f602083614c1a565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b60006140df602183614c1a565b91507f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60008301527f77000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614145602c83614c1a565b91507f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b60006141ab602083614c1a565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b60006141eb602483614c1a565b91507f416c726561647920436c61696d6564207468652077686974656c69737465642060008301527f6d696e74000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614251602983614c1a565b91507f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008301527f73206e6f74206f776e00000000000000000000000000000000000000000000006020830152604082019050919050565b60006142b7602f83614c1a565b91507f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008301527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006020830152604082019050919050565b600061431d601283614c1a565b91507f4e6f7420656e6f756768207265736572766500000000000000000000000000006000830152602082019050919050565b600061435d602183614c1a565b91507f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006143c3602083614c1a565b91507f43616e206f6e6c79206d696e74203320746f6b656e7320617420612074696d656000830152602082019050919050565b6000614403603183614c1a565b91507f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008301527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020830152604082019050919050565b6000614469601d83614c1a565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b60006144a9602283614c1a565b91507f53616c65206d7573742062652061637469766520746f206d696e74204375706360008301527f61740000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061450f601d83614c1a565b91507f4d696e742076696120636f6e7472616374206e6f7420616c6c6f7765640000006000830152602082019050919050565b600061454f600d83614c1a565b91507f496e76616c69642070726f6f66000000000000000000000000000000000000006000830152602082019050919050565b61458b81614cbc565b82525050565b61459a81614cbc565b82525050565b60006145ac8284613932565b60148201915081905092915050565b60006145c782856139c5565b6020820191506145d782846139c5565b6020820191508190509392505050565b60006145f38284613a15565b915081905092915050565b600061460a8285613a7f565b91506146168284613a7f565b91508190509392505050565b60006020820190506146376000830184613923565b92915050565b60006080820190506146526000830187613914565b61465f6020830186613923565b61466c6040830185614591565b818103606083015261467e81846139dc565b905095945050505050565b600060208201905081810360008301526146a38184613949565b905092915050565b60006020820190506146c060008301846139a7565b92915050565b60006020820190506146db60008301846139b6565b92915050565b600060208201905081810360008301526146fb8184613a46565b905092915050565b6000602082019050818103600083015261471c81613ab0565b9050919050565b6000602082019050818103600083015261473c81613b16565b9050919050565b6000602082019050818103600083015261475c81613b7c565b9050919050565b6000602082019050818103600083015261477c81613be2565b9050919050565b6000602082019050818103600083015261479c81613c22565b9050919050565b600060208201905081810360008301526147bc81613c62565b9050919050565b600060208201905081810360008301526147dc81613cc8565b9050919050565b600060208201905081810360008301526147fc81613d2e565b9050919050565b6000602082019050818103600083015261481c81613d6e565b9050919050565b6000602082019050818103600083015261483c81613dae565b9050919050565b6000602082019050818103600083015261485c81613dee565b9050919050565b6000602082019050818103600083015261487c81613e54565b9050919050565b6000602082019050818103600083015261489c81613eba565b9050919050565b600060208201905081810360008301526148bc81613f20565b9050919050565b600060208201905081810360008301526148dc81613f60565b9050919050565b600060208201905081810360008301526148fc81613fc6565b9050919050565b6000602082019050818103600083015261491c8161402c565b9050919050565b6000602082019050818103600083015261493c81614092565b9050919050565b6000602082019050818103600083015261495c816140d2565b9050919050565b6000602082019050818103600083015261497c81614138565b9050919050565b6000602082019050818103600083015261499c8161419e565b9050919050565b600060208201905081810360008301526149bc816141de565b9050919050565b600060208201905081810360008301526149dc81614244565b9050919050565b600060208201905081810360008301526149fc816142aa565b9050919050565b60006020820190508181036000830152614a1c81614310565b9050919050565b60006020820190508181036000830152614a3c81614350565b9050919050565b60006020820190508181036000830152614a5c816143b6565b9050919050565b60006020820190508181036000830152614a7c816143f6565b9050919050565b60006020820190508181036000830152614a9c8161445c565b9050919050565b60006020820190508181036000830152614abc8161449c565b9050919050565b60006020820190508181036000830152614adc81614502565b9050919050565b60006020820190508181036000830152614afc81614542565b9050919050565b6000602082019050614b186000830184614591565b92915050565b6000604051905081810181811067ffffffffffffffff82111715614b4557614b44614d36565b5b8060405250919050565b600067ffffffffffffffff821115614b6a57614b69614d36565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115614b9a57614b99614d36565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000614c4182614c9c565b9050919050565b6000614c5382614c9c565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015614cf3578082015181840152602081019050614cd8565b83811115614d02576000848401525b50505050565b6000614d1382614d24565b9050919050565b6000819050919050565b6000614d2f82614d49565b9050919050565bfe5b6000601f19601f8301169050919050565b60008160601b9050919050565b614d5f81614c36565b8114614d6a57600080fd5b50565b614d7681614c5a565b8114614d8157600080fd5b50565b614d8d81614c66565b8114614d9857600080fd5b50565b614da481614c70565b8114614daf57600080fd5b50565b614dbb81614cbc565b8114614dc657600080fd5b5056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea26469706673582212201eeb8ee7963b104f3656793967c2f4d6c64d48d1140a7dfbb2631fd9f9d41f3c64736f6c63430007060033

Deployed Bytecode Sourcemap

68711:4398:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10447:150;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51732:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54518:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54048:404;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68975:55;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70040:127;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53526:211;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55408:305;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68941:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53288:162;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70284:89;;;;;;;;;;;;;:::i;:::-;;69500:131;;;;;;;;;;;;;:::i;:::-;;55784:151;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72190:158;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53814:172;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70175:99;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51488:177;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68794:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53107:97;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51205:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66443:148;;;;;;;;;;;;;:::i;:::-;;69134:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72358:748;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69639:391;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70391:540;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65792:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51901:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68837:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54811:295;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69037:42;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56006:285;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;52076:792;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69086:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55177:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69174:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66746:244;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70956:988;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;10447:150;10532:4;10556:20;:33;10577:11;10556:33;;;;;;;;;;;;;;;;;;;;;;;;;;;10549:40;;10447:150;;;:::o;51732:100::-;51786:13;51819:5;51812:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51732:100;:::o;54518:221::-;54594:7;54622:16;54630:7;54622;:16::i;:::-;54614:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;54707:15;:24;54723:7;54707:24;;;;;;;;;;;;;;;;;;;;;54700:31;;54518:221;;;:::o;54048:404::-;54129:13;54145:23;54160:7;54145:14;:23::i;:::-;54129:39;;54193:5;54187:11;;:2;:11;;;;54179:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;54273:5;54257:21;;:12;:10;:12::i;:::-;:21;;;:69;;;;54282:44;54306:5;54313:12;:10;:12::i;:::-;54282:23;:44::i;:::-;54257:69;54249:161;;;;;;;;;;;;:::i;:::-;;;;;;;;;54423:21;54432:2;54436:7;54423:8;:21::i;:::-;54048:404;;;:::o;68975:55::-;69013:17;68975:55;:::o;70040:127::-;66023:12;:10;:12::i;:::-;66012:23;;:7;:5;:7::i;:::-;:23;;;66004:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;70145:14:::1;70125:17;:34;;;;;;;;;;;;:::i;:::-;;70040:127:::0;:::o;53526:211::-;53587:7;53708:21;:12;:19;:21::i;:::-;53701:28;;53526:211;:::o;55408:305::-;55569:41;55588:12;:10;:12::i;:::-;55602:7;55569:18;:41::i;:::-;55561:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;55677:28;55687:4;55693:2;55697:7;55677:9;:28::i;:::-;55408:305;;;:::o;68941:25::-;;;;:::o;53288:162::-;53385:7;53412:30;53436:5;53412:13;:20;53426:5;53412:20;;;;;;;;;;;;;;;:23;;:30;;;;:::i;:::-;53405:37;;53288:162;;;;:::o;70284:89::-;66023:12;:10;:12::i;:::-;66012:23;;:7;:5;:7::i;:::-;:23;;;66004:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;70353:12:::1;;;;;;;;;;;70352:13;70337:12;;:28;;;;;;;;;;;;;;;;;;70284:89::o:0;69500:131::-;66023:12;:10;:12::i;:::-;66012:23;;:7;:5;:7::i;:::-;:23;;;66004:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;69548:12:::1;69563:21;69548:36;;69595:10;:19;;:28;69615:7;69595:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;66083:1;69500:131::o:0;55784:151::-;55888:39;55905:4;55911:2;55915:7;55888:39;;;;;;;;;;;;:16;:39::i;:::-;55784:151;;;:::o;72190:158::-;66023:12;:10;:12::i;:::-;66012:23;;:7;:5;:7::i;:::-;:23;;;66004:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;72282:13:::1;72269:10;:26;;;;72311:29;72329:10;;72311:29;;;;;;:::i;:::-;;;;;;;;72190:158:::0;:::o;53814:172::-;53889:7;53910:15;53931:22;53947:5;53931:12;:15;;:22;;;;:::i;:::-;53909:44;;;53971:7;53964:14;;;53814:172;;;:::o;70175:99::-;66023:12;:10;:12::i;:::-;66012:23;;:7;:5;:7::i;:::-;:23;;;66004:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;70246:20:::1;70258:7;70246:11;:20::i;:::-;70175:99:::0;:::o;51488:177::-;51560:7;51587:70;51604:7;51587:70;;;;;;;;;;;;;;;;;:12;:16;;:70;;;;;:::i;:::-;51580:77;;51488:177;;;:::o;68794:36::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;53107:97::-;53155:13;53188:8;53181:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53107:97;:::o;51205:221::-;51277:7;51322:1;51305:19;;:5;:19;;;;51297:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;51389:29;:13;:20;51403:5;51389:20;;;;;;;;;;;;;;;:27;:29::i;:::-;51382:36;;51205:221;;;:::o;66443:148::-;66023:12;:10;:12::i;:::-;66012:23;;:7;:5;:7::i;:::-;:23;;;66004:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;66550:1:::1;66513:40;;66534:6;;;;;;;;;;;66513:40;;;;;;;;;;;;66581:1;66564:6;;:19;;;;;;;;;;;;;;;;;;66443:148::o:0;69134:31::-;;;;:::o;72358:748::-;72447:13;72463:10;72447:26;;69013:17;72494:9;:24;72486:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;69123:4;72577:20;72595:1;72577:13;:11;:13::i;:::-;:17;;:20;;;;:::i;:::-;:34;;72569:86;;;;;;;;;;;;:::i;:::-;;;;;;;;;72675:19;:26;72695:5;72675:26;;;;;;;;;;;;;;;;;;;;;;;;;72674:27;72666:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;72798:82;72817:11;;72798:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72830:10;;72870:5;72853:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;72843:34;;;;;;72798:18;:82::i;:::-;72790:108;;;;;;;;;;;;:::i;:::-;;;;;;;;;72968:4;72939:19;:26;72959:5;72939:26;;;;;;;;;;;;;;;;:33;;;;;;;;;;;;;;;;;;73027:31;73037:5;73044:13;:11;:13::i;:::-;73027:9;:31::i;:::-;73076:22;73092:5;73076:22;;;;;;:::i;:::-;;;;;;;;72358:748;;;:::o;69639:391::-;66023:12;:10;:12::i;:::-;66012:23;;:7;:5;:7::i;:::-;:23;;;66004:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;69735:11:::1;69749:13;:11;:13::i;:::-;69735:27;;69798:1;69781:14;:18;:53;;;;;69821:13;;69803:14;:31;;69781:53;69773:84;;;;;;;;;;;;:::i;:::-;;;;;;;;;69873:6;69868:95;69889:14;69885:1;:18;69868:95;;;69925:26;69935:3;69949:1;69940:6;:10;69925:9;:26::i;:::-;69905:3;;;;;;;69868:95;;;;69989:33;70007:14;69989:13;;:17;;:33;;;;:::i;:::-;69973:13;:49;;;;66083:1;69639:391:::0;;:::o;70391:540::-;70452:16;70482:18;70503:17;70513:6;70503:9;:17::i;:::-;70482:38;;70549:1;70535:10;:15;70531:393;;;70626:1;70612:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70605:23;;;;;70531:393;70661:23;70701:10;70687:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70661:51;;70727:13;70755:130;70779:10;70771:5;:18;70755:130;;;70835:34;70855:6;70863:5;70835:19;:34::i;:::-;70819:6;70826:5;70819:13;;;;;;;;;;;;;:50;;;;;70791:7;;;;;;;70755:130;;;70906:6;70899:13;;;;;70391:540;;;;:::o;65792:87::-;65838:7;65865:6;;;;;;;;;;;65858:13;;65792:87;:::o;51901:104::-;51957:13;51990:7;51983:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51901:104;:::o;68837:31::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;54811:295::-;54926:12;:10;:12::i;:::-;54914:24;;:8;:24;;;;54906:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;55026:8;54981:18;:32;55000:12;:10;:12::i;:::-;54981:32;;;;;;;;;;;;;;;:42;55014:8;54981:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;55079:8;55050:48;;55065:12;:10;:12::i;:::-;55050:48;;;55089:8;55050:48;;;;;;:::i;:::-;;;;;;;;54811:295;;:::o;69037:42::-;69078:1;69037:42;:::o;56006:285::-;56138:41;56157:12;:10;:12::i;:::-;56171:7;56138:18;:41::i;:::-;56130:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;56244:39;56258:4;56264:2;56268:7;56277:5;56244:13;:39::i;:::-;56006:285;;;;:::o;52076:792::-;52149:13;52183:16;52191:7;52183;:16::i;:::-;52175:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;52264:23;52290:10;:19;52301:7;52290:19;;;;;;;;;;;52264:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52320:18;52341:9;:7;:9::i;:::-;52320:30;;52448:1;52432:4;52426:18;:23;52422:72;;;52473:9;52466:16;;;;;;52422:72;52624:1;52604:9;52598:23;:27;52594:108;;;52673:4;52679:9;52656:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;52642:48;;;;;;52594:108;52834:4;52840:18;:7;:16;:18::i;:::-;52817:42;;;;;;;;;:::i;:::-;;;;;;;;;;;;;52803:57;;;;52076:792;;;;:::o;69086:41::-;69123:4;69086:41;:::o;55177:164::-;55274:4;55298:18;:25;55317:5;55298:25;;;;;;;;;;;;;;;:35;55324:8;55298:35;;;;;;;;;;;;;;;;;;;;;;;;;55291:42;;55177:164;;;;:::o;69174:32::-;;;;;;;;;;;;;:::o;66746:244::-;66023:12;:10;:12::i;:::-;66012:23;;:7;:5;:7::i;:::-;:23;;;66004:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;66855:1:::1;66835:22;;:8;:22;;;;66827:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;66945:8;66916:38;;66937:6;;;;;;;;;;;66916:38;;;;;;;;;;;;66974:8;66965:6;;:17;;;;;;;;;;;;;;;;;;66746:244:::0;:::o;70956:988::-;71031:12;;;;;;;;;;;71023:59;;;;;;;;;;;;:::i;:::-;;;;;;;;;71102:22;71113:10;71102;:22::i;:::-;71101:23;71093:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;71194:1;71177:14;:18;:57;;;;;69078:1;71199:14;:35;;71177:57;71169:102;;;;;;;;;;;;:::i;:::-;;;;;;;;;71303:31;71319:14;69013:17;71303:15;;:31;;;;:::i;:::-;71290:9;:44;71282:88;;;;;;;;;;;;:::i;:::-;;;;;;;;;71446:1;71389:53;71427:14;71389:21;:33;71411:10;71389:33;;;;;;;;;;;;;;;;:37;;:53;;;;:::i;:::-;:58;;71381:100;;;;;;;;;;;;:::i;:::-;;;;;;;;;71506:6;71502:435;71522:14;71518:1;:18;71502:435;;;69123:4;71562:13;:11;:13::i;:::-;:26;71558:368;;;71609:36;71619:10;71631:13;:11;:13::i;:::-;71609:9;:36::i;:::-;71700:40;71738:1;71700:21;:33;71722:10;71700:33;;;;;;;;;;;;;;;;:37;;:40;;;;:::i;:::-;71664:21;:33;71686:10;71664:33;;;;;;;;;;;;;;;:76;;;;71558:368;;;71796:12;;;;;;;;;;;71795:13;71780:12;;:28;;;;;;;;;;;;;;;;;;71827:10;:19;;:59;71847:38;69013:17;71847:21;71866:1;71847:14;:18;;:21;;;;:::i;:::-;:25;;:38;;;;:::i;:::-;71827:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71905:5;;71558:368;71538:3;;;;;;;71502:435;;;;70956:988;:::o;57758:127::-;57823:4;57847:30;57869:7;57847:12;:21;;:30;;;;:::i;:::-;57840:37;;57758:127;;;:::o;881:106::-;934:15;969:10;962:17;;881:106;:::o;63776:192::-;63878:2;63851:15;:24;63867:7;63851:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;63934:7;63930:2;63896:46;;63905:23;63920:7;63905:14;:23::i;:::-;63896:46;;;;;;;;;;;;63776:192;;:::o;44490:123::-;44559:7;44586:19;44594:3;:10;;44586:7;:19::i;:::-;44579:26;;44490:123;;;:::o;58052:355::-;58145:4;58170:16;58178:7;58170;:16::i;:::-;58162:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;58246:13;58262:23;58277:7;58262:14;:23::i;:::-;58246:39;;58315:5;58304:16;;:7;:16;;;:51;;;;58348:7;58324:31;;:20;58336:7;58324:11;:20::i;:::-;:31;;;58304:51;:94;;;;58359:39;58383:5;58390:7;58359:23;:39::i;:::-;58304:94;58296:103;;;58052:355;;;;:::o;61188:599::-;61313:4;61286:31;;:23;61301:7;61286:14;:23::i;:::-;:31;;;61278:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;61414:1;61400:16;;:2;:16;;;;61392:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;61470:39;61491:4;61497:2;61501:7;61470:20;:39::i;:::-;61574:29;61591:1;61595:7;61574:8;:29::i;:::-;61616:35;61643:7;61616:13;:19;61630:4;61616:19;;;;;;;;;;;;;;;:26;;:35;;;;:::i;:::-;;61662:30;61684:7;61662:13;:17;61676:2;61662:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;61705:29;61722:7;61731:2;61705:12;:16;;:29;;;;;:::i;:::-;;61771:7;61767:2;61752:27;;61761:4;61752:27;;;;;;;;;;;;61188:599;;;:::o;36281:137::-;36352:7;36387:22;36391:3;:10;;36403:5;36387:3;:22::i;:::-;36379:31;;36372:38;;36281:137;;;;:::o;44952:236::-;45032:7;45041;45062:11;45075:13;45092:22;45096:3;:10;;45108:5;45092:3;:22::i;:::-;45061:53;;;;45141:3;45133:12;;45171:5;45163:14;;45125:55;;;;;;44952:236;;;;;:::o;62388:100::-;62472:8;62461;:19;;;;;;;;;;;;:::i;:::-;;62388:100;:::o;46238:213::-;46345:7;46396:44;46401:3;:10;;46421:3;46413:12;;46427;46396:4;:44::i;:::-;46388:53;;46365:78;;46238:213;;;;;:::o;35823:114::-;35883:7;35910:19;35918:3;:10;;35910:7;:19::i;:::-;35903:26;;35823:114;;;:::o;14009:179::-;14067:7;14087:9;14103:1;14099;:5;14087:17;;14128:1;14123;:6;;14115:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;14179:1;14172:8;;;14009:179;;;;:::o;67826:830::-;67951:4;67968:20;67991:4;67968:27;;68013:9;68008:525;68032:5;:12;68028:1;:16;68008:525;;;68066:20;68089:5;68095:1;68089:8;;;;;;;;;;;;;;68066:31;;68134:12;68118;:28;68114:408;;68288:12;68302;68271:44;;;;;;;;;:::i;:::-;;;;;;;;;;;;;68261:55;;;;;;68246:70;;68114:408;;;68478:12;68492;68461:44;;;;;;;;;:::i;:::-;;;;;;;;;;;;;68451:55;;;;;;68436:70;;68114:408;68008:525;68046:3;;;;;;;68008:525;;;;68644:4;68628:12;:20;68621:27;;;67826:830;;;;;:::o;58750:110::-;58826:26;58836:2;58840:7;58826:26;;;;;;;;;;;;:9;:26::i;:::-;58750:110;;:::o;14471:158::-;14529:7;14562:1;14557;:6;;14549:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;14620:1;14616;:5;14609:12;;14471:158;;;;:::o;57173:272::-;57287:28;57297:4;57303:2;57307:7;57287:9;:28::i;:::-;57334:48;57357:4;57363:2;57367:7;57376:5;57334:22;:48::i;:::-;57326:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;57173:272;;;;:::o;46702:746::-;46758:13;46988:1;46979:5;:10;46975:53;;;47006:10;;;;;;;;;;;;;;;;;;;;;46975:53;47038:12;47053:5;47038:20;;47069:14;47094:78;47109:1;47101:4;:9;47094:78;;47127:8;;;;;;;47158:2;47150:10;;;;;;;;;47094:78;;;47182:19;47214:6;47204:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47182:39;;47232:13;47257:1;47248:6;:10;47232:26;;47276:5;47269:12;;47292:117;47307:1;47299:4;:9;47292:117;;47368:2;47361:4;:9;;;;;;47356:2;:14;47343:29;;47325:6;47332:7;;;;;;;47325:15;;;;;;;;;;;:47;;;;;;;;;;;47395:2;47387:10;;;;;;;;;47292:117;;;47433:6;47419:21;;;;;;46702:746;;;;:::o;71949:196::-;72009:4;72026:12;72093:7;72081:20;72073:28;;72136:1;72129:4;:8;72122:15;;;71949:196;;;:::o;14888:220::-;14946:7;14975:1;14970;:6;14966:20;;;14985:1;14978:8;;;;14966:20;14997:9;15013:1;15009;:5;14997:17;;15042:1;15037;15033;:5;;;;;;:10;15025:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;15099:1;15092:8;;;14888:220;;;;;:::o;44251:151::-;44335:4;44359:35;44369:3;:10;;44389:3;44381:12;;44359:9;:35::i;:::-;44352:42;;44251:151;;;;:::o;41069:110::-;41125:7;41152:3;:12;;:19;;;;41145:26;;41069:110;;;:::o;64581:93::-;;;;:::o;35368:137::-;35438:4;35462:35;35470:3;:10;;35490:5;35482:14;;35462:7;:35::i;:::-;35455:42;;35368:137;;;;:::o;35061:131::-;35128:4;35152:32;35157:3;:10;;35177:5;35169:14;;35152:4;:32::i;:::-;35145:39;;35061:131;;;;:::o;43674:185::-;43763:4;43787:64;43792:3;:10;;43812:3;43804:12;;43842:5;43826:23;;43818:32;;43787:4;:64::i;:::-;43780:71;;43674:185;;;;;:::o;31319:204::-;31386:7;31435:5;31414:3;:11;;:18;;;;:26;31406:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;31497:3;:11;;31509:5;31497:18;;;;;;;;;;;;;;;;31490:25;;31319:204;;;;:::o;41534:279::-;41601:7;41610;41660:5;41638:3;:12;;:19;;;;:27;41630:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;41717:22;41742:3;:12;;41755:5;41742:19;;;;;;;;;;;;;;;;;;41717:44;;41780:5;:10;;;41792:5;:12;;;41772:33;;;;;41534:279;;;;;:::o;43031:319::-;43125:7;43145:16;43164:3;:12;;:17;43177:3;43164:17;;;;;;;;;;;;43145:36;;43212:1;43200:8;:13;;43215:12;43192:36;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;43282:3;:12;;43306:1;43295:8;:12;43282:26;;;;;;;;;;;;;;;;;;:33;;;43275:40;;;43031:319;;;;;:::o;30866:109::-;30922:7;30949:3;:11;;:18;;;;30942:25;;30866:109;;;:::o;59087:250::-;59183:18;59189:2;59193:7;59183:5;:18::i;:::-;59220:54;59251:1;59255:2;59259:7;59268:5;59220:22;:54::i;:::-;59212:117;;;;;;;;;;;;:::i;:::-;;;;;;;;;59087:250;;;:::o;63053:604::-;63174:4;63201:15;:2;:13;;;:15::i;:::-;63196:60;;63240:4;63233:11;;;;63196:60;63266:23;63292:252;63345:45;;;63405:12;:10;:12::i;:::-;63432:4;63451:7;63473:5;63308:181;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63292:252;;;;;;;;;;;;;;;;;:2;:15;;;;:252;;;;;:::i;:::-;63266:278;;63555:13;63582:10;63571:32;;;;;;;;;;;;:::i;:::-;63555:48;;48202:10;63632:16;;63622:26;;;:6;:26;;;;63614:35;;;;63053:604;;;;;;;:::o;40849:125::-;40920:4;40965:1;40944:3;:12;;:17;40957:3;40944:17;;;;;;;;;;;;:22;;40937:29;;40849:125;;;;:::o;29021:1544::-;29087:4;29205:18;29226:3;:12;;:19;29239:5;29226:19;;;;;;;;;;;;29205:40;;29276:1;29262:10;:15;29258:1300;;29624:21;29661:1;29648:10;:14;29624:38;;29677:17;29718:1;29697:3;:11;;:18;;;;:22;29677:42;;29964:17;29984:3;:11;;29996:9;29984:22;;;;;;;;;;;;;;;;29964:42;;30130:9;30101:3;:11;;30113:13;30101:26;;;;;;;;;;;;;;;:38;;;;30249:1;30233:13;:17;30207:3;:12;;:23;30220:9;30207:23;;;;;;;;;;;:43;;;;30359:3;:11;;:17;;;;;;;;;;;;;;;;;;;;;;;;30454:3;:12;;:19;30467:5;30454:19;;;;;;;;;;;30447:26;;;30497:4;30490:11;;;;;;;;29258:1300;30541:5;30534:12;;;29021:1544;;;;;:::o;28431:414::-;28494:4;28516:21;28526:3;28531:5;28516:9;:21::i;:::-;28511:327;;28554:3;:11;;28571:5;28554:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28737:3;:11;;:18;;;;28715:3;:12;;:19;28728:5;28715:19;;;;;;;;;;;:40;;;;28777:4;28770:11;;;;28511:327;28821:5;28814:12;;28431:414;;;;;:::o;38349:692::-;38425:4;38541:16;38560:3;:12;;:17;38573:3;38560:17;;;;;;;;;;;;38541:36;;38606:1;38594:8;:13;38590:444;;;38661:3;:12;;38679:38;;;;;;;;38696:3;38679:38;;;;38709:5;38679:38;;;38661:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38876:3;:12;;:19;;;;38856:3;:12;;:17;38869:3;38856:17;;;;;;;;;;;:39;;;;38917:4;38910:11;;;;;38590:444;38990:5;38954:3;:12;;38978:1;38967:8;:12;38954:26;;;;;;;;;;;;;;;;;;:33;;:41;;;;39017:5;39010:12;;;38349:692;;;;;;:::o;59673:404::-;59767:1;59753:16;;:2;:16;;;;59745:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;59826:16;59834:7;59826;:16::i;:::-;59825:17;59817:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;59888:45;59917:1;59921:2;59925:7;59888:20;:45::i;:::-;59946:30;59968:7;59946:13;:17;59960:2;59946:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;59989:29;60006:7;60015:2;59989:12;:16;;:29;;;;;:::i;:::-;;60061:7;60057:2;60036:33;;60053:1;60036:33;;;;;;;;;;;;59673:404;;:::o;19450:422::-;19510:4;19718:12;19829:7;19817:20;19809:28;;19863:1;19856:4;:8;19849:15;;;19450:422;;;:::o;22368:195::-;22471:12;22503:52;22525:6;22533:4;22539:1;22542:12;22503:21;:52::i;:::-;22496:59;;22368:195;;;;;:::o;30651:129::-;30724:4;30771:1;30748:3;:12;;:19;30761:5;30748:19;;;;;;;;;;;;:24;;30741:31;;30651:129;;;;:::o;23420:530::-;23547:12;23605:5;23580:21;:30;;23572:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;23672:18;23683:6;23672:10;:18::i;:::-;23664:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;23798:12;23812:23;23839:6;:11;;23859:5;23867:4;23839:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23797:75;;;;23890:52;23908:7;23917:10;23929:12;23890:17;:52::i;:::-;23883:59;;;;23420:530;;;;;;:::o;25960:742::-;26075:12;26104:7;26100:595;;;26135:10;26128:17;;;;26100:595;26269:1;26249:10;:17;:21;26245:439;;;26512:10;26506:17;26573:15;26560:10;26556:2;26552:19;26545:44;26460:148;26655:12;26648:20;;;;;;;;;;;:::i;:::-;;;;;;;;25960:742;;;;;;:::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;867:367::-;;;1000:3;993:4;985:6;981:17;977:27;967:2;;1018:1;1015;1008:12;967:2;1054:6;1041:20;1031:30;;1084:18;1076:6;1073:30;1070:2;;;1116:1;1113;1106:12;1070:2;1153:4;1145:6;1141:17;1129:29;;1207:3;1199:4;1191:6;1187:17;1177:8;1173:32;1170:41;1167:2;;;1224:1;1221;1214:12;1167:2;957:277;;;;;:::o;1240:133::-;;1321:6;1308:20;1299:29;;1337:30;1361:5;1337:30;:::i;:::-;1289:84;;;;:::o;1379:139::-;;1463:6;1450:20;1441:29;;1479:33;1506:5;1479:33;:::i;:::-;1431:87;;;;:::o;1524:137::-;;1607:6;1594:20;1585:29;;1623:32;1649:5;1623:32;:::i;:::-;1575:86;;;;:::o;1667:141::-;;1754:6;1748:13;1739:22;;1770:32;1796:5;1770:32;:::i;:::-;1729:79;;;;:::o;1827:271::-;;1931:3;1924:4;1916:6;1912:17;1908:27;1898:2;;1949:1;1946;1939:12;1898:2;1989:6;1976:20;2014:78;2088:3;2080:6;2073:4;2065:6;2061:17;2014:78;:::i;:::-;2005:87;;1888:210;;;;;:::o;2118:273::-;;2223:3;2216:4;2208:6;2204:17;2200:27;2190:2;;2241:1;2238;2231:12;2190:2;2281:6;2268:20;2306:79;2381:3;2373:6;2366:4;2358:6;2354:17;2306:79;:::i;:::-;2297:88;;2180:211;;;;;:::o;2397:139::-;;2481:6;2468:20;2459:29;;2497:33;2524:5;2497:33;:::i;:::-;2449:87;;;;:::o;2542:262::-;;2650:2;2638:9;2629:7;2625:23;2621:32;2618:2;;;2666:1;2663;2656:12;2618:2;2709:1;2734:53;2779:7;2770:6;2759:9;2755:22;2734:53;:::i;:::-;2724:63;;2680:117;2608:196;;;;:::o;2810:407::-;;;2935:2;2923:9;2914:7;2910:23;2906:32;2903:2;;;2951:1;2948;2941:12;2903:2;2994:1;3019:53;3064:7;3055:6;3044:9;3040:22;3019:53;:::i;:::-;3009:63;;2965:117;3121:2;3147:53;3192:7;3183:6;3172:9;3168:22;3147:53;:::i;:::-;3137:63;;3092:118;2893:324;;;;;:::o;3223:552::-;;;;3365:2;3353:9;3344:7;3340:23;3336:32;3333:2;;;3381:1;3378;3371:12;3333:2;3424:1;3449:53;3494:7;3485:6;3474:9;3470:22;3449:53;:::i;:::-;3439:63;;3395:117;3551:2;3577:53;3622:7;3613:6;3602:9;3598:22;3577:53;:::i;:::-;3567:63;;3522:118;3679:2;3705:53;3750:7;3741:6;3730:9;3726:22;3705:53;:::i;:::-;3695:63;;3650:118;3323:452;;;;;:::o;3781:809::-;;;;;3949:3;3937:9;3928:7;3924:23;3920:33;3917:2;;;3966:1;3963;3956:12;3917:2;4009:1;4034:53;4079:7;4070:6;4059:9;4055:22;4034:53;:::i;:::-;4024:63;;3980:117;4136:2;4162:53;4207:7;4198:6;4187:9;4183:22;4162:53;:::i;:::-;4152:63;;4107:118;4264:2;4290:53;4335:7;4326:6;4315:9;4311:22;4290:53;:::i;:::-;4280:63;;4235:118;4420:2;4409:9;4405:18;4392:32;4451:18;4443:6;4440:30;4437:2;;;4483:1;4480;4473:12;4437:2;4511:62;4565:7;4556:6;4545:9;4541:22;4511:62;:::i;:::-;4501:72;;4363:220;3907:683;;;;;;;:::o;4596:401::-;;;4718:2;4706:9;4697:7;4693:23;4689:32;4686:2;;;4734:1;4731;4724:12;4686:2;4777:1;4802:53;4847:7;4838:6;4827:9;4823:22;4802:53;:::i;:::-;4792:63;;4748:117;4904:2;4930:50;4972:7;4963:6;4952:9;4948:22;4930:50;:::i;:::-;4920:60;;4875:115;4676:321;;;;;:::o;5003:407::-;;;5128:2;5116:9;5107:7;5103:23;5099:32;5096:2;;;5144:1;5141;5134:12;5096:2;5187:1;5212:53;5257:7;5248:6;5237:9;5233:22;5212:53;:::i;:::-;5202:63;;5158:117;5314:2;5340:53;5385:7;5376:6;5365:9;5361:22;5340:53;:::i;:::-;5330:63;;5285:118;5086:324;;;;;:::o;5416:425::-;;;5559:2;5547:9;5538:7;5534:23;5530:32;5527:2;;;5575:1;5572;5565:12;5527:2;5646:1;5635:9;5631:17;5618:31;5676:18;5668:6;5665:30;5662:2;;;5708:1;5705;5698:12;5662:2;5744:80;5816:7;5807:6;5796:9;5792:22;5744:80;:::i;:::-;5726:98;;;;5589:245;5517:324;;;;;:::o;5847:262::-;;5955:2;5943:9;5934:7;5930:23;5926:32;5923:2;;;5971:1;5968;5961:12;5923:2;6014:1;6039:53;6084:7;6075:6;6064:9;6060:22;6039:53;:::i;:::-;6029:63;;5985:117;5913:196;;;;:::o;6115:260::-;;6222:2;6210:9;6201:7;6197:23;6193:32;6190:2;;;6238:1;6235;6228:12;6190:2;6281:1;6306:52;6350:7;6341:6;6330:9;6326:22;6306:52;:::i;:::-;6296:62;;6252:116;6180:195;;;;:::o;6381:282::-;;6499:2;6487:9;6478:7;6474:23;6470:32;6467:2;;;6515:1;6512;6505:12;6467:2;6558:1;6583:63;6638:7;6629:6;6618:9;6614:22;6583:63;:::i;:::-;6573:73;;6529:127;6457:206;;;;:::o;6669:375::-;;6787:2;6775:9;6766:7;6762:23;6758:32;6755:2;;;6803:1;6800;6793:12;6755:2;6874:1;6863:9;6859:17;6846:31;6904:18;6896:6;6893:30;6890:2;;;6936:1;6933;6926:12;6890:2;6964:63;7019:7;7010:6;6999:9;6995:22;6964:63;:::i;:::-;6954:73;;6817:220;6745:299;;;;:::o;7050:262::-;;7158:2;7146:9;7137:7;7133:23;7129:32;7126:2;;;7174:1;7171;7164:12;7126:2;7217:1;7242:53;7287:7;7278:6;7267:9;7263:22;7242:53;:::i;:::-;7232:63;;7188:117;7116:196;;;;:::o;7318:179::-;;7408:46;7450:3;7442:6;7408:46;:::i;:::-;7486:4;7481:3;7477:14;7463:28;;7398:99;;;;:::o;7503:142::-;7606:32;7632:5;7606:32;:::i;:::-;7601:3;7594:45;7584:61;;:::o;7651:118::-;7738:24;7756:5;7738:24;:::i;:::-;7733:3;7726:37;7716:53;;:::o;7775:157::-;7880:45;7900:24;7918:5;7900:24;:::i;:::-;7880:45;:::i;:::-;7875:3;7868:58;7858:74;;:::o;7968:732::-;;8116:54;8164:5;8116:54;:::i;:::-;8186:86;8265:6;8260:3;8186:86;:::i;:::-;8179:93;;8296:56;8346:5;8296:56;:::i;:::-;8375:7;8406:1;8391:284;8416:6;8413:1;8410:13;8391:284;;;8492:6;8486:13;8519:63;8578:3;8563:13;8519:63;:::i;:::-;8512:70;;8605:60;8658:6;8605:60;:::i;:::-;8595:70;;8451:224;8438:1;8435;8431:9;8426:14;;8391:284;;;8395:14;8691:3;8684:10;;8092:608;;;;;;;:::o;8706:109::-;8787:21;8802:5;8787:21;:::i;:::-;8782:3;8775:34;8765:50;;:::o;8821:118::-;8908:24;8926:5;8908:24;:::i;:::-;8903:3;8896:37;8886:53;;:::o;8945:157::-;9050:45;9070:24;9088:5;9070:24;:::i;:::-;9050:45;:::i;:::-;9045:3;9038:58;9028:74;;:::o;9108:360::-;;9222:38;9254:5;9222:38;:::i;:::-;9276:70;9339:6;9334:3;9276:70;:::i;:::-;9269:77;;9355:52;9400:6;9395:3;9388:4;9381:5;9377:16;9355:52;:::i;:::-;9432:29;9454:6;9432:29;:::i;:::-;9427:3;9423:39;9416:46;;9198:270;;;;;:::o;9474:373::-;;9606:38;9638:5;9606:38;:::i;:::-;9660:88;9741:6;9736:3;9660:88;:::i;:::-;9653:95;;9757:52;9802:6;9797:3;9790:4;9783:5;9779:16;9757:52;:::i;:::-;9834:6;9829:3;9825:16;9818:23;;9582:265;;;;;:::o;9853:364::-;;9969:39;10002:5;9969:39;:::i;:::-;10024:71;10088:6;10083:3;10024:71;:::i;:::-;10017:78;;10104:52;10149:6;10144:3;10137:4;10130:5;10126:16;10104:52;:::i;:::-;10181:29;10203:6;10181:29;:::i;:::-;10176:3;10172:39;10165:46;;9945:272;;;;;:::o;10223:377::-;;10357:39;10390:5;10357:39;:::i;:::-;10412:89;10494:6;10489:3;10412:89;:::i;:::-;10405:96;;10510:52;10555:6;10550:3;10543:4;10536:5;10532:16;10510:52;:::i;:::-;10587:6;10582:3;10578:16;10571:23;;10333:267;;;;;:::o;10606:366::-;;10769:67;10833:2;10828:3;10769:67;:::i;:::-;10762:74;;10866:34;10862:1;10857:3;10853:11;10846:55;10932:4;10927:2;10922:3;10918:12;10911:26;10963:2;10958:3;10954:12;10947:19;;10752:220;;;:::o;10978:382::-;;11141:67;11205:2;11200:3;11141:67;:::i;:::-;11134:74;;11238:34;11234:1;11229:3;11225:11;11218:55;11304:20;11299:2;11294:3;11290:12;11283:42;11351:2;11346:3;11342:12;11335:19;;11124:236;;;:::o;11366:370::-;;11529:67;11593:2;11588:3;11529:67;:::i;:::-;11522:74;;11626:34;11622:1;11617:3;11613:11;11606:55;11692:8;11687:2;11682:3;11678:12;11671:30;11727:2;11722:3;11718:12;11711:19;;11512:224;;;:::o;11742:326::-;;11905:67;11969:2;11964:3;11905:67;:::i;:::-;11898:74;;12002:30;11998:1;11993:3;11989:11;11982:51;12059:2;12054:3;12050:12;12043:19;;11888:180;;;:::o;12074:325::-;;12237:67;12301:2;12296:3;12237:67;:::i;:::-;12230:74;;12334:29;12330:1;12325:3;12321:11;12314:50;12390:2;12385:3;12381:12;12374:19;;12220:179;;;:::o;12405:371::-;;12568:67;12632:2;12627:3;12568:67;:::i;:::-;12561:74;;12665:34;12661:1;12656:3;12652:11;12645:55;12731:9;12726:2;12721:3;12717:12;12710:31;12767:2;12762:3;12758:12;12751:19;;12551:225;;;:::o;12782:368::-;;12945:67;13009:2;13004:3;12945:67;:::i;:::-;12938:74;;13042:34;13038:1;13033:3;13029:11;13022:55;13108:6;13103:2;13098:3;13094:12;13087:28;13141:2;13136:3;13132:12;13125:19;;12928:222;;;:::o;13156:323::-;;13319:67;13383:2;13378:3;13319:67;:::i;:::-;13312:74;;13416:27;13412:1;13407:3;13403:11;13396:48;13470:2;13465:3;13461:12;13454:19;;13302:177;;;:::o;13485:329::-;;13648:67;13712:2;13707:3;13648:67;:::i;:::-;13641:74;;13745:33;13741:1;13736:3;13732:11;13725:54;13805:2;13800:3;13796:12;13789:19;;13631:183;;;:::o;13820:328::-;;13983:67;14047:2;14042:3;13983:67;:::i;:::-;13976:74;;14080:32;14076:1;14071:3;14067:11;14060:53;14139:2;14134:3;14130:12;14123:19;;13966:182;;;:::o;14154:370::-;;14317:67;14381:2;14376:3;14317:67;:::i;:::-;14310:74;;14414:34;14410:1;14405:3;14401:11;14394:55;14480:8;14475:2;14470:3;14466:12;14459:30;14515:2;14510:3;14506:12;14499:19;;14300:224;;;:::o;14530:376::-;;14693:67;14757:2;14752:3;14693:67;:::i;:::-;14686:74;;14790:34;14786:1;14781:3;14777:11;14770:55;14856:14;14851:2;14846:3;14842:12;14835:36;14897:2;14892:3;14888:12;14881:19;;14676:230;;;:::o;14912:367::-;;15075:67;15139:2;15134:3;15075:67;:::i;:::-;15068:74;;15172:34;15168:1;15163:3;15159:11;15152:55;15238:5;15233:2;15228:3;15224:12;15217:27;15270:2;15265:3;15261:12;15254:19;;15058:221;;;:::o;15285:328::-;;15448:67;15512:2;15507:3;15448:67;:::i;:::-;15441:74;;15545:32;15541:1;15536:3;15532:11;15525:53;15604:2;15599:3;15595:12;15588:19;;15431:182;;;:::o;15619:388::-;;15782:67;15846:2;15841:3;15782:67;:::i;:::-;15775:74;;15879:34;15875:1;15870:3;15866:11;15859:55;15945:26;15940:2;15935:3;15931:12;15924:48;15998:2;15993:3;15989:12;15982:19;;15765:242;;;:::o;16013:374::-;;16176:67;16240:2;16235:3;16176:67;:::i;:::-;16169:74;;16273:34;16269:1;16264:3;16260:11;16253:55;16339:12;16334:2;16329:3;16325:12;16318:34;16378:2;16373:3;16369:12;16362:19;;16159:228;;;:::o;16393:366::-;;16556:67;16620:2;16615:3;16556:67;:::i;:::-;16549:74;;16653:34;16649:1;16644:3;16640:11;16633:55;16719:4;16714:2;16709:3;16705:12;16698:26;16750:2;16745:3;16741:12;16734:19;;16539:220;;;:::o;16765:330::-;;16928:67;16992:2;16987:3;16928:67;:::i;:::-;16921:74;;17025:34;17021:1;17016:3;17012:11;17005:55;17086:2;17081:3;17077:12;17070:19;;16911:184;;;:::o;17101:365::-;;17264:67;17328:2;17323:3;17264:67;:::i;:::-;17257:74;;17361:34;17357:1;17352:3;17348:11;17341:55;17427:3;17422:2;17417:3;17413:12;17406:25;17457:2;17452:3;17448:12;17441:19;;17247:219;;;:::o;17472:376::-;;17635:67;17699:2;17694:3;17635:67;:::i;:::-;17628:74;;17732:34;17728:1;17723:3;17719:11;17712:55;17798:14;17793:2;17788:3;17784:12;17777:36;17839:2;17834:3;17830:12;17823:19;;17618:230;;;:::o;17854:330::-;;18017:67;18081:2;18076:3;18017:67;:::i;:::-;18010:74;;18114:34;18110:1;18105:3;18101:11;18094:55;18175:2;18170:3;18166:12;18159:19;;18000:184;;;:::o;18190:368::-;;18353:67;18417:2;18412:3;18353:67;:::i;:::-;18346:74;;18450:34;18446:1;18441:3;18437:11;18430:55;18516:6;18511:2;18506:3;18502:12;18495:28;18549:2;18544:3;18540:12;18533:19;;18336:222;;;:::o;18564:373::-;;18727:67;18791:2;18786:3;18727:67;:::i;:::-;18720:74;;18824:34;18820:1;18815:3;18811:11;18804:55;18890:11;18885:2;18880:3;18876:12;18869:33;18928:2;18923:3;18919:12;18912:19;;18710:227;;;:::o;18943:379::-;;19106:67;19170:2;19165:3;19106:67;:::i;:::-;19099:74;;19203:34;19199:1;19194:3;19190:11;19183:55;19269:17;19264:2;19259:3;19255:12;19248:39;19313:2;19308:3;19304:12;19297:19;;19089:233;;;:::o;19328:316::-;;19491:67;19555:2;19550:3;19491:67;:::i;:::-;19484:74;;19588:20;19584:1;19579:3;19575:11;19568:41;19635:2;19630:3;19626:12;19619:19;;19474:170;;;:::o;19650:365::-;;19813:67;19877:2;19872:3;19813:67;:::i;:::-;19806:74;;19910:34;19906:1;19901:3;19897:11;19890:55;19976:3;19971:2;19966:3;19962:12;19955:25;20006:2;20001:3;19997:12;19990:19;;19796:219;;;:::o;20021:330::-;;20184:67;20248:2;20243:3;20184:67;:::i;:::-;20177:74;;20281:34;20277:1;20272:3;20268:11;20261:55;20342:2;20337:3;20333:12;20326:19;;20167:184;;;:::o;20357:381::-;;20520:67;20584:2;20579:3;20520:67;:::i;:::-;20513:74;;20617:34;20613:1;20608:3;20604:11;20597:55;20683:19;20678:2;20673:3;20669:12;20662:41;20729:2;20724:3;20720:12;20713:19;;20503:235;;;:::o;20744:327::-;;20907:67;20971:2;20966:3;20907:67;:::i;:::-;20900:74;;21004:31;21000:1;20995:3;20991:11;20984:52;21062:2;21057:3;21053:12;21046:19;;20890:181;;;:::o;21077:366::-;;21240:67;21304:2;21299:3;21240:67;:::i;:::-;21233:74;;21337:34;21333:1;21328:3;21324:11;21317:55;21403:4;21398:2;21393:3;21389:12;21382:26;21434:2;21429:3;21425:12;21418:19;;21223:220;;;:::o;21449:327::-;;21612:67;21676:2;21671:3;21612:67;:::i;:::-;21605:74;;21709:31;21705:1;21700:3;21696:11;21689:52;21767:2;21762:3;21758:12;21751:19;;21595:181;;;:::o;21782:311::-;;21945:67;22009:2;22004:3;21945:67;:::i;:::-;21938:74;;22042:15;22038:1;22033:3;22029:11;22022:36;22084:2;22079:3;22075:12;22068:19;;21928:165;;;:::o;22099:108::-;22176:24;22194:5;22176:24;:::i;:::-;22171:3;22164:37;22154:53;;:::o;22213:118::-;22300:24;22318:5;22300:24;:::i;:::-;22295:3;22288:37;22278:53;;:::o;22337:256::-;;22464:75;22535:3;22526:6;22464:75;:::i;:::-;22564:2;22559:3;22555:12;22548:19;;22584:3;22577:10;;22453:140;;;;:::o;22599:397::-;;22754:75;22825:3;22816:6;22754:75;:::i;:::-;22854:2;22849:3;22845:12;22838:19;;22867:75;22938:3;22929:6;22867:75;:::i;:::-;22967:2;22962:3;22958:12;22951:19;;22987:3;22980:10;;22743:253;;;;;:::o;23002:271::-;;23154:93;23243:3;23234:6;23154:93;:::i;:::-;23147:100;;23264:3;23257:10;;23136:137;;;;:::o;23279:435::-;;23481:95;23572:3;23563:6;23481:95;:::i;:::-;23474:102;;23593:95;23684:3;23675:6;23593:95;:::i;:::-;23586:102;;23705:3;23698:10;;23463:251;;;;;:::o;23720:222::-;;23851:2;23840:9;23836:18;23828:26;;23864:71;23932:1;23921:9;23917:17;23908:6;23864:71;:::i;:::-;23818:124;;;;:::o;23948:672::-;;24197:3;24186:9;24182:19;24174:27;;24211:87;24295:1;24284:9;24280:17;24271:6;24211:87;:::i;:::-;24308:72;24376:2;24365:9;24361:18;24352:6;24308:72;:::i;:::-;24390;24458:2;24447:9;24443:18;24434:6;24390:72;:::i;:::-;24509:9;24503:4;24499:20;24494:2;24483:9;24479:18;24472:48;24537:76;24608:4;24599:6;24537:76;:::i;:::-;24529:84;;24164:456;;;;;;;:::o;24626:373::-;;24807:2;24796:9;24792:18;24784:26;;24856:9;24850:4;24846:20;24842:1;24831:9;24827:17;24820:47;24884:108;24987:4;24978:6;24884:108;:::i;:::-;24876:116;;24774:225;;;;:::o;25005:210::-;;25130:2;25119:9;25115:18;25107:26;;25143:65;25205:1;25194:9;25190:17;25181:6;25143:65;:::i;:::-;25097:118;;;;:::o;25221:222::-;;25352:2;25341:9;25337:18;25329:26;;25365:71;25433:1;25422:9;25418:17;25409:6;25365:71;:::i;:::-;25319:124;;;;:::o;25449:313::-;;25600:2;25589:9;25585:18;25577:26;;25649:9;25643:4;25639:20;25635:1;25624:9;25620:17;25613:47;25677:78;25750:4;25741:6;25677:78;:::i;:::-;25669:86;;25567:195;;;;:::o;25768:419::-;;25972:2;25961:9;25957:18;25949:26;;26021:9;26015:4;26011:20;26007:1;25996:9;25992:17;25985:47;26049:131;26175:4;26049:131;:::i;:::-;26041:139;;25939:248;;;:::o;26193:419::-;;26397:2;26386:9;26382:18;26374:26;;26446:9;26440:4;26436:20;26432:1;26421:9;26417:17;26410:47;26474:131;26600:4;26474:131;:::i;:::-;26466:139;;26364:248;;;:::o;26618:419::-;;26822:2;26811:9;26807:18;26799:26;;26871:9;26865:4;26861:20;26857:1;26846:9;26842:17;26835:47;26899:131;27025:4;26899:131;:::i;:::-;26891:139;;26789:248;;;:::o;27043:419::-;;27247:2;27236:9;27232:18;27224:26;;27296:9;27290:4;27286:20;27282:1;27271:9;27267:17;27260:47;27324:131;27450:4;27324:131;:::i;:::-;27316:139;;27214:248;;;:::o;27468:419::-;;27672:2;27661:9;27657:18;27649:26;;27721:9;27715:4;27711:20;27707:1;27696:9;27692:17;27685:47;27749:131;27875:4;27749:131;:::i;:::-;27741:139;;27639:248;;;:::o;27893:419::-;;28097:2;28086:9;28082:18;28074:26;;28146:9;28140:4;28136:20;28132:1;28121:9;28117:17;28110:47;28174:131;28300:4;28174:131;:::i;:::-;28166:139;;28064:248;;;:::o;28318:419::-;;28522:2;28511:9;28507:18;28499:26;;28571:9;28565:4;28561:20;28557:1;28546:9;28542:17;28535:47;28599:131;28725:4;28599:131;:::i;:::-;28591:139;;28489:248;;;:::o;28743:419::-;;28947:2;28936:9;28932:18;28924:26;;28996:9;28990:4;28986:20;28982:1;28971:9;28967:17;28960:47;29024:131;29150:4;29024:131;:::i;:::-;29016:139;;28914:248;;;:::o;29168:419::-;;29372:2;29361:9;29357:18;29349:26;;29421:9;29415:4;29411:20;29407:1;29396:9;29392:17;29385:47;29449:131;29575:4;29449:131;:::i;:::-;29441:139;;29339:248;;;:::o;29593:419::-;;29797:2;29786:9;29782:18;29774:26;;29846:9;29840:4;29836:20;29832:1;29821:9;29817:17;29810:47;29874:131;30000:4;29874:131;:::i;:::-;29866:139;;29764:248;;;:::o;30018:419::-;;30222:2;30211:9;30207:18;30199:26;;30271:9;30265:4;30261:20;30257:1;30246:9;30242:17;30235:47;30299:131;30425:4;30299:131;:::i;:::-;30291:139;;30189:248;;;:::o;30443:419::-;;30647:2;30636:9;30632:18;30624:26;;30696:9;30690:4;30686:20;30682:1;30671:9;30667:17;30660:47;30724:131;30850:4;30724:131;:::i;:::-;30716:139;;30614:248;;;:::o;30868:419::-;;31072:2;31061:9;31057:18;31049:26;;31121:9;31115:4;31111:20;31107:1;31096:9;31092:17;31085:47;31149:131;31275:4;31149:131;:::i;:::-;31141:139;;31039:248;;;:::o;31293:419::-;;31497:2;31486:9;31482:18;31474:26;;31546:9;31540:4;31536:20;31532:1;31521:9;31517:17;31510:47;31574:131;31700:4;31574:131;:::i;:::-;31566:139;;31464:248;;;:::o;31718:419::-;;31922:2;31911:9;31907:18;31899:26;;31971:9;31965:4;31961:20;31957:1;31946:9;31942:17;31935:47;31999:131;32125:4;31999:131;:::i;:::-;31991:139;;31889:248;;;:::o;32143:419::-;;32347:2;32336:9;32332:18;32324:26;;32396:9;32390:4;32386:20;32382:1;32371:9;32367:17;32360:47;32424:131;32550:4;32424:131;:::i;:::-;32416:139;;32314:248;;;:::o;32568:419::-;;32772:2;32761:9;32757:18;32749:26;;32821:9;32815:4;32811:20;32807:1;32796:9;32792:17;32785:47;32849:131;32975:4;32849:131;:::i;:::-;32841:139;;32739:248;;;:::o;32993:419::-;;33197:2;33186:9;33182:18;33174:26;;33246:9;33240:4;33236:20;33232:1;33221:9;33217:17;33210:47;33274:131;33400:4;33274:131;:::i;:::-;33266:139;;33164:248;;;:::o;33418:419::-;;33622:2;33611:9;33607:18;33599:26;;33671:9;33665:4;33661:20;33657:1;33646:9;33642:17;33635:47;33699:131;33825:4;33699:131;:::i;:::-;33691:139;;33589:248;;;:::o;33843:419::-;;34047:2;34036:9;34032:18;34024:26;;34096:9;34090:4;34086:20;34082:1;34071:9;34067:17;34060:47;34124:131;34250:4;34124:131;:::i;:::-;34116:139;;34014:248;;;:::o;34268:419::-;;34472:2;34461:9;34457:18;34449:26;;34521:9;34515:4;34511:20;34507:1;34496:9;34492:17;34485:47;34549:131;34675:4;34549:131;:::i;:::-;34541:139;;34439:248;;;:::o;34693:419::-;;34897:2;34886:9;34882:18;34874:26;;34946:9;34940:4;34936:20;34932:1;34921:9;34917:17;34910:47;34974:131;35100:4;34974:131;:::i;:::-;34966:139;;34864:248;;;:::o;35118:419::-;;35322:2;35311:9;35307:18;35299:26;;35371:9;35365:4;35361:20;35357:1;35346:9;35342:17;35335:47;35399:131;35525:4;35399:131;:::i;:::-;35391:139;;35289:248;;;:::o;35543:419::-;;35747:2;35736:9;35732:18;35724:26;;35796:9;35790:4;35786:20;35782:1;35771:9;35767:17;35760:47;35824:131;35950:4;35824:131;:::i;:::-;35816:139;;35714:248;;;:::o;35968:419::-;;36172:2;36161:9;36157:18;36149:26;;36221:9;36215:4;36211:20;36207:1;36196:9;36192:17;36185:47;36249:131;36375:4;36249:131;:::i;:::-;36241:139;;36139:248;;;:::o;36393:419::-;;36597:2;36586:9;36582:18;36574:26;;36646:9;36640:4;36636:20;36632:1;36621:9;36617:17;36610:47;36674:131;36800:4;36674:131;:::i;:::-;36666:139;;36564:248;;;:::o;36818:419::-;;37022:2;37011:9;37007:18;36999:26;;37071:9;37065:4;37061:20;37057:1;37046:9;37042:17;37035:47;37099:131;37225:4;37099:131;:::i;:::-;37091:139;;36989:248;;;:::o;37243:419::-;;37447:2;37436:9;37432:18;37424:26;;37496:9;37490:4;37486:20;37482:1;37471:9;37467:17;37460:47;37524:131;37650:4;37524:131;:::i;:::-;37516:139;;37414:248;;;:::o;37668:419::-;;37872:2;37861:9;37857:18;37849:26;;37921:9;37915:4;37911:20;37907:1;37896:9;37892:17;37885:47;37949:131;38075:4;37949:131;:::i;:::-;37941:139;;37839:248;;;:::o;38093:419::-;;38297:2;38286:9;38282:18;38274:26;;38346:9;38340:4;38336:20;38332:1;38321:9;38317:17;38310:47;38374:131;38500:4;38374:131;:::i;:::-;38366:139;;38264:248;;;:::o;38518:419::-;;38722:2;38711:9;38707:18;38699:26;;38771:9;38765:4;38761:20;38757:1;38746:9;38742:17;38735:47;38799:131;38925:4;38799:131;:::i;:::-;38791:139;;38689:248;;;:::o;38943:419::-;;39147:2;39136:9;39132:18;39124:26;;39196:9;39190:4;39186:20;39182:1;39171:9;39167:17;39160:47;39224:131;39350:4;39224:131;:::i;:::-;39216:139;;39114:248;;;:::o;39368:222::-;;39499:2;39488:9;39484:18;39476:26;;39512:71;39580:1;39569:9;39565:17;39556:6;39512:71;:::i;:::-;39466:124;;;;:::o;39596:278::-;;39662:2;39656:9;39646:19;;39704:4;39696:6;39692:17;39811:6;39799:10;39796:22;39775:18;39763:10;39760:34;39757:62;39754:2;;;39822:13;;:::i;:::-;39754:2;39857:10;39853:2;39846:22;39636:238;;;;:::o;39880:326::-;;40031:18;40023:6;40020:30;40017:2;;;40053:13;;:::i;:::-;40017:2;40133:4;40129:9;40122:4;40114:6;40110:17;40106:33;40098:41;;40194:4;40188;40184:15;40176:23;;39946:260;;;:::o;40212:327::-;;40364:18;40356:6;40353:30;40350:2;;;40386:13;;:::i;:::-;40350:2;40466:4;40462:9;40455:4;40447:6;40443:17;40439:33;40431:41;;40527:4;40521;40517:15;40509:23;;40279:260;;;:::o;40545:132::-;;40635:3;40627:11;;40665:4;40660:3;40656:14;40648:22;;40617:60;;;:::o;40683:114::-;;40784:5;40778:12;40768:22;;40757:40;;;:::o;40803:98::-;;40888:5;40882:12;40872:22;;40861:40;;;:::o;40907:99::-;;40993:5;40987:12;40977:22;;40966:40;;;:::o;41012:113::-;;41114:4;41109:3;41105:14;41097:22;;41087:38;;;:::o;41131:184::-;;41264:6;41259:3;41252:19;41304:4;41299:3;41295:14;41280:29;;41242:73;;;;:::o;41321:168::-;;41438:6;41433:3;41426:19;41478:4;41473:3;41469:14;41454:29;;41416:73;;;;:::o;41495:147::-;;41633:3;41618:18;;41608:34;;;;:::o;41648:169::-;;41766:6;41761:3;41754:19;41806:4;41801:3;41797:14;41782:29;;41744:73;;;;:::o;41823:148::-;;41962:3;41947:18;;41937:34;;;;:::o;41977:96::-;;42043:24;42061:5;42043:24;:::i;:::-;42032:35;;42022:51;;;:::o;42079:104::-;;42153:24;42171:5;42153:24;:::i;:::-;42142:35;;42132:51;;;:::o;42189:90::-;;42266:5;42259:13;42252:21;42241:32;;42231:48;;;:::o;42285:77::-;;42351:5;42340:16;;42330:32;;;:::o;42368:149::-;;42444:66;42437:5;42433:78;42422:89;;42412:105;;;:::o;42523:126::-;;42600:42;42593:5;42589:54;42578:65;;42568:81;;;:::o;42655:77::-;;42721:5;42710:16;;42700:32;;;:::o;42738:154::-;42822:6;42817:3;42812;42799:30;42884:1;42875:6;42870:3;42866:16;42859:27;42789:103;;;:::o;42898:307::-;42966:1;42976:113;42990:6;42987:1;42984:13;42976:113;;;43075:1;43070:3;43066:11;43060:18;43056:1;43051:3;43047:11;43040:39;43012:2;43009:1;43005:10;43000:15;;42976:113;;;43107:6;43104:1;43101:13;43098:2;;;43187:1;43178:6;43173:3;43169:16;43162:27;43098:2;42947:258;;;;:::o;43211:100::-;;43279:26;43299:5;43279:26;:::i;:::-;43268:37;;43258:53;;;:::o;43317:79::-;;43385:5;43374:16;;43364:32;;;:::o;43402:94::-;;43470:20;43484:5;43470:20;:::i;:::-;43459:31;;43449:47;;;:::o;43502:48::-;43535:9;43556:102;;43648:2;43644:7;43639:2;43632:5;43628:14;43624:28;43614:38;;43604:54;;;:::o;43664:94::-;;43745:5;43741:2;43737:14;43716:35;;43706:52;;;:::o;43764:122::-;43837:24;43855:5;43837:24;:::i;:::-;43830:5;43827:35;43817:2;;43876:1;43873;43866:12;43817:2;43807:79;:::o;43892:116::-;43962:21;43977:5;43962:21;:::i;:::-;43955:5;43952:32;43942:2;;43998:1;43995;43988:12;43942:2;43932:76;:::o;44014:122::-;44087:24;44105:5;44087:24;:::i;:::-;44080:5;44077:35;44067:2;;44126:1;44123;44116:12;44067:2;44057:79;:::o;44142:120::-;44214:23;44231:5;44214:23;:::i;:::-;44207:5;44204:34;44194:2;;44252:1;44249;44242:12;44194:2;44184:78;:::o;44268:122::-;44341:24;44359:5;44341:24;:::i;:::-;44334:5;44331:35;44321:2;;44380:1;44377;44370:12;44321:2;44311:79;:::o

Swarm Source

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