ETH Price: $3,424.38 (-2.10%)
Gas: 5 Gwei

Token

Apes Together Club (APE)
 

Overview

Max Total Supply

179 APE

Holders

82

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
2 APE
0xd97c78a597b51a18f43f34ef099e1529f1c6b9c8
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
ApesTogether

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-10-10
*/

// 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 ApesTogether is ERC721, Ownable {
    
    using SafeMath for uint256;

    address private owner_;
    bytes32 public merkleRoot;

    uint256 public constant apesPrice = 70000000000000000;
    uint public constant maxApesPurchase = 10;
    uint256 public constant MAX_APES = 1250;
    uint public apesReserve = 50;

    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("Apes Together Club", "APE") { }
    
    function withdraw() public onlyOwner {
        uint balance = address(this).balance;
        msg.sender.transfer(balance);
    }

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


    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 mintQP(uint numberOfTokens) public payable {
        require(saleIsActive, "Sale must be active to mint Apes");
        require(numberOfTokens > 0 && numberOfTokens <= maxApesPurchase, "Can only mint 10 tokens at a time");
        require(msg.value == apesPrice.mul(numberOfTokens), "Ether value sent is not correct");
        
        for(uint i = 0; i < numberOfTokens; i++) {
            if (totalSupply() < MAX_APES) {
                _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(apesPrice));
                break;
            }
        }
    }

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


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

        require(numberOfTokens > 0 && numberOfTokens <= 5, "Can only mint 5 tokens at a time");
        require(msg.value == apesPrice.mul(numberOfTokens), "Ether value sent is not correct");
        require(max_mints_per_address[msg.sender].add(numberOfTokens) <= 5,"Max 5 mints allowed per whitelisted wallet");

        // Verify the merkle proof
        require(MerkleProof.verify(merkleProof, merkleRoot,  keccak256(abi.encodePacked(user_))  ), "Invalid proof");
		
		for(uint i = 0; i < numberOfTokens; i++) {
            if (totalSupply() < MAX_APES) {
                _safeMint(msg.sender, totalSupply());
                max_mints_per_address[msg.sender] = max_mints_per_address[msg.sender].add(1);
            } else {
                msg.sender.transfer(numberOfTokens.sub(i).mul(apesPrice));
                break;
            }
        }

        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":"MAX_APES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"apesPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"apesReserve","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":"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":"maxApesPurchase","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":"mintQP","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":"reserveQP","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":"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":"uint256","name":"numberOfTokens","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"whitelistedMints","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526032600d556000600e60006101000a81548160ff0219169083151502179055503480156200003157600080fd5b506040518060400160405280601281526020017f4170657320546f67657468657220436c756200000000000000000000000000008152506040518060400160405280600381526020017f4150450000000000000000000000000000000000000000000000000000000000815250620000b66301ffc9a760e01b620001e960201b60201c565b8160069080519060200190620000ce929190620002c9565b508060079080519060200190620000e7929190620002c9565b50620001006380ac58cd60e01b620001e960201b60201c565b62000118635b5e139f60e01b620001e960201b60201c565b6200013063780e9d6360e01b620001e960201b60201c565b5050600062000144620002c160201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350620003f4565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141562000255576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200024c90620003c1565b60405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200030157600085556200034d565b82601f106200031c57805160ff19168380011785556200034d565b828001600101855582156200034d579182015b828111156200034c5782518255916020019190600101906200032f565b5b5090506200035c919062000360565b5090565b5b808211156200037b57600081600090555060010162000361565b5090565b60006200038e601c83620003e3565b91507f4552433136353a20696e76616c696420696e74657266616365206964000000006000830152602082019050919050565b60006020820190508181036000830152620003dc816200037f565b9050919050565b600082825260208201905092915050565b614a8e80620004046000396000f3fe6080604052600436106101f95760003560e01c80636352211e1161010d578063b88d4fde116100a0578063d3b46e201161006f578063d3b46e2014610703578063e22da2b71461072e578063e985e9c514610759578063eb8d244414610796578063f2fde38b146107c1576101f9565b8063b88d4fde14610656578063bb8a16bd1461067f578063c87b56dd146106aa578063d31a1112146106e7576101f9565b80638462151c116100dc5780638462151c1461059a5780638da5cb5b146105d757806395d89b4114610602578063a22cb4651461062d576101f9565b80636352211e146104de5780636c0360eb1461051b57806370a0823114610546578063715018a614610583576101f9565b80632f745c59116101905780634783f0ef1161015f5780634783f0ef1461040a5780634f6ccce71461043357806355f804b3146104705780635d6dec9f146104995780635de8fa51146104c2576101f9565b80632f745c591461037657806334918dfd146103b35780633ccfd60b146103ca57806342842e0e146103e1576101f9565b8063104bf5ab116101cc578063104bf5ab146102cc57806318160ddd146102f757806323b872dd146103225780632eb4a7ab1461034b576101f9565b806301ffc9a7146101fe57806306fdde031461023b578063081812fc14610266578063095ea7b3146102a3575b600080fd5b34801561020a57600080fd5b5061022560048036038101906102209190613588565b6107ea565b604051610232919061433f565b60405180910390f35b34801561024757600080fd5b50610250610851565b60405161025d9190614375565b60405180910390f35b34801561027257600080fd5b5061028d6004803603810190610288919061361b565b6108f3565b60405161029a91906142b6565b60405180910390f35b3480156102af57600080fd5b506102ca60048036038101906102c59190613523565b610978565b005b3480156102d857600080fd5b506102e1610a90565b6040516102ee9190614737565b60405180910390f35b34801561030357600080fd5b5061030c610a95565b6040516103199190614737565b60405180910390f35b34801561032e57600080fd5b506103496004803603810190610344919061341d565b610aa6565b005b34801561035757600080fd5b50610360610b06565b60405161036d919061435a565b60405180910390f35b34801561038257600080fd5b5061039d60048036038101906103989190613523565b610b0c565b6040516103aa9190614737565b60405180910390f35b3480156103bf57600080fd5b506103c8610b67565b005b3480156103d657600080fd5b506103df610c0f565b005b3480156103ed57600080fd5b506104086004803603810190610403919061341d565b610cda565b005b34801561041657600080fd5b50610431600480360381019061042c919061355f565b610cfa565b005b34801561043f57600080fd5b5061045a6004803603810190610455919061361b565b610db9565b6040516104679190614737565b60405180910390f35b34801561047c57600080fd5b50610497600480360381019061049291906135da565b610ddc565b005b3480156104a557600080fd5b506104c060048036038101906104bb9190613523565b610e64565b005b6104dc60048036038101906104d7919061361b565b610f82565b005b3480156104ea57600080fd5b506105056004803603810190610500919061361b565b6111f6565b60405161051291906142b6565b60405180910390f35b34801561052757600080fd5b5061053061122d565b60405161053d9190614375565b60405180910390f35b34801561055257600080fd5b5061056d600480360381019061056891906133b8565b6112cf565b60405161057a9190614737565b60405180910390f35b34801561058f57600080fd5b5061059861138e565b005b3480156105a657600080fd5b506105c160048036038101906105bc91906133b8565b6114cb565b6040516105ce919061431d565b60405180910390f35b3480156105e357600080fd5b506105ec6115c4565b6040516105f991906142b6565b60405180910390f35b34801561060e57600080fd5b506106176115ee565b6040516106249190614375565b60405180910390f35b34801561063957600080fd5b50610654600480360381019061064f91906134e7565b611690565b005b34801561066257600080fd5b5061067d6004803603810190610678919061346c565b611811565b005b34801561068b57600080fd5b50610694611873565b6040516106a19190614737565b60405180910390f35b3480156106b657600080fd5b506106d160048036038101906106cc919061361b565b611879565b6040516106de9190614375565b60405180910390f35b61070160048036038101906106fc9190613644565b6119fc565b005b34801561070f57600080fd5b50610718611d7e565b6040516107259190614737565b60405180910390f35b34801561073a57600080fd5b50610743611d89565b6040516107509190614737565b60405180910390f35b34801561076557600080fd5b50610780600480360381019061077b91906133e1565b611d8f565b60405161078d919061433f565b60405180910390f35b3480156107a257600080fd5b506107ab611e23565b6040516107b8919061433f565b60405180910390f35b3480156107cd57600080fd5b506107e860048036038101906107e391906133b8565b611e36565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108e95780601f106108be576101008083540402835291602001916108e9565b820191906000526020600020905b8154815290600101906020018083116108cc57829003601f168201915b5050505050905090565b60006108fe82611fe2565b61093d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610934906145d7565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610983826111f6565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156109f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109eb90614677565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a13611fff565b73ffffffffffffffffffffffffffffffffffffffff161480610a425750610a4181610a3c611fff565b611d8f565b5b610a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7890614537565b60405180910390fd5b610a8b8383612007565b505050565b600a81565b6000610aa160026120c0565b905090565b610ab7610ab1611fff565b826120d5565b610af6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aed90614697565b60405180910390fd5b610b018383836121b3565b505050565b600c5481565b6000610b5f82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206123ca90919063ffffffff16565b905092915050565b610b6f611fff565b73ffffffffffffffffffffffffffffffffffffffff16610b8d6115c4565b73ffffffffffffffffffffffffffffffffffffffff1614610be3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bda906145f7565b60405180910390fd5b600e60009054906101000a900460ff1615600e60006101000a81548160ff021916908315150217905550565b610c17611fff565b73ffffffffffffffffffffffffffffffffffffffff16610c356115c4565b73ffffffffffffffffffffffffffffffffffffffff1614610c8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c82906145f7565b60405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610cd6573d6000803e3d6000fd5b5050565b610cf583838360405180602001604052806000815250611811565b505050565b610d02611fff565b73ffffffffffffffffffffffffffffffffffffffff16610d206115c4565b73ffffffffffffffffffffffffffffffffffffffff1614610d76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6d906145f7565b60405180910390fd5b80600c819055507f90004c04698bc3322499a575ed3752dd4abf33e0a7294c06a787a0fe01bea941600c54604051610dae919061435a565b60405180910390a150565b600080610dd08360026123e490919063ffffffff16565b50905080915050919050565b610de4611fff565b73ffffffffffffffffffffffffffffffffffffffff16610e026115c4565b73ffffffffffffffffffffffffffffffffffffffff1614610e58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4f906145f7565b60405180910390fd5b610e6181612410565b50565b610e6c611fff565b73ffffffffffffffffffffffffffffffffffffffff16610e8a6115c4565b73ffffffffffffffffffffffffffffffffffffffff1614610ee0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed7906145f7565b60405180910390fd5b6000610eea610a95565b9050600082118015610efe5750600d548211155b610f3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3490614657565b60405180910390fd5b60005b82811015610f6157610f548482840161242a565b8080600101915050610f40565b50610f7782600d5461244890919063ffffffff16565b600d81905550505050565b600e60009054906101000a900460ff16610fd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fc890614717565b60405180910390fd5b600081118015610fe25750600a8111155b611021576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611018906146f7565b60405180910390fd5b61103b8166f8b0a10e47000061249890919063ffffffff16565b341461107c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611073906144b7565b60405180910390fd5b60005b818110156111f2576104e2611092610a95565b1015611144576110a9336110a4610a95565b61242a565b6110fc6001601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461250890919063ffffffff16565b601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506111e5565b600e60009054906101000a900460ff1615600e60006101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff166108fc6111b466f8b0a10e4700006111a6858761244890919063ffffffff16565b61249890919063ffffffff16565b9081150290604051600060405180830381858888f193505050501580156111df573d6000803e3d6000fd5b506111f2565b808060010191505061107f565b5050565b600061122682604051806060016040528060298152602001614a3060299139600261255d9092919063ffffffff16565b9050919050565b606060098054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156112c55780601f1061129a576101008083540402835291602001916112c5565b820191906000526020600020905b8154815290600101906020018083116112a857829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611340576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133790614557565b60405180910390fd5b611387600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061257c565b9050919050565b611396611fff565b73ffffffffffffffffffffffffffffffffffffffff166113b46115c4565b73ffffffffffffffffffffffffffffffffffffffff161461140a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611401906145f7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b606060006114d8836112cf565b9050600081141561153357600067ffffffffffffffff811180156114fb57600080fd5b5060405190808252806020026020018201604052801561152a5781602001602082028036833780820191505090505b509150506115bf565b60008167ffffffffffffffff8111801561154c57600080fd5b5060405190808252806020026020018201604052801561157b5781602001602082028036833780820191505090505b50905060005b828110156115b8576115938582610b0c565b82828151811061159f57fe5b6020026020010181815250508080600101915050611581565b8193505050505b919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060078054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156116865780601f1061165b57610100808354040283529160200191611686565b820191906000526020600020905b81548152906001019060200180831161166957829003601f168201915b5050505050905090565b611698611fff565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611706576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116fd90614497565b60405180910390fd5b8060056000611713611fff565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166117c0611fff565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611805919061433f565b60405180910390a35050565b61182261181c611fff565b836120d5565b611861576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185890614697565b60405180910390fd5b61186d84848484612591565b50505050565b6104e281565b606061188482611fe2565b6118c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118ba90614637565b60405180910390fd5b6000600860008481526020019081526020016000208054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561196c5780601f106119415761010080835404028352916020019161196c565b820191906000526020600020905b81548152906001019060200180831161194f57829003601f168201915b50505050509050600061197d61122d565b90506000815114156119935781925050506119f7565b6000825111156119c85780826040516020016119b0929190614292565b604051602081830303815290604052925050506119f7565b806119d2856125ed565b6040516020016119e3929190614292565b604051602081830303815290604052925050505b919050565b6000339050600084118015611a12575060058411155b611a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a48906143d7565b60405180910390fd5b611a6b8466f8b0a10e47000061249890919063ffffffff16565b3414611aac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aa3906144b7565b60405180910390fd5b6005611b0085601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461250890919063ffffffff16565b1115611b41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b38906143b7565b60405180910390fd5b611bb5838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600c5483604051602001611b9a9190614234565b60405160208183030381529060405280519060200120612734565b611bf4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611beb906146d7565b60405180910390fd5b60005b84811015611d40576104e2611c0a610a95565b1015611cbc57611c2133611c1c610a95565b61242a565b611c746001601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461250890919063ffffffff16565b601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611d33565b3373ffffffffffffffffffffffffffffffffffffffff166108fc611d0266f8b0a10e470000611cf4858a61244890919063ffffffff16565b61249890919063ffffffff16565b9081150290604051600060405180830381858888f19350505050158015611d2d573d6000803e3d6000fd5b50611d40565b8080600101915050611bf7565b507f67c400238edbf2cfe078e9c46b03af4a14f535dafde7829c4ebd8ffc76448bee81604051611d7091906142b6565b60405180910390a150505050565b66f8b0a10e47000081565b600d5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600e60009054906101000a900460ff1681565b611e3e611fff565b73ffffffffffffffffffffffffffffffffffffffff16611e5c6115c4565b73ffffffffffffffffffffffffffffffffffffffff1614611eb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ea9906145f7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611f22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1990614417565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000611ff88260026127dd90919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff1661207a836111f6565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006120ce826000016127f7565b9050919050565b60006120e082611fe2565b61211f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161211690614517565b60405180910390fd5b600061212a836111f6565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061219957508373ffffffffffffffffffffffffffffffffffffffff16612181846108f3565b73ffffffffffffffffffffffffffffffffffffffff16145b806121aa57506121a98185611d8f565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166121d3826111f6565b73ffffffffffffffffffffffffffffffffffffffff1614612229576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161222090614617565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612299576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161229090614477565b60405180910390fd5b6122a4838383612808565b6122af600082612007565b61230081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061280d90919063ffffffff16565b5061235281600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061282790919063ffffffff16565b50612369818360026128419092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006123d98360000183612876565b60001c905092915050565b6000806000806123f786600001866128e3565b915091508160001c8160001c9350935050509250929050565b8060099080519060200190612426929190613175565b5050565b612444828260405180602001604052806000815250612966565b5050565b60008282111561248d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612484906144d7565b60405180910390fd5b818303905092915050565b6000808314156124ab5760009050612502565b60008284029050828482816124bc57fe5b04146124fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124f4906145b7565b60405180910390fd5b809150505b92915050565b600080828401905083811015612553576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161254a90614457565b60405180910390fd5b8091505092915050565b6000612570846000018460001b846129c1565b60001c90509392505050565b600061258a82600001612a52565b9050919050565b61259c8484846121b3565b6125a884848484612a63565b6125e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125de906143f7565b60405180910390fd5b50505050565b60606000821415612635576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061272f565b600082905060005b6000821461265f578080600101915050600a828161265757fe5b04915061263d565b60008167ffffffffffffffff8111801561267857600080fd5b506040519080825280601f01601f1916602001820160405280156126ab5781602001600182028036833780820191505090505b50905060006001830390508593505b6000841461272757600a84816126cc57fe5b0660300160f81b828280600190039350815181106126e657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a848161271f57fe5b0493506126ba565b819450505050505b919050565b60008082905060005b85518110156127cf57600086828151811061275457fe5b6020026020010151905080831161279557828160405160200161277892919061424f565b6040516020818303038152906040528051906020012092506127c1565b80836040516020016127a892919061424f565b6040516020818303038152906040528051906020012092505b50808060010191505061273d565b508381149150509392505050565b60006127ef836000018360001b612bc7565b905092915050565b600081600001805490509050919050565b505050565b600061281f836000018360001b612bea565b905092915050565b6000612839836000018360001b612cd2565b905092915050565b600061286d846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612d42565b90509392505050565b6000818360000180549050116128c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b890614397565b60405180910390fd5b8260000182815481106128d057fe5b9060005260206000200154905092915050565b6000808284600001805490501161292f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161292690614577565b60405180910390fd5b600084600001848154811061294057fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b6129708383612e1e565b61297d6000848484612a63565b6129bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129b3906143f7565b60405180910390fd5b505050565b60008084600101600085815260200190815260200160002054905060008114158390612a23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a1a9190614375565b60405180910390fd5b50846000016001820381548110612a3657fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b6000612a848473ffffffffffffffffffffffffffffffffffffffff16612fac565b612a915760019050612bbf565b6000612b5863150b7a0260e01b612aa6611fff565b888787604051602401612abc94939291906142d1565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518060600160405280603281526020016149fe603291398773ffffffffffffffffffffffffffffffffffffffff16612fbf9092919063ffffffff16565b9050600081806020019051810190612b7091906135b1565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612cc65760006001820390506000600186600001805490500390506000866000018281548110612c3557fe5b9060005260206000200154905080876000018481548110612c5257fe5b9060005260206000200181905550600183018760010160008381526020019081526020016000208190555086600001805480612c8a57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050612ccc565b60009150505b92915050565b6000612cde8383612fd7565b612d37578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612d3c565b600090505b92915050565b6000808460010160008581526020019081526020016000205490506000811415612de957846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050612e17565b82856000016001830381548110612dfc57fe5b90600052602060002090600202016001018190555060009150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612e8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e8590614597565b60405180910390fd5b612e9781611fe2565b15612ed7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ece90614437565b60405180910390fd5b612ee360008383612808565b612f3481600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061282790919063ffffffff16565b50612f4b818360026128419092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b6060612fce8484600085612ffa565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b60608247101561303f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613036906144f7565b60405180910390fd5b61304885612fac565b613087576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161307e906146b7565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516130b0919061427b565b60006040518083038185875af1925050503d80600081146130ed576040519150601f19603f3d011682016040523d82523d6000602084013e6130f2565b606091505b509150915061310282828661310e565b92505050949350505050565b6060831561311e5782905061316e565b6000835111156131315782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131659190614375565b60405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826131ab57600085556131f2565b82601f106131c457805160ff19168380011785556131f2565b828001600101855582156131f2579182015b828111156131f15782518255916020019190600101906131d6565b5b5090506131ff9190613203565b5090565b5b8082111561321c576000816000905550600101613204565b5090565b600061323361322e84614783565b614752565b90508281526020810184848401111561324b57600080fd5b6132568482856148fa565b509392505050565b600061327161326c846147b3565b614752565b90508281526020810184848401111561328957600080fd5b6132948482856148fa565b509392505050565b6000813590506132ab8161498a565b92915050565b60008083601f8401126132c357600080fd5b8235905067ffffffffffffffff8111156132dc57600080fd5b6020830191508360208202830111156132f457600080fd5b9250929050565b60008135905061330a816149a1565b92915050565b60008135905061331f816149b8565b92915050565b600081359050613334816149cf565b92915050565b600081519050613349816149cf565b92915050565b600082601f83011261336057600080fd5b8135613370848260208601613220565b91505092915050565b600082601f83011261338a57600080fd5b813561339a84826020860161325e565b91505092915050565b6000813590506133b2816149e6565b92915050565b6000602082840312156133ca57600080fd5b60006133d88482850161329c565b91505092915050565b600080604083850312156133f457600080fd5b60006134028582860161329c565b92505060206134138582860161329c565b9150509250929050565b60008060006060848603121561343257600080fd5b60006134408682870161329c565b93505060206134518682870161329c565b9250506040613462868287016133a3565b9150509250925092565b6000806000806080858703121561348257600080fd5b60006134908782880161329c565b94505060206134a18782880161329c565b93505060406134b2878288016133a3565b925050606085013567ffffffffffffffff8111156134cf57600080fd5b6134db8782880161334f565b91505092959194509250565b600080604083850312156134fa57600080fd5b60006135088582860161329c565b9250506020613519858286016132fb565b9150509250929050565b6000806040838503121561353657600080fd5b60006135448582860161329c565b9250506020613555858286016133a3565b9150509250929050565b60006020828403121561357157600080fd5b600061357f84828501613310565b91505092915050565b60006020828403121561359a57600080fd5b60006135a884828501613325565b91505092915050565b6000602082840312156135c357600080fd5b60006135d18482850161333a565b91505092915050565b6000602082840312156135ec57600080fd5b600082013567ffffffffffffffff81111561360657600080fd5b61361284828501613379565b91505092915050565b60006020828403121561362d57600080fd5b600061363b848285016133a3565b91505092915050565b60008060006040848603121561365957600080fd5b6000613667868287016133a3565b935050602084013567ffffffffffffffff81111561368457600080fd5b613690868287016132b1565b92509250509250925092565b60006136a88383614216565b60208301905092915050565b6136bd8161487c565b82525050565b6136cc8161486a565b82525050565b6136e36136de8261486a565b61493c565b82525050565b60006136f4826147f3565b6136fe8185614821565b9350613709836147e3565b8060005b8381101561373a578151613721888261369c565b975061372c83614814565b92505060018101905061370d565b5085935050505092915050565b6137508161488e565b82525050565b61375f8161489a565b82525050565b6137766137718261489a565b61494e565b82525050565b6000613787826147fe565b6137918185614832565b93506137a1818560208601614909565b6137aa8161496c565b840191505092915050565b60006137c0826147fe565b6137ca8185614843565b93506137da818560208601614909565b80840191505092915050565b60006137f182614809565b6137fb818561484e565b935061380b818560208601614909565b6138148161496c565b840191505092915050565b600061382a82614809565b613834818561485f565b9350613844818560208601614909565b80840191505092915050565b600061385d60228361484e565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006138c3602a8361484e565b91507f4d61782035206d696e747320616c6c6f776564207065722077686974656c697360008301527f7465642077616c6c6574000000000000000000000000000000000000000000006020830152604082019050919050565b600061392960208361484e565b91507f43616e206f6e6c79206d696e74203520746f6b656e7320617420612074696d656000830152602082019050919050565b600061396960328361484e565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b60006139cf60268361484e565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a35601c8361484e565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b6000613a75601b8361484e565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b6000613ab560248361484e565b91507f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613b1b60198361484e565b91507f4552433732313a20617070726f766520746f2063616c6c6572000000000000006000830152602082019050919050565b6000613b5b601f8361484e565b91507f45746865722076616c75652073656e74206973206e6f7420636f7272656374006000830152602082019050919050565b6000613b9b601e8361484e565b91507f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006000830152602082019050919050565b6000613bdb60268361484e565b91507f416464726573733a20696e73756666696369656e742062616c616e636520666f60008301527f722063616c6c00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613c41602c8361484e565b91507f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613ca760388361484e565b91507f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008301527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006020830152604082019050919050565b6000613d0d602a8361484e565b91507f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008301527f726f2061646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b6000613d7360228361484e565b91507f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613dd960208361484e565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b6000613e1960218361484e565b91507f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60008301527f77000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613e7f602c8361484e565b91507f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613ee560208361484e565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000613f2560298361484e565b91507f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008301527f73206e6f74206f776e00000000000000000000000000000000000000000000006020830152604082019050919050565b6000613f8b602f8361484e565b91507f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008301527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006020830152604082019050919050565b6000613ff160128361484e565b91507f4e6f7420656e6f756768207265736572766500000000000000000000000000006000830152602082019050919050565b600061403160218361484e565b91507f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061409760318361484e565b91507f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008301527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020830152604082019050919050565b60006140fd601d8361484e565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b600061413d600d8361484e565b91507f496e76616c69642070726f6f66000000000000000000000000000000000000006000830152602082019050919050565b600061417d60218361484e565b91507f43616e206f6e6c79206d696e7420313020746f6b656e7320617420612074696d60008301527f65000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006141e360208361484e565b91507f53616c65206d7573742062652061637469766520746f206d696e7420417065736000830152602082019050919050565b61421f816148f0565b82525050565b61422e816148f0565b82525050565b600061424082846136d2565b60148201915081905092915050565b600061425b8285613765565b60208201915061426b8284613765565b6020820191508190509392505050565b600061428782846137b5565b915081905092915050565b600061429e828561381f565b91506142aa828461381f565b91508190509392505050565b60006020820190506142cb60008301846136c3565b92915050565b60006080820190506142e660008301876136b4565b6142f360208301866136c3565b6143006040830185614225565b8181036060830152614312818461377c565b905095945050505050565b6000602082019050818103600083015261433781846136e9565b905092915050565b60006020820190506143546000830184613747565b92915050565b600060208201905061436f6000830184613756565b92915050565b6000602082019050818103600083015261438f81846137e6565b905092915050565b600060208201905081810360008301526143b081613850565b9050919050565b600060208201905081810360008301526143d0816138b6565b9050919050565b600060208201905081810360008301526143f08161391c565b9050919050565b600060208201905081810360008301526144108161395c565b9050919050565b60006020820190508181036000830152614430816139c2565b9050919050565b6000602082019050818103600083015261445081613a28565b9050919050565b6000602082019050818103600083015261447081613a68565b9050919050565b6000602082019050818103600083015261449081613aa8565b9050919050565b600060208201905081810360008301526144b081613b0e565b9050919050565b600060208201905081810360008301526144d081613b4e565b9050919050565b600060208201905081810360008301526144f081613b8e565b9050919050565b6000602082019050818103600083015261451081613bce565b9050919050565b6000602082019050818103600083015261453081613c34565b9050919050565b6000602082019050818103600083015261455081613c9a565b9050919050565b6000602082019050818103600083015261457081613d00565b9050919050565b6000602082019050818103600083015261459081613d66565b9050919050565b600060208201905081810360008301526145b081613dcc565b9050919050565b600060208201905081810360008301526145d081613e0c565b9050919050565b600060208201905081810360008301526145f081613e72565b9050919050565b6000602082019050818103600083015261461081613ed8565b9050919050565b6000602082019050818103600083015261463081613f18565b9050919050565b6000602082019050818103600083015261465081613f7e565b9050919050565b6000602082019050818103600083015261467081613fe4565b9050919050565b6000602082019050818103600083015261469081614024565b9050919050565b600060208201905081810360008301526146b08161408a565b9050919050565b600060208201905081810360008301526146d0816140f0565b9050919050565b600060208201905081810360008301526146f081614130565b9050919050565b6000602082019050818103600083015261471081614170565b9050919050565b60006020820190508181036000830152614730816141d6565b9050919050565b600060208201905061474c6000830184614225565b92915050565b6000604051905081810181811067ffffffffffffffff821117156147795761477861496a565b5b8060405250919050565b600067ffffffffffffffff82111561479e5761479d61496a565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff8211156147ce576147cd61496a565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000614875826148d0565b9050919050565b6000614887826148d0565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561492757808201518184015260208101905061490c565b83811115614936576000848401525b50505050565b600061494782614958565b9050919050565b6000819050919050565b60006149638261497d565b9050919050565bfe5b6000601f19601f8301169050919050565b60008160601b9050919050565b6149938161486a565b811461499e57600080fd5b50565b6149aa8161488e565b81146149b557600080fd5b50565b6149c18161489a565b81146149cc57600080fd5b50565b6149d8816148a4565b81146149e357600080fd5b50565b6149ef816148f0565b81146149fa57600080fd5b5056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea26469706673582212200afcbb76389dcfc6f696dc2eb564ba88364121af8d105f874630cb7497c9bc0c64736f6c63430007060033

Deployed Bytecode

0x6080604052600436106101f95760003560e01c80636352211e1161010d578063b88d4fde116100a0578063d3b46e201161006f578063d3b46e2014610703578063e22da2b71461072e578063e985e9c514610759578063eb8d244414610796578063f2fde38b146107c1576101f9565b8063b88d4fde14610656578063bb8a16bd1461067f578063c87b56dd146106aa578063d31a1112146106e7576101f9565b80638462151c116100dc5780638462151c1461059a5780638da5cb5b146105d757806395d89b4114610602578063a22cb4651461062d576101f9565b80636352211e146104de5780636c0360eb1461051b57806370a0823114610546578063715018a614610583576101f9565b80632f745c59116101905780634783f0ef1161015f5780634783f0ef1461040a5780634f6ccce71461043357806355f804b3146104705780635d6dec9f146104995780635de8fa51146104c2576101f9565b80632f745c591461037657806334918dfd146103b35780633ccfd60b146103ca57806342842e0e146103e1576101f9565b8063104bf5ab116101cc578063104bf5ab146102cc57806318160ddd146102f757806323b872dd146103225780632eb4a7ab1461034b576101f9565b806301ffc9a7146101fe57806306fdde031461023b578063081812fc14610266578063095ea7b3146102a3575b600080fd5b34801561020a57600080fd5b5061022560048036038101906102209190613588565b6107ea565b604051610232919061433f565b60405180910390f35b34801561024757600080fd5b50610250610851565b60405161025d9190614375565b60405180910390f35b34801561027257600080fd5b5061028d6004803603810190610288919061361b565b6108f3565b60405161029a91906142b6565b60405180910390f35b3480156102af57600080fd5b506102ca60048036038101906102c59190613523565b610978565b005b3480156102d857600080fd5b506102e1610a90565b6040516102ee9190614737565b60405180910390f35b34801561030357600080fd5b5061030c610a95565b6040516103199190614737565b60405180910390f35b34801561032e57600080fd5b506103496004803603810190610344919061341d565b610aa6565b005b34801561035757600080fd5b50610360610b06565b60405161036d919061435a565b60405180910390f35b34801561038257600080fd5b5061039d60048036038101906103989190613523565b610b0c565b6040516103aa9190614737565b60405180910390f35b3480156103bf57600080fd5b506103c8610b67565b005b3480156103d657600080fd5b506103df610c0f565b005b3480156103ed57600080fd5b506104086004803603810190610403919061341d565b610cda565b005b34801561041657600080fd5b50610431600480360381019061042c919061355f565b610cfa565b005b34801561043f57600080fd5b5061045a6004803603810190610455919061361b565b610db9565b6040516104679190614737565b60405180910390f35b34801561047c57600080fd5b50610497600480360381019061049291906135da565b610ddc565b005b3480156104a557600080fd5b506104c060048036038101906104bb9190613523565b610e64565b005b6104dc60048036038101906104d7919061361b565b610f82565b005b3480156104ea57600080fd5b506105056004803603810190610500919061361b565b6111f6565b60405161051291906142b6565b60405180910390f35b34801561052757600080fd5b5061053061122d565b60405161053d9190614375565b60405180910390f35b34801561055257600080fd5b5061056d600480360381019061056891906133b8565b6112cf565b60405161057a9190614737565b60405180910390f35b34801561058f57600080fd5b5061059861138e565b005b3480156105a657600080fd5b506105c160048036038101906105bc91906133b8565b6114cb565b6040516105ce919061431d565b60405180910390f35b3480156105e357600080fd5b506105ec6115c4565b6040516105f991906142b6565b60405180910390f35b34801561060e57600080fd5b506106176115ee565b6040516106249190614375565b60405180910390f35b34801561063957600080fd5b50610654600480360381019061064f91906134e7565b611690565b005b34801561066257600080fd5b5061067d6004803603810190610678919061346c565b611811565b005b34801561068b57600080fd5b50610694611873565b6040516106a19190614737565b60405180910390f35b3480156106b657600080fd5b506106d160048036038101906106cc919061361b565b611879565b6040516106de9190614375565b60405180910390f35b61070160048036038101906106fc9190613644565b6119fc565b005b34801561070f57600080fd5b50610718611d7e565b6040516107259190614737565b60405180910390f35b34801561073a57600080fd5b50610743611d89565b6040516107509190614737565b60405180910390f35b34801561076557600080fd5b50610780600480360381019061077b91906133e1565b611d8f565b60405161078d919061433f565b60405180910390f35b3480156107a257600080fd5b506107ab611e23565b6040516107b8919061433f565b60405180910390f35b3480156107cd57600080fd5b506107e860048036038101906107e391906133b8565b611e36565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108e95780601f106108be576101008083540402835291602001916108e9565b820191906000526020600020905b8154815290600101906020018083116108cc57829003601f168201915b5050505050905090565b60006108fe82611fe2565b61093d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610934906145d7565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610983826111f6565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156109f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109eb90614677565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a13611fff565b73ffffffffffffffffffffffffffffffffffffffff161480610a425750610a4181610a3c611fff565b611d8f565b5b610a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7890614537565b60405180910390fd5b610a8b8383612007565b505050565b600a81565b6000610aa160026120c0565b905090565b610ab7610ab1611fff565b826120d5565b610af6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aed90614697565b60405180910390fd5b610b018383836121b3565b505050565b600c5481565b6000610b5f82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206123ca90919063ffffffff16565b905092915050565b610b6f611fff565b73ffffffffffffffffffffffffffffffffffffffff16610b8d6115c4565b73ffffffffffffffffffffffffffffffffffffffff1614610be3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bda906145f7565b60405180910390fd5b600e60009054906101000a900460ff1615600e60006101000a81548160ff021916908315150217905550565b610c17611fff565b73ffffffffffffffffffffffffffffffffffffffff16610c356115c4565b73ffffffffffffffffffffffffffffffffffffffff1614610c8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c82906145f7565b60405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610cd6573d6000803e3d6000fd5b5050565b610cf583838360405180602001604052806000815250611811565b505050565b610d02611fff565b73ffffffffffffffffffffffffffffffffffffffff16610d206115c4565b73ffffffffffffffffffffffffffffffffffffffff1614610d76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6d906145f7565b60405180910390fd5b80600c819055507f90004c04698bc3322499a575ed3752dd4abf33e0a7294c06a787a0fe01bea941600c54604051610dae919061435a565b60405180910390a150565b600080610dd08360026123e490919063ffffffff16565b50905080915050919050565b610de4611fff565b73ffffffffffffffffffffffffffffffffffffffff16610e026115c4565b73ffffffffffffffffffffffffffffffffffffffff1614610e58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4f906145f7565b60405180910390fd5b610e6181612410565b50565b610e6c611fff565b73ffffffffffffffffffffffffffffffffffffffff16610e8a6115c4565b73ffffffffffffffffffffffffffffffffffffffff1614610ee0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed7906145f7565b60405180910390fd5b6000610eea610a95565b9050600082118015610efe5750600d548211155b610f3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3490614657565b60405180910390fd5b60005b82811015610f6157610f548482840161242a565b8080600101915050610f40565b50610f7782600d5461244890919063ffffffff16565b600d81905550505050565b600e60009054906101000a900460ff16610fd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fc890614717565b60405180910390fd5b600081118015610fe25750600a8111155b611021576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611018906146f7565b60405180910390fd5b61103b8166f8b0a10e47000061249890919063ffffffff16565b341461107c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611073906144b7565b60405180910390fd5b60005b818110156111f2576104e2611092610a95565b1015611144576110a9336110a4610a95565b61242a565b6110fc6001601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461250890919063ffffffff16565b601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506111e5565b600e60009054906101000a900460ff1615600e60006101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff166108fc6111b466f8b0a10e4700006111a6858761244890919063ffffffff16565b61249890919063ffffffff16565b9081150290604051600060405180830381858888f193505050501580156111df573d6000803e3d6000fd5b506111f2565b808060010191505061107f565b5050565b600061122682604051806060016040528060298152602001614a3060299139600261255d9092919063ffffffff16565b9050919050565b606060098054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156112c55780601f1061129a576101008083540402835291602001916112c5565b820191906000526020600020905b8154815290600101906020018083116112a857829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611340576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133790614557565b60405180910390fd5b611387600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061257c565b9050919050565b611396611fff565b73ffffffffffffffffffffffffffffffffffffffff166113b46115c4565b73ffffffffffffffffffffffffffffffffffffffff161461140a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611401906145f7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b606060006114d8836112cf565b9050600081141561153357600067ffffffffffffffff811180156114fb57600080fd5b5060405190808252806020026020018201604052801561152a5781602001602082028036833780820191505090505b509150506115bf565b60008167ffffffffffffffff8111801561154c57600080fd5b5060405190808252806020026020018201604052801561157b5781602001602082028036833780820191505090505b50905060005b828110156115b8576115938582610b0c565b82828151811061159f57fe5b6020026020010181815250508080600101915050611581565b8193505050505b919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060078054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156116865780601f1061165b57610100808354040283529160200191611686565b820191906000526020600020905b81548152906001019060200180831161166957829003601f168201915b5050505050905090565b611698611fff565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611706576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116fd90614497565b60405180910390fd5b8060056000611713611fff565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166117c0611fff565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611805919061433f565b60405180910390a35050565b61182261181c611fff565b836120d5565b611861576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185890614697565b60405180910390fd5b61186d84848484612591565b50505050565b6104e281565b606061188482611fe2565b6118c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118ba90614637565b60405180910390fd5b6000600860008481526020019081526020016000208054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561196c5780601f106119415761010080835404028352916020019161196c565b820191906000526020600020905b81548152906001019060200180831161194f57829003601f168201915b50505050509050600061197d61122d565b90506000815114156119935781925050506119f7565b6000825111156119c85780826040516020016119b0929190614292565b604051602081830303815290604052925050506119f7565b806119d2856125ed565b6040516020016119e3929190614292565b604051602081830303815290604052925050505b919050565b6000339050600084118015611a12575060058411155b611a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a48906143d7565b60405180910390fd5b611a6b8466f8b0a10e47000061249890919063ffffffff16565b3414611aac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aa3906144b7565b60405180910390fd5b6005611b0085601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461250890919063ffffffff16565b1115611b41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b38906143b7565b60405180910390fd5b611bb5838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600c5483604051602001611b9a9190614234565b60405160208183030381529060405280519060200120612734565b611bf4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611beb906146d7565b60405180910390fd5b60005b84811015611d40576104e2611c0a610a95565b1015611cbc57611c2133611c1c610a95565b61242a565b611c746001601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461250890919063ffffffff16565b601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611d33565b3373ffffffffffffffffffffffffffffffffffffffff166108fc611d0266f8b0a10e470000611cf4858a61244890919063ffffffff16565b61249890919063ffffffff16565b9081150290604051600060405180830381858888f19350505050158015611d2d573d6000803e3d6000fd5b50611d40565b8080600101915050611bf7565b507f67c400238edbf2cfe078e9c46b03af4a14f535dafde7829c4ebd8ffc76448bee81604051611d7091906142b6565b60405180910390a150505050565b66f8b0a10e47000081565b600d5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600e60009054906101000a900460ff1681565b611e3e611fff565b73ffffffffffffffffffffffffffffffffffffffff16611e5c6115c4565b73ffffffffffffffffffffffffffffffffffffffff1614611eb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ea9906145f7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611f22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1990614417565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000611ff88260026127dd90919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff1661207a836111f6565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006120ce826000016127f7565b9050919050565b60006120e082611fe2565b61211f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161211690614517565b60405180910390fd5b600061212a836111f6565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061219957508373ffffffffffffffffffffffffffffffffffffffff16612181846108f3565b73ffffffffffffffffffffffffffffffffffffffff16145b806121aa57506121a98185611d8f565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166121d3826111f6565b73ffffffffffffffffffffffffffffffffffffffff1614612229576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161222090614617565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612299576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161229090614477565b60405180910390fd5b6122a4838383612808565b6122af600082612007565b61230081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061280d90919063ffffffff16565b5061235281600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061282790919063ffffffff16565b50612369818360026128419092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006123d98360000183612876565b60001c905092915050565b6000806000806123f786600001866128e3565b915091508160001c8160001c9350935050509250929050565b8060099080519060200190612426929190613175565b5050565b612444828260405180602001604052806000815250612966565b5050565b60008282111561248d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612484906144d7565b60405180910390fd5b818303905092915050565b6000808314156124ab5760009050612502565b60008284029050828482816124bc57fe5b04146124fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124f4906145b7565b60405180910390fd5b809150505b92915050565b600080828401905083811015612553576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161254a90614457565b60405180910390fd5b8091505092915050565b6000612570846000018460001b846129c1565b60001c90509392505050565b600061258a82600001612a52565b9050919050565b61259c8484846121b3565b6125a884848484612a63565b6125e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125de906143f7565b60405180910390fd5b50505050565b60606000821415612635576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061272f565b600082905060005b6000821461265f578080600101915050600a828161265757fe5b04915061263d565b60008167ffffffffffffffff8111801561267857600080fd5b506040519080825280601f01601f1916602001820160405280156126ab5781602001600182028036833780820191505090505b50905060006001830390508593505b6000841461272757600a84816126cc57fe5b0660300160f81b828280600190039350815181106126e657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a848161271f57fe5b0493506126ba565b819450505050505b919050565b60008082905060005b85518110156127cf57600086828151811061275457fe5b6020026020010151905080831161279557828160405160200161277892919061424f565b6040516020818303038152906040528051906020012092506127c1565b80836040516020016127a892919061424f565b6040516020818303038152906040528051906020012092505b50808060010191505061273d565b508381149150509392505050565b60006127ef836000018360001b612bc7565b905092915050565b600081600001805490509050919050565b505050565b600061281f836000018360001b612bea565b905092915050565b6000612839836000018360001b612cd2565b905092915050565b600061286d846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612d42565b90509392505050565b6000818360000180549050116128c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b890614397565b60405180910390fd5b8260000182815481106128d057fe5b9060005260206000200154905092915050565b6000808284600001805490501161292f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161292690614577565b60405180910390fd5b600084600001848154811061294057fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b6129708383612e1e565b61297d6000848484612a63565b6129bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129b3906143f7565b60405180910390fd5b505050565b60008084600101600085815260200190815260200160002054905060008114158390612a23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a1a9190614375565b60405180910390fd5b50846000016001820381548110612a3657fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b6000612a848473ffffffffffffffffffffffffffffffffffffffff16612fac565b612a915760019050612bbf565b6000612b5863150b7a0260e01b612aa6611fff565b888787604051602401612abc94939291906142d1565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518060600160405280603281526020016149fe603291398773ffffffffffffffffffffffffffffffffffffffff16612fbf9092919063ffffffff16565b9050600081806020019051810190612b7091906135b1565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612cc65760006001820390506000600186600001805490500390506000866000018281548110612c3557fe5b9060005260206000200154905080876000018481548110612c5257fe5b9060005260206000200181905550600183018760010160008381526020019081526020016000208190555086600001805480612c8a57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050612ccc565b60009150505b92915050565b6000612cde8383612fd7565b612d37578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612d3c565b600090505b92915050565b6000808460010160008581526020019081526020016000205490506000811415612de957846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050612e17565b82856000016001830381548110612dfc57fe5b90600052602060002090600202016001018190555060009150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612e8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e8590614597565b60405180910390fd5b612e9781611fe2565b15612ed7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ece90614437565b60405180910390fd5b612ee360008383612808565b612f3481600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061282790919063ffffffff16565b50612f4b818360026128419092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b6060612fce8484600085612ffa565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b60608247101561303f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613036906144f7565b60405180910390fd5b61304885612fac565b613087576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161307e906146b7565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516130b0919061427b565b60006040518083038185875af1925050503d80600081146130ed576040519150601f19603f3d011682016040523d82523d6000602084013e6130f2565b606091505b509150915061310282828661310e565b92505050949350505050565b6060831561311e5782905061316e565b6000835111156131315782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131659190614375565b60405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826131ab57600085556131f2565b82601f106131c457805160ff19168380011785556131f2565b828001600101855582156131f2579182015b828111156131f15782518255916020019190600101906131d6565b5b5090506131ff9190613203565b5090565b5b8082111561321c576000816000905550600101613204565b5090565b600061323361322e84614783565b614752565b90508281526020810184848401111561324b57600080fd5b6132568482856148fa565b509392505050565b600061327161326c846147b3565b614752565b90508281526020810184848401111561328957600080fd5b6132948482856148fa565b509392505050565b6000813590506132ab8161498a565b92915050565b60008083601f8401126132c357600080fd5b8235905067ffffffffffffffff8111156132dc57600080fd5b6020830191508360208202830111156132f457600080fd5b9250929050565b60008135905061330a816149a1565b92915050565b60008135905061331f816149b8565b92915050565b600081359050613334816149cf565b92915050565b600081519050613349816149cf565b92915050565b600082601f83011261336057600080fd5b8135613370848260208601613220565b91505092915050565b600082601f83011261338a57600080fd5b813561339a84826020860161325e565b91505092915050565b6000813590506133b2816149e6565b92915050565b6000602082840312156133ca57600080fd5b60006133d88482850161329c565b91505092915050565b600080604083850312156133f457600080fd5b60006134028582860161329c565b92505060206134138582860161329c565b9150509250929050565b60008060006060848603121561343257600080fd5b60006134408682870161329c565b93505060206134518682870161329c565b9250506040613462868287016133a3565b9150509250925092565b6000806000806080858703121561348257600080fd5b60006134908782880161329c565b94505060206134a18782880161329c565b93505060406134b2878288016133a3565b925050606085013567ffffffffffffffff8111156134cf57600080fd5b6134db8782880161334f565b91505092959194509250565b600080604083850312156134fa57600080fd5b60006135088582860161329c565b9250506020613519858286016132fb565b9150509250929050565b6000806040838503121561353657600080fd5b60006135448582860161329c565b9250506020613555858286016133a3565b9150509250929050565b60006020828403121561357157600080fd5b600061357f84828501613310565b91505092915050565b60006020828403121561359a57600080fd5b60006135a884828501613325565b91505092915050565b6000602082840312156135c357600080fd5b60006135d18482850161333a565b91505092915050565b6000602082840312156135ec57600080fd5b600082013567ffffffffffffffff81111561360657600080fd5b61361284828501613379565b91505092915050565b60006020828403121561362d57600080fd5b600061363b848285016133a3565b91505092915050565b60008060006040848603121561365957600080fd5b6000613667868287016133a3565b935050602084013567ffffffffffffffff81111561368457600080fd5b613690868287016132b1565b92509250509250925092565b60006136a88383614216565b60208301905092915050565b6136bd8161487c565b82525050565b6136cc8161486a565b82525050565b6136e36136de8261486a565b61493c565b82525050565b60006136f4826147f3565b6136fe8185614821565b9350613709836147e3565b8060005b8381101561373a578151613721888261369c565b975061372c83614814565b92505060018101905061370d565b5085935050505092915050565b6137508161488e565b82525050565b61375f8161489a565b82525050565b6137766137718261489a565b61494e565b82525050565b6000613787826147fe565b6137918185614832565b93506137a1818560208601614909565b6137aa8161496c565b840191505092915050565b60006137c0826147fe565b6137ca8185614843565b93506137da818560208601614909565b80840191505092915050565b60006137f182614809565b6137fb818561484e565b935061380b818560208601614909565b6138148161496c565b840191505092915050565b600061382a82614809565b613834818561485f565b9350613844818560208601614909565b80840191505092915050565b600061385d60228361484e565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006138c3602a8361484e565b91507f4d61782035206d696e747320616c6c6f776564207065722077686974656c697360008301527f7465642077616c6c6574000000000000000000000000000000000000000000006020830152604082019050919050565b600061392960208361484e565b91507f43616e206f6e6c79206d696e74203520746f6b656e7320617420612074696d656000830152602082019050919050565b600061396960328361484e565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b60006139cf60268361484e565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a35601c8361484e565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b6000613a75601b8361484e565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b6000613ab560248361484e565b91507f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613b1b60198361484e565b91507f4552433732313a20617070726f766520746f2063616c6c6572000000000000006000830152602082019050919050565b6000613b5b601f8361484e565b91507f45746865722076616c75652073656e74206973206e6f7420636f7272656374006000830152602082019050919050565b6000613b9b601e8361484e565b91507f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006000830152602082019050919050565b6000613bdb60268361484e565b91507f416464726573733a20696e73756666696369656e742062616c616e636520666f60008301527f722063616c6c00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613c41602c8361484e565b91507f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613ca760388361484e565b91507f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008301527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006020830152604082019050919050565b6000613d0d602a8361484e565b91507f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008301527f726f2061646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b6000613d7360228361484e565b91507f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613dd960208361484e565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b6000613e1960218361484e565b91507f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60008301527f77000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613e7f602c8361484e565b91507f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613ee560208361484e565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000613f2560298361484e565b91507f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008301527f73206e6f74206f776e00000000000000000000000000000000000000000000006020830152604082019050919050565b6000613f8b602f8361484e565b91507f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008301527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006020830152604082019050919050565b6000613ff160128361484e565b91507f4e6f7420656e6f756768207265736572766500000000000000000000000000006000830152602082019050919050565b600061403160218361484e565b91507f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061409760318361484e565b91507f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008301527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020830152604082019050919050565b60006140fd601d8361484e565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b600061413d600d8361484e565b91507f496e76616c69642070726f6f66000000000000000000000000000000000000006000830152602082019050919050565b600061417d60218361484e565b91507f43616e206f6e6c79206d696e7420313020746f6b656e7320617420612074696d60008301527f65000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006141e360208361484e565b91507f53616c65206d7573742062652061637469766520746f206d696e7420417065736000830152602082019050919050565b61421f816148f0565b82525050565b61422e816148f0565b82525050565b600061424082846136d2565b60148201915081905092915050565b600061425b8285613765565b60208201915061426b8284613765565b6020820191508190509392505050565b600061428782846137b5565b915081905092915050565b600061429e828561381f565b91506142aa828461381f565b91508190509392505050565b60006020820190506142cb60008301846136c3565b92915050565b60006080820190506142e660008301876136b4565b6142f360208301866136c3565b6143006040830185614225565b8181036060830152614312818461377c565b905095945050505050565b6000602082019050818103600083015261433781846136e9565b905092915050565b60006020820190506143546000830184613747565b92915050565b600060208201905061436f6000830184613756565b92915050565b6000602082019050818103600083015261438f81846137e6565b905092915050565b600060208201905081810360008301526143b081613850565b9050919050565b600060208201905081810360008301526143d0816138b6565b9050919050565b600060208201905081810360008301526143f08161391c565b9050919050565b600060208201905081810360008301526144108161395c565b9050919050565b60006020820190508181036000830152614430816139c2565b9050919050565b6000602082019050818103600083015261445081613a28565b9050919050565b6000602082019050818103600083015261447081613a68565b9050919050565b6000602082019050818103600083015261449081613aa8565b9050919050565b600060208201905081810360008301526144b081613b0e565b9050919050565b600060208201905081810360008301526144d081613b4e565b9050919050565b600060208201905081810360008301526144f081613b8e565b9050919050565b6000602082019050818103600083015261451081613bce565b9050919050565b6000602082019050818103600083015261453081613c34565b9050919050565b6000602082019050818103600083015261455081613c9a565b9050919050565b6000602082019050818103600083015261457081613d00565b9050919050565b6000602082019050818103600083015261459081613d66565b9050919050565b600060208201905081810360008301526145b081613dcc565b9050919050565b600060208201905081810360008301526145d081613e0c565b9050919050565b600060208201905081810360008301526145f081613e72565b9050919050565b6000602082019050818103600083015261461081613ed8565b9050919050565b6000602082019050818103600083015261463081613f18565b9050919050565b6000602082019050818103600083015261465081613f7e565b9050919050565b6000602082019050818103600083015261467081613fe4565b9050919050565b6000602082019050818103600083015261469081614024565b9050919050565b600060208201905081810360008301526146b08161408a565b9050919050565b600060208201905081810360008301526146d0816140f0565b9050919050565b600060208201905081810360008301526146f081614130565b9050919050565b6000602082019050818103600083015261471081614170565b9050919050565b60006020820190508181036000830152614730816141d6565b9050919050565b600060208201905061474c6000830184614225565b92915050565b6000604051905081810181811067ffffffffffffffff821117156147795761477861496a565b5b8060405250919050565b600067ffffffffffffffff82111561479e5761479d61496a565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff8211156147ce576147cd61496a565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000614875826148d0565b9050919050565b6000614887826148d0565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561492757808201518184015260208101905061490c565b83811115614936576000848401525b50505050565b600061494782614958565b9050919050565b6000819050919050565b60006149638261497d565b9050919050565bfe5b6000601f19601f8301169050919050565b60008160601b9050919050565b6149938161486a565b811461499e57600080fd5b50565b6149aa8161488e565b81146149b557600080fd5b50565b6149c18161489a565b81146149cc57600080fd5b50565b6149d8816148a4565b81146149e357600080fd5b50565b6149ef816148f0565b81146149fa57600080fd5b5056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea26469706673582212200afcbb76389dcfc6f696dc2eb564ba88364121af8d105f874630cb7497c9bc0c64736f6c63430007060033

Deployed Bytecode Sourcemap

68440:4037:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10204:150;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51465:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54251:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53781:404;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68652:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53259:211;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55141:305;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68558:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53021:162;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69753:89;;;;;;;;;;;;;:::i;:::-;;69114:131;;;;;;;;;;;;;:::i;:::-;;55517:151;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71254:158;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53547:172;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69644:99;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69253:381;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70422:788;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51221:177;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52840:97;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50938:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66172:148;;;;;;;;;;;;;:::i;:::-;;69860:540;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65521:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51634:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54544:295;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55739:285;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68700:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51809:792;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71422:1052;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68592:53;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68746:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54910:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68783:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66475:244;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;10204:150;10289:4;10313:20;:33;10334:11;10313:33;;;;;;;;;;;;;;;;;;;;;;;;;;;10306:40;;10204:150;;;:::o;51465:100::-;51519:13;51552:5;51545:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51465:100;:::o;54251:221::-;54327:7;54355:16;54363:7;54355;:16::i;:::-;54347:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;54440:15;:24;54456:7;54440:24;;;;;;;;;;;;;;;;;;;;;54433:31;;54251:221;;;:::o;53781:404::-;53862:13;53878:23;53893:7;53878:14;:23::i;:::-;53862:39;;53926:5;53920:11;;:2;:11;;;;53912:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;54006:5;53990:21;;:12;:10;:12::i;:::-;:21;;;:69;;;;54015:44;54039:5;54046:12;:10;:12::i;:::-;54015:23;:44::i;:::-;53990:69;53982:161;;;;;;;;;;;;:::i;:::-;;;;;;;;;54156:21;54165:2;54169:7;54156:8;:21::i;:::-;53781:404;;;:::o;68652:41::-;68691:2;68652:41;:::o;53259:211::-;53320:7;53441:21;:12;:19;:21::i;:::-;53434:28;;53259:211;:::o;55141:305::-;55302:41;55321:12;:10;:12::i;:::-;55335:7;55302:18;:41::i;:::-;55294:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;55410:28;55420:4;55426:2;55430:7;55410:9;:28::i;:::-;55141:305;;;:::o;68558:25::-;;;;:::o;53021:162::-;53118:7;53145:30;53169:5;53145:13;:20;53159:5;53145:20;;;;;;;;;;;;;;;:23;;:30;;;;:::i;:::-;53138:37;;53021:162;;;;:::o;69753:89::-;65752:12;:10;:12::i;:::-;65741:23;;:7;:5;:7::i;:::-;:23;;;65733:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;69822:12:::1;;;;;;;;;;;69821:13;69806:12;;:28;;;;;;;;;;;;;;;;;;69753:89::o:0;69114:131::-;65752:12;:10;:12::i;:::-;65741:23;;:7;:5;:7::i;:::-;:23;;;65733:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;69162:12:::1;69177:21;69162:36;;69209:10;:19;;:28;69229:7;69209:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;65812:1;69114:131::o:0;55517:151::-;55621:39;55638:4;55644:2;55648:7;55621:39;;;;;;;;;;;;:16;:39::i;:::-;55517:151;;;:::o;71254:158::-;65752:12;:10;:12::i;:::-;65741:23;;:7;:5;:7::i;:::-;:23;;;65733:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;71346:13:::1;71333:10;:26;;;;71375:29;71393:10;;71375:29;;;;;;:::i;:::-;;;;;;;;71254:158:::0;:::o;53547:172::-;53622:7;53643:15;53664:22;53680:5;53664:12;:15;;:22;;;;:::i;:::-;53642:44;;;53704:7;53697:14;;;53547:172;;;:::o;69644:99::-;65752:12;:10;:12::i;:::-;65741:23;;:7;:5;:7::i;:::-;:23;;;65733:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;69715:20:::1;69727:7;69715:11;:20::i;:::-;69644:99:::0;:::o;69253:381::-;65752:12;:10;:12::i;:::-;65741:23;;:7;:5;:7::i;:::-;:23;;;65733:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;69345:11:::1;69359:13;:11;:13::i;:::-;69345:27;;69408:1;69391:14;:18;:51;;;;;69431:11;;69413:14;:29;;69391:51;69383:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;69481:6;69476:95;69497:14;69493:1;:18;69476:95;;;69533:26;69543:3;69557:1;69548:6;:10;69533:9;:26::i;:::-;69513:3;;;;;;;69476:95;;;;69595:31;69611:14;69595:11;;:15;;:31;;;;:::i;:::-;69581:11;:45;;;;65812:1;69253:381:::0;;:::o;70422:788::-;70493:12;;;;;;;;;;;70485:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;70578:1;70561:14;:18;:55;;;;;68691:2;70583:14;:33;;70561:55;70553:101;;;;;;;;;;;;:::i;:::-;;;;;;;;;70686:29;70700:14;68628:17;70686:13;;:29;;;;:::i;:::-;70673:9;:42;70665:86;;;;;;;;;;;;:::i;:::-;;;;;;;;;70776:6;70772:431;70792:14;70788:1;:18;70772:431;;;68735:4;70832:13;:11;:13::i;:::-;:24;70828:364;;;70877:36;70887:10;70899:13;:11;:13::i;:::-;70877:9;:36::i;:::-;70968:40;71006:1;70968:21;:33;70990:10;70968:33;;;;;;;;;;;;;;;;:37;;:40;;;;:::i;:::-;70932:21;:33;70954:10;70932:33;;;;;;;;;;;;;;;:76;;;;70828:364;;;71064:12;;;;;;;;;;;71063:13;71048:12;;:28;;;;;;;;;;;;;;;;;;71095:10;:19;;:57;71115:36;68628:17;71115:21;71134:1;71115:14;:18;;:21;;;;:::i;:::-;:25;;:36;;;;:::i;:::-;71095:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71171:5;;70828:364;70808:3;;;;;;;70772:431;;;;70422:788;:::o;51221:177::-;51293:7;51320:70;51337:7;51320:70;;;;;;;;;;;;;;;;;:12;:16;;:70;;;;;:::i;:::-;51313:77;;51221:177;;;:::o;52840:97::-;52888:13;52921:8;52914:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52840:97;:::o;50938:221::-;51010:7;51055:1;51038:19;;:5;:19;;;;51030:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;51122:29;:13;:20;51136:5;51122:20;;;;;;;;;;;;;;;:27;:29::i;:::-;51115:36;;50938:221;;;:::o;66172:148::-;65752:12;:10;:12::i;:::-;65741:23;;:7;:5;:7::i;:::-;:23;;;65733:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;66279:1:::1;66242:40;;66263:6;;;;;;;;;;;66242:40;;;;;;;;;;;;66310:1;66293:6;;:19;;;;;;;;;;;;;;;;;;66172:148::o:0;69860:540::-;69921:16;69951:18;69972:17;69982:6;69972:9;:17::i;:::-;69951:38;;70018:1;70004:10;:15;70000:393;;;70095:1;70081:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70074:23;;;;;70000:393;70130:23;70170:10;70156:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70130:51;;70196:13;70224:130;70248:10;70240:5;:18;70224:130;;;70304:34;70324:6;70332:5;70304:19;:34::i;:::-;70288:6;70295:5;70288:13;;;;;;;;;;;;;:50;;;;;70260:7;;;;;;;70224:130;;;70375:6;70368:13;;;;;69860:540;;;;:::o;65521:87::-;65567:7;65594:6;;;;;;;;;;;65587:13;;65521:87;:::o;51634:104::-;51690:13;51723:7;51716:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51634:104;:::o;54544:295::-;54659:12;:10;:12::i;:::-;54647:24;;:8;:24;;;;54639:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;54759:8;54714:18;:32;54733:12;:10;:12::i;:::-;54714:32;;;;;;;;;;;;;;;:42;54747:8;54714:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;54812:8;54783:48;;54798:12;:10;:12::i;:::-;54783:48;;;54822:8;54783:48;;;;;;:::i;:::-;;;;;;;;54544:295;;:::o;55739:285::-;55871:41;55890:12;:10;:12::i;:::-;55904:7;55871:18;:41::i;:::-;55863:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;55977:39;55991:4;55997:2;56001:7;56010:5;55977:13;:39::i;:::-;55739:285;;;;:::o;68700:39::-;68735:4;68700:39;:::o;51809:792::-;51882:13;51916:16;51924:7;51916;:16::i;:::-;51908:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;51997:23;52023:10;:19;52034:7;52023:19;;;;;;;;;;;51997:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52053:18;52074:9;:7;:9::i;:::-;52053:30;;52181:1;52165:4;52159:18;:23;52155:72;;;52206:9;52199:16;;;;;;52155:72;52357:1;52337:9;52331:23;:27;52327:108;;;52406:4;52412:9;52389:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;52375:48;;;;;;52327:108;52567:4;52573:18;:7;:16;:18::i;:::-;52550:42;;;;;;;;;:::i;:::-;;;;;;;;;;;;;52536:57;;;;51809:792;;;;:::o;71422:1052::-;71531:13;71547:10;71531:26;;71595:1;71578:14;:18;:41;;;;;71618:1;71600:14;:19;;71578:41;71570:86;;;;;;;;;;;;:::i;:::-;;;;;;;;;71688:29;71702:14;68628:17;71688:13;;:29;;;;:::i;:::-;71675:9;:42;71667:86;;;;;;;;;;;;:::i;:::-;;;;;;;;;71829:1;71772:53;71810:14;71772:21;:33;71794:10;71772:33;;;;;;;;;;;;;;;;:37;;:53;;;;:::i;:::-;:58;;71764:112;;;;;;;;;;;;:::i;:::-;;;;;;;;;71933:82;71952:11;;71933:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71965:10;;72005:5;71988:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;71978:34;;;;;;71933:18;:82::i;:::-;71925:108;;;;;;;;;;;;:::i;:::-;;;;;;;;;72046:6;72042:385;72062:14;72058:1;:18;72042:385;;;68735:4;72102:13;:11;:13::i;:::-;:24;72098:318;;;72147:36;72157:10;72169:13;:11;:13::i;:::-;72147:9;:36::i;:::-;72238:40;72276:1;72238:21;:33;72260:10;72238:33;;;;;;;;;;;;;;;;:37;;:40;;;;:::i;:::-;72202:21;:33;72224:10;72202:33;;;;;;;;;;;;;;;:76;;;;72098:318;;;72319:10;:19;;:57;72339:36;68628:17;72339:21;72358:1;72339:14;:18;;:21;;;;:::i;:::-;:25;;:36;;;;:::i;:::-;72319:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72395:5;;72098:318;72078:3;;;;;;;72042:385;;;;72444:22;72460:5;72444:22;;;;;;:::i;:::-;;;;;;;;71422:1052;;;;:::o;68592:53::-;68628:17;68592:53;:::o;68746:28::-;;;;:::o;54910:164::-;55007:4;55031:18;:25;55050:5;55031:25;;;;;;;;;;;;;;;:35;55057:8;55031:35;;;;;;;;;;;;;;;;;;;;;;;;;55024:42;;54910:164;;;;:::o;68783:32::-;;;;;;;;;;;;;:::o;66475:244::-;65752:12;:10;:12::i;:::-;65741:23;;:7;:5;:7::i;:::-;:23;;;65733:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;66584:1:::1;66564:22;;:8;:22;;;;66556:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;66674:8;66645:38;;66666:6;;;;;;;;;;;66645:38;;;;;;;;;;;;66703:8;66694:6;;:17;;;;;;;;;;;;;;;;;;66475:244:::0;:::o;57491:127::-;57556:4;57580:30;57602:7;57580:12;:21;;:30;;;;:::i;:::-;57573:37;;57491:127;;;:::o;668:106::-;721:15;756:10;749:17;;668:106;:::o;63509:192::-;63611:2;63584:15;:24;63600:7;63584:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;63667:7;63663:2;63629:46;;63638:23;63653:7;63638:14;:23::i;:::-;63629:46;;;;;;;;;;;;63509:192;;:::o;44231:123::-;44300:7;44327:19;44335:3;:10;;44327:7;:19::i;:::-;44320:26;;44231:123;;;:::o;57785:355::-;57878:4;57903:16;57911:7;57903;:16::i;:::-;57895:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;57979:13;57995:23;58010:7;57995:14;:23::i;:::-;57979:39;;58048:5;58037:16;;:7;:16;;;:51;;;;58081:7;58057:31;;:20;58069:7;58057:11;:20::i;:::-;:31;;;58037:51;:94;;;;58092:39;58116:5;58123:7;58092:23;:39::i;:::-;58037:94;58029:103;;;57785:355;;;;:::o;60921:599::-;61046:4;61019:31;;:23;61034:7;61019:14;:23::i;:::-;:31;;;61011:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;61147:1;61133:16;;:2;:16;;;;61125:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;61203:39;61224:4;61230:2;61234:7;61203:20;:39::i;:::-;61307:29;61324:1;61328:7;61307:8;:29::i;:::-;61349:35;61376:7;61349:13;:19;61363:4;61349:19;;;;;;;;;;;;;;;:26;;:35;;;;:::i;:::-;;61395:30;61417:7;61395:13;:17;61409:2;61395:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;61438:29;61455:7;61464:2;61438:12;:16;;:29;;;;;:::i;:::-;;61504:7;61500:2;61485:27;;61494:4;61485:27;;;;;;;;;;;;60921:599;;;:::o;36026:137::-;36097:7;36132:22;36136:3;:10;;36148:5;36132:3;:22::i;:::-;36124:31;;36117:38;;36026:137;;;;:::o;44693:236::-;44773:7;44782;44803:11;44816:13;44833:22;44837:3;:10;;44849:5;44833:3;:22::i;:::-;44802:53;;;;44882:3;44874:12;;44912:5;44904:14;;44866:55;;;;;;44693:236;;;;;:::o;62121:100::-;62205:8;62194;:19;;;;;;;;;;;;:::i;:::-;;62121:100;:::o;58483:110::-;58559:26;58569:2;58573:7;58559:26;;;;;;;;;;;;:9;:26::i;:::-;58483:110;;:::o;14224:158::-;14282:7;14315:1;14310;:6;;14302:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;14373:1;14369;:5;14362:12;;14224:158;;;;:::o;14641:220::-;14699:7;14728:1;14723;:6;14719:20;;;14738:1;14731:8;;;;14719:20;14750:9;14766:1;14762;:5;14750:17;;14795:1;14790;14786;:5;;;;;;:10;14778:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;14852:1;14845:8;;;14641:220;;;;;:::o;13762:179::-;13820:7;13840:9;13856:1;13852;:5;13840:17;;13881:1;13876;:6;;13868:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;13932:1;13925:8;;;13762:179;;;;:::o;45979:213::-;46086:7;46137:44;46142:3;:10;;46162:3;46154:12;;46168;46137:4;:44::i;:::-;46129:53;;46106:78;;45979:213;;;;;:::o;35568:114::-;35628:7;35655:19;35663:3;:10;;35655:7;:19::i;:::-;35648:26;;35568:114;;;:::o;56906:272::-;57020:28;57030:4;57036:2;57040:7;57020:9;:28::i;:::-;57067:48;57090:4;57096:2;57100:7;57109:5;57067:22;:48::i;:::-;57059:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;56906:272;;;;:::o;46439:746::-;46495:13;46725:1;46716:5;:10;46712:53;;;46743:10;;;;;;;;;;;;;;;;;;;;;46712:53;46775:12;46790:5;46775:20;;46806:14;46831:78;46846:1;46838:4;:9;46831:78;;46864:8;;;;;;;46895:2;46887:10;;;;;;;;;46831:78;;;46919:19;46951:6;46941:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46919:39;;46969:13;46994:1;46985:6;:10;46969:26;;47013:5;47006:12;;47029:117;47044:1;47036:4;:9;47029:117;;47105:2;47098:4;:9;;;;;;47093:2;:14;47080:29;;47062:6;47069:7;;;;;;;47062:15;;;;;;;;;;;:47;;;;;;;;;;;47132:2;47124:10;;;;;;;;;47029:117;;;47170:6;47156:21;;;;;;46439:746;;;;:::o;67555:830::-;67680:4;67697:20;67720:4;67697:27;;67742:9;67737:525;67761:5;:12;67757:1;:16;67737:525;;;67795:20;67818:5;67824:1;67818:8;;;;;;;;;;;;;;67795:31;;67863:12;67847;:28;67843:408;;68017:12;68031;68000:44;;;;;;;;;:::i;:::-;;;;;;;;;;;;;67990:55;;;;;;67975:70;;67843:408;;;68207:12;68221;68190:44;;;;;;;;;:::i;:::-;;;;;;;;;;;;;68180:55;;;;;;68165:70;;67843:408;67737:525;67775:3;;;;;;;67737:525;;;;68373:4;68357:12;:20;68350:27;;;67555:830;;;;;:::o;43992:151::-;44076:4;44100:35;44110:3;:10;;44130:3;44122:12;;44100:9;:35::i;:::-;44093:42;;43992:151;;;;:::o;40810:110::-;40866:7;40893:3;:12;;:19;;;;40886:26;;40810:110;;;:::o;64314:93::-;;;;:::o;35113:137::-;35183:4;35207:35;35215:3;:10;;35235:5;35227:14;;35207:7;:35::i;:::-;35200:42;;35113:137;;;;:::o;34806:131::-;34873:4;34897:32;34902:3;:10;;34922:5;34914:14;;34897:4;:32::i;:::-;34890:39;;34806:131;;;;:::o;43415:185::-;43504:4;43528:64;43533:3;:10;;43553:3;43545:12;;43583:5;43567:23;;43559:32;;43528:4;:64::i;:::-;43521:71;;43415:185;;;;;:::o;31064:204::-;31131:7;31180:5;31159:3;:11;;:18;;;;:26;31151:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;31242:3;:11;;31254:5;31242:18;;;;;;;;;;;;;;;;31235:25;;31064:204;;;;:::o;41275:279::-;41342:7;41351;41401:5;41379:3;:12;;:19;;;;:27;41371:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;41458:22;41483:3;:12;;41496:5;41483:19;;;;;;;;;;;;;;;;;;41458:44;;41521:5;:10;;;41533:5;:12;;;41513:33;;;;;41275:279;;;;;:::o;58820:250::-;58916:18;58922:2;58926:7;58916:5;:18::i;:::-;58953:54;58984:1;58988:2;58992:7;59001:5;58953:22;:54::i;:::-;58945:117;;;;;;;;;;;;:::i;:::-;;;;;;;;;58820:250;;;:::o;42772:319::-;42866:7;42886:16;42905:3;:12;;:17;42918:3;42905:17;;;;;;;;;;;;42886:36;;42953:1;42941:8;:13;;42956:12;42933:36;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;43023:3;:12;;43047:1;43036:8;:12;43023:26;;;;;;;;;;;;;;;;;;:33;;;43016:40;;;42772:319;;;;;:::o;30611:109::-;30667:7;30694:3;:11;;:18;;;;30687:25;;30611:109;;;:::o;62786:604::-;62907:4;62934:15;:2;:13;;;:15::i;:::-;62929:60;;62973:4;62966:11;;;;62929:60;62999:23;63025:252;63078:45;;;63138:12;:10;:12::i;:::-;63165:4;63184:7;63206:5;63041:181;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63025:252;;;;;;;;;;;;;;;;;:2;:15;;;;:252;;;;;:::i;:::-;62999:278;;63288:13;63315:10;63304:32;;;;;;;;;;;;:::i;:::-;63288:48;;47935:10;63365:16;;63355:26;;;:6;:26;;;;63347:35;;;;62786:604;;;;;;;:::o;40590:125::-;40661:4;40706:1;40685:3;:12;;:17;40698:3;40685:17;;;;;;;;;;;;:22;;40678:29;;40590:125;;;;:::o;28766:1544::-;28832:4;28950:18;28971:3;:12;;:19;28984:5;28971:19;;;;;;;;;;;;28950:40;;29021:1;29007:10;:15;29003:1300;;29369:21;29406:1;29393:10;:14;29369:38;;29422:17;29463:1;29442:3;:11;;:18;;;;:22;29422:42;;29709:17;29729:3;:11;;29741:9;29729:22;;;;;;;;;;;;;;;;29709:42;;29875:9;29846:3;:11;;29858:13;29846:26;;;;;;;;;;;;;;;:38;;;;29994:1;29978:13;:17;29952:3;:12;;:23;29965:9;29952:23;;;;;;;;;;;:43;;;;30104:3;:11;;:17;;;;;;;;;;;;;;;;;;;;;;;;30199:3;:12;;:19;30212:5;30199:19;;;;;;;;;;;30192:26;;;30242:4;30235:11;;;;;;;;29003:1300;30286:5;30279:12;;;28766:1544;;;;;:::o;28176:414::-;28239:4;28261:21;28271:3;28276:5;28261:9;:21::i;:::-;28256:327;;28299:3;:11;;28316:5;28299:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28482:3;:11;;:18;;;;28460:3;:12;;:19;28473:5;28460:19;;;;;;;;;;;:40;;;;28522:4;28515:11;;;;28256:327;28566:5;28559:12;;28176:414;;;;;:::o;38090:692::-;38166:4;38282:16;38301:3;:12;;:17;38314:3;38301:17;;;;;;;;;;;;38282:36;;38347:1;38335:8;:13;38331:444;;;38402:3;:12;;38420:38;;;;;;;;38437:3;38420:38;;;;38450:5;38420:38;;;38402:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38617:3;:12;;:19;;;;38597:3;:12;;:17;38610:3;38597:17;;;;;;;;;;;:39;;;;38658:4;38651:11;;;;;38331:444;38731:5;38695:3;:12;;38719:1;38708:8;:12;38695:26;;;;;;;;;;;;;;;;;;:33;;:41;;;;38758:5;38751:12;;;38090:692;;;;;;:::o;59406:404::-;59500:1;59486:16;;:2;:16;;;;59478:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;59559:16;59567:7;59559;:16::i;:::-;59558:17;59550:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;59621:45;59650:1;59654:2;59658:7;59621:20;:45::i;:::-;59679:30;59701:7;59679:13;:17;59693:2;59679:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;59722:29;59739:7;59748:2;59722:12;:16;;:29;;;;;:::i;:::-;;59794:7;59790:2;59769:33;;59786:1;59769:33;;;;;;;;;;;;59406:404;;:::o;19199:422::-;19259:4;19467:12;19578:7;19566:20;19558:28;;19612:1;19605:4;:8;19598:15;;;19199:422;;;:::o;22117:195::-;22220:12;22252:52;22274:6;22282:4;22288:1;22291:12;22252:21;:52::i;:::-;22245:59;;22117:195;;;;;:::o;30396:129::-;30469:4;30516:1;30493:3;:12;;:19;30506:5;30493:19;;;;;;;;;;;;:24;;30486:31;;30396:129;;;;:::o;23169:530::-;23296:12;23354:5;23329:21;:30;;23321:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;23421:18;23432:6;23421:10;:18::i;:::-;23413:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;23547:12;23561:23;23588:6;:11;;23608:5;23616:4;23588:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23546:75;;;;23639:52;23657:7;23666:10;23678:12;23639:17;:52::i;:::-;23632:59;;;;23169:530;;;;;;:::o;25709:742::-;25824:12;25853:7;25849:595;;;25884:10;25877:17;;;;25849:595;26018:1;25998:10;:17;:21;25994:439;;;26261:10;26255:17;26322:15;26309:10;26305:2;26301:19;26294:44;26209:148;26404:12;26397:20;;;;;;;;;;;:::i;:::-;;;;;;;;25709: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:262::-;;5524:2;5512:9;5503:7;5499:23;5495:32;5492:2;;;5540:1;5537;5530:12;5492:2;5583:1;5608:53;5653:7;5644:6;5633:9;5629:22;5608:53;:::i;:::-;5598:63;;5554:117;5482:196;;;;:::o;5684:260::-;;5791:2;5779:9;5770:7;5766:23;5762:32;5759:2;;;5807:1;5804;5797:12;5759:2;5850:1;5875:52;5919:7;5910:6;5899:9;5895:22;5875:52;:::i;:::-;5865:62;;5821:116;5749:195;;;;:::o;5950:282::-;;6068:2;6056:9;6047:7;6043:23;6039:32;6036:2;;;6084:1;6081;6074:12;6036:2;6127:1;6152:63;6207:7;6198:6;6187:9;6183:22;6152:63;:::i;:::-;6142:73;;6098:127;6026:206;;;;:::o;6238:375::-;;6356:2;6344:9;6335:7;6331:23;6327:32;6324:2;;;6372:1;6369;6362:12;6324:2;6443:1;6432:9;6428:17;6415:31;6473:18;6465:6;6462:30;6459:2;;;6505:1;6502;6495:12;6459:2;6533:63;6588:7;6579:6;6568:9;6564:22;6533:63;:::i;:::-;6523:73;;6386:220;6314:299;;;;:::o;6619:262::-;;6727:2;6715:9;6706:7;6702:23;6698:32;6695:2;;;6743:1;6740;6733:12;6695:2;6786:1;6811:53;6856:7;6847:6;6836:9;6832:22;6811:53;:::i;:::-;6801:63;;6757:117;6685:196;;;;:::o;6887:570::-;;;;7047:2;7035:9;7026:7;7022:23;7018:32;7015:2;;;7063:1;7060;7053:12;7015:2;7106:1;7131:53;7176:7;7167:6;7156:9;7152:22;7131:53;:::i;:::-;7121:63;;7077:117;7261:2;7250:9;7246:18;7233:32;7292:18;7284:6;7281:30;7278:2;;;7324:1;7321;7314:12;7278:2;7360:80;7432:7;7423:6;7412:9;7408:22;7360:80;:::i;:::-;7342:98;;;;7204:246;7005:452;;;;;:::o;7463:179::-;;7553:46;7595:3;7587:6;7553:46;:::i;:::-;7631:4;7626:3;7622:14;7608:28;;7543:99;;;;:::o;7648:142::-;7751:32;7777:5;7751:32;:::i;:::-;7746:3;7739:45;7729:61;;:::o;7796:118::-;7883:24;7901:5;7883:24;:::i;:::-;7878:3;7871:37;7861:53;;:::o;7920:157::-;8025:45;8045:24;8063:5;8045:24;:::i;:::-;8025:45;:::i;:::-;8020:3;8013:58;8003:74;;:::o;8113:732::-;;8261:54;8309:5;8261:54;:::i;:::-;8331:86;8410:6;8405:3;8331:86;:::i;:::-;8324:93;;8441:56;8491:5;8441:56;:::i;:::-;8520:7;8551:1;8536:284;8561:6;8558:1;8555:13;8536:284;;;8637:6;8631:13;8664:63;8723:3;8708:13;8664:63;:::i;:::-;8657:70;;8750:60;8803:6;8750:60;:::i;:::-;8740:70;;8596:224;8583:1;8580;8576:9;8571:14;;8536:284;;;8540:14;8836:3;8829:10;;8237:608;;;;;;;:::o;8851:109::-;8932:21;8947:5;8932:21;:::i;:::-;8927:3;8920:34;8910:50;;:::o;8966:118::-;9053:24;9071:5;9053:24;:::i;:::-;9048:3;9041:37;9031:53;;:::o;9090:157::-;9195:45;9215:24;9233:5;9215:24;:::i;:::-;9195:45;:::i;:::-;9190:3;9183:58;9173:74;;:::o;9253:360::-;;9367:38;9399:5;9367:38;:::i;:::-;9421:70;9484:6;9479:3;9421:70;:::i;:::-;9414:77;;9500:52;9545:6;9540:3;9533:4;9526:5;9522:16;9500:52;:::i;:::-;9577:29;9599:6;9577:29;:::i;:::-;9572:3;9568:39;9561:46;;9343:270;;;;;:::o;9619:373::-;;9751:38;9783:5;9751:38;:::i;:::-;9805:88;9886:6;9881:3;9805:88;:::i;:::-;9798:95;;9902:52;9947:6;9942:3;9935:4;9928:5;9924:16;9902:52;:::i;:::-;9979:6;9974:3;9970:16;9963:23;;9727:265;;;;;:::o;9998:364::-;;10114:39;10147:5;10114:39;:::i;:::-;10169:71;10233:6;10228:3;10169:71;:::i;:::-;10162:78;;10249:52;10294:6;10289:3;10282:4;10275:5;10271:16;10249:52;:::i;:::-;10326:29;10348:6;10326:29;:::i;:::-;10321:3;10317:39;10310:46;;10090:272;;;;;:::o;10368:377::-;;10502:39;10535:5;10502:39;:::i;:::-;10557:89;10639:6;10634:3;10557:89;:::i;:::-;10550:96;;10655:52;10700:6;10695:3;10688:4;10681:5;10677:16;10655:52;:::i;:::-;10732:6;10727:3;10723:16;10716:23;;10478:267;;;;;:::o;10751:366::-;;10914:67;10978:2;10973:3;10914:67;:::i;:::-;10907:74;;11011:34;11007:1;11002:3;10998:11;10991:55;11077:4;11072:2;11067:3;11063:12;11056:26;11108:2;11103:3;11099:12;11092:19;;10897:220;;;:::o;11123:374::-;;11286:67;11350:2;11345:3;11286:67;:::i;:::-;11279:74;;11383:34;11379:1;11374:3;11370:11;11363:55;11449:12;11444:2;11439:3;11435:12;11428:34;11488:2;11483:3;11479:12;11472:19;;11269:228;;;:::o;11503:330::-;;11666:67;11730:2;11725:3;11666:67;:::i;:::-;11659:74;;11763:34;11759:1;11754:3;11750:11;11743:55;11824:2;11819:3;11815:12;11808:19;;11649:184;;;:::o;11839:382::-;;12002:67;12066:2;12061:3;12002:67;:::i;:::-;11995:74;;12099:34;12095:1;12090:3;12086:11;12079:55;12165:20;12160:2;12155:3;12151:12;12144:42;12212:2;12207:3;12203:12;12196:19;;11985:236;;;:::o;12227:370::-;;12390:67;12454:2;12449:3;12390:67;:::i;:::-;12383:74;;12487:34;12483:1;12478:3;12474:11;12467:55;12553:8;12548:2;12543:3;12539:12;12532:30;12588:2;12583:3;12579:12;12572:19;;12373:224;;;:::o;12603:326::-;;12766:67;12830:2;12825:3;12766:67;:::i;:::-;12759:74;;12863:30;12859:1;12854:3;12850:11;12843:51;12920:2;12915:3;12911:12;12904:19;;12749:180;;;:::o;12935:325::-;;13098:67;13162:2;13157:3;13098:67;:::i;:::-;13091:74;;13195:29;13191:1;13186:3;13182:11;13175:50;13251:2;13246:3;13242:12;13235:19;;13081:179;;;:::o;13266:368::-;;13429:67;13493:2;13488:3;13429:67;:::i;:::-;13422:74;;13526:34;13522:1;13517:3;13513:11;13506:55;13592:6;13587:2;13582:3;13578:12;13571:28;13625:2;13620:3;13616:12;13609:19;;13412:222;;;:::o;13640:323::-;;13803:67;13867:2;13862:3;13803:67;:::i;:::-;13796:74;;13900:27;13896:1;13891:3;13887:11;13880:48;13954:2;13949:3;13945:12;13938:19;;13786:177;;;:::o;13969:329::-;;14132:67;14196:2;14191:3;14132:67;:::i;:::-;14125:74;;14229:33;14225:1;14220:3;14216:11;14209:54;14289:2;14284:3;14280:12;14273:19;;14115:183;;;:::o;14304:328::-;;14467:67;14531:2;14526:3;14467:67;:::i;:::-;14460:74;;14564:32;14560:1;14555:3;14551:11;14544:53;14623:2;14618:3;14614:12;14607:19;;14450:182;;;:::o;14638:370::-;;14801:67;14865:2;14860:3;14801:67;:::i;:::-;14794:74;;14898:34;14894:1;14889:3;14885:11;14878:55;14964:8;14959:2;14954:3;14950:12;14943:30;14999:2;14994:3;14990:12;14983:19;;14784:224;;;:::o;15014:376::-;;15177:67;15241:2;15236:3;15177:67;:::i;:::-;15170:74;;15274:34;15270:1;15265:3;15261:11;15254:55;15340:14;15335:2;15330:3;15326:12;15319:36;15381:2;15376:3;15372:12;15365:19;;15160:230;;;:::o;15396:388::-;;15559:67;15623:2;15618:3;15559:67;:::i;:::-;15552:74;;15656:34;15652:1;15647:3;15643:11;15636:55;15722:26;15717:2;15712:3;15708:12;15701:48;15775:2;15770:3;15766:12;15759:19;;15542:242;;;:::o;15790:374::-;;15953:67;16017:2;16012:3;15953:67;:::i;:::-;15946:74;;16050:34;16046:1;16041:3;16037:11;16030:55;16116:12;16111:2;16106:3;16102:12;16095:34;16155:2;16150:3;16146:12;16139:19;;15936:228;;;:::o;16170:366::-;;16333:67;16397:2;16392:3;16333:67;:::i;:::-;16326:74;;16430:34;16426:1;16421:3;16417:11;16410:55;16496:4;16491:2;16486:3;16482:12;16475:26;16527:2;16522:3;16518:12;16511:19;;16316:220;;;:::o;16542:330::-;;16705:67;16769:2;16764:3;16705:67;:::i;:::-;16698:74;;16802:34;16798:1;16793:3;16789:11;16782:55;16863:2;16858:3;16854:12;16847:19;;16688:184;;;:::o;16878:365::-;;17041:67;17105:2;17100:3;17041:67;:::i;:::-;17034:74;;17138:34;17134:1;17129:3;17125:11;17118:55;17204:3;17199:2;17194:3;17190:12;17183:25;17234:2;17229:3;17225:12;17218:19;;17024:219;;;:::o;17249:376::-;;17412:67;17476:2;17471:3;17412:67;:::i;:::-;17405:74;;17509:34;17505:1;17500:3;17496:11;17489:55;17575:14;17570:2;17565:3;17561:12;17554:36;17616:2;17611:3;17607:12;17600:19;;17395:230;;;:::o;17631:330::-;;17794:67;17858:2;17853:3;17794:67;:::i;:::-;17787:74;;17891:34;17887:1;17882:3;17878:11;17871:55;17952:2;17947:3;17943:12;17936:19;;17777:184;;;:::o;17967:373::-;;18130:67;18194:2;18189:3;18130:67;:::i;:::-;18123:74;;18227:34;18223:1;18218:3;18214:11;18207:55;18293:11;18288:2;18283:3;18279:12;18272:33;18331:2;18326:3;18322:12;18315:19;;18113:227;;;:::o;18346:379::-;;18509:67;18573:2;18568:3;18509:67;:::i;:::-;18502:74;;18606:34;18602:1;18597:3;18593:11;18586:55;18672:17;18667:2;18662:3;18658:12;18651:39;18716:2;18711:3;18707:12;18700:19;;18492:233;;;:::o;18731:316::-;;18894:67;18958:2;18953:3;18894:67;:::i;:::-;18887:74;;18991:20;18987:1;18982:3;18978:11;18971:41;19038:2;19033:3;19029:12;19022:19;;18877:170;;;:::o;19053:365::-;;19216:67;19280:2;19275:3;19216:67;:::i;:::-;19209:74;;19313:34;19309:1;19304:3;19300:11;19293:55;19379:3;19374:2;19369:3;19365:12;19358:25;19409:2;19404:3;19400:12;19393:19;;19199:219;;;:::o;19424:381::-;;19587:67;19651:2;19646:3;19587:67;:::i;:::-;19580:74;;19684:34;19680:1;19675:3;19671:11;19664:55;19750:19;19745:2;19740:3;19736:12;19729:41;19796:2;19791:3;19787:12;19780:19;;19570:235;;;:::o;19811:327::-;;19974:67;20038:2;20033:3;19974:67;:::i;:::-;19967:74;;20071:31;20067:1;20062:3;20058:11;20051:52;20129:2;20124:3;20120:12;20113:19;;19957:181;;;:::o;20144:311::-;;20307:67;20371:2;20366:3;20307:67;:::i;:::-;20300:74;;20404:15;20400:1;20395:3;20391:11;20384:36;20446:2;20441:3;20437:12;20430:19;;20290:165;;;:::o;20461:365::-;;20624:67;20688:2;20683:3;20624:67;:::i;:::-;20617:74;;20721:34;20717:1;20712:3;20708:11;20701:55;20787:3;20782:2;20777:3;20773:12;20766:25;20817:2;20812:3;20808:12;20801:19;;20607:219;;;:::o;20832:330::-;;20995:67;21059:2;21054:3;20995:67;:::i;:::-;20988:74;;21092:34;21088:1;21083:3;21079:11;21072:55;21153:2;21148:3;21144:12;21137:19;;20978:184;;;:::o;21168:108::-;21245:24;21263:5;21245:24;:::i;:::-;21240:3;21233:37;21223:53;;:::o;21282:118::-;21369:24;21387:5;21369:24;:::i;:::-;21364:3;21357:37;21347:53;;:::o;21406:256::-;;21533:75;21604:3;21595:6;21533:75;:::i;:::-;21633:2;21628:3;21624:12;21617:19;;21653:3;21646:10;;21522:140;;;;:::o;21668:397::-;;21823:75;21894:3;21885:6;21823:75;:::i;:::-;21923:2;21918:3;21914:12;21907:19;;21936:75;22007:3;21998:6;21936:75;:::i;:::-;22036:2;22031:3;22027:12;22020:19;;22056:3;22049:10;;21812:253;;;;;:::o;22071:271::-;;22223:93;22312:3;22303:6;22223:93;:::i;:::-;22216:100;;22333:3;22326:10;;22205:137;;;;:::o;22348:435::-;;22550:95;22641:3;22632:6;22550:95;:::i;:::-;22543:102;;22662:95;22753:3;22744:6;22662:95;:::i;:::-;22655:102;;22774:3;22767:10;;22532:251;;;;;:::o;22789:222::-;;22920:2;22909:9;22905:18;22897:26;;22933:71;23001:1;22990:9;22986:17;22977:6;22933:71;:::i;:::-;22887:124;;;;:::o;23017:672::-;;23266:3;23255:9;23251:19;23243:27;;23280:87;23364:1;23353:9;23349:17;23340:6;23280:87;:::i;:::-;23377:72;23445:2;23434:9;23430:18;23421:6;23377:72;:::i;:::-;23459;23527:2;23516:9;23512:18;23503:6;23459:72;:::i;:::-;23578:9;23572:4;23568:20;23563:2;23552:9;23548:18;23541:48;23606:76;23677:4;23668:6;23606:76;:::i;:::-;23598:84;;23233:456;;;;;;;:::o;23695:373::-;;23876:2;23865:9;23861:18;23853:26;;23925:9;23919:4;23915:20;23911:1;23900:9;23896:17;23889:47;23953:108;24056:4;24047:6;23953:108;:::i;:::-;23945:116;;23843:225;;;;:::o;24074:210::-;;24199:2;24188:9;24184:18;24176:26;;24212:65;24274:1;24263:9;24259:17;24250:6;24212:65;:::i;:::-;24166:118;;;;:::o;24290:222::-;;24421:2;24410:9;24406:18;24398:26;;24434:71;24502:1;24491:9;24487:17;24478:6;24434:71;:::i;:::-;24388:124;;;;:::o;24518:313::-;;24669:2;24658:9;24654:18;24646:26;;24718:9;24712:4;24708:20;24704:1;24693:9;24689:17;24682:47;24746:78;24819:4;24810:6;24746:78;:::i;:::-;24738:86;;24636:195;;;;:::o;24837:419::-;;25041:2;25030:9;25026:18;25018:26;;25090:9;25084:4;25080:20;25076:1;25065:9;25061:17;25054:47;25118:131;25244:4;25118:131;:::i;:::-;25110:139;;25008:248;;;:::o;25262:419::-;;25466:2;25455:9;25451:18;25443:26;;25515:9;25509:4;25505:20;25501:1;25490:9;25486:17;25479:47;25543:131;25669:4;25543:131;:::i;:::-;25535:139;;25433:248;;;:::o;25687:419::-;;25891:2;25880:9;25876:18;25868:26;;25940:9;25934:4;25930:20;25926:1;25915:9;25911:17;25904:47;25968:131;26094:4;25968:131;:::i;:::-;25960:139;;25858:248;;;:::o;26112:419::-;;26316:2;26305:9;26301:18;26293:26;;26365:9;26359:4;26355:20;26351:1;26340:9;26336:17;26329:47;26393:131;26519:4;26393:131;:::i;:::-;26385:139;;26283:248;;;:::o;26537:419::-;;26741:2;26730:9;26726:18;26718:26;;26790:9;26784:4;26780:20;26776:1;26765:9;26761:17;26754:47;26818:131;26944:4;26818:131;:::i;:::-;26810:139;;26708:248;;;:::o;26962:419::-;;27166:2;27155:9;27151:18;27143:26;;27215:9;27209:4;27205:20;27201:1;27190:9;27186:17;27179:47;27243:131;27369:4;27243:131;:::i;:::-;27235:139;;27133:248;;;:::o;27387:419::-;;27591:2;27580:9;27576:18;27568:26;;27640:9;27634:4;27630:20;27626:1;27615:9;27611:17;27604:47;27668:131;27794:4;27668:131;:::i;:::-;27660:139;;27558:248;;;:::o;27812:419::-;;28016:2;28005:9;28001:18;27993:26;;28065:9;28059:4;28055:20;28051:1;28040:9;28036:17;28029:47;28093:131;28219:4;28093:131;:::i;:::-;28085:139;;27983:248;;;:::o;28237:419::-;;28441:2;28430:9;28426:18;28418:26;;28490:9;28484:4;28480:20;28476:1;28465:9;28461:17;28454:47;28518:131;28644:4;28518:131;:::i;:::-;28510:139;;28408:248;;;:::o;28662:419::-;;28866:2;28855:9;28851:18;28843:26;;28915:9;28909:4;28905:20;28901:1;28890:9;28886:17;28879:47;28943:131;29069:4;28943:131;:::i;:::-;28935:139;;28833:248;;;:::o;29087:419::-;;29291:2;29280:9;29276:18;29268:26;;29340:9;29334:4;29330:20;29326:1;29315:9;29311:17;29304:47;29368:131;29494:4;29368:131;:::i;:::-;29360:139;;29258:248;;;:::o;29512:419::-;;29716:2;29705:9;29701:18;29693:26;;29765:9;29759:4;29755:20;29751:1;29740:9;29736:17;29729:47;29793:131;29919:4;29793:131;:::i;:::-;29785:139;;29683:248;;;:::o;29937:419::-;;30141:2;30130:9;30126:18;30118:26;;30190:9;30184:4;30180:20;30176:1;30165:9;30161:17;30154:47;30218:131;30344:4;30218:131;:::i;:::-;30210:139;;30108:248;;;:::o;30362:419::-;;30566:2;30555:9;30551:18;30543:26;;30615:9;30609:4;30605:20;30601:1;30590:9;30586:17;30579:47;30643:131;30769:4;30643:131;:::i;:::-;30635:139;;30533:248;;;:::o;30787:419::-;;30991:2;30980:9;30976:18;30968:26;;31040:9;31034:4;31030:20;31026:1;31015:9;31011:17;31004:47;31068:131;31194:4;31068:131;:::i;:::-;31060:139;;30958:248;;;:::o;31212:419::-;;31416:2;31405:9;31401:18;31393:26;;31465:9;31459:4;31455:20;31451:1;31440:9;31436:17;31429:47;31493:131;31619:4;31493:131;:::i;:::-;31485:139;;31383:248;;;:::o;31637:419::-;;31841:2;31830:9;31826:18;31818:26;;31890:9;31884:4;31880:20;31876:1;31865:9;31861:17;31854:47;31918:131;32044:4;31918:131;:::i;:::-;31910:139;;31808:248;;;:::o;32062:419::-;;32266:2;32255:9;32251:18;32243:26;;32315:9;32309:4;32305:20;32301:1;32290:9;32286:17;32279:47;32343:131;32469:4;32343:131;:::i;:::-;32335:139;;32233:248;;;:::o;32487:419::-;;32691:2;32680:9;32676:18;32668:26;;32740:9;32734:4;32730:20;32726:1;32715:9;32711:17;32704:47;32768:131;32894:4;32768:131;:::i;:::-;32760:139;;32658:248;;;:::o;32912:419::-;;33116:2;33105:9;33101:18;33093:26;;33165:9;33159:4;33155:20;33151:1;33140:9;33136:17;33129:47;33193:131;33319:4;33193:131;:::i;:::-;33185:139;;33083:248;;;:::o;33337:419::-;;33541:2;33530:9;33526:18;33518:26;;33590:9;33584:4;33580:20;33576:1;33565:9;33561:17;33554:47;33618:131;33744:4;33618:131;:::i;:::-;33610:139;;33508:248;;;:::o;33762:419::-;;33966:2;33955:9;33951:18;33943:26;;34015:9;34009:4;34005:20;34001:1;33990:9;33986:17;33979:47;34043:131;34169:4;34043:131;:::i;:::-;34035:139;;33933:248;;;:::o;34187:419::-;;34391:2;34380:9;34376:18;34368:26;;34440:9;34434:4;34430:20;34426:1;34415:9;34411:17;34404:47;34468:131;34594:4;34468:131;:::i;:::-;34460:139;;34358:248;;;:::o;34612:419::-;;34816:2;34805:9;34801:18;34793:26;;34865:9;34859:4;34855:20;34851:1;34840:9;34836:17;34829:47;34893:131;35019:4;34893:131;:::i;:::-;34885:139;;34783:248;;;:::o;35037:419::-;;35241:2;35230:9;35226:18;35218:26;;35290:9;35284:4;35280:20;35276:1;35265:9;35261:17;35254:47;35318:131;35444:4;35318:131;:::i;:::-;35310:139;;35208:248;;;:::o;35462:419::-;;35666:2;35655:9;35651:18;35643:26;;35715:9;35709:4;35705:20;35701:1;35690:9;35686:17;35679:47;35743:131;35869:4;35743:131;:::i;:::-;35735:139;;35633:248;;;:::o;35887:419::-;;36091:2;36080:9;36076:18;36068:26;;36140:9;36134:4;36130:20;36126:1;36115:9;36111:17;36104:47;36168:131;36294:4;36168:131;:::i;:::-;36160:139;;36058:248;;;:::o;36312:419::-;;36516:2;36505:9;36501:18;36493:26;;36565:9;36559:4;36555:20;36551:1;36540:9;36536:17;36529:47;36593:131;36719:4;36593:131;:::i;:::-;36585:139;;36483:248;;;:::o;36737:419::-;;36941:2;36930:9;36926:18;36918:26;;36990:9;36984:4;36980:20;36976:1;36965:9;36961:17;36954:47;37018:131;37144:4;37018:131;:::i;:::-;37010:139;;36908:248;;;:::o;37162:222::-;;37293:2;37282:9;37278:18;37270:26;;37306:71;37374:1;37363:9;37359:17;37350:6;37306:71;:::i;:::-;37260:124;;;;:::o;37390:278::-;;37456:2;37450:9;37440:19;;37498:4;37490:6;37486:17;37605:6;37593:10;37590:22;37569:18;37557:10;37554:34;37551:62;37548:2;;;37616:13;;:::i;:::-;37548:2;37651:10;37647:2;37640:22;37430:238;;;;:::o;37674:326::-;;37825:18;37817:6;37814:30;37811:2;;;37847:13;;:::i;:::-;37811:2;37927:4;37923:9;37916:4;37908:6;37904:17;37900:33;37892:41;;37988:4;37982;37978:15;37970:23;;37740:260;;;:::o;38006:327::-;;38158:18;38150:6;38147:30;38144:2;;;38180:13;;:::i;:::-;38144:2;38260:4;38256:9;38249:4;38241:6;38237:17;38233:33;38225:41;;38321:4;38315;38311:15;38303:23;;38073:260;;;:::o;38339:132::-;;38429:3;38421:11;;38459:4;38454:3;38450:14;38442:22;;38411:60;;;:::o;38477:114::-;;38578:5;38572:12;38562:22;;38551:40;;;:::o;38597:98::-;;38682:5;38676:12;38666:22;;38655:40;;;:::o;38701:99::-;;38787:5;38781:12;38771:22;;38760:40;;;:::o;38806:113::-;;38908:4;38903:3;38899:14;38891:22;;38881:38;;;:::o;38925:184::-;;39058:6;39053:3;39046:19;39098:4;39093:3;39089:14;39074:29;;39036:73;;;;:::o;39115:168::-;;39232:6;39227:3;39220:19;39272:4;39267:3;39263:14;39248:29;;39210:73;;;;:::o;39289:147::-;;39427:3;39412:18;;39402:34;;;;:::o;39442:169::-;;39560:6;39555:3;39548:19;39600:4;39595:3;39591:14;39576:29;;39538:73;;;;:::o;39617:148::-;;39756:3;39741:18;;39731:34;;;;:::o;39771:96::-;;39837:24;39855:5;39837:24;:::i;:::-;39826:35;;39816:51;;;:::o;39873:104::-;;39947:24;39965:5;39947:24;:::i;:::-;39936:35;;39926:51;;;:::o;39983:90::-;;40060:5;40053:13;40046:21;40035:32;;40025:48;;;:::o;40079:77::-;;40145:5;40134:16;;40124:32;;;:::o;40162:149::-;;40238:66;40231:5;40227:78;40216:89;;40206:105;;;:::o;40317:126::-;;40394:42;40387:5;40383:54;40372:65;;40362:81;;;:::o;40449:77::-;;40515:5;40504:16;;40494:32;;;:::o;40532:154::-;40616:6;40611:3;40606;40593:30;40678:1;40669:6;40664:3;40660:16;40653:27;40583:103;;;:::o;40692:307::-;40760:1;40770:113;40784:6;40781:1;40778:13;40770:113;;;40869:1;40864:3;40860:11;40854:18;40850:1;40845:3;40841:11;40834:39;40806:2;40803:1;40799:10;40794:15;;40770:113;;;40901:6;40898:1;40895:13;40892:2;;;40981:1;40972:6;40967:3;40963:16;40956:27;40892:2;40741:258;;;;:::o;41005:100::-;;41073:26;41093:5;41073:26;:::i;:::-;41062:37;;41052:53;;;:::o;41111:79::-;;41179:5;41168:16;;41158:32;;;:::o;41196:94::-;;41264:20;41278:5;41264:20;:::i;:::-;41253:31;;41243:47;;;:::o;41296:48::-;41329:9;41350:102;;41442:2;41438:7;41433:2;41426:5;41422:14;41418:28;41408:38;;41398:54;;;:::o;41458:94::-;;41539:5;41535:2;41531:14;41510:35;;41500:52;;;:::o;41558:122::-;41631:24;41649:5;41631:24;:::i;:::-;41624:5;41621:35;41611:2;;41670:1;41667;41660:12;41611:2;41601:79;:::o;41686:116::-;41756:21;41771:5;41756:21;:::i;:::-;41749:5;41746:32;41736:2;;41792:1;41789;41782:12;41736:2;41726:76;:::o;41808:122::-;41881:24;41899:5;41881:24;:::i;:::-;41874:5;41871:35;41861:2;;41920:1;41917;41910:12;41861:2;41851:79;:::o;41936:120::-;42008:23;42025:5;42008:23;:::i;:::-;42001:5;41998:34;41988:2;;42046:1;42043;42036:12;41988:2;41978:78;:::o;42062:122::-;42135:24;42153:5;42135:24;:::i;:::-;42128:5;42125:35;42115:2;;42174:1;42171;42164:12;42115:2;42105:79;:::o

Swarm Source

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