ETH Price: $2,607.66 (-5.47%)

Token

pxPengus (PXP)
 

Overview

Max Total Supply

93 PXP

Holders

30

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
krisprolls.eth
Balance
7 PXP
0xAE260A8f5cFb927cfD38F8aC717bE3E0CDB9cdD2
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
pxPengus

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

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

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

pragma solidity >=0.6.0 <0.8.0;

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

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

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



pragma solidity >=0.6.0 <0.8.0;

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

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



pragma solidity >=0.6.2 <0.8.0;


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

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

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

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

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

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

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

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

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

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

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

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

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



pragma solidity >=0.6.2 <0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {

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

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

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

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



pragma solidity >=0.6.2 <0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

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



pragma solidity >=0.6.0 <0.8.0;

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

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



pragma solidity >=0.6.0 <0.8.0;


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

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

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

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

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

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



pragma solidity >=0.6.0 <0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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



pragma solidity >=0.6.2 <0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain`call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
      return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

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

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

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

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



pragma solidity >=0.6.0 <0.8.0;

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

    struct Set {
        // Storage of set values
        bytes32[] _values;

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

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

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

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

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

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

            bytes32 lastvalue = set._values[lastIndex];

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

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

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

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

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

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

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

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

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

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

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

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


    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

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

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

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



pragma solidity >=0.6.0 <0.8.0;

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

    struct MapEntry {
        bytes32 _key;
        bytes32 _value;
    }

    struct Map {
        // Storage of map keys and values
        MapEntry[] _entries;

        // Position of the entry defined by a key in the `entries` array, plus 1
        // because index 0 means a key is not in the map.
        mapping (bytes32 => uint256) _indexes;
    }

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

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

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

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

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

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

            MapEntry storage lastEntry = map._entries[lastIndex];

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

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

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

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

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

    // UintToAddressMap

    struct UintToAddressMap {
        Map _inner;
    }

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

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

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

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

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

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

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

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

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



pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    /**
     * @dev Converts a `uint256` to its ASCII `string` representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        uint256 index = digits - 1;
        temp = value;
        while (temp != 0) {
            buffer[index--] = bytes1(uint8(48 + temp % 10));
            temp /= 10;
        }
        return string(buffer);
    }
}

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



pragma solidity >=0.6.0 <0.8.0;

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

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

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

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

    // Mapping from token ID to approved address
    mapping (uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping (address => mapping (address => bool)) private _operatorApprovals;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

    // Base URI
    string private _baseURI;

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

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

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

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor (string memory name_, string memory symbol_) public {
        _name = name_;
        _symbol = symbol_;

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _holderTokens[owner].length();
    }

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

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = baseURI();

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

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

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

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

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

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

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

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(address from, address to, uint256 tokenId) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _tokenOwners.contains(tokenId);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     d*
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
        _mint(to, tokenId);
        require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

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

        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId); // internal owner

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

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

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

        _holderTokens[owner].remove(tokenId);

        _tokenOwners.remove(tokenId);

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(address from, address to, uint256 tokenId) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); // internal owner
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

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

        _tokenOwners.set(tokenId, to);

        emit Transfer(from, to, tokenId);
    }

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

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

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
        private returns (bool)
    {
        if (!to.isContract()) {
            return true;
        }
        bytes memory returndata = to.functionCall(abi.encodeWithSelector(
            IERC721Receiver(to).onERC721Received.selector,
            _msgSender(),
            from,
            tokenId,
            _data
        ), "ERC721: transfer to non ERC721Receiver implementer");
        bytes4 retval = abi.decode(returndata, (bytes4));
        return (retval == _ERC721_RECEIVED);
    }

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

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }
}

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



pragma solidity >=0.6.0 <0.8.0;

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

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

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

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

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

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

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




pragma solidity ^0.7.0;
pragma abicoder v2;

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

    uint256 public constant pxpPrice = 20000000000000000; 

    uint public constant purchaseLimit = 20;

    uint256 public constant MAX_ITEMS = 8888;

    bool public salesOn = false;
 
    uint public pxpReserve = 100;
    
    
    event licenseisLocked(string _licenseText);

    constructor() ERC721("pxPengus", "PXP") { }
    
    function withdrawAll() public onlyOwner {
        uint balance = address(this).balance;
        msg.sender.transfer(balance);
    }
    
    function reservePXP(address _to, uint256 _reserveAmount) public onlyOwner {        
        uint supply = totalSupply();
        require(_reserveAmount > 0 && _reserveAmount <= pxpReserve, "No more reserves");
        for (uint i = 0; i < _reserveAmount; i++) {
            _safeMint(_to, supply + i);
        }
        pxpReserve = pxpReserve.sub(_reserveAmount);
    }


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


    function flipSales() public onlyOwner {
        salesOn = !salesOn;
    }
    
    
    function tokensOfOwner(address _owner) external view returns(uint256[] memory ) {
        uint256 tokenCount = balanceOf(_owner);
        if (tokenCount == 0) {
            // Return an empty array
            return new uint256[](0);
        } else {
            uint256[] memory result = new uint256[](tokenCount);
            uint256 index;
            for (index = 0; index < tokenCount; index++) {
                result[index] = tokenOfOwnerByIndex(_owner, index);
            }
            return result;
        }
    }


    function mintPengus(uint numberOfTokens) public payable {
        require(salesOn, "Sale is not active");
        require(numberOfTokens > 0 && numberOfTokens <= purchaseLimit, "Max 20 mint at time");
        require(totalSupply().add(numberOfTokens) <= MAX_ITEMS, "We have sold out!");
        require(msg.value >= pxpPrice.mul(numberOfTokens), "Ether value sent is not correct");
        
        for(uint i = 0; i < numberOfTokens; i++) {
            uint mintIndex = totalSupply();
            if (totalSupply() < MAX_ITEMS) {
                _safeMint(msg.sender, mintIndex);
            }
        }

    }
    

}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_licenseText","type":"string"}],"name":"licenseisLocked","type":"event"},{"inputs":[],"name":"MAX_ITEMS","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":"flipSales","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"mintPengus","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"purchaseLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pxpPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pxpReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_reserveAmount","type":"uint256"}],"name":"reservePXP","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":"salesOn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526000600a60146101000a81548160ff0219169083151502179055506064600b553480156200003157600080fd5b506040518060400160405280600881526020017f707850656e6775730000000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f5058500000000000000000000000000000000000000000000000000000000000815250620000b66301ffc9a760e01b620001e960201b60201c565b8160069080519060200190620000ce929190620002c9565b508060079080519060200190620000e7929190620002c9565b50620001006380ac58cd60e01b620001e960201b60201c565b62000118635b5e139f60e01b620001e960201b60201c565b6200013063780e9d6360e01b620001e960201b60201c565b5050600062000144620002c160201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350620003f4565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141562000255576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200024c90620003c1565b60405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200030157600085556200034d565b82601f106200031c57805160ff19168380011785556200034d565b828001600101855582156200034d579182015b828111156200034c5782518255916020019190600101906200032f565b5b5090506200035c919062000360565b5090565b5b808211156200037b57600081600090555060010162000361565b5090565b60006200038e601c83620003e3565b91507f4552433136353a20696e76616c696420696e74657266616365206964000000006000830152602082019050919050565b60006020820190508181036000830152620003dc816200037f565b9050919050565b600082825260208201905092915050565b61415080620004046000396000f3fe6080604052600436106101d85760003560e01c8063665ce32a1161010257806395d89b4111610095578063c87b56dd11610064578063c87b56dd1461068b578063e985e9c5146106c8578063eb3e21a514610705578063f2fde38b14610730576101d8565b806395d89b41146105f2578063a22cb4651461061d578063b88d4fde14610646578063c33a25ad1461066f576101d8565b806372d5916d116100d157806372d5916d1461055c5780638462151c14610573578063853828b6146105b05780638da5cb5b146105c7576101d8565b8063665ce32a146104b25780636c0360eb146104dd57806370a0823114610508578063715018a614610545576101d8565b806323b872dd1161017a5780634f6ccce7116101495780634f6ccce7146103e457806355f804b31461042157806357d4c4ee1461044a5780636352211e14610475576101d8565b806323b872dd1461032a5780632f745c591461035357806342842e0e14610390578063491c0c47146103b9576101d8565b8063095ea7b3116101b6578063095ea7b3146102825780630ecba1ae146102ab57806318160ddd146102d457806318886657146102ff576101d8565b806301ffc9a7146101dd57806306fdde031461021a578063081812fc14610245575b600080fd5b3480156101e957600080fd5b5061020460048036038101906101ff9190612ea9565b610759565b6040516102119190613ab8565b60405180910390f35b34801561022657600080fd5b5061022f6107c0565b60405161023c9190613ad3565b60405180910390f35b34801561025157600080fd5b5061026c60048036038101906102679190612f3c565b610862565b6040516102799190613a2f565b60405180910390f35b34801561028e57600080fd5b506102a960048036038101906102a49190612e6d565b6108e7565b005b3480156102b757600080fd5b506102d260048036038101906102cd9190612e6d565b6109ff565b005b3480156102e057600080fd5b506102e9610b1d565b6040516102f69190613e55565b60405180910390f35b34801561030b57600080fd5b50610314610b2e565b6040516103219190613e55565b60405180910390f35b34801561033657600080fd5b50610351600480360381019061034c9190612d67565b610b33565b005b34801561035f57600080fd5b5061037a60048036038101906103759190612e6d565b610b93565b6040516103879190613e55565b60405180910390f35b34801561039c57600080fd5b506103b760048036038101906103b29190612d67565b610bee565b005b3480156103c557600080fd5b506103ce610c0e565b6040516103db9190613ab8565b60405180910390f35b3480156103f057600080fd5b5061040b60048036038101906104069190612f3c565b610c21565b6040516104189190613e55565b60405180910390f35b34801561042d57600080fd5b5061044860048036038101906104439190612efb565b610c44565b005b34801561045657600080fd5b5061045f610ccc565b60405161046c9190613e55565b60405180910390f35b34801561048157600080fd5b5061049c60048036038101906104979190612f3c565b610cd2565b6040516104a99190613a2f565b60405180910390f35b3480156104be57600080fd5b506104c7610d09565b6040516104d49190613e55565b60405180910390f35b3480156104e957600080fd5b506104f2610d0f565b6040516104ff9190613ad3565b60405180910390f35b34801561051457600080fd5b5061052f600480360381019061052a9190612d02565b610db1565b60405161053c9190613e55565b60405180910390f35b34801561055157600080fd5b5061055a610e70565b005b34801561056857600080fd5b50610571610fad565b005b34801561057f57600080fd5b5061059a60048036038101906105959190612d02565b611055565b6040516105a79190613a96565b60405180910390f35b3480156105bc57600080fd5b506105c561114e565b005b3480156105d357600080fd5b506105dc611219565b6040516105e99190613a2f565b60405180910390f35b3480156105fe57600080fd5b50610607611243565b6040516106149190613ad3565b60405180910390f35b34801561062957600080fd5b50610644600480360381019061063f9190612e31565b6112e5565b005b34801561065257600080fd5b5061066d60048036038101906106689190612db6565b611466565b005b61068960048036038101906106849190612f3c565b6114c8565b005b34801561069757600080fd5b506106b260048036038101906106ad9190612f3c565b611666565b6040516106bf9190613ad3565b60405180910390f35b3480156106d457600080fd5b506106ef60048036038101906106ea9190612d2b565b6117e9565b6040516106fc9190613ab8565b60405180910390f35b34801561071157600080fd5b5061071a61187d565b6040516107279190613e55565b60405180910390f35b34801561073c57600080fd5b5061075760048036038101906107529190612d02565b611888565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108585780601f1061082d57610100808354040283529160200191610858565b820191906000526020600020905b81548152906001019060200180831161083b57829003601f168201915b5050505050905090565b600061086d82611a34565b6108ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a390613d35565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006108f282610cd2565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610963576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095a90613db5565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610982611a51565b73ffffffffffffffffffffffffffffffffffffffff1614806109b157506109b0816109ab611a51565b6117e9565b5b6109f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e790613c95565b60405180910390fd5b6109fa8383611a59565b505050565b610a07611a51565b73ffffffffffffffffffffffffffffffffffffffff16610a25611219565b73ffffffffffffffffffffffffffffffffffffffff1614610a7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7290613d55565b60405180910390fd5b6000610a85610b1d565b9050600082118015610a995750600b548211155b610ad8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610acf90613dd5565b60405180910390fd5b60005b82811015610afc57610aef84828401611b12565b8080600101915050610adb565b50610b1282600b54611b3090919063ffffffff16565b600b81905550505050565b6000610b296002611b80565b905090565b601481565b610b44610b3e611a51565b82611b95565b610b83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7a90613df5565b60405180910390fd5b610b8e838383611c73565b505050565b6000610be682600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611e8a90919063ffffffff16565b905092915050565b610c0983838360405180602001604052806000815250611466565b505050565b600a60149054906101000a900460ff1681565b600080610c38836002611ea490919063ffffffff16565b50905080915050919050565b610c4c611a51565b73ffffffffffffffffffffffffffffffffffffffff16610c6a611219565b73ffffffffffffffffffffffffffffffffffffffff1614610cc0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cb790613d55565b60405180910390fd5b610cc981611ed0565b50565b6122b881565b6000610d02826040518060600160405280602981526020016140f2602991396002611eea9092919063ffffffff16565b9050919050565b600b5481565b606060098054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610da75780601f10610d7c57610100808354040283529160200191610da7565b820191906000526020600020905b815481529060010190602001808311610d8a57829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610e22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1990613cb5565b60405180910390fd5b610e69600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611f09565b9050919050565b610e78611a51565b73ffffffffffffffffffffffffffffffffffffffff16610e96611219565b73ffffffffffffffffffffffffffffffffffffffff1614610eec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee390613d55565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b610fb5611a51565b73ffffffffffffffffffffffffffffffffffffffff16610fd3611219565b73ffffffffffffffffffffffffffffffffffffffff1614611029576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161102090613d55565b60405180910390fd5b600a60149054906101000a900460ff1615600a60146101000a81548160ff021916908315150217905550565b6060600061106283610db1565b905060008114156110bd57600067ffffffffffffffff8111801561108557600080fd5b506040519080825280602002602001820160405280156110b45781602001602082028036833780820191505090505b50915050611149565b60008167ffffffffffffffff811180156110d657600080fd5b506040519080825280602002602001820160405280156111055781602001602082028036833780820191505090505b50905060005b828110156111425761111d8582610b93565b82828151811061112957fe5b602002602001018181525050808060010191505061110b565b8193505050505b919050565b611156611a51565b73ffffffffffffffffffffffffffffffffffffffff16611174611219565b73ffffffffffffffffffffffffffffffffffffffff16146111ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111c190613d55565b60405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611215573d6000803e3d6000fd5b5050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060078054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156112db5780601f106112b0576101008083540402835291602001916112db565b820191906000526020600020905b8154815290600101906020018083116112be57829003601f168201915b5050505050905090565b6112ed611a51565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561135b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135290613bb5565b60405180910390fd5b8060056000611368611a51565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611415611a51565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161145a9190613ab8565b60405180910390a35050565b611477611471611a51565b83611b95565b6114b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ad90613df5565b60405180910390fd5b6114c284848484611f1e565b50505050565b600a60149054906101000a900460ff16611517576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161150e90613bd5565b60405180910390fd5b600081118015611528575060148111155b611567576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155e90613c75565b60405180910390fd5b6122b861158482611576610b1d565b611f7a90919063ffffffff16565b11156115c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bc90613e35565b60405180910390fd5b6115df8166470de4df820000611fcf90919063ffffffff16565b341015611621576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161890613bf5565b60405180910390fd5b60005b81811015611662576000611636610b1d565b90506122b8611643610b1d565b1015611654576116533382611b12565b5b508080600101915050611624565b5050565b606061167182611a34565b6116b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a790613d95565b60405180910390fd5b6000600860008481526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156117595780601f1061172e57610100808354040283529160200191611759565b820191906000526020600020905b81548152906001019060200180831161173c57829003601f168201915b50505050509050600061176a610d0f565b90506000815114156117805781925050506117e4565b6000825111156117b557808260405160200161179d929190613a0b565b604051602081830303815290604052925050506117e4565b806117bf8561203f565b6040516020016117d0929190613a0b565b604051602081830303815290604052925050505b919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b66470de4df82000081565b611890611a51565b73ffffffffffffffffffffffffffffffffffffffff166118ae611219565b73ffffffffffffffffffffffffffffffffffffffff1614611904576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118fb90613d55565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b90613b35565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000611a4a82600261218690919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611acc83610cd2565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611b2c8282604051806020016040528060008152506121a0565b5050565b600082821115611b75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b6c90613c15565b60405180910390fd5b818303905092915050565b6000611b8e826000016121fb565b9050919050565b6000611ba082611a34565b611bdf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bd690613c55565b60405180910390fd5b6000611bea83610cd2565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611c5957508373ffffffffffffffffffffffffffffffffffffffff16611c4184610862565b73ffffffffffffffffffffffffffffffffffffffff16145b80611c6a5750611c6981856117e9565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611c9382610cd2565b73ffffffffffffffffffffffffffffffffffffffff1614611ce9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce090613d75565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611d59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d5090613b95565b60405180910390fd5b611d6483838361220c565b611d6f600082611a59565b611dc081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061221190919063ffffffff16565b50611e1281600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061222b90919063ffffffff16565b50611e29818360026122459092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000611e99836000018361227a565b60001c905092915050565b600080600080611eb786600001866122e7565b915091508160001c8160001c9350935050509250929050565b8060099080519060200190611ee6929190612b1e565b5050565b6000611efd846000018460001b8461236a565b60001c90509392505050565b6000611f17826000016123fb565b9050919050565b611f29848484611c73565b611f358484848461240c565b611f74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6b90613b15565b60405180910390fd5b50505050565b600080828401905083811015611fc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fbc90613b75565b60405180910390fd5b8091505092915050565b600080831415611fe25760009050612039565b6000828402905082848281611ff357fe5b0414612034576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202b90613d15565b60405180910390fd5b809150505b92915050565b60606000821415612087576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612181565b600082905060005b600082146120b1578080600101915050600a82816120a957fe5b04915061208f565b60008167ffffffffffffffff811180156120ca57600080fd5b506040519080825280601f01601f1916602001820160405280156120fd5781602001600182028036833780820191505090505b50905060006001830390508593505b6000841461217957600a848161211e57fe5b0660300160f81b8282806001900393508151811061213857fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a848161217157fe5b04935061210c565b819450505050505b919050565b6000612198836000018360001b612570565b905092915050565b6121aa8383612593565b6121b7600084848461240c565b6121f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121ed90613b15565b60405180910390fd5b505050565b600081600001805490509050919050565b505050565b6000612223836000018360001b612721565b905092915050565b600061223d836000018360001b612809565b905092915050565b6000612271846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612879565b90509392505050565b6000818360000180549050116122c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122bc90613af5565b60405180910390fd5b8260000182815481106122d457fe5b9060005260206000200154905092915050565b60008082846000018054905011612333576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161232a90613cd5565b60405180910390fd5b600084600001848154811061234457fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b600080846001016000858152602001908152602001600020549050600081141583906123cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123c39190613ad3565b60405180910390fd5b508460000160018203815481106123df57fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b600061242d8473ffffffffffffffffffffffffffffffffffffffff16612955565b61243a5760019050612568565b600061250163150b7a0260e01b61244f611a51565b8887876040516024016124659493929190613a4a565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518060600160405280603281526020016140c0603291398773ffffffffffffffffffffffffffffffffffffffff166129689092919063ffffffff16565b90506000818060200190518101906125199190612ed2565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612603576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125fa90613cf5565b60405180910390fd5b61260c81611a34565b1561264c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161264390613b55565b60405180910390fd5b6126586000838361220c565b6126a981600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061222b90919063ffffffff16565b506126c0818360026122459092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080836001016000848152602001908152602001600020549050600081146127fd576000600182039050600060018660000180549050039050600086600001828154811061276c57fe5b906000526020600020015490508087600001848154811061278957fe5b90600052602060002001819055506001830187600101600083815260200190815260200160002081905550866000018054806127c157fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050612803565b60009150505b92915050565b60006128158383612980565b61286e578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612873565b600090505b92915050565b60008084600101600085815260200190815260200160002054905060008114156129205784600001604051806040016040528086815260200185815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000155602082015181600101555050846000018054905085600101600086815260200190815260200160002081905550600191505061294e565b8285600001600183038154811061293357fe5b90600052602060002090600202016001018190555060009150505b9392505050565b600080823b905060008111915050919050565b606061297784846000856129a3565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b6060824710156129e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129df90613c35565b60405180910390fd5b6129f185612955565b612a30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a2790613e15565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612a5991906139f4565b60006040518083038185875af1925050503d8060008114612a96576040519150601f19603f3d011682016040523d82523d6000602084013e612a9b565b606091505b5091509150612aab828286612ab7565b92505050949350505050565b60608315612ac757829050612b17565b600083511115612ada5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b0e9190613ad3565b60405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282612b545760008555612b9b565b82601f10612b6d57805160ff1916838001178555612b9b565b82800160010185558215612b9b579182015b82811115612b9a578251825591602001919060010190612b7f565b5b509050612ba89190612bac565b5090565b5b80821115612bc5576000816000905550600101612bad565b5090565b6000612bdc612bd784613ea1565b613e70565b905082815260208101848484011115612bf457600080fd5b612bff84828561400e565b509392505050565b6000612c1a612c1584613ed1565b613e70565b905082815260208101848484011115612c3257600080fd5b612c3d84828561400e565b509392505050565b600081359050612c5481614063565b92915050565b600081359050612c698161407a565b92915050565b600081359050612c7e81614091565b92915050565b600081519050612c9381614091565b92915050565b600082601f830112612caa57600080fd5b8135612cba848260208601612bc9565b91505092915050565b600082601f830112612cd457600080fd5b8135612ce4848260208601612c07565b91505092915050565b600081359050612cfc816140a8565b92915050565b600060208284031215612d1457600080fd5b6000612d2284828501612c45565b91505092915050565b60008060408385031215612d3e57600080fd5b6000612d4c85828601612c45565b9250506020612d5d85828601612c45565b9150509250929050565b600080600060608486031215612d7c57600080fd5b6000612d8a86828701612c45565b9350506020612d9b86828701612c45565b9250506040612dac86828701612ced565b9150509250925092565b60008060008060808587031215612dcc57600080fd5b6000612dda87828801612c45565b9450506020612deb87828801612c45565b9350506040612dfc87828801612ced565b925050606085013567ffffffffffffffff811115612e1957600080fd5b612e2587828801612c99565b91505092959194509250565b60008060408385031215612e4457600080fd5b6000612e5285828601612c45565b9250506020612e6385828601612c5a565b9150509250929050565b60008060408385031215612e8057600080fd5b6000612e8e85828601612c45565b9250506020612e9f85828601612ced565b9150509250929050565b600060208284031215612ebb57600080fd5b6000612ec984828501612c6f565b91505092915050565b600060208284031215612ee457600080fd5b6000612ef284828501612c84565b91505092915050565b600060208284031215612f0d57600080fd5b600082013567ffffffffffffffff811115612f2757600080fd5b612f3384828501612cc3565b91505092915050565b600060208284031215612f4e57600080fd5b6000612f5c84828501612ced565b91505092915050565b6000612f7183836139d6565b60208301905092915050565b612f8681613f9a565b82525050565b612f9581613f88565b82525050565b6000612fa682613f11565b612fb08185613f3f565b9350612fbb83613f01565b8060005b83811015612fec578151612fd38882612f65565b9750612fde83613f32565b925050600181019050612fbf565b5085935050505092915050565b61300281613fac565b82525050565b600061301382613f1c565b61301d8185613f50565b935061302d81856020860161401d565b61303681614052565b840191505092915050565b600061304c82613f1c565b6130568185613f61565b935061306681856020860161401d565b80840191505092915050565b600061307d82613f27565b6130878185613f6c565b935061309781856020860161401d565b6130a081614052565b840191505092915050565b60006130b682613f27565b6130c08185613f7d565b93506130d081856020860161401d565b80840191505092915050565b60006130e9602283613f6c565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061314f603283613f6c565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b60006131b5602683613f6c565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061321b601c83613f6c565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b600061325b601b83613f6c565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b600061329b602483613f6c565b91507f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613301601983613f6c565b91507f4552433732313a20617070726f766520746f2063616c6c6572000000000000006000830152602082019050919050565b6000613341601283613f6c565b91507f53616c65206973206e6f742061637469766500000000000000000000000000006000830152602082019050919050565b6000613381601f83613f6c565b91507f45746865722076616c75652073656e74206973206e6f7420636f7272656374006000830152602082019050919050565b60006133c1601e83613f6c565b91507f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006000830152602082019050919050565b6000613401602683613f6c565b91507f416464726573733a20696e73756666696369656e742062616c616e636520666f60008301527f722063616c6c00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613467602c83613f6c565b91507f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b60006134cd601383613f6c565b91507f4d6178203230206d696e742061742074696d65000000000000000000000000006000830152602082019050919050565b600061350d603883613f6c565b91507f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008301527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006020830152604082019050919050565b6000613573602a83613f6c565b91507f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008301527f726f2061646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b60006135d9602283613f6c565b91507f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061363f602083613f6c565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b600061367f602183613f6c565b91507f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60008301527f77000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006136e5602c83613f6c565b91507f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b600061374b602083613f6c565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b600061378b602983613f6c565b91507f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008301527f73206e6f74206f776e00000000000000000000000000000000000000000000006020830152604082019050919050565b60006137f1602f83613f6c565b91507f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008301527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006020830152604082019050919050565b6000613857602183613f6c565b91507f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006138bd601083613f6c565b91507f4e6f206d6f7265207265736572766573000000000000000000000000000000006000830152602082019050919050565b60006138fd603183613f6c565b91507f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008301527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020830152604082019050919050565b6000613963601d83613f6c565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b60006139a3601183613f6c565b91507f5765206861766520736f6c64206f7574210000000000000000000000000000006000830152602082019050919050565b6139df81614004565b82525050565b6139ee81614004565b82525050565b6000613a008284613041565b915081905092915050565b6000613a1782856130ab565b9150613a2382846130ab565b91508190509392505050565b6000602082019050613a446000830184612f8c565b92915050565b6000608082019050613a5f6000830187612f7d565b613a6c6020830186612f8c565b613a7960408301856139e5565b8181036060830152613a8b8184613008565b905095945050505050565b60006020820190508181036000830152613ab08184612f9b565b905092915050565b6000602082019050613acd6000830184612ff9565b92915050565b60006020820190508181036000830152613aed8184613072565b905092915050565b60006020820190508181036000830152613b0e816130dc565b9050919050565b60006020820190508181036000830152613b2e81613142565b9050919050565b60006020820190508181036000830152613b4e816131a8565b9050919050565b60006020820190508181036000830152613b6e8161320e565b9050919050565b60006020820190508181036000830152613b8e8161324e565b9050919050565b60006020820190508181036000830152613bae8161328e565b9050919050565b60006020820190508181036000830152613bce816132f4565b9050919050565b60006020820190508181036000830152613bee81613334565b9050919050565b60006020820190508181036000830152613c0e81613374565b9050919050565b60006020820190508181036000830152613c2e816133b4565b9050919050565b60006020820190508181036000830152613c4e816133f4565b9050919050565b60006020820190508181036000830152613c6e8161345a565b9050919050565b60006020820190508181036000830152613c8e816134c0565b9050919050565b60006020820190508181036000830152613cae81613500565b9050919050565b60006020820190508181036000830152613cce81613566565b9050919050565b60006020820190508181036000830152613cee816135cc565b9050919050565b60006020820190508181036000830152613d0e81613632565b9050919050565b60006020820190508181036000830152613d2e81613672565b9050919050565b60006020820190508181036000830152613d4e816136d8565b9050919050565b60006020820190508181036000830152613d6e8161373e565b9050919050565b60006020820190508181036000830152613d8e8161377e565b9050919050565b60006020820190508181036000830152613dae816137e4565b9050919050565b60006020820190508181036000830152613dce8161384a565b9050919050565b60006020820190508181036000830152613dee816138b0565b9050919050565b60006020820190508181036000830152613e0e816138f0565b9050919050565b60006020820190508181036000830152613e2e81613956565b9050919050565b60006020820190508181036000830152613e4e81613996565b9050919050565b6000602082019050613e6a60008301846139e5565b92915050565b6000604051905081810181811067ffffffffffffffff82111715613e9757613e96614050565b5b8060405250919050565b600067ffffffffffffffff821115613ebc57613ebb614050565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115613eec57613eeb614050565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000613f9382613fe4565b9050919050565b6000613fa582613fe4565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561403b578082015181840152602081019050614020565b8381111561404a576000848401525b50505050565bfe5b6000601f19601f8301169050919050565b61406c81613f88565b811461407757600080fd5b50565b61408381613fac565b811461408e57600080fd5b50565b61409a81613fb8565b81146140a557600080fd5b50565b6140b181614004565b81146140bc57600080fd5b5056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220ea20789a4be389fbb2f01fb4f705070da52f2e184164feb834765e691e642e0a64736f6c63430007060033

Deployed Bytecode

0x6080604052600436106101d85760003560e01c8063665ce32a1161010257806395d89b4111610095578063c87b56dd11610064578063c87b56dd1461068b578063e985e9c5146106c8578063eb3e21a514610705578063f2fde38b14610730576101d8565b806395d89b41146105f2578063a22cb4651461061d578063b88d4fde14610646578063c33a25ad1461066f576101d8565b806372d5916d116100d157806372d5916d1461055c5780638462151c14610573578063853828b6146105b05780638da5cb5b146105c7576101d8565b8063665ce32a146104b25780636c0360eb146104dd57806370a0823114610508578063715018a614610545576101d8565b806323b872dd1161017a5780634f6ccce7116101495780634f6ccce7146103e457806355f804b31461042157806357d4c4ee1461044a5780636352211e14610475576101d8565b806323b872dd1461032a5780632f745c591461035357806342842e0e14610390578063491c0c47146103b9576101d8565b8063095ea7b3116101b6578063095ea7b3146102825780630ecba1ae146102ab57806318160ddd146102d457806318886657146102ff576101d8565b806301ffc9a7146101dd57806306fdde031461021a578063081812fc14610245575b600080fd5b3480156101e957600080fd5b5061020460048036038101906101ff9190612ea9565b610759565b6040516102119190613ab8565b60405180910390f35b34801561022657600080fd5b5061022f6107c0565b60405161023c9190613ad3565b60405180910390f35b34801561025157600080fd5b5061026c60048036038101906102679190612f3c565b610862565b6040516102799190613a2f565b60405180910390f35b34801561028e57600080fd5b506102a960048036038101906102a49190612e6d565b6108e7565b005b3480156102b757600080fd5b506102d260048036038101906102cd9190612e6d565b6109ff565b005b3480156102e057600080fd5b506102e9610b1d565b6040516102f69190613e55565b60405180910390f35b34801561030b57600080fd5b50610314610b2e565b6040516103219190613e55565b60405180910390f35b34801561033657600080fd5b50610351600480360381019061034c9190612d67565b610b33565b005b34801561035f57600080fd5b5061037a60048036038101906103759190612e6d565b610b93565b6040516103879190613e55565b60405180910390f35b34801561039c57600080fd5b506103b760048036038101906103b29190612d67565b610bee565b005b3480156103c557600080fd5b506103ce610c0e565b6040516103db9190613ab8565b60405180910390f35b3480156103f057600080fd5b5061040b60048036038101906104069190612f3c565b610c21565b6040516104189190613e55565b60405180910390f35b34801561042d57600080fd5b5061044860048036038101906104439190612efb565b610c44565b005b34801561045657600080fd5b5061045f610ccc565b60405161046c9190613e55565b60405180910390f35b34801561048157600080fd5b5061049c60048036038101906104979190612f3c565b610cd2565b6040516104a99190613a2f565b60405180910390f35b3480156104be57600080fd5b506104c7610d09565b6040516104d49190613e55565b60405180910390f35b3480156104e957600080fd5b506104f2610d0f565b6040516104ff9190613ad3565b60405180910390f35b34801561051457600080fd5b5061052f600480360381019061052a9190612d02565b610db1565b60405161053c9190613e55565b60405180910390f35b34801561055157600080fd5b5061055a610e70565b005b34801561056857600080fd5b50610571610fad565b005b34801561057f57600080fd5b5061059a60048036038101906105959190612d02565b611055565b6040516105a79190613a96565b60405180910390f35b3480156105bc57600080fd5b506105c561114e565b005b3480156105d357600080fd5b506105dc611219565b6040516105e99190613a2f565b60405180910390f35b3480156105fe57600080fd5b50610607611243565b6040516106149190613ad3565b60405180910390f35b34801561062957600080fd5b50610644600480360381019061063f9190612e31565b6112e5565b005b34801561065257600080fd5b5061066d60048036038101906106689190612db6565b611466565b005b61068960048036038101906106849190612f3c565b6114c8565b005b34801561069757600080fd5b506106b260048036038101906106ad9190612f3c565b611666565b6040516106bf9190613ad3565b60405180910390f35b3480156106d457600080fd5b506106ef60048036038101906106ea9190612d2b565b6117e9565b6040516106fc9190613ab8565b60405180910390f35b34801561071157600080fd5b5061071a61187d565b6040516107279190613e55565b60405180910390f35b34801561073c57600080fd5b5061075760048036038101906107529190612d02565b611888565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108585780601f1061082d57610100808354040283529160200191610858565b820191906000526020600020905b81548152906001019060200180831161083b57829003601f168201915b5050505050905090565b600061086d82611a34565b6108ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a390613d35565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006108f282610cd2565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610963576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095a90613db5565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610982611a51565b73ffffffffffffffffffffffffffffffffffffffff1614806109b157506109b0816109ab611a51565b6117e9565b5b6109f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e790613c95565b60405180910390fd5b6109fa8383611a59565b505050565b610a07611a51565b73ffffffffffffffffffffffffffffffffffffffff16610a25611219565b73ffffffffffffffffffffffffffffffffffffffff1614610a7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7290613d55565b60405180910390fd5b6000610a85610b1d565b9050600082118015610a995750600b548211155b610ad8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610acf90613dd5565b60405180910390fd5b60005b82811015610afc57610aef84828401611b12565b8080600101915050610adb565b50610b1282600b54611b3090919063ffffffff16565b600b81905550505050565b6000610b296002611b80565b905090565b601481565b610b44610b3e611a51565b82611b95565b610b83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7a90613df5565b60405180910390fd5b610b8e838383611c73565b505050565b6000610be682600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611e8a90919063ffffffff16565b905092915050565b610c0983838360405180602001604052806000815250611466565b505050565b600a60149054906101000a900460ff1681565b600080610c38836002611ea490919063ffffffff16565b50905080915050919050565b610c4c611a51565b73ffffffffffffffffffffffffffffffffffffffff16610c6a611219565b73ffffffffffffffffffffffffffffffffffffffff1614610cc0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cb790613d55565b60405180910390fd5b610cc981611ed0565b50565b6122b881565b6000610d02826040518060600160405280602981526020016140f2602991396002611eea9092919063ffffffff16565b9050919050565b600b5481565b606060098054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610da75780601f10610d7c57610100808354040283529160200191610da7565b820191906000526020600020905b815481529060010190602001808311610d8a57829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610e22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1990613cb5565b60405180910390fd5b610e69600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611f09565b9050919050565b610e78611a51565b73ffffffffffffffffffffffffffffffffffffffff16610e96611219565b73ffffffffffffffffffffffffffffffffffffffff1614610eec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee390613d55565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b610fb5611a51565b73ffffffffffffffffffffffffffffffffffffffff16610fd3611219565b73ffffffffffffffffffffffffffffffffffffffff1614611029576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161102090613d55565b60405180910390fd5b600a60149054906101000a900460ff1615600a60146101000a81548160ff021916908315150217905550565b6060600061106283610db1565b905060008114156110bd57600067ffffffffffffffff8111801561108557600080fd5b506040519080825280602002602001820160405280156110b45781602001602082028036833780820191505090505b50915050611149565b60008167ffffffffffffffff811180156110d657600080fd5b506040519080825280602002602001820160405280156111055781602001602082028036833780820191505090505b50905060005b828110156111425761111d8582610b93565b82828151811061112957fe5b602002602001018181525050808060010191505061110b565b8193505050505b919050565b611156611a51565b73ffffffffffffffffffffffffffffffffffffffff16611174611219565b73ffffffffffffffffffffffffffffffffffffffff16146111ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111c190613d55565b60405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611215573d6000803e3d6000fd5b5050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060078054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156112db5780601f106112b0576101008083540402835291602001916112db565b820191906000526020600020905b8154815290600101906020018083116112be57829003601f168201915b5050505050905090565b6112ed611a51565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561135b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135290613bb5565b60405180910390fd5b8060056000611368611a51565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611415611a51565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161145a9190613ab8565b60405180910390a35050565b611477611471611a51565b83611b95565b6114b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ad90613df5565b60405180910390fd5b6114c284848484611f1e565b50505050565b600a60149054906101000a900460ff16611517576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161150e90613bd5565b60405180910390fd5b600081118015611528575060148111155b611567576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155e90613c75565b60405180910390fd5b6122b861158482611576610b1d565b611f7a90919063ffffffff16565b11156115c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bc90613e35565b60405180910390fd5b6115df8166470de4df820000611fcf90919063ffffffff16565b341015611621576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161890613bf5565b60405180910390fd5b60005b81811015611662576000611636610b1d565b90506122b8611643610b1d565b1015611654576116533382611b12565b5b508080600101915050611624565b5050565b606061167182611a34565b6116b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a790613d95565b60405180910390fd5b6000600860008481526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156117595780601f1061172e57610100808354040283529160200191611759565b820191906000526020600020905b81548152906001019060200180831161173c57829003601f168201915b50505050509050600061176a610d0f565b90506000815114156117805781925050506117e4565b6000825111156117b557808260405160200161179d929190613a0b565b604051602081830303815290604052925050506117e4565b806117bf8561203f565b6040516020016117d0929190613a0b565b604051602081830303815290604052925050505b919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b66470de4df82000081565b611890611a51565b73ffffffffffffffffffffffffffffffffffffffff166118ae611219565b73ffffffffffffffffffffffffffffffffffffffff1614611904576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118fb90613d55565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b90613b35565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000611a4a82600261218690919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611acc83610cd2565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611b2c8282604051806020016040528060008152506121a0565b5050565b600082821115611b75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b6c90613c15565b60405180910390fd5b818303905092915050565b6000611b8e826000016121fb565b9050919050565b6000611ba082611a34565b611bdf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bd690613c55565b60405180910390fd5b6000611bea83610cd2565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611c5957508373ffffffffffffffffffffffffffffffffffffffff16611c4184610862565b73ffffffffffffffffffffffffffffffffffffffff16145b80611c6a5750611c6981856117e9565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611c9382610cd2565b73ffffffffffffffffffffffffffffffffffffffff1614611ce9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce090613d75565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611d59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d5090613b95565b60405180910390fd5b611d6483838361220c565b611d6f600082611a59565b611dc081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061221190919063ffffffff16565b50611e1281600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061222b90919063ffffffff16565b50611e29818360026122459092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000611e99836000018361227a565b60001c905092915050565b600080600080611eb786600001866122e7565b915091508160001c8160001c9350935050509250929050565b8060099080519060200190611ee6929190612b1e565b5050565b6000611efd846000018460001b8461236a565b60001c90509392505050565b6000611f17826000016123fb565b9050919050565b611f29848484611c73565b611f358484848461240c565b611f74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6b90613b15565b60405180910390fd5b50505050565b600080828401905083811015611fc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fbc90613b75565b60405180910390fd5b8091505092915050565b600080831415611fe25760009050612039565b6000828402905082848281611ff357fe5b0414612034576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202b90613d15565b60405180910390fd5b809150505b92915050565b60606000821415612087576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612181565b600082905060005b600082146120b1578080600101915050600a82816120a957fe5b04915061208f565b60008167ffffffffffffffff811180156120ca57600080fd5b506040519080825280601f01601f1916602001820160405280156120fd5781602001600182028036833780820191505090505b50905060006001830390508593505b6000841461217957600a848161211e57fe5b0660300160f81b8282806001900393508151811061213857fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a848161217157fe5b04935061210c565b819450505050505b919050565b6000612198836000018360001b612570565b905092915050565b6121aa8383612593565b6121b7600084848461240c565b6121f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121ed90613b15565b60405180910390fd5b505050565b600081600001805490509050919050565b505050565b6000612223836000018360001b612721565b905092915050565b600061223d836000018360001b612809565b905092915050565b6000612271846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612879565b90509392505050565b6000818360000180549050116122c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122bc90613af5565b60405180910390fd5b8260000182815481106122d457fe5b9060005260206000200154905092915050565b60008082846000018054905011612333576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161232a90613cd5565b60405180910390fd5b600084600001848154811061234457fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b600080846001016000858152602001908152602001600020549050600081141583906123cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123c39190613ad3565b60405180910390fd5b508460000160018203815481106123df57fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b600061242d8473ffffffffffffffffffffffffffffffffffffffff16612955565b61243a5760019050612568565b600061250163150b7a0260e01b61244f611a51565b8887876040516024016124659493929190613a4a565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518060600160405280603281526020016140c0603291398773ffffffffffffffffffffffffffffffffffffffff166129689092919063ffffffff16565b90506000818060200190518101906125199190612ed2565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612603576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125fa90613cf5565b60405180910390fd5b61260c81611a34565b1561264c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161264390613b55565b60405180910390fd5b6126586000838361220c565b6126a981600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061222b90919063ffffffff16565b506126c0818360026122459092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080836001016000848152602001908152602001600020549050600081146127fd576000600182039050600060018660000180549050039050600086600001828154811061276c57fe5b906000526020600020015490508087600001848154811061278957fe5b90600052602060002001819055506001830187600101600083815260200190815260200160002081905550866000018054806127c157fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050612803565b60009150505b92915050565b60006128158383612980565b61286e578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612873565b600090505b92915050565b60008084600101600085815260200190815260200160002054905060008114156129205784600001604051806040016040528086815260200185815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000155602082015181600101555050846000018054905085600101600086815260200190815260200160002081905550600191505061294e565b8285600001600183038154811061293357fe5b90600052602060002090600202016001018190555060009150505b9392505050565b600080823b905060008111915050919050565b606061297784846000856129a3565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b6060824710156129e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129df90613c35565b60405180910390fd5b6129f185612955565b612a30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a2790613e15565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612a5991906139f4565b60006040518083038185875af1925050503d8060008114612a96576040519150601f19603f3d011682016040523d82523d6000602084013e612a9b565b606091505b5091509150612aab828286612ab7565b92505050949350505050565b60608315612ac757829050612b17565b600083511115612ada5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b0e9190613ad3565b60405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282612b545760008555612b9b565b82601f10612b6d57805160ff1916838001178555612b9b565b82800160010185558215612b9b579182015b82811115612b9a578251825591602001919060010190612b7f565b5b509050612ba89190612bac565b5090565b5b80821115612bc5576000816000905550600101612bad565b5090565b6000612bdc612bd784613ea1565b613e70565b905082815260208101848484011115612bf457600080fd5b612bff84828561400e565b509392505050565b6000612c1a612c1584613ed1565b613e70565b905082815260208101848484011115612c3257600080fd5b612c3d84828561400e565b509392505050565b600081359050612c5481614063565b92915050565b600081359050612c698161407a565b92915050565b600081359050612c7e81614091565b92915050565b600081519050612c9381614091565b92915050565b600082601f830112612caa57600080fd5b8135612cba848260208601612bc9565b91505092915050565b600082601f830112612cd457600080fd5b8135612ce4848260208601612c07565b91505092915050565b600081359050612cfc816140a8565b92915050565b600060208284031215612d1457600080fd5b6000612d2284828501612c45565b91505092915050565b60008060408385031215612d3e57600080fd5b6000612d4c85828601612c45565b9250506020612d5d85828601612c45565b9150509250929050565b600080600060608486031215612d7c57600080fd5b6000612d8a86828701612c45565b9350506020612d9b86828701612c45565b9250506040612dac86828701612ced565b9150509250925092565b60008060008060808587031215612dcc57600080fd5b6000612dda87828801612c45565b9450506020612deb87828801612c45565b9350506040612dfc87828801612ced565b925050606085013567ffffffffffffffff811115612e1957600080fd5b612e2587828801612c99565b91505092959194509250565b60008060408385031215612e4457600080fd5b6000612e5285828601612c45565b9250506020612e6385828601612c5a565b9150509250929050565b60008060408385031215612e8057600080fd5b6000612e8e85828601612c45565b9250506020612e9f85828601612ced565b9150509250929050565b600060208284031215612ebb57600080fd5b6000612ec984828501612c6f565b91505092915050565b600060208284031215612ee457600080fd5b6000612ef284828501612c84565b91505092915050565b600060208284031215612f0d57600080fd5b600082013567ffffffffffffffff811115612f2757600080fd5b612f3384828501612cc3565b91505092915050565b600060208284031215612f4e57600080fd5b6000612f5c84828501612ced565b91505092915050565b6000612f7183836139d6565b60208301905092915050565b612f8681613f9a565b82525050565b612f9581613f88565b82525050565b6000612fa682613f11565b612fb08185613f3f565b9350612fbb83613f01565b8060005b83811015612fec578151612fd38882612f65565b9750612fde83613f32565b925050600181019050612fbf565b5085935050505092915050565b61300281613fac565b82525050565b600061301382613f1c565b61301d8185613f50565b935061302d81856020860161401d565b61303681614052565b840191505092915050565b600061304c82613f1c565b6130568185613f61565b935061306681856020860161401d565b80840191505092915050565b600061307d82613f27565b6130878185613f6c565b935061309781856020860161401d565b6130a081614052565b840191505092915050565b60006130b682613f27565b6130c08185613f7d565b93506130d081856020860161401d565b80840191505092915050565b60006130e9602283613f6c565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061314f603283613f6c565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b60006131b5602683613f6c565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061321b601c83613f6c565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b600061325b601b83613f6c565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b600061329b602483613f6c565b91507f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613301601983613f6c565b91507f4552433732313a20617070726f766520746f2063616c6c6572000000000000006000830152602082019050919050565b6000613341601283613f6c565b91507f53616c65206973206e6f742061637469766500000000000000000000000000006000830152602082019050919050565b6000613381601f83613f6c565b91507f45746865722076616c75652073656e74206973206e6f7420636f7272656374006000830152602082019050919050565b60006133c1601e83613f6c565b91507f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006000830152602082019050919050565b6000613401602683613f6c565b91507f416464726573733a20696e73756666696369656e742062616c616e636520666f60008301527f722063616c6c00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613467602c83613f6c565b91507f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b60006134cd601383613f6c565b91507f4d6178203230206d696e742061742074696d65000000000000000000000000006000830152602082019050919050565b600061350d603883613f6c565b91507f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008301527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006020830152604082019050919050565b6000613573602a83613f6c565b91507f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008301527f726f2061646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b60006135d9602283613f6c565b91507f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061363f602083613f6c565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b600061367f602183613f6c565b91507f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60008301527f77000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006136e5602c83613f6c565b91507f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b600061374b602083613f6c565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b600061378b602983613f6c565b91507f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008301527f73206e6f74206f776e00000000000000000000000000000000000000000000006020830152604082019050919050565b60006137f1602f83613f6c565b91507f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008301527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006020830152604082019050919050565b6000613857602183613f6c565b91507f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006138bd601083613f6c565b91507f4e6f206d6f7265207265736572766573000000000000000000000000000000006000830152602082019050919050565b60006138fd603183613f6c565b91507f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008301527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020830152604082019050919050565b6000613963601d83613f6c565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b60006139a3601183613f6c565b91507f5765206861766520736f6c64206f7574210000000000000000000000000000006000830152602082019050919050565b6139df81614004565b82525050565b6139ee81614004565b82525050565b6000613a008284613041565b915081905092915050565b6000613a1782856130ab565b9150613a2382846130ab565b91508190509392505050565b6000602082019050613a446000830184612f8c565b92915050565b6000608082019050613a5f6000830187612f7d565b613a6c6020830186612f8c565b613a7960408301856139e5565b8181036060830152613a8b8184613008565b905095945050505050565b60006020820190508181036000830152613ab08184612f9b565b905092915050565b6000602082019050613acd6000830184612ff9565b92915050565b60006020820190508181036000830152613aed8184613072565b905092915050565b60006020820190508181036000830152613b0e816130dc565b9050919050565b60006020820190508181036000830152613b2e81613142565b9050919050565b60006020820190508181036000830152613b4e816131a8565b9050919050565b60006020820190508181036000830152613b6e8161320e565b9050919050565b60006020820190508181036000830152613b8e8161324e565b9050919050565b60006020820190508181036000830152613bae8161328e565b9050919050565b60006020820190508181036000830152613bce816132f4565b9050919050565b60006020820190508181036000830152613bee81613334565b9050919050565b60006020820190508181036000830152613c0e81613374565b9050919050565b60006020820190508181036000830152613c2e816133b4565b9050919050565b60006020820190508181036000830152613c4e816133f4565b9050919050565b60006020820190508181036000830152613c6e8161345a565b9050919050565b60006020820190508181036000830152613c8e816134c0565b9050919050565b60006020820190508181036000830152613cae81613500565b9050919050565b60006020820190508181036000830152613cce81613566565b9050919050565b60006020820190508181036000830152613cee816135cc565b9050919050565b60006020820190508181036000830152613d0e81613632565b9050919050565b60006020820190508181036000830152613d2e81613672565b9050919050565b60006020820190508181036000830152613d4e816136d8565b9050919050565b60006020820190508181036000830152613d6e8161373e565b9050919050565b60006020820190508181036000830152613d8e8161377e565b9050919050565b60006020820190508181036000830152613dae816137e4565b9050919050565b60006020820190508181036000830152613dce8161384a565b9050919050565b60006020820190508181036000830152613dee816138b0565b9050919050565b60006020820190508181036000830152613e0e816138f0565b9050919050565b60006020820190508181036000830152613e2e81613956565b9050919050565b60006020820190508181036000830152613e4e81613996565b9050919050565b6000602082019050613e6a60008301846139e5565b92915050565b6000604051905081810181811067ffffffffffffffff82111715613e9757613e96614050565b5b8060405250919050565b600067ffffffffffffffff821115613ebc57613ebb614050565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115613eec57613eeb614050565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000613f9382613fe4565b9050919050565b6000613fa582613fe4565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561403b578082015181840152602081019050614020565b8381111561404a576000848401525b50505050565bfe5b6000601f19601f8301169050919050565b61406c81613f88565b811461407757600080fd5b50565b61408381613fac565b811461408e57600080fd5b50565b61409a81613fb8565b81146140a557600080fd5b50565b6140b181614004565b81146140bc57600080fd5b5056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220ea20789a4be389fbb2f01fb4f705070da52f2e184164feb834765e691e642e0a64736f6c63430007060033

Deployed Bytecode Sourcemap

66840:2354:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10236:150;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51521:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54307:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53837:404;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67420:377;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53315:211;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66987:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55197:305;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53077:162;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55573:151;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67084:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53603:172;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67807:99;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67035:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51277:177;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67121:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52896:97;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50994:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66232:148;;;;;;;;;;;;;:::i;:::-;;67916:75;;;;;;;;;;;;;:::i;:::-;;68009:540;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67274:134;;;;;;;;;;;;;:::i;:::-;;65581:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51690:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54600:295;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55795:285;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68559:624;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51865:792;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54966:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66925:52;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66535:244;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;10236:150;10321:4;10345:20;:33;10366:11;10345:33;;;;;;;;;;;;;;;;;;;;;;;;;;;10338:40;;10236:150;;;:::o;51521:100::-;51575:13;51608:5;51601:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51521:100;:::o;54307:221::-;54383:7;54411:16;54419:7;54411;:16::i;:::-;54403:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;54496:15;:24;54512:7;54496:24;;;;;;;;;;;;;;;;;;;;;54489:31;;54307:221;;;:::o;53837:404::-;53918:13;53934:23;53949:7;53934:14;:23::i;:::-;53918:39;;53982:5;53976:11;;:2;:11;;;;53968:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;54062:5;54046:21;;:12;:10;:12::i;:::-;:21;;;:69;;;;54071:44;54095:5;54102:12;:10;:12::i;:::-;54071:23;:44::i;:::-;54046:69;54038:161;;;;;;;;;;;;:::i;:::-;;;;;;;;;54212:21;54221:2;54225:7;54212:8;:21::i;:::-;53837:404;;;:::o;67420:377::-;65812:12;:10;:12::i;:::-;65801:23;;:7;:5;:7::i;:::-;:23;;;65793:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;67513:11:::1;67527:13;:11;:13::i;:::-;67513:27;;67576:1;67559:14;:18;:50;;;;;67599:10;;67581:14;:28;;67559:50;67551:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;67646:6;67641:95;67662:14;67658:1;:18;67641:95;;;67698:26;67708:3;67722:1;67713:6;:10;67698:9;:26::i;:::-;67678:3;;;;;;;67641:95;;;;67759:30;67774:14;67759:10;;:14;;:30;;;;:::i;:::-;67746:10;:43;;;;65872:1;67420:377:::0;;:::o;53315:211::-;53376:7;53497:21;:12;:19;:21::i;:::-;53490:28;;53315:211;:::o;66987:39::-;67024:2;66987:39;:::o;55197:305::-;55358:41;55377:12;:10;:12::i;:::-;55391:7;55358:18;:41::i;:::-;55350:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;55466:28;55476:4;55482:2;55486:7;55466:9;:28::i;:::-;55197:305;;;:::o;53077:162::-;53174:7;53201:30;53225:5;53201:13;:20;53215:5;53201:20;;;;;;;;;;;;;;;:23;;:30;;;;:::i;:::-;53194:37;;53077:162;;;;:::o;55573:151::-;55677:39;55694:4;55700:2;55704:7;55677:39;;;;;;;;;;;;:16;:39::i;:::-;55573:151;;;:::o;67084:27::-;;;;;;;;;;;;;:::o;53603:172::-;53678:7;53699:15;53720:22;53736:5;53720:12;:15;;:22;;;;:::i;:::-;53698:44;;;53760:7;53753:14;;;53603:172;;;:::o;67807:99::-;65812:12;:10;:12::i;:::-;65801:23;;:7;:5;:7::i;:::-;:23;;;65793:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;67878:20:::1;67890:7;67878:11;:20::i;:::-;67807:99:::0;:::o;67035:40::-;67071:4;67035:40;:::o;51277:177::-;51349:7;51376:70;51393:7;51376:70;;;;;;;;;;;;;;;;;:12;:16;;:70;;;;;:::i;:::-;51369:77;;51277:177;;;:::o;67121:28::-;;;;:::o;52896:97::-;52944:13;52977:8;52970:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52896:97;:::o;50994:221::-;51066:7;51111:1;51094:19;;:5;:19;;;;51086:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;51178:29;:13;:20;51192:5;51178:20;;;;;;;;;;;;;;;:27;:29::i;:::-;51171:36;;50994:221;;;:::o;66232:148::-;65812:12;:10;:12::i;:::-;65801:23;;:7;:5;:7::i;:::-;:23;;;65793:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;66339:1:::1;66302:40;;66323:6;;;;;;;;;;;66302:40;;;;;;;;;;;;66370:1;66353:6;;:19;;;;;;;;;;;;;;;;;;66232:148::o:0;67916:75::-;65812:12;:10;:12::i;:::-;65801:23;;:7;:5;:7::i;:::-;:23;;;65793:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;67976:7:::1;;;;;;;;;;;67975:8;67965:7;;:18;;;;;;;;;;;;;;;;;;67916:75::o:0;68009:540::-;68070:16;68100:18;68121:17;68131:6;68121:9;:17::i;:::-;68100:38;;68167:1;68153:10;:15;68149:393;;;68244:1;68230:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68223:23;;;;;68149:393;68279:23;68319:10;68305:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68279:51;;68345:13;68373:130;68397:10;68389:5;:18;68373:130;;;68453:34;68473:6;68481:5;68453:19;:34::i;:::-;68437:6;68444:5;68437:13;;;;;;;;;;;;;:50;;;;;68409:7;;;;;;;68373:130;;;68524:6;68517:13;;;;;68009:540;;;;:::o;67274:134::-;65812:12;:10;:12::i;:::-;65801:23;;:7;:5;:7::i;:::-;:23;;;65793:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;67325:12:::1;67340:21;67325:36;;67372:10;:19;;:28;67392:7;67372:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;65872:1;67274:134::o:0;65581:87::-;65627:7;65654:6;;;;;;;;;;;65647:13;;65581:87;:::o;51690:104::-;51746:13;51779:7;51772:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51690:104;:::o;54600:295::-;54715:12;:10;:12::i;:::-;54703:24;;:8;:24;;;;54695:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;54815:8;54770:18;:32;54789:12;:10;:12::i;:::-;54770:32;;;;;;;;;;;;;;;:42;54803:8;54770:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;54868:8;54839:48;;54854:12;:10;:12::i;:::-;54839:48;;;54878:8;54839:48;;;;;;:::i;:::-;;;;;;;;54600:295;;:::o;55795:285::-;55927:41;55946:12;:10;:12::i;:::-;55960:7;55927:18;:41::i;:::-;55919:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;56033:39;56047:4;56053:2;56057:7;56066:5;56033:13;:39::i;:::-;55795:285;;;;:::o;68559:624::-;68634:7;;;;;;;;;;;68626:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;68700:1;68683:14;:18;:53;;;;;67024:2;68705:14;:31;;68683:53;68675:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;67071:4;68779:33;68797:14;68779:13;:11;:13::i;:::-;:17;;:33;;;;:::i;:::-;:46;;68771:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;68879:28;68892:14;66960:17;68879:12;;:28;;;;:::i;:::-;68866:9;:41;;68858:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;68968:6;68964:210;68984:14;68980:1;:18;68964:210;;;69020:14;69037:13;:11;:13::i;:::-;69020:30;;67071:4;69069:13;:11;:13::i;:::-;:25;69065:98;;;69115:32;69125:10;69137:9;69115;:32::i;:::-;69065:98;68964:210;69000:3;;;;;;;68964:210;;;;68559:624;:::o;51865:792::-;51938:13;51972:16;51980:7;51972;:16::i;:::-;51964:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;52053:23;52079:10;:19;52090:7;52079:19;;;;;;;;;;;52053:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52109:18;52130:9;:7;:9::i;:::-;52109:30;;52237:1;52221:4;52215:18;:23;52211:72;;;52262:9;52255:16;;;;;;52211:72;52413:1;52393:9;52387:23;:27;52383:108;;;52462:4;52468:9;52445:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;52431:48;;;;;;52383:108;52623:4;52629:18;:7;:16;:18::i;:::-;52606:42;;;;;;;;;:::i;:::-;;;;;;;;;;;;;52592:57;;;;51865:792;;;;:::o;54966:164::-;55063:4;55087:18;:25;55106:5;55087:25;;;;;;;;;;;;;;;:35;55113:8;55087:35;;;;;;;;;;;;;;;;;;;;;;;;;55080:42;;54966:164;;;;:::o;66925:52::-;66960:17;66925:52;:::o;66535:244::-;65812:12;:10;:12::i;:::-;65801:23;;:7;:5;:7::i;:::-;:23;;;65793:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;66644:1:::1;66624:22;;:8;:22;;;;66616:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;66734:8;66705:38;;66726:6;;;;;;;;;;;66705:38;;;;;;;;;;;;66763:8;66754:6;;:17;;;;;;;;;;;;;;;;;;66535:244:::0;:::o;57547:127::-;57612:4;57636:30;57658:7;57636:12;:21;;:30;;;;:::i;:::-;57629:37;;57547:127;;;:::o;668:106::-;721:15;756:10;749:17;;668:106;:::o;63565:192::-;63667:2;63640:15;:24;63656:7;63640:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;63723:7;63719:2;63685:46;;63694:23;63709:7;63694:14;:23::i;:::-;63685:46;;;;;;;;;;;;63565:192;;:::o;58539:110::-;58615:26;58625:2;58629:7;58615:26;;;;;;;;;;;;:9;:26::i;:::-;58539:110;;:::o;14260:158::-;14318:7;14351:1;14346;:6;;14338:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;14409:1;14405;:5;14398:12;;14260:158;;;;:::o;44279:123::-;44348:7;44375:19;44383:3;:10;;44375:7;:19::i;:::-;44368:26;;44279:123;;;:::o;57841:355::-;57934:4;57959:16;57967:7;57959;:16::i;:::-;57951:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;58035:13;58051:23;58066:7;58051:14;:23::i;:::-;58035:39;;58104:5;58093:16;;:7;:16;;;:51;;;;58137:7;58113:31;;:20;58125:7;58113:11;:20::i;:::-;:31;;;58093:51;:94;;;;58148:39;58172:5;58179:7;58148:23;:39::i;:::-;58093:94;58085:103;;;57841:355;;;;:::o;60977:599::-;61102:4;61075:31;;:23;61090:7;61075:14;:23::i;:::-;:31;;;61067:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;61203:1;61189:16;;:2;:16;;;;61181:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;61259:39;61280:4;61286:2;61290:7;61259:20;:39::i;:::-;61363:29;61380:1;61384:7;61363:8;:29::i;:::-;61405:35;61432:7;61405:13;:19;61419:4;61405:19;;;;;;;;;;;;;;;:26;;:35;;;;:::i;:::-;;61451:30;61473:7;61451:13;:17;61465:2;61451:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;61494:29;61511:7;61520:2;61494:12;:16;;:29;;;;;:::i;:::-;;61560:7;61556:2;61541:27;;61550:4;61541:27;;;;;;;;;;;;60977:599;;;:::o;36070:137::-;36141:7;36176:22;36180:3;:10;;36192:5;36176:3;:22::i;:::-;36168:31;;36161:38;;36070:137;;;;:::o;44741:236::-;44821:7;44830;44851:11;44864:13;44881:22;44885:3;:10;;44897:5;44881:3;:22::i;:::-;44850:53;;;;44930:3;44922:12;;44960:5;44952:14;;44914:55;;;;;;44741:236;;;;;:::o;62177:100::-;62261:8;62250;:19;;;;;;;;;;;;:::i;:::-;;62177:100;:::o;46027:213::-;46134:7;46185:44;46190:3;:10;;46210:3;46202:12;;46216;46185:4;:44::i;:::-;46177:53;;46154:78;;46027:213;;;;;:::o;35612:114::-;35672:7;35699:19;35707:3;:10;;35699:7;:19::i;:::-;35692:26;;35612:114;;;:::o;56962:272::-;57076:28;57086:4;57092:2;57096:7;57076:9;:28::i;:::-;57123:48;57146:4;57152:2;57156:7;57165:5;57123:22;:48::i;:::-;57115:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;56962:272;;;;:::o;13798:179::-;13856:7;13876:9;13892:1;13888;:5;13876:17;;13917:1;13912;:6;;13904:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;13968:1;13961:8;;;13798:179;;;;:::o;14677:220::-;14735:7;14764:1;14759;:6;14755:20;;;14774:1;14767:8;;;;14755:20;14786:9;14802:1;14798;:5;14786:17;;14831:1;14826;14822;:5;;;;;;:10;14814:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;14888:1;14881:8;;;14677:220;;;;;:::o;46491:746::-;46547:13;46777:1;46768:5;:10;46764:53;;;46795:10;;;;;;;;;;;;;;;;;;;;;46764:53;46827:12;46842:5;46827:20;;46858:14;46883:78;46898:1;46890:4;:9;46883:78;;46916:8;;;;;;;46947:2;46939:10;;;;;;;;;46883:78;;;46971:19;47003:6;46993:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46971:39;;47021:13;47046:1;47037:6;:10;47021:26;;47065:5;47058:12;;47081:117;47096:1;47088:4;:9;47081:117;;47157:2;47150:4;:9;;;;;;47145:2;:14;47132:29;;47114:6;47121:7;;;;;;;47114:15;;;;;;;;;;;:47;;;;;;;;;;;47184:2;47176:10;;;;;;;;;47081:117;;;47222:6;47208:21;;;;;;46491:746;;;;:::o;44040:151::-;44124:4;44148:35;44158:3;:10;;44178:3;44170:12;;44148:9;:35::i;:::-;44141:42;;44040:151;;;;:::o;58876:250::-;58972:18;58978:2;58982:7;58972:5;:18::i;:::-;59009:54;59040:1;59044:2;59048:7;59057:5;59009:22;:54::i;:::-;59001:117;;;;;;;;;;;;:::i;:::-;;;;;;;;;58876:250;;;:::o;40858:110::-;40914:7;40941:3;:12;;:19;;;;40934:26;;40858:110;;;:::o;64370:93::-;;;;:::o;35157:137::-;35227:4;35251:35;35259:3;:10;;35279:5;35271:14;;35251:7;:35::i;:::-;35244:42;;35157:137;;;;:::o;34850:131::-;34917:4;34941:32;34946:3;:10;;34966:5;34958:14;;34941:4;:32::i;:::-;34934:39;;34850:131;;;;:::o;43463:185::-;43552:4;43576:64;43581:3;:10;;43601:3;43593:12;;43631:5;43615:23;;43607:32;;43576:4;:64::i;:::-;43569:71;;43463:185;;;;;:::o;31108:204::-;31175:7;31224:5;31203:3;:11;;:18;;;;:26;31195:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;31286:3;:11;;31298:5;31286:18;;;;;;;;;;;;;;;;31279:25;;31108:204;;;;:::o;41323:279::-;41390:7;41399;41449:5;41427:3;:12;;:19;;;;:27;41419:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;41506:22;41531:3;:12;;41544:5;41531:19;;;;;;;;;;;;;;;;;;41506:44;;41569:5;:10;;;41581:5;:12;;;41561:33;;;;;41323:279;;;;;:::o;42820:319::-;42914:7;42934:16;42953:3;:12;;:17;42966:3;42953:17;;;;;;;;;;;;42934:36;;43001:1;42989:8;:13;;43004:12;42981:36;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;43071:3;:12;;43095:1;43084:8;:12;43071:26;;;;;;;;;;;;;;;;;;:33;;;43064:40;;;42820:319;;;;;:::o;30655:109::-;30711:7;30738:3;:11;;:18;;;;30731:25;;30655:109;;;:::o;62842:604::-;62963:4;62990:15;:2;:13;;;:15::i;:::-;62985:60;;63029:4;63022:11;;;;62985:60;63055:23;63081:252;63134:45;;;63194:12;:10;:12::i;:::-;63221:4;63240:7;63262:5;63097:181;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63081:252;;;;;;;;;;;;;;;;;:2;:15;;;;:252;;;;;:::i;:::-;63055:278;;63344:13;63371:10;63360:32;;;;;;;;;;;;:::i;:::-;63344:48;;47991:10;63421:16;;63411:26;;;:6;:26;;;;63403:35;;;;62842:604;;;;;;;:::o;40638:125::-;40709:4;40754:1;40733:3;:12;;:17;40746:3;40733:17;;;;;;;;;;;;:22;;40726:29;;40638:125;;;;:::o;59462:404::-;59556:1;59542:16;;:2;:16;;;;59534:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;59615:16;59623:7;59615;:16::i;:::-;59614:17;59606:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;59677:45;59706:1;59710:2;59714:7;59677:20;:45::i;:::-;59735:30;59757:7;59735:13;:17;59749:2;59735:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;59778:29;59795:7;59804:2;59778:12;:16;;:29;;;;;:::i;:::-;;59850:7;59846:2;59825:33;;59842:1;59825:33;;;;;;;;;;;;59462:404;;:::o;28810:1544::-;28876:4;28994:18;29015:3;:12;;:19;29028:5;29015:19;;;;;;;;;;;;28994:40;;29065:1;29051:10;:15;29047:1300;;29413:21;29450:1;29437:10;:14;29413:38;;29466:17;29507:1;29486:3;:11;;:18;;;;:22;29466:42;;29753:17;29773:3;:11;;29785:9;29773:22;;;;;;;;;;;;;;;;29753:42;;29919:9;29890:3;:11;;29902:13;29890:26;;;;;;;;;;;;;;;:38;;;;30038:1;30022:13;:17;29996:3;:12;;:23;30009:9;29996:23;;;;;;;;;;;:43;;;;30148:3;:11;;:17;;;;;;;;;;;;;;;;;;;;;;;;30243:3;:12;;:19;30256:5;30243:19;;;;;;;;;;;30236:26;;;30286:4;30279:11;;;;;;;;29047:1300;30330:5;30323:12;;;28810:1544;;;;;:::o;28220:414::-;28283:4;28305:21;28315:3;28320:5;28305:9;:21::i;:::-;28300:327;;28343:3;:11;;28360:5;28343:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28526:3;:11;;:18;;;;28504:3;:12;;:19;28517:5;28504:19;;;;;;;;;;;:40;;;;28566:4;28559:11;;;;28300:327;28610:5;28603:12;;28220:414;;;;;:::o;38138:692::-;38214:4;38330:16;38349:3;:12;;:17;38362:3;38349:17;;;;;;;;;;;;38330:36;;38395:1;38383:8;:13;38379:444;;;38450:3;:12;;38468:38;;;;;;;;38485:3;38468:38;;;;38498:5;38468:38;;;38450:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38665:3;:12;;:19;;;;38645:3;:12;;:17;38658:3;38645:17;;;;;;;;;;;:39;;;;38706:4;38699:11;;;;;38379:444;38779:5;38743:3;:12;;38767:1;38756:8;:12;38743:26;;;;;;;;;;;;;;;;;;:33;;:41;;;;38806:5;38799:12;;;38138:692;;;;;;:::o;19239:422::-;19299:4;19507:12;19618:7;19606:20;19598:28;;19652:1;19645:4;:8;19638:15;;;19239:422;;;:::o;22157:195::-;22260:12;22292:52;22314:6;22322:4;22328:1;22331:12;22292:21;:52::i;:::-;22285:59;;22157:195;;;;;:::o;30440:129::-;30513:4;30560:1;30537:3;:12;;:19;30550:5;30537:19;;;;;;;;;;;;:24;;30530:31;;30440:129;;;;:::o;23209:530::-;23336:12;23394:5;23369:21;:30;;23361:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;23461:18;23472:6;23461:10;:18::i;:::-;23453:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;23587:12;23601:23;23628:6;:11;;23648:5;23656:4;23628:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23586:75;;;;23679:52;23697:7;23706:10;23718:12;23679:17;:52::i;:::-;23672:59;;;;23209:530;;;;;;:::o;25749:742::-;25864:12;25893:7;25889:595;;;25924:10;25917:17;;;;25889:595;26058:1;26038:10;:17;:21;26034:439;;;26301:10;26295:17;26362:15;26349:10;26345:2;26341:19;26334:44;26249:148;26444:12;26437:20;;;;;;;;;;;:::i;:::-;;;;;;;;25749:742;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:342:1:-;;109:64;124:48;165:6;124:48;:::i;:::-;109:64;:::i;:::-;100:73;;196:6;189:5;182:21;234:4;227:5;223:16;272:3;263:6;258:3;254:16;251:25;248:2;;;289:1;286;279:12;248:2;302:41;336:6;331:3;326;302:41;:::i;:::-;90:259;;;;;;:::o;355:344::-;;458:65;473:49;515:6;473:49;:::i;:::-;458:65;:::i;:::-;449:74;;546:6;539:5;532:21;584:4;577:5;573:16;622:3;613:6;608:3;604:16;601:25;598:2;;;639:1;636;629:12;598:2;652:41;686:6;681:3;676;652:41;:::i;:::-;439:260;;;;;;:::o;705:139::-;;789:6;776:20;767:29;;805:33;832:5;805:33;:::i;:::-;757:87;;;;:::o;850:133::-;;931:6;918:20;909:29;;947:30;971:5;947:30;:::i;:::-;899:84;;;;:::o;989:137::-;;1072:6;1059:20;1050:29;;1088:32;1114:5;1088:32;:::i;:::-;1040:86;;;;:::o;1132:141::-;;1219:6;1213:13;1204:22;;1235:32;1261:5;1235:32;:::i;:::-;1194:79;;;;:::o;1292:271::-;;1396:3;1389:4;1381:6;1377:17;1373:27;1363:2;;1414:1;1411;1404:12;1363:2;1454:6;1441:20;1479:78;1553:3;1545:6;1538:4;1530:6;1526:17;1479:78;:::i;:::-;1470:87;;1353:210;;;;;:::o;1583:273::-;;1688:3;1681:4;1673:6;1669:17;1665:27;1655:2;;1706:1;1703;1696:12;1655:2;1746:6;1733:20;1771:79;1846:3;1838:6;1831:4;1823:6;1819:17;1771:79;:::i;:::-;1762:88;;1645:211;;;;;:::o;1862:139::-;;1946:6;1933:20;1924:29;;1962:33;1989:5;1962:33;:::i;:::-;1914:87;;;;:::o;2007:262::-;;2115:2;2103:9;2094:7;2090:23;2086:32;2083:2;;;2131:1;2128;2121:12;2083:2;2174:1;2199:53;2244:7;2235:6;2224:9;2220:22;2199:53;:::i;:::-;2189:63;;2145:117;2073:196;;;;:::o;2275:407::-;;;2400:2;2388:9;2379:7;2375:23;2371:32;2368:2;;;2416:1;2413;2406:12;2368:2;2459:1;2484:53;2529:7;2520:6;2509:9;2505:22;2484:53;:::i;:::-;2474:63;;2430:117;2586:2;2612:53;2657:7;2648:6;2637:9;2633:22;2612:53;:::i;:::-;2602:63;;2557:118;2358:324;;;;;:::o;2688:552::-;;;;2830:2;2818:9;2809:7;2805:23;2801:32;2798:2;;;2846:1;2843;2836:12;2798:2;2889:1;2914:53;2959:7;2950:6;2939:9;2935:22;2914:53;:::i;:::-;2904:63;;2860:117;3016:2;3042:53;3087:7;3078:6;3067:9;3063:22;3042:53;:::i;:::-;3032:63;;2987:118;3144:2;3170:53;3215:7;3206:6;3195:9;3191:22;3170:53;:::i;:::-;3160:63;;3115:118;2788:452;;;;;:::o;3246:809::-;;;;;3414:3;3402:9;3393:7;3389:23;3385:33;3382:2;;;3431:1;3428;3421:12;3382:2;3474:1;3499:53;3544:7;3535:6;3524:9;3520:22;3499:53;:::i;:::-;3489:63;;3445:117;3601:2;3627:53;3672:7;3663:6;3652:9;3648:22;3627:53;:::i;:::-;3617:63;;3572:118;3729:2;3755:53;3800:7;3791:6;3780:9;3776:22;3755:53;:::i;:::-;3745:63;;3700:118;3885:2;3874:9;3870:18;3857:32;3916:18;3908:6;3905:30;3902:2;;;3948:1;3945;3938:12;3902:2;3976:62;4030:7;4021:6;4010:9;4006:22;3976:62;:::i;:::-;3966:72;;3828:220;3372:683;;;;;;;:::o;4061:401::-;;;4183:2;4171:9;4162:7;4158:23;4154:32;4151:2;;;4199:1;4196;4189:12;4151:2;4242:1;4267:53;4312:7;4303:6;4292:9;4288:22;4267:53;:::i;:::-;4257:63;;4213:117;4369:2;4395:50;4437:7;4428:6;4417:9;4413:22;4395:50;:::i;:::-;4385:60;;4340:115;4141:321;;;;;:::o;4468:407::-;;;4593:2;4581:9;4572:7;4568:23;4564:32;4561:2;;;4609:1;4606;4599:12;4561:2;4652:1;4677:53;4722:7;4713:6;4702:9;4698:22;4677:53;:::i;:::-;4667:63;;4623:117;4779:2;4805:53;4850:7;4841:6;4830:9;4826:22;4805:53;:::i;:::-;4795:63;;4750:118;4551:324;;;;;:::o;4881:260::-;;4988:2;4976:9;4967:7;4963:23;4959:32;4956:2;;;5004:1;5001;4994:12;4956:2;5047:1;5072:52;5116:7;5107:6;5096:9;5092:22;5072:52;:::i;:::-;5062:62;;5018:116;4946:195;;;;:::o;5147:282::-;;5265:2;5253:9;5244:7;5240:23;5236:32;5233:2;;;5281:1;5278;5271:12;5233:2;5324:1;5349:63;5404:7;5395:6;5384:9;5380:22;5349:63;:::i;:::-;5339:73;;5295:127;5223:206;;;;:::o;5435:375::-;;5553:2;5541:9;5532:7;5528:23;5524:32;5521:2;;;5569:1;5566;5559:12;5521:2;5640:1;5629:9;5625:17;5612:31;5670:18;5662:6;5659:30;5656:2;;;5702:1;5699;5692:12;5656:2;5730:63;5785:7;5776:6;5765:9;5761:22;5730:63;:::i;:::-;5720:73;;5583:220;5511:299;;;;:::o;5816:262::-;;5924:2;5912:9;5903:7;5899:23;5895:32;5892:2;;;5940:1;5937;5930:12;5892:2;5983:1;6008:53;6053:7;6044:6;6033:9;6029:22;6008:53;:::i;:::-;5998:63;;5954:117;5882:196;;;;:::o;6084:179::-;;6174:46;6216:3;6208:6;6174:46;:::i;:::-;6252:4;6247:3;6243:14;6229:28;;6164:99;;;;:::o;6269:142::-;6372:32;6398:5;6372:32;:::i;:::-;6367:3;6360:45;6350:61;;:::o;6417:118::-;6504:24;6522:5;6504:24;:::i;:::-;6499:3;6492:37;6482:53;;:::o;6571:732::-;;6719:54;6767:5;6719:54;:::i;:::-;6789:86;6868:6;6863:3;6789:86;:::i;:::-;6782:93;;6899:56;6949:5;6899:56;:::i;:::-;6978:7;7009:1;6994:284;7019:6;7016:1;7013:13;6994:284;;;7095:6;7089:13;7122:63;7181:3;7166:13;7122:63;:::i;:::-;7115:70;;7208:60;7261:6;7208:60;:::i;:::-;7198:70;;7054:224;7041:1;7038;7034:9;7029:14;;6994:284;;;6998:14;7294:3;7287:10;;6695:608;;;;;;;:::o;7309:109::-;7390:21;7405:5;7390:21;:::i;:::-;7385:3;7378:34;7368:50;;:::o;7424:360::-;;7538:38;7570:5;7538:38;:::i;:::-;7592:70;7655:6;7650:3;7592:70;:::i;:::-;7585:77;;7671:52;7716:6;7711:3;7704:4;7697:5;7693:16;7671:52;:::i;:::-;7748:29;7770:6;7748:29;:::i;:::-;7743:3;7739:39;7732:46;;7514:270;;;;;:::o;7790:373::-;;7922:38;7954:5;7922:38;:::i;:::-;7976:88;8057:6;8052:3;7976:88;:::i;:::-;7969:95;;8073:52;8118:6;8113:3;8106:4;8099:5;8095:16;8073:52;:::i;:::-;8150:6;8145:3;8141:16;8134:23;;7898:265;;;;;:::o;8169:364::-;;8285:39;8318:5;8285:39;:::i;:::-;8340:71;8404:6;8399:3;8340:71;:::i;:::-;8333:78;;8420:52;8465:6;8460:3;8453:4;8446:5;8442:16;8420:52;:::i;:::-;8497:29;8519:6;8497:29;:::i;:::-;8492:3;8488:39;8481:46;;8261:272;;;;;:::o;8539:377::-;;8673:39;8706:5;8673:39;:::i;:::-;8728:89;8810:6;8805:3;8728:89;:::i;:::-;8721:96;;8826:52;8871:6;8866:3;8859:4;8852:5;8848:16;8826:52;:::i;:::-;8903:6;8898:3;8894:16;8887:23;;8649:267;;;;;:::o;8922:366::-;;9085:67;9149:2;9144:3;9085:67;:::i;:::-;9078:74;;9182:34;9178:1;9173:3;9169:11;9162:55;9248:4;9243:2;9238:3;9234:12;9227:26;9279:2;9274:3;9270:12;9263:19;;9068:220;;;:::o;9294:382::-;;9457:67;9521:2;9516:3;9457:67;:::i;:::-;9450:74;;9554:34;9550:1;9545:3;9541:11;9534:55;9620:20;9615:2;9610:3;9606:12;9599:42;9667:2;9662:3;9658:12;9651:19;;9440:236;;;:::o;9682:370::-;;9845:67;9909:2;9904:3;9845:67;:::i;:::-;9838:74;;9942:34;9938:1;9933:3;9929:11;9922:55;10008:8;10003:2;9998:3;9994:12;9987:30;10043:2;10038:3;10034:12;10027:19;;9828:224;;;:::o;10058:326::-;;10221:67;10285:2;10280:3;10221:67;:::i;:::-;10214:74;;10318:30;10314:1;10309:3;10305:11;10298:51;10375:2;10370:3;10366:12;10359:19;;10204:180;;;:::o;10390:325::-;;10553:67;10617:2;10612:3;10553:67;:::i;:::-;10546:74;;10650:29;10646:1;10641:3;10637:11;10630:50;10706:2;10701:3;10697:12;10690:19;;10536:179;;;:::o;10721:368::-;;10884:67;10948:2;10943:3;10884:67;:::i;:::-;10877:74;;10981:34;10977:1;10972:3;10968:11;10961:55;11047:6;11042:2;11037:3;11033:12;11026:28;11080:2;11075:3;11071:12;11064:19;;10867:222;;;:::o;11095:323::-;;11258:67;11322:2;11317:3;11258:67;:::i;:::-;11251:74;;11355:27;11351:1;11346:3;11342:11;11335:48;11409:2;11404:3;11400:12;11393:19;;11241:177;;;:::o;11424:316::-;;11587:67;11651:2;11646:3;11587:67;:::i;:::-;11580:74;;11684:20;11680:1;11675:3;11671:11;11664:41;11731:2;11726:3;11722:12;11715:19;;11570:170;;;:::o;11746:329::-;;11909:67;11973:2;11968:3;11909:67;:::i;:::-;11902:74;;12006:33;12002:1;11997:3;11993:11;11986:54;12066:2;12061:3;12057:12;12050:19;;11892:183;;;:::o;12081:328::-;;12244:67;12308:2;12303:3;12244:67;:::i;:::-;12237:74;;12341:32;12337:1;12332:3;12328:11;12321:53;12400:2;12395:3;12391:12;12384:19;;12227:182;;;:::o;12415:370::-;;12578:67;12642:2;12637:3;12578:67;:::i;:::-;12571:74;;12675:34;12671:1;12666:3;12662:11;12655:55;12741:8;12736:2;12731:3;12727:12;12720:30;12776:2;12771:3;12767:12;12760:19;;12561:224;;;:::o;12791:376::-;;12954:67;13018:2;13013:3;12954:67;:::i;:::-;12947:74;;13051:34;13047:1;13042:3;13038:11;13031:55;13117:14;13112:2;13107:3;13103:12;13096:36;13158:2;13153:3;13149:12;13142:19;;12937:230;;;:::o;13173:317::-;;13336:67;13400:2;13395:3;13336:67;:::i;:::-;13329:74;;13433:21;13429:1;13424:3;13420:11;13413:42;13481:2;13476:3;13472:12;13465:19;;13319:171;;;:::o;13496:388::-;;13659:67;13723:2;13718:3;13659:67;:::i;:::-;13652:74;;13756:34;13752:1;13747:3;13743:11;13736:55;13822:26;13817:2;13812:3;13808:12;13801:48;13875:2;13870:3;13866:12;13859:19;;13642:242;;;:::o;13890:374::-;;14053:67;14117:2;14112:3;14053:67;:::i;:::-;14046:74;;14150:34;14146:1;14141:3;14137:11;14130:55;14216:12;14211:2;14206:3;14202:12;14195:34;14255:2;14250:3;14246:12;14239:19;;14036:228;;;:::o;14270:366::-;;14433:67;14497:2;14492:3;14433:67;:::i;:::-;14426:74;;14530:34;14526:1;14521:3;14517:11;14510:55;14596:4;14591:2;14586:3;14582:12;14575:26;14627:2;14622:3;14618:12;14611:19;;14416:220;;;:::o;14642:330::-;;14805:67;14869:2;14864:3;14805:67;:::i;:::-;14798:74;;14902:34;14898:1;14893:3;14889:11;14882:55;14963:2;14958:3;14954:12;14947:19;;14788:184;;;:::o;14978:365::-;;15141:67;15205:2;15200:3;15141:67;:::i;:::-;15134:74;;15238:34;15234:1;15229:3;15225:11;15218:55;15304:3;15299:2;15294:3;15290:12;15283:25;15334:2;15329:3;15325:12;15318:19;;15124:219;;;:::o;15349:376::-;;15512:67;15576:2;15571:3;15512:67;:::i;:::-;15505:74;;15609:34;15605:1;15600:3;15596:11;15589:55;15675:14;15670:2;15665:3;15661:12;15654:36;15716:2;15711:3;15707:12;15700:19;;15495:230;;;:::o;15731:330::-;;15894:67;15958:2;15953:3;15894:67;:::i;:::-;15887:74;;15991:34;15987:1;15982:3;15978:11;15971:55;16052:2;16047:3;16043:12;16036:19;;15877:184;;;:::o;16067:373::-;;16230:67;16294:2;16289:3;16230:67;:::i;:::-;16223:74;;16327:34;16323:1;16318:3;16314:11;16307:55;16393:11;16388:2;16383:3;16379:12;16372:33;16431:2;16426:3;16422:12;16415:19;;16213:227;;;:::o;16446:379::-;;16609:67;16673:2;16668:3;16609:67;:::i;:::-;16602:74;;16706:34;16702:1;16697:3;16693:11;16686:55;16772:17;16767:2;16762:3;16758:12;16751:39;16816:2;16811:3;16807:12;16800:19;;16592:233;;;:::o;16831:365::-;;16994:67;17058:2;17053:3;16994:67;:::i;:::-;16987:74;;17091:34;17087:1;17082:3;17078:11;17071:55;17157:3;17152:2;17147:3;17143:12;17136:25;17187:2;17182:3;17178:12;17171:19;;16977:219;;;:::o;17202:314::-;;17365:67;17429:2;17424:3;17365:67;:::i;:::-;17358:74;;17462:18;17458:1;17453:3;17449:11;17442:39;17507:2;17502:3;17498:12;17491:19;;17348:168;;;:::o;17522:381::-;;17685:67;17749:2;17744:3;17685:67;:::i;:::-;17678:74;;17782:34;17778:1;17773:3;17769:11;17762:55;17848:19;17843:2;17838:3;17834:12;17827:41;17894:2;17889:3;17885:12;17878:19;;17668:235;;;:::o;17909:327::-;;18072:67;18136:2;18131:3;18072:67;:::i;:::-;18065:74;;18169:31;18165:1;18160:3;18156:11;18149:52;18227:2;18222:3;18218:12;18211:19;;18055:181;;;:::o;18242:315::-;;18405:67;18469:2;18464:3;18405:67;:::i;:::-;18398:74;;18502:19;18498:1;18493:3;18489:11;18482:40;18548:2;18543:3;18539:12;18532:19;;18388:169;;;:::o;18563:108::-;18640:24;18658:5;18640:24;:::i;:::-;18635:3;18628:37;18618:53;;:::o;18677:118::-;18764:24;18782:5;18764:24;:::i;:::-;18759:3;18752:37;18742:53;;:::o;18801:271::-;;18953:93;19042:3;19033:6;18953:93;:::i;:::-;18946:100;;19063:3;19056:10;;18935:137;;;;:::o;19078:435::-;;19280:95;19371:3;19362:6;19280:95;:::i;:::-;19273:102;;19392:95;19483:3;19474:6;19392:95;:::i;:::-;19385:102;;19504:3;19497:10;;19262:251;;;;;:::o;19519:222::-;;19650:2;19639:9;19635:18;19627:26;;19663:71;19731:1;19720:9;19716:17;19707:6;19663:71;:::i;:::-;19617:124;;;;:::o;19747:672::-;;19996:3;19985:9;19981:19;19973:27;;20010:87;20094:1;20083:9;20079:17;20070:6;20010:87;:::i;:::-;20107:72;20175:2;20164:9;20160:18;20151:6;20107:72;:::i;:::-;20189;20257:2;20246:9;20242:18;20233:6;20189:72;:::i;:::-;20308:9;20302:4;20298:20;20293:2;20282:9;20278:18;20271:48;20336:76;20407:4;20398:6;20336:76;:::i;:::-;20328:84;;19963:456;;;;;;;:::o;20425:373::-;;20606:2;20595:9;20591:18;20583:26;;20655:9;20649:4;20645:20;20641:1;20630:9;20626:17;20619:47;20683:108;20786:4;20777:6;20683:108;:::i;:::-;20675:116;;20573:225;;;;:::o;20804:210::-;;20929:2;20918:9;20914:18;20906:26;;20942:65;21004:1;20993:9;20989:17;20980:6;20942:65;:::i;:::-;20896:118;;;;:::o;21020:313::-;;21171:2;21160:9;21156:18;21148:26;;21220:9;21214:4;21210:20;21206:1;21195:9;21191:17;21184:47;21248:78;21321:4;21312:6;21248:78;:::i;:::-;21240:86;;21138:195;;;;:::o;21339:419::-;;21543:2;21532:9;21528:18;21520:26;;21592:9;21586:4;21582:20;21578:1;21567:9;21563:17;21556:47;21620:131;21746:4;21620:131;:::i;:::-;21612:139;;21510:248;;;:::o;21764:419::-;;21968:2;21957:9;21953:18;21945:26;;22017:9;22011:4;22007:20;22003:1;21992:9;21988:17;21981:47;22045:131;22171:4;22045:131;:::i;:::-;22037:139;;21935:248;;;:::o;22189:419::-;;22393:2;22382:9;22378:18;22370:26;;22442:9;22436:4;22432:20;22428:1;22417:9;22413:17;22406:47;22470:131;22596:4;22470:131;:::i;:::-;22462:139;;22360:248;;;:::o;22614:419::-;;22818:2;22807:9;22803:18;22795:26;;22867:9;22861:4;22857:20;22853:1;22842:9;22838:17;22831:47;22895:131;23021:4;22895:131;:::i;:::-;22887:139;;22785:248;;;:::o;23039:419::-;;23243:2;23232:9;23228:18;23220:26;;23292:9;23286:4;23282:20;23278:1;23267:9;23263:17;23256:47;23320:131;23446:4;23320:131;:::i;:::-;23312:139;;23210:248;;;:::o;23464:419::-;;23668:2;23657:9;23653:18;23645:26;;23717:9;23711:4;23707:20;23703:1;23692:9;23688:17;23681:47;23745:131;23871:4;23745:131;:::i;:::-;23737:139;;23635:248;;;:::o;23889:419::-;;24093:2;24082:9;24078:18;24070:26;;24142:9;24136:4;24132:20;24128:1;24117:9;24113:17;24106:47;24170:131;24296:4;24170:131;:::i;:::-;24162:139;;24060:248;;;:::o;24314:419::-;;24518:2;24507:9;24503:18;24495:26;;24567:9;24561:4;24557:20;24553:1;24542:9;24538:17;24531:47;24595:131;24721:4;24595:131;:::i;:::-;24587:139;;24485:248;;;:::o;24739:419::-;;24943:2;24932:9;24928:18;24920:26;;24992:9;24986:4;24982:20;24978:1;24967:9;24963:17;24956:47;25020:131;25146:4;25020:131;:::i;:::-;25012:139;;24910:248;;;:::o;25164:419::-;;25368:2;25357:9;25353:18;25345:26;;25417:9;25411:4;25407:20;25403:1;25392:9;25388:17;25381:47;25445:131;25571:4;25445:131;:::i;:::-;25437:139;;25335:248;;;:::o;25589:419::-;;25793:2;25782:9;25778:18;25770:26;;25842:9;25836:4;25832:20;25828:1;25817:9;25813:17;25806:47;25870:131;25996:4;25870:131;:::i;:::-;25862:139;;25760:248;;;:::o;26014:419::-;;26218:2;26207:9;26203:18;26195:26;;26267:9;26261:4;26257:20;26253:1;26242:9;26238:17;26231:47;26295:131;26421:4;26295:131;:::i;:::-;26287:139;;26185:248;;;:::o;26439:419::-;;26643:2;26632:9;26628:18;26620:26;;26692:9;26686:4;26682:20;26678:1;26667:9;26663:17;26656:47;26720:131;26846:4;26720:131;:::i;:::-;26712:139;;26610:248;;;:::o;26864:419::-;;27068:2;27057:9;27053:18;27045:26;;27117:9;27111:4;27107:20;27103:1;27092:9;27088:17;27081:47;27145:131;27271:4;27145:131;:::i;:::-;27137:139;;27035:248;;;:::o;27289:419::-;;27493:2;27482:9;27478:18;27470:26;;27542:9;27536:4;27532:20;27528:1;27517:9;27513:17;27506:47;27570:131;27696:4;27570:131;:::i;:::-;27562:139;;27460:248;;;:::o;27714:419::-;;27918:2;27907:9;27903:18;27895:26;;27967:9;27961:4;27957:20;27953:1;27942:9;27938:17;27931:47;27995:131;28121:4;27995:131;:::i;:::-;27987:139;;27885:248;;;:::o;28139:419::-;;28343:2;28332:9;28328:18;28320:26;;28392:9;28386:4;28382:20;28378:1;28367:9;28363:17;28356:47;28420:131;28546:4;28420:131;:::i;:::-;28412:139;;28310:248;;;:::o;28564:419::-;;28768:2;28757:9;28753:18;28745:26;;28817:9;28811:4;28807:20;28803:1;28792:9;28788:17;28781:47;28845:131;28971:4;28845:131;:::i;:::-;28837:139;;28735:248;;;:::o;28989:419::-;;29193:2;29182:9;29178:18;29170:26;;29242:9;29236:4;29232:20;29228:1;29217:9;29213:17;29206:47;29270:131;29396:4;29270:131;:::i;:::-;29262:139;;29160:248;;;:::o;29414:419::-;;29618:2;29607:9;29603:18;29595:26;;29667:9;29661:4;29657:20;29653:1;29642:9;29638:17;29631:47;29695:131;29821:4;29695:131;:::i;:::-;29687:139;;29585:248;;;:::o;29839:419::-;;30043:2;30032:9;30028:18;30020:26;;30092:9;30086:4;30082:20;30078:1;30067:9;30063:17;30056:47;30120:131;30246:4;30120:131;:::i;:::-;30112:139;;30010:248;;;:::o;30264:419::-;;30468:2;30457:9;30453:18;30445:26;;30517:9;30511:4;30507:20;30503:1;30492:9;30488:17;30481:47;30545:131;30671:4;30545:131;:::i;:::-;30537:139;;30435:248;;;:::o;30689:419::-;;30893:2;30882:9;30878:18;30870:26;;30942:9;30936:4;30932:20;30928:1;30917:9;30913:17;30906:47;30970:131;31096:4;30970:131;:::i;:::-;30962:139;;30860:248;;;:::o;31114:419::-;;31318:2;31307:9;31303:18;31295:26;;31367:9;31361:4;31357:20;31353:1;31342:9;31338:17;31331:47;31395:131;31521:4;31395:131;:::i;:::-;31387:139;;31285:248;;;:::o;31539:419::-;;31743:2;31732:9;31728:18;31720:26;;31792:9;31786:4;31782:20;31778:1;31767:9;31763:17;31756:47;31820:131;31946:4;31820:131;:::i;:::-;31812:139;;31710:248;;;:::o;31964:419::-;;32168:2;32157:9;32153:18;32145:26;;32217:9;32211:4;32207:20;32203:1;32192:9;32188:17;32181:47;32245:131;32371:4;32245:131;:::i;:::-;32237:139;;32135:248;;;:::o;32389:419::-;;32593:2;32582:9;32578:18;32570:26;;32642:9;32636:4;32632:20;32628:1;32617:9;32613:17;32606:47;32670:131;32796:4;32670:131;:::i;:::-;32662:139;;32560:248;;;:::o;32814:222::-;;32945:2;32934:9;32930:18;32922:26;;32958:71;33026:1;33015:9;33011:17;33002:6;32958:71;:::i;:::-;32912:124;;;;:::o;33042:278::-;;33108:2;33102:9;33092:19;;33150:4;33142:6;33138:17;33257:6;33245:10;33242:22;33221:18;33209:10;33206:34;33203:62;33200:2;;;33268:13;;:::i;:::-;33200:2;33303:10;33299:2;33292:22;33082:238;;;;:::o;33326:326::-;;33477:18;33469:6;33466:30;33463:2;;;33499:13;;:::i;:::-;33463:2;33579:4;33575:9;33568:4;33560:6;33556:17;33552:33;33544:41;;33640:4;33634;33630:15;33622:23;;33392:260;;;:::o;33658:327::-;;33810:18;33802:6;33799:30;33796:2;;;33832:13;;:::i;:::-;33796:2;33912:4;33908:9;33901:4;33893:6;33889:17;33885:33;33877:41;;33973:4;33967;33963:15;33955:23;;33725:260;;;:::o;33991:132::-;;34081:3;34073:11;;34111:4;34106:3;34102:14;34094:22;;34063:60;;;:::o;34129:114::-;;34230:5;34224:12;34214:22;;34203:40;;;:::o;34249:98::-;;34334:5;34328:12;34318:22;;34307:40;;;:::o;34353:99::-;;34439:5;34433:12;34423:22;;34412:40;;;:::o;34458:113::-;;34560:4;34555:3;34551:14;34543:22;;34533:38;;;:::o;34577:184::-;;34710:6;34705:3;34698:19;34750:4;34745:3;34741:14;34726:29;;34688:73;;;;:::o;34767:168::-;;34884:6;34879:3;34872:19;34924:4;34919:3;34915:14;34900:29;;34862:73;;;;:::o;34941:147::-;;35079:3;35064:18;;35054:34;;;;:::o;35094:169::-;;35212:6;35207:3;35200:19;35252:4;35247:3;35243:14;35228:29;;35190:73;;;;:::o;35269:148::-;;35408:3;35393:18;;35383:34;;;;:::o;35423:96::-;;35489:24;35507:5;35489:24;:::i;:::-;35478:35;;35468:51;;;:::o;35525:104::-;;35599:24;35617:5;35599:24;:::i;:::-;35588:35;;35578:51;;;:::o;35635:90::-;;35712:5;35705:13;35698:21;35687:32;;35677:48;;;:::o;35731:149::-;;35807:66;35800:5;35796:78;35785:89;;35775:105;;;:::o;35886:126::-;;35963:42;35956:5;35952:54;35941:65;;35931:81;;;:::o;36018:77::-;;36084:5;36073:16;;36063:32;;;:::o;36101:154::-;36185:6;36180:3;36175;36162:30;36247:1;36238:6;36233:3;36229:16;36222:27;36152:103;;;:::o;36261:307::-;36329:1;36339:113;36353:6;36350:1;36347:13;36339:113;;;36438:1;36433:3;36429:11;36423:18;36419:1;36414:3;36410:11;36403:39;36375:2;36372:1;36368:10;36363:15;;36339:113;;;36470:6;36467:1;36464:13;36461:2;;;36550:1;36541:6;36536:3;36532:16;36525:27;36461:2;36310:258;;;;:::o;36574:48::-;36607:9;36628:102;;36720:2;36716:7;36711:2;36704:5;36700:14;36696:28;36686:38;;36676:54;;;:::o;36736:122::-;36809:24;36827:5;36809:24;:::i;:::-;36802:5;36799:35;36789:2;;36848:1;36845;36838:12;36789:2;36779:79;:::o;36864:116::-;36934:21;36949:5;36934:21;:::i;:::-;36927:5;36924:32;36914:2;;36970:1;36967;36960:12;36914:2;36904:76;:::o;36986:120::-;37058:23;37075:5;37058:23;:::i;:::-;37051:5;37048:34;37038:2;;37096:1;37093;37086:12;37038:2;37028:78;:::o;37112:122::-;37185:24;37203:5;37185:24;:::i;:::-;37178:5;37175:35;37165:2;;37224:1;37221;37214:12;37165:2;37155:79;:::o

Swarm Source

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