ETH Price: $3,328.33 (-2.53%)

Token

The Doge Pound (DOGGY)
 

Overview

Max Total Supply

10,000 DOGGY

Holders

5,064

Market

Volume (24H)

0.0686 ETH

Min Price (24H)

$228.32 @ 0.068600 ETH

Max Price (24H)

$228.32 @ 0.068600 ETH
Balance
0 DOGGY
0x1b5fc2b63ef3c05847a32a1441d591e8aa46058a
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

The Doge Pound is 10,000 art pieces carefully chosen by Professor Elon.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
TheDogePound

Compiler Version
v0.8.1+commit.df193b15

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;


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

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

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

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

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


// File: contracts/TheDogePound.sol

/**
 * @title TheDogePound contract
 * @dev Extends ERC721 Non-Fungible Token Standard basic implementation
 */
contract TheDogePound is ERC721, Ownable {
    using SafeMath for uint256;

    uint256 public startingIndexBlock;
    uint256 public startingIndex;
    uint256 public mintPrice;
    uint256 public maxToMint;
    uint256 public MAX_DOGE_SUPPLY;
    uint256 public REVEAL_TIMESTAMP;

    string public PROVENANCE_HASH = "";
    bool public saleIsActive;

    address wallet1;
    address wallet2;

    constructor() ERC721("The Doge Pound", "DOGGY") {
        MAX_DOGE_SUPPLY = 10000;
        REVEAL_TIMESTAMP = block.timestamp + (86400 * 7);
        mintPrice = 69000000000000000; // 0.069 ETH
        maxToMint = 30;
        saleIsActive = false;
        wallet1 = 0xbb683E735ca23fDb9Ba6F22F3608bf5eD20B845f;
        wallet2 = 0x1097F467E199018e1F2E506cb646431E863C417f;
    }

    /**
     * Get the array of token for owner.
     */
    function tokensOfOwner(address _owner) external view returns(uint256[] memory) {
        uint256 tokenCount = balanceOf(_owner);
        if (tokenCount == 0) {
            return new uint256[](0);
        } else {
            uint256[] memory result = new uint256[](tokenCount);
            for (uint256 index; index < tokenCount; index++) {
                result[index] = tokenOfOwnerByIndex(_owner, index);
            }
            return result;
        }
    }

    /**
     * Check if certain token id is exists.
     */
    function exists(uint256 _tokenId) public view returns (bool) {
        return _exists(_tokenId);
    }

    /**
     * Set price to mint a Doge.
     */
    function setMintPrice(uint256 _price) external onlyOwner {
        mintPrice = _price;
    }

    /**
     * Set maximum count to mint per once.
     */
    function setMaxToMint(uint256 _maxValue) external onlyOwner {
        maxToMint = _maxValue;
    }

    /**
     * Mint Doges by owner
     */
    function reserveDoges(address _to, uint256 _numberOfTokens) external onlyOwner {
        require(_to != address(0), "Invalid address to reserve.");
        uint256 supply = totalSupply();
        uint256 i;
        
        for (i = 0; i < _numberOfTokens; i++) {
            _safeMint(_to, supply + i);
        }
    }

    /**
     * Set reveal timestamp when finished the sale.
     */
    function setRevealTimestamp(uint256 _revealTimeStamp) external onlyOwner {
        REVEAL_TIMESTAMP = _revealTimeStamp;
    } 

    /*     
    * Set provenance once it's calculated
    */
    function setProvenanceHash(string memory _provenanceHash) external onlyOwner {
        PROVENANCE_HASH = _provenanceHash;
    }

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

    /*
    * Pause sale if active, make active if paused
    */
    function setSaleState() external onlyOwner {
        saleIsActive = !saleIsActive;
    }

    /**
    * Mints tokens
    */
    function mintDoges(uint256 numberOfTokens) external payable {
        require(saleIsActive, "Sale must be active to mint");
        require(numberOfTokens <= maxToMint, "Invalid amount to mint per once");
        require(totalSupply().add(numberOfTokens) <= MAX_DOGE_SUPPLY, "Purchase would exceed max supply");
        require(mintPrice.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct");
        
        for(uint256 i = 0; i < numberOfTokens; i++) {
            uint256 mintIndex = totalSupply();
            if (totalSupply() < MAX_DOGE_SUPPLY) {
                _safeMint(msg.sender, mintIndex);
            }
        }

        // If we haven't set the starting index and this is either
        // 1) the last saleable token or 2) the first token to be sold after
        // the end of pre-sale, set the starting index block
        if (startingIndexBlock == 0 && (totalSupply() == MAX_DOGE_SUPPLY || block.timestamp >= REVEAL_TIMESTAMP)) {
            startingIndexBlock = block.number;
        } 
    }

    /**
     * Set the starting index for the collection
     */
    function setStartingIndex() external {
        require(startingIndex == 0, "Starting index is already set");
        require(startingIndexBlock != 0, "Starting index block must be set");
        
        startingIndex = uint256(blockhash(startingIndexBlock)) % MAX_DOGE_SUPPLY;
        // Just a sanity case in the worst case if this function is called late (EVM only stores last 256 block hashes)
        if (block.number.sub(startingIndexBlock) > 255) {
            startingIndex = uint256(blockhash(block.number - 1)) % MAX_DOGE_SUPPLY;
        }
        // Prevent default sequence
        if (startingIndex == 0) {
            startingIndex = startingIndex.add(1);
        }
    }

    /**
     * Set the starting index block for the collection, essentially unblocking
     * setting starting index
     */
    function emergencySetStartingIndexBlock() external onlyOwner {
        require(startingIndex == 0, "Starting index is already set");
        
        startingIndexBlock = block.number;
    }

    function withdraw() external onlyOwner {
        uint256 balance = address(this).balance;
        uint256 walletBalance = balance.mul(50).div(100);
        payable(wallet1).transfer(walletBalance);
        payable(wallet2).transfer(balance.sub(walletBalance));
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_DOGE_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PROVENANCE_HASH","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REVEAL_TIMESTAMP","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":"emergencySetStartingIndexBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxToMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"mintDoges","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_numberOfTokens","type":"uint256"}],"name":"reserveDoges","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxValue","type":"uint256"}],"name":"setMaxToMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_provenanceHash","type":"string"}],"name":"setProvenanceHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_revealTimeStamp","type":"uint256"}],"name":"setRevealTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setStartingIndex","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startingIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startingIndexBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260405180602001604052806000815250601190805190602001906200002b929190620003cc565b503480156200003957600080fd5b506040518060400160405280600e81526020017f54686520446f676520506f756e640000000000000000000000000000000000008152506040518060400160405280600581526020017f444f474759000000000000000000000000000000000000000000000000000000815250620000be6301ffc9a760e01b620002ec60201b60201c565b8160069080519060200190620000d6929190620003cc565b508060079080519060200190620000ef929190620003cc565b50620001086380ac58cd60e01b620002ec60201b60201c565b62000120635b5e139f60e01b620002ec60201b60201c565b6200013863780e9d6360e01b620002ec60201b60201c565b505060006200014c620003c460201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350612710600f8190555062093a8042620002059190620004d6565b60108190555066f5232269808000600d81905550601e600e819055506000601260006101000a81548160ff02191690831515021790555073bb683e735ca23fdb9ba6f22f3608bf5ed20b845f601260016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550731097f467e199018e1f2e506cb646431e863c417f601360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620005fa565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141562000358576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200034f90620004a3565b60405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b828054620003da906200053d565b90600052602060002090601f016020900481019282620003fe57600085556200044a565b82601f106200041957805160ff19168380011785556200044a565b828001600101855582156200044a579182015b82811115620004495782518255916020019190600101906200042c565b5b5090506200045991906200045d565b5090565b5b80821115620004785760008160009055506001016200045e565b5090565b60006200048b601c83620004c5565b91506200049882620005d1565b602082019050919050565b60006020820190508181036000830152620004be816200047c565b9050919050565b600082825260208201905092915050565b6000620004e38262000533565b9150620004f08362000533565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111562000528576200052762000573565b5b828201905092915050565b6000819050919050565b600060028204905060018216806200055657607f821691505b602082108114156200056d576200056c620005a2565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4552433136353a20696e76616c696420696e7465726661636520696400000000600082015250565b6150c2806200060a6000396000f3fe6080604052600436106102465760003560e01c80636c0360eb11610139578063a22cb465116100b6578063e985e9c51161007a578063e985e9c51461085b578063e986655014610898578063eb8d2444146108af578063f2fde38b146108da578063f4a0a52814610903578063ff1b65561461092c57610246565b8063a22cb46514610776578063b88d4fde1461079f578063c87b56dd146107c8578063cb774d4714610805578063e36d64981461083057610246565b80637f599127116100fd5780637f5991271461068f5780638462151c146106b8578063879dafb3146106f55780638da5cb5b1461072057806395d89b411461074b57610246565b80636c0360eb146105d05780637084b2b7146105fb57806370a0823114610624578063715018a6146106615780637d17fcbe1461067857610246565b80631ed40559116101c75780634f558e791161018b5780634f558e79146104c55780634f6ccce71461050257806355f804b31461053f5780636352211e146105685780636817c76c146105a557610246565b80631ed405591461040857806323b872dd1461041f5780632f745c59146104485780633ccfd60b1461048557806342842e0e1461049c57610246565b80630ba133c51161020e5780630ba133c514610342578063109695231461036d5780631421d74f1461039657806318160ddd146103b257806318e20a38146103dd57610246565b8063018a2c371461024b57806301ffc9a71461027457806306fdde03146102b1578063081812fc146102dc578063095ea7b314610319575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d919061397b565b610957565b005b34801561028057600080fd5b5061029b600480360381019061029691906138e8565b6109dd565b6040516102a89190614008565b60405180910390f35b3480156102bd57600080fd5b506102c6610a44565b6040516102d39190614023565b60405180910390f35b3480156102e857600080fd5b5061030360048036038101906102fe919061397b565b610ad6565b6040516103109190613f7f565b60405180910390f35b34801561032557600080fd5b50610340600480360381019061033b91906138ac565b610b5b565b005b34801561034e57600080fd5b50610357610c73565b6040516103649190614405565b60405180910390f35b34801561037957600080fd5b50610394600480360381019061038f919061393a565b610c79565b005b6103b060048036038101906103ab919061397b565b610d0f565b005b3480156103be57600080fd5b506103c7610ed7565b6040516103d49190614405565b60405180910390f35b3480156103e957600080fd5b506103f2610ee8565b6040516103ff9190614405565b60405180910390f35b34801561041457600080fd5b5061041d610eee565b005b34801561042b57600080fd5b50610446600480360381019061044191906137a6565b610f96565b005b34801561045457600080fd5b5061046f600480360381019061046a91906138ac565b610ff6565b60405161047c9190614405565b60405180910390f35b34801561049157600080fd5b5061049a611051565b005b3480156104a857600080fd5b506104c360048036038101906104be91906137a6565b6111e5565b005b3480156104d157600080fd5b506104ec60048036038101906104e7919061397b565b611205565b6040516104f99190614008565b60405180910390f35b34801561050e57600080fd5b506105296004803603810190610524919061397b565b611217565b6040516105369190614405565b60405180910390f35b34801561054b57600080fd5b506105666004803603810190610561919061393a565b61123a565b005b34801561057457600080fd5b5061058f600480360381019061058a919061397b565b6112c2565b60405161059c9190613f7f565b60405180910390f35b3480156105b157600080fd5b506105ba6112f9565b6040516105c79190614405565b60405180910390f35b3480156105dc57600080fd5b506105e56112ff565b6040516105f29190614023565b60405180910390f35b34801561060757600080fd5b50610622600480360381019061061d919061397b565b611391565b005b34801561063057600080fd5b5061064b60048036038101906106469190613741565b611417565b6040516106589190614405565b60405180910390f35b34801561066d57600080fd5b506106766114d6565b005b34801561068457600080fd5b5061068d611613565b005b34801561069b57600080fd5b506106b660048036038101906106b191906138ac565b6116dd565b005b3480156106c457600080fd5b506106df60048036038101906106da9190613741565b61180e565b6040516106ec9190613fe6565b60405180910390f35b34801561070157600080fd5b5061070a61198a565b6040516107179190614405565b60405180910390f35b34801561072c57600080fd5b50610735611990565b6040516107429190613f7f565b60405180910390f35b34801561075757600080fd5b506107606119ba565b60405161076d9190614023565b60405180910390f35b34801561078257600080fd5b5061079d60048036038101906107989190613870565b611a4c565b005b3480156107ab57600080fd5b506107c660048036038101906107c191906137f5565b611bcd565b005b3480156107d457600080fd5b506107ef60048036038101906107ea919061397b565b611c2f565b6040516107fc9190614023565b60405180910390f35b34801561081157600080fd5b5061081a611da2565b6040516108279190614405565b60405180910390f35b34801561083c57600080fd5b50610845611da8565b6040516108529190614405565b60405180910390f35b34801561086757600080fd5b50610882600480360381019061087d919061376a565b611dae565b60405161088f9190614008565b60405180910390f35b3480156108a457600080fd5b506108ad611e42565b005b3480156108bb57600080fd5b506108c4611f53565b6040516108d19190614008565b60405180910390f35b3480156108e657600080fd5b5061090160048036038101906108fc9190613741565b611f66565b005b34801561090f57600080fd5b5061092a6004803603810190610925919061397b565b612112565b005b34801561093857600080fd5b50610941612198565b60405161094e9190614023565b60405180910390f35b61095f612226565b73ffffffffffffffffffffffffffffffffffffffff1661097d611990565b73ffffffffffffffffffffffffffffffffffffffff16146109d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ca90614305565b60405180910390fd5b8060108190555050565b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054610a5390614723565b80601f0160208091040260200160405190810160405280929190818152602001828054610a7f90614723565b8015610acc5780601f10610aa157610100808354040283529160200191610acc565b820191906000526020600020905b815481529060010190602001808311610aaf57829003601f168201915b5050505050905090565b6000610ae18261222e565b610b20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b17906142e5565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610b66826112c2565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610bd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bce90614365565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610bf6612226565b73ffffffffffffffffffffffffffffffffffffffff161480610c255750610c2481610c1f612226565b611dae565b5b610c64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c5b90614225565b60405180910390fd5b610c6e838361224b565b505050565b600e5481565b610c81612226565b73ffffffffffffffffffffffffffffffffffffffff16610c9f611990565b73ffffffffffffffffffffffffffffffffffffffff1614610cf5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cec90614305565b60405180910390fd5b8060119080519060200190610d0b929190613565565b5050565b601260009054906101000a900460ff16610d5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5590614185565b60405180910390fd5b600e54811115610da3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d9a90614065565b60405180910390fd5b600f54610dc082610db2610ed7565b61230490919063ffffffff16565b1115610e01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df890614265565b60405180910390fd5b34610e1782600d5461236290919063ffffffff16565b1115610e58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4f90614145565b60405180910390fd5b60005b81811015610e9f576000610e6d610ed7565b9050600f54610e7a610ed7565b1015610e8b57610e8a33826123dd565b5b508080610e9790614786565b915050610e5b565b506000600b54148015610ec75750600f54610eb8610ed7565b1480610ec657506010544210155b5b15610ed45743600b819055505b50565b6000610ee360026123fb565b905090565b60105481565b610ef6612226565b73ffffffffffffffffffffffffffffffffffffffff16610f14611990565b73ffffffffffffffffffffffffffffffffffffffff1614610f6a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6190614305565b60405180910390fd5b601260009054906101000a900460ff1615601260006101000a81548160ff021916908315150217905550565b610fa7610fa1612226565b82612410565b610fe6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdd906143c5565b60405180910390fd5b610ff18383836124ee565b505050565b600061104982600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061270590919063ffffffff16565b905092915050565b611059612226565b73ffffffffffffffffffffffffffffffffffffffff16611077611990565b73ffffffffffffffffffffffffffffffffffffffff16146110cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c490614305565b60405180910390fd5b600047905060006110fb60646110ed60328561236290919063ffffffff16565b61271f90919063ffffffff16565b9050601260019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611165573d6000803e3d6000fd5b50601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc6111b5838561277790919063ffffffff16565b9081150290604051600060405180830381858888f193505050501580156111e0573d6000803e3d6000fd5b505050565b61120083838360405180602001604052806000815250611bcd565b505050565b60006112108261222e565b9050919050565b60008061122e8360026127d090919063ffffffff16565b50905080915050919050565b611242612226565b73ffffffffffffffffffffffffffffffffffffffff16611260611990565b73ffffffffffffffffffffffffffffffffffffffff16146112b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ad90614305565b60405180910390fd5b6112bf816127fc565b50565b60006112f2826040518060600160405280602981526020016150646029913960026128169092919063ffffffff16565b9050919050565b600d5481565b60606009805461130e90614723565b80601f016020809104026020016040519081016040528092919081815260200182805461133a90614723565b80156113875780601f1061135c57610100808354040283529160200191611387565b820191906000526020600020905b81548152906001019060200180831161136a57829003601f168201915b5050505050905090565b611399612226565b73ffffffffffffffffffffffffffffffffffffffff166113b7611990565b73ffffffffffffffffffffffffffffffffffffffff161461140d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140490614305565b60405180910390fd5b80600e8190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611488576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147f90614245565b60405180910390fd5b6114cf600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612835565b9050919050565b6114de612226565b73ffffffffffffffffffffffffffffffffffffffff166114fc611990565b73ffffffffffffffffffffffffffffffffffffffff1614611552576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161154990614305565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b61161b612226565b73ffffffffffffffffffffffffffffffffffffffff16611639611990565b73ffffffffffffffffffffffffffffffffffffffff161461168f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168690614305565b60405180910390fd5b6000600c54146116d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116cb90614205565b60405180910390fd5b43600b81905550565b6116e5612226565b73ffffffffffffffffffffffffffffffffffffffff16611703611990565b73ffffffffffffffffffffffffffffffffffffffff1614611759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161175090614305565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156117c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c090614385565b60405180910390fd5b60006117d3610ed7565b905060005b82811015611808576117f58482846117f0919061452e565b6123dd565b808061180090614786565b9150506117d8565b50505050565b6060600061181b83611417565b9050600081141561189e57600067ffffffffffffffff811115611867577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156118955781602001602082028036833780820191505090505b50915050611985565b60008167ffffffffffffffff8111156118e0577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405190808252806020026020018201604052801561190e5781602001602082028036833780820191505090505b50905060005b8281101561197e576119268582610ff6565b82828151811061195f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061197690614786565b915050611914565b5080925050505b919050565b600f5481565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600780546119c990614723565b80601f01602080910402602001604051908101604052809291908181526020018280546119f590614723565b8015611a425780601f10611a1757610100808354040283529160200191611a42565b820191906000526020600020905b815481529060010190602001808311611a2557829003601f168201915b5050505050905090565b611a54612226565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ac2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab990614125565b60405180910390fd5b8060056000611acf612226565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611b7c612226565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611bc19190614008565b60405180910390a35050565b611bde611bd8612226565b83612410565b611c1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c14906143c5565b60405180910390fd5b611c298484848461284a565b50505050565b6060611c3a8261222e565b611c79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7090614345565b60405180910390fd5b6000600860008481526020019081526020016000208054611c9990614723565b80601f0160208091040260200160405190810160405280929190818152602001828054611cc590614723565b8015611d125780601f10611ce757610100808354040283529160200191611d12565b820191906000526020600020905b815481529060010190602001808311611cf557829003601f168201915b505050505090506000611d236112ff565b9050600081511415611d39578192505050611d9d565b600082511115611d6e578082604051602001611d56929190613f5b565b60405160208183030381529060405292505050611d9d565b80611d78856128a6565b604051602001611d89929190613f5b565b604051602081830303815290604052925050505b919050565b600c5481565b600b5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000600c5414611e87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e7e90614205565b60405180910390fd5b6000600b541415611ecd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec4906143a5565b60405180910390fd5b600f54600b544060001c611ee191906147cf565b600c8190555060ff611efe600b544361277790919063ffffffff16565b1115611f2957600f54600143611f14919061460f565b4060001c611f2291906147cf565b600c819055505b6000600c541415611f5157611f4a6001600c5461230490919063ffffffff16565b600c819055505b565b601260009054906101000a900460ff1681565b611f6e612226565b73ffffffffffffffffffffffffffffffffffffffff16611f8c611990565b73ffffffffffffffffffffffffffffffffffffffff1614611fe2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fd990614305565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612052576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612049906140a5565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61211a612226565b73ffffffffffffffffffffffffffffffffffffffff16612138611990565b73ffffffffffffffffffffffffffffffffffffffff161461218e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161218590614305565b60405180910390fd5b80600d8190555050565b601180546121a590614723565b80601f01602080910402602001604051908101604052809291908181526020018280546121d190614723565b801561221e5780601f106121f35761010080835404028352916020019161221e565b820191906000526020600020905b81548152906001019060200180831161220157829003601f168201915b505050505081565b600033905090565b6000612244826002612a6590919063ffffffff16565b9050919050565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166122be836112c2565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000808284612313919061452e565b905083811015612358576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161234f906140e5565b60405180910390fd5b8091505092915050565b60008083141561237557600090506123d7565b6000828461238391906145b5565b90508284826123929190614584565b146123d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123c9906142c5565b60405180910390fd5b809150505b92915050565b6123f7828260405180602001604052806000815250612a7f565b5050565b600061240982600001612ada565b9050919050565b600061241b8261222e565b61245a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612451906141c5565b60405180910390fd5b6000612465836112c2565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806124d457508373ffffffffffffffffffffffffffffffffffffffff166124bc84610ad6565b73ffffffffffffffffffffffffffffffffffffffff16145b806124e557506124e48185611dae565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661250e826112c2565b73ffffffffffffffffffffffffffffffffffffffff1614612564576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161255b90614325565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156125d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125cb90614105565b60405180910390fd5b6125df838383612aeb565b6125ea60008261224b565b61263b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612af090919063ffffffff16565b5061268d81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612b0a90919063ffffffff16565b506126a481836002612b249092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006127148360000183612b59565b60001c905092915050565b6000808211612763576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161275a906141e5565b60405180910390fd5b818361276f9190614584565b905092915050565b6000828211156127bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127b390614165565b60405180910390fd5b81836127c8919061460f565b905092915050565b6000806000806127e38660000186612bf3565b915091508160001c8160001c9350935050509250929050565b8060099080519060200190612812929190613565565b5050565b6000612829846000018460001b84612ca3565b60001c90509392505050565b600061284382600001612d6a565b9050919050565b6128558484846124ee565b61286184848484612d7b565b6128a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161289790614085565b60405180910390fd5b50505050565b606060008214156128ee576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612a60565b600082905060005b6000821461292057808061290990614786565b915050600a826129199190614584565b91506128f6565b60008167ffffffffffffffff811115612962577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156129945781602001600182028036833780820191505090505b50905060006001836129a6919061460f565b90508593505b60008414612a5857600a846129c191906147cf565b60306129cd919061452e565b60f81b8282806129dc906146f9565b935081518110612a15577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a84612a519190614584565b93506129ac565b819450505050505b919050565b6000612a77836000018360001b612edf565b905092915050565b612a898383612f02565b612a966000848484612d7b565b612ad5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612acc90614085565b60405180910390fd5b505050565b600081600001805490509050919050565b505050565b6000612b02836000018360001b613090565b905092915050565b6000612b1c836000018360001b61321a565b905092915050565b6000612b50846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b61328a565b90509392505050565b600081836000018054905011612ba4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b9b90614045565b60405180910390fd5b826000018281548110612be0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b60008082846000018054905011612c3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c3690614285565b60405180910390fd5b6000846000018481548110612c7d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008084600101600085815260200190815260200160002054905060008114158390612d05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cfc9190614023565b60405180910390fd5b5084600001600182612d17919061460f565b81548110612d4e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b6000612d9c8473ffffffffffffffffffffffffffffffffffffffff1661339c565b612da95760019050612ed7565b6000612e7063150b7a0260e01b612dbe612226565b888787604051602401612dd49493929190613f9a565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051806060016040528060328152602001615032603291398773ffffffffffffffffffffffffffffffffffffffff166133af9092919063ffffffff16565b9050600081806020019051810190612e889190613911565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612f72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f69906142a5565b60405180910390fd5b612f7b8161222e565b15612fbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fb2906140c5565b60405180910390fd5b612fc760008383612aeb565b61301881600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612b0a90919063ffffffff16565b5061302f81836002612b249092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b6000808360010160008481526020019081526020016000205490506000811461320e5760006001826130c2919061460f565b90506000600186600001805490506130da919061460f565b9050600086600001828154811061311a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110613164577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020018190555060018361317f919061452e565b87600101600083815260200190815260200160002081905550866000018054806131d2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050613214565b60009150505b92915050565b600061322683836133c7565b61327f578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613284565b600090505b92915050565b600080846001016000858152602001908152602001600020549050600081141561333157846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050613395565b8285600001600183613343919061460f565b8154811061337a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600202016001018190555060009150505b9392505050565b600080823b905060008111915050919050565b60606133be84846000856133ea565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b60608247101561342f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613426906141a5565b60405180910390fd5b6134388561339c565b613477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161346e906143e5565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516134a09190613f44565b60006040518083038185875af1925050503d80600081146134dd576040519150601f19603f3d011682016040523d82523d6000602084013e6134e2565b606091505b50915091506134f28282866134fe565b92505050949350505050565b6060831561350e5782905061355e565b6000835111156135215782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135559190614023565b60405180910390fd5b9392505050565b82805461357190614723565b90600052602060002090601f01602090048101928261359357600085556135da565b82601f106135ac57805160ff19168380011785556135da565b828001600101855582156135da579182015b828111156135d95782518255916020019190600101906135be565b5b5090506135e791906135eb565b5090565b5b808211156136045760008160009055506001016135ec565b5090565b600061361b61361684614445565b614420565b90508281526020810184848401111561363357600080fd5b61363e8482856146b7565b509392505050565b600061365961365484614476565b614420565b90508281526020810184848401111561367157600080fd5b61367c8482856146b7565b509392505050565b60008135905061369381614fd5565b92915050565b6000813590506136a881614fec565b92915050565b6000813590506136bd81615003565b92915050565b6000815190506136d281615003565b92915050565b600082601f8301126136e957600080fd5b81356136f9848260208601613608565b91505092915050565b600082601f83011261371357600080fd5b8135613723848260208601613646565b91505092915050565b60008135905061373b8161501a565b92915050565b60006020828403121561375357600080fd5b600061376184828501613684565b91505092915050565b6000806040838503121561377d57600080fd5b600061378b85828601613684565b925050602061379c85828601613684565b9150509250929050565b6000806000606084860312156137bb57600080fd5b60006137c986828701613684565b93505060206137da86828701613684565b92505060406137eb8682870161372c565b9150509250925092565b6000806000806080858703121561380b57600080fd5b600061381987828801613684565b945050602061382a87828801613684565b935050604061383b8782880161372c565b925050606085013567ffffffffffffffff81111561385857600080fd5b613864878288016136d8565b91505092959194509250565b6000806040838503121561388357600080fd5b600061389185828601613684565b92505060206138a285828601613699565b9150509250929050565b600080604083850312156138bf57600080fd5b60006138cd85828601613684565b92505060206138de8582860161372c565b9150509250929050565b6000602082840312156138fa57600080fd5b6000613908848285016136ae565b91505092915050565b60006020828403121561392357600080fd5b6000613931848285016136c3565b91505092915050565b60006020828403121561394c57600080fd5b600082013567ffffffffffffffff81111561396657600080fd5b61397284828501613702565b91505092915050565b60006020828403121561398d57600080fd5b600061399b8482850161372c565b91505092915050565b60006139b08383613f26565b60208301905092915050565b6139c581614643565b82525050565b60006139d6826144b7565b6139e081856144e5565b93506139eb836144a7565b8060005b83811015613a1c578151613a0388826139a4565b9750613a0e836144d8565b9250506001810190506139ef565b5085935050505092915050565b613a3281614655565b82525050565b6000613a43826144c2565b613a4d81856144f6565b9350613a5d8185602086016146c6565b613a66816148bc565b840191505092915050565b6000613a7c826144c2565b613a868185614507565b9350613a968185602086016146c6565b80840191505092915050565b6000613aad826144cd565b613ab78185614512565b9350613ac78185602086016146c6565b613ad0816148bc565b840191505092915050565b6000613ae6826144cd565b613af08185614523565b9350613b008185602086016146c6565b80840191505092915050565b6000613b19602283614512565b9150613b24826148cd565b604082019050919050565b6000613b3c601f83614512565b9150613b478261491c565b602082019050919050565b6000613b5f603283614512565b9150613b6a82614945565b604082019050919050565b6000613b82602683614512565b9150613b8d82614994565b604082019050919050565b6000613ba5601c83614512565b9150613bb0826149e3565b602082019050919050565b6000613bc8601b83614512565b9150613bd382614a0c565b602082019050919050565b6000613beb602483614512565b9150613bf682614a35565b604082019050919050565b6000613c0e601983614512565b9150613c1982614a84565b602082019050919050565b6000613c31601f83614512565b9150613c3c82614aad565b602082019050919050565b6000613c54601e83614512565b9150613c5f82614ad6565b602082019050919050565b6000613c77601b83614512565b9150613c8282614aff565b602082019050919050565b6000613c9a602683614512565b9150613ca582614b28565b604082019050919050565b6000613cbd602c83614512565b9150613cc882614b77565b604082019050919050565b6000613ce0601a83614512565b9150613ceb82614bc6565b602082019050919050565b6000613d03601d83614512565b9150613d0e82614bef565b602082019050919050565b6000613d26603883614512565b9150613d3182614c18565b604082019050919050565b6000613d49602a83614512565b9150613d5482614c67565b604082019050919050565b6000613d6c602083614512565b9150613d7782614cb6565b602082019050919050565b6000613d8f602283614512565b9150613d9a82614cdf565b604082019050919050565b6000613db2602083614512565b9150613dbd82614d2e565b602082019050919050565b6000613dd5602183614512565b9150613de082614d57565b604082019050919050565b6000613df8602c83614512565b9150613e0382614da6565b604082019050919050565b6000613e1b602083614512565b9150613e2682614df5565b602082019050919050565b6000613e3e602983614512565b9150613e4982614e1e565b604082019050919050565b6000613e61602f83614512565b9150613e6c82614e6d565b604082019050919050565b6000613e84602183614512565b9150613e8f82614ebc565b604082019050919050565b6000613ea7601b83614512565b9150613eb282614f0b565b602082019050919050565b6000613eca602083614512565b9150613ed582614f34565b602082019050919050565b6000613eed603183614512565b9150613ef882614f5d565b604082019050919050565b6000613f10601d83614512565b9150613f1b82614fac565b602082019050919050565b613f2f816146ad565b82525050565b613f3e816146ad565b82525050565b6000613f508284613a71565b915081905092915050565b6000613f678285613adb565b9150613f738284613adb565b91508190509392505050565b6000602082019050613f9460008301846139bc565b92915050565b6000608082019050613faf60008301876139bc565b613fbc60208301866139bc565b613fc96040830185613f35565b8181036060830152613fdb8184613a38565b905095945050505050565b6000602082019050818103600083015261400081846139cb565b905092915050565b600060208201905061401d6000830184613a29565b92915050565b6000602082019050818103600083015261403d8184613aa2565b905092915050565b6000602082019050818103600083015261405e81613b0c565b9050919050565b6000602082019050818103600083015261407e81613b2f565b9050919050565b6000602082019050818103600083015261409e81613b52565b9050919050565b600060208201905081810360008301526140be81613b75565b9050919050565b600060208201905081810360008301526140de81613b98565b9050919050565b600060208201905081810360008301526140fe81613bbb565b9050919050565b6000602082019050818103600083015261411e81613bde565b9050919050565b6000602082019050818103600083015261413e81613c01565b9050919050565b6000602082019050818103600083015261415e81613c24565b9050919050565b6000602082019050818103600083015261417e81613c47565b9050919050565b6000602082019050818103600083015261419e81613c6a565b9050919050565b600060208201905081810360008301526141be81613c8d565b9050919050565b600060208201905081810360008301526141de81613cb0565b9050919050565b600060208201905081810360008301526141fe81613cd3565b9050919050565b6000602082019050818103600083015261421e81613cf6565b9050919050565b6000602082019050818103600083015261423e81613d19565b9050919050565b6000602082019050818103600083015261425e81613d3c565b9050919050565b6000602082019050818103600083015261427e81613d5f565b9050919050565b6000602082019050818103600083015261429e81613d82565b9050919050565b600060208201905081810360008301526142be81613da5565b9050919050565b600060208201905081810360008301526142de81613dc8565b9050919050565b600060208201905081810360008301526142fe81613deb565b9050919050565b6000602082019050818103600083015261431e81613e0e565b9050919050565b6000602082019050818103600083015261433e81613e31565b9050919050565b6000602082019050818103600083015261435e81613e54565b9050919050565b6000602082019050818103600083015261437e81613e77565b9050919050565b6000602082019050818103600083015261439e81613e9a565b9050919050565b600060208201905081810360008301526143be81613ebd565b9050919050565b600060208201905081810360008301526143de81613ee0565b9050919050565b600060208201905081810360008301526143fe81613f03565b9050919050565b600060208201905061441a6000830184613f35565b92915050565b600061442a61443b565b90506144368282614755565b919050565b6000604051905090565b600067ffffffffffffffff8211156144605761445f61488d565b5b614469826148bc565b9050602081019050919050565b600067ffffffffffffffff8211156144915761449061488d565b5b61449a826148bc565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000614539826146ad565b9150614544836146ad565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561457957614578614800565b5b828201905092915050565b600061458f826146ad565b915061459a836146ad565b9250826145aa576145a961482f565b5b828204905092915050565b60006145c0826146ad565b91506145cb836146ad565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561460457614603614800565b5b828202905092915050565b600061461a826146ad565b9150614625836146ad565b92508282101561463857614637614800565b5b828203905092915050565b600061464e8261468d565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156146e45780820151818401526020810190506146c9565b838111156146f3576000848401525b50505050565b6000614704826146ad565b9150600082141561471857614717614800565b5b600182039050919050565b6000600282049050600182168061473b57607f821691505b6020821081141561474f5761474e61485e565b5b50919050565b61475e826148bc565b810181811067ffffffffffffffff8211171561477d5761477c61488d565b5b80604052505050565b6000614791826146ad565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156147c4576147c3614800565b5b600182019050919050565b60006147da826146ad565b91506147e5836146ad565b9250826147f5576147f461482f565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008201527f6473000000000000000000000000000000000000000000000000000000000000602082015250565b7f496e76616c696420616d6f756e7420746f206d696e7420706572206f6e636500600082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f45746865722076616c75652073656e74206973206e6f7420636f727265637400600082015250565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000600082015250565b7f53616c65206d7573742062652061637469766520746f206d696e740000000000600082015250565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f536166654d6174683a206469766973696f6e206279207a65726f000000000000600082015250565b7f5374617274696e6720696e64657820697320616c726561647920736574000000600082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f507572636861736520776f756c6420657863656564206d617820737570706c79600082015250565b7f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008201527f6473000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60008201527f7700000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f496e76616c6964206164647265737320746f20726573657276652e0000000000600082015250565b7f5374617274696e6720696e64657820626c6f636b206d75737420626520736574600082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b614fde81614643565b8114614fe957600080fd5b50565b614ff581614655565b811461500057600080fd5b50565b61500c81614661565b811461501757600080fd5b50565b615023816146ad565b811461502e57600080fd5b5056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220365bb54fa065813f546e3f7dfc4bbe8efb3bec4533dd8900be1ce58eb548c30164736f6c63430008010033

Deployed Bytecode

0x6080604052600436106102465760003560e01c80636c0360eb11610139578063a22cb465116100b6578063e985e9c51161007a578063e985e9c51461085b578063e986655014610898578063eb8d2444146108af578063f2fde38b146108da578063f4a0a52814610903578063ff1b65561461092c57610246565b8063a22cb46514610776578063b88d4fde1461079f578063c87b56dd146107c8578063cb774d4714610805578063e36d64981461083057610246565b80637f599127116100fd5780637f5991271461068f5780638462151c146106b8578063879dafb3146106f55780638da5cb5b1461072057806395d89b411461074b57610246565b80636c0360eb146105d05780637084b2b7146105fb57806370a0823114610624578063715018a6146106615780637d17fcbe1461067857610246565b80631ed40559116101c75780634f558e791161018b5780634f558e79146104c55780634f6ccce71461050257806355f804b31461053f5780636352211e146105685780636817c76c146105a557610246565b80631ed405591461040857806323b872dd1461041f5780632f745c59146104485780633ccfd60b1461048557806342842e0e1461049c57610246565b80630ba133c51161020e5780630ba133c514610342578063109695231461036d5780631421d74f1461039657806318160ddd146103b257806318e20a38146103dd57610246565b8063018a2c371461024b57806301ffc9a71461027457806306fdde03146102b1578063081812fc146102dc578063095ea7b314610319575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d919061397b565b610957565b005b34801561028057600080fd5b5061029b600480360381019061029691906138e8565b6109dd565b6040516102a89190614008565b60405180910390f35b3480156102bd57600080fd5b506102c6610a44565b6040516102d39190614023565b60405180910390f35b3480156102e857600080fd5b5061030360048036038101906102fe919061397b565b610ad6565b6040516103109190613f7f565b60405180910390f35b34801561032557600080fd5b50610340600480360381019061033b91906138ac565b610b5b565b005b34801561034e57600080fd5b50610357610c73565b6040516103649190614405565b60405180910390f35b34801561037957600080fd5b50610394600480360381019061038f919061393a565b610c79565b005b6103b060048036038101906103ab919061397b565b610d0f565b005b3480156103be57600080fd5b506103c7610ed7565b6040516103d49190614405565b60405180910390f35b3480156103e957600080fd5b506103f2610ee8565b6040516103ff9190614405565b60405180910390f35b34801561041457600080fd5b5061041d610eee565b005b34801561042b57600080fd5b50610446600480360381019061044191906137a6565b610f96565b005b34801561045457600080fd5b5061046f600480360381019061046a91906138ac565b610ff6565b60405161047c9190614405565b60405180910390f35b34801561049157600080fd5b5061049a611051565b005b3480156104a857600080fd5b506104c360048036038101906104be91906137a6565b6111e5565b005b3480156104d157600080fd5b506104ec60048036038101906104e7919061397b565b611205565b6040516104f99190614008565b60405180910390f35b34801561050e57600080fd5b506105296004803603810190610524919061397b565b611217565b6040516105369190614405565b60405180910390f35b34801561054b57600080fd5b506105666004803603810190610561919061393a565b61123a565b005b34801561057457600080fd5b5061058f600480360381019061058a919061397b565b6112c2565b60405161059c9190613f7f565b60405180910390f35b3480156105b157600080fd5b506105ba6112f9565b6040516105c79190614405565b60405180910390f35b3480156105dc57600080fd5b506105e56112ff565b6040516105f29190614023565b60405180910390f35b34801561060757600080fd5b50610622600480360381019061061d919061397b565b611391565b005b34801561063057600080fd5b5061064b60048036038101906106469190613741565b611417565b6040516106589190614405565b60405180910390f35b34801561066d57600080fd5b506106766114d6565b005b34801561068457600080fd5b5061068d611613565b005b34801561069b57600080fd5b506106b660048036038101906106b191906138ac565b6116dd565b005b3480156106c457600080fd5b506106df60048036038101906106da9190613741565b61180e565b6040516106ec9190613fe6565b60405180910390f35b34801561070157600080fd5b5061070a61198a565b6040516107179190614405565b60405180910390f35b34801561072c57600080fd5b50610735611990565b6040516107429190613f7f565b60405180910390f35b34801561075757600080fd5b506107606119ba565b60405161076d9190614023565b60405180910390f35b34801561078257600080fd5b5061079d60048036038101906107989190613870565b611a4c565b005b3480156107ab57600080fd5b506107c660048036038101906107c191906137f5565b611bcd565b005b3480156107d457600080fd5b506107ef60048036038101906107ea919061397b565b611c2f565b6040516107fc9190614023565b60405180910390f35b34801561081157600080fd5b5061081a611da2565b6040516108279190614405565b60405180910390f35b34801561083c57600080fd5b50610845611da8565b6040516108529190614405565b60405180910390f35b34801561086757600080fd5b50610882600480360381019061087d919061376a565b611dae565b60405161088f9190614008565b60405180910390f35b3480156108a457600080fd5b506108ad611e42565b005b3480156108bb57600080fd5b506108c4611f53565b6040516108d19190614008565b60405180910390f35b3480156108e657600080fd5b5061090160048036038101906108fc9190613741565b611f66565b005b34801561090f57600080fd5b5061092a6004803603810190610925919061397b565b612112565b005b34801561093857600080fd5b50610941612198565b60405161094e9190614023565b60405180910390f35b61095f612226565b73ffffffffffffffffffffffffffffffffffffffff1661097d611990565b73ffffffffffffffffffffffffffffffffffffffff16146109d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ca90614305565b60405180910390fd5b8060108190555050565b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054610a5390614723565b80601f0160208091040260200160405190810160405280929190818152602001828054610a7f90614723565b8015610acc5780601f10610aa157610100808354040283529160200191610acc565b820191906000526020600020905b815481529060010190602001808311610aaf57829003601f168201915b5050505050905090565b6000610ae18261222e565b610b20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b17906142e5565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610b66826112c2565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610bd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bce90614365565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610bf6612226565b73ffffffffffffffffffffffffffffffffffffffff161480610c255750610c2481610c1f612226565b611dae565b5b610c64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c5b90614225565b60405180910390fd5b610c6e838361224b565b505050565b600e5481565b610c81612226565b73ffffffffffffffffffffffffffffffffffffffff16610c9f611990565b73ffffffffffffffffffffffffffffffffffffffff1614610cf5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cec90614305565b60405180910390fd5b8060119080519060200190610d0b929190613565565b5050565b601260009054906101000a900460ff16610d5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5590614185565b60405180910390fd5b600e54811115610da3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d9a90614065565b60405180910390fd5b600f54610dc082610db2610ed7565b61230490919063ffffffff16565b1115610e01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df890614265565b60405180910390fd5b34610e1782600d5461236290919063ffffffff16565b1115610e58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4f90614145565b60405180910390fd5b60005b81811015610e9f576000610e6d610ed7565b9050600f54610e7a610ed7565b1015610e8b57610e8a33826123dd565b5b508080610e9790614786565b915050610e5b565b506000600b54148015610ec75750600f54610eb8610ed7565b1480610ec657506010544210155b5b15610ed45743600b819055505b50565b6000610ee360026123fb565b905090565b60105481565b610ef6612226565b73ffffffffffffffffffffffffffffffffffffffff16610f14611990565b73ffffffffffffffffffffffffffffffffffffffff1614610f6a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6190614305565b60405180910390fd5b601260009054906101000a900460ff1615601260006101000a81548160ff021916908315150217905550565b610fa7610fa1612226565b82612410565b610fe6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdd906143c5565b60405180910390fd5b610ff18383836124ee565b505050565b600061104982600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061270590919063ffffffff16565b905092915050565b611059612226565b73ffffffffffffffffffffffffffffffffffffffff16611077611990565b73ffffffffffffffffffffffffffffffffffffffff16146110cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c490614305565b60405180910390fd5b600047905060006110fb60646110ed60328561236290919063ffffffff16565b61271f90919063ffffffff16565b9050601260019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611165573d6000803e3d6000fd5b50601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc6111b5838561277790919063ffffffff16565b9081150290604051600060405180830381858888f193505050501580156111e0573d6000803e3d6000fd5b505050565b61120083838360405180602001604052806000815250611bcd565b505050565b60006112108261222e565b9050919050565b60008061122e8360026127d090919063ffffffff16565b50905080915050919050565b611242612226565b73ffffffffffffffffffffffffffffffffffffffff16611260611990565b73ffffffffffffffffffffffffffffffffffffffff16146112b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ad90614305565b60405180910390fd5b6112bf816127fc565b50565b60006112f2826040518060600160405280602981526020016150646029913960026128169092919063ffffffff16565b9050919050565b600d5481565b60606009805461130e90614723565b80601f016020809104026020016040519081016040528092919081815260200182805461133a90614723565b80156113875780601f1061135c57610100808354040283529160200191611387565b820191906000526020600020905b81548152906001019060200180831161136a57829003601f168201915b5050505050905090565b611399612226565b73ffffffffffffffffffffffffffffffffffffffff166113b7611990565b73ffffffffffffffffffffffffffffffffffffffff161461140d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140490614305565b60405180910390fd5b80600e8190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611488576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147f90614245565b60405180910390fd5b6114cf600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612835565b9050919050565b6114de612226565b73ffffffffffffffffffffffffffffffffffffffff166114fc611990565b73ffffffffffffffffffffffffffffffffffffffff1614611552576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161154990614305565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b61161b612226565b73ffffffffffffffffffffffffffffffffffffffff16611639611990565b73ffffffffffffffffffffffffffffffffffffffff161461168f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168690614305565b60405180910390fd5b6000600c54146116d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116cb90614205565b60405180910390fd5b43600b81905550565b6116e5612226565b73ffffffffffffffffffffffffffffffffffffffff16611703611990565b73ffffffffffffffffffffffffffffffffffffffff1614611759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161175090614305565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156117c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c090614385565b60405180910390fd5b60006117d3610ed7565b905060005b82811015611808576117f58482846117f0919061452e565b6123dd565b808061180090614786565b9150506117d8565b50505050565b6060600061181b83611417565b9050600081141561189e57600067ffffffffffffffff811115611867577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156118955781602001602082028036833780820191505090505b50915050611985565b60008167ffffffffffffffff8111156118e0577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405190808252806020026020018201604052801561190e5781602001602082028036833780820191505090505b50905060005b8281101561197e576119268582610ff6565b82828151811061195f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061197690614786565b915050611914565b5080925050505b919050565b600f5481565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600780546119c990614723565b80601f01602080910402602001604051908101604052809291908181526020018280546119f590614723565b8015611a425780601f10611a1757610100808354040283529160200191611a42565b820191906000526020600020905b815481529060010190602001808311611a2557829003601f168201915b5050505050905090565b611a54612226565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ac2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab990614125565b60405180910390fd5b8060056000611acf612226565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611b7c612226565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611bc19190614008565b60405180910390a35050565b611bde611bd8612226565b83612410565b611c1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c14906143c5565b60405180910390fd5b611c298484848461284a565b50505050565b6060611c3a8261222e565b611c79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7090614345565b60405180910390fd5b6000600860008481526020019081526020016000208054611c9990614723565b80601f0160208091040260200160405190810160405280929190818152602001828054611cc590614723565b8015611d125780601f10611ce757610100808354040283529160200191611d12565b820191906000526020600020905b815481529060010190602001808311611cf557829003601f168201915b505050505090506000611d236112ff565b9050600081511415611d39578192505050611d9d565b600082511115611d6e578082604051602001611d56929190613f5b565b60405160208183030381529060405292505050611d9d565b80611d78856128a6565b604051602001611d89929190613f5b565b604051602081830303815290604052925050505b919050565b600c5481565b600b5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000600c5414611e87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e7e90614205565b60405180910390fd5b6000600b541415611ecd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec4906143a5565b60405180910390fd5b600f54600b544060001c611ee191906147cf565b600c8190555060ff611efe600b544361277790919063ffffffff16565b1115611f2957600f54600143611f14919061460f565b4060001c611f2291906147cf565b600c819055505b6000600c541415611f5157611f4a6001600c5461230490919063ffffffff16565b600c819055505b565b601260009054906101000a900460ff1681565b611f6e612226565b73ffffffffffffffffffffffffffffffffffffffff16611f8c611990565b73ffffffffffffffffffffffffffffffffffffffff1614611fe2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fd990614305565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612052576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612049906140a5565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61211a612226565b73ffffffffffffffffffffffffffffffffffffffff16612138611990565b73ffffffffffffffffffffffffffffffffffffffff161461218e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161218590614305565b60405180910390fd5b80600d8190555050565b601180546121a590614723565b80601f01602080910402602001604051908101604052809291908181526020018280546121d190614723565b801561221e5780601f106121f35761010080835404028352916020019161221e565b820191906000526020600020905b81548152906001019060200180831161220157829003601f168201915b505050505081565b600033905090565b6000612244826002612a6590919063ffffffff16565b9050919050565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166122be836112c2565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000808284612313919061452e565b905083811015612358576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161234f906140e5565b60405180910390fd5b8091505092915050565b60008083141561237557600090506123d7565b6000828461238391906145b5565b90508284826123929190614584565b146123d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123c9906142c5565b60405180910390fd5b809150505b92915050565b6123f7828260405180602001604052806000815250612a7f565b5050565b600061240982600001612ada565b9050919050565b600061241b8261222e565b61245a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612451906141c5565b60405180910390fd5b6000612465836112c2565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806124d457508373ffffffffffffffffffffffffffffffffffffffff166124bc84610ad6565b73ffffffffffffffffffffffffffffffffffffffff16145b806124e557506124e48185611dae565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661250e826112c2565b73ffffffffffffffffffffffffffffffffffffffff1614612564576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161255b90614325565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156125d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125cb90614105565b60405180910390fd5b6125df838383612aeb565b6125ea60008261224b565b61263b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612af090919063ffffffff16565b5061268d81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612b0a90919063ffffffff16565b506126a481836002612b249092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006127148360000183612b59565b60001c905092915050565b6000808211612763576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161275a906141e5565b60405180910390fd5b818361276f9190614584565b905092915050565b6000828211156127bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127b390614165565b60405180910390fd5b81836127c8919061460f565b905092915050565b6000806000806127e38660000186612bf3565b915091508160001c8160001c9350935050509250929050565b8060099080519060200190612812929190613565565b5050565b6000612829846000018460001b84612ca3565b60001c90509392505050565b600061284382600001612d6a565b9050919050565b6128558484846124ee565b61286184848484612d7b565b6128a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161289790614085565b60405180910390fd5b50505050565b606060008214156128ee576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612a60565b600082905060005b6000821461292057808061290990614786565b915050600a826129199190614584565b91506128f6565b60008167ffffffffffffffff811115612962577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156129945781602001600182028036833780820191505090505b50905060006001836129a6919061460f565b90508593505b60008414612a5857600a846129c191906147cf565b60306129cd919061452e565b60f81b8282806129dc906146f9565b935081518110612a15577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a84612a519190614584565b93506129ac565b819450505050505b919050565b6000612a77836000018360001b612edf565b905092915050565b612a898383612f02565b612a966000848484612d7b565b612ad5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612acc90614085565b60405180910390fd5b505050565b600081600001805490509050919050565b505050565b6000612b02836000018360001b613090565b905092915050565b6000612b1c836000018360001b61321a565b905092915050565b6000612b50846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b61328a565b90509392505050565b600081836000018054905011612ba4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b9b90614045565b60405180910390fd5b826000018281548110612be0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b60008082846000018054905011612c3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c3690614285565b60405180910390fd5b6000846000018481548110612c7d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008084600101600085815260200190815260200160002054905060008114158390612d05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cfc9190614023565b60405180910390fd5b5084600001600182612d17919061460f565b81548110612d4e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b6000612d9c8473ffffffffffffffffffffffffffffffffffffffff1661339c565b612da95760019050612ed7565b6000612e7063150b7a0260e01b612dbe612226565b888787604051602401612dd49493929190613f9a565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051806060016040528060328152602001615032603291398773ffffffffffffffffffffffffffffffffffffffff166133af9092919063ffffffff16565b9050600081806020019051810190612e889190613911565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612f72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f69906142a5565b60405180910390fd5b612f7b8161222e565b15612fbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fb2906140c5565b60405180910390fd5b612fc760008383612aeb565b61301881600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612b0a90919063ffffffff16565b5061302f81836002612b249092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b6000808360010160008481526020019081526020016000205490506000811461320e5760006001826130c2919061460f565b90506000600186600001805490506130da919061460f565b9050600086600001828154811061311a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110613164577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020018190555060018361317f919061452e565b87600101600083815260200190815260200160002081905550866000018054806131d2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050613214565b60009150505b92915050565b600061322683836133c7565b61327f578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613284565b600090505b92915050565b600080846001016000858152602001908152602001600020549050600081141561333157846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050613395565b8285600001600183613343919061460f565b8154811061337a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600202016001018190555060009150505b9392505050565b600080823b905060008111915050919050565b60606133be84846000856133ea565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b60608247101561342f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613426906141a5565b60405180910390fd5b6134388561339c565b613477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161346e906143e5565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516134a09190613f44565b60006040518083038185875af1925050503d80600081146134dd576040519150601f19603f3d011682016040523d82523d6000602084013e6134e2565b606091505b50915091506134f28282866134fe565b92505050949350505050565b6060831561350e5782905061355e565b6000835111156135215782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135559190614023565b60405180910390fd5b9392505050565b82805461357190614723565b90600052602060002090601f01602090048101928261359357600085556135da565b82601f106135ac57805160ff19168380011785556135da565b828001600101855582156135da579182015b828111156135d95782518255916020019190600101906135be565b5b5090506135e791906135eb565b5090565b5b808211156136045760008160009055506001016135ec565b5090565b600061361b61361684614445565b614420565b90508281526020810184848401111561363357600080fd5b61363e8482856146b7565b509392505050565b600061365961365484614476565b614420565b90508281526020810184848401111561367157600080fd5b61367c8482856146b7565b509392505050565b60008135905061369381614fd5565b92915050565b6000813590506136a881614fec565b92915050565b6000813590506136bd81615003565b92915050565b6000815190506136d281615003565b92915050565b600082601f8301126136e957600080fd5b81356136f9848260208601613608565b91505092915050565b600082601f83011261371357600080fd5b8135613723848260208601613646565b91505092915050565b60008135905061373b8161501a565b92915050565b60006020828403121561375357600080fd5b600061376184828501613684565b91505092915050565b6000806040838503121561377d57600080fd5b600061378b85828601613684565b925050602061379c85828601613684565b9150509250929050565b6000806000606084860312156137bb57600080fd5b60006137c986828701613684565b93505060206137da86828701613684565b92505060406137eb8682870161372c565b9150509250925092565b6000806000806080858703121561380b57600080fd5b600061381987828801613684565b945050602061382a87828801613684565b935050604061383b8782880161372c565b925050606085013567ffffffffffffffff81111561385857600080fd5b613864878288016136d8565b91505092959194509250565b6000806040838503121561388357600080fd5b600061389185828601613684565b92505060206138a285828601613699565b9150509250929050565b600080604083850312156138bf57600080fd5b60006138cd85828601613684565b92505060206138de8582860161372c565b9150509250929050565b6000602082840312156138fa57600080fd5b6000613908848285016136ae565b91505092915050565b60006020828403121561392357600080fd5b6000613931848285016136c3565b91505092915050565b60006020828403121561394c57600080fd5b600082013567ffffffffffffffff81111561396657600080fd5b61397284828501613702565b91505092915050565b60006020828403121561398d57600080fd5b600061399b8482850161372c565b91505092915050565b60006139b08383613f26565b60208301905092915050565b6139c581614643565b82525050565b60006139d6826144b7565b6139e081856144e5565b93506139eb836144a7565b8060005b83811015613a1c578151613a0388826139a4565b9750613a0e836144d8565b9250506001810190506139ef565b5085935050505092915050565b613a3281614655565b82525050565b6000613a43826144c2565b613a4d81856144f6565b9350613a5d8185602086016146c6565b613a66816148bc565b840191505092915050565b6000613a7c826144c2565b613a868185614507565b9350613a968185602086016146c6565b80840191505092915050565b6000613aad826144cd565b613ab78185614512565b9350613ac78185602086016146c6565b613ad0816148bc565b840191505092915050565b6000613ae6826144cd565b613af08185614523565b9350613b008185602086016146c6565b80840191505092915050565b6000613b19602283614512565b9150613b24826148cd565b604082019050919050565b6000613b3c601f83614512565b9150613b478261491c565b602082019050919050565b6000613b5f603283614512565b9150613b6a82614945565b604082019050919050565b6000613b82602683614512565b9150613b8d82614994565b604082019050919050565b6000613ba5601c83614512565b9150613bb0826149e3565b602082019050919050565b6000613bc8601b83614512565b9150613bd382614a0c565b602082019050919050565b6000613beb602483614512565b9150613bf682614a35565b604082019050919050565b6000613c0e601983614512565b9150613c1982614a84565b602082019050919050565b6000613c31601f83614512565b9150613c3c82614aad565b602082019050919050565b6000613c54601e83614512565b9150613c5f82614ad6565b602082019050919050565b6000613c77601b83614512565b9150613c8282614aff565b602082019050919050565b6000613c9a602683614512565b9150613ca582614b28565b604082019050919050565b6000613cbd602c83614512565b9150613cc882614b77565b604082019050919050565b6000613ce0601a83614512565b9150613ceb82614bc6565b602082019050919050565b6000613d03601d83614512565b9150613d0e82614bef565b602082019050919050565b6000613d26603883614512565b9150613d3182614c18565b604082019050919050565b6000613d49602a83614512565b9150613d5482614c67565b604082019050919050565b6000613d6c602083614512565b9150613d7782614cb6565b602082019050919050565b6000613d8f602283614512565b9150613d9a82614cdf565b604082019050919050565b6000613db2602083614512565b9150613dbd82614d2e565b602082019050919050565b6000613dd5602183614512565b9150613de082614d57565b604082019050919050565b6000613df8602c83614512565b9150613e0382614da6565b604082019050919050565b6000613e1b602083614512565b9150613e2682614df5565b602082019050919050565b6000613e3e602983614512565b9150613e4982614e1e565b604082019050919050565b6000613e61602f83614512565b9150613e6c82614e6d565b604082019050919050565b6000613e84602183614512565b9150613e8f82614ebc565b604082019050919050565b6000613ea7601b83614512565b9150613eb282614f0b565b602082019050919050565b6000613eca602083614512565b9150613ed582614f34565b602082019050919050565b6000613eed603183614512565b9150613ef882614f5d565b604082019050919050565b6000613f10601d83614512565b9150613f1b82614fac565b602082019050919050565b613f2f816146ad565b82525050565b613f3e816146ad565b82525050565b6000613f508284613a71565b915081905092915050565b6000613f678285613adb565b9150613f738284613adb565b91508190509392505050565b6000602082019050613f9460008301846139bc565b92915050565b6000608082019050613faf60008301876139bc565b613fbc60208301866139bc565b613fc96040830185613f35565b8181036060830152613fdb8184613a38565b905095945050505050565b6000602082019050818103600083015261400081846139cb565b905092915050565b600060208201905061401d6000830184613a29565b92915050565b6000602082019050818103600083015261403d8184613aa2565b905092915050565b6000602082019050818103600083015261405e81613b0c565b9050919050565b6000602082019050818103600083015261407e81613b2f565b9050919050565b6000602082019050818103600083015261409e81613b52565b9050919050565b600060208201905081810360008301526140be81613b75565b9050919050565b600060208201905081810360008301526140de81613b98565b9050919050565b600060208201905081810360008301526140fe81613bbb565b9050919050565b6000602082019050818103600083015261411e81613bde565b9050919050565b6000602082019050818103600083015261413e81613c01565b9050919050565b6000602082019050818103600083015261415e81613c24565b9050919050565b6000602082019050818103600083015261417e81613c47565b9050919050565b6000602082019050818103600083015261419e81613c6a565b9050919050565b600060208201905081810360008301526141be81613c8d565b9050919050565b600060208201905081810360008301526141de81613cb0565b9050919050565b600060208201905081810360008301526141fe81613cd3565b9050919050565b6000602082019050818103600083015261421e81613cf6565b9050919050565b6000602082019050818103600083015261423e81613d19565b9050919050565b6000602082019050818103600083015261425e81613d3c565b9050919050565b6000602082019050818103600083015261427e81613d5f565b9050919050565b6000602082019050818103600083015261429e81613d82565b9050919050565b600060208201905081810360008301526142be81613da5565b9050919050565b600060208201905081810360008301526142de81613dc8565b9050919050565b600060208201905081810360008301526142fe81613deb565b9050919050565b6000602082019050818103600083015261431e81613e0e565b9050919050565b6000602082019050818103600083015261433e81613e31565b9050919050565b6000602082019050818103600083015261435e81613e54565b9050919050565b6000602082019050818103600083015261437e81613e77565b9050919050565b6000602082019050818103600083015261439e81613e9a565b9050919050565b600060208201905081810360008301526143be81613ebd565b9050919050565b600060208201905081810360008301526143de81613ee0565b9050919050565b600060208201905081810360008301526143fe81613f03565b9050919050565b600060208201905061441a6000830184613f35565b92915050565b600061442a61443b565b90506144368282614755565b919050565b6000604051905090565b600067ffffffffffffffff8211156144605761445f61488d565b5b614469826148bc565b9050602081019050919050565b600067ffffffffffffffff8211156144915761449061488d565b5b61449a826148bc565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000614539826146ad565b9150614544836146ad565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561457957614578614800565b5b828201905092915050565b600061458f826146ad565b915061459a836146ad565b9250826145aa576145a961482f565b5b828204905092915050565b60006145c0826146ad565b91506145cb836146ad565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561460457614603614800565b5b828202905092915050565b600061461a826146ad565b9150614625836146ad565b92508282101561463857614637614800565b5b828203905092915050565b600061464e8261468d565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156146e45780820151818401526020810190506146c9565b838111156146f3576000848401525b50505050565b6000614704826146ad565b9150600082141561471857614717614800565b5b600182039050919050565b6000600282049050600182168061473b57607f821691505b6020821081141561474f5761474e61485e565b5b50919050565b61475e826148bc565b810181811067ffffffffffffffff8211171561477d5761477c61488d565b5b80604052505050565b6000614791826146ad565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156147c4576147c3614800565b5b600182019050919050565b60006147da826146ad565b91506147e5836146ad565b9250826147f5576147f461482f565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008201527f6473000000000000000000000000000000000000000000000000000000000000602082015250565b7f496e76616c696420616d6f756e7420746f206d696e7420706572206f6e636500600082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f45746865722076616c75652073656e74206973206e6f7420636f727265637400600082015250565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000600082015250565b7f53616c65206d7573742062652061637469766520746f206d696e740000000000600082015250565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f536166654d6174683a206469766973696f6e206279207a65726f000000000000600082015250565b7f5374617274696e6720696e64657820697320616c726561647920736574000000600082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f507572636861736520776f756c6420657863656564206d617820737570706c79600082015250565b7f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008201527f6473000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60008201527f7700000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f496e76616c6964206164647265737320746f20726573657276652e0000000000600082015250565b7f5374617274696e6720696e64657820626c6f636b206d75737420626520736574600082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b614fde81614643565b8114614fe957600080fd5b50565b614ff581614655565b811461500057600080fd5b50565b61500c81614661565b811461501757600080fd5b50565b615023816146ad565b811461502e57600080fd5b5056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220365bb54fa065813f546e3f7dfc4bbe8efb3bec4533dd8900be1ce58eb548c30164736f6c63430008010033

Deployed Bytecode Sourcemap

66403:5387:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68708:127;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;9976:150;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51027:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53813:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53343:404;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;66592:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68908:129;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69356:1047;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;52821:211;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66660:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69221:90;;;;;;;;;;;;;:::i;:::-;;54703:305;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;52583:162;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71516:271;;;;;;;;;;;;;:::i;:::-;;55079:151;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67820:104;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53109:172;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69045:101;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;50783:177;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66561:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52402:97;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68148:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;50500:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65692:148;;;;;;;;;;;;;:::i;:::-;;71314:194;;;;;;;;;;;;;:::i;:::-;;68302:327;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67272:477;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66623:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65041:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51196:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54106:295;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55301:285;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51371:792;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66526:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66486:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54472:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70479:698;;;;;;;;;;;;;:::i;:::-;;66741:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65995:244;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67984:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;66700:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68708:127;65272:12;:10;:12::i;:::-;65261:23;;:7;:5;:7::i;:::-;:23;;;65253:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;68811:16:::1;68792;:35;;;;68708:127:::0;:::o;9976:150::-;10061:4;10085:20;:33;10106:11;10085:33;;;;;;;;;;;;;;;;;;;;;;;;;;;10078:40;;9976:150;;;:::o;51027:100::-;51081:13;51114:5;51107:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51027:100;:::o;53813:221::-;53889:7;53917:16;53925:7;53917;:16::i;:::-;53909:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;54002:15;:24;54018:7;54002:24;;;;;;;;;;;;;;;;;;;;;53995:31;;53813:221;;;:::o;53343:404::-;53424:13;53440:23;53455:7;53440:14;:23::i;:::-;53424:39;;53488:5;53482:11;;:2;:11;;;;53474:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;53568:5;53552:21;;:12;:10;:12::i;:::-;:21;;;:69;;;;53577:44;53601:5;53608:12;:10;:12::i;:::-;53577:23;:44::i;:::-;53552:69;53544:161;;;;;;;;;;;;:::i;:::-;;;;;;;;;53718:21;53727:2;53731:7;53718:8;:21::i;:::-;53343:404;;;:::o;66592:24::-;;;;:::o;68908:129::-;65272:12;:10;:12::i;:::-;65261:23;;:7;:5;:7::i;:::-;:23;;;65253:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;69014:15:::1;68996;:33;;;;;;;;;;;;:::i;:::-;;68908:129:::0;:::o;69356:1047::-;69435:12;;;;;;;;;;;69427:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;69516:9;;69498:14;:27;;69490:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;69617:15;;69580:33;69598:14;69580:13;:11;:13::i;:::-;:17;;:33;;;;:::i;:::-;:52;;69572:97;;;;;;;;;;;;:::i;:::-;;;;;;;;;69721:9;69688:29;69702:14;69688:9;;:13;;:29;;;;:::i;:::-;:42;;69680:86;;;;;;;;;;;;:::i;:::-;;;;;;;;;69791:9;69787:222;69810:14;69806:1;:18;69787:222;;;69846:17;69866:13;:11;:13::i;:::-;69846:33;;69914:15;;69898:13;:11;:13::i;:::-;:31;69894:104;;;69950:32;69960:10;69972:9;69950;:32::i;:::-;69894:104;69787:222;69826:3;;;;;:::i;:::-;;;;69787:222;;;;70255:1;70233:18;;:23;:100;;;;;70278:15;;70261:13;:11;:13::i;:::-;:32;:71;;;;70316:16;;70297:15;:35;;70261:71;70233:100;70229:166;;;70371:12;70350:18;:33;;;;70229:166;69356:1047;:::o;52821:211::-;52882:7;53003:21;:12;:19;:21::i;:::-;52996:28;;52821:211;:::o;66660:31::-;;;;:::o;69221:90::-;65272:12;:10;:12::i;:::-;65261:23;;:7;:5;:7::i;:::-;:23;;;65253:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;69291:12:::1;;;;;;;;;;;69290:13;69275:12;;:28;;;;;;;;;;;;;;;;;;69221:90::o:0;54703:305::-;54864:41;54883:12;:10;:12::i;:::-;54897:7;54864:18;:41::i;:::-;54856:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;54972:28;54982:4;54988:2;54992:7;54972:9;:28::i;:::-;54703:305;;;:::o;52583:162::-;52680:7;52707:30;52731:5;52707:13;:20;52721:5;52707:20;;;;;;;;;;;;;;;:23;;:30;;;;:::i;:::-;52700:37;;52583:162;;;;:::o;71516:271::-;65272:12;:10;:12::i;:::-;65261:23;;:7;:5;:7::i;:::-;:23;;;65253:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;71566:15:::1;71584:21;71566:39;;71616:21;71640:24;71660:3;71640:15;71652:2;71640:7;:11;;:15;;;;:::i;:::-;:19;;:24;;;;:::i;:::-;71616:48;;71683:7;;;;;;;;;;;71675:25;;:40;71701:13;71675:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;71734:7;;;;;;;;;;;71726:25;;:53;71752:26;71764:13;71752:7;:11;;:26;;;;:::i;:::-;71726:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;65332:1;;71516:271::o:0;55079:151::-;55183:39;55200:4;55206:2;55210:7;55183:39;;;;;;;;;;;;:16;:39::i;:::-;55079:151;;;:::o;67820:104::-;67875:4;67899:17;67907:8;67899:7;:17::i;:::-;67892:24;;67820:104;;;:::o;53109:172::-;53184:7;53205:15;53226:22;53242:5;53226:12;:15;;:22;;;;:::i;:::-;53204:44;;;53266:7;53259:14;;;53109:172;;;:::o;69045:101::-;65272:12;:10;:12::i;:::-;65261:23;;:7;:5;:7::i;:::-;:23;;;65253:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;69118:20:::1;69130:7;69118:11;:20::i;:::-;69045:101:::0;:::o;50783:177::-;50855:7;50882:70;50899:7;50882:70;;;;;;;;;;;;;;;;;:12;:16;;:70;;;;;:::i;:::-;50875:77;;50783:177;;;:::o;66561:24::-;;;;:::o;52402:97::-;52450:13;52483:8;52476:15;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52402:97;:::o;68148:100::-;65272:12;:10;:12::i;:::-;65261:23;;:7;:5;:7::i;:::-;:23;;;65253:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;68231:9:::1;68219;:21;;;;68148:100:::0;:::o;50500:221::-;50572:7;50617:1;50600:19;;:5;:19;;;;50592:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;50684:29;:13;:20;50698:5;50684:20;;;;;;;;;;;;;;;:27;:29::i;:::-;50677:36;;50500:221;;;:::o;65692:148::-;65272:12;:10;:12::i;:::-;65261:23;;:7;:5;:7::i;:::-;:23;;;65253:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;65799:1:::1;65762:40;;65783:6;;;;;;;;;;;65762:40;;;;;;;;;;;;65830:1;65813:6;;:19;;;;;;;;;;;;;;;;;;65692:148::o:0;71314:194::-;65272:12;:10;:12::i;:::-;65261:23;;:7;:5;:7::i;:::-;:23;;;65253:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;71411:1:::1;71394:13;;:18;71386:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;71488:12;71467:18;:33;;;;71314:194::o:0;68302:327::-;65272:12;:10;:12::i;:::-;65261:23;;:7;:5;:7::i;:::-;:23;;;65253:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;68415:1:::1;68400:17;;:3;:17;;;;68392:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;68460:14;68477:13;:11;:13::i;:::-;68460:30;;68501:9;68531:91;68547:15;68543:1;:19;68531:91;;;68584:26;68594:3;68608:1;68599:6;:10;;;;:::i;:::-;68584:9;:26::i;:::-;68564:3;;;;;:::i;:::-;;;;68531:91;;;65332:1;;68302:327:::0;;:::o;67272:477::-;67333:16;67362:18;67383:17;67393:6;67383:9;:17::i;:::-;67362:38;;67429:1;67415:10;:15;67411:331;;;67468:1;67454:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67447:23;;;;;67411:331;67503:23;67543:10;67529:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67503:51;;67574:13;67569:134;67597:10;67589:5;:18;67569:134;;;67653:34;67673:6;67681:5;67653:19;:34::i;:::-;67637:6;67644:5;67637:13;;;;;;;;;;;;;;;;;;;;;:50;;;;;67609:7;;;;;:::i;:::-;;;;67569:134;;;;67724:6;67717:13;;;;67272:477;;;;:::o;66623:30::-;;;;:::o;65041:87::-;65087:7;65114:6;;;;;;;;;;;65107:13;;65041:87;:::o;51196:104::-;51252:13;51285:7;51278:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51196:104;:::o;54106:295::-;54221:12;:10;:12::i;:::-;54209:24;;:8;:24;;;;54201:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;54321:8;54276:18;:32;54295:12;:10;:12::i;:::-;54276:32;;;;;;;;;;;;;;;:42;54309:8;54276:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;54374:8;54345:48;;54360:12;:10;:12::i;:::-;54345:48;;;54384:8;54345:48;;;;;;:::i;:::-;;;;;;;;54106:295;;:::o;55301:285::-;55433:41;55452:12;:10;:12::i;:::-;55466:7;55433:18;:41::i;:::-;55425:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;55539:39;55553:4;55559:2;55563:7;55572:5;55539:13;:39::i;:::-;55301:285;;;;:::o;51371:792::-;51444:13;51478:16;51486:7;51478;:16::i;:::-;51470:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;51559:23;51585:10;:19;51596:7;51585:19;;;;;;;;;;;51559:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51615:18;51636:9;:7;:9::i;:::-;51615:30;;51743:1;51727:4;51721:18;:23;51717:72;;;51768:9;51761:16;;;;;;51717:72;51919:1;51899:9;51893:23;:27;51889:108;;;51968:4;51974:9;51951:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;51937:48;;;;;;51889:108;52129:4;52135:18;:7;:16;:18::i;:::-;52112:42;;;;;;;;;:::i;:::-;;;;;;;;;;;;;52098:57;;;;51371:792;;;;:::o;66526:28::-;;;;:::o;66486:33::-;;;;:::o;54472:164::-;54569:4;54593:18;:25;54612:5;54593:25;;;;;;;;;;;;;;;:35;54619:8;54593:35;;;;;;;;;;;;;;;;;;;;;;;;;54586:42;;54472:164;;;;:::o;70479:698::-;70552:1;70535:13;;:18;70527:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;70628:1;70606:18;;:23;;70598:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;70744:15;;70721:18;;70711:29;70703:38;;:56;;;;:::i;:::-;70687:13;:72;;;;70934:3;70895:36;70912:18;;70895:12;:16;;:36;;;;:::i;:::-;:42;70891:145;;;71009:15;;71003:1;70988:12;:16;;;;:::i;:::-;70978:27;70970:36;;:54;;;;:::i;:::-;70954:13;:70;;;;70891:145;71104:1;71087:13;;:18;71083:87;;;71138:20;71156:1;71138:13;;:17;;:20;;;;:::i;:::-;71122:13;:36;;;;71083:87;70479:698::o;66741:24::-;;;;;;;;;;;;;:::o;65995:244::-;65272:12;:10;:12::i;:::-;65261:23;;:7;:5;:7::i;:::-;:23;;;65253:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;66104:1:::1;66084:22;;:8;:22;;;;66076:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;66194:8;66165:38;;66186:6;;;;;;;;;;;66165:38;;;;;;;;;;;;66223:8;66214:6;;:17;;;;;;;;;;;;;;;;;;65995:244:::0;:::o;67984:94::-;65272:12;:10;:12::i;:::-;65261:23;;:7;:5;:7::i;:::-;:23;;;65253:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;68064:6:::1;68052:9;:18;;;;67984:94:::0;:::o;66700:34::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;657:98::-;710:7;737:10;730:17;;657:98;:::o;57053:127::-;57118:4;57142:30;57164:7;57142:12;:21;;:30;;;;:::i;:::-;57135:37;;57053:127;;;:::o;63071:192::-;63173:2;63146:15;:24;63162:7;63146:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;63229:7;63225:2;63191:46;;63200:23;63215:7;63200:14;:23::i;:::-;63191:46;;;;;;;;;;;;63071:192;;:::o;13501:179::-;13559:7;13579:9;13595:1;13591;:5;;;;:::i;:::-;13579:17;;13620:1;13615;:6;;13607:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;13671:1;13664:8;;;13501:179;;;;:::o;14380:220::-;14438:7;14467:1;14462;:6;14458:20;;;14477:1;14470:8;;;;14458:20;14489:9;14505:1;14501;:5;;;;:::i;:::-;14489:17;;14534:1;14529;14525;:5;;;;:::i;:::-;:10;14517:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;14591:1;14584:8;;;14380:220;;;;;:::o;58045:110::-;58121:26;58131:2;58135:7;58121:26;;;;;;;;;;;;:9;:26::i;:::-;58045:110;;:::o;43869:123::-;43938:7;43965:19;43973:3;:10;;43965:7;:19::i;:::-;43958:26;;43869:123;;;:::o;57347:355::-;57440:4;57465:16;57473:7;57465;:16::i;:::-;57457:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;57541:13;57557:23;57572:7;57557:14;:23::i;:::-;57541:39;;57610:5;57599:16;;:7;:16;;;:51;;;;57643:7;57619:31;;:20;57631:7;57619:11;:20::i;:::-;:31;;;57599:51;:94;;;;57654:39;57678:5;57685:7;57654:23;:39::i;:::-;57599:94;57591:103;;;57347:355;;;;:::o;60483:599::-;60608:4;60581:31;;:23;60596:7;60581:14;:23::i;:::-;:31;;;60573:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;60709:1;60695:16;;:2;:16;;;;60687:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;60765:39;60786:4;60792:2;60796:7;60765:20;:39::i;:::-;60869:29;60886:1;60890:7;60869:8;:29::i;:::-;60911:35;60938:7;60911:13;:19;60925:4;60911:19;;;;;;;;;;;;;;;:26;;:35;;;;:::i;:::-;;60957:30;60979:7;60957:13;:17;60971:2;60957:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;61000:29;61017:7;61026:2;61000:12;:16;;:29;;;;;:::i;:::-;;61066:7;61062:2;61047:27;;61056:4;61047:27;;;;;;;;;;;;60483:599;;;:::o;35697:137::-;35768:7;35803:22;35807:3;:10;;35819:5;35803:3;:22::i;:::-;35795:31;;35788:38;;35697:137;;;;:::o;15078:153::-;15136:7;15168:1;15164;:5;15156:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;15222:1;15218;:5;;;;:::i;:::-;15211:12;;15078:153;;;;:::o;13963:158::-;14021:7;14054:1;14049;:6;;14041:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;14112:1;14108;:5;;;;:::i;:::-;14101:12;;13963:158;;;;:::o;44331:236::-;44411:7;44420;44441:11;44454:13;44471:22;44475:3;:10;;44487:5;44471:3;:22::i;:::-;44440:53;;;;44520:3;44512:12;;44550:5;44542:14;;44504:55;;;;;;44331:236;;;;;:::o;61683:100::-;61767:8;61756;:19;;;;;;;;;;;;:::i;:::-;;61683:100;:::o;45617:213::-;45724:7;45775:44;45780:3;:10;;45800:3;45792:12;;45806;45775:4;:44::i;:::-;45767:53;;45744:78;;45617:213;;;;;:::o;35239:114::-;35299:7;35326:19;35334:3;:10;;35326:7;:19::i;:::-;35319:26;;35239:114;;;:::o;56468:272::-;56582:28;56592:4;56598:2;56602:7;56582:9;:28::i;:::-;56629:48;56652:4;56658:2;56662:7;56671:5;56629:22;:48::i;:::-;56621:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;56468:272;;;;:::o;46044:746::-;46100:13;46330:1;46321:5;:10;46317:53;;;46348:10;;;;;;;;;;;;;;;;;;;;;46317:53;46380:12;46395:5;46380:20;;46411:14;46436:78;46451:1;46443:4;:9;46436:78;;46469:8;;;;;:::i;:::-;;;;46500:2;46492:10;;;;;:::i;:::-;;;46436:78;;;46524:19;46556:6;46546:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46524:39;;46574:13;46599:1;46590:6;:10;;;;:::i;:::-;46574:26;;46618:5;46611:12;;46634:117;46649:1;46641:4;:9;46634:117;;46710:2;46703:4;:9;;;;:::i;:::-;46698:2;:14;;;;:::i;:::-;46685:29;;46667:6;46674:7;;;;;:::i;:::-;;;46667:15;;;;;;;;;;;;;;;;;;;:47;;;;;;;;;;;46737:2;46729:10;;;;;:::i;:::-;;;46634:117;;;46775:6;46761:21;;;;;;46044:746;;;;:::o;43630:151::-;43714:4;43738:35;43748:3;:10;;43768:3;43760:12;;43738:9;:35::i;:::-;43731:42;;43630:151;;;;:::o;58382:250::-;58478:18;58484:2;58488:7;58478:5;:18::i;:::-;58515:54;58546:1;58550:2;58554:7;58563:5;58515:22;:54::i;:::-;58507:117;;;;;;;;;;;;:::i;:::-;;;;;;;;;58382:250;;;:::o;40448:110::-;40504:7;40531:3;:12;;:19;;;;40524:26;;40448:110;;;:::o;63876:93::-;;;;:::o;34784:137::-;34854:4;34878:35;34886:3;:10;;34906:5;34898:14;;34878:7;:35::i;:::-;34871:42;;34784:137;;;;:::o;34477:131::-;34544:4;34568:32;34573:3;:10;;34593:5;34585:14;;34568:4;:32::i;:::-;34561:39;;34477:131;;;;:::o;43053:185::-;43142:4;43166:64;43171:3;:10;;43191:3;43183:12;;43221:5;43205:23;;43197:32;;43166:4;:64::i;:::-;43159:71;;43053:185;;;;;:::o;30737:204::-;30804:7;30853:5;30832:3;:11;;:18;;;;:26;30824:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;30915:3;:11;;30927:5;30915:18;;;;;;;;;;;;;;;;;;;;;;;;30908:25;;30737:204;;;;:::o;40913:279::-;40980:7;40989;41039:5;41017:3;:12;;:19;;;;:27;41009:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;41096:22;41121:3;:12;;41134:5;41121:19;;;;;;;;;;;;;;;;;;;;;;;;;;41096:44;;41159:5;:10;;;41171:5;:12;;;41151:33;;;;;40913:279;;;;;:::o;42410:319::-;42504:7;42524:16;42543:3;:12;;:17;42556:3;42543:17;;;;;;;;;;;;42524:36;;42591:1;42579:8;:13;;42594:12;42571:36;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;42661:3;:12;;42685:1;42674:8;:12;;;;:::i;:::-;42661:26;;;;;;;;;;;;;;;;;;;;;;;;;;:33;;;42654:40;;;42410:319;;;;;:::o;30284:109::-;30340:7;30367:3;:11;;:18;;;;30360:25;;30284:109;;;:::o;62348:604::-;62469:4;62496:15;:2;:13;;;:15::i;:::-;62491:60;;62535:4;62528:11;;;;62491:60;62561:23;62587:252;62640:45;;;62700:12;:10;:12::i;:::-;62727:4;62746:7;62768:5;62603:181;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62587:252;;;;;;;;;;;;;;;;;:2;:15;;;;:252;;;;;:::i;:::-;62561:278;;62850:13;62877:10;62866:32;;;;;;;;;;;;:::i;:::-;62850:48;;47504:10;62927:16;;62917:26;;;:6;:26;;;;62909:35;;;;62348:604;;;;;;;:::o;40228:125::-;40299:4;40344:1;40323:3;:12;;:17;40336:3;40323:17;;;;;;;;;;;;:22;;40316:29;;40228:125;;;;:::o;58968:404::-;59062:1;59048:16;;:2;:16;;;;59040:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;59121:16;59129:7;59121;:16::i;:::-;59120:17;59112:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;59183:45;59212:1;59216:2;59220:7;59183:20;:45::i;:::-;59241:30;59263:7;59241:13;:17;59255:2;59241:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;59284:29;59301:7;59310:2;59284:12;:16;;:29;;;;;:::i;:::-;;59356:7;59352:2;59331:33;;59348:1;59331:33;;;;;;;;;;;;58968:404;;:::o;28439:1544::-;28505:4;28623:18;28644:3;:12;;:19;28657:5;28644:19;;;;;;;;;;;;28623:40;;28694:1;28680:10;:15;28676:1300;;29042:21;29079:1;29066:10;:14;;;;:::i;:::-;29042:38;;29095:17;29136:1;29115:3;:11;;:18;;;;:22;;;;:::i;:::-;29095:42;;29382:17;29402:3;:11;;29414:9;29402:22;;;;;;;;;;;;;;;;;;;;;;;;29382:42;;29548:9;29519:3;:11;;29531:13;29519:26;;;;;;;;;;;;;;;;;;;;;;;:38;;;;29667:1;29651:13;:17;;;;:::i;:::-;29625:3;:12;;:23;29638:9;29625:23;;;;;;;;;;;:43;;;;29777:3;:11;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29872:3;:12;;:19;29885:5;29872:19;;;;;;;;;;;29865:26;;;29915:4;29908:11;;;;;;;;28676:1300;29959:5;29952:12;;;28439:1544;;;;;:::o;27849:414::-;27912:4;27934:21;27944:3;27949:5;27934:9;:21::i;:::-;27929:327;;27972:3;:11;;27989:5;27972:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28155:3;:11;;:18;;;;28133:3;:12;;:19;28146:5;28133:19;;;;;;;;;;;:40;;;;28195:4;28188:11;;;;27929:327;28239:5;28232:12;;27849:414;;;;;:::o;37728:692::-;37804:4;37920:16;37939:3;:12;;:17;37952:3;37939:17;;;;;;;;;;;;37920:36;;37985:1;37973:8;:13;37969:444;;;38040:3;:12;;38058:38;;;;;;;;38075:3;38058:38;;;;38088:5;38058:38;;;38040:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38255:3;:12;;:19;;;;38235:3;:12;;:17;38248:3;38235:17;;;;;;;;;;;:39;;;;38296:4;38289:11;;;;;37969:444;38369:5;38333:3;:12;;38357:1;38346:8;:12;;;;:::i;:::-;38333:26;;;;;;;;;;;;;;;;;;;;;;;;;;:33;;:41;;;;38396:5;38389:12;;;37728:692;;;;;;:::o;18905:422::-;18965:4;19173:12;19284:7;19272:20;19264:28;;19318:1;19311:4;:8;19304:15;;;18905:422;;;:::o;21823:195::-;21926:12;21958:52;21980:6;21988:4;21994:1;21997:12;21958:21;:52::i;:::-;21951:59;;21823:195;;;;;:::o;30069:129::-;30142:4;30189:1;30166:3;:12;;:19;30179:5;30166:19;;;;;;;;;;;;:24;;30159:31;;30069:129;;;;:::o;22875:530::-;23002:12;23060:5;23035:21;:30;;23027:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;23127:18;23138:6;23127:10;:18::i;:::-;23119:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;23253:12;23267:23;23294:6;:11;;23314:5;23322:4;23294:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23252:75;;;;23345:52;23363:7;23372:10;23384:12;23345:17;:52::i;:::-;23338:59;;;;22875:530;;;;;;:::o;25415:742::-;25530:12;25559:7;25555:595;;;25590:10;25583:17;;;;25555:595;25724:1;25704:10;:17;:21;25700:439;;;25967:10;25961:17;26028:15;26015:10;26011:2;26007:19;26000:44;25915:148;26110:12;26103:20;;;;;;;;;;;:::i;:::-;;;;;;;;25415:742;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:343:1:-;;109:65;125:48;166:6;125:48;:::i;:::-;109:65;:::i;:::-;100:74;;197:6;190:5;183:21;235:4;228:5;224:16;273:3;264:6;259:3;255:16;252:25;249:2;;;290:1;287;280:12;249:2;303:41;337:6;332:3;327;303:41;:::i;:::-;90:260;;;;;;:::o;356:345::-;;459:66;475:49;517:6;475:49;:::i;:::-;459:66;:::i;:::-;450:75;;548:6;541:5;534:21;586:4;579:5;575:16;624:3;615:6;610:3;606:16;603:25;600:2;;;641:1;638;631:12;600:2;654:41;688:6;683:3;678;654:41;:::i;:::-;440:261;;;;;;:::o;707:139::-;;791:6;778:20;769:29;;807:33;834:5;807:33;:::i;:::-;759:87;;;;:::o;852:133::-;;933:6;920:20;911:29;;949:30;973:5;949:30;:::i;:::-;901:84;;;;:::o;991:137::-;;1074:6;1061:20;1052:29;;1090:32;1116:5;1090:32;:::i;:::-;1042:86;;;;:::o;1134:141::-;;1221:6;1215:13;1206:22;;1237:32;1263:5;1237:32;:::i;:::-;1196:79;;;;:::o;1294:271::-;;1398:3;1391:4;1383:6;1379:17;1375:27;1365:2;;1416:1;1413;1406:12;1365:2;1456:6;1443:20;1481:78;1555:3;1547:6;1540:4;1532:6;1528:17;1481:78;:::i;:::-;1472:87;;1355:210;;;;;:::o;1585:273::-;;1690:3;1683:4;1675:6;1671:17;1667:27;1657:2;;1708:1;1705;1698:12;1657:2;1748:6;1735:20;1773:79;1848:3;1840:6;1833:4;1825:6;1821:17;1773:79;:::i;:::-;1764:88;;1647:211;;;;;:::o;1864:139::-;;1948:6;1935:20;1926:29;;1964:33;1991:5;1964:33;:::i;:::-;1916:87;;;;:::o;2009:262::-;;2117:2;2105:9;2096:7;2092:23;2088:32;2085:2;;;2133:1;2130;2123:12;2085:2;2176:1;2201:53;2246:7;2237:6;2226:9;2222:22;2201:53;:::i;:::-;2191:63;;2147:117;2075:196;;;;:::o;2277:407::-;;;2402:2;2390:9;2381:7;2377:23;2373:32;2370:2;;;2418:1;2415;2408:12;2370:2;2461:1;2486:53;2531:7;2522:6;2511:9;2507:22;2486:53;:::i;:::-;2476:63;;2432:117;2588:2;2614:53;2659:7;2650:6;2639:9;2635:22;2614:53;:::i;:::-;2604:63;;2559:118;2360:324;;;;;:::o;2690:552::-;;;;2832:2;2820:9;2811:7;2807:23;2803:32;2800:2;;;2848:1;2845;2838:12;2800:2;2891:1;2916:53;2961:7;2952:6;2941:9;2937:22;2916:53;:::i;:::-;2906:63;;2862:117;3018:2;3044:53;3089:7;3080:6;3069:9;3065:22;3044:53;:::i;:::-;3034:63;;2989:118;3146:2;3172:53;3217:7;3208:6;3197:9;3193:22;3172:53;:::i;:::-;3162:63;;3117:118;2790:452;;;;;:::o;3248:809::-;;;;;3416:3;3404:9;3395:7;3391:23;3387:33;3384:2;;;3433:1;3430;3423:12;3384:2;3476:1;3501:53;3546:7;3537:6;3526:9;3522:22;3501:53;:::i;:::-;3491:63;;3447:117;3603:2;3629:53;3674:7;3665:6;3654:9;3650:22;3629:53;:::i;:::-;3619:63;;3574:118;3731:2;3757:53;3802:7;3793:6;3782:9;3778:22;3757:53;:::i;:::-;3747:63;;3702:118;3887:2;3876:9;3872:18;3859:32;3918:18;3910:6;3907:30;3904:2;;;3950:1;3947;3940:12;3904:2;3978:62;4032:7;4023:6;4012:9;4008:22;3978:62;:::i;:::-;3968:72;;3830:220;3374:683;;;;;;;:::o;4063:401::-;;;4185:2;4173:9;4164:7;4160:23;4156:32;4153:2;;;4201:1;4198;4191:12;4153:2;4244:1;4269:53;4314:7;4305:6;4294:9;4290:22;4269:53;:::i;:::-;4259:63;;4215:117;4371:2;4397:50;4439:7;4430:6;4419:9;4415:22;4397:50;:::i;:::-;4387:60;;4342:115;4143:321;;;;;:::o;4470:407::-;;;4595:2;4583:9;4574:7;4570:23;4566:32;4563:2;;;4611:1;4608;4601:12;4563:2;4654:1;4679:53;4724:7;4715:6;4704:9;4700:22;4679:53;:::i;:::-;4669:63;;4625:117;4781:2;4807:53;4852:7;4843:6;4832:9;4828:22;4807:53;:::i;:::-;4797:63;;4752:118;4553:324;;;;;:::o;4883:260::-;;4990:2;4978:9;4969:7;4965:23;4961:32;4958:2;;;5006:1;5003;4996:12;4958:2;5049:1;5074:52;5118:7;5109:6;5098:9;5094:22;5074:52;:::i;:::-;5064:62;;5020:116;4948:195;;;;:::o;5149:282::-;;5267:2;5255:9;5246:7;5242:23;5238:32;5235:2;;;5283:1;5280;5273:12;5235:2;5326:1;5351:63;5406:7;5397:6;5386:9;5382:22;5351:63;:::i;:::-;5341:73;;5297:127;5225:206;;;;:::o;5437:375::-;;5555:2;5543:9;5534:7;5530:23;5526:32;5523:2;;;5571:1;5568;5561:12;5523:2;5642:1;5631:9;5627:17;5614:31;5672:18;5664:6;5661:30;5658:2;;;5704:1;5701;5694:12;5658:2;5732:63;5787:7;5778:6;5767:9;5763:22;5732:63;:::i;:::-;5722:73;;5585:220;5513:299;;;;:::o;5818:262::-;;5926:2;5914:9;5905:7;5901:23;5897:32;5894:2;;;5942:1;5939;5932:12;5894:2;5985:1;6010:53;6055:7;6046:6;6035:9;6031:22;6010:53;:::i;:::-;6000:63;;5956:117;5884:196;;;;:::o;6086:179::-;;6176:46;6218:3;6210:6;6176:46;:::i;:::-;6254:4;6249:3;6245:14;6231:28;;6166:99;;;;:::o;6271:118::-;6358:24;6376:5;6358:24;:::i;:::-;6353:3;6346:37;6336:53;;:::o;6425:732::-;;6573:54;6621:5;6573:54;:::i;:::-;6643:86;6722:6;6717:3;6643:86;:::i;:::-;6636:93;;6753:56;6803:5;6753:56;:::i;:::-;6832:7;6863:1;6848:284;6873:6;6870:1;6867:13;6848:284;;;6949:6;6943:13;6976:63;7035:3;7020:13;6976:63;:::i;:::-;6969:70;;7062:60;7115:6;7062:60;:::i;:::-;7052:70;;6908:224;6895:1;6892;6888:9;6883:14;;6848:284;;;6852:14;7148:3;7141:10;;6549:608;;;;;;;:::o;7163:109::-;7244:21;7259:5;7244:21;:::i;:::-;7239:3;7232:34;7222:50;;:::o;7278:360::-;;7392:38;7424:5;7392:38;:::i;:::-;7446:70;7509:6;7504:3;7446:70;:::i;:::-;7439:77;;7525:52;7570:6;7565:3;7558:4;7551:5;7547:16;7525:52;:::i;:::-;7602:29;7624:6;7602:29;:::i;:::-;7597:3;7593:39;7586:46;;7368:270;;;;;:::o;7644:373::-;;7776:38;7808:5;7776:38;:::i;:::-;7830:88;7911:6;7906:3;7830:88;:::i;:::-;7823:95;;7927:52;7972:6;7967:3;7960:4;7953:5;7949:16;7927:52;:::i;:::-;8004:6;7999:3;7995:16;7988:23;;7752:265;;;;;:::o;8023:364::-;;8139:39;8172:5;8139:39;:::i;:::-;8194:71;8258:6;8253:3;8194:71;:::i;:::-;8187:78;;8274:52;8319:6;8314:3;8307:4;8300:5;8296:16;8274:52;:::i;:::-;8351:29;8373:6;8351:29;:::i;:::-;8346:3;8342:39;8335:46;;8115:272;;;;;:::o;8393:377::-;;8527:39;8560:5;8527:39;:::i;:::-;8582:89;8664:6;8659:3;8582:89;:::i;:::-;8575:96;;8680:52;8725:6;8720:3;8713:4;8706:5;8702:16;8680:52;:::i;:::-;8757:6;8752:3;8748:16;8741:23;;8503:267;;;;;:::o;8776:366::-;;8939:67;9003:2;8998:3;8939:67;:::i;:::-;8932:74;;9015:93;9104:3;9015:93;:::i;:::-;9133:2;9128:3;9124:12;9117:19;;8922:220;;;:::o;9148:366::-;;9311:67;9375:2;9370:3;9311:67;:::i;:::-;9304:74;;9387:93;9476:3;9387:93;:::i;:::-;9505:2;9500:3;9496:12;9489:19;;9294:220;;;:::o;9520:366::-;;9683:67;9747:2;9742:3;9683:67;:::i;:::-;9676:74;;9759:93;9848:3;9759:93;:::i;:::-;9877:2;9872:3;9868:12;9861:19;;9666:220;;;:::o;9892:366::-;;10055:67;10119:2;10114:3;10055:67;:::i;:::-;10048:74;;10131:93;10220:3;10131:93;:::i;:::-;10249:2;10244:3;10240:12;10233:19;;10038:220;;;:::o;10264:366::-;;10427:67;10491:2;10486:3;10427:67;:::i;:::-;10420:74;;10503:93;10592:3;10503:93;:::i;:::-;10621:2;10616:3;10612:12;10605:19;;10410:220;;;:::o;10636:366::-;;10799:67;10863:2;10858:3;10799:67;:::i;:::-;10792:74;;10875:93;10964:3;10875:93;:::i;:::-;10993:2;10988:3;10984:12;10977:19;;10782:220;;;:::o;11008:366::-;;11171:67;11235:2;11230:3;11171:67;:::i;:::-;11164:74;;11247:93;11336:3;11247:93;:::i;:::-;11365:2;11360:3;11356:12;11349:19;;11154:220;;;:::o;11380:366::-;;11543:67;11607:2;11602:3;11543:67;:::i;:::-;11536:74;;11619:93;11708:3;11619:93;:::i;:::-;11737:2;11732:3;11728:12;11721:19;;11526:220;;;:::o;11752:366::-;;11915:67;11979:2;11974:3;11915:67;:::i;:::-;11908:74;;11991:93;12080:3;11991:93;:::i;:::-;12109:2;12104:3;12100:12;12093:19;;11898:220;;;:::o;12124:366::-;;12287:67;12351:2;12346:3;12287:67;:::i;:::-;12280:74;;12363:93;12452:3;12363:93;:::i;:::-;12481:2;12476:3;12472:12;12465:19;;12270:220;;;:::o;12496:366::-;;12659:67;12723:2;12718:3;12659:67;:::i;:::-;12652:74;;12735:93;12824:3;12735:93;:::i;:::-;12853:2;12848:3;12844:12;12837:19;;12642:220;;;:::o;12868:366::-;;13031:67;13095:2;13090:3;13031:67;:::i;:::-;13024:74;;13107:93;13196:3;13107:93;:::i;:::-;13225:2;13220:3;13216:12;13209:19;;13014:220;;;:::o;13240:366::-;;13403:67;13467:2;13462:3;13403:67;:::i;:::-;13396:74;;13479:93;13568:3;13479:93;:::i;:::-;13597:2;13592:3;13588:12;13581:19;;13386:220;;;:::o;13612:366::-;;13775:67;13839:2;13834:3;13775:67;:::i;:::-;13768:74;;13851:93;13940:3;13851:93;:::i;:::-;13969:2;13964:3;13960:12;13953:19;;13758:220;;;:::o;13984:366::-;;14147:67;14211:2;14206:3;14147:67;:::i;:::-;14140:74;;14223:93;14312:3;14223:93;:::i;:::-;14341:2;14336:3;14332:12;14325:19;;14130:220;;;:::o;14356:366::-;;14519:67;14583:2;14578:3;14519:67;:::i;:::-;14512:74;;14595:93;14684:3;14595:93;:::i;:::-;14713:2;14708:3;14704:12;14697:19;;14502:220;;;:::o;14728:366::-;;14891:67;14955:2;14950:3;14891:67;:::i;:::-;14884:74;;14967:93;15056:3;14967:93;:::i;:::-;15085:2;15080:3;15076:12;15069:19;;14874:220;;;:::o;15100:366::-;;15263:67;15327:2;15322:3;15263:67;:::i;:::-;15256:74;;15339:93;15428:3;15339:93;:::i;:::-;15457:2;15452:3;15448:12;15441:19;;15246:220;;;:::o;15472:366::-;;15635:67;15699:2;15694:3;15635:67;:::i;:::-;15628:74;;15711:93;15800:3;15711:93;:::i;:::-;15829:2;15824:3;15820:12;15813:19;;15618:220;;;:::o;15844:366::-;;16007:67;16071:2;16066:3;16007:67;:::i;:::-;16000:74;;16083:93;16172:3;16083:93;:::i;:::-;16201:2;16196:3;16192:12;16185:19;;15990:220;;;:::o;16216:366::-;;16379:67;16443:2;16438:3;16379:67;:::i;:::-;16372:74;;16455:93;16544:3;16455:93;:::i;:::-;16573:2;16568:3;16564:12;16557:19;;16362:220;;;:::o;16588:366::-;;16751:67;16815:2;16810:3;16751:67;:::i;:::-;16744:74;;16827:93;16916:3;16827:93;:::i;:::-;16945:2;16940:3;16936:12;16929:19;;16734:220;;;:::o;16960:366::-;;17123:67;17187:2;17182:3;17123:67;:::i;:::-;17116:74;;17199:93;17288:3;17199:93;:::i;:::-;17317:2;17312:3;17308:12;17301:19;;17106:220;;;:::o;17332:366::-;;17495:67;17559:2;17554:3;17495:67;:::i;:::-;17488:74;;17571:93;17660:3;17571:93;:::i;:::-;17689:2;17684:3;17680:12;17673:19;;17478:220;;;:::o;17704:366::-;;17867:67;17931:2;17926:3;17867:67;:::i;:::-;17860:74;;17943:93;18032:3;17943:93;:::i;:::-;18061:2;18056:3;18052:12;18045:19;;17850:220;;;:::o;18076:366::-;;18239:67;18303:2;18298:3;18239:67;:::i;:::-;18232:74;;18315:93;18404:3;18315:93;:::i;:::-;18433:2;18428:3;18424:12;18417:19;;18222:220;;;:::o;18448:366::-;;18611:67;18675:2;18670:3;18611:67;:::i;:::-;18604:74;;18687:93;18776:3;18687:93;:::i;:::-;18805:2;18800:3;18796:12;18789:19;;18594:220;;;:::o;18820:366::-;;18983:67;19047:2;19042:3;18983:67;:::i;:::-;18976:74;;19059:93;19148:3;19059:93;:::i;:::-;19177:2;19172:3;19168:12;19161:19;;18966:220;;;:::o;19192:366::-;;19355:67;19419:2;19414:3;19355:67;:::i;:::-;19348:74;;19431:93;19520:3;19431:93;:::i;:::-;19549:2;19544:3;19540:12;19533:19;;19338:220;;;:::o;19564:366::-;;19727:67;19791:2;19786:3;19727:67;:::i;:::-;19720:74;;19803:93;19892:3;19803:93;:::i;:::-;19921:2;19916:3;19912:12;19905:19;;19710:220;;;:::o;19936:108::-;20013:24;20031:5;20013:24;:::i;:::-;20008:3;20001:37;19991:53;;:::o;20050:118::-;20137:24;20155:5;20137:24;:::i;:::-;20132:3;20125:37;20115:53;;:::o;20174:271::-;;20326:93;20415:3;20406:6;20326:93;:::i;:::-;20319:100;;20436:3;20429:10;;20308:137;;;;:::o;20451:435::-;;20653:95;20744:3;20735:6;20653:95;:::i;:::-;20646:102;;20765:95;20856:3;20847:6;20765:95;:::i;:::-;20758:102;;20877:3;20870:10;;20635:251;;;;;:::o;20892:222::-;;21023:2;21012:9;21008:18;21000:26;;21036:71;21104:1;21093:9;21089:17;21080:6;21036:71;:::i;:::-;20990:124;;;;:::o;21120:640::-;;21353:3;21342:9;21338:19;21330:27;;21367:71;21435:1;21424:9;21420:17;21411:6;21367:71;:::i;:::-;21448:72;21516:2;21505:9;21501:18;21492:6;21448:72;:::i;:::-;21530;21598:2;21587:9;21583:18;21574:6;21530:72;:::i;:::-;21649:9;21643:4;21639:20;21634:2;21623:9;21619:18;21612:48;21677:76;21748:4;21739:6;21677:76;:::i;:::-;21669:84;;21320:440;;;;;;;:::o;21766:373::-;;21947:2;21936:9;21932:18;21924:26;;21996:9;21990:4;21986:20;21982:1;21971:9;21967:17;21960:47;22024:108;22127:4;22118:6;22024:108;:::i;:::-;22016:116;;21914:225;;;;:::o;22145:210::-;;22270:2;22259:9;22255:18;22247:26;;22283:65;22345:1;22334:9;22330:17;22321:6;22283:65;:::i;:::-;22237:118;;;;:::o;22361:313::-;;22512:2;22501:9;22497:18;22489:26;;22561:9;22555:4;22551:20;22547:1;22536:9;22532:17;22525:47;22589:78;22662:4;22653:6;22589:78;:::i;:::-;22581:86;;22479:195;;;;:::o;22680:419::-;;22884:2;22873:9;22869:18;22861:26;;22933:9;22927:4;22923:20;22919:1;22908:9;22904:17;22897:47;22961:131;23087:4;22961:131;:::i;:::-;22953:139;;22851:248;;;:::o;23105:419::-;;23309:2;23298:9;23294:18;23286:26;;23358:9;23352:4;23348:20;23344:1;23333:9;23329:17;23322:47;23386:131;23512:4;23386:131;:::i;:::-;23378:139;;23276:248;;;:::o;23530:419::-;;23734:2;23723:9;23719:18;23711:26;;23783:9;23777:4;23773:20;23769:1;23758:9;23754:17;23747:47;23811:131;23937:4;23811:131;:::i;:::-;23803:139;;23701:248;;;:::o;23955:419::-;;24159:2;24148:9;24144:18;24136:26;;24208:9;24202:4;24198:20;24194:1;24183:9;24179:17;24172:47;24236:131;24362:4;24236:131;:::i;:::-;24228:139;;24126:248;;;:::o;24380:419::-;;24584:2;24573:9;24569:18;24561:26;;24633:9;24627:4;24623:20;24619:1;24608:9;24604:17;24597:47;24661:131;24787:4;24661:131;:::i;:::-;24653:139;;24551:248;;;:::o;24805:419::-;;25009:2;24998:9;24994:18;24986:26;;25058:9;25052:4;25048:20;25044:1;25033:9;25029:17;25022:47;25086:131;25212:4;25086:131;:::i;:::-;25078:139;;24976:248;;;:::o;25230:419::-;;25434:2;25423:9;25419:18;25411:26;;25483:9;25477:4;25473:20;25469:1;25458:9;25454:17;25447:47;25511:131;25637:4;25511:131;:::i;:::-;25503:139;;25401:248;;;:::o;25655:419::-;;25859:2;25848:9;25844:18;25836:26;;25908:9;25902:4;25898:20;25894:1;25883:9;25879:17;25872:47;25936:131;26062:4;25936:131;:::i;:::-;25928:139;;25826:248;;;:::o;26080:419::-;;26284:2;26273:9;26269:18;26261:26;;26333:9;26327:4;26323:20;26319:1;26308:9;26304:17;26297:47;26361:131;26487:4;26361:131;:::i;:::-;26353:139;;26251:248;;;:::o;26505:419::-;;26709:2;26698:9;26694:18;26686:26;;26758:9;26752:4;26748:20;26744:1;26733:9;26729:17;26722:47;26786:131;26912:4;26786:131;:::i;:::-;26778:139;;26676:248;;;:::o;26930:419::-;;27134:2;27123:9;27119:18;27111:26;;27183:9;27177:4;27173:20;27169:1;27158:9;27154:17;27147:47;27211:131;27337:4;27211:131;:::i;:::-;27203:139;;27101:248;;;:::o;27355:419::-;;27559:2;27548:9;27544:18;27536:26;;27608:9;27602:4;27598:20;27594:1;27583:9;27579:17;27572:47;27636:131;27762:4;27636:131;:::i;:::-;27628:139;;27526:248;;;:::o;27780:419::-;;27984:2;27973:9;27969:18;27961:26;;28033:9;28027:4;28023:20;28019:1;28008:9;28004:17;27997:47;28061:131;28187:4;28061:131;:::i;:::-;28053:139;;27951:248;;;:::o;28205:419::-;;28409:2;28398:9;28394:18;28386:26;;28458:9;28452:4;28448:20;28444:1;28433:9;28429:17;28422:47;28486:131;28612:4;28486:131;:::i;:::-;28478:139;;28376:248;;;:::o;28630:419::-;;28834:2;28823:9;28819:18;28811:26;;28883:9;28877:4;28873:20;28869:1;28858:9;28854:17;28847:47;28911:131;29037:4;28911:131;:::i;:::-;28903:139;;28801:248;;;:::o;29055:419::-;;29259:2;29248:9;29244:18;29236:26;;29308:9;29302:4;29298:20;29294:1;29283:9;29279:17;29272:47;29336:131;29462:4;29336:131;:::i;:::-;29328:139;;29226:248;;;:::o;29480:419::-;;29684:2;29673:9;29669:18;29661:26;;29733:9;29727:4;29723:20;29719:1;29708:9;29704:17;29697:47;29761:131;29887:4;29761:131;:::i;:::-;29753:139;;29651:248;;;:::o;29905:419::-;;30109:2;30098:9;30094:18;30086:26;;30158:9;30152:4;30148:20;30144:1;30133:9;30129:17;30122:47;30186:131;30312:4;30186:131;:::i;:::-;30178:139;;30076:248;;;:::o;30330:419::-;;30534:2;30523:9;30519:18;30511:26;;30583:9;30577:4;30573:20;30569:1;30558:9;30554:17;30547:47;30611:131;30737:4;30611:131;:::i;:::-;30603:139;;30501:248;;;:::o;30755:419::-;;30959:2;30948:9;30944:18;30936:26;;31008:9;31002:4;30998:20;30994:1;30983:9;30979:17;30972:47;31036:131;31162:4;31036:131;:::i;:::-;31028:139;;30926:248;;;:::o;31180:419::-;;31384:2;31373:9;31369:18;31361:26;;31433:9;31427:4;31423:20;31419:1;31408:9;31404:17;31397:47;31461:131;31587:4;31461:131;:::i;:::-;31453:139;;31351:248;;;:::o;31605:419::-;;31809:2;31798:9;31794:18;31786:26;;31858:9;31852:4;31848:20;31844:1;31833:9;31829:17;31822:47;31886:131;32012:4;31886:131;:::i;:::-;31878:139;;31776:248;;;:::o;32030:419::-;;32234:2;32223:9;32219:18;32211:26;;32283:9;32277:4;32273:20;32269:1;32258:9;32254:17;32247:47;32311:131;32437:4;32311:131;:::i;:::-;32303:139;;32201:248;;;:::o;32455:419::-;;32659:2;32648:9;32644:18;32636:26;;32708:9;32702:4;32698:20;32694:1;32683:9;32679:17;32672:47;32736:131;32862:4;32736:131;:::i;:::-;32728:139;;32626:248;;;:::o;32880:419::-;;33084:2;33073:9;33069:18;33061:26;;33133:9;33127:4;33123:20;33119:1;33108:9;33104:17;33097:47;33161:131;33287:4;33161:131;:::i;:::-;33153:139;;33051:248;;;:::o;33305:419::-;;33509:2;33498:9;33494:18;33486:26;;33558:9;33552:4;33548:20;33544:1;33533:9;33529:17;33522:47;33586:131;33712:4;33586:131;:::i;:::-;33578:139;;33476:248;;;:::o;33730:419::-;;33934:2;33923:9;33919:18;33911:26;;33983:9;33977:4;33973:20;33969:1;33958:9;33954:17;33947:47;34011:131;34137:4;34011:131;:::i;:::-;34003:139;;33901:248;;;:::o;34155:419::-;;34359:2;34348:9;34344:18;34336:26;;34408:9;34402:4;34398:20;34394:1;34383:9;34379:17;34372:47;34436:131;34562:4;34436:131;:::i;:::-;34428:139;;34326:248;;;:::o;34580:419::-;;34784:2;34773:9;34769:18;34761:26;;34833:9;34827:4;34823:20;34819:1;34808:9;34804:17;34797:47;34861:131;34987:4;34861:131;:::i;:::-;34853:139;;34751:248;;;:::o;35005:419::-;;35209:2;35198:9;35194:18;35186:26;;35258:9;35252:4;35248:20;35244:1;35233:9;35229:17;35222:47;35286:131;35412:4;35286:131;:::i;:::-;35278:139;;35176:248;;;:::o;35430:222::-;;35561:2;35550:9;35546:18;35538:26;;35574:71;35642:1;35631:9;35627:17;35618:6;35574:71;:::i;:::-;35528:124;;;;:::o;35658:129::-;;35719:20;;:::i;:::-;35709:30;;35748:33;35776:4;35768:6;35748:33;:::i;:::-;35699:88;;;:::o;35793:75::-;;35859:2;35853:9;35843:19;;35833:35;:::o;35874:307::-;;36025:18;36017:6;36014:30;36011:2;;;36047:18;;:::i;:::-;36011:2;36085:29;36107:6;36085:29;:::i;:::-;36077:37;;36169:4;36163;36159:15;36151:23;;35940:241;;;:::o;36187:308::-;;36339:18;36331:6;36328:30;36325:2;;;36361:18;;:::i;:::-;36325:2;36399:29;36421:6;36399:29;:::i;:::-;36391:37;;36483:4;36477;36473:15;36465:23;;36254:241;;;:::o;36501:132::-;;36591:3;36583:11;;36621:4;36616:3;36612:14;36604:22;;36573:60;;;:::o;36639:114::-;;36740:5;36734:12;36724:22;;36713:40;;;:::o;36759:98::-;;36844:5;36838:12;36828:22;;36817:40;;;:::o;36863:99::-;;36949:5;36943:12;36933:22;;36922:40;;;:::o;36968:113::-;;37070:4;37065:3;37061:14;37053:22;;37043:38;;;:::o;37087:184::-;;37220:6;37215:3;37208:19;37260:4;37255:3;37251:14;37236:29;;37198:73;;;;:::o;37277:168::-;;37394:6;37389:3;37382:19;37434:4;37429:3;37425:14;37410:29;;37372:73;;;;:::o;37451:147::-;;37589:3;37574:18;;37564:34;;;;:::o;37604:169::-;;37722:6;37717:3;37710:19;37762:4;37757:3;37753:14;37738:29;;37700:73;;;;:::o;37779:148::-;;37918:3;37903:18;;37893:34;;;;:::o;37933:305::-;;37992:20;38010:1;37992:20;:::i;:::-;37987:25;;38026:20;38044:1;38026:20;:::i;:::-;38021:25;;38180:1;38112:66;38108:74;38105:1;38102:81;38099:2;;;38186:18;;:::i;:::-;38099:2;38230:1;38227;38223:9;38216:16;;37977:261;;;;:::o;38244:185::-;;38301:20;38319:1;38301:20;:::i;:::-;38296:25;;38335:20;38353:1;38335:20;:::i;:::-;38330:25;;38374:1;38364:2;;38379:18;;:::i;:::-;38364:2;38421:1;38418;38414:9;38409:14;;38286:143;;;;:::o;38435:348::-;;38498:20;38516:1;38498:20;:::i;:::-;38493:25;;38532:20;38550:1;38532:20;:::i;:::-;38527:25;;38720:1;38652:66;38648:74;38645:1;38642:81;38637:1;38630:9;38623:17;38619:105;38616:2;;;38727:18;;:::i;:::-;38616:2;38775:1;38772;38768:9;38757:20;;38483:300;;;;:::o;38789:191::-;;38849:20;38867:1;38849:20;:::i;:::-;38844:25;;38883:20;38901:1;38883:20;:::i;:::-;38878:25;;38922:1;38919;38916:8;38913:2;;;38927:18;;:::i;:::-;38913:2;38972:1;38969;38965:9;38957:17;;38834:146;;;;:::o;38986:96::-;;39052:24;39070:5;39052:24;:::i;:::-;39041:35;;39031:51;;;:::o;39088:90::-;;39165:5;39158:13;39151:21;39140:32;;39130:48;;;:::o;39184:149::-;;39260:66;39253:5;39249:78;39238:89;;39228:105;;;:::o;39339:126::-;;39416:42;39409:5;39405:54;39394:65;;39384:81;;;:::o;39471:77::-;;39537:5;39526:16;;39516:32;;;:::o;39554:154::-;39638:6;39633:3;39628;39615:30;39700:1;39691:6;39686:3;39682:16;39675:27;39605:103;;;:::o;39714:307::-;39782:1;39792:113;39806:6;39803:1;39800:13;39792:113;;;39891:1;39886:3;39882:11;39876:18;39872:1;39867:3;39863:11;39856:39;39828:2;39825:1;39821:10;39816:15;;39792:113;;;39923:6;39920:1;39917:13;39914:2;;;40003:1;39994:6;39989:3;39985:16;39978:27;39914:2;39763:258;;;;:::o;40027:171::-;;40089:24;40107:5;40089:24;:::i;:::-;40080:33;;40135:4;40128:5;40125:15;40122:2;;;40143:18;;:::i;:::-;40122:2;40190:1;40183:5;40179:13;40172:20;;40070:128;;;:::o;40204:320::-;;40285:1;40279:4;40275:12;40265:22;;40332:1;40326:4;40322:12;40353:18;40343:2;;40409:4;40401:6;40397:17;40387:27;;40343:2;40471;40463:6;40460:14;40440:18;40437:38;40434:2;;;40490:18;;:::i;:::-;40434:2;40255:269;;;;:::o;40530:281::-;40613:27;40635:4;40613:27;:::i;:::-;40605:6;40601:40;40743:6;40731:10;40728:22;40707:18;40695:10;40692:34;40689:62;40686:2;;;40754:18;;:::i;:::-;40686:2;40794:10;40790:2;40783:22;40573:238;;;:::o;40817:233::-;;40879:24;40897:5;40879:24;:::i;:::-;40870:33;;40925:66;40918:5;40915:77;40912:2;;;40995:18;;:::i;:::-;40912:2;41042:1;41035:5;41031:13;41024:20;;40860:190;;;:::o;41056:176::-;;41105:20;41123:1;41105:20;:::i;:::-;41100:25;;41139:20;41157:1;41139:20;:::i;:::-;41134:25;;41178:1;41168:2;;41183:18;;:::i;:::-;41168:2;41224:1;41221;41217:9;41212:14;;41090:142;;;;:::o;41238:180::-;41286:77;41283:1;41276:88;41383:4;41380:1;41373:15;41407:4;41404:1;41397:15;41424:180;41472:77;41469:1;41462:88;41569:4;41566:1;41559:15;41593:4;41590:1;41583:15;41610:180;41658:77;41655:1;41648:88;41755:4;41752:1;41745:15;41779:4;41776:1;41769:15;41796:180;41844:77;41841:1;41834:88;41941:4;41938:1;41931:15;41965:4;41962:1;41955:15;41982:102;;42074:2;42070:7;42065:2;42058:5;42054:14;42050:28;42040:38;;42030:54;;;:::o;42090:221::-;42230:34;42226:1;42218:6;42214:14;42207:58;42299:4;42294:2;42286:6;42282:15;42275:29;42196:115;:::o;42317:181::-;42457:33;42453:1;42445:6;42441:14;42434:57;42423:75;:::o;42504:237::-;42644:34;42640:1;42632:6;42628:14;42621:58;42713:20;42708:2;42700:6;42696:15;42689:45;42610:131;:::o;42747:225::-;42887:34;42883:1;42875:6;42871:14;42864:58;42956:8;42951:2;42943:6;42939:15;42932:33;42853:119;:::o;42978:178::-;43118:30;43114:1;43106:6;43102:14;43095:54;43084:72;:::o;43162:177::-;43302:29;43298:1;43290:6;43286:14;43279:53;43268:71;:::o;43345:223::-;43485:34;43481:1;43473:6;43469:14;43462:58;43554:6;43549:2;43541:6;43537:15;43530:31;43451:117;:::o;43574:175::-;43714:27;43710:1;43702:6;43698:14;43691:51;43680:69;:::o;43755:181::-;43895:33;43891:1;43883:6;43879:14;43872:57;43861:75;:::o;43942:180::-;44082:32;44078:1;44070:6;44066:14;44059:56;44048:74;:::o;44128:177::-;44268:29;44264:1;44256:6;44252:14;44245:53;44234:71;:::o;44311:225::-;44451:34;44447:1;44439:6;44435:14;44428:58;44520:8;44515:2;44507:6;44503:15;44496:33;44417:119;:::o;44542:231::-;44682:34;44678:1;44670:6;44666:14;44659:58;44751:14;44746:2;44738:6;44734:15;44727:39;44648:125;:::o;44779:176::-;44919:28;44915:1;44907:6;44903:14;44896:52;44885:70;:::o;44961:179::-;45101:31;45097:1;45089:6;45085:14;45078:55;45067:73;:::o;45146:243::-;45286:34;45282:1;45274:6;45270:14;45263:58;45355:26;45350:2;45342:6;45338:15;45331:51;45252:137;:::o;45395:229::-;45535:34;45531:1;45523:6;45519:14;45512:58;45604:12;45599:2;45591:6;45587:15;45580:37;45501:123;:::o;45630:182::-;45770:34;45766:1;45758:6;45754:14;45747:58;45736:76;:::o;45818:221::-;45958:34;45954:1;45946:6;45942:14;45935:58;46027:4;46022:2;46014:6;46010:15;46003:29;45924:115;:::o;46045:182::-;46185:34;46181:1;46173:6;46169:14;46162:58;46151:76;:::o;46233:220::-;46373:34;46369:1;46361:6;46357:14;46350:58;46442:3;46437:2;46429:6;46425:15;46418:28;46339:114;:::o;46459:231::-;46599:34;46595:1;46587:6;46583:14;46576:58;46668:14;46663:2;46655:6;46651:15;46644:39;46565:125;:::o;46696:182::-;46836:34;46832:1;46824:6;46820:14;46813:58;46802:76;:::o;46884:228::-;47024:34;47020:1;47012:6;47008:14;47001:58;47093:11;47088:2;47080:6;47076:15;47069:36;46990:122;:::o;47118:234::-;47258:34;47254:1;47246:6;47242:14;47235:58;47327:17;47322:2;47314:6;47310:15;47303:42;47224:128;:::o;47358:220::-;47498:34;47494:1;47486:6;47482:14;47475:58;47567:3;47562:2;47554:6;47550:15;47543:28;47464:114;:::o;47584:177::-;47724:29;47720:1;47712:6;47708:14;47701:53;47690:71;:::o;47767:182::-;47907:34;47903:1;47895:6;47891:14;47884:58;47873:76;:::o;47955:236::-;48095:34;48091:1;48083:6;48079:14;48072:58;48164:19;48159:2;48151:6;48147:15;48140:44;48061:130;:::o;48197:179::-;48337:31;48333:1;48325:6;48321:14;48314:55;48303:73;:::o;48382:122::-;48455:24;48473:5;48455:24;:::i;:::-;48448:5;48445:35;48435:2;;48494:1;48491;48484:12;48435:2;48425:79;:::o;48510:116::-;48580:21;48595:5;48580:21;:::i;:::-;48573:5;48570:32;48560:2;;48616:1;48613;48606:12;48560:2;48550:76;:::o;48632:120::-;48704:23;48721:5;48704:23;:::i;:::-;48697:5;48694:34;48684:2;;48742:1;48739;48732:12;48684:2;48674:78;:::o;48758:122::-;48831:24;48849:5;48831:24;:::i;:::-;48824:5;48821:35;48811:2;;48870:1;48867;48860:12;48811:2;48801:79;:::o

Swarm Source

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