ETH Price: $3,468.49 (+2.19%)
Gas: 17 Gwei

Token

The Moon Monsters (TMM)
 

Overview

Max Total Supply

299 TMM

Holders

141

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
5 TMM
0x2bb0131f561df1a69b49da3d26c8501710327dc1
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:
THEMOONMONSTER

Compiler Version
v0.7.0+commit.9e61f92b

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

/**

___________.__                _____                            _____                          __                       
\__    ___/|  |__   ____     /     \   ____   ____   ____     /     \   ____   ____   _______/  |_  ___________  ______
  |    |   |  |  \_/ __ \   /  \ /  \ /  _ \ /  _ \ /    \   /  \ /  \ /  _ \ /    \ /  ___/\   __\/ __ \_  __ \/  ___/
  |    |   |   Y  \  ___/  /    Y    (  <_> |  <_> )   |  \ /    Y    (  <_> )   |  \\___ \  |  | \  ___/|  | \/\___ \ 
  |____|   |___|  /\___  > \____|__  /\____/ \____/|___|  / \____|__  /\____/|___|  /____  > |__|  \___  >__|  /____  >
                \/     \/          \/                   \/          \/            \/     \/            \/           \/ 

by Mert Tığlıoğlu https://twitter.com/tiglioglum                
*/

// Sources flattened with hardhat v2.6.1 https://hardhat.org

// File @openzeppelin/contracts/GSN/[email protected]

// SPDX-License-Identifier: MIT

pragma solidity ^0.7.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/[email protected]


pragma solidity ^0.7.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/[email protected]


pragma solidity ^0.7.0;

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transfered 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/[email protected]


pragma solidity ^0.7.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/[email protected]


pragma solidity ^0.7.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/[email protected]


pragma solidity ^0.7.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/[email protected]


pragma solidity ^0.7.0;

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

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

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

    /**
     * @dev See {IERC165-supportsInterface}.
     *
     * Time complexity O(1), guaranteed to always use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) public view 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/[email protected]


pragma solidity ^0.7.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, 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) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * 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);
        uint256 c = a - b;

        return c;
    }

    /**
     * @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) {
        // 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 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts 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) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts 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) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}


// File @openzeppelin/contracts/utils/[email protected]


pragma solidity ^0.7.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) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != accountHash && codehash != 0x0);
    }

    /**
     * @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");
        return _functionCallWithValue(target, data, value, errorMessage);
    }

    function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
        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/[email protected]


pragma solidity ^0.7.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.0.0, only sets of type `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];
    }

    // 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(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(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(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(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/[email protected]


pragma solidity ^0.7.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 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) {
        return _get(map, key, "EnumerableMap: nonexistent key");
    }

    /**
     * @dev Same as {_get}, with a custom error message when `key` is not in the map.
     */
    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(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(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(uint256(_get(map._inner, bytes32(key))));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     */
    function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {
        return address(uint256(_get(map._inner, bytes32(key), errorMessage)));
    }
}


// File @openzeppelin/contracts/utils/[email protected]


pragma solidity ^0.7.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--] = byte(uint8(48 + temp % 10));
            temp /= 10;
        }
        return string(buffer);
    }
}


// File @openzeppelin/contracts/token/ERC721/[email protected]


pragma solidity ^0.7.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) {
        _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 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 override returns (address) {
        return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token");
    }

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

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

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

        string memory _tokenURI = _tokenURIs[tokenId];

        // If there is no base URI, return the token URI.
        if (bytes(_baseURI).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(_baseURI, _tokenURI));
        }
        // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
        return string(abi.encodePacked(_baseURI, 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 returns (string memory) {
        return _baseURI;
    }

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

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view 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 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 = ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(_msgSender() == owner || 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 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 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 mecanisms 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 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 returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || 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 = ownerOf(tokenId);

        _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(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        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);
    }

    function _approve(address to, uint256 tokenId) private {
        _tokenApprovals[tokenId] = to;
        emit Approval(ownerOf(tokenId), to, tokenId);
    }

    /**
     * @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/[email protected]


pragma solidity ^0.7.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.
 */
contract Ownable is Context {
    address private _owner;

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

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

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

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

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

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


// File contracts/MOONMONSTER.sol

pragma solidity ^0.7.0;


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

    uint256 public presale_price = 65000000000000000; //65000000000000000;
    uint256 public public_price = 80000000000000000; //80000000000000000;
    uint256 public constant MAX_THEMOONMONSTER = 10000; //10000;
    uint256 public constant MAX_THEMOONMONSTER_PRE_SALE = 1800; //1800;
    uint256 public constant MAX_THEMOONMONSTER_PRESALE_PERWALLET = 5; //5; 
    uint256 public MAX_THEMOONMONSTER_RESERVE = 200; //200;

    address FOUNDER_1 = 0xdE5D7bF79FD96F22EAdE09031294A61cD3976581;
    address FOUNDER_2 = 0x87A58C3D03093b43433e85Ad3043A87F62A75776;
    address MOONVERSE_NFT_GAMING = 0x08a3d4816EA40EA9F5c58E49eFf8Ce19748004F8;

    string public whitelistURI;

	mapping(address => bool) public presalerList;
	mapping(address => uint256) public presalerListPurchases;

    bool public saleIsActive = false;
    bool public preSaleIsActive = false;
    uint internal nonce = 0;
    uint256[MAX_THEMOONMONSTER] internal indices;

    constructor() 
    
    ERC721("The Moon Monsters", "TMM") { }

    function setPresalePrice(uint256 limit) public  onlyOwner {
       require(msg.sender == owner(), "Invalid sender");
        presale_price = limit;
    }

    function setPublicPrice(uint256 limit) public  onlyOwner {
       require(msg.sender == owner(), "Invalid sender");
        public_price = limit;
    }

    function addToPresaleList(address[] calldata entries) external onlyOwner {
		for (uint256 i = 0; i < entries.length; i++) {
			address entry = entries[i];
			require(entry != address(0), 'NULL_ADDRESS');
			require(!presalerList[entry], 'DUPLICATE_ENTRY');

			presalerList[entry] = true;
		}
	}

	function removeFromPresaleList(address[] calldata entries) external onlyOwner {
		for (uint256 i = 0; i < entries.length; i++) {
			address entry = entries[i];
			require(entry != address(0), 'NULL_ADDRESS');

			presalerList[entry] = false;
		}
	}

    function randomIndex() internal returns (uint256) {
        uint256 totalSize = MAX_THEMOONMONSTER - totalSupply();
        uint256 index = uint(keccak256(abi.encodePacked(nonce, msg.sender, block.difficulty, block.timestamp))) % totalSize;
        uint256 value = 0;

        if (indices[index] != 0) {
        value = indices[index];
        } else {
        value = index;
        }

        if (indices[totalSize - 1] == 0) {
        indices[index] = totalSize - 1;
        } else {
        indices[index] = indices[totalSize - 1];
        }

        nonce++;
        return value.add(1);
    }

    function _mintWithRandomTokenId(address _to) private {
        uint _tokenID = randomIndex();
        _safeMint(_to, _tokenID);
    }    

    function burn(uint256 tokenId) external onlyOwner{
        require(ownerOf(tokenId) == msg.sender, "NOT_OWNER_OF_TOKEN");
        _burn(tokenId);
    }
    

    function mintNFT(uint256 numberOfTokens) public payable {
        require(saleIsActive, 'SALE_CLOSED');
		require(!preSaleIsActive, 'ONLY_PUBLIC_SALE');
        //require(numberOfTokens + balanceOf(msg.sender) <= MAX_THEMOONMONSTER_PUBLICSALE_PERWALLET, "You have exceeded max limit per wallet");
        //require(numberOfTokens <= MAX_THEMOONMONSTER_PUBLICSALE_PERWALLET, "You have exceeded max limit per transaction for public sale");
        require(totalSupply().add(numberOfTokens) <= MAX_THEMOONMONSTER.sub(MAX_THEMOONMONSTER_RESERVE) , "Purchase would exceed max supply");
        require(public_price * numberOfTokens <= msg.value, "Ether value sent is not correct");

        for(uint i = 0; i < numberOfTokens; i++) {
            if (totalSupply() < MAX_THEMOONMONSTER) {
                _mintWithRandomTokenId(msg.sender);
            }
        }
    }
    
    function presaleNFT(uint256 numberOfTokens) public payable {
        require(preSaleIsActive, 'SALE_CLOSED');
		require(!saleIsActive, 'ONLY_PRESALE');
        require(numberOfTokens + balanceOf(msg.sender) <= MAX_THEMOONMONSTER_PRESALE_PERWALLET, "You have exceeded max limit per wallet");
        require(numberOfTokens <= MAX_THEMOONMONSTER_PRESALE_PERWALLET, "Too many tokens at once");
        require(totalSupply().add(numberOfTokens) <= MAX_THEMOONMONSTER_PRE_SALE, "Purchase would exceed max supply");
        require(msg.value >= presale_price * numberOfTokens, "Not enough money");
      	//require(presalerList[msg.sender], 'Not on the list');
        //require(presalerListPurchases[msg.sender] + numberOfTokens <= MAX_THEMOONMONSTER_PRESALE_PERWALLET,'EXCEED_ALLOC');
        

        for(uint i = 0; i < numberOfTokens; i++) {
            if (totalSupply() < MAX_THEMOONMONSTER_PRE_SALE) {
                _mintWithRandomTokenId(msg.sender);
            }
        }

        
    } 

     function giveAway(uint256 numberOfTokens, address to) public payable {
        require(msg.sender == owner(), "Invalid sender");
        require(numberOfTokens > 0 && numberOfTokens <= MAX_THEMOONMONSTER_RESERVE, "Not enough reserve left for team");

        for(uint i = 0; i < numberOfTokens; i++) {
            if (totalSupply() < MAX_THEMOONMONSTER) {
                _mintWithRandomTokenId(to);
            }
        }
        MAX_THEMOONMONSTER_RESERVE = MAX_THEMOONMONSTER_RESERVE.sub(numberOfTokens);
    }

     function withdrawAll() public onlyOwner {
        uint256 balance = address(this).balance;
        require(balance > 0);

        _withdraw(FOUNDER_1, (balance * 30) / 100);
        _withdraw(FOUNDER_2, (balance * 30) / 100);
        _withdraw(MOONVERSE_NFT_GAMING, (balance * 40) / 100);
       
        _withdraw(owner(), address(this).balance);
    }

    function _withdraw(address _address, uint256 _amount) private {
        (bool success, ) = _address.call{value: _amount}("");
        require(success, "Transfer failed.");
    }

    function isPresaler(address addr) external view returns (bool) {
		return presalerList[addr];
	}

	function presalePurchasedCount(address addr) external view returns (uint256) {
		return presalerListPurchases[addr];
	}

    function flipSaleState() public onlyOwner {
        saleIsActive = !saleIsActive;
    }

    function flipPreSaleState() public  onlyOwner {
        preSaleIsActive = !preSaleIsActive;
    }

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

    function multiBurn(uint256 startTokenId,uint256 endTokenId) external  onlyOwner{
        for(uint i = startTokenId; i <= endTokenId; i++) {
            require(ownerOf(i) == msg.sender, "NOT_OWNER_OF_TOKEN");
            _burn(i); 
        }
    }

     function setWhiteList( string memory _whitelistURI) public onlyOwner {
        require(msg.sender == owner(), "Invalid sender");
        whitelistURI = _whitelistURI;
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_THEMOONMONSTER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_THEMOONMONSTER_PRESALE_PERWALLET","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_THEMOONMONSTER_PRE_SALE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_THEMOONMONSTER_RESERVE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"entries","type":"address[]"}],"name":"addToPresaleList","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipPreSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"giveAway","outputs":[],"stateMutability":"payable","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":"address","name":"addr","type":"address"}],"name":"isPresaler","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"mintNFT","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startTokenId","type":"uint256"},{"internalType":"uint256","name":"endTokenId","type":"uint256"}],"name":"multiBurn","outputs":[],"stateMutability":"nonpayable","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":"preSaleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"presaleNFT","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"presalePurchasedCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presale_price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"presalerList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"presalerListPurchases","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"public_price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"entries","type":"address[]"}],"name":"removeFromPresaleList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"setPresalePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"setPublicPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_whitelistURI","type":"string"}],"name":"setWhiteList","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":[],"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":"whitelistURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405266e6ed27d6668000600b5567011c37937e080000600c5560c8600d5573de5d7bf79fd96f22eade09031294a61cd3976581600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507387a58c3d03093b43433e85ad3043a87f62a75776600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507308a3d4816ea40ea9f5c58e49eff8ce19748004f8601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000601460006101000a81548160ff0219169083151502179055506000601460016101000a81548160ff02191690831515021790555060006015553480156200016757600080fd5b506040518060400160405280601181526020017f546865204d6f6f6e204d6f6e73746572730000000000000000000000000000008152506040518060400160405280600381526020017f544d4d0000000000000000000000000000000000000000000000000000000000815250620001ec6301ffc9a760e01b6200031f60201b60201c565b81600690805190602001906200020492919062000430565b5080600790805190602001906200021d92919062000430565b50620002366380ac58cd60e01b6200031f60201b60201c565b6200024e635b5e139f60e01b6200031f60201b60201c565b6200026663780e9d6360e01b6200031f60201b60201c565b505060006200027a6200042860201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350620004d6565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415620003bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433136353a20696e76616c696420696e746572666163652069640000000081525060200191505060405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200047357805160ff1916838001178555620004a4565b82800160010185558215620004a4579182015b82811115620004a357825182559160200191906001019062000486565b5b509050620004b39190620004b7565b5090565b5b80821115620004d2576000816000905550600101620004b8565b5090565b61594a80620004e66000396000f3fe6080604052600436106102885760003560e01c80637204a3c91161015a578063ab80baac116100c1578063eb8d24441161007a578063eb8d2444146111f3578063f032554914611220578063f2fde38b14611237578063f33b7e9214611288578063f49bc8b514611318578063ff147ef81461134357610288565b8063ab80baac14610eba578063b179e06014610ee5578063b88d4fde14610f6b578063c62752551461107d578063c87b56dd146110b8578063e985e9c51461116c57610288565b8063969745e811610113578063969745e814610cd45780639bf8031614610cff5780639cf2e8d614610d645780639e273b2f14610dcb578063a22cb46514610e32578063a69f675014610e8f57610288565b80637204a3c914610b0d5780637f5230ab14610b93578063853828b614610bbe5780638da5cb5b14610bd55780639264274414610c1657806395d89b4114610c4457610288565b80633549345e116101fe57806355f804b3116101b757806355f804b31461086f5780635ce7af1f146109375780636352211e1461099c5780636c0360eb14610a0157806370a0823114610a91578063715018a614610af657610288565b80633549345e146106bc5780633a6a85bf146106f757806342842e0e1461072557806342966c68146107a05780634d5012e3146107db5780634f6ccce71461082057610288565b806318160ddd1161025057806318160ddd146105155780631f0234d81461054057806323b872dd1461056d578063261d3b21146105e85780632f745c591461063657806334918dfd146106a557610288565b806301ffc9a71461028d57806306fdde03146102fd578063081812fc1461038d578063095ea7b3146103f257806313209af01461044d575b600080fd5b34801561029957600080fd5b506102e5600480360360208110156102b057600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916906020019092919050505061136e565b60405180821515815260200191505060405180910390f35b34801561030957600080fd5b506103126113d5565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610352578082015181840152602081019050610337565b50505050905090810190601f16801561037f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561039957600080fd5b506103c6600480360360208110156103b057600080fd5b8101908080359060200190929190505050611477565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156103fe57600080fd5b5061044b6004803603604081101561041557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611512565b005b34801561045957600080fd5b506105136004803603602081101561047057600080fd5b810190808035906020019064010000000081111561048d57600080fd5b82018360208201111561049f57600080fd5b803590602001918460018302840111640100000000831117156104c157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611656565b005b34801561052157600080fd5b5061052a6117e2565b6040518082815260200191505060405180910390f35b34801561054c57600080fd5b506105556117f3565b60405180821515815260200191505060405180910390f35b34801561057957600080fd5b506105e66004803603606081101561059057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611806565b005b610634600480360360408110156105fe57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061187c565b005b34801561064257600080fd5b5061068f6004803603604081101561065957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506119fb565b6040518082815260200191505060405180910390f35b3480156106b157600080fd5b506106ba611a56565b005b3480156106c857600080fd5b506106f5600480360360208110156106df57600080fd5b8101908080359060200190929190505050611b4c565b005b6107236004803603602081101561070d57600080fd5b8101908080359060200190929190505050611cc8565b005b34801561073157600080fd5b5061079e6004803603606081101561074857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611fea565b005b3480156107ac57600080fd5b506107d9600480360360208110156107c357600080fd5b810190808035906020019092919050505061200a565b005b3480156107e757600080fd5b5061081e600480360360408110156107fe57600080fd5b810190808035906020019092919080359060200190929190505050612189565b005b34801561082c57600080fd5b506108596004803603602081101561084357600080fd5b8101908080359060200190929190505050612324565b6040518082815260200191505060405180910390f35b34801561087b57600080fd5b506109356004803603602081101561089257600080fd5b81019080803590602001906401000000008111156108af57600080fd5b8201836020820111156108c157600080fd5b803590602001918460018302840111640100000000831117156108e357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612347565b005b34801561094357600080fd5b506109866004803603602081101561095a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061241d565b6040518082815260200191505060405180910390f35b3480156109a857600080fd5b506109d5600480360360208110156109bf57600080fd5b8101908080359060200190929190505050612466565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610a0d57600080fd5b50610a1661249d565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610a56578082015181840152602081019050610a3b565b50505050905090810190601f168015610a835780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610a9d57600080fd5b50610ae060048036036020811015610ab457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061253f565b6040518082815260200191505060405180910390f35b348015610b0257600080fd5b50610b0b612614565b005b348015610b1957600080fd5b50610b9160048036036020811015610b3057600080fd5b8101908080359060200190640100000000811115610b4d57600080fd5b820183602082011115610b5f57600080fd5b80359060200191846020830284011164010000000083111715610b8157600080fd5b909192939192939050505061279f565b005b348015610b9f57600080fd5b50610ba8612a72565b6040518082815260200191505060405180910390f35b348015610bca57600080fd5b50610bd3612a77565b005b348015610be157600080fd5b50610bea612c12565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610c4260048036036020811015610c2c57600080fd5b8101908080359060200190929190505050612c3c565b005b348015610c5057600080fd5b50610c59612e97565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610c99578082015181840152602081019050610c7e565b50505050905090810190601f168015610cc65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610ce057600080fd5b50610ce9612f39565b6040518082815260200191505060405180910390f35b348015610d0b57600080fd5b50610d4e60048036036020811015610d2257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f3f565b6040518082815260200191505060405180910390f35b348015610d7057600080fd5b50610db360048036036020811015610d8757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f57565b60405180821515815260200191505060405180910390f35b348015610dd757600080fd5b50610e1a60048036036020811015610dee57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f77565b60405180821515815260200191505060405180910390f35b348015610e3e57600080fd5b50610e8d60048036036040811015610e5557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050612fcd565b005b348015610e9b57600080fd5b50610ea4613183565b6040518082815260200191505060405180910390f35b348015610ec657600080fd5b50610ecf613189565b6040518082815260200191505060405180910390f35b348015610ef157600080fd5b50610f6960048036036020811015610f0857600080fd5b8101908080359060200190640100000000811115610f2557600080fd5b820183602082011115610f3757600080fd5b80359060200191846020830284011164010000000083111715610f5957600080fd5b909192939192939050505061318f565b005b348015610f7757600080fd5b5061107b60048036036080811015610f8e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610ff557600080fd5b82018360208201111561100757600080fd5b8035906020019184600183028401116401000000008311171561102957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506133a2565b005b34801561108957600080fd5b506110b6600480360360208110156110a057600080fd5b810190808035906020019092919050505061341a565b005b3480156110c457600080fd5b506110f1600480360360208110156110db57600080fd5b8101908080359060200190929190505050613596565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611131578082015181840152602081019050611116565b50505050905090810190601f16801561115e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561117857600080fd5b506111db6004803603604081101561118f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061387f565b60405180821515815260200191505060405180910390f35b3480156111ff57600080fd5b50611208613913565b60405180821515815260200191505060405180910390f35b34801561122c57600080fd5b50611235613926565b005b34801561124357600080fd5b506112866004803603602081101561125a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613a1c565b005b34801561129457600080fd5b5061129d613c2c565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156112dd5780820151818401526020810190506112c2565b50505050905090810190601f16801561130a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561132457600080fd5b5061132d613cca565b6040518082815260200191505060405180910390f35b34801561134f57600080fd5b50611358613cd0565b6040518082815260200191505060405180910390f35b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561146d5780601f106114425761010080835404028352916020019161146d565b820191906000526020600020905b81548152906001019060200180831161145057829003601f168201915b5050505050905090565b600061148282613cd6565b6114d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061583f602c913960400191505060405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061151d82612466565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156115a4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806158c36021913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166115c3613cf3565b73ffffffffffffffffffffffffffffffffffffffff1614806115f257506115f1816115ec613cf3565b61387f565b5b611647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806157926038913960400191505060405180910390fd5b6116518383613cfb565b505050565b61165e613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611720576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611728612c12565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146117c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b80601190805190602001906117de9291906155bc565b5050565b60006117ee6002613db4565b905090565b601460019054906101000a900460ff1681565b611817611811613cf3565b82613dc9565b61186c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806158e46031913960400191505060405180910390fd5b611877838383613ebd565b505050565b611884612c12565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611924576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000821180156119365750600d548211155b6119a8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4e6f7420656e6f7567682072657365727665206c65667420666f72207465616d81525060200191505060405180910390fd5b60005b828110156119db576127106119be6117e2565b10156119ce576119cd82614100565b5b80806001019150506119ab565b506119f182600d5461411a90919063ffffffff16565b600d819055505050565b6000611a4e82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061416490919063ffffffff16565b905092915050565b611a5e613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611b20576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b601460009054906101000a900460ff1615601460006101000a81548160ff021916908315150217905550565b611b54613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611c16576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611c1e612c12565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611cbe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b80600b8190555050565b601460019054906101000a900460ff16611d4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f53414c455f434c4f53454400000000000000000000000000000000000000000081525060200191505060405180910390fd5b601460009054906101000a900460ff1615611dcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4f4e4c595f50524553414c45000000000000000000000000000000000000000081525060200191505060405180910390fd5b6005611dd83361253f565b82011115611e31576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806156c46026913960400191505060405180910390fd5b6005811115611ea8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f546f6f206d616e7920746f6b656e73206174206f6e636500000000000000000081525060200191505060405180910390fd5b610708611ec582611eb76117e2565b61417e90919063ffffffff16565b1115611f39576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f507572636861736520776f756c6420657863656564206d617820737570706c7981525060200191505060405180910390fd5b80600b5402341015611fb3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4e6f7420656e6f756768206d6f6e65790000000000000000000000000000000081525060200191505060405180910390fd5b60005b81811015611fe657610708611fc96117e2565b1015611fd957611fd833614100565b5b8080600101915050611fb6565b5050565b612005838383604051806020016040528060008152506133a2565b505050565b612012613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146120d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166120f482612466565b73ffffffffffffffffffffffffffffffffffffffff161461217d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4e4f545f4f574e45525f4f465f544f4b454e000000000000000000000000000081525060200191505060405180910390fd5b61218681614206565b50565b612191613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612253576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60008290505b81811161231f573373ffffffffffffffffffffffffffffffffffffffff1661228082612466565b73ffffffffffffffffffffffffffffffffffffffff1614612309576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4e4f545f4f574e45525f4f465f544f4b454e000000000000000000000000000081525060200191505060405180910390fd5b61231281614206565b8080600101915050612259565b505050565b60008061233b83600261434090919063ffffffff16565b50905080915050919050565b61234f613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612411576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61241a8161436c565b50565b6000601360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000612496826040518060600160405280602981526020016157f46029913960026143869092919063ffffffff16565b9050919050565b606060098054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156125355780601f1061250a57610100808354040283529160200191612535565b820191906000526020600020905b81548152906001019060200180831161251857829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156125c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a8152602001806157ca602a913960400191505060405180910390fd5b61260d600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206143a5565b9050919050565b61261c613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146126de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6127a7613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612869576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60005b82829050811015612a6d57600083838381811061288557fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612947576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e554c4c5f41444452455353000000000000000000000000000000000000000081525060200191505060405180910390fd5b601260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f4455504c49434154455f454e545259000000000000000000000000000000000081525060200191505060405180910390fd5b6001601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050808060010191505061286c565b505050565b600581565b612a7f613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612b41576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600047905060008111612b5357600080fd5b612b8c600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064601e840281612b8657fe5b046143ba565b612bc5600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064601e840281612bbf57fe5b046143ba565b612bfe601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660646028840281612bf857fe5b046143ba565b612c0f612c09612c12565b476143ba565b50565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b601460009054906101000a900460ff16612cbe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f53414c455f434c4f53454400000000000000000000000000000000000000000081525060200191505060405180910390fd5b601460019054906101000a900460ff1615612d41576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4f4e4c595f5055424c49435f53414c450000000000000000000000000000000081525060200191505060405180910390fd5b612d58600d5461271061411a90919063ffffffff16565b612d7282612d646117e2565b61417e90919063ffffffff16565b1115612de6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f507572636861736520776f756c6420657863656564206d617820737570706c7981525060200191505060405180910390fd5b3481600c54021115612e60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45746865722076616c75652073656e74206973206e6f7420636f72726563740081525060200191505060405180910390fd5b60005b81811015612e9357612710612e766117e2565b1015612e8657612e8533614100565b5b8080600101915050612e63565b5050565b606060078054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612f2f5780601f10612f0457610100808354040283529160200191612f2f565b820191906000526020600020905b815481529060010190602001808311612f1257829003601f168201915b5050505050905090565b600b5481565b60136020528060005260406000206000915090505481565b60126020528060005260406000206000915054906101000a900460ff1681565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b612fd5613cf3565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613076576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4552433732313a20617070726f766520746f2063616c6c65720000000000000081525060200191505060405180910390fd5b8060056000613083613cf3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16613130613cf3565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b600c5481565b61271081565b613197613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613259576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60005b8282905081101561339d57600083838381811061327557fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415613337576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e554c4c5f41444452455353000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050808060010191505061325c565b505050565b6133b36133ad613cf3565b83613dc9565b613408576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806158e46031913960400191505060405180910390fd5b6134148484848461449b565b50505050565b613422613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146134e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6134ec612c12565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461358c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b80600c8190555050565b60606135a182613cd6565b6135f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180615894602f913960400191505060405180910390fd5b6060600860008481526020019081526020016000208054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561369f5780601f106136745761010080835404028352916020019161369f565b820191906000526020600020905b81548152906001019060200180831161368257829003601f168201915b505050505090506000600980546001816001161561010002031660029004905014156136ce578091505061387a565b6000815111156137a75760098160405160200180838054600181600116156101000203166002900480156137395780601f10613717576101008083540402835291820191613739565b820191906000526020600020905b815481529060010190602001808311613725575b505082805190602001908083835b6020831061376a5780518252602082019150602081019050602083039250613747565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405291505061387a565b60096137b28461450d565b60405160200180838054600181600116156101000203166002900480156138105780601f106137ee576101008083540402835291820191613810565b820191906000526020600020905b8154815290600101906020018083116137fc575b505082805190602001908083835b60208310613841578051825260208201915060208101905060208303925061381e565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529150505b919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b601460009054906101000a900460ff1681565b61392e613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146139f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b601460019054906101000a900460ff1615601460016101000a81548160ff021916908315150217905550565b613a24613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613ae6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415613b6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061571c6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60118054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613cc25780601f10613c9757610100808354040283529160200191613cc2565b820191906000526020600020905b815481529060010190602001808311613ca557829003601f168201915b505050505081565b61070881565b600d5481565b6000613cec82600261465490919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16613d6e83612466565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000613dc28260000161466e565b9050919050565b6000613dd482613cd6565b613e29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615766602c913960400191505060405180910390fd5b6000613e3483612466565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480613ea357508373ffffffffffffffffffffffffffffffffffffffff16613e8b84611477565b73ffffffffffffffffffffffffffffffffffffffff16145b80613eb45750613eb3818561387f565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16613edd82612466565b73ffffffffffffffffffffffffffffffffffffffff1614613f49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602981526020018061586b6029913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613fcf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806157426024913960400191505060405180910390fd5b613fda83838361467f565b613fe5600082613cfb565b61403681600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061468490919063ffffffff16565b5061408881600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061469e90919063ffffffff16565b5061409f818360026146b89092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600061410a6146ed565b90506141168282614827565b5050565b600061415c83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614845565b905092915050565b60006141738360000183614905565b60001c905092915050565b6000808284019050838110156141fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600061421182612466565b905061421f8160008461467f565b61422a600083613cfb565b6000600860008481526020019081526020016000208054600181600116156101000203166002900490501461427957600860008381526020019081526020016000206000614278919061563c565b5b6142ca82600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061468490919063ffffffff16565b506142df82600261498890919063ffffffff16565b5081600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b60008060008061435386600001866149a2565b915091508160001c8160001c9350935050509250929050565b80600990805190602001906143829291906155bc565b5050565b6000614399846000018460001b84614a3b565b60001c90509392505050565b60006143b382600001614b31565b9050919050565b60008273ffffffffffffffffffffffffffffffffffffffff168260405180600001905060006040518083038185875af1925050503d806000811461441a576040519150601f19603f3d011682016040523d82523d6000602084013e61441f565b606091505b5050905080614496576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5472616e73666572206661696c65642e0000000000000000000000000000000081525060200191505060405180910390fd5b505050565b6144a6848484613ebd565b6144b284848484614b42565b614507576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806156ea6032913960400191505060405180910390fd5b50505050565b60606000821415614555576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061464f565b600082905060005b6000821461457f578080600101915050600a828161457757fe5b04915061455d565b60608167ffffffffffffffff8111801561459857600080fd5b506040519080825280601f01601f1916602001820160405280156145cb5781602001600182028036833780820191505090505b50905060006001830390508593505b6000841461464757600a84816145ec57fe5b0660300160f81b8282806001900393508151811061460657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a848161463f57fe5b0493506145da565b819450505050505b919050565b6000614666836000018360001b614d5b565b905092915050565b600081600001805490509050919050565b505050565b6000614696836000018360001b614d7e565b905092915050565b60006146b0836000018360001b614e66565b905092915050565b60006146e4846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b614ed6565b90509392505050565b6000806146f86117e2565b612710039050600081601554334442604051602001808581526020018473ffffffffffffffffffffffffffffffffffffffff1660601b81526014018381526020018281526020019450505050506040516020818303038152906040528051906020012060001c8161476557fe5b069050600080601683612710811061477957fe5b01541461479757601682612710811061478e57fe5b0154905061479b565b8190505b600060166001850361271081106147ae57fe5b015414156147d2576001830360168361271081106147c857fe5b01819055506147f9565b60166001840361271081106147e357fe5b015460168361271081106147f357fe5b01819055505b60156000815480929190600101919050555061481f60018261417e90919063ffffffff16565b935050505090565b614841828260405180602001604052806000815250614fb2565b5050565b60008383111582906148f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156148b757808201518184015260208101905061489c565b50505050905090810190601f1680156148e45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600081836000018054905011614966576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806156a26022913960400191505060405180910390fd5b82600001828154811061497557fe5b9060005260206000200154905092915050565b600061499a836000018360001b615023565b905092915050565b60008082846000018054905011614a04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061581d6022913960400191505060405180910390fd5b6000846000018481548110614a1557fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008084600101600085815260200190815260200160002054905060008114158390614b02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614ac7578082015181840152602081019050614aac565b50505050905090810190601f168015614af45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50846000016001820381548110614b1557fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b6000614b638473ffffffffffffffffffffffffffffffffffffffff1661513c565b614b705760019050614d53565b6060614cda63150b7a0260e01b614b85613cf3565b888787604051602401808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015614c09578082015181840152602081019050614bee565b50505050905090810190601f168015614c365780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518060600160405280603281526020016156ea603291398773ffffffffffffffffffffffffffffffffffffffff166151879092919063ffffffff16565b90506000818060200190516020811015614cf357600080fd5b8101908080519060200190929190505050905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114614e5a5760006001820390506000600186600001805490500390506000866000018281548110614dc957fe5b9060005260206000200154905080876000018481548110614de657fe5b9060005260206000200181905550600183018760010160008381526020019081526020016000208190555086600001805480614e1e57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050614e60565b60009150505b92915050565b6000614e72838361519f565b614ecb578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050614ed0565b600090505b92915050565b6000808460010160008581526020019081526020016000205490506000811415614f7d57846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050614fab565b82856000016001830381548110614f9057fe5b90600052602060002090600202016001018190555060009150505b9392505050565b614fbc83836151c2565b614fc96000848484614b42565b61501e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806156ea6032913960400191505060405180910390fd5b505050565b60008083600101600084815260200190815260200160002054905060008114615130576000600182039050600060018660000180549050039050600086600001828154811061506e57fe5b906000526020600020906002020190508087600001848154811061508e57fe5b90600052602060002090600202016000820154816000015560018201548160010155905050600183018760010160008360000154815260200190815260200160002081905550866000018054806150e157fe5b6001900381819060005260206000209060020201600080820160009055600182016000905550509055866001016000878152602001908152602001600020600090556001945050505050615136565b60009150505b92915050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f915080821415801561517e57506000801b8214155b92505050919050565b606061519684846000856153b6565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415615265576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4552433732313a206d696e7420746f20746865207a65726f206164647265737381525060200191505060405180910390fd5b61526e81613cd6565b156152e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000081525060200191505060405180910390fd5b6152ed6000838361467f565b61533e81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061469e90919063ffffffff16565b50615355818360026146b89092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b60606153c18561513c565b615433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b602083106154835780518252602082019150602081019050602083039250615460565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146154e5576040519150601f19603f3d011682016040523d82523d6000602084013e6154ea565b606091505b509150915081156154ff5780925050506155b4565b6000815111156155125780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561557957808201518184015260208101905061555e565b50505050905090810190601f1680156155a65780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106155fd57805160ff191683800117855561562b565b8280016001018555821561562b579182015b8281111561562a57825182559160200191906001019061560f565b5b5090506156389190615684565b5090565b50805460018160011615610100020316600290046000825580601f106156625750615681565b601f0160209004906000526020600020908101906156809190615684565b5b50565b5b8082111561569d576000816000905550600101615685565b509056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473596f752068617665206578636565646564206d6178206c696d6974207065722077616c6c65744552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564a2646970667358221220c155da54ec331c9779b6b0388a97ac8206c3ff928e02b3ce069de11b1c73e76964736f6c63430007000033

Deployed Bytecode

0x6080604052600436106102885760003560e01c80637204a3c91161015a578063ab80baac116100c1578063eb8d24441161007a578063eb8d2444146111f3578063f032554914611220578063f2fde38b14611237578063f33b7e9214611288578063f49bc8b514611318578063ff147ef81461134357610288565b8063ab80baac14610eba578063b179e06014610ee5578063b88d4fde14610f6b578063c62752551461107d578063c87b56dd146110b8578063e985e9c51461116c57610288565b8063969745e811610113578063969745e814610cd45780639bf8031614610cff5780639cf2e8d614610d645780639e273b2f14610dcb578063a22cb46514610e32578063a69f675014610e8f57610288565b80637204a3c914610b0d5780637f5230ab14610b93578063853828b614610bbe5780638da5cb5b14610bd55780639264274414610c1657806395d89b4114610c4457610288565b80633549345e116101fe57806355f804b3116101b757806355f804b31461086f5780635ce7af1f146109375780636352211e1461099c5780636c0360eb14610a0157806370a0823114610a91578063715018a614610af657610288565b80633549345e146106bc5780633a6a85bf146106f757806342842e0e1461072557806342966c68146107a05780634d5012e3146107db5780634f6ccce71461082057610288565b806318160ddd1161025057806318160ddd146105155780631f0234d81461054057806323b872dd1461056d578063261d3b21146105e85780632f745c591461063657806334918dfd146106a557610288565b806301ffc9a71461028d57806306fdde03146102fd578063081812fc1461038d578063095ea7b3146103f257806313209af01461044d575b600080fd5b34801561029957600080fd5b506102e5600480360360208110156102b057600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916906020019092919050505061136e565b60405180821515815260200191505060405180910390f35b34801561030957600080fd5b506103126113d5565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610352578082015181840152602081019050610337565b50505050905090810190601f16801561037f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561039957600080fd5b506103c6600480360360208110156103b057600080fd5b8101908080359060200190929190505050611477565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156103fe57600080fd5b5061044b6004803603604081101561041557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611512565b005b34801561045957600080fd5b506105136004803603602081101561047057600080fd5b810190808035906020019064010000000081111561048d57600080fd5b82018360208201111561049f57600080fd5b803590602001918460018302840111640100000000831117156104c157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611656565b005b34801561052157600080fd5b5061052a6117e2565b6040518082815260200191505060405180910390f35b34801561054c57600080fd5b506105556117f3565b60405180821515815260200191505060405180910390f35b34801561057957600080fd5b506105e66004803603606081101561059057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611806565b005b610634600480360360408110156105fe57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061187c565b005b34801561064257600080fd5b5061068f6004803603604081101561065957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506119fb565b6040518082815260200191505060405180910390f35b3480156106b157600080fd5b506106ba611a56565b005b3480156106c857600080fd5b506106f5600480360360208110156106df57600080fd5b8101908080359060200190929190505050611b4c565b005b6107236004803603602081101561070d57600080fd5b8101908080359060200190929190505050611cc8565b005b34801561073157600080fd5b5061079e6004803603606081101561074857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611fea565b005b3480156107ac57600080fd5b506107d9600480360360208110156107c357600080fd5b810190808035906020019092919050505061200a565b005b3480156107e757600080fd5b5061081e600480360360408110156107fe57600080fd5b810190808035906020019092919080359060200190929190505050612189565b005b34801561082c57600080fd5b506108596004803603602081101561084357600080fd5b8101908080359060200190929190505050612324565b6040518082815260200191505060405180910390f35b34801561087b57600080fd5b506109356004803603602081101561089257600080fd5b81019080803590602001906401000000008111156108af57600080fd5b8201836020820111156108c157600080fd5b803590602001918460018302840111640100000000831117156108e357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612347565b005b34801561094357600080fd5b506109866004803603602081101561095a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061241d565b6040518082815260200191505060405180910390f35b3480156109a857600080fd5b506109d5600480360360208110156109bf57600080fd5b8101908080359060200190929190505050612466565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610a0d57600080fd5b50610a1661249d565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610a56578082015181840152602081019050610a3b565b50505050905090810190601f168015610a835780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610a9d57600080fd5b50610ae060048036036020811015610ab457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061253f565b6040518082815260200191505060405180910390f35b348015610b0257600080fd5b50610b0b612614565b005b348015610b1957600080fd5b50610b9160048036036020811015610b3057600080fd5b8101908080359060200190640100000000811115610b4d57600080fd5b820183602082011115610b5f57600080fd5b80359060200191846020830284011164010000000083111715610b8157600080fd5b909192939192939050505061279f565b005b348015610b9f57600080fd5b50610ba8612a72565b6040518082815260200191505060405180910390f35b348015610bca57600080fd5b50610bd3612a77565b005b348015610be157600080fd5b50610bea612c12565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610c4260048036036020811015610c2c57600080fd5b8101908080359060200190929190505050612c3c565b005b348015610c5057600080fd5b50610c59612e97565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610c99578082015181840152602081019050610c7e565b50505050905090810190601f168015610cc65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610ce057600080fd5b50610ce9612f39565b6040518082815260200191505060405180910390f35b348015610d0b57600080fd5b50610d4e60048036036020811015610d2257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f3f565b6040518082815260200191505060405180910390f35b348015610d7057600080fd5b50610db360048036036020811015610d8757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f57565b60405180821515815260200191505060405180910390f35b348015610dd757600080fd5b50610e1a60048036036020811015610dee57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f77565b60405180821515815260200191505060405180910390f35b348015610e3e57600080fd5b50610e8d60048036036040811015610e5557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050612fcd565b005b348015610e9b57600080fd5b50610ea4613183565b6040518082815260200191505060405180910390f35b348015610ec657600080fd5b50610ecf613189565b6040518082815260200191505060405180910390f35b348015610ef157600080fd5b50610f6960048036036020811015610f0857600080fd5b8101908080359060200190640100000000811115610f2557600080fd5b820183602082011115610f3757600080fd5b80359060200191846020830284011164010000000083111715610f5957600080fd5b909192939192939050505061318f565b005b348015610f7757600080fd5b5061107b60048036036080811015610f8e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610ff557600080fd5b82018360208201111561100757600080fd5b8035906020019184600183028401116401000000008311171561102957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506133a2565b005b34801561108957600080fd5b506110b6600480360360208110156110a057600080fd5b810190808035906020019092919050505061341a565b005b3480156110c457600080fd5b506110f1600480360360208110156110db57600080fd5b8101908080359060200190929190505050613596565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611131578082015181840152602081019050611116565b50505050905090810190601f16801561115e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561117857600080fd5b506111db6004803603604081101561118f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061387f565b60405180821515815260200191505060405180910390f35b3480156111ff57600080fd5b50611208613913565b60405180821515815260200191505060405180910390f35b34801561122c57600080fd5b50611235613926565b005b34801561124357600080fd5b506112866004803603602081101561125a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613a1c565b005b34801561129457600080fd5b5061129d613c2c565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156112dd5780820151818401526020810190506112c2565b50505050905090810190601f16801561130a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561132457600080fd5b5061132d613cca565b6040518082815260200191505060405180910390f35b34801561134f57600080fd5b50611358613cd0565b6040518082815260200191505060405180910390f35b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561146d5780601f106114425761010080835404028352916020019161146d565b820191906000526020600020905b81548152906001019060200180831161145057829003601f168201915b5050505050905090565b600061148282613cd6565b6114d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061583f602c913960400191505060405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061151d82612466565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156115a4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806158c36021913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166115c3613cf3565b73ffffffffffffffffffffffffffffffffffffffff1614806115f257506115f1816115ec613cf3565b61387f565b5b611647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806157926038913960400191505060405180910390fd5b6116518383613cfb565b505050565b61165e613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611720576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611728612c12565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146117c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b80601190805190602001906117de9291906155bc565b5050565b60006117ee6002613db4565b905090565b601460019054906101000a900460ff1681565b611817611811613cf3565b82613dc9565b61186c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806158e46031913960400191505060405180910390fd5b611877838383613ebd565b505050565b611884612c12565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611924576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000821180156119365750600d548211155b6119a8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4e6f7420656e6f7567682072657365727665206c65667420666f72207465616d81525060200191505060405180910390fd5b60005b828110156119db576127106119be6117e2565b10156119ce576119cd82614100565b5b80806001019150506119ab565b506119f182600d5461411a90919063ffffffff16565b600d819055505050565b6000611a4e82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061416490919063ffffffff16565b905092915050565b611a5e613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611b20576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b601460009054906101000a900460ff1615601460006101000a81548160ff021916908315150217905550565b611b54613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611c16576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611c1e612c12565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611cbe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b80600b8190555050565b601460019054906101000a900460ff16611d4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f53414c455f434c4f53454400000000000000000000000000000000000000000081525060200191505060405180910390fd5b601460009054906101000a900460ff1615611dcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4f4e4c595f50524553414c45000000000000000000000000000000000000000081525060200191505060405180910390fd5b6005611dd83361253f565b82011115611e31576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806156c46026913960400191505060405180910390fd5b6005811115611ea8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f546f6f206d616e7920746f6b656e73206174206f6e636500000000000000000081525060200191505060405180910390fd5b610708611ec582611eb76117e2565b61417e90919063ffffffff16565b1115611f39576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f507572636861736520776f756c6420657863656564206d617820737570706c7981525060200191505060405180910390fd5b80600b5402341015611fb3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4e6f7420656e6f756768206d6f6e65790000000000000000000000000000000081525060200191505060405180910390fd5b60005b81811015611fe657610708611fc96117e2565b1015611fd957611fd833614100565b5b8080600101915050611fb6565b5050565b612005838383604051806020016040528060008152506133a2565b505050565b612012613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146120d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166120f482612466565b73ffffffffffffffffffffffffffffffffffffffff161461217d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4e4f545f4f574e45525f4f465f544f4b454e000000000000000000000000000081525060200191505060405180910390fd5b61218681614206565b50565b612191613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612253576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60008290505b81811161231f573373ffffffffffffffffffffffffffffffffffffffff1661228082612466565b73ffffffffffffffffffffffffffffffffffffffff1614612309576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4e4f545f4f574e45525f4f465f544f4b454e000000000000000000000000000081525060200191505060405180910390fd5b61231281614206565b8080600101915050612259565b505050565b60008061233b83600261434090919063ffffffff16565b50905080915050919050565b61234f613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612411576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61241a8161436c565b50565b6000601360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000612496826040518060600160405280602981526020016157f46029913960026143869092919063ffffffff16565b9050919050565b606060098054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156125355780601f1061250a57610100808354040283529160200191612535565b820191906000526020600020905b81548152906001019060200180831161251857829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156125c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a8152602001806157ca602a913960400191505060405180910390fd5b61260d600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206143a5565b9050919050565b61261c613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146126de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6127a7613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612869576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60005b82829050811015612a6d57600083838381811061288557fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612947576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e554c4c5f41444452455353000000000000000000000000000000000000000081525060200191505060405180910390fd5b601260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f4455504c49434154455f454e545259000000000000000000000000000000000081525060200191505060405180910390fd5b6001601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050808060010191505061286c565b505050565b600581565b612a7f613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612b41576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600047905060008111612b5357600080fd5b612b8c600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064601e840281612b8657fe5b046143ba565b612bc5600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064601e840281612bbf57fe5b046143ba565b612bfe601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660646028840281612bf857fe5b046143ba565b612c0f612c09612c12565b476143ba565b50565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b601460009054906101000a900460ff16612cbe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f53414c455f434c4f53454400000000000000000000000000000000000000000081525060200191505060405180910390fd5b601460019054906101000a900460ff1615612d41576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4f4e4c595f5055424c49435f53414c450000000000000000000000000000000081525060200191505060405180910390fd5b612d58600d5461271061411a90919063ffffffff16565b612d7282612d646117e2565b61417e90919063ffffffff16565b1115612de6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f507572636861736520776f756c6420657863656564206d617820737570706c7981525060200191505060405180910390fd5b3481600c54021115612e60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45746865722076616c75652073656e74206973206e6f7420636f72726563740081525060200191505060405180910390fd5b60005b81811015612e9357612710612e766117e2565b1015612e8657612e8533614100565b5b8080600101915050612e63565b5050565b606060078054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612f2f5780601f10612f0457610100808354040283529160200191612f2f565b820191906000526020600020905b815481529060010190602001808311612f1257829003601f168201915b5050505050905090565b600b5481565b60136020528060005260406000206000915090505481565b60126020528060005260406000206000915054906101000a900460ff1681565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b612fd5613cf3565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613076576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4552433732313a20617070726f766520746f2063616c6c65720000000000000081525060200191505060405180910390fd5b8060056000613083613cf3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16613130613cf3565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b600c5481565b61271081565b613197613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613259576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60005b8282905081101561339d57600083838381811061327557fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415613337576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e554c4c5f41444452455353000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050808060010191505061325c565b505050565b6133b36133ad613cf3565b83613dc9565b613408576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806158e46031913960400191505060405180910390fd5b6134148484848461449b565b50505050565b613422613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146134e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6134ec612c12565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461358c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b80600c8190555050565b60606135a182613cd6565b6135f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180615894602f913960400191505060405180910390fd5b6060600860008481526020019081526020016000208054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561369f5780601f106136745761010080835404028352916020019161369f565b820191906000526020600020905b81548152906001019060200180831161368257829003601f168201915b505050505090506000600980546001816001161561010002031660029004905014156136ce578091505061387a565b6000815111156137a75760098160405160200180838054600181600116156101000203166002900480156137395780601f10613717576101008083540402835291820191613739565b820191906000526020600020905b815481529060010190602001808311613725575b505082805190602001908083835b6020831061376a5780518252602082019150602081019050602083039250613747565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405291505061387a565b60096137b28461450d565b60405160200180838054600181600116156101000203166002900480156138105780601f106137ee576101008083540402835291820191613810565b820191906000526020600020905b8154815290600101906020018083116137fc575b505082805190602001908083835b60208310613841578051825260208201915060208101905060208303925061381e565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529150505b919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b601460009054906101000a900460ff1681565b61392e613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146139f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b601460019054906101000a900460ff1615601460016101000a81548160ff021916908315150217905550565b613a24613cf3565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613ae6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415613b6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061571c6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60118054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613cc25780601f10613c9757610100808354040283529160200191613cc2565b820191906000526020600020905b815481529060010190602001808311613ca557829003601f168201915b505050505081565b61070881565b600d5481565b6000613cec82600261465490919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16613d6e83612466565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000613dc28260000161466e565b9050919050565b6000613dd482613cd6565b613e29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615766602c913960400191505060405180910390fd5b6000613e3483612466565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480613ea357508373ffffffffffffffffffffffffffffffffffffffff16613e8b84611477565b73ffffffffffffffffffffffffffffffffffffffff16145b80613eb45750613eb3818561387f565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16613edd82612466565b73ffffffffffffffffffffffffffffffffffffffff1614613f49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602981526020018061586b6029913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613fcf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806157426024913960400191505060405180910390fd5b613fda83838361467f565b613fe5600082613cfb565b61403681600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061468490919063ffffffff16565b5061408881600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061469e90919063ffffffff16565b5061409f818360026146b89092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600061410a6146ed565b90506141168282614827565b5050565b600061415c83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614845565b905092915050565b60006141738360000183614905565b60001c905092915050565b6000808284019050838110156141fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600061421182612466565b905061421f8160008461467f565b61422a600083613cfb565b6000600860008481526020019081526020016000208054600181600116156101000203166002900490501461427957600860008381526020019081526020016000206000614278919061563c565b5b6142ca82600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061468490919063ffffffff16565b506142df82600261498890919063ffffffff16565b5081600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b60008060008061435386600001866149a2565b915091508160001c8160001c9350935050509250929050565b80600990805190602001906143829291906155bc565b5050565b6000614399846000018460001b84614a3b565b60001c90509392505050565b60006143b382600001614b31565b9050919050565b60008273ffffffffffffffffffffffffffffffffffffffff168260405180600001905060006040518083038185875af1925050503d806000811461441a576040519150601f19603f3d011682016040523d82523d6000602084013e61441f565b606091505b5050905080614496576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5472616e73666572206661696c65642e0000000000000000000000000000000081525060200191505060405180910390fd5b505050565b6144a6848484613ebd565b6144b284848484614b42565b614507576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806156ea6032913960400191505060405180910390fd5b50505050565b60606000821415614555576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061464f565b600082905060005b6000821461457f578080600101915050600a828161457757fe5b04915061455d565b60608167ffffffffffffffff8111801561459857600080fd5b506040519080825280601f01601f1916602001820160405280156145cb5781602001600182028036833780820191505090505b50905060006001830390508593505b6000841461464757600a84816145ec57fe5b0660300160f81b8282806001900393508151811061460657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a848161463f57fe5b0493506145da565b819450505050505b919050565b6000614666836000018360001b614d5b565b905092915050565b600081600001805490509050919050565b505050565b6000614696836000018360001b614d7e565b905092915050565b60006146b0836000018360001b614e66565b905092915050565b60006146e4846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b614ed6565b90509392505050565b6000806146f86117e2565b612710039050600081601554334442604051602001808581526020018473ffffffffffffffffffffffffffffffffffffffff1660601b81526014018381526020018281526020019450505050506040516020818303038152906040528051906020012060001c8161476557fe5b069050600080601683612710811061477957fe5b01541461479757601682612710811061478e57fe5b0154905061479b565b8190505b600060166001850361271081106147ae57fe5b015414156147d2576001830360168361271081106147c857fe5b01819055506147f9565b60166001840361271081106147e357fe5b015460168361271081106147f357fe5b01819055505b60156000815480929190600101919050555061481f60018261417e90919063ffffffff16565b935050505090565b614841828260405180602001604052806000815250614fb2565b5050565b60008383111582906148f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156148b757808201518184015260208101905061489c565b50505050905090810190601f1680156148e45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600081836000018054905011614966576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806156a26022913960400191505060405180910390fd5b82600001828154811061497557fe5b9060005260206000200154905092915050565b600061499a836000018360001b615023565b905092915050565b60008082846000018054905011614a04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061581d6022913960400191505060405180910390fd5b6000846000018481548110614a1557fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008084600101600085815260200190815260200160002054905060008114158390614b02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614ac7578082015181840152602081019050614aac565b50505050905090810190601f168015614af45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50846000016001820381548110614b1557fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b6000614b638473ffffffffffffffffffffffffffffffffffffffff1661513c565b614b705760019050614d53565b6060614cda63150b7a0260e01b614b85613cf3565b888787604051602401808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015614c09578082015181840152602081019050614bee565b50505050905090810190601f168015614c365780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518060600160405280603281526020016156ea603291398773ffffffffffffffffffffffffffffffffffffffff166151879092919063ffffffff16565b90506000818060200190516020811015614cf357600080fd5b8101908080519060200190929190505050905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114614e5a5760006001820390506000600186600001805490500390506000866000018281548110614dc957fe5b9060005260206000200154905080876000018481548110614de657fe5b9060005260206000200181905550600183018760010160008381526020019081526020016000208190555086600001805480614e1e57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050614e60565b60009150505b92915050565b6000614e72838361519f565b614ecb578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050614ed0565b600090505b92915050565b6000808460010160008581526020019081526020016000205490506000811415614f7d57846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050614fab565b82856000016001830381548110614f9057fe5b90600052602060002090600202016001018190555060009150505b9392505050565b614fbc83836151c2565b614fc96000848484614b42565b61501e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806156ea6032913960400191505060405180910390fd5b505050565b60008083600101600084815260200190815260200160002054905060008114615130576000600182039050600060018660000180549050039050600086600001828154811061506e57fe5b906000526020600020906002020190508087600001848154811061508e57fe5b90600052602060002090600202016000820154816000015560018201548160010155905050600183018760010160008360000154815260200190815260200160002081905550866000018054806150e157fe5b6001900381819060005260206000209060020201600080820160009055600182016000905550509055866001016000878152602001908152602001600020600090556001945050505050615136565b60009150505b92915050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f915080821415801561517e57506000801b8214155b92505050919050565b606061519684846000856153b6565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415615265576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4552433732313a206d696e7420746f20746865207a65726f206164647265737381525060200191505060405180910390fd5b61526e81613cd6565b156152e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000081525060200191505060405180910390fd5b6152ed6000838361467f565b61533e81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061469e90919063ffffffff16565b50615355818360026146b89092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b60606153c18561513c565b615433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b602083106154835780518252602082019150602081019050602083039250615460565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146154e5576040519150601f19603f3d011682016040523d82523d6000602084013e6154ea565b606091505b509150915081156154ff5780925050506155b4565b6000815111156155125780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561557957808201518184015260208101905061555e565b50505050905090810190601f1680156155a65780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106155fd57805160ff191683800117855561562b565b8280016001018555821561562b579182015b8281111561562a57825182559160200191906001019061560f565b5b5090506156389190615684565b5090565b50805460018160011615610100020316600290046000825580601f106156625750615681565b601f0160209004906000526020600020908101906156809190615684565b5b50565b5b8082111561569d576000816000905550600101615685565b509056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473596f752068617665206578636565646564206d6178206c696d6974207065722077616c6c65744552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564a2646970667358221220c155da54ec331c9779b6b0388a97ac8206c3ff928e02b3ce069de11b1c73e76964736f6c63430007000033

Deployed Bytecode Sourcemap

60478:6950:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11133:142;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;45506:92;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48193:213;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;47737:390;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;67248:175;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;47231:203;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;61402:35;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;49067:305;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;65350:524;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;47001:154;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;66673:89;;;;;;;;;;;;;:::i;:::-;;61599:156;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;64326:1014;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;49443:151;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;63269:154;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;66987:252;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;47511:164;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;66877:99;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;66544:121;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;45270:169;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;46828:89;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44993:215;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;59856:148;;;;;;;;;;;;;:::i;:::-;;61925:303;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;60858:64;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;65883:362;;;;;;;;;;;;;:::i;:::-;;59214:79;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;63437:877;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;45667:96;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60568:48;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;61298:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;61250:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;66441:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;48478:295;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;60644:47;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;60719:50;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;62233:255;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;49665:285;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;61763:154;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;45834:755;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48844:156;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;61363:32;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;66770:99;;;;;;;;;;;;;:::i;:::-;;60159:244;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;61218:26;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60785:58;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;60935:47;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;11133:142;11210:4;11234:20;:33;11255:11;11234:33;;;;;;;;;;;;;;;;;;;;;;;;;;;11227:40;;11133:142;;;:::o;45506:92::-;45552:13;45585:5;45578:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45506:92;:::o;48193:213::-;48261:7;48289:16;48297:7;48289;:16::i;:::-;48281:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48374:15;:24;48390:7;48374:24;;;;;;;;;;;;;;;;;;;;;48367:31;;48193:213;;;:::o;47737:390::-;47818:13;47834:16;47842:7;47834;:16::i;:::-;47818:32;;47875:5;47869:11;;:2;:11;;;;47861:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47955:5;47939:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;47964:37;47981:5;47988:12;:10;:12::i;:::-;47964:16;:37::i;:::-;47939:62;47931:154;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48098:21;48107:2;48111:7;48098:8;:21::i;:::-;47737:390;;;:::o;67248:175::-;59436:12;:10;:12::i;:::-;59426:22;;:6;;;;;;;;;;;:22;;;59418:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67350:7:::1;:5;:7::i;:::-;67336:21;;:10;:21;;;67328:48;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;67402:13;67387:12;:28;;;;;;;;;;;;:::i;:::-;;67248:175:::0;:::o;47231:203::-;47284:7;47405:21;:12;:19;:21::i;:::-;47398:28;;47231:203;:::o;61402:35::-;;;;;;;;;;;;;:::o;49067:305::-;49228:41;49247:12;:10;:12::i;:::-;49261:7;49228:18;:41::i;:::-;49220:103;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49336:28;49346:4;49352:2;49356:7;49336:9;:28::i;:::-;49067:305;;;:::o;65350:524::-;65452:7;:5;:7::i;:::-;65438:21;;:10;:21;;;65430:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65514:1;65497:14;:18;:66;;;;;65537:26;;65519:14;:44;;65497:66;65489:111;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65617:6;65613:168;65633:14;65629:1;:18;65613:168;;;60764:5;65673:13;:11;:13::i;:::-;:34;65669:101;;;65728:26;65751:2;65728:22;:26::i;:::-;65669:101;65649:3;;;;;;;65613:168;;;;65820:46;65851:14;65820:26;;:30;;:46;;;;:::i;:::-;65791:26;:75;;;;65350:524;;:::o;47001:154::-;47090:7;47117:30;47141:5;47117:13;:20;47131:5;47117:20;;;;;;;;;;;;;;;:23;;:30;;;;:::i;:::-;47110:37;;47001:154;;;;:::o;66673:89::-;59436:12;:10;:12::i;:::-;59426:22;;:6;;;;;;;;;;;:22;;;59418:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66742:12:::1;;;;;;;;;;;66741:13;66726:12;;:28;;;;;;;;;;;;;;;;;;66673:89::o:0;61599:156::-;59436:12;:10;:12::i;:::-;59426:22;;:6;;;;;;;;;;;:22;;;59418:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61689:7:::1;:5;:7::i;:::-;61675:21;;:10;:21;;;61667:48;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;61742:5;61726:13;:21;;;;61599:156:::0;:::o;64326:1014::-;64404:15;;;;;;;;;;;64396:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64449:12;;;;;;;;;;;64448:13;64440:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60921:1;64514:21;64524:10;64514:9;:21::i;:::-;64497:14;:38;:78;;64489:129;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60921:1;64637:14;:54;;64629:90;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60839:4;64738:33;64756:14;64738:13;:11;:13::i;:::-;:17;;:33;;;;:::i;:::-;:64;;64730:109;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64887:14;64871:13;;:30;64858:9;:43;;64850:72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65140:6;65136:185;65156:14;65152:1;:18;65136:185;;;60839:4;65196:13;:11;:13::i;:::-;:43;65192:118;;;65260:34;65283:10;65260:22;:34::i;:::-;65192:118;65172:3;;;;;;;65136:185;;;;64326:1014;:::o;49443:151::-;49547:39;49564:4;49570:2;49574:7;49547:39;;;;;;;;;;;;:16;:39::i;:::-;49443:151;;;:::o;63269:154::-;59436:12;:10;:12::i;:::-;59426:22;;:6;;;;;;;;;;;:22;;;59418:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63357:10:::1;63337:30;;:16;63345:7;63337;:16::i;:::-;:30;;;63329:61;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;63401:14;63407:7;63401:5;:14::i;:::-;63269:154:::0;:::o;66987:252::-;59436:12;:10;:12::i;:::-;59426:22;;:6;;;;;;;;;;;:22;;;59418:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67081:6:::1;67090:12;67081:21;;67077:155;67109:10;67104:1;:15;67077:155;;67163:10;67149:24;;:10;67157:1;67149:7;:10::i;:::-;:24;;;67141:55;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;67211:8;67217:1;67211:5;:8::i;:::-;67121:3;;;;;;;67077:155;;;;66987:252:::0;;:::o;47511:164::-;47578:7;47599:15;47620:22;47636:5;47620:12;:15;;:22;;;;:::i;:::-;47598:44;;;47660:7;47653:14;;;47511:164;;;:::o;66877:99::-;59436:12;:10;:12::i;:::-;59426:22;;:6;;;;;;;;;;;:22;;;59418:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66948:20:::1;66960:7;66948:11;:20::i;:::-;66877:99:::0;:::o;66544:121::-;66612:7;66633:21;:27;66655:4;66633:27;;;;;;;;;;;;;;;;66626:34;;66544:121;;;:::o;45270:169::-;45334:7;45361:70;45378:7;45361:70;;;;;;;;;;;;;;;;;:12;:16;;:70;;;;;:::i;:::-;45354:77;;45270:169;;;:::o;46828:89::-;46868:13;46901:8;46894:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46828:89;:::o;44993:215::-;45057:7;45102:1;45085:19;;:5;:19;;;;45077:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45171:29;:13;:20;45185:5;45171:20;;;;;;;;;;;;;;;:27;:29::i;:::-;45164:36;;44993:215;;;:::o;59856:148::-;59436:12;:10;:12::i;:::-;59426:22;;:6;;;;;;;;;;;:22;;;59418:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59963:1:::1;59926:40;;59947:6;;;;;;;;;;;59926:40;;;;;;;;;;;;59994:1;59977:6;;:19;;;;;;;;;;;;;;;;;;59856:148::o:0;61925:303::-;59436:12;:10;:12::i;:::-;59426:22;;:6;;;;;;;;;;;:22;;;59418:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62008:9:::1;62003:221;62027:7;;:14;;62023:1;:18;62003:221;;;62054:13;62070:7;;62078:1;62070:10;;;;;;;;;;;;;;;62054:26;;62111:1;62094:19;;:5;:19;;;;62086:44;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;62145:12;:19;62158:5;62145:19;;;;;;;;;;;;;;;;;;;;;;;;;62144:20;62136:48;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;62214:4;62192:12;:19;62205:5;62192:19;;;;;;;;;;;;;;;;:26;;;;;;;;;;;;;;;;;;62003:221;62043:3;;;;;;;62003:221;;;;61925:303:::0;;:::o;60858:64::-;60921:1;60858:64;:::o;65883:362::-;59436:12;:10;:12::i;:::-;59426:22;;:6;;;;;;;;;;;:22;;;59418:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65934:15:::1;65952:21;65934:39;;66002:1;65992:7;:11;65984:20;;;::::0;::::1;;66017:42;66027:9;;;;;;;;;;;66055:3;66049:2;66039:7;:12;66038:20;;;;;;66017:9;:42::i;:::-;66070;66080:9;;;;;;;;;;;66108:3;66102:2;66092:7;:12;66091:20;;;;;;66070:9;:42::i;:::-;66123:53;66133:20;;;;;;;;;;;66172:3;66166:2;66156:7;:12;66155:20;;;;;;66123:9;:53::i;:::-;66196:41;66206:7;:5;:7::i;:::-;66215:21;66196:9;:41::i;:::-;59496:1;65883:362::o:0;59214:79::-;59252:7;59279:6;;;;;;;;;;;59272:13;;59214:79;:::o;63437:877::-;63512:12;;;;;;;;;;;63504:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63554:15;;;;;;;;;;;63553:16;63545:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63933:50;63956:26;;60764:5;63933:22;;:50;;;;:::i;:::-;63896:33;63914:14;63896:13;:11;:13::i;:::-;:17;;:33;;;;:::i;:::-;:87;;63888:133;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64073:9;64055:14;64040:12;;:29;:42;;64032:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64135:6;64131:176;64151:14;64147:1;:18;64131:176;;;60764:5;64191:13;:11;:13::i;:::-;:34;64187:109;;;64246:34;64269:10;64246:22;:34::i;:::-;64187:109;64167:3;;;;;;;64131:176;;;;63437:877;:::o;45667:96::-;45715:13;45748:7;45741:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45667:96;:::o;60568:48::-;;;;:::o;61298:56::-;;;;;;;;;;;;;;;;;:::o;61250:44::-;;;;;;;;;;;;;;;;;;;;;;:::o;66441:98::-;66498:4;66516:12;:18;66529:4;66516:18;;;;;;;;;;;;;;;;;;;;;;;;;66509:25;;66441:98;;;:::o;48478:295::-;48593:12;:10;:12::i;:::-;48581:24;;:8;:24;;;;48573:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48693:8;48648:18;:32;48667:12;:10;:12::i;:::-;48648:32;;;;;;;;;;;;;;;:42;48681:8;48648:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;48746:8;48717:48;;48732:12;:10;:12::i;:::-;48717:48;;;48756:8;48717:48;;;;;;;;;;;;;;;;;;;;48478:295;;:::o;60644:47::-;;;;:::o;60719:50::-;60764:5;60719:50;:::o;62233:255::-;59436:12;:10;:12::i;:::-;59426:22;;:6;;;;;;;;;;;:22;;;59418:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62321:9:::1;62316:168;62340:7;;:14;;62336:1;:18;62316:168;;;62367:13;62383:7;;62391:1;62383:10;;;;;;;;;;;;;;;62367:26;;62424:1;62407:19;;:5;:19;;;;62399:44;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;62473:5;62451:12;:19;62464:5;62451:19;;;;;;;;;;;;;;;;:27;;;;;;;;;;;;;;;;;;62316:168;62356:3;;;;;;;62316:168;;;;62233:255:::0;;:::o;49665:285::-;49797:41;49816:12;:10;:12::i;:::-;49830:7;49797:18;:41::i;:::-;49789:103;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49903:39;49917:4;49923:2;49927:7;49936:5;49903:13;:39::i;:::-;49665:285;;;;:::o;61763:154::-;59436:12;:10;:12::i;:::-;59426:22;;:6;;;;;;;;;;;:22;;;59418:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61852:7:::1;:5;:7::i;:::-;61838:21;;:10;:21;;;61830:48;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;61904:5;61889:12;:20;;;;61763:154:::0;:::o;45834:755::-;45899:13;45933:16;45941:7;45933;:16::i;:::-;45925:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46014:23;46040:10;:19;46051:7;46040:19;;;;;;;;;;;46014:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46161:1;46141:8;46135:22;;;;;;;;;;;;;;;;:27;46131:76;;;46186:9;46179:16;;;;;46131:76;46337:1;46317:9;46311:23;:27;46307:112;;;46386:8;46396:9;46369:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46355:52;;;;;46307:112;46551:8;46561:18;:7;:16;:18::i;:::-;46534:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46520:61;;;45834:755;;;;:::o;48844:156::-;48933:4;48957:18;:25;48976:5;48957:25;;;;;;;;;;;;;;;:35;48983:8;48957:35;;;;;;;;;;;;;;;;;;;;;;;;;48950:42;;48844:156;;;;:::o;61363:32::-;;;;;;;;;;;;;:::o;66770:99::-;59436:12;:10;:12::i;:::-;59426:22;;:6;;;;;;;;;;;:22;;;59418:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66846:15:::1;;;;;;;;;;;66845:16;66827:15;;:34;;;;;;;;;;;;;;;;;;66770:99::o:0;60159:244::-;59436:12;:10;:12::i;:::-;59426:22;;:6;;;;;;;;;;;:22;;;59418:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60268:1:::1;60248:22;;:8;:22;;;;60240:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60358:8;60329:38;;60350:6;;;;;;;;;;;60329:38;;;;;;;;;;;;60387:8;60378:6;;:17;;;;;;;;;;;;;;;;;;60159:244:::0;:::o;61218:26::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;60785:58::-;60839:4;60785:58;:::o;60935:47::-;;;;:::o;51416:119::-;51473:4;51497:30;51519:7;51497:12;:21;;:30;;;;:::i;:::-;51490:37;;51416:119;;;:::o;1547:106::-;1600:15;1635:10;1628:17;;1547:106;:::o;57243:158::-;57336:2;57309:15;:24;57325:7;57309:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;57385:7;57381:2;57354:39;;57363:16;57371:7;57363;:16::i;:::-;57354:39;;;;;;;;;;;;57243:158;;:::o;38893:123::-;38962:7;38989:19;38997:3;:10;;38989:7;:19::i;:::-;38982:26;;38893:123;;;:::o;51702:333::-;51787:4;51812:16;51820:7;51812;:16::i;:::-;51804:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51888:13;51904:16;51912:7;51904;:16::i;:::-;51888:32;;51950:5;51939:16;;:7;:16;;;:51;;;;51983:7;51959:31;;:20;51971:7;51959:11;:20::i;:::-;:31;;;51939:51;:87;;;;51994:32;52011:5;52018:7;51994:16;:32::i;:::-;51939:87;51931:96;;;51702:333;;;;:::o;54791:574::-;54909:4;54889:24;;:16;54897:7;54889;:16::i;:::-;:24;;;54881:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54992:1;54978:16;;:2;:16;;;;54970:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55048:39;55069:4;55075:2;55079:7;55048:20;:39::i;:::-;55152:29;55169:1;55173:7;55152:8;:29::i;:::-;55194:35;55221:7;55194:13;:19;55208:4;55194:19;;;;;;;;;;;;;;;:26;;:35;;;;:::i;:::-;;55240:30;55262:7;55240:13;:17;55254:2;55240:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;55283:29;55300:7;55309:2;55283:12;:16;;:29;;;;;:::i;:::-;;55349:7;55345:2;55330:27;;55339:4;55330:27;;;;;;;;;;;;54791:574;;;:::o;63121:136::-;63185:13;63201;:11;:13::i;:::-;63185:29;;63225:24;63235:3;63240:8;63225:9;:24::i;:::-;63121:136;;:::o;13294:::-;13352:7;13379:43;13383:1;13386;13379:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;13372:50;;13294:136;;;;:::o;31481:137::-;31552:7;31587:22;31591:3;:10;;31603:5;31587:3;:22::i;:::-;31579:31;;31572:38;;31481:137;;;;:::o;12830:181::-;12888:7;12908:9;12924:1;12920;:5;12908:17;;12949:1;12944;:6;;12936:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13002:1;12995:8;;;12830:181;;;;:::o;53934:520::-;53994:13;54010:16;54018:7;54010;:16::i;:::-;53994:32;;54039:48;54060:5;54075:1;54079:7;54039:20;:48::i;:::-;54128:29;54145:1;54149:7;54128:8;:29::i;:::-;54247:1;54216:10;:19;54227:7;54216:19;;;;;;;;;;;54210:33;;;;;;;;;;;;;;;;:38;54206:97;;54272:10;:19;54283:7;54272:19;;;;;;;;;;;;54265:26;;;;:::i;:::-;54206:97;54315:36;54343:7;54315:13;:20;54329:5;54315:20;;;;;;;;;;;;;;;:27;;:36;;;;:::i;:::-;;54364:28;54384:7;54364:12;:19;;:28;;;;:::i;:::-;;54438:7;54434:1;54410:36;;54419:5;54410:36;;;;;;;;;;;;53934:520;;:::o;39355:227::-;39435:7;39444;39465:11;39478:13;39495:22;39499:3;:10;;39511:5;39495:3;:22::i;:::-;39464:53;;;;39544:3;39536:12;;39566:5;39558:14;;39528:46;;;;;;39355:227;;;;;:::o;55966:100::-;56050:8;56039;:19;;;;;;;;;;;;:::i;:::-;;55966:100;:::o;40017:204::-;40124:7;40167:44;40172:3;:10;;40192:3;40184:12;;40198;40167:4;:44::i;:::-;40159:53;;40144:69;;40017:204;;;;;:::o;31023:114::-;31083:7;31110:19;31118:3;:10;;31110:7;:19::i;:::-;31103:26;;31023:114;;;:::o;66253:180::-;66327:12;66345:8;:13;;66366:7;66345:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66326:52;;;66397:7;66389:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66253:180;;;:::o;50831:272::-;50945:28;50955:4;50961:2;50965:7;50945:9;:28::i;:::-;50992:48;51015:4;51021:2;51025:7;51034:5;50992:22;:48::i;:::-;50984:111;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50831:272;;;;:::o;40479:744::-;40535:13;40765:1;40756:5;:10;40752:53;;;40783:10;;;;;;;;;;;;;;;;;;;;;40752:53;40815:12;40830:5;40815:20;;40846:14;40871:78;40886:1;40878:4;:9;40871:78;;40904:8;;;;;;;40935:2;40927:10;;;;;;;;;40871:78;;;40959:19;40991:6;40981:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40959:39;;41009:13;41034:1;41025:6;:10;41009:26;;41053:5;41046:12;;41069:115;41084:1;41076:4;:9;41069:115;;41143:2;41136:4;:9;;;;;;41131:2;:14;41120:27;;41102:6;41109:7;;;;;;;41102:15;;;;;;;;;;;:45;;;;;;;;;;;41170:2;41162:10;;;;;;;;;41069:115;;;41208:6;41194:21;;;;;;40479:744;;;;:::o;38654:151::-;38738:4;38762:35;38772:3;:10;;38792:3;38784:12;;38762:9;:35::i;:::-;38755:42;;38654:151;;;;:::o;36276:110::-;36332:7;36359:3;:12;;:19;;;;36352:26;;36276:110;;;:::o;58014:93::-;;;;:::o;30568:137::-;30638:4;30662:35;30670:3;:10;;30690:5;30682:14;;30662:7;:35::i;:::-;30655:42;;30568:137;;;;:::o;30261:131::-;30328:4;30352:32;30357:3;:10;;30377:5;30369:14;;30352:4;:32::i;:::-;30345:39;;30261:131;;;;:::o;38086:176::-;38175:4;38199:55;38204:3;:10;;38224:3;38216:12;;38246:5;38238:14;;38230:23;;38199:4;:55::i;:::-;38192:62;;38086:176;;;;;:::o;62496:617::-;62537:7;62557:17;62598:13;:11;:13::i;:::-;60764:5;62577:34;62557:54;;62622:13;62728:9;62670:5;;62677:10;62689:16;62707:15;62653:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62643:81;;;;;;62638:87;;:99;;;;;;62622:115;;62748:13;62800:1;62782:7;62790:5;62782:14;;;;;;;;;:19;62778:112;;62822:7;62830:5;62822:14;;;;;;;;;62814:22;;62778:112;;;62873:5;62865:13;;62778:112;62932:1;62906:7;62926:1;62914:9;:13;62906:22;;;;;;;;;:27;62902:154;;;62975:1;62963:9;:13;62946:7;62954:5;62946:14;;;;;;;;:30;;;;62902:154;;;63022:7;63042:1;63030:9;:13;63022:22;;;;;;;;;63005:7;63013:5;63005:14;;;;;;;;:39;;;;62902:154;63068:5;;:7;;;;;;;;;;;;;63093:12;63103:1;63093:5;:9;;:12;;;;:::i;:::-;63086:19;;;;;62496:617;:::o;52378:110::-;52454:26;52464:2;52468:7;52454:26;;;;;;;;;;;;:9;:26::i;:::-;52378:110;;:::o;13733:192::-;13819:7;13852:1;13847;:6;;13855:12;13839:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13879:9;13895:1;13891;:5;13879:17;;13916:1;13909:8;;;13733:192;;;;;:::o;28145:204::-;28212:7;28261:5;28240:3;:11;;:18;;;;:26;28232:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28323:3;:11;;28335:5;28323:18;;;;;;;;;;;;;;;;28316:25;;28145:204;;;;:::o;38428:142::-;38505:4;38529:33;38537:3;:10;;38557:3;38549:12;;38529:7;:33::i;:::-;38522:40;;38428:142;;;;:::o;36741:279::-;36808:7;36817;36867:5;36845:3;:12;;:19;;;;:27;36837:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36924:22;36949:3;:12;;36962:5;36949:19;;;;;;;;;;;;;;;;;;36924:44;;36987:5;:10;;;36999:5;:12;;;36979:33;;;;;36741:279;;;;;:::o;37443:319::-;37537:7;37557:16;37576:3;:12;;:17;37589:3;37576:17;;;;;;;;;;;;37557:36;;37624:1;37612:8;:13;;37627:12;37604:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37694:3;:12;;37718:1;37707:8;:12;37694:26;;;;;;;;;;;;;;;;;;:33;;;37687:40;;;37443:319;;;;;:::o;27692:109::-;27748:7;27775:3;:11;;:18;;;;27768:25;;27692:109;;;:::o;56631:604::-;56752:4;56779:15;:2;:13;;;:15::i;:::-;56774:60;;56818:4;56811:11;;;;56774:60;56844:23;56870:252;56923:45;;;56983:12;:10;:12::i;:::-;57010:4;57029:7;57051:5;56886:181;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56870:252;;;;;;;;;;;;;;;;;:2;:15;;;;:252;;;;;:::i;:::-;56844:278;;57133:13;57160:10;57149:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57133:48;;42001:10;57210:16;;57200:26;;;:6;:26;;;;57192:35;;;;56631:604;;;;;;;:::o;36056:125::-;36127:4;36172:1;36151:3;:12;;:17;36164:3;36151:17;;;;;;;;;;;;:22;;36144:29;;36056:125;;;;:::o;25847:1544::-;25913:4;26031:18;26052:3;:12;;:19;26065:5;26052:19;;;;;;;;;;;;26031:40;;26102:1;26088:10;:15;26084:1300;;26450:21;26487:1;26474:10;:14;26450:38;;26503:17;26544:1;26523:3;:11;;:18;;;;:22;26503:42;;26790:17;26810:3;:11;;26822:9;26810:22;;;;;;;;;;;;;;;;26790:42;;26956:9;26927:3;:11;;26939:13;26927:26;;;;;;;;;;;;;;;:38;;;;27075:1;27059:13;:17;27033:3;:12;;:23;27046:9;27033:23;;;;;;;;;;;:43;;;;27185:3;:11;;:17;;;;;;;;;;;;;;;;;;;;;;;;27280:3;:12;;:19;27293:5;27280:19;;;;;;;;;;;27273:26;;;27323:4;27316:11;;;;;;;;26084:1300;27367:5;27360:12;;;25847:1544;;;;;:::o;25257:414::-;25320:4;25342:21;25352:3;25357:5;25342:9;:21::i;:::-;25337:327;;25380:3;:11;;25397:5;25380:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25563:3;:11;;:18;;;;25541:3;:12;;:19;25554:5;25541:19;;;;;;;;;;;:40;;;;25603:4;25596:11;;;;25337:327;25647:5;25640:12;;25257:414;;;;;:::o;33556:692::-;33632:4;33748:16;33767:3;:12;;:17;33780:3;33767:17;;;;;;;;;;;;33748:36;;33813:1;33801:8;:13;33797:444;;;33868:3;:12;;33886:38;;;;;;;;33903:3;33886:38;;;;33916:5;33886:38;;;33868:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34083:3;:12;;:19;;;;34063:3;:12;;:17;34076:3;34063:17;;;;;;;;;;;:39;;;;34124:4;34117:11;;;;;33797:444;34197:5;34161:3;:12;;34185:1;34174:8;:12;34161:26;;;;;;;;;;;;;;;;;;:33;;:41;;;;34224:5;34217:12;;;33556:692;;;;;;:::o;52715:250::-;52811:18;52817:2;52821:7;52811:5;:18::i;:::-;52848:54;52879:1;52883:2;52887:7;52896:5;52848:22;:54::i;:::-;52840:117;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52715:250;;;:::o;34423:1549::-;34487:4;34603:16;34622:3;:12;;:17;34635:3;34622:17;;;;;;;;;;;;34603:36;;34668:1;34656:8;:13;34652:1313;;35017:21;35052:1;35041:8;:12;35017:36;;35068:17;35110:1;35088:3;:12;;:19;;;;:23;35068:43;;35356:26;35385:3;:12;;35398:9;35385:23;;;;;;;;;;;;;;;;;;35356:52;;35533:9;35503:3;:12;;35516:13;35503:27;;;;;;;;;;;;;;;;;;:39;;;;;;;;;;;;;;;;;;;35657:1;35641:13;:17;35610:3;:12;;:28;35623:9;:14;;;35610:28;;;;;;;;;;;:48;;;;35767:3;:12;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35863:3;:12;;:17;35876:3;35863:17;;;;;;;;;;;35856:24;;;35904:4;35897:11;;;;;;;;34652:1313;35948:5;35941:12;;;34423:1549;;;;;:::o;18071:619::-;18131:4;18393:16;18420:19;18442:66;18420:88;;;;18611:7;18599:20;18587:32;;18651:11;18639:8;:23;;:42;;;;;18678:3;18666:15;;:8;:15;;18639:42;18631:51;;;;18071:619;;;:::o;21186:196::-;21289:12;21321:53;21344:6;21352:4;21358:1;21361:12;21321:22;:53::i;:::-;21314:60;;21186:196;;;;;:::o;27477:129::-;27550:4;27597:1;27574:3;:12;;:19;27587:5;27574:19;;;;;;;;;;;;:24;;27567:31;;27477:129;;;;:::o;53301:404::-;53395:1;53381:16;;:2;:16;;;;53373:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53454:16;53462:7;53454;:16::i;:::-;53453:17;53445:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53516:45;53545:1;53549:2;53553:7;53516:20;:45::i;:::-;53574:30;53596:7;53574:13;:17;53588:2;53574:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;53617:29;53634:7;53643:2;53617:12;:16;;:29;;;;;:::i;:::-;;53689:7;53685:2;53664:33;;53681:1;53664:33;;;;;;;;;;;;53301:404;;:::o;22563:979::-;22693:12;22726:18;22737:6;22726:10;:18::i;:::-;22718:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22852:12;22866:23;22893:6;:11;;22913:8;22924:4;22893:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22851:78;;;;22944:7;22940:595;;;22975:10;22968:17;;;;;;22940:595;23109:1;23089:10;:17;:21;23085:439;;;23352:10;23346:17;23413:15;23400:10;23396:2;23392:19;23385:44;23300:148;23495:12;23488:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22563:979;;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

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