ETH Price: $2,514.78 (+0.66%)
Gas: 3.75 Gwei

Token

AstroGator VX (AGVX)
 

Overview

Max Total Supply

1,734 AGVX

Holders

972

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
2 AGVX
0x70ffb12eaee078f412f846e4b2166e7a23856321
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:
AstroGator_VX

Compiler Version
v0.8.0+commit.c7dfd78e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-03-15
*/

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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



pragma solidity ^0.8.0;

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

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



pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

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

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

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

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



pragma solidity ^0.8.0;


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

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

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

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

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



pragma solidity ^0.8.0;


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

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

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

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

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



pragma solidity ^0.8.0;

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

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



pragma solidity ^0.8.0;


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

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

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

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

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

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



pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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



pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

            bytes32 lastvalue = set._values[lastIndex];

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

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

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

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

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

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

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

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

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

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

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

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


    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

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

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

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



pragma solidity ^0.8.0;

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

    struct MapEntry {
        bytes32 _key;
        bytes32 _value;
    }

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

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

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

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

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

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

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

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

            MapEntry storage lastEntry = map._entries[lastIndex];

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

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

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

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

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

    // UintToAddressMap

    struct UintToAddressMap {
        Map _inner;
    }

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

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

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

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

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

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

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

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

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



pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    function toString(uint _i) internal pure returns (string memory _uintAsString) {
        if (_i == 0) {
            return "0";
        }
        uint j = _i;
        uint len;
        while (j != 0) {
            len++;
            j /= 10;
        }
        bytes memory bstr = new bytes(len);
        uint k = len;
        while (_i != 0) {
            k = k-1;
            uint8 temp = (48 + uint8(_i - _i / 10 * 10));
            bytes1 b1 = bytes1(temp);
            bstr[k] = b1;
            _i /= 10;
        }
        return string(bstr);
    }
}

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



pragma solidity ^0.8.0;

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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

    // Base URI
    string private _baseURI;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

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

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

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

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

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

        _holderTokens[owner].remove(tokenId);

        _tokenOwners.remove(tokenId);

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        _tokenOwners.set(tokenId, to);

        emit Transfer(from, to, tokenId);
    }

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

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

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

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

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

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



pragma solidity ^0.8.0;

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

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

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

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

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

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

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

interface IAstro2dInterface {
    function balanceOf(address owner) external view returns (uint256);
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);
    function ownerOf(uint256 tokenId) external view returns (address);
}


library MerkleProof {
    
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }
        }
        return computedHash;
    }
}

pragma solidity ^0.8.0;

// MADE BY LOOTEX
/**
 * @title AstroGator_VX
 * @dev Extends ERC721 Non-Fungible Token Standard basic implementation
 */
contract AstroGator_VX is ERC721, Ownable {
    using Strings for uint256;

    uint256 public constant maxAstroGatorPurchase = 20;
    uint256 public constant AstroGatorPrice = 0.2e18; //0.2 ETH
    uint256 public constant eachPhaseSupply =  1000;
    uint256 public immutable MAX_AstroGators;
    uint256 public nextTokenId = 10000;
    uint256 public startingIndexForFirst;
    uint256 public startingIndexForSecond;
    uint256 public startingIndexForThird;

    bool public saleIsActive = false;
    bool public BaseURIUnchangeable = false;

    address public immutable treasury;

    bytes32 public rootForClaim = 0xba8e582feee9fb682656368941482537b52f094170d0df79b95ee2c0d3cc7b1a;
    bytes32 public root;

    mapping(uint256 => bool) public claimedTokenId;

    IAstro2dInterface public immutable astro2dContract;

    event BaseURISet(string baseURI);
    event SaleStateFlipped(bool saleIsActive);
    event RootSet(bytes32 root);
    event RootForClaimSet(bytes32 rootForClaim);
    event StartingIndexForFirstSet(uint256 startingIndexForFirst);
    event StartingIndexForSecondSet(uint256 startingIndexForSecond);
    event StartingIndexForThirdSet(uint256 startingIndexForThird);

    constructor(uint256 maxNftSupply, address fundReceiver, address astro2dContractAddress) ERC721("AstroGator VX", "AGVX") {
        MAX_AstroGators = maxNftSupply;
        treasury = fundReceiver;
        astro2dContract = IAstro2dInterface(astro2dContractAddress);
    }

    /**
    * Mints AstroGators
    */
    function mint(uint numberOfTokens, bytes32[] memory proof) external payable {
        address operator = _msgSender();
        uint256 _nextTokenId = nextTokenId;

        require(operator == tx.origin, "Contract wallet disallowed");
        require(saleIsActive, "Sale not active");
        require(numberOfTokens <= maxAstroGatorPurchase, "20 tokens once");
        require(numberOfTokens + _nextTokenId <= MAX_AstroGators, "Purchase exceed max supply");
        require(AstroGatorPrice * numberOfTokens == msg.value, "Ether value sent incorrect");
        if (root != 0) {
            require(MerkleProof.verify(proof, root, keccak256(abi.encodePacked(operator))), "Not whitelisted");
        }

        nextTokenId += numberOfTokens;

        for(uint i = 0; i < numberOfTokens; i++) {
            _safeMint(operator, _nextTokenId + i);
        }
    }

    /**
    * For 2d holders to claim 3d AstroGators
    */
    function claimById(uint256 tokenId, bytes32[] memory proof) external {
        address operator = _msgSender();

        require(MerkleProof.verify(proof, rootForClaim, keccak256(abi.encodePacked(tokenId.toString()))), "TokenId unclaimable");
        require(astro2dContract.ownerOf(tokenId) == operator, "Not the token owner");
        require(!claimedTokenId[tokenId], "Token already claimed");

        claimedTokenId[tokenId] = true;
        _safeMint(operator, tokenId);
    }

    function claimAll() external {
        address operator = _msgSender();

        require(rootForClaim == 0, "not yet");
        uint balance = astro2dContract.balanceOf(operator);
        require(balance > 0, "You have no 2d astrogators.");
        require(balance < 21, "Will run out of gas, please use claimByList instead.");

        for (uint i = 0; i < balance; i++) {
            uint256 tokenId = astro2dContract.tokenOfOwnerByIndex(operator, i);
            if (!claimedTokenId[tokenId]) {
                claimedTokenId[tokenId] = true;
                _safeMint(operator, tokenId);
            }
        }
    }

    function claimByList(uint256[] memory tokenList) external {
        address operator = _msgSender();

        require(rootForClaim == 0, "not yet");
        require(tokenList.length < 21, "Will run out of gas, please claim maximum of 20 at once.");

        for (uint i = 0; i < tokenList.length; i++) {
            uint256 _tokenId = tokenList[i];
            require(astro2dContract.ownerOf(_tokenId) == operator, "You are not the owner of the token.");
            if (!claimedTokenId[_tokenId]) {
                claimedTokenId[_tokenId] = true;
                _safeMint(operator, _tokenId);
            }
        }
    }

    /**
     * Set some AstroGators aside
     */
    function reserveAstroGators(uint numberOfTokens) external onlyOwner {
        uint256 _nextTokenId = nextTokenId;
        require(numberOfTokens + _nextTokenId <= MAX_AstroGators, "Reserve exceed max supply");

        nextTokenId += numberOfTokens;

        for(uint i = 0; i < numberOfTokens; i++) {
            _safeMint(_msgSender(), _nextTokenId + i);
        }
    }

    function setrootForClaim(bytes32 _rootForClaim) external onlyOwner {
        rootForClaim = _rootForClaim;
        emit RootForClaimSet(_rootForClaim);
    }

    function setroot(bytes32 _root) external onlyOwner {
        root = _root;
        emit RootSet(_root);
    }

    // RNG for each phase after fully minted
    function setStartingIndexForFirst() external onlyOwner {
        require(startingIndexForFirst == 0, "Already set");
        
        startingIndexForFirst = uint(blockhash(block.number - 1)) % eachPhaseSupply;
        emit StartingIndexForFirstSet(startingIndexForFirst);
    }

    function setStartingIndexForSecond() external onlyOwner {
        require(startingIndexForSecond == 0, "Already set");
        
        startingIndexForSecond = uint(blockhash(block.number - 1)) % eachPhaseSupply;
        emit StartingIndexForSecondSet(startingIndexForSecond);
    }

    function setStartingIndexForThird() external onlyOwner {
        require(startingIndexForThird == 0, "Already set");
        
        startingIndexForThird = uint(blockhash(block.number - 1)) % eachPhaseSupply;
        emit StartingIndexForThirdSet(startingIndexForThird);
    }

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory base = baseURI();
        string memory unRevealURI = "https://astrogator.mypinata.cloud/ipfs/QmeTqKeKtjKT66YmbhNJe9j8BD1deh4v3qZLZG89hz9r4o/blindbox"; 
        uint256 _eachPhaseSupply = eachPhaseSupply;

        if (tokenId < 10000) {
            return string(abi.encodePacked(base, tokenId.toString()));
        }

        // when first start index has been revealed
        if (startingIndexForFirst != 0 && tokenId < 11000 ) {
            uint256 _id = tokenId + startingIndexForFirst;
            if (_id > 10999) {
                _id -= _eachPhaseSupply;
            }
            return string(abi.encodePacked(base, _id.toString()));
        }

        // when second phase start index has been revealed
        if (startingIndexForSecond != 0 && tokenId < 12000) {
            uint256 _id = tokenId + startingIndexForSecond;
            if (_id > 11999) {
                _id -= _eachPhaseSupply;
            }
            return string(abi.encodePacked(base, _id.toString()));
        }

        // when third phase start index has been revealed
        if (startingIndexForThird != 0) {
            uint256 _id = tokenId + startingIndexForThird;
            if (_id >= MAX_AstroGators) {
                _id -= _eachPhaseSupply;
            }
            return string(abi.encodePacked(base, _id.toString()));
        }

        // when not revealed yet, give the same image
        return unRevealURI;
    }

    function withdraw() external onlyOwner {
        payable(treasury).call{value:address(this).balance}("");
    }

    function setBaseURI(string memory baseURI) external onlyOwner {
        require(!BaseURIUnchangeable, "BaseURI unchangeable");
        _setBaseURI(baseURI);
        emit BaseURISet(baseURI);
    }

    function lockBaseURI() external onlyOwner {
        require(!BaseURIUnchangeable, "Already locked");
        BaseURIUnchangeable = true;
    }

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"maxNftSupply","type":"uint256"},{"internalType":"address","name":"fundReceiver","type":"address"},{"internalType":"address","name":"astro2dContractAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"baseURI","type":"string"}],"name":"BaseURISet","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":false,"internalType":"bytes32","name":"rootForClaim","type":"bytes32"}],"name":"RootForClaimSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"RootSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"saleIsActive","type":"bool"}],"name":"SaleStateFlipped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"startingIndexForFirst","type":"uint256"}],"name":"StartingIndexForFirstSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"startingIndexForSecond","type":"uint256"}],"name":"StartingIndexForSecondSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"startingIndexForThird","type":"uint256"}],"name":"StartingIndexForThirdSet","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":"AstroGatorPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BaseURIUnchangeable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_AstroGators","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"astro2dContract","outputs":[{"internalType":"contract IAstro2dInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"claimById","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenList","type":"uint256[]"}],"name":"claimByList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"claimedTokenId","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eachPhaseSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flipSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxAstroGatorPurchase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"reserveAstroGators","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rootForClaim","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","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":[],"name":"setStartingIndexForFirst","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setStartingIndexForSecond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setStartingIndexForThird","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"setroot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_rootForClaim","type":"bytes32"}],"name":"setrootForClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startingIndexForFirst","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startingIndexForSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startingIndexForThird","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"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":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60e0604052612710600b55600f805461ffff191690557fba8e582feee9fb682656368941482537b52f094170d0df79b95ee2c0d3cc7b1a6010553480156200004657600080fd5b5060405162003c4e38038062003c4e8339810160408190526200006991620002c2565b604080518082018252600d81526c082e6e8e4de8ec2e8dee440acb609b1b602080830191909152825180840190935260048352630828eacb60e31b9083015290620000bb6301ffc9a760e01b620001a0565b8151620000d0906006906020850190620001ff565b508051620000e6906007906020840190620001ff565b50620000f96380ac58cd60e01b620001a0565b6200010b635b5e139f60e01b620001a0565b6200011d63780e9d6360e01b620001a0565b50600090506200012c620001fb565b600a80546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506080929092526001600160601b0319606091821b811660a05291901b1660c05262000376565b6001600160e01b03198082161415620001d65760405162461bcd60e51b8152600401620001cd9062000302565b60405180910390fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b3390565b8280546200020d9062000339565b90600052602060002090601f0160209004810192826200023157600085556200027c565b82601f106200024c57805160ff19168380011785556200027c565b828001600101855582156200027c579182015b828111156200027c5782518255916020019190600101906200025f565b506200028a9291506200028e565b5090565b5b808211156200028a57600081556001016200028f565b80516001600160a01b0381168114620002bd57600080fd5b919050565b600080600060608486031215620002d7578283fd5b83519250620002e960208501620002a5565b9150620002f960408501620002a5565b90509250925092565b6020808252601c908201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604082015260600190565b6002810460018216806200034e57607f821691505b602082108114156200037057634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160601c60c05160601c61386a620003e46000396000818161094c01528181610c8c015281816118b20152818161199e0152611b98015260008181610f0c01526111810152600081816113f9015281816115d40152818161183c0152611ab3015261386a6000f3fe6080604052600436106102ae5760003560e01c8063699fcbb811610175578063b88d4fde116100dc578063e985e9c511610095578063f03a43141161006f578063f03a43141461077d578063f2fde38b14610792578063f87cfd97146107b2578063ffff5dd8146107c7576102ae565b8063e985e9c514610733578063eb8d244414610753578063ebf0c71714610768576102ae565b8063b88d4fde14610696578063b8a8fecf146106b6578063ba41b0c6146106d6578063c7cde8fd146106e9578063c87b56dd146106fe578063d1058e591461071e576102ae565b80638da5cb5b1161012e5780638da5cb5b146105f757806395d89b411461060c57806398cdceae14610621578063a22cb46514610636578063ae3f07f014610656578063b4411eb114610676576102ae565b8063699fcbb81461056e5780636c0360eb1461058357806370a0823114610598578063715018a6146105b857806375794a3c146105cd57806381b43c44146105e2576102ae565b806334918dfd116102195780634f6ccce7116101d25780634f6ccce7146104cf57806353df5c7c146104ef57806355f804b31461050457806361d027b3146105245780636352211e1461053957806363a9639314610559576102ae565b806334918dfd146104465780633c952bd31461045b5780633ccfd60b14610470578063426040441461048557806342842e0e1461049a5780634d6bd02a146104ba576102ae565b806318160ddd1161026b57806318160ddd1461038f57806323b872dd146103b1578063275ffed7146103d157806328b34f90146103e65780632b530602146104065780632f745c5914610426576102ae565b806301ffc9a7146102b357806306fdde03146102e9578063081812fc1461030b578063089c621214610338578063093c7f771461035a578063095ea7b31461036f575b600080fd5b3480156102bf57600080fd5b506102d36102ce366004612aba565b6107dc565b6040516102e09190612cfb565b60405180910390f35b3480156102f557600080fd5b506102fe6107ff565b6040516102e09190612d0f565b34801561031757600080fd5b5061032b610326366004612aa2565b610891565b6040516102e09190612c91565b34801561034457600080fd5b50610358610353366004612b50565b6108dd565b005b34801561036657600080fd5b50610358610a63565b34801561037b57600080fd5b5061035861038a3660046129e2565b610b18565b34801561039b57600080fd5b506103a4610bab565b6040516102e09190612d06565b3480156103bd57600080fd5b506103586103cc3660046128f4565b610bbc565b3480156103dd57600080fd5b506103a4610bf4565b3480156103f257600080fd5b50610358610401366004612a0d565b610bfa565b34801561041257600080fd5b50610358610421366004612aa2565b610d98565b34801561043257600080fd5b506103a46104413660046129e2565b610e17565b34801561045257600080fd5b50610358610e42565b34801561046757600080fd5b506103a4610ec5565b34801561047c57600080fd5b50610358610ecb565b34801561049157600080fd5b50610358610f7e565b3480156104a657600080fd5b506103586104b53660046128f4565b611029565b3480156104c657600080fd5b506102d3611044565b3480156104db57600080fd5b506103a46104ea366004612aa2565b611052565b3480156104fb57600080fd5b50610358611068565b34801561051057600080fd5b5061035861051f366004612af2565b6110e0565b34801561053057600080fd5b5061032b61117f565b34801561054557600080fd5b5061032b610554366004612aa2565b6111a3565b34801561056557600080fd5b506103a46111cb565b34801561057a57600080fd5b506103a46111d1565b34801561058f57600080fd5b506102fe6111d7565b3480156105a457600080fd5b506103a46105b3366004612884565b6111e6565b3480156105c457600080fd5b5061035861122f565b3480156105d957600080fd5b506103a46112b8565b3480156105ee57600080fd5b506103a46112be565b34801561060357600080fd5b5061032b6112c3565b34801561061857600080fd5b506102fe6112d2565b34801561062d57600080fd5b506103a46112e1565b34801561064257600080fd5b506103586106513660046129b1565b6112e7565b34801561066257600080fd5b50610358610671366004612aa2565b6113b5565b34801561068257600080fd5b50610358610691366004612aa2565b61148f565b3480156106a257600080fd5b506103586106b1366004612934565b611503565b3480156106c257600080fd5b506102d36106d1366004612aa2565b611542565b6103586106e4366004612b50565b611557565b3480156106f557600080fd5b506103a46116d1565b34801561070a57600080fd5b506102fe610719366004612aa2565b6116dd565b34801561072a57600080fd5b5061035861186b565b34801561073f57600080fd5b506102d361074e3660046128bc565b611a74565b34801561075f57600080fd5b506102d3611aa2565b34801561077457600080fd5b506103a4611aab565b34801561078957600080fd5b506103a4611ab1565b34801561079e57600080fd5b506103586107ad366004612884565b611ad5565b3480156107be57600080fd5b5061032b611b96565b3480156107d357600080fd5b50610358611bba565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60606006805461080e906136a1565b80601f016020809104026020016040519081016040528092919081815260200182805461083a906136a1565b80156108875780601f1061085c57610100808354040283529160200191610887565b820191906000526020600020905b81548152906001019060200180831161086a57829003601f168201915b5050505050905090565b600061089c82611c65565b6108c15760405162461bcd60e51b81526004016108b8906132e5565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006108e7611c72565b9050610924826010546108f986611c76565b6040516020016109099190612c43565b60405160208183030381529060405280519060200120611dbc565b6109405760405162461bcd60e51b81526004016108b890613573565b806001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636352211e856040518263ffffffff1660e01b81526004016109969190612d06565b60206040518083038186803b1580156109ae57600080fd5b505afa1580156109c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e691906128a0565b6001600160a01b031614610a0c5760405162461bcd60e51b81526004016108b890613008565b60008381526012602052604090205460ff1615610a3b5760405162461bcd60e51b81526004016108b890612f8d565b6000838152601260205260409020805460ff19166001179055610a5e8184611dd4565b505050565b610a6b611c72565b6001600160a01b0316610a7c6112c3565b6001600160a01b031614610aa25760405162461bcd60e51b81526004016108b890613331565b600e5415610ac25760405162461bcd60e51b81526004016108b8906131c2565b6103e8610ad060014361365e565b610adb9190406136f7565b600e8190556040517fedfb7dc8ddcd4d12e24e8d772f17a4ea0549ce78c952f67c00a85d3b897db66291610b0e91612d06565b60405180910390a1565b6000610b23826111a3565b9050806001600160a01b0316836001600160a01b03161415610b575760405162461bcd60e51b81526004016108b8906133fe565b806001600160a01b0316610b69611c72565b6001600160a01b03161480610b855750610b858161074e611c72565b610ba15760405162461bcd60e51b81526004016108b8906130f2565b610a5e8383611df2565b6000610bb76002611e60565b905090565b610bcd610bc7611c72565b82611e6b565b610be95760405162461bcd60e51b81526004016108b890613497565b610a5e838383611ef0565b600c5481565b6000610c04611c72565b60105490915015610c275760405162461bcd60e51b81526004016108b89061343f565b6015825110610c485760405162461bcd60e51b81526004016108b89061305e565b60005b8251811015610a5e576000838281518110610c7657634e487b7160e01b600052603260045260246000fd5b60200260200101519050826001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636352211e836040518263ffffffff1660e01b8152600401610cd69190612d06565b60206040518083038186803b158015610cee57600080fd5b505afa158015610d02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2691906128a0565b6001600160a01b031614610d4c5760405162461bcd60e51b81526004016108b890612f4a565b60008181526012602052604090205460ff16610d85576000818152601260205260409020805460ff19166001179055610d858382611dd4565b5080610d90816136dc565b915050610c4b565b610da0611c72565b6001600160a01b0316610db16112c3565b6001600160a01b031614610dd75760405162461bcd60e51b81526004016108b890613331565b60108190556040517fb26bdcb05068fadf3ea5f83eb759965e8fc51039e10499ce2d3256db979c7b3c90610e0c908390612d06565b60405180910390a150565b6001600160a01b0382166000908152600160205260408120610e399083611ffe565b90505b92915050565b610e4a611c72565b6001600160a01b0316610e5b6112c3565b6001600160a01b031614610e815760405162461bcd60e51b81526004016108b890613331565b600f805460ff19811660ff9182161517918290556040517f710bbf0bcdcb35985b999576c56823590f7fa7a1500e9115f5ee3d13492a548692610b0e921690612cfb565b600e5481565b610ed3611c72565b6001600160a01b0316610ee46112c3565b6001600160a01b031614610f0a5760405162461bcd60e51b81526004016108b890613331565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031647604051610f4190612c8e565b60006040518083038185875af1925050503d8060008114610a5e576040519150601f19603f3d011682016040523d82523d6000602084013e610a5e565b610f86611c72565b6001600160a01b0316610f976112c3565b6001600160a01b031614610fbd5760405162461bcd60e51b81526004016108b890613331565b600d5415610fdd5760405162461bcd60e51b81526004016108b8906131c2565b6103e8610feb60014361365e565b610ff69190406136f7565b600d8190556040517f8cc967396402e20373358cf6c7dc63ff400c43129206eaab600b4a26815bcffa91610b0e91612d06565b610a5e83838360405180602001604052806000815250611503565b600f54610100900460ff1681565b60008061106060028461200a565b509392505050565b611070611c72565b6001600160a01b03166110816112c3565b6001600160a01b0316146110a75760405162461bcd60e51b81526004016108b890613331565b600f54610100900460ff16156110cf5760405162461bcd60e51b81526004016108b890613288565b600f805461ff001916610100179055565b6110e8611c72565b6001600160a01b03166110f96112c3565b6001600160a01b03161461111f5760405162461bcd60e51b81526004016108b890613331565b600f54610100900460ff16156111475760405162461bcd60e51b81526004016108b890612ea1565b61115081612026565b7ff9c7803e94e0d3c02900d8a90893a6d5e90dd04d32a4cfe825520f82bf9f32f681604051610e0c9190612d0f565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000610e3c826040518060600160405280602981526020016137ae6029913960029190612039565b60105481565b6103e881565b60606009805461080e906136a1565b60006001600160a01b03821661120e5760405162461bcd60e51b81526004016108b890613178565b6001600160a01b0382166000908152600160205260409020610e3c90611e60565b611237611c72565b6001600160a01b03166112486112c3565b6001600160a01b03161461126e5760405162461bcd60e51b81526004016108b890613331565b600a546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600a80546001600160a01b0319169055565b600b5481565b601481565b600a546001600160a01b031690565b60606007805461080e906136a1565b600d5481565b6112ef611c72565b6001600160a01b0316826001600160a01b031614156113205760405162461bcd60e51b81526004016108b890612f13565b806005600061132d611c72565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611371611c72565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516113a99190612cfb565b60405180910390a35050565b6113bd611c72565b6001600160a01b03166113ce6112c3565b6001600160a01b0316146113f45760405162461bcd60e51b81526004016108b890613331565b600b547f000000000000000000000000000000000000000000000000000000000000000061142282846135ee565b11156114405760405162461bcd60e51b81526004016108b890612d64565b81600b600082825461145291906135ee565b90915550600090505b82811015610a5e5761147d61146e611c72565b61147883856135ee565b611dd4565b80611487816136dc565b91505061145b565b611497611c72565b6001600160a01b03166114a86112c3565b6001600160a01b0316146114ce5760405162461bcd60e51b81526004016108b890613331565b60118190556040517f2ae0bd135f5bcfc82b9dbffdabe76051e763c2ed1c7188197181a575aa0e55b390610e0c908390612d06565b61151461150e611c72565b83611e6b565b6115305760405162461bcd60e51b81526004016108b890613497565b61153c84848484612046565b50505050565b60126020526000908152604090205460ff1681565b6000611561611c72565b600b549091506001600160a01b038216321461158f5760405162461bcd60e51b81526004016108b890612d9b565b600f5460ff166115b15760405162461bcd60e51b81526004016108b890613035565b60148411156115d25760405162461bcd60e51b81526004016108b8906131e7565b7f00000000000000000000000000000000000000000000000000000000000000006115fd82866135ee565b111561161b5760405162461bcd60e51b81526004016108b890613460565b3461162e856702c68af0bb14000061363f565b1461164b5760405162461bcd60e51b81526004016108b89061320f565b601154156116875761166b83601154846040516020016109099190612c18565b6116875760405162461bcd60e51b81526004016108b89061314f565b83600b600082825461169991906135ee565b90915550600090505b848110156116ca576116b88361147883856135ee565b806116c2816136dc565b9150506116a2565b5050505050565b6702c68af0bb14000081565b60606116e882611c65565b6117045760405162461bcd60e51b81526004016108b8906133af565b600061170e6111d7565b905060006040518060800160405280605e81526020016137d7605e913990506103e861271085101561176e578261174486611c76565b604051602001611755929190612c5f565b60405160208183030381529060405293505050506107fa565b600c54158015906117805750612af885105b156117e3576000600c548661179591906135ee565b9050612af78111156117ae576117ab828261365e565b90505b836117b882611c76565b6040516020016117c9929190612c5f565b6040516020818303038152906040529450505050506107fa565b600d54158015906117f55750612ee085105b15611820576000600d548661180a91906135ee565b9050612edf8111156117ae576117ab828261365e565b600e5415611060576000600e548661183891906135ee565b90507f000000000000000000000000000000000000000000000000000000000000000081106117ae576117ab828261365e565b6000611875611c72565b601054909150156118985760405162461bcd60e51b81526004016108b89061343f565b6040516370a0823160e01b81526000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a08231906118e7908590600401612c91565b60206040518083038186803b1580156118ff57600080fd5b505afa158015611913573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119379190612b38565b9050600081116119595760405162461bcd60e51b81526004016108b8906130bb565b601581106119795760405162461bcd60e51b81526004016108b89061351f565b60005b81811015610a5e57604051632f745c5960e01b81526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632f745c59906119d59087908690600401612ce2565b60206040518083038186803b1580156119ed57600080fd5b505afa158015611a01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a259190612b38565b60008181526012602052604090205490915060ff16611a61576000818152601260205260409020805460ff19166001179055611a618482611dd4565b5080611a6c816136dc565b91505061197c565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b600f5460ff1681565b60115481565b7f000000000000000000000000000000000000000000000000000000000000000081565b611add611c72565b6001600160a01b0316611aee6112c3565b6001600160a01b031614611b145760405162461bcd60e51b81526004016108b890613331565b6001600160a01b038116611b3a5760405162461bcd60e51b81526004016108b890612e24565b600a546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600a80546001600160a01b0319166001600160a01b0392909216919091179055565b7f000000000000000000000000000000000000000000000000000000000000000081565b611bc2611c72565b6001600160a01b0316611bd36112c3565b6001600160a01b031614611bf95760405162461bcd60e51b81526004016108b890613331565b600c5415611c195760405162461bcd60e51b81526004016108b8906131c2565b6103e8611c2760014361365e565b611c329190406136f7565b600c8190556040517f8984a88ffc1c14d1f78a44f4ff9fd2de719adc32116449b65ddd679965d8abfd91610b0e91612d06565b6000610e3c600283612079565b3390565b606081611c9b57506040805180820190915260018152600360fc1b60208201526107fa565b8160005b8115611cc55780611caf816136dc565b9150611cbe9050600a8361362b565b9150611c9f565b60008167ffffffffffffffff811115611cee57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611d18576020820181803683370190505b509050815b8515611db357611d2e60018261365e565b90506000611d3d600a8861362b565b611d4890600a61363f565b611d52908861365e565b611d5d906030613606565b905060008160f81b905080848481518110611d8857634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350611daa600a8961362b565b97505050611d1d565b50949350505050565b600082611dc98584612085565b1490505b9392505050565b611dee828260405180602001604052806000815250612135565b5050565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611e27826111a3565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610e3c82612168565b6000611e7682611c65565b611e925760405162461bcd60e51b81526004016108b890612fbc565b6000611e9d836111a3565b9050806001600160a01b0316846001600160a01b03161480611ed85750836001600160a01b0316611ecd84610891565b6001600160a01b0316145b80611ee85750611ee88185611a74565b949350505050565b826001600160a01b0316611f03826111a3565b6001600160a01b031614611f295760405162461bcd60e51b81526004016108b890613366565b6001600160a01b038216611f4f5760405162461bcd60e51b81526004016108b890612ecf565b611f5a838383610a5e565b611f65600082611df2565b6001600160a01b0383166000908152600160205260409020611f87908261216c565b506001600160a01b0382166000908152600160205260409020611faa9082612178565b50611fb760028284612184565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000610e39838361219a565b600080808061201986866121f3565b9097909650945050505050565b8051611dee906009906020840190612793565b6000611ee8848484612263565b612051848484611ef0565b61205d848484846122da565b61153c5760405162461bcd60e51b81526004016108b890612dd2565b6000610e3983836123b9565b600081815b84518110156110605760008582815181106120b557634e487b7160e01b600052603260045260246000fd5b602002602001015190508083116120f65782816040516020016120d9929190612c35565b604051602081830303815290604052805190602001209250612122565b8083604051602001612109929190612c35565b6040516020818303038152906040528051906020012092505b508061212d816136dc565b91505061208a565b61213f83836123d1565b61214c60008484846122da565b610a5e5760405162461bcd60e51b81526004016108b890612dd2565b5490565b6000610e398383612495565b6000610e3983836125b2565b6000611ee884846001600160a01b0385166125fc565b815460009082106121bd5760405162461bcd60e51b81526004016108b890612d22565b8260000182815481106121e057634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b8154600090819083106122185760405162461bcd60e51b81526004016108b890613246565b600084600001848154811061223d57634e487b7160e01b600052603260045260246000fd5b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816122935760405162461bcd60e51b81526004016108b89190612d0f565b50846122a060018361365e565b815481106122be57634e487b7160e01b600052603260045260246000fd5b9060005260206000209060020201600101549150509392505050565b60006122ee846001600160a01b03166126ab565b6122fa57506001611ee8565b6000612382630a85bd0160e11b61230f611c72565b8887876040516024016123259493929190612ca5565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505060405180606001604052806032815260200161377c603291396001600160a01b03881691906126b1565b905060008180602001905181019061239a9190612ad6565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b60009081526001919091016020526040902054151590565b6001600160a01b0382166123f75760405162461bcd60e51b81526004016108b8906132b0565b61240081611c65565b1561241d5760405162461bcd60e51b81526004016108b890612e6a565b61242960008383610a5e565b6001600160a01b038216600090815260016020526040902061244b9082612178565b5061245860028284612184565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600081815260018301602052604081205480156125a85760006124b960018361365e565b85549091506000906124cd9060019061365e565b905060008660000182815481106124f457634e487b7160e01b600052603260045260246000fd5b906000526020600020015490508087600001848154811061252557634e487b7160e01b600052603260045260246000fd5b60009182526020909120015561253c8360016135ee565b6000828152600189016020526040902055865487908061256c57634e487b7160e01b600052603160045260246000fd5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610e3c565b6000915050610e3c565b60006125be83836123b9565b6125f457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610e3c565b506000610e3c565b600082815260018401602052604081205480612661575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055611dcd565b828561266e60018461365e565b8154811061268c57634e487b7160e01b600052603260045260246000fd5b9060005260206000209060020201600101819055506000915050611dcd565b3b151590565b6060611ee88484600085856126c5856126ab565b6126e15760405162461bcd60e51b81526004016108b8906134e8565b600080866001600160a01b031685876040516126fd9190612c43565b60006040518083038185875af1925050503d806000811461273a576040519150601f19603f3d011682016040523d82523d6000602084013e61273f565b606091505b509150915061274f82828661275a565b979650505050505050565b60608315612769575081611dcd565b8251156127795782518084602001fd5b8160405162461bcd60e51b81526004016108b89190612d0f565b82805461279f906136a1565b90600052602060002090601f0160209004810192826127c15760008555612807565b82601f106127da57805160ff1916838001178555612807565b82800160010185558215612807579182015b828111156128075782518255916020019190600101906127ec565b50612813929150612817565b5090565b5b808211156128135760008155600101612818565b600067ffffffffffffffff83111561284657612846613737565b612859601f8401601f19166020016135a0565b905082815283838301111561286d57600080fd5b828260208301376000602084830101529392505050565b600060208284031215612895578081fd5b8135611dcd8161374d565b6000602082840312156128b1578081fd5b8151611dcd8161374d565b600080604083850312156128ce578081fd5b82356128d98161374d565b915060208301356128e98161374d565b809150509250929050565b600080600060608486031215612908578081fd5b83356129138161374d565b925060208401356129238161374d565b929592945050506040919091013590565b60008060008060808587031215612949578081fd5b84356129548161374d565b935060208501356129648161374d565b925060408501359150606085013567ffffffffffffffff811115612986578182fd5b8501601f81018713612996578182fd5b6129a58782356020840161282c565b91505092959194509250565b600080604083850312156129c3578182fd5b82356129ce8161374d565b9150602083013580151581146128e9578182fd5b600080604083850312156129f4578182fd5b82356129ff8161374d565b946020939093013593505050565b60006020808385031215612a1f578182fd5b823567ffffffffffffffff811115612a35578283fd5b8301601f81018513612a45578283fd5b8035612a58612a53826135ca565b6135a0565b8181528381019083850185840285018601891015612a74578687fd5b8694505b83851015612a96578035835260019490940193918501918501612a78565b50979650505050505050565b600060208284031215612ab3578081fd5b5035919050565b600060208284031215612acb578081fd5b8135611dcd81613765565b600060208284031215612ae7578081fd5b8151611dcd81613765565b600060208284031215612b03578081fd5b813567ffffffffffffffff811115612b19578182fd5b8201601f81018413612b29578182fd5b611ee88482356020840161282c565b600060208284031215612b49578081fd5b5051919050565b60008060408385031215612b62578182fd5b8235915060208084013567ffffffffffffffff811115612b80578283fd5b8401601f81018613612b90578283fd5b8035612b9e612a53826135ca565b81815283810190838501858402850186018a1015612bba578687fd5b8694505b83851015612bdc578035835260019490940193918501918501612bbe565b5080955050505050509250929050565b60008151808452612c04816020860160208601613675565b601f01601f19169290920160200192915050565b60609190911b6bffffffffffffffffffffffff1916815260140190565b918252602082015260400190565b60008251612c55818460208701613675565b9190910192915050565b60008351612c71818460208801613675565b835190830190612c85818360208801613675565b01949350505050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612cd890830184612bec565b9695505050505050565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b90815260200190565b600060208252610e396020830184612bec565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b60208082526019908201527f5265736572766520657863656564206d617820737570706c7900000000000000604082015260600190565b6020808252601a908201527f436f6e74726163742077616c6c657420646973616c6c6f776564000000000000604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b6020808252601490820152734261736555524920756e6368616e676561626c6560601b604082015260600190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b60208082526023908201527f596f7520617265206e6f7420746865206f776e6572206f662074686520746f6b60408201526232b71760e91b606082015260800190565b602080825260159082015274151bdad95b88185b1c9958591e4818db185a5b5959605a1b604082015260600190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252601390820152722737ba103a3432903a37b5b2b71037bbb732b960691b604082015260600190565b6020808252600f908201526e53616c65206e6f742061637469766560881b604082015260600190565b60208082526038908201527f57696c6c2072756e206f7574206f66206761732c20706c6561736520636c616960408201527f6d206d6178696d756d206f66203230206174206f6e63652e0000000000000000606082015260800190565b6020808252601b908201527f596f752068617665206e6f20326420617374726f6761746f72732e0000000000604082015260600190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252600f908201526e139bdd081dda1a5d195b1a5cdd1959608a1b604082015260600190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252600b908201526a105b1c9958591e481cd95d60aa1b604082015260600190565b6020808252600e908201526d323020746f6b656e73206f6e636560901b604082015260600190565b6020808252601a908201527f45746865722076616c75652073656e7420696e636f7272656374000000000000604082015260600190565b60208082526022908201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252600e908201526d105b1c9958591e481b1bd8dad95960921b604082015260600190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b6020808252602f908201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60408201526e3732bc34b9ba32b73a103a37b5b2b760891b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b6020808252600790820152661b9bdd081e595d60ca1b604082015260600190565b6020808252601a908201527f507572636861736520657863656564206d617820737570706c79000000000000604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b60208082526034908201527f57696c6c2072756e206f7574206f66206761732c20706c65617365207573652060408201527331b630b4b6a13ca634b9ba1034b739ba32b0b21760611b606082015260800190565b602080825260139082015272546f6b656e496420756e636c61696d61626c6560681b604082015260600190565b60405181810167ffffffffffffffff811182821017156135c2576135c2613737565b604052919050565b600067ffffffffffffffff8211156135e4576135e4613737565b5060209081020190565b600082198211156136015761360161370b565b500190565b600060ff821660ff84168060ff038211156136235761362361370b565b019392505050565b60008261363a5761363a613721565b500490565b60008160001904831182151516156136595761365961370b565b500290565b6000828210156136705761367061370b565b500390565b60005b83811015613690578181015183820152602001613678565b8381111561153c5750506000910152565b6002810460018216806136b557607f821691505b602082108114156136d657634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156136f0576136f061370b565b5060010190565b60008261370657613706613721565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461376257600080fd5b50565b6001600160e01b03198116811461376257600080fdfe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e68747470733a2f2f617374726f6761746f722e6d7970696e6174612e636c6f75642f697066732f516d6554714b654b746a4b543636596d62684e4a65396a38424431646568347633715a4c5a473839687a3972346f2f626c696e64626f78a26469706673582212204c0df92dbbf36555195a76f71ea6a01ec4689fe82a402de6ee4df92e642ea5ee64736f6c634300080000330000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000009d03e845a08cce64e2bbf38d8c42f7dccc533a160000000000000000000000002af743179e9d464c9bd687e90bc18f5ea146950f

Deployed Bytecode

0x6080604052600436106102ae5760003560e01c8063699fcbb811610175578063b88d4fde116100dc578063e985e9c511610095578063f03a43141161006f578063f03a43141461077d578063f2fde38b14610792578063f87cfd97146107b2578063ffff5dd8146107c7576102ae565b8063e985e9c514610733578063eb8d244414610753578063ebf0c71714610768576102ae565b8063b88d4fde14610696578063b8a8fecf146106b6578063ba41b0c6146106d6578063c7cde8fd146106e9578063c87b56dd146106fe578063d1058e591461071e576102ae565b80638da5cb5b1161012e5780638da5cb5b146105f757806395d89b411461060c57806398cdceae14610621578063a22cb46514610636578063ae3f07f014610656578063b4411eb114610676576102ae565b8063699fcbb81461056e5780636c0360eb1461058357806370a0823114610598578063715018a6146105b857806375794a3c146105cd57806381b43c44146105e2576102ae565b806334918dfd116102195780634f6ccce7116101d25780634f6ccce7146104cf57806353df5c7c146104ef57806355f804b31461050457806361d027b3146105245780636352211e1461053957806363a9639314610559576102ae565b806334918dfd146104465780633c952bd31461045b5780633ccfd60b14610470578063426040441461048557806342842e0e1461049a5780634d6bd02a146104ba576102ae565b806318160ddd1161026b57806318160ddd1461038f57806323b872dd146103b1578063275ffed7146103d157806328b34f90146103e65780632b530602146104065780632f745c5914610426576102ae565b806301ffc9a7146102b357806306fdde03146102e9578063081812fc1461030b578063089c621214610338578063093c7f771461035a578063095ea7b31461036f575b600080fd5b3480156102bf57600080fd5b506102d36102ce366004612aba565b6107dc565b6040516102e09190612cfb565b60405180910390f35b3480156102f557600080fd5b506102fe6107ff565b6040516102e09190612d0f565b34801561031757600080fd5b5061032b610326366004612aa2565b610891565b6040516102e09190612c91565b34801561034457600080fd5b50610358610353366004612b50565b6108dd565b005b34801561036657600080fd5b50610358610a63565b34801561037b57600080fd5b5061035861038a3660046129e2565b610b18565b34801561039b57600080fd5b506103a4610bab565b6040516102e09190612d06565b3480156103bd57600080fd5b506103586103cc3660046128f4565b610bbc565b3480156103dd57600080fd5b506103a4610bf4565b3480156103f257600080fd5b50610358610401366004612a0d565b610bfa565b34801561041257600080fd5b50610358610421366004612aa2565b610d98565b34801561043257600080fd5b506103a46104413660046129e2565b610e17565b34801561045257600080fd5b50610358610e42565b34801561046757600080fd5b506103a4610ec5565b34801561047c57600080fd5b50610358610ecb565b34801561049157600080fd5b50610358610f7e565b3480156104a657600080fd5b506103586104b53660046128f4565b611029565b3480156104c657600080fd5b506102d3611044565b3480156104db57600080fd5b506103a46104ea366004612aa2565b611052565b3480156104fb57600080fd5b50610358611068565b34801561051057600080fd5b5061035861051f366004612af2565b6110e0565b34801561053057600080fd5b5061032b61117f565b34801561054557600080fd5b5061032b610554366004612aa2565b6111a3565b34801561056557600080fd5b506103a46111cb565b34801561057a57600080fd5b506103a46111d1565b34801561058f57600080fd5b506102fe6111d7565b3480156105a457600080fd5b506103a46105b3366004612884565b6111e6565b3480156105c457600080fd5b5061035861122f565b3480156105d957600080fd5b506103a46112b8565b3480156105ee57600080fd5b506103a46112be565b34801561060357600080fd5b5061032b6112c3565b34801561061857600080fd5b506102fe6112d2565b34801561062d57600080fd5b506103a46112e1565b34801561064257600080fd5b506103586106513660046129b1565b6112e7565b34801561066257600080fd5b50610358610671366004612aa2565b6113b5565b34801561068257600080fd5b50610358610691366004612aa2565b61148f565b3480156106a257600080fd5b506103586106b1366004612934565b611503565b3480156106c257600080fd5b506102d36106d1366004612aa2565b611542565b6103586106e4366004612b50565b611557565b3480156106f557600080fd5b506103a46116d1565b34801561070a57600080fd5b506102fe610719366004612aa2565b6116dd565b34801561072a57600080fd5b5061035861186b565b34801561073f57600080fd5b506102d361074e3660046128bc565b611a74565b34801561075f57600080fd5b506102d3611aa2565b34801561077457600080fd5b506103a4611aab565b34801561078957600080fd5b506103a4611ab1565b34801561079e57600080fd5b506103586107ad366004612884565b611ad5565b3480156107be57600080fd5b5061032b611b96565b3480156107d357600080fd5b50610358611bba565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60606006805461080e906136a1565b80601f016020809104026020016040519081016040528092919081815260200182805461083a906136a1565b80156108875780601f1061085c57610100808354040283529160200191610887565b820191906000526020600020905b81548152906001019060200180831161086a57829003601f168201915b5050505050905090565b600061089c82611c65565b6108c15760405162461bcd60e51b81526004016108b8906132e5565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006108e7611c72565b9050610924826010546108f986611c76565b6040516020016109099190612c43565b60405160208183030381529060405280519060200120611dbc565b6109405760405162461bcd60e51b81526004016108b890613573565b806001600160a01b03167f0000000000000000000000002af743179e9d464c9bd687e90bc18f5ea146950f6001600160a01b0316636352211e856040518263ffffffff1660e01b81526004016109969190612d06565b60206040518083038186803b1580156109ae57600080fd5b505afa1580156109c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e691906128a0565b6001600160a01b031614610a0c5760405162461bcd60e51b81526004016108b890613008565b60008381526012602052604090205460ff1615610a3b5760405162461bcd60e51b81526004016108b890612f8d565b6000838152601260205260409020805460ff19166001179055610a5e8184611dd4565b505050565b610a6b611c72565b6001600160a01b0316610a7c6112c3565b6001600160a01b031614610aa25760405162461bcd60e51b81526004016108b890613331565b600e5415610ac25760405162461bcd60e51b81526004016108b8906131c2565b6103e8610ad060014361365e565b610adb9190406136f7565b600e8190556040517fedfb7dc8ddcd4d12e24e8d772f17a4ea0549ce78c952f67c00a85d3b897db66291610b0e91612d06565b60405180910390a1565b6000610b23826111a3565b9050806001600160a01b0316836001600160a01b03161415610b575760405162461bcd60e51b81526004016108b8906133fe565b806001600160a01b0316610b69611c72565b6001600160a01b03161480610b855750610b858161074e611c72565b610ba15760405162461bcd60e51b81526004016108b8906130f2565b610a5e8383611df2565b6000610bb76002611e60565b905090565b610bcd610bc7611c72565b82611e6b565b610be95760405162461bcd60e51b81526004016108b890613497565b610a5e838383611ef0565b600c5481565b6000610c04611c72565b60105490915015610c275760405162461bcd60e51b81526004016108b89061343f565b6015825110610c485760405162461bcd60e51b81526004016108b89061305e565b60005b8251811015610a5e576000838281518110610c7657634e487b7160e01b600052603260045260246000fd5b60200260200101519050826001600160a01b03167f0000000000000000000000002af743179e9d464c9bd687e90bc18f5ea146950f6001600160a01b0316636352211e836040518263ffffffff1660e01b8152600401610cd69190612d06565b60206040518083038186803b158015610cee57600080fd5b505afa158015610d02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2691906128a0565b6001600160a01b031614610d4c5760405162461bcd60e51b81526004016108b890612f4a565b60008181526012602052604090205460ff16610d85576000818152601260205260409020805460ff19166001179055610d858382611dd4565b5080610d90816136dc565b915050610c4b565b610da0611c72565b6001600160a01b0316610db16112c3565b6001600160a01b031614610dd75760405162461bcd60e51b81526004016108b890613331565b60108190556040517fb26bdcb05068fadf3ea5f83eb759965e8fc51039e10499ce2d3256db979c7b3c90610e0c908390612d06565b60405180910390a150565b6001600160a01b0382166000908152600160205260408120610e399083611ffe565b90505b92915050565b610e4a611c72565b6001600160a01b0316610e5b6112c3565b6001600160a01b031614610e815760405162461bcd60e51b81526004016108b890613331565b600f805460ff19811660ff9182161517918290556040517f710bbf0bcdcb35985b999576c56823590f7fa7a1500e9115f5ee3d13492a548692610b0e921690612cfb565b600e5481565b610ed3611c72565b6001600160a01b0316610ee46112c3565b6001600160a01b031614610f0a5760405162461bcd60e51b81526004016108b890613331565b7f0000000000000000000000009d03e845a08cce64e2bbf38d8c42f7dccc533a166001600160a01b031647604051610f4190612c8e565b60006040518083038185875af1925050503d8060008114610a5e576040519150601f19603f3d011682016040523d82523d6000602084013e610a5e565b610f86611c72565b6001600160a01b0316610f976112c3565b6001600160a01b031614610fbd5760405162461bcd60e51b81526004016108b890613331565b600d5415610fdd5760405162461bcd60e51b81526004016108b8906131c2565b6103e8610feb60014361365e565b610ff69190406136f7565b600d8190556040517f8cc967396402e20373358cf6c7dc63ff400c43129206eaab600b4a26815bcffa91610b0e91612d06565b610a5e83838360405180602001604052806000815250611503565b600f54610100900460ff1681565b60008061106060028461200a565b509392505050565b611070611c72565b6001600160a01b03166110816112c3565b6001600160a01b0316146110a75760405162461bcd60e51b81526004016108b890613331565b600f54610100900460ff16156110cf5760405162461bcd60e51b81526004016108b890613288565b600f805461ff001916610100179055565b6110e8611c72565b6001600160a01b03166110f96112c3565b6001600160a01b03161461111f5760405162461bcd60e51b81526004016108b890613331565b600f54610100900460ff16156111475760405162461bcd60e51b81526004016108b890612ea1565b61115081612026565b7ff9c7803e94e0d3c02900d8a90893a6d5e90dd04d32a4cfe825520f82bf9f32f681604051610e0c9190612d0f565b7f0000000000000000000000009d03e845a08cce64e2bbf38d8c42f7dccc533a1681565b6000610e3c826040518060600160405280602981526020016137ae6029913960029190612039565b60105481565b6103e881565b60606009805461080e906136a1565b60006001600160a01b03821661120e5760405162461bcd60e51b81526004016108b890613178565b6001600160a01b0382166000908152600160205260409020610e3c90611e60565b611237611c72565b6001600160a01b03166112486112c3565b6001600160a01b03161461126e5760405162461bcd60e51b81526004016108b890613331565b600a546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600a80546001600160a01b0319169055565b600b5481565b601481565b600a546001600160a01b031690565b60606007805461080e906136a1565b600d5481565b6112ef611c72565b6001600160a01b0316826001600160a01b031614156113205760405162461bcd60e51b81526004016108b890612f13565b806005600061132d611c72565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611371611c72565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516113a99190612cfb565b60405180910390a35050565b6113bd611c72565b6001600160a01b03166113ce6112c3565b6001600160a01b0316146113f45760405162461bcd60e51b81526004016108b890613331565b600b547f0000000000000000000000000000000000000000000000000000000000000bb861142282846135ee565b11156114405760405162461bcd60e51b81526004016108b890612d64565b81600b600082825461145291906135ee565b90915550600090505b82811015610a5e5761147d61146e611c72565b61147883856135ee565b611dd4565b80611487816136dc565b91505061145b565b611497611c72565b6001600160a01b03166114a86112c3565b6001600160a01b0316146114ce5760405162461bcd60e51b81526004016108b890613331565b60118190556040517f2ae0bd135f5bcfc82b9dbffdabe76051e763c2ed1c7188197181a575aa0e55b390610e0c908390612d06565b61151461150e611c72565b83611e6b565b6115305760405162461bcd60e51b81526004016108b890613497565b61153c84848484612046565b50505050565b60126020526000908152604090205460ff1681565b6000611561611c72565b600b549091506001600160a01b038216321461158f5760405162461bcd60e51b81526004016108b890612d9b565b600f5460ff166115b15760405162461bcd60e51b81526004016108b890613035565b60148411156115d25760405162461bcd60e51b81526004016108b8906131e7565b7f0000000000000000000000000000000000000000000000000000000000000bb86115fd82866135ee565b111561161b5760405162461bcd60e51b81526004016108b890613460565b3461162e856702c68af0bb14000061363f565b1461164b5760405162461bcd60e51b81526004016108b89061320f565b601154156116875761166b83601154846040516020016109099190612c18565b6116875760405162461bcd60e51b81526004016108b89061314f565b83600b600082825461169991906135ee565b90915550600090505b848110156116ca576116b88361147883856135ee565b806116c2816136dc565b9150506116a2565b5050505050565b6702c68af0bb14000081565b60606116e882611c65565b6117045760405162461bcd60e51b81526004016108b8906133af565b600061170e6111d7565b905060006040518060800160405280605e81526020016137d7605e913990506103e861271085101561176e578261174486611c76565b604051602001611755929190612c5f565b60405160208183030381529060405293505050506107fa565b600c54158015906117805750612af885105b156117e3576000600c548661179591906135ee565b9050612af78111156117ae576117ab828261365e565b90505b836117b882611c76565b6040516020016117c9929190612c5f565b6040516020818303038152906040529450505050506107fa565b600d54158015906117f55750612ee085105b15611820576000600d548661180a91906135ee565b9050612edf8111156117ae576117ab828261365e565b600e5415611060576000600e548661183891906135ee565b90507f0000000000000000000000000000000000000000000000000000000000000bb881106117ae576117ab828261365e565b6000611875611c72565b601054909150156118985760405162461bcd60e51b81526004016108b89061343f565b6040516370a0823160e01b81526000906001600160a01b037f0000000000000000000000002af743179e9d464c9bd687e90bc18f5ea146950f16906370a08231906118e7908590600401612c91565b60206040518083038186803b1580156118ff57600080fd5b505afa158015611913573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119379190612b38565b9050600081116119595760405162461bcd60e51b81526004016108b8906130bb565b601581106119795760405162461bcd60e51b81526004016108b89061351f565b60005b81811015610a5e57604051632f745c5960e01b81526000906001600160a01b037f0000000000000000000000002af743179e9d464c9bd687e90bc18f5ea146950f1690632f745c59906119d59087908690600401612ce2565b60206040518083038186803b1580156119ed57600080fd5b505afa158015611a01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a259190612b38565b60008181526012602052604090205490915060ff16611a61576000818152601260205260409020805460ff19166001179055611a618482611dd4565b5080611a6c816136dc565b91505061197c565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b600f5460ff1681565b60115481565b7f0000000000000000000000000000000000000000000000000000000000000bb881565b611add611c72565b6001600160a01b0316611aee6112c3565b6001600160a01b031614611b145760405162461bcd60e51b81526004016108b890613331565b6001600160a01b038116611b3a5760405162461bcd60e51b81526004016108b890612e24565b600a546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600a80546001600160a01b0319166001600160a01b0392909216919091179055565b7f0000000000000000000000002af743179e9d464c9bd687e90bc18f5ea146950f81565b611bc2611c72565b6001600160a01b0316611bd36112c3565b6001600160a01b031614611bf95760405162461bcd60e51b81526004016108b890613331565b600c5415611c195760405162461bcd60e51b81526004016108b8906131c2565b6103e8611c2760014361365e565b611c329190406136f7565b600c8190556040517f8984a88ffc1c14d1f78a44f4ff9fd2de719adc32116449b65ddd679965d8abfd91610b0e91612d06565b6000610e3c600283612079565b3390565b606081611c9b57506040805180820190915260018152600360fc1b60208201526107fa565b8160005b8115611cc55780611caf816136dc565b9150611cbe9050600a8361362b565b9150611c9f565b60008167ffffffffffffffff811115611cee57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611d18576020820181803683370190505b509050815b8515611db357611d2e60018261365e565b90506000611d3d600a8861362b565b611d4890600a61363f565b611d52908861365e565b611d5d906030613606565b905060008160f81b905080848481518110611d8857634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350611daa600a8961362b565b97505050611d1d565b50949350505050565b600082611dc98584612085565b1490505b9392505050565b611dee828260405180602001604052806000815250612135565b5050565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611e27826111a3565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610e3c82612168565b6000611e7682611c65565b611e925760405162461bcd60e51b81526004016108b890612fbc565b6000611e9d836111a3565b9050806001600160a01b0316846001600160a01b03161480611ed85750836001600160a01b0316611ecd84610891565b6001600160a01b0316145b80611ee85750611ee88185611a74565b949350505050565b826001600160a01b0316611f03826111a3565b6001600160a01b031614611f295760405162461bcd60e51b81526004016108b890613366565b6001600160a01b038216611f4f5760405162461bcd60e51b81526004016108b890612ecf565b611f5a838383610a5e565b611f65600082611df2565b6001600160a01b0383166000908152600160205260409020611f87908261216c565b506001600160a01b0382166000908152600160205260409020611faa9082612178565b50611fb760028284612184565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000610e39838361219a565b600080808061201986866121f3565b9097909650945050505050565b8051611dee906009906020840190612793565b6000611ee8848484612263565b612051848484611ef0565b61205d848484846122da565b61153c5760405162461bcd60e51b81526004016108b890612dd2565b6000610e3983836123b9565b600081815b84518110156110605760008582815181106120b557634e487b7160e01b600052603260045260246000fd5b602002602001015190508083116120f65782816040516020016120d9929190612c35565b604051602081830303815290604052805190602001209250612122565b8083604051602001612109929190612c35565b6040516020818303038152906040528051906020012092505b508061212d816136dc565b91505061208a565b61213f83836123d1565b61214c60008484846122da565b610a5e5760405162461bcd60e51b81526004016108b890612dd2565b5490565b6000610e398383612495565b6000610e3983836125b2565b6000611ee884846001600160a01b0385166125fc565b815460009082106121bd5760405162461bcd60e51b81526004016108b890612d22565b8260000182815481106121e057634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b8154600090819083106122185760405162461bcd60e51b81526004016108b890613246565b600084600001848154811061223d57634e487b7160e01b600052603260045260246000fd5b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816122935760405162461bcd60e51b81526004016108b89190612d0f565b50846122a060018361365e565b815481106122be57634e487b7160e01b600052603260045260246000fd5b9060005260206000209060020201600101549150509392505050565b60006122ee846001600160a01b03166126ab565b6122fa57506001611ee8565b6000612382630a85bd0160e11b61230f611c72565b8887876040516024016123259493929190612ca5565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505060405180606001604052806032815260200161377c603291396001600160a01b03881691906126b1565b905060008180602001905181019061239a9190612ad6565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b60009081526001919091016020526040902054151590565b6001600160a01b0382166123f75760405162461bcd60e51b81526004016108b8906132b0565b61240081611c65565b1561241d5760405162461bcd60e51b81526004016108b890612e6a565b61242960008383610a5e565b6001600160a01b038216600090815260016020526040902061244b9082612178565b5061245860028284612184565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600081815260018301602052604081205480156125a85760006124b960018361365e565b85549091506000906124cd9060019061365e565b905060008660000182815481106124f457634e487b7160e01b600052603260045260246000fd5b906000526020600020015490508087600001848154811061252557634e487b7160e01b600052603260045260246000fd5b60009182526020909120015561253c8360016135ee565b6000828152600189016020526040902055865487908061256c57634e487b7160e01b600052603160045260246000fd5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610e3c565b6000915050610e3c565b60006125be83836123b9565b6125f457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610e3c565b506000610e3c565b600082815260018401602052604081205480612661575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055611dcd565b828561266e60018461365e565b8154811061268c57634e487b7160e01b600052603260045260246000fd5b9060005260206000209060020201600101819055506000915050611dcd565b3b151590565b6060611ee88484600085856126c5856126ab565b6126e15760405162461bcd60e51b81526004016108b8906134e8565b600080866001600160a01b031685876040516126fd9190612c43565b60006040518083038185875af1925050503d806000811461273a576040519150601f19603f3d011682016040523d82523d6000602084013e61273f565b606091505b509150915061274f82828661275a565b979650505050505050565b60608315612769575081611dcd565b8251156127795782518084602001fd5b8160405162461bcd60e51b81526004016108b89190612d0f565b82805461279f906136a1565b90600052602060002090601f0160209004810192826127c15760008555612807565b82601f106127da57805160ff1916838001178555612807565b82800160010185558215612807579182015b828111156128075782518255916020019190600101906127ec565b50612813929150612817565b5090565b5b808211156128135760008155600101612818565b600067ffffffffffffffff83111561284657612846613737565b612859601f8401601f19166020016135a0565b905082815283838301111561286d57600080fd5b828260208301376000602084830101529392505050565b600060208284031215612895578081fd5b8135611dcd8161374d565b6000602082840312156128b1578081fd5b8151611dcd8161374d565b600080604083850312156128ce578081fd5b82356128d98161374d565b915060208301356128e98161374d565b809150509250929050565b600080600060608486031215612908578081fd5b83356129138161374d565b925060208401356129238161374d565b929592945050506040919091013590565b60008060008060808587031215612949578081fd5b84356129548161374d565b935060208501356129648161374d565b925060408501359150606085013567ffffffffffffffff811115612986578182fd5b8501601f81018713612996578182fd5b6129a58782356020840161282c565b91505092959194509250565b600080604083850312156129c3578182fd5b82356129ce8161374d565b9150602083013580151581146128e9578182fd5b600080604083850312156129f4578182fd5b82356129ff8161374d565b946020939093013593505050565b60006020808385031215612a1f578182fd5b823567ffffffffffffffff811115612a35578283fd5b8301601f81018513612a45578283fd5b8035612a58612a53826135ca565b6135a0565b8181528381019083850185840285018601891015612a74578687fd5b8694505b83851015612a96578035835260019490940193918501918501612a78565b50979650505050505050565b600060208284031215612ab3578081fd5b5035919050565b600060208284031215612acb578081fd5b8135611dcd81613765565b600060208284031215612ae7578081fd5b8151611dcd81613765565b600060208284031215612b03578081fd5b813567ffffffffffffffff811115612b19578182fd5b8201601f81018413612b29578182fd5b611ee88482356020840161282c565b600060208284031215612b49578081fd5b5051919050565b60008060408385031215612b62578182fd5b8235915060208084013567ffffffffffffffff811115612b80578283fd5b8401601f81018613612b90578283fd5b8035612b9e612a53826135ca565b81815283810190838501858402850186018a1015612bba578687fd5b8694505b83851015612bdc578035835260019490940193918501918501612bbe565b5080955050505050509250929050565b60008151808452612c04816020860160208601613675565b601f01601f19169290920160200192915050565b60609190911b6bffffffffffffffffffffffff1916815260140190565b918252602082015260400190565b60008251612c55818460208701613675565b9190910192915050565b60008351612c71818460208801613675565b835190830190612c85818360208801613675565b01949350505050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612cd890830184612bec565b9695505050505050565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b90815260200190565b600060208252610e396020830184612bec565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b60208082526019908201527f5265736572766520657863656564206d617820737570706c7900000000000000604082015260600190565b6020808252601a908201527f436f6e74726163742077616c6c657420646973616c6c6f776564000000000000604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b6020808252601490820152734261736555524920756e6368616e676561626c6560601b604082015260600190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b60208082526023908201527f596f7520617265206e6f7420746865206f776e6572206f662074686520746f6b60408201526232b71760e91b606082015260800190565b602080825260159082015274151bdad95b88185b1c9958591e4818db185a5b5959605a1b604082015260600190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252601390820152722737ba103a3432903a37b5b2b71037bbb732b960691b604082015260600190565b6020808252600f908201526e53616c65206e6f742061637469766560881b604082015260600190565b60208082526038908201527f57696c6c2072756e206f7574206f66206761732c20706c6561736520636c616960408201527f6d206d6178696d756d206f66203230206174206f6e63652e0000000000000000606082015260800190565b6020808252601b908201527f596f752068617665206e6f20326420617374726f6761746f72732e0000000000604082015260600190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252600f908201526e139bdd081dda1a5d195b1a5cdd1959608a1b604082015260600190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252600b908201526a105b1c9958591e481cd95d60aa1b604082015260600190565b6020808252600e908201526d323020746f6b656e73206f6e636560901b604082015260600190565b6020808252601a908201527f45746865722076616c75652073656e7420696e636f7272656374000000000000604082015260600190565b60208082526022908201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252600e908201526d105b1c9958591e481b1bd8dad95960921b604082015260600190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b6020808252602f908201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60408201526e3732bc34b9ba32b73a103a37b5b2b760891b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b6020808252600790820152661b9bdd081e595d60ca1b604082015260600190565b6020808252601a908201527f507572636861736520657863656564206d617820737570706c79000000000000604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b60208082526034908201527f57696c6c2072756e206f7574206f66206761732c20706c65617365207573652060408201527331b630b4b6a13ca634b9ba1034b739ba32b0b21760611b606082015260800190565b602080825260139082015272546f6b656e496420756e636c61696d61626c6560681b604082015260600190565b60405181810167ffffffffffffffff811182821017156135c2576135c2613737565b604052919050565b600067ffffffffffffffff8211156135e4576135e4613737565b5060209081020190565b600082198211156136015761360161370b565b500190565b600060ff821660ff84168060ff038211156136235761362361370b565b019392505050565b60008261363a5761363a613721565b500490565b60008160001904831182151516156136595761365961370b565b500290565b6000828210156136705761367061370b565b500390565b60005b83811015613690578181015183820152602001613678565b8381111561153c5750506000910152565b6002810460018216806136b557607f821691505b602082108114156136d657634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156136f0576136f061370b565b5060010190565b60008261370657613706613721565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461376257600080fd5b50565b6001600160e01b03198116811461376257600080fdfe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e68747470733a2f2f617374726f6761746f722e6d7970696e6174612e636c6f75642f697066732f516d6554714b654b746a4b543636596d62684e4a65396a38424431646568347633715a4c5a473839687a3972346f2f626c696e64626f78a26469706673582212204c0df92dbbf36555195a76f71ea6a01ec4689fe82a402de6ee4df92e642ea5ee64736f6c63430008000033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000009d03e845a08cce64e2bbf38d8c42f7dccc533a160000000000000000000000002af743179e9d464c9bd687e90bc18f5ea146950f

-----Decoded View---------------
Arg [0] : maxNftSupply (uint256): 3000
Arg [1] : fundReceiver (address): 0x9d03E845A08CcE64E2BBF38D8C42F7dCcC533a16
Arg [2] : astro2dContractAddress (address): 0x2aF743179e9d464c9BD687E90bc18f5ea146950F

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000bb8
Arg [1] : 0000000000000000000000009d03e845a08cce64e2bbf38d8c42f7dccc533a16
Arg [2] : 0000000000000000000000002af743179e9d464c9bd687e90bc18f5ea146950f


Deployed Bytecode Sourcemap

60207:8302:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10106:150;;;;;;;;;;-1:-1:-1;10106:150:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43581:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;46367:221::-;;;;;;;;;;-1:-1:-1;46367:221:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;62707:490::-;;;;;;;;;;-1:-1:-1;62707:490:0;;;;;:::i;:::-;;:::i;:::-;;65860:283;;;;;;;;;;;;;:::i;45897:404::-;;;;;;;;;;-1:-1:-1;45897:404:0;;;;;:::i;:::-;;:::i;45375:211::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;47257:305::-;;;;;;;;;;-1:-1:-1;47257:305:0;;;;;:::i;:::-;;:::i;60554:36::-;;;;;;;;;;;;;:::i;63849:640::-;;;;;;;;;;-1:-1:-1;63849:640:0;;;;;:::i;:::-;;:::i;64939:160::-;;;;;;;;;;-1:-1:-1;64939:160:0;;;;;:::i;:::-;;:::i;45137:162::-;;;;;;;;;;-1:-1:-1;45137:162:0;;;;;:::i;:::-;;:::i;68369:137::-;;;;;;;;;;;;;:::i;60641:36::-;;;;;;;;;;;;;:::i;67820:113::-;;;;;;;;;;;;;:::i;65564:288::-;;;;;;;;;;;;;:::i;47633:151::-;;;;;;;;;;-1:-1:-1;47633:151:0;;;;;:::i;:::-;;:::i;60725:39::-;;;;;;;;;;;;;:::i;45663:172::-;;;;;;;;;;-1:-1:-1;45663:172:0;;;;;:::i;:::-;;:::i;68149:145::-;;;;;;;;;;;;;:::i;67941:200::-;;;;;;;;;;-1:-1:-1;67941:200:0;;;;;:::i;:::-;;:::i;60773:33::-;;;;;;;;;;;;;:::i;43337:177::-;;;;;;;;;;-1:-1:-1;43337:177:0;;;;;:::i;:::-;;:::i;60815:96::-;;;;;;;;;;;;;:::i;60412:47::-;;;;;;;;;;;;;:::i;44956:97::-;;;;;;;;;;;;;:::i;43054:221::-;;;;;;;;;;-1:-1:-1;43054:221:0;;;;;:::i;:::-;;:::i;58275:148::-;;;;;;;;;;;;;:::i;60513:34::-;;;;;;;;;;;;;:::i;60290:50::-;;;;;;;;;;;;;:::i;57624:87::-;;;;;;;;;;;;;:::i;43750:104::-;;;;;;;;;;;;;:::i;60597:37::-;;;;;;;;;;;;;:::i;46660:295::-;;;;;;;;;;-1:-1:-1;46660:295:0;;;;;:::i;:::-;;:::i;64550:381::-;;;;;;;;;;-1:-1:-1;64550:381:0;;;;;:::i;:::-;;:::i;65107:112::-;;;;;;;;;;-1:-1:-1;65107:112:0;;;;;:::i;:::-;;:::i;47855:285::-;;;;;;;;;;-1:-1:-1;47855:285:0;;;;;:::i;:::-;;:::i;60946:46::-;;;;;;;;;;-1:-1:-1;60946:46:0;;;;;:::i;:::-;;:::i;61762:874::-;;;;;;:::i;:::-;;:::i;60347:48::-;;;;;;;;;;;;;:::i;66151:1661::-;;;;;;;;;;-1:-1:-1;66151:1661:0;;;;;:::i;:::-;;:::i;63205:636::-;;;;;;;;;;;;;:::i;47026:164::-;;;;;;;;;;-1:-1:-1;47026:164:0;;;;;:::i;:::-;;:::i;60686:32::-;;;;;;;;;;;;;:::i;60918:19::-;;;;;;;;;;;;;:::i;60466:40::-;;;;;;;;;;;;;:::i;58578:244::-;;;;;;;;;;-1:-1:-1;58578:244:0;;;;;:::i;:::-;;:::i;61001:50::-;;;;;;;;;;;;;:::i;65273:283::-;;;;;;;;;;;;;:::i;10106:150::-;-1:-1:-1;;;;;;10215:33:0;;10191:4;10215:33;;;;;;;;;;;;;10106:150;;;;:::o;43581:100::-;43635:13;43668:5;43661:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43581:100;:::o;46367:221::-;46443:7;46471:16;46479:7;46471;:16::i;:::-;46463:73;;;;-1:-1:-1;;;46463:73:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;46556:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;46556:24:0;;46367:221::o;62707:490::-;62787:16;62806:12;:10;:12::i;:::-;62787:31;;62839:88;62858:5;62865:12;;62906:18;:7;:16;:18::i;:::-;62889:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;62879:47;;;;;;62839:18;:88::i;:::-;62831:120;;;;-1:-1:-1;;;62831:120:0;;;;;;;:::i;:::-;63006:8;-1:-1:-1;;;;;62970:44:0;:15;-1:-1:-1;;;;;62970:23:0;;62994:7;62970:32;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;62970:44:0;;62962:76;;;;-1:-1:-1;;;62962:76:0;;;;;;;:::i;:::-;63058:23;;;;:14;:23;;;;;;;;63057:24;63049:58;;;;-1:-1:-1;;;63049:58:0;;;;;;;:::i;:::-;63120:23;;;;:14;:23;;;;;:30;;-1:-1:-1;;63120:30:0;63146:4;63120:30;;;63161:28;63171:8;63135:7;63161:9;:28::i;:::-;62707:490;;;:::o;65860:283::-;57855:12;:10;:12::i;:::-;-1:-1:-1;;;;;57844:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;57844:23:0;;57836:68;;;;-1:-1:-1;;;57836:68:0;;;;;;;:::i;:::-;65934:21:::1;::::0;:26;65926:50:::1;;;;-1:-1:-1::0;;;65926:50:0::1;;;;;;;:::i;:::-;60455:4;66036:16;66051:1;66036:12;:16;:::i;:::-;66021:51;::::0;;66026:27:::1;66021:51;:::i;:::-;65997:21;:75:::0;;;66088:47:::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;;;;;;;;65860:283::o:0;45897:404::-;45978:13;45994:23;46009:7;45994:14;:23::i;:::-;45978:39;;46042:5;-1:-1:-1;;;;;46036:11:0;:2;-1:-1:-1;;;;;46036:11:0;;;46028:57;;;;-1:-1:-1;;;46028:57:0;;;;;;;:::i;:::-;46122:5;-1:-1:-1;;;;;46106:21:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;46106:21:0;;:69;;;;46131:44;46155:5;46162:12;:10;:12::i;46131:44::-;46098:161;;;;-1:-1:-1;;;46098:161:0;;;;;;;:::i;:::-;46272:21;46281:2;46285:7;46272:8;:21::i;45375:211::-;45436:7;45557:21;:12;:19;:21::i;:::-;45550:28;;45375:211;:::o;47257:305::-;47418:41;47437:12;:10;:12::i;:::-;47451:7;47418:18;:41::i;:::-;47410:103;;;;-1:-1:-1;;;47410:103:0;;;;;;;:::i;:::-;47526:28;47536:4;47542:2;47546:7;47526:9;:28::i;60554:36::-;;;;:::o;63849:640::-;63918:16;63937:12;:10;:12::i;:::-;63970;;63918:31;;-1:-1:-1;63970:17:0;63962:37;;;;-1:-1:-1;;;63962:37:0;;;;;;;:::i;:::-;64037:2;64018:9;:16;:21;64010:90;;;;-1:-1:-1;;;64010:90:0;;;;;;;:::i;:::-;64118:6;64113:369;64134:9;:16;64130:1;:20;64113:369;;;64172:16;64191:9;64201:1;64191:12;;;;;;-1:-1:-1;;;64191:12:0;;;;;;;;;;;;;;;64172:31;;64263:8;-1:-1:-1;;;;;64226:45:0;:15;-1:-1:-1;;;;;64226:23:0;;64250:8;64226:33;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;64226:45:0;;64218:93;;;;-1:-1:-1;;;64218:93:0;;;;;;;:::i;:::-;64331:24;;;;:14;:24;;;;;;;;64326:145;;64376:24;;;;:14;:24;;;;;:31;;-1:-1:-1;;64376:31:0;64403:4;64376:31;;;64426:29;64436:8;64391;64426:9;:29::i;:::-;-1:-1:-1;64152:3:0;;;;:::i;:::-;;;;64113:369;;64939:160;57855:12;:10;:12::i;:::-;-1:-1:-1;;;;;57844:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;57844:23:0;;57836:68;;;;-1:-1:-1;;;57836:68:0;;;;;;;:::i;:::-;65017:12:::1;:28:::0;;;65061:30:::1;::::0;::::1;::::0;::::1;::::0;65032:13;;65061:30:::1;:::i;:::-;;;;;;;;64939:160:::0;:::o;45137:162::-;-1:-1:-1;;;;;45261:20:0;;45234:7;45261:20;;;:13;:20;;;;;:30;;45285:5;45261:23;:30::i;:::-;45254:37;;45137:162;;;;;:::o;68369:137::-;57855:12;:10;:12::i;:::-;-1:-1:-1;;;;;57844:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;57844:23:0;;57836:68;;;;-1:-1:-1;;;57836:68:0;;;;;;;:::i;:::-;68440:12:::1;::::0;;-1:-1:-1;;68424:28:0;::::1;68440:12;::::0;;::::1;68439:13;68424:28;::::0;;;;68468:30:::1;::::0;::::1;::::0;::::1;::::0;68485:12:::1;::::0;68468:30:::1;:::i;60641:36::-:0;;;;:::o;67820:113::-;57855:12;:10;:12::i;:::-;-1:-1:-1;;;;;57844:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;57844:23:0;;57836:68;;;;-1:-1:-1;;;57836:68:0;;;;;;;:::i;:::-;67878:8:::1;-1:-1:-1::0;;;;;67870:22:0::1;67899:21;67870:55;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65564:288:::0;57855:12;:10;:12::i;:::-;-1:-1:-1;;;;;57844:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;57844:23:0;;57836:68;;;;-1:-1:-1;;;57836:68:0;;;;;;;:::i;:::-;65639:22:::1;::::0;:27;65631:51:::1;;;;-1:-1:-1::0;;;65631:51:0::1;;;;;;;:::i;:::-;60455:4;65743:16;65758:1;65743:12;:16;:::i;:::-;65728:51;::::0;;65733:27:::1;65728:51;:::i;:::-;65703:22;:76:::0;;;65795:49:::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;47633:151::-:0;47737:39;47754:4;47760:2;47764:7;47737:39;;;;;;;;;;;;:16;:39::i;60725:::-;;;;;;;;;:::o;45663:172::-;45738:7;;45780:22;:12;45796:5;45780:15;:22::i;:::-;-1:-1:-1;45758:44:0;45663:172;-1:-1:-1;;;45663:172:0:o;68149:145::-;57855:12;:10;:12::i;:::-;-1:-1:-1;;;;;57844:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;57844:23:0;;57836:68;;;;-1:-1:-1;;;57836:68:0;;;;;;;:::i;:::-;68211:19:::1;::::0;::::1;::::0;::::1;;;68210:20;68202:47;;;;-1:-1:-1::0;;;68202:47:0::1;;;;;;;:::i;:::-;68260:19;:26:::0;;-1:-1:-1;;68260:26:0::1;;;::::0;;68149:145::o;67941:200::-;57855:12;:10;:12::i;:::-;-1:-1:-1;;;;;57844:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;57844:23:0;;57836:68;;;;-1:-1:-1;;;57836:68:0;;;;;;;:::i;:::-;68023:19:::1;::::0;::::1;::::0;::::1;;;68022:20;68014:53;;;;-1:-1:-1::0;;;68014:53:0::1;;;;;;;:::i;:::-;68078:20;68090:7;68078:11;:20::i;:::-;68114:19;68125:7;68114:19;;;;;;:::i;60773:33::-:0;;;:::o;43337:177::-;43409:7;43436:70;43453:7;43436:70;;;;;;;;;;;;;;;;;:12;;:70;:16;:70::i;60815:96::-;;;;:::o;60412:47::-;60455:4;60412:47;:::o;44956:97::-;45004:13;45037:8;45030:15;;;;;:::i;43054:221::-;43126:7;-1:-1:-1;;;;;43154:19:0;;43146:74;;;;-1:-1:-1;;;43146:74:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;43238:20:0;;;;;;:13;:20;;;;;:29;;:27;:29::i;58275:148::-;57855:12;:10;:12::i;:::-;-1:-1:-1;;;;;57844:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;57844:23:0;;57836:68;;;;-1:-1:-1;;;57836:68:0;;;;;;;:::i;:::-;58366:6:::1;::::0;58345:40:::1;::::0;58382:1:::1;::::0;-1:-1:-1;;;;;58366:6:0::1;::::0;58345:40:::1;::::0;58382:1;;58345:40:::1;58396:6;:19:::0;;-1:-1:-1;;;;;;58396:19:0::1;::::0;;58275:148::o;60513:34::-;;;;:::o;60290:50::-;60338:2;60290:50;:::o;57624:87::-;57697:6;;-1:-1:-1;;;;;57697:6:0;57624:87;:::o;43750:104::-;43806:13;43839:7;43832:14;;;;;:::i;60597:37::-;;;;:::o;46660:295::-;46775:12;:10;:12::i;:::-;-1:-1:-1;;;;;46763:24:0;:8;-1:-1:-1;;;;;46763:24:0;;;46755:62;;;;-1:-1:-1;;;46755:62:0;;;;;;;:::i;:::-;46875:8;46830:18;:32;46849:12;:10;:12::i;:::-;-1:-1:-1;;;;;46830:32:0;;;;;;;;;;;;;;;;;-1:-1:-1;46830:32:0;;;:42;;;;;;;;;;;;:53;;-1:-1:-1;;46830:53:0;;;;;;;;;;;46914:12;:10;:12::i;:::-;-1:-1:-1;;;;;46899:48:0;;46938:8;46899:48;;;;;;:::i;:::-;;;;;;;;46660:295;;:::o;64550:381::-;57855:12;:10;:12::i;:::-;-1:-1:-1;;;;;57844:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;57844:23:0;;57836:68;;;;-1:-1:-1;;;57836:68:0;;;;;;;:::i;:::-;64652:11:::1;::::0;64715:15:::1;64682:29;64652:11:::0;64682:14;:29:::1;:::i;:::-;:48;;64674:86;;;;-1:-1:-1::0;;;64674:86:0::1;;;;;;;:::i;:::-;64788:14;64773:11;;:29;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;64819:6:0::1;::::0;-1:-1:-1;64815:109:0::1;64835:14;64831:1;:18;64815:109;;;64871:41;64881:12;:10;:12::i;:::-;64895:16;64910:1:::0;64895:12;:16:::1;:::i;:::-;64871:9;:41::i;:::-;64851:3:::0;::::1;::::0;::::1;:::i;:::-;;;;64815:109;;65107:112:::0;57855:12;:10;:12::i;:::-;-1:-1:-1;;;;;57844:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;57844:23:0;;57836:68;;;;-1:-1:-1;;;57836:68:0;;;;;;;:::i;:::-;65169:4:::1;:12:::0;;;65197:14:::1;::::0;::::1;::::0;::::1;::::0;65176:5;;65197:14:::1;:::i;47855:285::-:0;47987:41;48006:12;:10;:12::i;:::-;48020:7;47987:18;:41::i;:::-;47979:103;;;;-1:-1:-1;;;47979:103:0;;;;;;;:::i;:::-;48093:39;48107:4;48113:2;48117:7;48126:5;48093:13;:39::i;:::-;47855:285;;;;:::o;60946:46::-;;;;;;;;;;;;;;;:::o;61762:874::-;61849:16;61868:12;:10;:12::i;:::-;61914:11;;61849:31;;-1:-1:-1;;;;;;61946:21:0;;61958:9;61946:21;61938:60;;;;-1:-1:-1;;;61938:60:0;;;;;;;:::i;:::-;62017:12;;;;62009:40;;;;-1:-1:-1;;;62009:40:0;;;;;;;:::i;:::-;60338:2;62068:14;:39;;62060:66;;;;-1:-1:-1;;;62060:66:0;;;;;;;:::i;:::-;62178:15;62145:29;62162:12;62145:14;:29;:::i;:::-;:48;;62137:87;;;;-1:-1:-1;;;62137:87:0;;;;;;;:::i;:::-;62279:9;62243:32;62261:14;60389:6;62243:32;:::i;:::-;:45;62235:84;;;;-1:-1:-1;;;62235:84:0;;;;;;;:::i;:::-;62334:4;;:9;62330:140;;62368:70;62387:5;62394:4;;62427:8;62410:26;;;;;;;;:::i;62368:70::-;62360:98;;;;-1:-1:-1;;;62360:98:0;;;;;;;:::i;:::-;62497:14;62482:11;;:29;;;;;;;:::i;:::-;;;;-1:-1:-1;62528:6:0;;-1:-1:-1;62524:105:0;62544:14;62540:1;:18;62524:105;;;62580:37;62590:8;62600:16;62615:1;62600:12;:16;:::i;62580:37::-;62560:3;;;;:::i;:::-;;;;62524:105;;;;61762:874;;;;:::o;60347:48::-;60389:6;60347:48;:::o;66151:1661::-;66224:13;66258:16;66266:7;66258;:16::i;:::-;66250:76;;;;-1:-1:-1;;;66250:76:0;;;;;;;:::i;:::-;66339:18;66360:9;:7;:9::i;:::-;66339:30;;66380:25;:124;;;;;;;;;;;;;;;;;;-1:-1:-1;60455:4:0;66585:5;66575:15;;66571:105;;;66638:4;66644:18;:7;:16;:18::i;:::-;66621:42;;;;;;;;;:::i;:::-;;;;;;;;;;;;;66607:57;;;;;;;66571:105;66745:21;;:26;;;;:45;;;66785:5;66775:7;:15;66745:45;66741:281;;;66808:11;66832:21;;66822:7;:31;;;;:::i;:::-;66808:45;;66878:5;66872:3;:11;66868:75;;;66904:23;66911:16;66904:23;;:::i;:::-;;;66868:75;66988:4;66994:14;:3;:12;:14::i;:::-;66971:38;;;;;;;;;:::i;:::-;;;;;;;;;;;;;66957:53;;;;;;;;66741:281;67098:22;;:27;;;;:46;;;67139:5;67129:7;:15;67098:46;67094:282;;;67161:11;67185:22;;67175:7;:32;;;;:::i;:::-;67161:46;;67232:5;67226:3;:11;67222:75;;;67258:23;67265:16;67258:23;;:::i;67094:282::-;67451:21;;:26;67447:272;;67494:11;67518:21;;67508:7;:31;;;;:::i;:::-;67494:45;;67565:15;67558:3;:22;67554:86;;67601:23;67608:16;67601:23;;:::i;63205:636::-;63245:16;63264:12;:10;:12::i;:::-;63297;;63245:31;;-1:-1:-1;63297:17:0;63289:37;;;;-1:-1:-1;;;63289:37:0;;;;;;;:::i;:::-;63352:35;;-1:-1:-1;;;63352:35:0;;63337:12;;-1:-1:-1;;;;;63352:15:0;:25;;;;:35;;63378:8;;63352:35;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63337:50;;63416:1;63406:7;:11;63398:51;;;;-1:-1:-1;;;63398:51:0;;;;;;;:::i;:::-;63478:2;63468:7;:12;63460:77;;;;-1:-1:-1;;;63460:77:0;;;;;;;:::i;:::-;63555:6;63550:284;63571:7;63567:1;:11;63550:284;;;63618:48;;-1:-1:-1;;;63618:48:0;;63600:15;;-1:-1:-1;;;;;63618:15:0;:35;;;;:48;;63654:8;;63664:1;;63618:48;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63686:23;;;;:14;:23;;;;;;63600:66;;-1:-1:-1;63686:23:0;;63681:142;;63730:23;;;;:14;:23;;;;;:30;;-1:-1:-1;;63730:30:0;63756:4;63730:30;;;63779:28;63789:8;63745:7;63779:9;:28::i;:::-;-1:-1:-1;63580:3:0;;;;:::i;:::-;;;;63550:284;;47026:164;-1:-1:-1;;;;;47147:25:0;;;47123:4;47147:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;47026:164::o;60686:32::-;;;;;;:::o;60918:19::-;;;;:::o;60466:40::-;;;:::o;58578:244::-;57855:12;:10;:12::i;:::-;-1:-1:-1;;;;;57844:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;57844:23:0;;57836:68;;;;-1:-1:-1;;;57836:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;58667:22:0;::::1;58659:73;;;;-1:-1:-1::0;;;58659:73:0::1;;;;;;;:::i;:::-;58769:6;::::0;58748:38:::1;::::0;-1:-1:-1;;;;;58748:38:0;;::::1;::::0;58769:6:::1;::::0;58748:38:::1;::::0;58769:6:::1;::::0;58748:38:::1;58797:6;:17:::0;;-1:-1:-1;;;;;;58797:17:0::1;-1:-1:-1::0;;;;;58797:17:0;;;::::1;::::0;;;::::1;::::0;;58578:244::o;61001:50::-;;;:::o;65273:283::-;57855:12;:10;:12::i;:::-;-1:-1:-1;;;;;57844:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;57844:23:0;;57836:68;;;;-1:-1:-1;;;57836:68:0;;;;;;;:::i;:::-;65347:21:::1;::::0;:26;65339:50:::1;;;;-1:-1:-1::0;;;65339:50:0::1;;;;;;;:::i;:::-;60455:4;65449:16;65464:1;65449:12;:16;:::i;:::-;65434:51;::::0;;65439:27:::1;65434:51;:::i;:::-;65410:21;:75:::0;;;65501:47:::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;49607:127::-:0;49672:4;49696:30;:12;49718:7;49696:21;:30::i;605:98::-;685:10;605:98;:::o;38775:573::-;38825:27;38869:7;38865:50;;-1:-1:-1;38893:10:0;;;;;;;;;;;;-1:-1:-1;;;38893:10:0;;;;;;38865:50;38934:2;38925:6;38966:69;38973:6;;38966:69;;38996:5;;;;:::i;:::-;;-1:-1:-1;39016:7:0;;-1:-1:-1;39021:2:0;39016:7;;:::i;:::-;;;38966:69;;;39045:17;39075:3;39065:14;;;;;;-1:-1:-1;;;39065:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39065:14:0;-1:-1:-1;39045:34:0;-1:-1:-1;39099:3:0;39113:198;39120:7;;39113:198;;39148:3;39150:1;39148;:3;:::i;:::-;39144:7;-1:-1:-1;39166:10:0;39196:7;39201:2;39196;:7;:::i;:::-;:12;;39206:2;39196:12;:::i;:::-;39191:17;;:2;:17;:::i;:::-;39180:29;;:2;:29;:::i;:::-;39166:44;;39225:9;39244:4;39237:12;;39225:24;;39274:2;39264:4;39269:1;39264:7;;;;;;-1:-1:-1;;;39264:7:0;;;;;;;;;;;;:12;-1:-1:-1;;;;;39264:12:0;;;;;;;;-1:-1:-1;39291:8:0;39297:2;39291:8;;:::i;:::-;;;39113:198;;;;;-1:-1:-1;39335:4:0;38775:573;-1:-1:-1;;;;38775:573:0:o;59141:190::-;59266:4;59319;59290:25;59303:5;59310:4;59290:12;:25::i;:::-;:33;59283:40;;59141:190;;;;;;:::o;50599:110::-;50675:26;50685:2;50689:7;50675:26;;;;;;;;;;;;:9;:26::i;:::-;50599:110;;:::o;55625:192::-;55700:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;55700:29:0;-1:-1:-1;;;;;55700:29:0;;;;;;;;:24;;55754:23;55700:24;55754:14;:23::i;:::-;-1:-1:-1;;;;;55745:46:0;;;;;;;;;;;55625:192;;:::o;36661:123::-;36730:7;36757:19;36765:3;36757:7;:19::i;49901:355::-;49994:4;50019:16;50027:7;50019;:16::i;:::-;50011:73;;;;-1:-1:-1;;;50011:73:0;;;;;;;:::i;:::-;50095:13;50111:23;50126:7;50111:14;:23::i;:::-;50095:39;;50164:5;-1:-1:-1;;;;;50153:16:0;:7;-1:-1:-1;;;;;50153:16:0;;:51;;;;50197:7;-1:-1:-1;;;;;50173:31:0;:20;50185:7;50173:11;:20::i;:::-;-1:-1:-1;;;;;50173:31:0;;50153:51;:94;;;;50208:39;50232:5;50239:7;50208:23;:39::i;:::-;50145:103;49901:355;-1:-1:-1;;;;49901:355:0:o;53037:599::-;53162:4;-1:-1:-1;;;;;53135:31:0;:23;53150:7;53135:14;:23::i;:::-;-1:-1:-1;;;;;53135:31:0;;53127:85;;;;-1:-1:-1;;;53127:85:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;53249:16:0;;53241:65;;;;-1:-1:-1;;;53241:65:0;;;;;;;:::i;:::-;53319:39;53340:4;53346:2;53350:7;53319:20;:39::i;:::-;53423:29;53440:1;53444:7;53423:8;:29::i;:::-;-1:-1:-1;;;;;53465:19:0;;;;;;:13;:19;;;;;:35;;53492:7;53465:26;:35::i;:::-;-1:-1:-1;;;;;;53511:17:0;;;;;;:13;:17;;;;;:30;;53533:7;53511:21;:30::i;:::-;-1:-1:-1;53554:29:0;:12;53571:7;53580:2;53554:16;:29::i;:::-;;53620:7;53616:2;-1:-1:-1;;;;;53601:27:0;53610:4;-1:-1:-1;;;;;53601:27:0;;;;;;;;;;;53037:599;;;:::o;28460:137::-;28531:7;28566:22;28570:3;28582:5;28566:3;:22::i;37123:236::-;37203:7;;;;37263:22;37267:3;37279:5;37263:3;:22::i;:::-;37232:53;;;;-1:-1:-1;37123:236:0;-1:-1:-1;;;;;37123:236:0:o;54237:100::-;54310:19;;;;:8;;:19;;;;;:::i;38409:213::-;38516:7;38567:44;38572:3;38592;38598:12;38567:4;:44::i;49022:272::-;49136:28;49146:4;49152:2;49156:7;49136:9;:28::i;:::-;49183:48;49206:4;49212:2;49216:7;49225:5;49183:22;:48::i;:::-;49175:111;;;;-1:-1:-1;;;49175:111:0;;;;;;;:::i;36422:151::-;36506:4;36530:35;36540:3;36560;36530:9;:35::i;59345:701::-;59428:7;59471:4;59428:7;59486:523;59510:5;:12;59506:1;:16;59486:523;;;59544:20;59567:5;59573:1;59567:8;;;;;;-1:-1:-1;;;59567:8:0;;;;;;;;;;;;;;;59544:31;;59610:12;59594;:28;59590:408;;59764:12;59778;59747:44;;;;;;;;;:::i;:::-;;;;;;;;;;;;;59737:55;;;;;;59722:70;;59590:408;;;59954:12;59968;59937:44;;;;;;;;;:::i;:::-;;;;;;;;;;;;;59927:55;;;;;;59912:70;;59590:408;-1:-1:-1;59524:3:0;;;;:::i;:::-;;;;59486:523;;50936:250;51032:18;51038:2;51042:7;51032:5;:18::i;:::-;51069:54;51100:1;51104:2;51108:7;51117:5;51069:22;:54::i;:::-;51061:117;;;;-1:-1:-1;;;51061:117:0;;;;;;;:::i;33240:110::-;33323:19;;33240:110::o;27547:137::-;27617:4;27641:35;27649:3;27669:5;27641:7;:35::i;27240:131::-;27307:4;27331:32;27336:3;27356:5;27331:4;:32::i;35845:185::-;35934:4;35958:64;35963:3;35983;-1:-1:-1;;;;;35997:23:0;;35958:4;:64::i;23498:204::-;23593:18;;23565:7;;23593:26;-1:-1:-1;23585:73:0;;;;-1:-1:-1;;;23585:73:0;;;;;;;:::i;:::-;23676:3;:11;;23688:5;23676:18;;;;;;-1:-1:-1;;;23676:18:0;;;;;;;;;;;;;;;;;23669:25;;23498:204;;;;:::o;33705:279::-;33809:19;;33772:7;;;;33809:27;-1:-1:-1;33801:74:0;;;;-1:-1:-1;;;33801:74:0;;;;;;;:::i;:::-;33888:22;33913:3;:12;;33926:5;33913:19;;;;;;-1:-1:-1;;;33913:19:0;;;;;;;;;;;;;;;;;;;33888:44;;33951:5;:10;;;33963:5;:12;;;33943:33;;;;;33705:279;;;;;:::o;35202:319::-;35296:7;35335:17;;;:12;;;:17;;;;;;35386:12;35371:13;35363:36;;;;-1:-1:-1;;;35363:36:0;;;;;;;;:::i;:::-;-1:-1:-1;35453:3:0;35466:12;35477:1;35466:8;:12;:::i;:::-;35453:26;;;;;;-1:-1:-1;;;35453:26:0;;;;;;;;;;;;;;;;;;;:33;;;35446:40;;;35202:319;;;;;:::o;54902:604::-;55023:4;55050:15;:2;-1:-1:-1;;;;;55050:13:0;;:15::i;:::-;55045:60;;-1:-1:-1;55089:4:0;55082:11;;55045:60;55115:23;55141:252;-1:-1:-1;;;55254:12:0;:10;:12::i;:::-;55281:4;55300:7;55322:5;55157:181;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;55157:181:0;;;;;;;-1:-1:-1;;;;;55157:181:0;;;;;;;;;;;55141:252;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;55141:15:0;;;:252;:15;:252::i;:::-;55115:278;;55404:13;55431:10;55420:32;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;55471:26:0;-1:-1:-1;;;55471:26:0;;-1:-1:-1;;;54902:604:0;;;;;;:::o;33020:125::-;33091:4;33115:17;;;:12;;;;;:17;;;;;;:22;;;33020:125::o;51522:404::-;-1:-1:-1;;;;;51602:16:0;;51594:61;;;;-1:-1:-1;;;51594:61:0;;;;;;;:::i;:::-;51675:16;51683:7;51675;:16::i;:::-;51674:17;51666:58;;;;-1:-1:-1;;;51666:58:0;;;;;;;:::i;:::-;51737:45;51766:1;51770:2;51774:7;51737:20;:45::i;:::-;-1:-1:-1;;;;;51795:17:0;;;;;;:13;:17;;;;;:30;;51817:7;51795:21;:30::i;:::-;-1:-1:-1;51838:29:0;:12;51855:7;51864:2;51838:16;:29::i;:::-;-1:-1:-1;51885:33:0;;51910:7;;-1:-1:-1;;;;;51885:33:0;;;51902:1;;51885:33;;51902:1;;51885:33;51522:404;;:::o;21200:1544::-;21266:4;21405:19;;;:12;;;:19;;;;;;21441:15;;21437:1300;;21803:21;21827:14;21840:1;21827:10;:14;:::i;:::-;21876:18;;21803:38;;-1:-1:-1;21856:17:0;;21876:22;;21897:1;;21876:22;:::i;:::-;21856:42;;22143:17;22163:3;:11;;22175:9;22163:22;;;;;;-1:-1:-1;;;22163:22:0;;;;;;;;;;;;;;;;;22143:42;;22309:9;22280:3;:11;;22292:13;22280:26;;;;;;-1:-1:-1;;;22280:26:0;;;;;;;;;;;;;;;;;;:38;22412:17;:13;22428:1;22412:17;:::i;:::-;22386:23;;;;:12;;;:23;;;;;:43;22538:17;;22386:3;;22538:17;;;-1:-1:-1;;;22538:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;22633:3;:12;;:19;22646:5;22633:19;;;;;;;;;;;22626:26;;;22676:4;22669:11;;;;;;;;21437:1300;22720:5;22713:12;;;;;20610:414;20673:4;20695:21;20705:3;20710:5;20695:9;:21::i;:::-;20690:327;;-1:-1:-1;20733:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;20916:18;;20894:19;;;:12;;;:19;;;;;;:40;;;;20949:11;;20690:327;-1:-1:-1;21000:5:0;20993:12;;30520:692;30596:4;30731:17;;;:12;;;:17;;;;;;30765:13;30761:444;;-1:-1:-1;;30850:38:0;;;;;;;;;;;;;;;;;;30832:57;;;;;;;;:12;:57;;;;;;;;;;;;;;;;;;;;;;;;31047:19;;31027:17;;;:12;;;:17;;;;;;;:39;31081:11;;30761:444;31161:5;31125:3;31138:12;31149:1;31138:8;:12;:::i;:::-;31125:26;;;;;;-1:-1:-1;;;31125:26:0;;;;;;;;;;;;;;;;;;;:33;;:41;;;;31188:5;31181:12;;;;;11637:422;12004:20;12043:8;;;11637:422::o;14555:195::-;14658:12;14690:52;14712:6;14720:4;14726:1;14729:12;14658;15859:18;15870:6;15859:10;:18::i;:::-;15851:60;;;;-1:-1:-1;;;15851:60:0;;;;;;;:::i;:::-;15985:12;15999:23;16026:6;-1:-1:-1;;;;;16026:11:0;16046:5;16054:4;16026:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15984:75;;;;16077:52;16095:7;16104:10;16116:12;16077:17;:52::i;:::-;16070:59;15607:530;-1:-1:-1;;;;;;;15607:530:0:o;18147:742::-;18262:12;18291:7;18287:595;;;-1:-1:-1;18322:10:0;18315:17;;18287:595;18436:17;;:21;18432:439;;18699:10;18693:17;18760:15;18747:10;18743:2;18739:19;18732:44;18647:148;18842:12;18835:20;;-1:-1:-1;;;18835:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:409:1;;114:18;106:6;103:30;100:2;;;136:18;;:::i;:::-;174:58;220:2;197:17;;-1:-1:-1;;193:31:1;226:4;189:42;174:58;:::i;:::-;165:67;;255:6;248:5;241:21;295:3;286:6;281:3;277:16;274:25;271:2;;;312:1;309;302:12;271:2;361:6;356:3;349:4;342:5;338:16;325:43;415:1;408:4;399:6;392:5;388:18;384:29;377:40;90:333;;;;;:::o;428:259::-;;540:2;528:9;519:7;515:23;511:32;508:2;;;561:6;553;546:22;508:2;605:9;592:23;624:33;651:5;624:33;:::i;692:263::-;;815:2;803:9;794:7;790:23;786:32;783:2;;;836:6;828;821:22;783:2;873:9;867:16;892:33;919:5;892:33;:::i;960:402::-;;;1089:2;1077:9;1068:7;1064:23;1060:32;1057:2;;;1110:6;1102;1095:22;1057:2;1154:9;1141:23;1173:33;1200:5;1173:33;:::i;:::-;1225:5;-1:-1:-1;1282:2:1;1267:18;;1254:32;1295:35;1254:32;1295:35;:::i;:::-;1349:7;1339:17;;;1047:315;;;;;:::o;1367:470::-;;;;1513:2;1501:9;1492:7;1488:23;1484:32;1481:2;;;1534:6;1526;1519:22;1481:2;1578:9;1565:23;1597:33;1624:5;1597:33;:::i;:::-;1649:5;-1:-1:-1;1706:2:1;1691:18;;1678:32;1719:35;1678:32;1719:35;:::i;:::-;1471:366;;1773:7;;-1:-1:-1;;;1827:2:1;1812:18;;;;1799:32;;1471:366::o;1842:830::-;;;;;2014:3;2002:9;1993:7;1989:23;1985:33;1982:2;;;2036:6;2028;2021:22;1982:2;2080:9;2067:23;2099:33;2126:5;2099:33;:::i;:::-;2151:5;-1:-1:-1;2208:2:1;2193:18;;2180:32;2221:35;2180:32;2221:35;:::i;:::-;2275:7;-1:-1:-1;2329:2:1;2314:18;;2301:32;;-1:-1:-1;2384:2:1;2369:18;;2356:32;2411:18;2400:30;;2397:2;;;2448:6;2440;2433:22;2397:2;2476:22;;2529:4;2521:13;;2517:27;-1:-1:-1;2507:2:1;;2563:6;2555;2548:22;2507:2;2591:75;2658:7;2653:2;2640:16;2635:2;2631;2627:11;2591:75;:::i;:::-;2581:85;;;1972:700;;;;;;;:::o;2677:438::-;;;2803:2;2791:9;2782:7;2778:23;2774:32;2771:2;;;2824:6;2816;2809:22;2771:2;2868:9;2855:23;2887:33;2914:5;2887:33;:::i;:::-;2939:5;-1:-1:-1;2996:2:1;2981:18;;2968:32;3038:15;;3031:23;3019:36;;3009:2;;3074:6;3066;3059:22;3120:327;;;3249:2;3237:9;3228:7;3224:23;3220:32;3217:2;;;3270:6;3262;3255:22;3217:2;3314:9;3301:23;3333:33;3360:5;3333:33;:::i;:::-;3385:5;3437:2;3422:18;;;;3409:32;;-1:-1:-1;;;3207:240:1:o;3452:953::-;;3567:2;3610;3598:9;3589:7;3585:23;3581:32;3578:2;;;3631:6;3623;3616:22;3578:2;3676:9;3663:23;3709:18;3701:6;3698:30;3695:2;;;3746:6;3738;3731:22;3695:2;3774:22;;3827:4;3819:13;;3815:27;-1:-1:-1;3805:2:1;;3861:6;3853;3846:22;3805:2;3902;3889:16;3925:65;3940:49;3986:2;3940:49;:::i;:::-;3925:65;:::i;:::-;4024:15;;;4055:12;;;;4087:11;;;4125;;;4117:20;;4113:29;;4110:42;-1:-1:-1;4107:2:1;;;4170:6;4162;4155:22;4107:2;4197:6;4188:15;;4212:163;4226:2;4223:1;4220:9;4212:163;;;4283:17;;4271:30;;4244:1;4237:9;;;;;4321:12;;;;4353;;4212:163;;;-1:-1:-1;4394:5:1;3547:858;-1:-1:-1;;;;;;;3547:858:1:o;4410:190::-;;4522:2;4510:9;4501:7;4497:23;4493:32;4490:2;;;4543:6;4535;4528:22;4490:2;-1:-1:-1;4571:23:1;;4480:120;-1:-1:-1;4480:120:1:o;4605:257::-;;4716:2;4704:9;4695:7;4691:23;4687:32;4684:2;;;4737:6;4729;4722:22;4684:2;4781:9;4768:23;4800:32;4826:5;4800:32;:::i;4867:261::-;;4989:2;4977:9;4968:7;4964:23;4960:32;4957:2;;;5010:6;5002;4995:22;4957:2;5047:9;5041:16;5066:32;5092:5;5066:32;:::i;5133:482::-;;5255:2;5243:9;5234:7;5230:23;5226:32;5223:2;;;5276:6;5268;5261:22;5223:2;5321:9;5308:23;5354:18;5346:6;5343:30;5340:2;;;5391:6;5383;5376:22;5340:2;5419:22;;5472:4;5464:13;;5460:27;-1:-1:-1;5450:2:1;;5506:6;5498;5491:22;5450:2;5534:75;5601:7;5596:2;5583:16;5578:2;5574;5570:11;5534:75;:::i;5815:194::-;;5938:2;5926:9;5917:7;5913:23;5909:32;5906:2;;;5959:6;5951;5944:22;5906:2;-1:-1:-1;5987:16:1;;5896:113;-1:-1:-1;5896:113:1:o;6014:1021::-;;;6168:2;6156:9;6147:7;6143:23;6139:32;6136:2;;;6189:6;6181;6174:22;6136:2;6230:9;6217:23;6207:33;;6259:2;6312;6301:9;6297:18;6284:32;6339:18;6331:6;6328:30;6325:2;;;6376:6;6368;6361:22;6325:2;6404:22;;6457:4;6449:13;;6445:27;-1:-1:-1;6435:2:1;;6491:6;6483;6476:22;6435:2;6532;6519:16;6555:65;6570:49;6616:2;6570:49;:::i;6555:65::-;6654:15;;;6685:12;;;;6717:11;;;6755;;;6747:20;;6743:29;;6740:42;-1:-1:-1;6737:2:1;;;6800:6;6792;6785:22;6737:2;6827:6;6818:15;;6842:163;6856:2;6853:1;6850:9;6842:163;;;6913:17;;6901:30;;6874:1;6867:9;;;;;6951:12;;;;6983;;6842:163;;;6846:3;7024:5;7014:15;;;;;;;6126:909;;;;;:::o;7040:259::-;;7121:5;7115:12;7148:6;7143:3;7136:19;7164:63;7220:6;7213:4;7208:3;7204:14;7197:4;7190:5;7186:16;7164:63;:::i;:::-;7281:2;7260:15;-1:-1:-1;;7256:29:1;7247:39;;;;7288:4;7243:50;;7091:208;-1:-1:-1;;7091:208:1:o;7304:229::-;7453:2;7449:15;;;;-1:-1:-1;;7445:53:1;7433:66;;7524:2;7515:12;;7423:110::o;7538:247::-;7695:19;;;7739:2;7730:12;;7723:28;7776:2;7767:12;;7685:100::o;7790:274::-;;7957:6;7951:13;7973:53;8019:6;8014:3;8007:4;7999:6;7995:17;7973:53;:::i;:::-;8042:16;;;;;7927:137;-1:-1:-1;;7927:137:1:o;8350:470::-;;8567:6;8561:13;8583:53;8629:6;8624:3;8617:4;8609:6;8605:17;8583:53;:::i;:::-;8699:13;;8658:16;;;;8721:57;8699:13;8658:16;8755:4;8743:17;;8721:57;:::i;:::-;8794:20;;8537:283;-1:-1:-1;;;;8537:283:1:o;8825:205::-;9025:3;9016:14::o;9035:203::-;-1:-1:-1;;;;;9199:32:1;;;;9181:51;;9169:2;9154:18;;9136:102::o;9243:490::-;-1:-1:-1;;;;;9512:15:1;;;9494:34;;9564:15;;9559:2;9544:18;;9537:43;9611:2;9596:18;;9589:34;;;9659:3;9654:2;9639:18;;9632:31;;;9243:490;;9680:47;;9707:19;;9699:6;9680:47;:::i;:::-;9672:55;9446:287;-1:-1:-1;;;;;;9446:287:1:o;9738:274::-;-1:-1:-1;;;;;9930:32:1;;;;9912:51;;9994:2;9979:18;;9972:34;9900:2;9885:18;;9867:145::o;10017:187::-;10182:14;;10175:22;10157:41;;10145:2;10130:18;;10112:92::o;10209:177::-;10355:25;;;10343:2;10328:18;;10310:76::o;10625:221::-;;10774:2;10763:9;10756:21;10794:46;10836:2;10825:9;10821:18;10813:6;10794:46;:::i;10851:398::-;11053:2;11035:21;;;11092:2;11072:18;;;11065:30;11131:34;11126:2;11111:18;;11104:62;-1:-1:-1;;;11197:2:1;11182:18;;11175:32;11239:3;11224:19;;11025:224::o;11254:349::-;11456:2;11438:21;;;11495:2;11475:18;;;11468:30;11534:27;11529:2;11514:18;;11507:55;11594:2;11579:18;;11428:175::o;11608:350::-;11810:2;11792:21;;;11849:2;11829:18;;;11822:30;11888:28;11883:2;11868:18;;11861:56;11949:2;11934:18;;11782:176::o;11963:414::-;12165:2;12147:21;;;12204:2;12184:18;;;12177:30;12243:34;12238:2;12223:18;;12216:62;-1:-1:-1;;;12309:2:1;12294:18;;12287:48;12367:3;12352:19;;12137:240::o;12382:402::-;12584:2;12566:21;;;12623:2;12603:18;;;12596:30;12662:34;12657:2;12642:18;;12635:62;-1:-1:-1;;;12728:2:1;12713:18;;12706:36;12774:3;12759:19;;12556:228::o;12789:352::-;12991:2;12973:21;;;13030:2;13010:18;;;13003:30;13069;13064:2;13049:18;;13042:58;13132:2;13117:18;;12963:178::o;13146:344::-;13348:2;13330:21;;;13387:2;13367:18;;;13360:30;-1:-1:-1;;;13421:2:1;13406:18;;13399:50;13481:2;13466:18;;13320:170::o;13495:400::-;13697:2;13679:21;;;13736:2;13716:18;;;13709:30;13775:34;13770:2;13755:18;;13748:62;-1:-1:-1;;;13841:2:1;13826:18;;13819:34;13885:3;13870:19;;13669:226::o;13900:349::-;14102:2;14084:21;;;14141:2;14121:18;;;14114:30;14180:27;14175:2;14160:18;;14153:55;14240:2;14225:18;;14074:175::o;14254:399::-;14456:2;14438:21;;;14495:2;14475:18;;;14468:30;14534:34;14529:2;14514:18;;14507:62;-1:-1:-1;;;14600:2:1;14585:18;;14578:33;14643:3;14628:19;;14428:225::o;15065:345::-;15267:2;15249:21;;;15306:2;15286:18;;;15279:30;-1:-1:-1;;;15340:2:1;15325:18;;15318:51;15401:2;15386:18;;15239:171::o;15415:408::-;15617:2;15599:21;;;15656:2;15636:18;;;15629:30;15695:34;15690:2;15675:18;;15668:62;-1:-1:-1;;;15761:2:1;15746:18;;15739:42;15813:3;15798:19;;15589:234::o;15828:343::-;16030:2;16012:21;;;16069:2;16049:18;;;16042:30;-1:-1:-1;;;16103:2:1;16088:18;;16081:49;16162:2;16147:18;;16002:169::o;16176:339::-;16378:2;16360:21;;;16417:2;16397:18;;;16390:30;-1:-1:-1;;;16451:2:1;16436:18;;16429:45;16506:2;16491:18;;16350:165::o;16520:420::-;16722:2;16704:21;;;16761:2;16741:18;;;16734:30;16800:34;16795:2;16780:18;;16773:62;16871:26;16866:2;16851:18;;16844:54;16930:3;16915:19;;16694:246::o;16945:351::-;17147:2;17129:21;;;17186:2;17166:18;;;17159:30;17225:29;17220:2;17205:18;;17198:57;17287:2;17272:18;;17119:177::o;17301:420::-;17503:2;17485:21;;;17542:2;17522:18;;;17515:30;17581:34;17576:2;17561:18;;17554:62;17652:26;17647:2;17632:18;;17625:54;17711:3;17696:19;;17475:246::o;17726:339::-;17928:2;17910:21;;;17967:2;17947:18;;;17940:30;-1:-1:-1;;;18001:2:1;17986:18;;17979:45;18056:2;18041:18;;17900:165::o;18070:406::-;18272:2;18254:21;;;18311:2;18291:18;;;18284:30;18350:34;18345:2;18330:18;;18323:62;-1:-1:-1;;;18416:2:1;18401:18;;18394:40;18466:3;18451:19;;18244:232::o;18481:335::-;18683:2;18665:21;;;18722:2;18702:18;;;18695:30;-1:-1:-1;;;18756:2:1;18741:18;;18734:41;18807:2;18792:18;;18655:161::o;18821:338::-;19023:2;19005:21;;;19062:2;19042:18;;;19035:30;-1:-1:-1;;;19096:2:1;19081:18;;19074:44;19150:2;19135:18;;18995:164::o;19164:350::-;19366:2;19348:21;;;19405:2;19385:18;;;19378:30;19444:28;19439:2;19424:18;;19417:56;19505:2;19490:18;;19338:176::o;19519:398::-;19721:2;19703:21;;;19760:2;19740:18;;;19733:30;19799:34;19794:2;19779:18;;19772:62;-1:-1:-1;;;19865:2:1;19850:18;;19843:32;19907:3;19892:19;;19693:224::o;19922:338::-;20124:2;20106:21;;;20163:2;20143:18;;;20136:30;-1:-1:-1;;;20197:2:1;20182:18;;20175:44;20251:2;20236:18;;20096:164::o;20265:356::-;20467:2;20449:21;;;20486:18;;;20479:30;20545:34;20540:2;20525:18;;20518:62;20612:2;20597:18;;20439:182::o;20626:408::-;20828:2;20810:21;;;20867:2;20847:18;;;20840:30;20906:34;20901:2;20886:18;;20879:62;-1:-1:-1;;;20972:2:1;20957:18;;20950:42;21024:3;21009:19;;20800:234::o;21039:356::-;21241:2;21223:21;;;21260:18;;;21253:30;21319:34;21314:2;21299:18;;21292:62;21386:2;21371:18;;21213:182::o;21400:405::-;21602:2;21584:21;;;21641:2;21621:18;;;21614:30;21680:34;21675:2;21660:18;;21653:62;-1:-1:-1;;;21746:2:1;21731:18;;21724:39;21795:3;21780:19;;21574:231::o;21810:411::-;22012:2;21994:21;;;22051:2;22031:18;;;22024:30;22090:34;22085:2;22070:18;;22063:62;-1:-1:-1;;;22156:2:1;22141:18;;22134:45;22211:3;22196:19;;21984:237::o;22226:397::-;22428:2;22410:21;;;22467:2;22447:18;;;22440:30;22506:34;22501:2;22486:18;;22479:62;-1:-1:-1;;;22572:2:1;22557:18;;22550:31;22613:3;22598:19;;22400:223::o;22628:330::-;22830:2;22812:21;;;22869:1;22849:18;;;22842:29;-1:-1:-1;;;22902:2:1;22887:18;;22880:37;22949:2;22934:18;;22802:156::o;22963:350::-;23165:2;23147:21;;;23204:2;23184:18;;;23177:30;23243:28;23238:2;23223:18;;23216:56;23304:2;23289:18;;23137:176::o;23318:413::-;23520:2;23502:21;;;23559:2;23539:18;;;23532:30;23598:34;23593:2;23578:18;;23571:62;-1:-1:-1;;;23664:2:1;23649:18;;23642:47;23721:3;23706:19;;23492:239::o;23736:353::-;23938:2;23920:21;;;23977:2;23957:18;;;23950:30;24016:31;24011:2;23996:18;;23989:59;24080:2;24065:18;;23910:179::o;24094:416::-;24296:2;24278:21;;;24335:2;24315:18;;;24308:30;24374:34;24369:2;24354:18;;24347:62;-1:-1:-1;;;24440:2:1;24425:18;;24418:50;24500:3;24485:19;;24268:242::o;24515:343::-;24717:2;24699:21;;;24756:2;24736:18;;;24729:30;-1:-1:-1;;;24790:2:1;24775:18;;24768:49;24849:2;24834:18;;24689:169::o;25045:251::-;25115:2;25109:9;25145:17;;;25192:18;25177:34;;25213:22;;;25174:62;25171:2;;;25239:18;;:::i;:::-;25275:2;25268:22;25089:207;;-1:-1:-1;25089:207:1:o;25301:192::-;;25400:18;25392:6;25389:30;25386:2;;;25422:18;;:::i;:::-;-1:-1:-1;25482:4:1;25463:17;;;25459:28;;25376:117::o;25498:128::-;;25569:1;25565:6;25562:1;25559:13;25556:2;;;25575:18;;:::i;:::-;-1:-1:-1;25611:9:1;;25546:80::o;25631:204::-;;25705:4;25702:1;25698:12;25737:4;25734:1;25730:12;25772:3;25766:4;25762:14;25757:3;25754:23;25751:2;;;25780:18;;:::i;:::-;25816:13;;25677:158;-1:-1:-1;;;25677:158:1:o;25840:120::-;;25906:1;25896:2;;25911:18;;:::i;:::-;-1:-1:-1;25945:9:1;;25886:74::o;25965:168::-;;26071:1;26067;26063:6;26059:14;26056:1;26053:21;26048:1;26041:9;26034:17;26030:45;26027:2;;;26078:18;;:::i;:::-;-1:-1:-1;26118:9:1;;26017:116::o;26138:125::-;;26206:1;26203;26200:8;26197:2;;;26211:18;;:::i;:::-;-1:-1:-1;26248:9:1;;26187:76::o;26268:258::-;26340:1;26350:113;26364:6;26361:1;26358:13;26350:113;;;26440:11;;;26434:18;26421:11;;;26414:39;26386:2;26379:10;26350:113;;;26481:6;26478:1;26475:13;26472:2;;;-1:-1:-1;;26516:1:1;26498:16;;26491:27;26321:205::o;26531:380::-;26616:1;26606:12;;26663:1;26653:12;;;26674:2;;26728:4;26720:6;26716:17;26706:27;;26674:2;26781;26773:6;26770:14;26750:18;26747:38;26744:2;;;26827:10;26822:3;26818:20;26815:1;26808:31;26862:4;26859:1;26852:15;26890:4;26887:1;26880:15;26744:2;;26586:325;;;:::o;26916:135::-;;-1:-1:-1;;26976:17:1;;26973:2;;;26996:18;;:::i;:::-;-1:-1:-1;27043:1:1;27032:13;;26963:88::o;27056:112::-;;27114:1;27104:2;;27119:18;;:::i;:::-;-1:-1:-1;27153:9:1;;27094:74::o;27173:127::-;27234:10;27229:3;27225:20;27222:1;27215:31;27265:4;27262:1;27255:15;27289:4;27286:1;27279:15;27305:127;27366:10;27361:3;27357:20;27354:1;27347:31;27397:4;27394:1;27387:15;27421:4;27418:1;27411:15;27437:127;27498:10;27493:3;27489:20;27486:1;27479:31;27529:4;27526:1;27519:15;27553:4;27550:1;27543:15;27569:133;-1:-1:-1;;;;;27646:31:1;;27636:42;;27626:2;;27692:1;27689;27682:12;27626:2;27616:86;:::o;27707:133::-;-1:-1:-1;;;;;;27783:32:1;;27773:43;;27763:2;;27830:1;27827;27820:12

Swarm Source

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