ETH Price: $3,175.20 (-7.75%)
Gas: 3 Gwei

Token

Double Decentraland LAND (doLAND)
 

Overview

Max Total Supply

18 doLAND

Holders

17

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
1 doLAND
0xa8D3F65b6E2922fED1430b77aC2b557e1fa8DA4a
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:
DclDoNFT

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-01-21
*/

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

// SPDX-License-Identifier: MIT

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;

            if (lastIndex != toDeleteIndex) {
                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] = valueIndex; // Replace lastvalue's index to valueIndex
            }

            // 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) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // 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);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        return _values(set._inner);
    }

    // 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))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        assembly {
            result := store
        }

        return result;
    }

    // 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));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        assembly {
            result := store
        }

        return result;
    }
}

// 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: contracts/OwnableContract.sol


pragma solidity 0.8.10;

contract OwnableContract {
    address public owner;
    address public pendingOwner;
    address public admin;

    event NewAdmin(address oldAdmin, address newAdmin);
    event NewOwner(address oldOwner, address newOwner);
    event NewPendingOwner(address oldPendingOwner, address newPendingOwner);

    function initOwnableContract() internal{
        owner = msg.sender;
        admin = msg.sender;
    }

    modifier onlyOwner {
        require(msg.sender == owner,"onlyOwner");
        _;
    }

    modifier onlyPendingOwner {
        require(msg.sender == pendingOwner,"onlyPendingOwner");
        _;
    }

    modifier onlyAdmin {
        require(msg.sender == admin || msg.sender == owner,"onlyAdmin");
        _;
    } 

    
    function transferOwnership(address _pendingOwner) public onlyOwner {
        emit NewPendingOwner(pendingOwner, _pendingOwner);
        pendingOwner = _pendingOwner;
    }

    function renounceOwnership() public virtual onlyOwner {
        emit NewOwner(owner, address(0));
        emit NewAdmin(admin, address(0));
        emit NewPendingOwner(pendingOwner, address(0));

        owner = address(0);
        pendingOwner = address(0);
        admin = address(0);
    }
    
    function acceptOwner() public onlyPendingOwner {
        emit NewOwner(owner, pendingOwner);
        owner = pendingOwner;

        address newPendingOwner = address(0);
        emit NewPendingOwner(pendingOwner, newPendingOwner);
        pendingOwner = newPendingOwner;
    }    
    
    function setAdmin(address newAdmin) public onlyOwner {
        emit NewAdmin(admin, newAdmin);
        admin = newAdmin;
    }




}

// File: contracts/IWrapDoNFT.sol


pragma solidity 0.8.10;




interface IWrapDoNFT {

    event Redeem(uint256 oid,uint256 tokenId);

    function couldRedeem(uint256 tokenId,uint256[] calldata durationIds) external view returns(bool);

    function redeem(uint256 tokenId,uint256[] calldata durationIds) external;

}

// File: @openzeppelin/contracts/utils/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/extensions/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/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;
        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");

        (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");

        (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");

        (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");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal 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

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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



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 meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

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



pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

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

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

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



pragma solidity ^0.8.0;


/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

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



pragma solidity ^0.8.0;








/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

    // 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;

    /**
     * @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_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @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 _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /**
     * @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 baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @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 || 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 _owners[tokenId] != address(0);
    }

    /**
     * @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 || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `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);

        _balances[to] += 1;
        _owners[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);

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

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

        _balances[owner] -= 1;
        delete _owners[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");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

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

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

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

    /**
     * @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()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @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` and `to` are never both zero.
     *
     * 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/token/ERC721/extensions/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/extensions/ERC721Enumerable.sol



pragma solidity ^0.8.0;



/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
        return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @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 override {
        super._beforeTokenTransfer(from, to, tokenId);

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol



pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

// File: contracts/IBaseDoNFT.sol


pragma solidity 0.8.10;



interface IBaseDoNFT is IERC721Receiver {
    struct Duration{
        uint64 start; 
        uint64 end;
    }

    struct DoNftInfo {
        uint256 oid;
        uint64 nonce;
        EnumerableSet.UintSet durationList;
    }

    event MetadataUpdate(uint256 tokenId);

    event DurationUpdate(uint256 durationId,uint256 tokenId,uint64 start,uint64 end);

    event DurationBurn(uint256[] durationIdList);

    event CheckIn(address opreator,address to,uint256 tokenId,uint256 durationId);

    function init(address address_,string memory name_, string memory symbol_) external;

    function isWrap() external pure returns(bool);

    function mintXNft(uint256 oid) external returns(uint256 tid);

    function mint(uint256 tokenId,uint256 durationId,uint64 start,uint64 end,address to) external returns(uint256 tid);

    function setMaxDuration(uint64 v) external;

    function getDurationIdList(uint256 tokenId) external view returns(uint256[] memory);

    function getDurationListLength(uint256 tokenId) external view returns(uint256);

    function getDoNftInfo(uint256 tokenId) external view returns(uint256 oid, uint256[] memory durationIds,uint64[] memory starts,uint64[] memory ends,uint64 nonce);

    function getNonce(uint256 tokenId) external view returns(uint64);

    function getDuration(uint256 durationId) external view returns(uint64 start, uint64 end);

    function getDurationByIndex(uint256 tokenId,uint256 index) external view returns(uint256 durationId,uint64 start, uint64 end);

    function getXNftId(uint256 originalNftId) external view returns(uint256);

    function isXNft(uint256 tokenId) external view returns(bool);

    function isValidNow(uint256 tokenId) external view returns(bool isValid);

    function getOriginalNftAddress() external view returns(address);

    function getOriginalNftId(uint256 tokenId) external view returns(uint256);

    function checkIn(address to,uint256 tokenId,uint256 durationId) external;

    function getUser(uint256 orignalNftId) external returns(address);

    function exists(uint256 tokenId) external view returns (bool);

    
}

// File: contracts/BaseDoNFT.sol


pragma solidity 0.8.10;





abstract contract BaseDoNFT is OwnableContract,ReentrancyGuard,ERC721Enumerable,IBaseDoNFT {
    using EnumerableSet for EnumerableSet.UintSet;
    address internal oNftAddress;
    uint256 public curDoid;
    uint256 public curDurationId;
    uint64 private maxDuration = 31536000;
    mapping(uint256 => DoNftInfo) internal doNftMapping;
    mapping(uint256 => Duration) internal durationMapping;
    mapping(uint256 => uint256) internal oid2xid;
    mapping(uint256 => address) internal checkInUserMapping;

    bool private isOnlyNow = true;
    string private _doName;
    string private _doSymbol;
    string private _dclURI;
    
    constructor()ERC721("DoNFT","DoNFT"){
        initOwnableContract();
    }

    modifier onlyNow(uint64 start) {
        if(isOnlyNow){
            require(start <= block.timestamp, "must from now");
        }
        _;
    }

    function onlyApprovedOrOwner(address spender,address nftAddress,uint256 tokenId) internal view returns(bool){
        address owner = ERC721(nftAddress).ownerOf(tokenId);
        require(owner != address(0),"ERC721: operator query for nonexistent token");
        return (spender == owner || ERC721(nftAddress).getApproved(tokenId) == spender || ERC721(nftAddress).isApprovedForAll(owner, spender));
    }

    function init(address address_,string memory name_, string memory symbol_) public {
        require(oNftAddress==address(0),"already inited");
        oNftAddress = address_;
        _doName = name_;
        _doSymbol = symbol_;
    }
    function name() public view virtual override returns (string memory) {
        return _doName;
    }
    function symbol() public view virtual override returns (string memory) {
        return _doSymbol;
    }

    function setIsOnlyNow(bool v) public onlyAdmin {
        isOnlyNow = v;
    }

    function contains(uint256 tokenId,uint256 durationId) public view returns(bool){
        return doNftMapping[tokenId].durationList.contains(durationId);
    }

    function getDurationIdList(uint256 tokenId) external view returns(uint256[] memory){
        DoNftInfo storage info = doNftMapping[tokenId];
        return info.durationList.values();
    }
    function getDuration(uint256 durationId) public view returns(uint64, uint64){
        Duration storage duration = durationMapping[durationId];
        return (duration.start,duration.end);
    }

    function getDurationByIndex(uint256 tokenId,uint256 index) public view returns(uint256 durationId,uint64 start, uint64 end){
        DoNftInfo storage info = doNftMapping[tokenId];
        require(index < info.durationList.length(),"out of range");
        durationId = info.durationList.at(index);
        (start,end) = getDuration(durationId);
        return(durationId,start,end);
    }

    function isValidNow(uint256 tokenId) public view returns(bool isValid){
        DoNftInfo storage info = doNftMapping[tokenId];
        uint256 length = info.durationList.length();
        uint256 durationId;
        for (uint256 index = 0; index < length; index++) {
            durationId = info.durationList.at(index);
            if(durationMapping[durationId].start <= block.timestamp && block.timestamp <= durationMapping[durationId].end){
                return true;
            }
        }
        return false;
    }

    function getDurationListLength(uint256 tokenId) external view returns(uint256){
        return doNftMapping[tokenId].durationList.length();
    }

    function getDoNftInfo(uint256 tokenId) public view returns(uint256 oid, uint256[] memory durationIds, uint64[] memory starts,uint64[] memory ends,uint64 nonce){
        DoNftInfo storage info = doNftMapping[tokenId];
        oid = info.oid;
        nonce = info.nonce;
        uint256 length = info.durationList.length();
        uint256 durationId;
        starts = new uint64[](length);
        ends = new uint64[](length);
        durationIds = info.durationList.values();
        for (uint256 index = 0; index < length; index++) {
            durationId = info.durationList.at(index);
            starts[index] = durationMapping[durationId].start;
            ends[index] = durationMapping[durationId].end;
        }
        
    }

    function getNonce(uint256 tokenId) external view returns(uint64){
       return doNftMapping[tokenId].nonce;
    }

    function mint(
        uint256 tokenId,
        uint256 durationId,
        uint64 start,
        uint64 end,
        address to
    ) public onlyNow(start) nonReentrant returns(uint256 tid){
        if(start < block.timestamp){
            start = uint64(block.timestamp);
        }
        require(_isApprovedOrOwner(_msgSender(), tokenId) || _isApprovedOrOwner(tx.origin, tokenId), "not owner nor approved");
        require(end > start && end <= block.timestamp + maxDuration, "invalid start or end");
        DoNftInfo storage info = doNftMapping[tokenId];
        require(contains(tokenId,durationId), "not contains durationId");
        Duration storage duration = durationMapping[durationId];
        require(start >= duration.start && end <= duration.end, "invalid duration");
        uint256 tDurationId;
        if (start == duration.start && end == duration.end) {
            tid = mintDoNft(to,info.oid,start,end);
            tDurationId = curDurationId;
            _burnDuration(tokenId, durationId);
            if(info.durationList.length() == 0){
                _burn(tokenId);
            }
        } else {
            if(start == duration.start && end != duration.end){
                duration.start = end + 1;
            }else if(start != duration.start && end == duration.end){
                duration.end = start - 1;
            }else{
                if (start > block.timestamp) {
                    newDuration(tokenId, duration.start, start-1);
                }
                duration.start = end + 1;
            }

            tid = mintDoNft(to, info.oid,start,end);
            tDurationId = curDurationId;
        }
        
        if(start==block.timestamp){
            checkIn(to, tid, tDurationId);
        }
        emit MetadataUpdate(tokenId);
        
    }
    
    function setMaxDuration(uint64 v) public onlyAdmin{
        maxDuration = v;
    }
    function newDoNft(uint256 oid_,uint64 start,uint64 end) internal returns (uint256)
    {
        curDoid++;
        DoNftInfo storage info = doNftMapping[curDoid];
        info.oid = oid_;
        info.nonce = 0;
        newDuration(curDoid,start,end);
        return curDoid;
    }
    
    function newDuration(uint256 tokenId,uint64 start,uint64 end) private{
        curDurationId++;
        durationMapping[curDurationId] = Duration(start,end);
        doNftMapping[tokenId].durationList.add(curDurationId);
        emit DurationUpdate(curDurationId,tokenId,start,end);
    }

    function mintDoNft(address to, uint256 oid_,uint64 start,uint64 end)
        internal
        returns (uint256)
    {
        newDoNft(oid_,start,end);
        _safeMint(to, curDoid);
        return curDoid;
    }

    function concat(uint256 tokenId,uint256 durationId,uint256 targetTokenId,uint256 targetDurationId) public {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        require(contains(tokenId,durationId),"not contains");
        require(ownerOf(tokenId) == ownerOf(targetTokenId), "diff owner");
        require(doNftMapping[tokenId].oid == doNftMapping[targetTokenId].oid , "diff oid");
        require(contains(targetTokenId,targetDurationId),"not contains");
        
        Duration storage duration = durationMapping[durationId];
        Duration storage targetDuration = durationMapping[targetDurationId];
        if(duration.end < targetDuration.start){
            require(duration.end+1==targetDuration.start);
            targetDuration.start = duration.start;
            _burnDuration(tokenId,durationId);
        }
        else if(targetDuration.end < duration.start){
            require(targetDuration.end+1 == duration.start);
            targetDuration.end = duration.end;
            _burnDuration(tokenId,durationId);
        }

        if(doNftMapping[tokenId].durationList.length() == 0){
            _burn(tokenId);
        }

    }

    function _burnDuration(uint256 tokenId,uint256 durationId) private{
        delete durationMapping[durationId];
        doNftMapping[tokenId].durationList.remove(durationId);
        uint256[] memory arr = new uint256[](1);
        arr[0] = durationId;
        emit DurationBurn(arr);
    }
   
    function _burnXNft(uint256 wid) internal {
        DoNftInfo storage info = doNftMapping[wid];
        uint256 length = info.durationList.length();
        for (uint256 index = 0; index < length; index++) {
            delete durationMapping[info.durationList.at(index)];
        }
        emit DurationBurn(info.durationList.values());
        delete info.durationList;
        delete oid2xid[info.oid];
        _burn(wid);
    }

    function _burn(uint256 tokenId) internal override virtual {
        ERC721._burn(tokenId);
        delete doNftMapping[tokenId];
    }

    function checkIn(address to,uint256 tokenId,uint256 durationId) public virtual{
        require(_isApprovedOrOwner(_msgSender(), tokenId) || _isApprovedOrOwner(tx.origin, tokenId), "not owner nor approved");
        DoNftInfo storage info = doNftMapping[tokenId];
        Duration storage duration = durationMapping[durationId];
        require(duration.end >= block.timestamp,"invalid end");
        require(duration.start <= block.timestamp,"invalid start");
        require(info.durationList.contains(durationId),"not contains");
        checkInUserMapping[info.oid] = to;
        emit CheckIn(tx.origin,to,tokenId,durationId);
    }

    function getUser(uint256 originalNftId) public view returns(address){
        return checkInUserMapping[originalNftId];
    }

    function gc(uint256 tokenId,uint256[] calldata durationIds) public {
        DoNftInfo storage info = doNftMapping[tokenId];
        uint256 durationId;
        Duration storage duration;
        for (uint256 index = 0; index < durationIds.length; index++) {
            durationId = durationIds[index];
            if(contains(tokenId, durationId)){
                duration = durationMapping[durationId];
                if(duration.end <= block.timestamp){
                    _burnDuration(tokenId,durationId);
                }
            }
        }
        
        if(info.durationList.length() == 0){
            require(!isXNft(tokenId),"can not burn xNFT");
            _burn(tokenId);
        }
    }

    function getFingerprint(uint256 tokenId) public view returns(bytes32 print){
        (uint256 oid, uint256[] memory durationIds,uint64[] memory starts,uint64[] memory ends,uint64 nonce) = getDoNftInfo(tokenId);
        print = keccak256(abi.encodePacked(oid,durationIds,starts,ends,nonce));
    }

    function isXNft(uint256 tokenId) public view returns(bool) {
        if(tokenId == 0) return false;
        
        return oid2xid[doNftMapping[tokenId].oid] == tokenId ;
    }

    function isWrap() public pure virtual returns(bool){
        return false;
    }

    function getOriginalNftAddress() external view returns(address){
        return oNftAddress;
    }
    function getOriginalNftId(uint256 tokenId) external view returns(uint256){
        DoNftInfo storage info = doNftMapping[tokenId];
        return info.oid;
    }

    function getXNftId(uint256 originalNftId) public view returns(uint256) {
        return oid2xid[originalNftId] ;
    }

    function onERC721Received(address operator,address from,uint256 tokenId,bytes calldata data
    ) external override virtual pure returns (bytes4) {
        bytes4 received = 0x150b7a02;
        return received;
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override{
        ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);
        doNftMapping[tokenId].nonce++;
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return
            interfaceId == type(IBaseDoNFT).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    function setBaseURI(string memory newBaseURI) public onlyAdmin {
        _dclURI = newBaseURI;
    }

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory){
        return string(abi.encodePacked(_dclURI, Strings.toString(tokenId)));
    }

    function exists(uint256 tokenId) public view virtual returns (bool) {
        return _exists(tokenId);
    }

    
}

// File: contracts/WrapDoNFT.sol


pragma solidity 0.8.10;




contract WrapDoNFT is BaseDoNFT,IWrapDoNFT{
    using EnumerableSet for EnumerableSet.UintSet;

    function mintXNft(uint256 oid) public nonReentrant override returns(uint256 tid){
        require(oid2xid[oid] == 0, "already warped");
        require(onlyApprovedOrOwner(tx.origin,oNftAddress,oid) || onlyApprovedOrOwner(msg.sender,oNftAddress,oid),"only approved or owner");
        address lastOwner = ERC721(oNftAddress).ownerOf(oid);
        ERC721(oNftAddress).safeTransferFrom(lastOwner, address(this), oid);
        tid = mintDoNft(lastOwner,oid,uint64(block.timestamp),type(uint64).max);
        oid2xid[oid] = tid;
    }

    function isWNft(uint256 tokenId)public view returns (bool){
        return isXNft(tokenId);
    }

    function getWNftId(uint256 oid) public view returns(uint256){
        return getXNftId(oid);
    }

    function mintWNft(uint256 oid) public returns(uint256 tid){
        tid = mintXNft(oid);
    }
    
    function couldRedeem(uint256 tokenId,uint256[] calldata durationIds) public view returns(bool) {
        require(isXNft(tokenId) , "not xNFT") ;
        DoNftInfo storage info = doNftMapping[tokenId];
        Duration storage duration = durationMapping[durationIds[0]];
        if(duration.start > block.timestamp){
            return false;
        }
        uint64 lastEndTime = duration.end;
        for (uint256 index = 1; index < durationIds.length; index++) {
            require(info.durationList.contains(durationIds[index]),"out of bundle");
            duration = durationMapping[durationIds[index]];
            if(lastEndTime+1 == duration.start){
                lastEndTime = duration.end;
            }
        }
        return lastEndTime == type(uint64).max;
        
        
    }
    
    function redeem(uint256 tokenId,uint256[] calldata durationIds) public{
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        require(couldRedeem(tokenId, durationIds),"cannot redeem");
        DoNftInfo storage info = doNftMapping[tokenId];
        ERC721(oNftAddress).safeTransferFrom(address(this), ownerOf(tokenId), info.oid);
        _burnXNft(tokenId);
        emit Redeem(info.oid,tokenId);
    }

    function isWrap() public pure override returns(bool){
        return true;
    }


}

// File: contracts/dcl/IDCL.sol


pragma solidity 0.8.10;

interface IDCL{
    function setUpdateOperator(uint256 assetId,address operator) external;
}

// File: contracts/dcl/DclDoNFT.sol


pragma solidity 0.8.10;




contract DclDoNFT is WrapDoNFT{
    using EnumerableSet for EnumerableSet.UintSet;
    constructor(address address_,string memory name_, string memory symbol_) {
        super.init(address_, name_, symbol_);
    }
    
    function checkIn(address to,uint256 tokenId,uint256 durationId) public override virtual{
        BaseDoNFT.checkIn(to,tokenId,durationId);
        DoNftInfo storage info = doNftMapping[tokenId];
        IDCL(oNftAddress).setUpdateOperator(info.oid, to);
    }

    

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"address_","type":"address"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"}],"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":"address","name":"opreator","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"durationId","type":"uint256"}],"name":"CheckIn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"durationIdList","type":"uint256[]"}],"name":"DurationBurn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"durationId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"start","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"end","type":"uint64"}],"name":"DurationUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"MetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"NewAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"NewOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldPendingOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newPendingOwner","type":"address"}],"name":"NewPendingOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Redeem","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":"acceptOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"durationId","type":"uint256"}],"name":"checkIn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"durationId","type":"uint256"},{"internalType":"uint256","name":"targetTokenId","type":"uint256"},{"internalType":"uint256","name":"targetDurationId","type":"uint256"}],"name":"concat","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"durationId","type":"uint256"}],"name":"contains","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256[]","name":"durationIds","type":"uint256[]"}],"name":"couldRedeem","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curDoid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curDurationId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256[]","name":"durationIds","type":"uint256[]"}],"name":"gc","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getDoNftInfo","outputs":[{"internalType":"uint256","name":"oid","type":"uint256"},{"internalType":"uint256[]","name":"durationIds","type":"uint256[]"},{"internalType":"uint64[]","name":"starts","type":"uint64[]"},{"internalType":"uint64[]","name":"ends","type":"uint64[]"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"durationId","type":"uint256"}],"name":"getDuration","outputs":[{"internalType":"uint64","name":"","type":"uint64"},{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getDurationByIndex","outputs":[{"internalType":"uint256","name":"durationId","type":"uint256"},{"internalType":"uint64","name":"start","type":"uint64"},{"internalType":"uint64","name":"end","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getDurationIdList","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getDurationListLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFingerprint","outputs":[{"internalType":"bytes32","name":"print","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getNonce","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOriginalNftAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getOriginalNftId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"originalNftId","type":"uint256"}],"name":"getUser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"oid","type":"uint256"}],"name":"getWNftId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"originalNftId","type":"uint256"}],"name":"getXNftId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"address_","type":"address"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isValidNow","outputs":[{"internalType":"bool","name":"isValid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isWNft","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isWrap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isXNft","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"durationId","type":"uint256"},{"internalType":"uint64","name":"start","type":"uint64"},{"internalType":"uint64","name":"end","type":"uint64"},{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"tid","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"oid","type":"uint256"}],"name":"mintWNft","outputs":[{"internalType":"uint256","name":"tid","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"oid","type":"uint256"}],"name":"mintXNft","outputs":[{"internalType":"uint256","name":"tid","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","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":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256[]","name":"durationIds","type":"uint256[]"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","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":"newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"v","type":"bool"}],"name":"setIsOnlyNow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"v","type":"uint64"}],"name":"setMaxDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pendingOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052601180546001600160401b0319166301e133801790556016805460ff191660011790553480156200003457600080fd5b50604051620048fd380380620048fd83398101604081905262000057916200030d565b604080518082018252600580825264111bd3919560da1b60208084018281528551808701909652928552840152600160035581519192916200009c916004916200019a565b508051620000b29060059060208401906200019a565b50620000de91505060008054336001600160a01b03199182168117909255600280549091169091179055565b620000f6838383620000ff60201b62001b681760201c565b505050620003d4565b600e546001600160a01b0316156200014e5760405162461bcd60e51b815260206004820152600e60248201526d185b1c9958591e481a5b9a5d195960921b604482015260640160405180910390fd5b600e80546001600160a01b0319166001600160a01b03851617905581516200017e9060179060208501906200019a565b508051620001949060189060208401906200019a565b50505050565b828054620001a89062000397565b90600052602060002090601f016020900481019282620001cc576000855562000217565b82601f10620001e757805160ff191683800117855562000217565b8280016001018555821562000217579182015b8281111562000217578251825591602001919060010190620001fa565b506200022592915062000229565b5090565b5b808211156200022557600081556001016200022a565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200026857600080fd5b81516001600160401b038082111562000285576200028562000240565b604051601f8301601f19908116603f01168101908282118183101715620002b057620002b062000240565b81604052838152602092508683858801011115620002cd57600080fd5b600091505b83821015620002f15785820183015181830184015290820190620002d2565b83821115620003035760008385830101525b9695505050505050565b6000806000606084860312156200032357600080fd5b83516001600160a01b03811681146200033b57600080fd5b60208501519093506001600160401b03808211156200035957600080fd5b620003678783880162000256565b935060408601519150808211156200037e57600080fd5b506200038d8682870162000256565b9150509250925092565b600181811c90821680620003ac57607f821691505b60208210811415620003ce57634e487b7160e01b600052602260045260246000fd5b50919050565b61451980620003e46000396000f3fe608060405234801561001057600080fd5b50600436106103775760003560e01c80638bb126a7116101d3578063cb697d1e11610104578063ebbc4965116100a2578063f2fde38b1161007c578063f2fde38b1461087d578063f851a44014610890578063fd83de62146108a3578063fe909ee4146108b657600080fd5b8063ebbc496514610842578063ee544b151461084a578063f01478321461086a57600080fd5b8063dbe102c0116100de578063dbe102c01461079b578063e30c3978146107bb578063e42e66a9146107ce578063e985e9c51461080657600080fd5b8063cb697d1e1461076e578063d7c6e71414610781578063d816f0911461078857600080fd5b8063abb2176a11610171578063b73bb40a1161014b578063b73bb40a14610722578063b88d4fde14610735578063c4a0db9614610748578063c87b56dd1461075b57600080fd5b8063abb2176a146106dd578063b0467deb146106e6578063b2b45df51461070f57600080fd5b806398e5d38f116101ad57806398e5d38f1461069b578063a050ac8f146106ae578063a22cb465146106b7578063a6963b97146106ca57600080fd5b80638bb126a71461062b5780638da5cb5b1461068057806395d89b411461069357600080fd5b806342842e0e116102ad5780636352211e1161024b57806370982aa51161022557806370982aa5146105ea57806370a08231146105fd578063715018a61461061057806385b5b1321461061857600080fd5b80636352211e146105b1578063704b6c02146105c4578063706023c1146105d757600080fd5b80634f558e79116102875780634f558e79146105545780634f6ccce71461056757806352332ed81461057a57806355f804b31461059e57600080fd5b806342842e0e1461051b578063438e15fc1461052e5780634e7765e31461054157600080fd5b806318160ddd1161031a57806325cb25b0116102f457806325cb25b0146104a05780632f745c59146104b1578063393b17a4146104c45780633d46b819146104d757600080fd5b806318160ddd146104655780631aa144981461046d57806323b872dd1461048d57600080fd5b8063081812fc11610356578063081812fc146103ce578063095ea7b3146103f9578063150b7a021461040c578063159a64751461044457600080fd5b806295d6451461037c57806301ffc9a71461039157806306fdde03146103b9575b600080fd5b61038f61038a366004613946565b6108c9565b005b6103a461039f366004613979565b610924565b60405190151581526020015b60405180910390f35b6103c161094f565b6040516103b091906139ee565b6103e16103dc366004613a01565b6109e1565b6040516001600160a01b0390911681526020016103b0565b61038f610407366004613a2f565b610a76565b61042b61041a366004613a5b565b630a85bd0160e11b95945050505050565b6040516001600160e01b031990911681526020016103b0565b610457610452366004613a01565b610b8c565b6040519081526020016103b0565b600c54610457565b61045761047b366004613a01565b60009081526012602052604090205490565b61038f61049b366004613af9565b610be3565b600e546001600160a01b03166103e1565b6104576104bf366004613a2f565b610c14565b6103a46104d2366004613a01565b610caa565b6105036104e5366004613a01565b6000908152601260205260409020600101546001600160401b031690565b6040516001600160401b0390911681526020016103b0565b61038f610529366004613af9565b610d59565b6103a461053c366004613b3a565b610d74565b61045761054f366004613a01565b610d96565b6103a4610562366004613a01565b610da1565b610457610575366004613a01565b610dc0565b61058d610588366004613a01565b610e53565b6040516103b0959493929190613bd0565b61038f6105ac366004613cd6565b610fec565b6103e16105bf366004613a01565b611042565b61038f6105d2366004613d0a565b6110b9565b6104576105e5366004613d43565b61114c565b6103a46105f8366004613a01565b6115ee565b61045761060b366004613d0a565b61161e565b61038f6116a5565b610457610626366004613a01565b6117c9565b610660610639366004613a01565b6000908152601360205260409020546001600160401b0380821692600160401b9092041690565b604080516001600160401b039384168152929091166020830152016103b0565b6000546103e1906001600160a01b031681565b6103c16119f6565b61038f6106a9366004613d9e565b611a05565b61045760105481565b61038f6106c5366004613dd3565b611a8f565b6104576106d8366004613a01565b611b54565b610457600f5481565b6103e16106f4366004613a01565b6000908152601560205260409020546001600160a01b031690565b61038f61071d366004613e0c565b611b68565b6103a4610730366004613a01565b611bfa565b61038f610743366004613e81565b611c05565b61038f610756366004613f00565b611c38565b6103c1610769366004613a01565b611d81565b6103a461077c366004613f00565b611db5565b60016103a4565b61038f610796366004613f7e565b611f70565b6107ae6107a9366004613a01565b6121dd565b6040516103b09190613fb0565b6001546103e1906001600160a01b031681565b6107e16107dc366004613b3a565b6121fa565b604080519384526001600160401b0392831660208501529116908201526060016103b0565b6103a4610814366004613fc3565b6001600160a01b03918216600090815260096020908152604080832093909416825291909152205460ff1690565b61038f612294565b610457610858366004613a01565b60009081526014602052604090205490565b61038f610878366004613ff1565b6123aa565b61038f61088b366004613d0a565b61240c565b6002546103e1906001600160a01b031681565b6104576108b1366004613a01565b612475565b61038f6108c4366004613f00565b61248f565b6002546001600160a01b03163314806108ec57506000546001600160a01b031633145b6109115760405162461bcd60e51b81526004016109089061400c565b60405180910390fd5b6016805460ff1916911515919091179055565b60006001600160e01b03198216632e541b5b60e21b148061094957506109498261257d565b92915050565b60606017805461095e9061402f565b80601f016020809104026020016040519081016040528092919081815260200182805461098a9061402f565b80156109d75780601f106109ac576101008083540402835291602001916109d7565b820191906000526020600020905b8154815290600101906020018083116109ba57829003601f168201915b5050505050905090565b6000818152600660205260408120546001600160a01b0316610a5a5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610908565b506000908152600860205260409020546001600160a01b031690565b6000610a8182611042565b9050806001600160a01b0316836001600160a01b03161415610aef5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610908565b336001600160a01b0382161480610b0b5750610b0b8133610814565b610b7d5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610908565b610b8783836125a2565b505050565b600080600080600080610b9e87610e53565b945094509450945094508484848484604051602001610bc1959493929190614098565b6040516020818303038152906040528051906020012095505050505050919050565b610bed3382612610565b610c095760405162461bcd60e51b8152600401610908906140ff565b610b878383836126c2565b6000610c1f8361161e565b8210610c815760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610908565b506001600160a01b03919091166000908152600a60209081526040808320938352929052205490565b600081815260126020526040812081610cc56002830161286d565b90506000805b82811015610d4d57610ce06002850182612877565b600081815260136020526040902054909250426001600160401b0390911611801590610d2a5750600082815260136020526040902054600160401b90046001600160401b03164211155b15610d3b5750600195945050505050565b80610d4581614166565b915050610ccb565b50600095945050505050565b610b8783838360405180602001604052806000815250611c05565b6000828152601260205260408120610d8f9060020183612883565b9392505050565b6000610949826117c9565b6000818152600660205260408120546001600160a01b03161515610949565b6000610dcb600c5490565b8210610e2e5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610908565b600c8281548110610e4157610e41614181565b90600052602060002001549050919050565b6000818152601260205260408120805460018201549092606092839283926001600160401b039091169190610e8a6002830161286d565b90506000816001600160401b03811115610ea657610ea6613c2b565b604051908082528060200260200182016040528015610ecf578160200160208202803683370190505b509550816001600160401b03811115610eea57610eea613c2b565b604051908082528060200260200182016040528015610f13578160200160208202803683370190505b509450610f228360020161289b565b965060005b82811015610fdf57610f3c6002850182612877565b60008181526013602052604090205488519193506001600160401b031690889083908110610f6c57610f6c614181565b6001600160401b039283166020918202929092018101919091526000848152601390915260409020548751600160401b90910490911690879083908110610fb557610fb5614181565b6001600160401b039092166020928302919091019091015280610fd781614166565b915050610f27565b5050505091939590929450565b6002546001600160a01b031633148061100f57506000546001600160a01b031633145b61102b5760405162461bcd60e51b81526004016109089061400c565b805161103e90601990602084019061387e565b5050565b6000818152600660205260408120546001600160a01b0316806109495760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610908565b6000546001600160a01b031633146110e35760405162461bcd60e51b815260040161090890614197565b6002546040517ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc91611122916001600160a01b039091169084906141ba565b60405180910390a1600280546001600160a01b0319166001600160a01b0392909216919091179055565b601654600090849060ff16156111a55742816001600160401b031611156111a55760405162461bcd60e51b815260206004820152600d60248201526c6d7573742066726f6d206e6f7760981b6044820152606401610908565b600260035414156111f85760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610908565b6002600355426001600160401b0386161015611212574294505b61121c3388612610565b8061122c575061122c3288612610565b6112715760405162461bcd60e51b81526020600482015260166024820152751b9bdd081bdddb995c881b9bdc88185c1c1c9bdd995960521b6044820152606401610908565b846001600160401b0316846001600160401b03161180156112b057506011546112a3906001600160401b0316426141d4565b846001600160401b031611155b6112f35760405162461bcd60e51b81526020600482015260146024820152731a5b9d985b1a59081cdd185c9d081bdc88195b9960621b6044820152606401610908565b600087815260126020526040902061130b8888610d74565b6113575760405162461bcd60e51b815260206004820152601760248201527f6e6f7420636f6e7461696e73206475726174696f6e49640000000000000000006044820152606401610908565b600087815260136020526040902080546001600160401b0390811690881610801590611398575080546001600160401b03600160401b909104811690871611155b6113d75760405162461bcd60e51b815260206004820152601060248201526f34b73b30b634b210323ab930ba34b7b760811b6044820152606401610908565b80546000906001600160401b038981169116148015611409575081546001600160401b03888116600160401b90920416145b1561144d5761141e8684600001548a8a6128a8565b9450601054905061142f8a8a6128ce565b61143b8360020161286d565b611448576114488a612983565b61158c565b81546001600160401b03898116911614801561147d575081546001600160401b03888116600160401b9092041614155b156114ae5761148d8760016141ec565b825467ffffffffffffffff19166001600160401b0391909116178255611574565b81546001600160401b038981169116148015906114de575081546001600160401b03888116600160401b90920416145b1561151a576114ee600189614217565b82546001600160401b0391909116600160401b0267ffffffffffffffff60401b19909116178255611574565b42886001600160401b0316111561154c57815461154c908b906001600160401b031661154760018c614217565b6129cb565b6115578760016141ec565b825467ffffffffffffffff19166001600160401b03919091161782555b6115848684600001548a8a6128a8565b945060105490505b42886001600160401b031614156115a8576115a8868683611a05565b6040518a81527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a15050600160035550909695505050505050565b6000816115fd57506000919050565b50600081815260126020908152604080832054835260149091529020541490565b60006001600160a01b0382166116895760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610908565b506001600160a01b031660009081526007602052604090205490565b6000546001600160a01b031633146116cf5760405162461bcd60e51b815260040161090890614197565b600080546040517f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b23649261170b926001600160a01b0316916141ba565b60405180910390a16002546040517ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc91611753916001600160a01b03909116906000906141ba565b60405180910390a16001546040517fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b9161179b916001600160a01b03909116906000906141ba565b60405180910390a1600080546001600160a01b03199081169091556001805482169055600280549091169055565b60006002600354141561181e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610908565b6002600355600082815260146020526040902054156118705760405162461bcd60e51b815260206004820152600e60248201526d185b1c9958591e481dd85c9c195960921b6044820152606401610908565b600e546118889032906001600160a01b031684612aa9565b806118a65750600e546118a69033906001600160a01b031684612aa9565b6118eb5760405162461bcd60e51b815260206004820152601660248201527537b7363c9030b8383937bb32b21037b91037bbb732b960511b6044820152606401610908565b600e546040516331a9108f60e11b8152600481018490526000916001600160a01b031690636352211e90602401602060405180830381865afa158015611935573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611959919061423f565b600e54604051632142170760e11b81526001600160a01b038084166004830152306024830152604482018790529293509116906342842e0e90606401600060405180830381600087803b1580156119af57600080fd5b505af11580156119c3573d6000803e3d6000fd5b505050506119da8184426001600160401b036128a8565b6000938452601460205260409093208390555050600160035590565b60606018805461095e9061402f565b611a10838383612c51565b60008281526012602052604090819020600e5481549251630585816360e51b815260048101939093526001600160a01b038681166024850152919291169063b0b02c6090604401600060405180830381600087803b158015611a7157600080fd5b505af1158015611a85573d6000803e3d6000fd5b5050505050505050565b6001600160a01b038216331415611ae85760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610908565b3360008181526009602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600081815260146020526040812054610949565b600e546001600160a01b031615611bb25760405162461bcd60e51b815260206004820152600e60248201526d185b1c9958591e481a5b9a5d195960921b6044820152606401610908565b600e80546001600160a01b0319166001600160a01b0385161790558151611be090601790602085019061387e565b508051611bf490601890602084019061387e565b50505050565b6000610949826115ee565b611c10335b83612610565b611c2c5760405162461bcd60e51b8152600401610908906140ff565b611bf484848484612e0a565b611c423384612610565b611c5e5760405162461bcd60e51b8152600401610908906140ff565b611c69838383611db5565b611ca55760405162461bcd60e51b815260206004820152600d60248201526c63616e6e6f742072656465656d60981b6044820152606401610908565b6000838152601260205260409020600e546001600160a01b03166342842e0e30611cce87611042565b845460405160e085901b6001600160e01b03191681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b158015611d1f57600080fd5b505af1158015611d33573d6000803e3d6000fd5b50505050611d4084612e3d565b805460408051918252602082018690527fe3829d5463fae0f748d927f86f762044188c9ce53d91a394eb93e98354cc3092910160405180910390a150505050565b60606019611d8e83612f1a565b604051602001611d9f929190614278565b6040516020818303038152906040529050919050565b6000611dc0846115ee565b611df75760405162461bcd60e51b81526020600482015260086024820152671b9bdd081e13919560c21b6044820152606401610908565b60008481526012602052604081209060138186868281611e1957611e19614181565b602090810292909201358352508101919091526040016000208054909150426001600160401b039091161115611e5457600092505050610d8f565b8054600160401b90046001600160401b031660015b85811015611f5957611e9f878783818110611e8657611e86614181565b905060200201358560020161288390919063ffffffff16565b611edb5760405162461bcd60e51b815260206004820152600d60248201526c6f7574206f662062756e646c6560981b6044820152606401610908565b60136000888884818110611ef157611ef1614181565b6020908102929092013583525081019190915260400160002080549093506001600160401b0316611f238360016141ec565b6001600160401b03161415611f47578254600160401b90046001600160401b031691505b80611f5181614166565b915050611e69565b506001600160401b03908116149695505050505050565b611f7a3385612610565b611f965760405162461bcd60e51b8152600401610908906140ff565b611fa08484610d74565b611fbc5760405162461bcd60e51b815260040161090890614316565b611fc582611042565b6001600160a01b0316611fd785611042565b6001600160a01b03161461201a5760405162461bcd60e51b815260206004820152600a6024820152693234b3331037bbb732b960b11b6044820152606401610908565b60008281526012602052604080822054868352912054146120685760405162461bcd60e51b8152602060048201526008602482015267191a5999881bda5960c21b6044820152606401610908565b6120728282610d74565b61208e5760405162461bcd60e51b815260040161090890614316565b6000838152601360205260408082208383529120805482546001600160401b03918216600160401b909104909116101561212457805482546001600160401b03918216916120e591600160401b90041660016141ec565b6001600160401b0316146120f857600080fd5b8154815467ffffffffffffffff19166001600160401b0390911617815561211f86866128ce565b6121ae565b815481546001600160401b03918216600160401b90910490911610156121ae57815481546001600160401b039182169161216791600160401b90041660016141ec565b6001600160401b03161461217a57600080fd5b8154815467ffffffffffffffff60401b1916600160401b918290046001600160401b03169091021781556121ae86866128ce565b60008681526012602052604090206121c89060020161286d565b6121d5576121d586612983565b505050505050565b6000818152601260205260409020606090610d8f6002820161289b565b6000828152601260205260408120819081906122186002820161286d565b85106122555760405162461bcd60e51b815260206004820152600c60248201526b6f7574206f662072616e676560a01b6044820152606401610908565b6122626002820186612877565b60008181526013602052604090205490976001600160401b038083169850600160401b90920490911695509350505050565b6001546001600160a01b031633146122e15760405162461bcd60e51b815260206004820152601060248201526f37b7363ca832b73234b733a7bbb732b960811b6044820152606401610908565b6000546001546040517f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236492612324926001600160a01b03918216929116906141ba565b60405180910390a1600154600080546001600160a01b0319166001600160a01b03909216918217815560405190917fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b91612380919084906141ba565b60405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b03163314806123cd57506000546001600160a01b031633145b6123e95760405162461bcd60e51b81526004016109089061400c565b6011805467ffffffffffffffff19166001600160401b0392909216919091179055565b6000546001600160a01b031633146124365760405162461bcd60e51b815260040161090890614197565b6001546040517fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b91612380916001600160a01b039091169084906141ba565b60008181526012602052604081206109499060020161286d565b60008381526012602052604081209080805b84811015612519578585828181106124bb576124bb614181565b9050602002013592506124ce8784610d74565b15612507576000838152601360205260409020805490925042600160401b9091046001600160401b0316116125075761250787846128ce565b8061251181614166565b9150506124a1565b506125268360020161286d565b6121d557612533866115ee565b156125745760405162461bcd60e51b815260206004820152601160248201527018d85b881b9bdd08189d5c9b881e139195607a1b6044820152606401610908565b6121d586612983565b60006001600160e01b0319821663780e9d6360e01b1480610949575061094982613017565b600081815260086020526040902080546001600160a01b0319166001600160a01b03841690811790915581906125d782611042565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600660205260408120546001600160a01b03166126445760405162461bcd60e51b81526004016109089061433c565b600061264f83611042565b9050806001600160a01b0316846001600160a01b0316148061268a5750836001600160a01b031661267f846109e1565b6001600160a01b0316145b806126ba57506001600160a01b0380821660009081526009602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b03166126d582611042565b6001600160a01b03161461273d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610908565b6001600160a01b03821661279f5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610908565b6127aa838383613067565b6127b56000826125a2565b6001600160a01b03831660009081526007602052604081208054600192906127de908490614388565b90915550506001600160a01b038216600090815260076020526040812080546001929061280c9084906141d4565b909155505060008181526006602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000610949825490565b6000610d8f83836130c2565b60008181526001830160205260408120541515610d8f565b60606000610d8f836130ec565b60006128b5848484613148565b506128c285600f5461319f565b50600f54949350505050565b600081815260136020908152604080832080546001600160801b03191690558483526012909152902061290490600201826131b9565b5060408051600180825281830190925260009160208083019080368337019050509050818160008151811061293b5761293b614181565b6020026020010181815250507fdaf2d83211561a92f21e9184ba96aac6a054d6e4132aa90592fd88eeff75879c816040516129769190613fb0565b60405180910390a1505050565b61298c816131c5565b600081815260126020526040812081815560018101805467ffffffffffffffff1916905590600282018181816129c28282613902565b50505050505050565b601080549060006129db83614166565b90915550506040805180820182526001600160401b0380851682528381166020808401918252601080546000908152601383528681209551865494518616600160401b026001600160801b03199095169516949094179290921790935554868252601290925291909120612a549160029091019061326c565b5060105460408051918252602082018590526001600160401b0380851691830191909152821660608201527fd89b3a389fda649f6511ea8da7b3cda710b4478a1a29d5e7a92c89b0b669aa1290608001612976565b6040516331a9108f60e11b81526004810182905260009081906001600160a01b03851690636352211e90602401602060405180830381865afa158015612af3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b17919061423f565b90506001600160a01b038116612b3f5760405162461bcd60e51b81526004016109089061433c565b806001600160a01b0316856001600160a01b03161480612bd3575060405163020604bf60e21b8152600481018490526001600160a01b03808716919086169063081812fc90602401602060405180830381865afa158015612ba4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc8919061423f565b6001600160a01b0316145b80612c48575060405163e985e9c560e01b81526001600160a01b0385169063e985e9c590612c0790849089906004016141ba565b602060405180830381865afa158015612c24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c48919061439f565b95945050505050565b612c5a33611c0a565b80612c6a5750612c6a3283612610565b612caf5760405162461bcd60e51b81526020600482015260166024820152751b9bdd081bdddb995c881b9bdc88185c1c1c9bdd995960521b6044820152606401610908565b60008281526012602090815260408083208484526013909252909120805442600160401b9091046001600160401b03161015612d1b5760405162461bcd60e51b815260206004820152600b60248201526a1a5b9d985b1a5908195b9960aa1b6044820152606401610908565b8054426001600160401b039091161115612d675760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081cdd185c9d609a1b6044820152606401610908565b612d746002830184612883565b612d905760405162461bcd60e51b815260040161090890614316565b815460009081526015602090815260409182902080546001600160a01b0319166001600160a01b038916908117909155825132815291820152908101859052606081018490527faa2ece7572de692cad6a7904cef219542877644f291ca8565ce9aa8a4ba21a379060800160405180910390a15050505050565b612e158484846126c2565b612e2184848484613278565b611bf45760405162461bcd60e51b8152600401610908906143bc565b600081815260126020526040812090612e586002830161286d565b905060005b81811015612ea65760136000612e766002860184612877565b8152602081019190915260400160002080546001600160801b031916905580612e9e81614166565b915050612e5d565b507fdaf2d83211561a92f21e9184ba96aac6a054d6e4132aa90592fd88eeff75879c612ed48360020161289b565b604051612ee19190613fb0565b60405180910390a16002820160008181612efb8282613902565b5050835460009081526014602052604081205550610b87905083612983565b606081612f3e5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612f685780612f5281614166565b9150612f619050600a83614424565b9150612f42565b6000816001600160401b03811115612f8257612f82613c2b565b6040519080825280601f01601f191660200182016040528015612fac576020820181803683370190505b5090505b84156126ba57612fc1600183614388565b9150612fce600a86614438565b612fd99060306141d4565b60f81b818381518110612fee57612fee614181565b60200101906001600160f81b031916908160001a905350613010600a86614424565b9450612fb0565b60006001600160e01b031982166380ac58cd60e01b148061304857506001600160e01b03198216635b5e139f60e01b145b8061094957506301ffc9a760e01b6001600160e01b0319831614610949565b613072838383613373565b600081815260126020526040812060010180546001600160401b0316916130988361444c565b91906101000a8154816001600160401b0302191690836001600160401b0316021790555050505050565b60008260000182815481106130d9576130d9614181565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561313c57602002820191906000526020600020905b815481526020019060010190808311613128575b50505050509050919050565b600f80546000918261315983614166565b9091555050600f8054600090815260126020526040902085815560018101805467ffffffffffffffff1916905590546131939085856129cb565b5050600f549392505050565b61103e82826040518060200160405280600081525061342b565b6000610d8f838361345e565b60006131d082611042565b90506131de81600084613067565b6131e96000836125a2565b6001600160a01b0381166000908152600760205260408120805460019290613212908490614388565b909155505060008281526006602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000610d8f8383613551565b60006001600160a01b0384163b1561336b57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906132bc903390899088908890600401614473565b6020604051808303816000875af19250505080156132f7575060408051601f3d908101601f191682019092526132f4918101906144b0565b60015b613351573d808015613325576040519150601f19603f3d011682016040523d82523d6000602084013e61332a565b606091505b5080516133495760405162461bcd60e51b8152600401610908906143bc565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506126ba565b5060016126ba565b6001600160a01b0383166133ce576133c981600c80546000838152600d60205260408120829055600182018355919091527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70155565b6133f1565b816001600160a01b0316836001600160a01b0316146133f1576133f183826135a0565b6001600160a01b03821661340857610b878161363d565b826001600160a01b0316826001600160a01b031614610b8757610b8782826136ec565b6134358383613730565b6134426000848484613278565b610b875760405162461bcd60e51b8152600401610908906143bc565b60008181526001830160205260408120548015613547576000613482600183614388565b855490915060009061349690600190614388565b90508181146134fb5760008660000182815481106134b6576134b6614181565b90600052602060002001549050808760000184815481106134d9576134d9614181565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061350c5761350c6144cd565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610949565b6000915050610949565b600081815260018301602052604081205461359857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610949565b506000610949565b600060016135ad8461161e565b6135b79190614388565b6000838152600b602052604090205490915080821461360a576001600160a01b0384166000908152600a602090815260408083208584528252808320548484528184208190558352600b90915290208190555b506000918252600b602090815260408084208490556001600160a01b039094168352600a81528383209183525290812055565b600c5460009061364f90600190614388565b6000838152600d6020526040812054600c805493945090928490811061367757613677614181565b9060005260206000200154905080600c838154811061369857613698614181565b6000918252602080832090910192909255828152600d9091526040808220849055858252812055600c8054806136d0576136d06144cd565b6001900381819060005260206000200160009055905550505050565b60006136f78361161e565b6001600160a01b039093166000908152600a602090815260408083208684528252808320859055938252600b9052919091209190915550565b6001600160a01b0382166137865760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610908565b6000818152600660205260409020546001600160a01b0316156137eb5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610908565b6137f760008383613067565b6001600160a01b03821660009081526007602052604081208054600192906138209084906141d4565b909155505060008181526006602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b82805461388a9061402f565b90600052602060002090601f0160209004810192826138ac57600085556138f2565b82601f106138c557805160ff19168380011785556138f2565b828001600101855582156138f2579182015b828111156138f25782518255916020019190600101906138d7565b506138fe929150613923565b5090565b50805460008255906000526020600020908101906139209190613923565b50565b5b808211156138fe5760008155600101613924565b801515811461392057600080fd5b60006020828403121561395857600080fd5b8135610d8f81613938565b6001600160e01b03198116811461392057600080fd5b60006020828403121561398b57600080fd5b8135610d8f81613963565b60005b838110156139b1578181015183820152602001613999565b83811115611bf45750506000910152565b600081518084526139da816020860160208601613996565b601f01601f19169290920160200192915050565b602081526000610d8f60208301846139c2565b600060208284031215613a1357600080fd5b5035919050565b6001600160a01b038116811461392057600080fd5b60008060408385031215613a4257600080fd5b8235613a4d81613a1a565b946020939093013593505050565b600080600080600060808688031215613a7357600080fd5b8535613a7e81613a1a565b94506020860135613a8e81613a1a565b93506040860135925060608601356001600160401b0380821115613ab157600080fd5b818801915088601f830112613ac557600080fd5b813581811115613ad457600080fd5b896020828501011115613ae657600080fd5b9699959850939650602001949392505050565b600080600060608486031215613b0e57600080fd5b8335613b1981613a1a565b92506020840135613b2981613a1a565b929592945050506040919091013590565b60008060408385031215613b4d57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015613b8c57815187529582019590820190600101613b70565b509495945050505050565b600081518084526020808501945080840160005b83811015613b8c5781516001600160401b031687529582019590820190600101613bab565b85815260a060208201526000613be960a0830187613b5c565b8281036040840152613bfb8187613b97565b90508281036060840152613c0f8186613b97565b9150506001600160401b03831660808301529695505050505050565b634e487b7160e01b600052604160045260246000fd5b60006001600160401b0380841115613c5b57613c5b613c2b565b604051601f8501601f19908116603f01168101908282118183101715613c8357613c83613c2b565b81604052809350858152868686011115613c9c57600080fd5b858560208301376000602087830101525050509392505050565b600082601f830112613cc757600080fd5b610d8f83833560208501613c41565b600060208284031215613ce857600080fd5b81356001600160401b03811115613cfe57600080fd5b6126ba84828501613cb6565b600060208284031215613d1c57600080fd5b8135610d8f81613a1a565b80356001600160401b0381168114613d3e57600080fd5b919050565b600080600080600060a08688031215613d5b57600080fd5b8535945060208601359350613d7260408701613d27565b9250613d8060608701613d27565b91506080860135613d9081613a1a565b809150509295509295909350565b600080600060608486031215613db357600080fd5b8335613dbe81613a1a565b95602085013595506040909401359392505050565b60008060408385031215613de657600080fd5b8235613df181613a1a565b91506020830135613e0181613938565b809150509250929050565b600080600060608486031215613e2157600080fd5b8335613e2c81613a1a565b925060208401356001600160401b0380821115613e4857600080fd5b613e5487838801613cb6565b93506040860135915080821115613e6a57600080fd5b50613e7786828701613cb6565b9150509250925092565b60008060008060808587031215613e9757600080fd5b8435613ea281613a1a565b93506020850135613eb281613a1a565b92506040850135915060608501356001600160401b03811115613ed457600080fd5b8501601f81018713613ee557600080fd5b613ef487823560208401613c41565b91505092959194509250565b600080600060408486031215613f1557600080fd5b8335925060208401356001600160401b0380821115613f3357600080fd5b818601915086601f830112613f4757600080fd5b813581811115613f5657600080fd5b8760208260051b8501011115613f6b57600080fd5b6020830194508093505050509250925092565b60008060008060808587031215613f9457600080fd5b5050823594602084013594506040840135936060013592509050565b602081526000610d8f6020830184613b5c565b60008060408385031215613fd657600080fd5b8235613fe181613a1a565b91506020830135613e0181613a1a565b60006020828403121561400357600080fd5b610d8f82613d27565b60208082526009908201526837b7363ca0b236b4b760b91b604082015260600190565b600181811c9082168061404357607f821691505b6020821081141561406457634e487b7160e01b600052602260045260246000fd5b50919050565b80516000906020808401838315613b8c5781516001600160401b031687529582019590820190600101613bab565b85815260006020808301875182890160005b828110156140c6578151845292840192908401906001016140aa565b5050506140dc6140d6828961406a565b8761406a565b60c09590951b6001600160c01b0319168552505060089092019695505050505050565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600060001982141561417a5761417a614150565b5060010190565b634e487b7160e01b600052603260045260246000fd5b60208082526009908201526837b7363ca7bbb732b960b91b604082015260600190565b6001600160a01b0392831681529116602082015260400190565b600082198211156141e7576141e7614150565b500190565b60006001600160401b0380831681851680830382111561420e5761420e614150565b01949350505050565b60006001600160401b038381169083168181101561423757614237614150565b039392505050565b60006020828403121561425157600080fd5b8151610d8f81613a1a565b6000815161426e818560208601613996565b9290920192915050565b600080845481600182811c91508083168061429457607f831692505b60208084108214156142b457634e487b7160e01b86526022600452602486fd5b8180156142c857600181146142d957614306565b60ff19861689528489019650614306565b60008b81526020902060005b868110156142fe5781548b8201529085019083016142e5565b505084890196505b505050505050612c48818561425c565b6020808252600c908201526b6e6f7420636f6e7461696e7360a01b604082015260600190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60008282101561439a5761439a614150565b500390565b6000602082840312156143b157600080fd5b8151610d8f81613938565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b6000826144335761443361440e565b500490565b6000826144475761444761440e565b500690565b60006001600160401b038083168181141561446957614469614150565b6001019392505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906144a6908301846139c2565b9695505050505050565b6000602082840312156144c257600080fd5b8151610d8f81613963565b634e487b7160e01b600052603160045260246000fdfea264697066735822122073d06d89b45fdcf72ee629030357568ecaa339891eb6c987b26004b01beb218f64736f6c634300080a0033000000000000000000000000f87e31492faf9a91b02ee0deaad50d51d56d5d4d000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000018446f75626c6520446563656e7472616c616e64204c414e4400000000000000000000000000000000000000000000000000000000000000000000000000000006646f4c414e440000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106103775760003560e01c80638bb126a7116101d3578063cb697d1e11610104578063ebbc4965116100a2578063f2fde38b1161007c578063f2fde38b1461087d578063f851a44014610890578063fd83de62146108a3578063fe909ee4146108b657600080fd5b8063ebbc496514610842578063ee544b151461084a578063f01478321461086a57600080fd5b8063dbe102c0116100de578063dbe102c01461079b578063e30c3978146107bb578063e42e66a9146107ce578063e985e9c51461080657600080fd5b8063cb697d1e1461076e578063d7c6e71414610781578063d816f0911461078857600080fd5b8063abb2176a11610171578063b73bb40a1161014b578063b73bb40a14610722578063b88d4fde14610735578063c4a0db9614610748578063c87b56dd1461075b57600080fd5b8063abb2176a146106dd578063b0467deb146106e6578063b2b45df51461070f57600080fd5b806398e5d38f116101ad57806398e5d38f1461069b578063a050ac8f146106ae578063a22cb465146106b7578063a6963b97146106ca57600080fd5b80638bb126a71461062b5780638da5cb5b1461068057806395d89b411461069357600080fd5b806342842e0e116102ad5780636352211e1161024b57806370982aa51161022557806370982aa5146105ea57806370a08231146105fd578063715018a61461061057806385b5b1321461061857600080fd5b80636352211e146105b1578063704b6c02146105c4578063706023c1146105d757600080fd5b80634f558e79116102875780634f558e79146105545780634f6ccce71461056757806352332ed81461057a57806355f804b31461059e57600080fd5b806342842e0e1461051b578063438e15fc1461052e5780634e7765e31461054157600080fd5b806318160ddd1161031a57806325cb25b0116102f457806325cb25b0146104a05780632f745c59146104b1578063393b17a4146104c45780633d46b819146104d757600080fd5b806318160ddd146104655780631aa144981461046d57806323b872dd1461048d57600080fd5b8063081812fc11610356578063081812fc146103ce578063095ea7b3146103f9578063150b7a021461040c578063159a64751461044457600080fd5b806295d6451461037c57806301ffc9a71461039157806306fdde03146103b9575b600080fd5b61038f61038a366004613946565b6108c9565b005b6103a461039f366004613979565b610924565b60405190151581526020015b60405180910390f35b6103c161094f565b6040516103b091906139ee565b6103e16103dc366004613a01565b6109e1565b6040516001600160a01b0390911681526020016103b0565b61038f610407366004613a2f565b610a76565b61042b61041a366004613a5b565b630a85bd0160e11b95945050505050565b6040516001600160e01b031990911681526020016103b0565b610457610452366004613a01565b610b8c565b6040519081526020016103b0565b600c54610457565b61045761047b366004613a01565b60009081526012602052604090205490565b61038f61049b366004613af9565b610be3565b600e546001600160a01b03166103e1565b6104576104bf366004613a2f565b610c14565b6103a46104d2366004613a01565b610caa565b6105036104e5366004613a01565b6000908152601260205260409020600101546001600160401b031690565b6040516001600160401b0390911681526020016103b0565b61038f610529366004613af9565b610d59565b6103a461053c366004613b3a565b610d74565b61045761054f366004613a01565b610d96565b6103a4610562366004613a01565b610da1565b610457610575366004613a01565b610dc0565b61058d610588366004613a01565b610e53565b6040516103b0959493929190613bd0565b61038f6105ac366004613cd6565b610fec565b6103e16105bf366004613a01565b611042565b61038f6105d2366004613d0a565b6110b9565b6104576105e5366004613d43565b61114c565b6103a46105f8366004613a01565b6115ee565b61045761060b366004613d0a565b61161e565b61038f6116a5565b610457610626366004613a01565b6117c9565b610660610639366004613a01565b6000908152601360205260409020546001600160401b0380821692600160401b9092041690565b604080516001600160401b039384168152929091166020830152016103b0565b6000546103e1906001600160a01b031681565b6103c16119f6565b61038f6106a9366004613d9e565b611a05565b61045760105481565b61038f6106c5366004613dd3565b611a8f565b6104576106d8366004613a01565b611b54565b610457600f5481565b6103e16106f4366004613a01565b6000908152601560205260409020546001600160a01b031690565b61038f61071d366004613e0c565b611b68565b6103a4610730366004613a01565b611bfa565b61038f610743366004613e81565b611c05565b61038f610756366004613f00565b611c38565b6103c1610769366004613a01565b611d81565b6103a461077c366004613f00565b611db5565b60016103a4565b61038f610796366004613f7e565b611f70565b6107ae6107a9366004613a01565b6121dd565b6040516103b09190613fb0565b6001546103e1906001600160a01b031681565b6107e16107dc366004613b3a565b6121fa565b604080519384526001600160401b0392831660208501529116908201526060016103b0565b6103a4610814366004613fc3565b6001600160a01b03918216600090815260096020908152604080832093909416825291909152205460ff1690565b61038f612294565b610457610858366004613a01565b60009081526014602052604090205490565b61038f610878366004613ff1565b6123aa565b61038f61088b366004613d0a565b61240c565b6002546103e1906001600160a01b031681565b6104576108b1366004613a01565b612475565b61038f6108c4366004613f00565b61248f565b6002546001600160a01b03163314806108ec57506000546001600160a01b031633145b6109115760405162461bcd60e51b81526004016109089061400c565b60405180910390fd5b6016805460ff1916911515919091179055565b60006001600160e01b03198216632e541b5b60e21b148061094957506109498261257d565b92915050565b60606017805461095e9061402f565b80601f016020809104026020016040519081016040528092919081815260200182805461098a9061402f565b80156109d75780601f106109ac576101008083540402835291602001916109d7565b820191906000526020600020905b8154815290600101906020018083116109ba57829003601f168201915b5050505050905090565b6000818152600660205260408120546001600160a01b0316610a5a5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610908565b506000908152600860205260409020546001600160a01b031690565b6000610a8182611042565b9050806001600160a01b0316836001600160a01b03161415610aef5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610908565b336001600160a01b0382161480610b0b5750610b0b8133610814565b610b7d5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610908565b610b8783836125a2565b505050565b600080600080600080610b9e87610e53565b945094509450945094508484848484604051602001610bc1959493929190614098565b6040516020818303038152906040528051906020012095505050505050919050565b610bed3382612610565b610c095760405162461bcd60e51b8152600401610908906140ff565b610b878383836126c2565b6000610c1f8361161e565b8210610c815760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610908565b506001600160a01b03919091166000908152600a60209081526040808320938352929052205490565b600081815260126020526040812081610cc56002830161286d565b90506000805b82811015610d4d57610ce06002850182612877565b600081815260136020526040902054909250426001600160401b0390911611801590610d2a5750600082815260136020526040902054600160401b90046001600160401b03164211155b15610d3b5750600195945050505050565b80610d4581614166565b915050610ccb565b50600095945050505050565b610b8783838360405180602001604052806000815250611c05565b6000828152601260205260408120610d8f9060020183612883565b9392505050565b6000610949826117c9565b6000818152600660205260408120546001600160a01b03161515610949565b6000610dcb600c5490565b8210610e2e5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610908565b600c8281548110610e4157610e41614181565b90600052602060002001549050919050565b6000818152601260205260408120805460018201549092606092839283926001600160401b039091169190610e8a6002830161286d565b90506000816001600160401b03811115610ea657610ea6613c2b565b604051908082528060200260200182016040528015610ecf578160200160208202803683370190505b509550816001600160401b03811115610eea57610eea613c2b565b604051908082528060200260200182016040528015610f13578160200160208202803683370190505b509450610f228360020161289b565b965060005b82811015610fdf57610f3c6002850182612877565b60008181526013602052604090205488519193506001600160401b031690889083908110610f6c57610f6c614181565b6001600160401b039283166020918202929092018101919091526000848152601390915260409020548751600160401b90910490911690879083908110610fb557610fb5614181565b6001600160401b039092166020928302919091019091015280610fd781614166565b915050610f27565b5050505091939590929450565b6002546001600160a01b031633148061100f57506000546001600160a01b031633145b61102b5760405162461bcd60e51b81526004016109089061400c565b805161103e90601990602084019061387e565b5050565b6000818152600660205260408120546001600160a01b0316806109495760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610908565b6000546001600160a01b031633146110e35760405162461bcd60e51b815260040161090890614197565b6002546040517ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc91611122916001600160a01b039091169084906141ba565b60405180910390a1600280546001600160a01b0319166001600160a01b0392909216919091179055565b601654600090849060ff16156111a55742816001600160401b031611156111a55760405162461bcd60e51b815260206004820152600d60248201526c6d7573742066726f6d206e6f7760981b6044820152606401610908565b600260035414156111f85760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610908565b6002600355426001600160401b0386161015611212574294505b61121c3388612610565b8061122c575061122c3288612610565b6112715760405162461bcd60e51b81526020600482015260166024820152751b9bdd081bdddb995c881b9bdc88185c1c1c9bdd995960521b6044820152606401610908565b846001600160401b0316846001600160401b03161180156112b057506011546112a3906001600160401b0316426141d4565b846001600160401b031611155b6112f35760405162461bcd60e51b81526020600482015260146024820152731a5b9d985b1a59081cdd185c9d081bdc88195b9960621b6044820152606401610908565b600087815260126020526040902061130b8888610d74565b6113575760405162461bcd60e51b815260206004820152601760248201527f6e6f7420636f6e7461696e73206475726174696f6e49640000000000000000006044820152606401610908565b600087815260136020526040902080546001600160401b0390811690881610801590611398575080546001600160401b03600160401b909104811690871611155b6113d75760405162461bcd60e51b815260206004820152601060248201526f34b73b30b634b210323ab930ba34b7b760811b6044820152606401610908565b80546000906001600160401b038981169116148015611409575081546001600160401b03888116600160401b90920416145b1561144d5761141e8684600001548a8a6128a8565b9450601054905061142f8a8a6128ce565b61143b8360020161286d565b611448576114488a612983565b61158c565b81546001600160401b03898116911614801561147d575081546001600160401b03888116600160401b9092041614155b156114ae5761148d8760016141ec565b825467ffffffffffffffff19166001600160401b0391909116178255611574565b81546001600160401b038981169116148015906114de575081546001600160401b03888116600160401b90920416145b1561151a576114ee600189614217565b82546001600160401b0391909116600160401b0267ffffffffffffffff60401b19909116178255611574565b42886001600160401b0316111561154c57815461154c908b906001600160401b031661154760018c614217565b6129cb565b6115578760016141ec565b825467ffffffffffffffff19166001600160401b03919091161782555b6115848684600001548a8a6128a8565b945060105490505b42886001600160401b031614156115a8576115a8868683611a05565b6040518a81527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a15050600160035550909695505050505050565b6000816115fd57506000919050565b50600081815260126020908152604080832054835260149091529020541490565b60006001600160a01b0382166116895760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610908565b506001600160a01b031660009081526007602052604090205490565b6000546001600160a01b031633146116cf5760405162461bcd60e51b815260040161090890614197565b600080546040517f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b23649261170b926001600160a01b0316916141ba565b60405180910390a16002546040517ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc91611753916001600160a01b03909116906000906141ba565b60405180910390a16001546040517fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b9161179b916001600160a01b03909116906000906141ba565b60405180910390a1600080546001600160a01b03199081169091556001805482169055600280549091169055565b60006002600354141561181e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610908565b6002600355600082815260146020526040902054156118705760405162461bcd60e51b815260206004820152600e60248201526d185b1c9958591e481dd85c9c195960921b6044820152606401610908565b600e546118889032906001600160a01b031684612aa9565b806118a65750600e546118a69033906001600160a01b031684612aa9565b6118eb5760405162461bcd60e51b815260206004820152601660248201527537b7363c9030b8383937bb32b21037b91037bbb732b960511b6044820152606401610908565b600e546040516331a9108f60e11b8152600481018490526000916001600160a01b031690636352211e90602401602060405180830381865afa158015611935573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611959919061423f565b600e54604051632142170760e11b81526001600160a01b038084166004830152306024830152604482018790529293509116906342842e0e90606401600060405180830381600087803b1580156119af57600080fd5b505af11580156119c3573d6000803e3d6000fd5b505050506119da8184426001600160401b036128a8565b6000938452601460205260409093208390555050600160035590565b60606018805461095e9061402f565b611a10838383612c51565b60008281526012602052604090819020600e5481549251630585816360e51b815260048101939093526001600160a01b038681166024850152919291169063b0b02c6090604401600060405180830381600087803b158015611a7157600080fd5b505af1158015611a85573d6000803e3d6000fd5b5050505050505050565b6001600160a01b038216331415611ae85760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610908565b3360008181526009602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600081815260146020526040812054610949565b600e546001600160a01b031615611bb25760405162461bcd60e51b815260206004820152600e60248201526d185b1c9958591e481a5b9a5d195960921b6044820152606401610908565b600e80546001600160a01b0319166001600160a01b0385161790558151611be090601790602085019061387e565b508051611bf490601890602084019061387e565b50505050565b6000610949826115ee565b611c10335b83612610565b611c2c5760405162461bcd60e51b8152600401610908906140ff565b611bf484848484612e0a565b611c423384612610565b611c5e5760405162461bcd60e51b8152600401610908906140ff565b611c69838383611db5565b611ca55760405162461bcd60e51b815260206004820152600d60248201526c63616e6e6f742072656465656d60981b6044820152606401610908565b6000838152601260205260409020600e546001600160a01b03166342842e0e30611cce87611042565b845460405160e085901b6001600160e01b03191681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b158015611d1f57600080fd5b505af1158015611d33573d6000803e3d6000fd5b50505050611d4084612e3d565b805460408051918252602082018690527fe3829d5463fae0f748d927f86f762044188c9ce53d91a394eb93e98354cc3092910160405180910390a150505050565b60606019611d8e83612f1a565b604051602001611d9f929190614278565b6040516020818303038152906040529050919050565b6000611dc0846115ee565b611df75760405162461bcd60e51b81526020600482015260086024820152671b9bdd081e13919560c21b6044820152606401610908565b60008481526012602052604081209060138186868281611e1957611e19614181565b602090810292909201358352508101919091526040016000208054909150426001600160401b039091161115611e5457600092505050610d8f565b8054600160401b90046001600160401b031660015b85811015611f5957611e9f878783818110611e8657611e86614181565b905060200201358560020161288390919063ffffffff16565b611edb5760405162461bcd60e51b815260206004820152600d60248201526c6f7574206f662062756e646c6560981b6044820152606401610908565b60136000888884818110611ef157611ef1614181565b6020908102929092013583525081019190915260400160002080549093506001600160401b0316611f238360016141ec565b6001600160401b03161415611f47578254600160401b90046001600160401b031691505b80611f5181614166565b915050611e69565b506001600160401b03908116149695505050505050565b611f7a3385612610565b611f965760405162461bcd60e51b8152600401610908906140ff565b611fa08484610d74565b611fbc5760405162461bcd60e51b815260040161090890614316565b611fc582611042565b6001600160a01b0316611fd785611042565b6001600160a01b03161461201a5760405162461bcd60e51b815260206004820152600a6024820152693234b3331037bbb732b960b11b6044820152606401610908565b60008281526012602052604080822054868352912054146120685760405162461bcd60e51b8152602060048201526008602482015267191a5999881bda5960c21b6044820152606401610908565b6120728282610d74565b61208e5760405162461bcd60e51b815260040161090890614316565b6000838152601360205260408082208383529120805482546001600160401b03918216600160401b909104909116101561212457805482546001600160401b03918216916120e591600160401b90041660016141ec565b6001600160401b0316146120f857600080fd5b8154815467ffffffffffffffff19166001600160401b0390911617815561211f86866128ce565b6121ae565b815481546001600160401b03918216600160401b90910490911610156121ae57815481546001600160401b039182169161216791600160401b90041660016141ec565b6001600160401b03161461217a57600080fd5b8154815467ffffffffffffffff60401b1916600160401b918290046001600160401b03169091021781556121ae86866128ce565b60008681526012602052604090206121c89060020161286d565b6121d5576121d586612983565b505050505050565b6000818152601260205260409020606090610d8f6002820161289b565b6000828152601260205260408120819081906122186002820161286d565b85106122555760405162461bcd60e51b815260206004820152600c60248201526b6f7574206f662072616e676560a01b6044820152606401610908565b6122626002820186612877565b60008181526013602052604090205490976001600160401b038083169850600160401b90920490911695509350505050565b6001546001600160a01b031633146122e15760405162461bcd60e51b815260206004820152601060248201526f37b7363ca832b73234b733a7bbb732b960811b6044820152606401610908565b6000546001546040517f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236492612324926001600160a01b03918216929116906141ba565b60405180910390a1600154600080546001600160a01b0319166001600160a01b03909216918217815560405190917fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b91612380919084906141ba565b60405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b03163314806123cd57506000546001600160a01b031633145b6123e95760405162461bcd60e51b81526004016109089061400c565b6011805467ffffffffffffffff19166001600160401b0392909216919091179055565b6000546001600160a01b031633146124365760405162461bcd60e51b815260040161090890614197565b6001546040517fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b91612380916001600160a01b039091169084906141ba565b60008181526012602052604081206109499060020161286d565b60008381526012602052604081209080805b84811015612519578585828181106124bb576124bb614181565b9050602002013592506124ce8784610d74565b15612507576000838152601360205260409020805490925042600160401b9091046001600160401b0316116125075761250787846128ce565b8061251181614166565b9150506124a1565b506125268360020161286d565b6121d557612533866115ee565b156125745760405162461bcd60e51b815260206004820152601160248201527018d85b881b9bdd08189d5c9b881e139195607a1b6044820152606401610908565b6121d586612983565b60006001600160e01b0319821663780e9d6360e01b1480610949575061094982613017565b600081815260086020526040902080546001600160a01b0319166001600160a01b03841690811790915581906125d782611042565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600660205260408120546001600160a01b03166126445760405162461bcd60e51b81526004016109089061433c565b600061264f83611042565b9050806001600160a01b0316846001600160a01b0316148061268a5750836001600160a01b031661267f846109e1565b6001600160a01b0316145b806126ba57506001600160a01b0380821660009081526009602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b03166126d582611042565b6001600160a01b03161461273d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610908565b6001600160a01b03821661279f5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610908565b6127aa838383613067565b6127b56000826125a2565b6001600160a01b03831660009081526007602052604081208054600192906127de908490614388565b90915550506001600160a01b038216600090815260076020526040812080546001929061280c9084906141d4565b909155505060008181526006602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000610949825490565b6000610d8f83836130c2565b60008181526001830160205260408120541515610d8f565b60606000610d8f836130ec565b60006128b5848484613148565b506128c285600f5461319f565b50600f54949350505050565b600081815260136020908152604080832080546001600160801b03191690558483526012909152902061290490600201826131b9565b5060408051600180825281830190925260009160208083019080368337019050509050818160008151811061293b5761293b614181565b6020026020010181815250507fdaf2d83211561a92f21e9184ba96aac6a054d6e4132aa90592fd88eeff75879c816040516129769190613fb0565b60405180910390a1505050565b61298c816131c5565b600081815260126020526040812081815560018101805467ffffffffffffffff1916905590600282018181816129c28282613902565b50505050505050565b601080549060006129db83614166565b90915550506040805180820182526001600160401b0380851682528381166020808401918252601080546000908152601383528681209551865494518616600160401b026001600160801b03199095169516949094179290921790935554868252601290925291909120612a549160029091019061326c565b5060105460408051918252602082018590526001600160401b0380851691830191909152821660608201527fd89b3a389fda649f6511ea8da7b3cda710b4478a1a29d5e7a92c89b0b669aa1290608001612976565b6040516331a9108f60e11b81526004810182905260009081906001600160a01b03851690636352211e90602401602060405180830381865afa158015612af3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b17919061423f565b90506001600160a01b038116612b3f5760405162461bcd60e51b81526004016109089061433c565b806001600160a01b0316856001600160a01b03161480612bd3575060405163020604bf60e21b8152600481018490526001600160a01b03808716919086169063081812fc90602401602060405180830381865afa158015612ba4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc8919061423f565b6001600160a01b0316145b80612c48575060405163e985e9c560e01b81526001600160a01b0385169063e985e9c590612c0790849089906004016141ba565b602060405180830381865afa158015612c24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c48919061439f565b95945050505050565b612c5a33611c0a565b80612c6a5750612c6a3283612610565b612caf5760405162461bcd60e51b81526020600482015260166024820152751b9bdd081bdddb995c881b9bdc88185c1c1c9bdd995960521b6044820152606401610908565b60008281526012602090815260408083208484526013909252909120805442600160401b9091046001600160401b03161015612d1b5760405162461bcd60e51b815260206004820152600b60248201526a1a5b9d985b1a5908195b9960aa1b6044820152606401610908565b8054426001600160401b039091161115612d675760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081cdd185c9d609a1b6044820152606401610908565b612d746002830184612883565b612d905760405162461bcd60e51b815260040161090890614316565b815460009081526015602090815260409182902080546001600160a01b0319166001600160a01b038916908117909155825132815291820152908101859052606081018490527faa2ece7572de692cad6a7904cef219542877644f291ca8565ce9aa8a4ba21a379060800160405180910390a15050505050565b612e158484846126c2565b612e2184848484613278565b611bf45760405162461bcd60e51b8152600401610908906143bc565b600081815260126020526040812090612e586002830161286d565b905060005b81811015612ea65760136000612e766002860184612877565b8152602081019190915260400160002080546001600160801b031916905580612e9e81614166565b915050612e5d565b507fdaf2d83211561a92f21e9184ba96aac6a054d6e4132aa90592fd88eeff75879c612ed48360020161289b565b604051612ee19190613fb0565b60405180910390a16002820160008181612efb8282613902565b5050835460009081526014602052604081205550610b87905083612983565b606081612f3e5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612f685780612f5281614166565b9150612f619050600a83614424565b9150612f42565b6000816001600160401b03811115612f8257612f82613c2b565b6040519080825280601f01601f191660200182016040528015612fac576020820181803683370190505b5090505b84156126ba57612fc1600183614388565b9150612fce600a86614438565b612fd99060306141d4565b60f81b818381518110612fee57612fee614181565b60200101906001600160f81b031916908160001a905350613010600a86614424565b9450612fb0565b60006001600160e01b031982166380ac58cd60e01b148061304857506001600160e01b03198216635b5e139f60e01b145b8061094957506301ffc9a760e01b6001600160e01b0319831614610949565b613072838383613373565b600081815260126020526040812060010180546001600160401b0316916130988361444c565b91906101000a8154816001600160401b0302191690836001600160401b0316021790555050505050565b60008260000182815481106130d9576130d9614181565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561313c57602002820191906000526020600020905b815481526020019060010190808311613128575b50505050509050919050565b600f80546000918261315983614166565b9091555050600f8054600090815260126020526040902085815560018101805467ffffffffffffffff1916905590546131939085856129cb565b5050600f549392505050565b61103e82826040518060200160405280600081525061342b565b6000610d8f838361345e565b60006131d082611042565b90506131de81600084613067565b6131e96000836125a2565b6001600160a01b0381166000908152600760205260408120805460019290613212908490614388565b909155505060008281526006602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000610d8f8383613551565b60006001600160a01b0384163b1561336b57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906132bc903390899088908890600401614473565b6020604051808303816000875af19250505080156132f7575060408051601f3d908101601f191682019092526132f4918101906144b0565b60015b613351573d808015613325576040519150601f19603f3d011682016040523d82523d6000602084013e61332a565b606091505b5080516133495760405162461bcd60e51b8152600401610908906143bc565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506126ba565b5060016126ba565b6001600160a01b0383166133ce576133c981600c80546000838152600d60205260408120829055600182018355919091527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70155565b6133f1565b816001600160a01b0316836001600160a01b0316146133f1576133f183826135a0565b6001600160a01b03821661340857610b878161363d565b826001600160a01b0316826001600160a01b031614610b8757610b8782826136ec565b6134358383613730565b6134426000848484613278565b610b875760405162461bcd60e51b8152600401610908906143bc565b60008181526001830160205260408120548015613547576000613482600183614388565b855490915060009061349690600190614388565b90508181146134fb5760008660000182815481106134b6576134b6614181565b90600052602060002001549050808760000184815481106134d9576134d9614181565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061350c5761350c6144cd565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610949565b6000915050610949565b600081815260018301602052604081205461359857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610949565b506000610949565b600060016135ad8461161e565b6135b79190614388565b6000838152600b602052604090205490915080821461360a576001600160a01b0384166000908152600a602090815260408083208584528252808320548484528184208190558352600b90915290208190555b506000918252600b602090815260408084208490556001600160a01b039094168352600a81528383209183525290812055565b600c5460009061364f90600190614388565b6000838152600d6020526040812054600c805493945090928490811061367757613677614181565b9060005260206000200154905080600c838154811061369857613698614181565b6000918252602080832090910192909255828152600d9091526040808220849055858252812055600c8054806136d0576136d06144cd565b6001900381819060005260206000200160009055905550505050565b60006136f78361161e565b6001600160a01b039093166000908152600a602090815260408083208684528252808320859055938252600b9052919091209190915550565b6001600160a01b0382166137865760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610908565b6000818152600660205260409020546001600160a01b0316156137eb5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610908565b6137f760008383613067565b6001600160a01b03821660009081526007602052604081208054600192906138209084906141d4565b909155505060008181526006602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b82805461388a9061402f565b90600052602060002090601f0160209004810192826138ac57600085556138f2565b82601f106138c557805160ff19168380011785556138f2565b828001600101855582156138f2579182015b828111156138f25782518255916020019190600101906138d7565b506138fe929150613923565b5090565b50805460008255906000526020600020908101906139209190613923565b50565b5b808211156138fe5760008155600101613924565b801515811461392057600080fd5b60006020828403121561395857600080fd5b8135610d8f81613938565b6001600160e01b03198116811461392057600080fd5b60006020828403121561398b57600080fd5b8135610d8f81613963565b60005b838110156139b1578181015183820152602001613999565b83811115611bf45750506000910152565b600081518084526139da816020860160208601613996565b601f01601f19169290920160200192915050565b602081526000610d8f60208301846139c2565b600060208284031215613a1357600080fd5b5035919050565b6001600160a01b038116811461392057600080fd5b60008060408385031215613a4257600080fd5b8235613a4d81613a1a565b946020939093013593505050565b600080600080600060808688031215613a7357600080fd5b8535613a7e81613a1a565b94506020860135613a8e81613a1a565b93506040860135925060608601356001600160401b0380821115613ab157600080fd5b818801915088601f830112613ac557600080fd5b813581811115613ad457600080fd5b896020828501011115613ae657600080fd5b9699959850939650602001949392505050565b600080600060608486031215613b0e57600080fd5b8335613b1981613a1a565b92506020840135613b2981613a1a565b929592945050506040919091013590565b60008060408385031215613b4d57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015613b8c57815187529582019590820190600101613b70565b509495945050505050565b600081518084526020808501945080840160005b83811015613b8c5781516001600160401b031687529582019590820190600101613bab565b85815260a060208201526000613be960a0830187613b5c565b8281036040840152613bfb8187613b97565b90508281036060840152613c0f8186613b97565b9150506001600160401b03831660808301529695505050505050565b634e487b7160e01b600052604160045260246000fd5b60006001600160401b0380841115613c5b57613c5b613c2b565b604051601f8501601f19908116603f01168101908282118183101715613c8357613c83613c2b565b81604052809350858152868686011115613c9c57600080fd5b858560208301376000602087830101525050509392505050565b600082601f830112613cc757600080fd5b610d8f83833560208501613c41565b600060208284031215613ce857600080fd5b81356001600160401b03811115613cfe57600080fd5b6126ba84828501613cb6565b600060208284031215613d1c57600080fd5b8135610d8f81613a1a565b80356001600160401b0381168114613d3e57600080fd5b919050565b600080600080600060a08688031215613d5b57600080fd5b8535945060208601359350613d7260408701613d27565b9250613d8060608701613d27565b91506080860135613d9081613a1a565b809150509295509295909350565b600080600060608486031215613db357600080fd5b8335613dbe81613a1a565b95602085013595506040909401359392505050565b60008060408385031215613de657600080fd5b8235613df181613a1a565b91506020830135613e0181613938565b809150509250929050565b600080600060608486031215613e2157600080fd5b8335613e2c81613a1a565b925060208401356001600160401b0380821115613e4857600080fd5b613e5487838801613cb6565b93506040860135915080821115613e6a57600080fd5b50613e7786828701613cb6565b9150509250925092565b60008060008060808587031215613e9757600080fd5b8435613ea281613a1a565b93506020850135613eb281613a1a565b92506040850135915060608501356001600160401b03811115613ed457600080fd5b8501601f81018713613ee557600080fd5b613ef487823560208401613c41565b91505092959194509250565b600080600060408486031215613f1557600080fd5b8335925060208401356001600160401b0380821115613f3357600080fd5b818601915086601f830112613f4757600080fd5b813581811115613f5657600080fd5b8760208260051b8501011115613f6b57600080fd5b6020830194508093505050509250925092565b60008060008060808587031215613f9457600080fd5b5050823594602084013594506040840135936060013592509050565b602081526000610d8f6020830184613b5c565b60008060408385031215613fd657600080fd5b8235613fe181613a1a565b91506020830135613e0181613a1a565b60006020828403121561400357600080fd5b610d8f82613d27565b60208082526009908201526837b7363ca0b236b4b760b91b604082015260600190565b600181811c9082168061404357607f821691505b6020821081141561406457634e487b7160e01b600052602260045260246000fd5b50919050565b80516000906020808401838315613b8c5781516001600160401b031687529582019590820190600101613bab565b85815260006020808301875182890160005b828110156140c6578151845292840192908401906001016140aa565b5050506140dc6140d6828961406a565b8761406a565b60c09590951b6001600160c01b0319168552505060089092019695505050505050565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600060001982141561417a5761417a614150565b5060010190565b634e487b7160e01b600052603260045260246000fd5b60208082526009908201526837b7363ca7bbb732b960b91b604082015260600190565b6001600160a01b0392831681529116602082015260400190565b600082198211156141e7576141e7614150565b500190565b60006001600160401b0380831681851680830382111561420e5761420e614150565b01949350505050565b60006001600160401b038381169083168181101561423757614237614150565b039392505050565b60006020828403121561425157600080fd5b8151610d8f81613a1a565b6000815161426e818560208601613996565b9290920192915050565b600080845481600182811c91508083168061429457607f831692505b60208084108214156142b457634e487b7160e01b86526022600452602486fd5b8180156142c857600181146142d957614306565b60ff19861689528489019650614306565b60008b81526020902060005b868110156142fe5781548b8201529085019083016142e5565b505084890196505b505050505050612c48818561425c565b6020808252600c908201526b6e6f7420636f6e7461696e7360a01b604082015260600190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60008282101561439a5761439a614150565b500390565b6000602082840312156143b157600080fd5b8151610d8f81613938565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b6000826144335761443361440e565b500490565b6000826144475761444761440e565b500690565b60006001600160401b038083168181141561446957614469614150565b6001019392505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906144a6908301846139c2565b9695505050505050565b6000602082840312156144c257600080fd5b8151610d8f81613963565b634e487b7160e01b600052603160045260246000fdfea264697066735822122073d06d89b45fdcf72ee629030357568ecaa339891eb6c987b26004b01beb218f64736f6c634300080a0033

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

000000000000000000000000f87e31492faf9a91b02ee0deaad50d51d56d5d4d000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000018446f75626c6520446563656e7472616c616e64204c414e4400000000000000000000000000000000000000000000000000000000000000000000000000000006646f4c414e440000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : address_ (address): 0xF87E31492Faf9A91B02Ee0dEAAd50d51d56D5d4d
Arg [1] : name_ (string): Double Decentraland LAND
Arg [2] : symbol_ (string): doLAND

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 000000000000000000000000f87e31492faf9a91b02ee0deaad50d51d56d5d4d
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000018
Arg [4] : 446f75626c6520446563656e7472616c616e64204c414e440000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [6] : 646f4c414e440000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

76212:505:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62295:79;;;;;;:::i;:::-;;:::i;:::-;;72877:226;;;;;;:::i;:::-;;:::i;:::-;;;934:14:1;;927:22;909:41;;897:2;882:18;72877:226:0;;;;;;;;62073:102;;;:::i;:::-;;;;;;;:::i;37811:221::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2083:32:1;;;2065:51;;2053:2;2038:18;37811:221:0;1919:203:1;37334:411:0;;;;;;:::i;:::-;;:::i;72394:220::-;;;;;;:::i;:::-;-1:-1:-1;;;72394:220:0;;;;;;;;;;;-1:-1:-1;;;;;;3686:33:1;;;3668:52;;3656:2;3641:18;72394:220:0;3524:202:1;71402:299:0;;;;;;:::i;:::-;;:::i;:::-;;;3877:25:1;;;3865:2;3850:18;71402:299:0;3731:177:1;49991:113:0;50079:10;:17;49991:113;;72094:164;;;;;;:::i;:::-;72159:7;72203:21;;;:12;:21;;;;;72242:8;;72094:164;38701:339;;;;;;:::i;:::-;;:::i;71988:100::-;72069:11;;-1:-1:-1;;;;;72069:11:0;71988:100;;49659:256;;;;;;:::i;:::-;;:::i;63356:537::-;;;;;;:::i;:::-;;:::i;64814:116::-;;;;;;:::i;:::-;64871:6;64895:21;;;:12;:21;;;;;:27;;;-1:-1:-1;;;;;64895:27:0;;64814:116;;;;-1:-1:-1;;;;;4718:31:1;;;4700:50;;4688:2;4673:18;64814:116:0;4556:200:1;39111:185:0;;;;;;:::i;:::-;;:::i;62382:160::-;;;;;;:::i;:::-;;:::i;74461:96::-;;;;;;:::i;:::-;;:::i;73402:110::-;;;;;;:::i;:::-;;:::i;50181:233::-;;;;;;:::i;:::-;;:::i;64056:750::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;73111:102::-;;;;;;:::i;:::-;;:::i;35946:239::-;;;;;;:::i;:::-;;:::i;15141:129::-;;;;;;:::i;:::-;;:::i;64938:1855::-;;;;;;:::i;:::-;;:::i;71709:181::-;;;;;;:::i;:::-;;:::i;35676:208::-;;;;;;:::i;:::-;;:::i;14529:301::-;;;:::i;73701:537::-;;;;;;:::i;:::-;;:::i;62748:197::-;;;;;;:::i;:::-;62809:6;62863:27;;;:15;:27;;;;;62909:14;-1:-1:-1;;;;;62909:14:0;;;;-1:-1:-1;;;62924:12:0;;;;;62748:197;;;;;-1:-1:-1;;;;;9264:15:1;;;9246:34;;9316:15;;;;9311:2;9296:18;;9289:43;9182:18;62748:197:0;9039:299:1;13605:20:0;;;;;-1:-1:-1;;;;;13605:20:0;;;62181:106;;;:::i;76441:263::-;;;;;;:::i;:::-;;:::i;60725:28::-;;;;;;38104:295;;;;;;:::i;:::-;;:::i;74353:100::-;;;;;;:::i;:::-;;:::i;60696:22::-;;;;;;70528:127;;;;;;:::i;:::-;70588:7;70614:33;;;:18;:33;;;;;;-1:-1:-1;;;;;70614:33:0;;70528:127;61828:239;;;;;;:::i;:::-;;:::i;74246:99::-;;;;;;:::i;:::-;;:::i;39367:328::-;;;;;;:::i;:::-;;:::i;75398:477::-;;;;;;:::i;:::-;;:::i;73221:173::-;;;;;;:::i;:::-;;:::i;74569:817::-;;;;;;:::i;:::-;;:::i;75883:82::-;75953:4;75883:82;;67726:1241;;;;;;:::i;:::-;;:::i;62550:192::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;13632:27::-;;;;;-1:-1:-1;;;;;13632:27:0;;;62953:395;;;;;;:::i;:::-;;:::i;:::-;;;;13143:25:1;;;-1:-1:-1;;;;;13241:15:1;;;13236:2;13221:18;;13214:43;13293:15;;13273:18;;;13266:43;13131:2;13116:18;62953:395:0;12945:370:1;38470:164:0;;;;;;:::i;:::-;-1:-1:-1;;;;;38591:25:0;;;38567:4;38591:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;38470:164;14842:283;;;:::i;72266:120::-;;;;;;:::i;:::-;72328:7;72355:22;;;:7;:22;;;;;;;72266:120;66805:84;;;;;;:::i;:::-;;:::i;14347:174::-;;;;;;:::i;:::-;;:::i;13666:20::-;;;;;-1:-1:-1;;;;;13666:20:0;;;63901:147;;;;;;:::i;:::-;;:::i;70663:731::-;;;;;;:::i;:::-;;:::i;62295:79::-;14271:5;;-1:-1:-1;;;;;14271:5:0;14257:10;:19;;:42;;-1:-1:-1;14294:5:0;;-1:-1:-1;;;;;14294:5:0;14280:10;:19;14257:42;14249:63;;;;-1:-1:-1;;;14249:63:0;;;;;;;:::i;:::-;;;;;;;;;62353:9:::1;:13:::0;;-1:-1:-1;;62353:13:0::1;::::0;::::1;;::::0;;;::::1;::::0;;62295:79::o;72877:226::-;72962:4;-1:-1:-1;;;;;;72999:43:0;;-1:-1:-1;;;72999:43:0;;:96;;;73059:36;73083:11;73059:23;:36::i;:::-;72979:116;72877:226;-1:-1:-1;;72877:226:0:o;62073:102::-;62127:13;62160:7;62153:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62073:102;:::o;37811:221::-;37887:7;41294:16;;;:7;:16;;;;;;-1:-1:-1;;;;;41294:16:0;37907:73;;;;-1:-1:-1;;;37907:73:0;;14826:2:1;37907:73:0;;;14808:21:1;14865:2;14845:18;;;14838:30;14904:34;14884:18;;;14877:62;-1:-1:-1;;;14955:18:1;;;14948:42;15007:19;;37907:73:0;14624:408:1;37907:73:0;-1:-1:-1;38000:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;38000:24:0;;37811:221::o;37334:411::-;37415:13;37431:23;37446:7;37431:14;:23::i;:::-;37415:39;;37479:5;-1:-1:-1;;;;;37473:11:0;:2;-1:-1:-1;;;;;37473:11:0;;;37465:57;;;;-1:-1:-1;;;37465:57:0;;15239:2:1;37465:57:0;;;15221:21:1;15278:2;15258:18;;;15251:30;15317:34;15297:18;;;15290:62;-1:-1:-1;;;15368:18:1;;;15361:31;15409:19;;37465:57:0;15037:397:1;37465:57:0;30809:10;-1:-1:-1;;;;;37557:21:0;;;;:62;;-1:-1:-1;37582:37:0;37599:5;30809:10;38470:164;:::i;37582:37::-;37535:168;;;;-1:-1:-1;;;37535:168:0;;15641:2:1;37535:168:0;;;15623:21:1;15680:2;15660:18;;;15653:30;15719:34;15699:18;;;15692:62;15790:26;15770:18;;;15763:54;15834:19;;37535:168:0;15439:420:1;37535:168:0;37716:21;37725:2;37729:7;37716:8;:21::i;:::-;37404:341;37334:411;;:::o;71402:299::-;71463:13;71489:11;71502:28;71531:22;71554:20;71575:12;71591:21;71604:7;71591:12;:21::i;:::-;71488:124;;;;;;;;;;71658:3;71662:11;71674:6;71681:4;71686:5;71641:51;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;71631:62;;;;;;71623:70;;71477:224;;;;;71402:299;;;:::o;38701:339::-;38896:41;30809:10;38929:7;38896:18;:41::i;:::-;38888:103;;;;-1:-1:-1;;;38888:103:0;;;;;;;:::i;:::-;39004:28;39014:4;39020:2;39024:7;39004:9;:28::i;49659:256::-;49756:7;49792:23;49809:5;49792:16;:23::i;:::-;49784:5;:31;49776:87;;;;-1:-1:-1;;;49776:87:0;;17919:2:1;49776:87:0;;;17901:21:1;17958:2;17938:18;;;17931:30;17997:34;17977:18;;;17970:62;-1:-1:-1;;;18048:18:1;;;18041:41;18099:19;;49776:87:0;17717:407:1;49776:87:0;-1:-1:-1;;;;;;49881:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;49659:256::o;63356:537::-;63413:12;63462:21;;;:12;:21;;;;;63413:12;63511:26;:17;;;:24;:26::i;:::-;63494:43;-1:-1:-1;63548:18:0;;63577:286;63609:6;63601:5;:14;63577:286;;;63654:27;:17;;;63675:5;63654:20;:27::i;:::-;63699;;;;:15;:27;;;;;:33;63641:40;;-1:-1:-1;63736:15:0;-1:-1:-1;;;;;63699:33:0;;;:52;;;;:106;;-1:-1:-1;63774:27:0;;;;:15;:27;;;;;:31;-1:-1:-1;;;63774:31:0;;-1:-1:-1;;;;;63774:31:0;63755:15;:50;;63699:106;63696:156;;;-1:-1:-1;63832:4:0;;63356:537;-1:-1:-1;;;;;63356:537:0:o;63696:156::-;63617:7;;;;:::i;:::-;;;;63577:286;;;-1:-1:-1;63880:5:0;;63356:537;-1:-1:-1;;;;;63356:537:0:o;39111:185::-;39249:39;39266:4;39272:2;39276:7;39249:39;;;;;;;;;;;;:16;:39::i;62382:160::-;62456:4;62479:21;;;:12;:21;;;;;:55;;:34;;62523:10;62479:43;:55::i;:::-;62472:62;62382:160;-1:-1:-1;;;62382:160:0:o;74461:96::-;74507:11;74536:13;74545:3;74536:8;:13::i;73402:110::-;73464:4;41294:16;;;:7;:16;;;;;;-1:-1:-1;;;;;41294:16:0;:30;;73488:16;41205:127;50181:233;50256:7;50292:30;50079:10;:17;;49991:113;50292:30;50284:5;:38;50276:95;;;;-1:-1:-1;;;50276:95:0;;18603:2:1;50276:95:0;;;18585:21:1;18642:2;18622:18;;;18615:30;18681:34;18661:18;;;18654:62;-1:-1:-1;;;18732:18:1;;;18725:42;18784:19;;50276:95:0;18401:408:1;50276:95:0;50389:10;50400:5;50389:17;;;;;;;;:::i;:::-;;;;;;;;;50382:24;;50181:233;;;:::o;64056:750::-;64115:11;64251:21;;;:12;:21;;;;;64289:8;;64316:10;;;;64289:8;;64128:28;;;;;;-1:-1:-1;;;;;64316:10:0;;;;64251:21;64354:26;:17;;;:24;:26::i;:::-;64337:43;;64391:18;64442:6;-1:-1:-1;;;;;64429:20:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64429:20:0;;64420:29;;64480:6;-1:-1:-1;;;;;64467:20:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64467:20:0;;64460:27;;64512:26;:4;:17;;:24;:26::i;:::-;64498:40;;64554:13;64549:240;64581:6;64573:5;:14;64549:240;;;64626:27;:17;;;64647:5;64626:20;:27::i;:::-;64684;;;;:15;:27;;;;;:33;64668:13;;64613:40;;-1:-1:-1;;;;;;64684:33:0;;64668:6;;64675:5;;64668:13;;;;;;:::i;:::-;-1:-1:-1;;;;;64668:49:0;;;:13;;;;;;;;;;:49;;;;64746:27;;;;:15;:27;;;;;;:31;64732:11;;-1:-1:-1;;;64746:31:0;;;;;;;64732:4;;64737:5;;64732:11;;;;;;:::i;:::-;-1:-1:-1;;;;;64732:45:0;;;:11;;;;;;;;;;;:45;64589:7;;;;:::i;:::-;;;;64549:240;;;;64215:591;;;64056:750;;;;;;;:::o;73111:102::-;14271:5;;-1:-1:-1;;;;;14271:5:0;14257:10;:19;;:42;;-1:-1:-1;14294:5:0;;-1:-1:-1;;;;;14294:5:0;14280:10;:19;14257:42;14249:63;;;;-1:-1:-1;;;14249:63:0;;;;;;;:::i;:::-;73185:20;;::::1;::::0;:7:::1;::::0;:20:::1;::::0;::::1;::::0;::::1;:::i;:::-;;73111:102:::0;:::o;35946:239::-;36018:7;36054:16;;;:7;:16;;;;;;-1:-1:-1;;;;;36054:16:0;36089:19;36081:73;;;;-1:-1:-1;;;36081:73:0;;19148:2:1;36081:73:0;;;19130:21:1;19187:2;19167:18;;;19160:30;19226:34;19206:18;;;19199:62;-1:-1:-1;;;19277:18:1;;;19270:39;19326:19;;36081:73:0;18946:405:1;15141:129:0;14054:5;;-1:-1:-1;;;;;14054:5:0;14040:10;:19;14032:40;;;;-1:-1:-1;;;14032:40:0;;;;;;;:::i;:::-;15219:5:::1;::::0;15210:25:::1;::::0;::::1;::::0;::::1;::::0;-1:-1:-1;;;;;15219:5:0;;::::1;::::0;15226:8;;15210:25:::1;:::i;:::-;;;;;;;;15246:5;:16:::0;;-1:-1:-1;;;;;;15246:16:0::1;-1:-1:-1::0;;;;;15246:16:0;;;::::1;::::0;;;::::1;::::0;;15141:129::o;64938:1855::-;61297:9;;65122:11;;65094:5;;61297:9;;61294:90;;;61339:15;61330:5;-1:-1:-1;;;;;61330:24:0;;;61322:50;;;;-1:-1:-1;;;61322:50:0;;20204:2:1;61322:50:0;;;20186:21:1;20243:2;20223:18;;;20216:30;-1:-1:-1;;;20262:18:1;;;20255:43;20315:18;;61322:50:0;20002:337:1;61322:50:0;57246:1:::1;57842:7;;:19;;57834:63;;;::::0;-1:-1:-1;;;57834:63:0;;20546:2:1;57834:63:0::1;::::0;::::1;20528:21:1::0;20585:2;20565:18;;;20558:30;20624:33;20604:18;;;20597:61;20675:18;;57834:63:0::1;20344:355:1::0;57834:63:0::1;57246:1;57975:7;:18:::0;65156:15:::2;-1:-1:-1::0;;;;;65148:23:0;::::2;;65145:85;;;65202:15;65187:31;;65145:85;65248:41;30809:10:::0;65281:7:::2;65248:18;:41::i;:::-;:83;;;;65293:38;65312:9;65323:7;65293:18;:38::i;:::-;65240:118;;;::::0;-1:-1:-1;;;65240:118:0;;20906:2:1;65240:118:0::2;::::0;::::2;20888:21:1::0;20945:2;20925:18;;;20918:30;-1:-1:-1;;;20964:18:1;;;20957:52;21026:18;;65240:118:0::2;20704:346:1::0;65240:118:0::2;65383:5;-1:-1:-1::0;;;;;65377:11:0::2;:3;-1:-1:-1::0;;;;;65377:11:0::2;;:51;;;;-1:-1:-1::0;65417:11:0::2;::::0;65399:29:::2;::::0;-1:-1:-1;;;;;65417:11:0::2;65399:15;:29;:::i;:::-;65392:3;-1:-1:-1::0;;;;;65392:36:0::2;;;65377:51;65369:84;;;::::0;-1:-1:-1;;;65369:84:0;;21390:2:1;65369:84:0::2;::::0;::::2;21372:21:1::0;21429:2;21409:18;;;21402:30;-1:-1:-1;;;21448:18:1;;;21441:50;21508:18;;65369:84:0::2;21188:344:1::0;65369:84:0::2;65464:22;65489:21:::0;;;:12:::2;:21;::::0;;;;65529:28:::2;65502:7:::0;65546:10;65529:8:::2;:28::i;:::-;65521:64;;;::::0;-1:-1:-1;;;65521:64:0;;21739:2:1;65521:64:0::2;::::0;::::2;21721:21:1::0;21778:2;21758:18;;;21751:30;21817:25;21797:18;;;21790:53;21860:18;;65521:64:0::2;21537:347:1::0;65521:64:0::2;65596:25;65624:27:::0;;;:15:::2;:27;::::0;;;;65679:14;;-1:-1:-1;;;;;65679:14:0;;::::2;65670:23:::0;;::::2;;::::0;::::2;::::0;:46:::2;;-1:-1:-1::0;65704:12:0;;-1:-1:-1;;;;;;;;65704:12:0;;::::2;::::0;::::2;65697:19:::0;;::::2;;;65670:46;65662:75;;;::::0;-1:-1:-1;;;65662:75:0;;22091:2:1;65662:75:0::2;::::0;::::2;22073:21:1::0;22130:2;22110:18;;;22103:30;-1:-1:-1;;;22149:18:1;;;22142:46;22205:18;;65662:75:0::2;21889:340:1::0;65662:75:0::2;65791:14:::0;;65748:19:::2;::::0;-1:-1:-1;;;;;65782:23:0;;::::2;65791:14:::0;::::2;65782:23;:46:::0;::::2;;;-1:-1:-1::0;65816:12:0;;-1:-1:-1;;;;;65809:19:0;;::::2;-1:-1:-1::0;;;65816:12:0;;::::2;;65809:19;65782:46;65778:857;;;65851:32;65861:2;65864:4;:8;;;65873:5;65879:3;65851:9;:32::i;:::-;65845:38;;65912:13;;65898:27;;65940:34;65954:7;65963:10;65940:13;:34::i;:::-;65992:26;:4;:17;;:24;:26::i;:::-;65989:84;;66043:14;66049:7;66043:5;:14::i;:::-;65778:857;;;66117:14:::0;;-1:-1:-1;;;;;66108:23:0;;::::2;66117:14:::0;::::2;66108:23;:46:::0;::::2;;;-1:-1:-1::0;66142:12:0;;-1:-1:-1;;;;;66135:19:0;;::::2;-1:-1:-1::0;;;66142:12:0;;::::2;;66135:19;;66108:46;66105:421;;;66191:7;:3:::0;66197:1:::2;66191:7;:::i;:::-;66174:24:::0;;-1:-1:-1;;66174:24:0::2;-1:-1:-1::0;;;;;66174:24:0;;;::::2;;::::0;;66105:421:::2;;;66231:14:::0;;-1:-1:-1;;;;;66222:23:0;;::::2;66231:14:::0;::::2;66222:23;::::0;::::2;::::0;:46:::2;;-1:-1:-1::0;66256:12:0;;-1:-1:-1;;;;;66249:19:0;;::::2;-1:-1:-1::0;;;66256:12:0;;::::2;;66249:19;66222:46;66219:307;;;66303:9;66311:1;66303:5:::0;:9:::2;:::i;:::-;66288:24:::0;;-1:-1:-1;;;;;66288:24:0;;;::::2;-1:-1:-1::0;;;66288:24:0::2;-1:-1:-1::0;;;;66288:24:0;;::::2;;::::0;;66219:307:::2;;;66363:15;66355:5;-1:-1:-1::0;;;;;66355:23:0::2;;66351:117;;;66424:14:::0;;66403:45:::2;::::0;66415:7;;-1:-1:-1;;;;;66424:14:0::2;66440:7;66424:14:::0;66440:5;:7:::2;:::i;:::-;66403:11;:45::i;:::-;66503:7;:3:::0;66509:1:::2;66503:7;:::i;:::-;66486:24:::0;;-1:-1:-1;;66486:24:0::2;-1:-1:-1::0;;;;;66486:24:0;;;::::2;;::::0;;66219:307:::2;66548:33;66558:2;66562:4;:8;;;66571:5;66577:3;66548:9;:33::i;:::-;66542:39;;66610:13;;66596:27;;65778:857;66665:15;66658:5;-1:-1:-1::0;;;;;66658:22:0::2;;66655:82;;;66696:29;66704:2;66708:3;66713:11;66696:7;:29::i;:::-;66752:23;::::0;3877:25:1;;;66752:23:0::2;::::0;3865:2:1;3850:18;66752:23:0::2;;;;;;;-1:-1:-1::0;;57202:1:0::1;58154:7;:22:::0;-1:-1:-1;64938:1855:0;;;-1:-1:-1;;;;;;64938:1855:0:o;71709:181::-;71762:4;71782:12;71779:29;;-1:-1:-1;71803:5:0;;71709:181;-1:-1:-1;71709:181:0:o;71779:29::-;-1:-1:-1;71836:34:0;71844:21;;;:12;:21;;;;;;;;:25;71836:34;;:7;:34;;;;;;:45;;71709:181::o;35676:208::-;35748:7;-1:-1:-1;;;;;35776:19:0;;35768:74;;;;-1:-1:-1;;;35768:74:0;;22911:2:1;35768:74:0;;;22893:21:1;22950:2;22930:18;;;22923:30;22989:34;22969:18;;;22962:62;-1:-1:-1;;;23040:18:1;;;23033:40;23090:19;;35768:74:0;22709:406:1;35768:74:0;-1:-1:-1;;;;;;35860:16:0;;;;;:9;:16;;;;;;;35676:208::o;14529:301::-;14054:5;;-1:-1:-1;;;;;14054:5:0;14040:10;:19;14032:40;;;;-1:-1:-1;;;14032:40:0;;;;;;;:::i;:::-;14608:5:::1;::::0;;14599:27:::1;::::0;::::1;::::0;::::1;::::0;-1:-1:-1;;;;;14608:5:0::1;::::0;14599:27:::1;:::i;:::-;;;;;;;;14651:5;::::0;14642:27:::1;::::0;::::1;::::0;::::1;::::0;-1:-1:-1;;;;;14651:5:0;;::::1;::::0;::::1;::::0;14642:27:::1;:::i;:::-;;;;;;;;14701:12;::::0;14685:41:::1;::::0;::::1;::::0;::::1;::::0;-1:-1:-1;;;;;14701:12:0;;::::1;::::0;::::1;::::0;14685:41:::1;:::i;:::-;;;;;;;;14755:1;14739:18:::0;;-1:-1:-1;;;;;;14739:18:0;;::::1;::::0;;;;14768:25;;;::::1;::::0;;14804:5:::1;:18:::0;;;;::::1;::::0;;14529:301::o;73701:537::-;73769:11;57246:1;57842:7;;:19;;57834:63;;;;-1:-1:-1;;;57834:63:0;;20546:2:1;57834:63:0;;;20528:21:1;20585:2;20565:18;;;20558:30;20624:33;20604:18;;;20597:61;20675:18;;57834:63:0;20344:355:1;57834:63:0;57246:1;57975:7;:18;73800:12:::1;::::0;;;:7:::1;:12;::::0;;;;;:17;73792:44:::1;;;::::0;-1:-1:-1;;;73792:44:0;;23322:2:1;73792:44:0::1;::::0;::::1;23304:21:1::0;23361:2;23341:18;;;23334:30;-1:-1:-1;;;23380:18:1;;;23373:44;23434:18;;73792:44:0::1;23120:338:1::0;73792:44:0::1;73885:11;::::0;73855:46:::1;::::0;73875:9:::1;::::0;-1:-1:-1;;;;;73885:11:0::1;73897:3:::0;73855:19:::1;:46::i;:::-;:97;;;-1:-1:-1::0;73936:11:0::1;::::0;73905:47:::1;::::0;73925:10:::1;::::0;-1:-1:-1;;;;;73936:11:0::1;73948:3:::0;73905:19:::1;:47::i;:::-;73847:131;;;::::0;-1:-1:-1;;;73847:131:0;;23665:2:1;73847:131:0::1;::::0;::::1;23647:21:1::0;23704:2;23684:18;;;23677:30;-1:-1:-1;;;23723:18:1;;;23716:52;23785:18;;73847:131:0::1;23463:346:1::0;73847:131:0::1;74016:11;::::0;74009:32:::1;::::0;-1:-1:-1;;;74009:32:0;;::::1;::::0;::::1;3877:25:1::0;;;73989:17:0::1;::::0;-1:-1:-1;;;;;74016:11:0::1;::::0;74009:27:::1;::::0;3850:18:1;;74009:32:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74059:11;::::0;74052:67:::1;::::0;-1:-1:-1;;;74052:67:0;;-1:-1:-1;;;;;24328:15:1;;;74052:67:0::1;::::0;::::1;24310:34:1::0;74108:4:0::1;24360:18:1::0;;;24353:43;24412:18;;;24405:34;;;73989:52:0;;-1:-1:-1;74059:11:0;::::1;::::0;74052:36:::1;::::0;24245:18:1;;74052:67:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;74136:65;74146:9;74156:3;74167:15;-1:-1:-1::0;;;;;74136:9:0::1;:65::i;:::-;74212:12;::::0;;;:7:::1;:12;::::0;;;;;:18;;;-1:-1:-1;;57202:1:0;58154:7;:22;74130:71;73701:537::o;62181:106::-;62237:13;62270:9;62263:16;;;;;:::i;76441:263::-;76539:40;76557:2;76560:7;76568:10;76539:17;:40::i;:::-;76590:22;76615:21;;;:12;:21;;;;;;;76652:11;;76683:8;;76647:49;;-1:-1:-1;;;76647:49:0;;;;;24624:25:1;;;;-1:-1:-1;;;;;24685:32:1;;;24665:18;;;24658:60;76615:21:0;;76652:11;;;76647:35;;24597:18:1;;76647:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76528:176;76441:263;;;:::o;38104:295::-;-1:-1:-1;;;;;38207:24:0;;30809:10;38207:24;;38199:62;;;;-1:-1:-1;;;38199:62:0;;24931:2:1;38199:62:0;;;24913:21:1;24970:2;24950:18;;;24943:30;25009:27;24989:18;;;24982:55;25054:18;;38199:62:0;24729:349:1;38199:62:0;30809:10;38274:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;38274:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;38274:53:0;;;;;;;;;;38343:48;;909:41:1;;;38274:42:0;;30809:10;38343:48;;882:18:1;38343:48:0;;;;;;;38104:295;;:::o;74353:100::-;74405:7;72355:22;;;:7;:22;;;;;;74431:14;72266:120;61828:239;61929:11;;-1:-1:-1;;;;;61929:11:0;:23;61921:49;;;;-1:-1:-1;;;61921:49:0;;25285:2:1;61921:49:0;;;25267:21:1;25324:2;25304:18;;;25297:30;-1:-1:-1;;;25343:18:1;;;25336:44;25397:18;;61921:49:0;25083:338:1;61921:49:0;61981:11;:22;;-1:-1:-1;;;;;;61981:22:0;-1:-1:-1;;;;;61981:22:0;;;;;62014:15;;;;:7;;:15;;;;;:::i;:::-;-1:-1:-1;62040:19:0;;;;:9;;:19;;;;;:::i;:::-;;61828:239;;;:::o;74246:99::-;74299:4;74322:15;74329:7;74322:6;:15::i;39367:328::-;39542:41;30809:10;39561:12;39575:7;39542:18;:41::i;:::-;39534:103;;;;-1:-1:-1;;;39534:103:0;;;;;;;:::i;:::-;39648:39;39662:4;39668:2;39672:7;39681:5;39648:13;:39::i;75398:477::-;75487:41;30809:10;75520:7;75487:18;:41::i;:::-;75479:103;;;;-1:-1:-1;;;75479:103:0;;;;;;;:::i;:::-;75601:33;75613:7;75622:11;;75601;:33::i;:::-;75593:58;;;;-1:-1:-1;;;75593:58:0;;25628:2:1;75593:58:0;;;25610:21:1;25667:2;25647:18;;;25640:30;-1:-1:-1;;;25686:18:1;;;25679:43;25739:18;;75593:58:0;25426:337:1;75593:58:0;75662:22;75687:21;;;:12;:21;;;;;75726:11;;-1:-1:-1;;;;;75726:11:0;75719:36;75764:4;75771:16;75700:7;75771;:16::i;:::-;75789:8;;75719:79;;;;;;-1:-1:-1;;;;;;75719:79:0;;;-1:-1:-1;;;;;24328:15:1;;;75719:79:0;;;24310:34:1;24380:15;;;;24360:18;;;24353:43;24412:18;;;24405:34;24245:18;;75719:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75809:18;75819:7;75809:9;:18::i;:::-;75850:8;;75843:24;;;25942:25:1;;;25998:2;25983:18;;25976:34;;;75843:24:0;;25915:18:1;75843:24:0;;;;;;;75468:407;75398:477;;;:::o;73221:173::-;73294:13;73350:7;73359:25;73376:7;73359:16;:25::i;:::-;73333:52;;;;;;;;;:::i;:::-;;;;;;;;;;;;;73319:67;;73221:173;;;:::o;74569:817::-;74658:4;74683:15;74690:7;74683:6;:15::i;:::-;74675:37;;;;-1:-1:-1;;;74675:37:0;;27718:2:1;74675:37:0;;;27700:21:1;27757:1;27737:18;;;27730:29;-1:-1:-1;;;27775:18:1;;;27768:38;27823:18;;74675:37:0;27516:331:1;74675:37:0;74724:22;74749:21;;;:12;:21;;;;;;74809:15;74724:22;74825:11;;74724:22;74825:14;;;;;:::i;:::-;;;;;;;;;;74809:31;;-1:-1:-1;74809:31:0;;;;;;;;-1:-1:-1;74809:31:0;74854:14;;74809:31;;-1:-1:-1;74871:15:0;-1:-1:-1;;;;;74854:14:0;;;:32;74851:75;;;74909:5;74902:12;;;;;;74851:75;74957:12;;-1:-1:-1;;;74957:12:0;;-1:-1:-1;;;;;74957:12:0;75001:1;74980:330;75004:26;;;74980:330;;;75064:46;75091:11;;75103:5;75091:18;;;;;;;:::i;:::-;;;;;;;75064:4;:17;;:26;;:46;;;;:::i;:::-;75056:71;;;;-1:-1:-1;;;75056:71:0;;28054:2:1;75056:71:0;;;28036:21:1;28093:2;28073:18;;;28066:30;-1:-1:-1;;;28112:18:1;;;28105:43;28165:18;;75056:71:0;27852:337:1;75056:71:0;75153:15;:35;75169:11;;75181:5;75169:18;;;;;;;:::i;:::-;;;;;;;;;;75153:35;;-1:-1:-1;75153:35:0;;;;;;;;-1:-1:-1;75153:35:0;75223:14;;75153:35;;-1:-1:-1;;;;;;75223:14:0;75206:13;:11;75223:14;75206:13;:::i;:::-;-1:-1:-1;;;;;75206:31:0;;75203:96;;;75271:12;;-1:-1:-1;;;75271:12:0;;-1:-1:-1;;;;;75271:12:0;;-1:-1:-1;75203:96:0;75032:7;;;;:::i;:::-;;;;74980:330;;;-1:-1:-1;;;;;;75327:31:0;;;;;74569:817;-1:-1:-1;;;;;;74569:817:0:o;67726:1241::-;67851:41;30809:10;67884:7;67851:18;:41::i;:::-;67843:103;;;;-1:-1:-1;;;67843:103:0;;;;;;;:::i;:::-;67965:28;67974:7;67982:10;67965:8;:28::i;:::-;67957:52;;;;-1:-1:-1;;;67957:52:0;;;;;;;:::i;:::-;68048:22;68056:13;68048:7;:22::i;:::-;-1:-1:-1;;;;;68028:42:0;:16;68036:7;68028;:16::i;:::-;-1:-1:-1;;;;;68028:42:0;;68020:65;;;;-1:-1:-1;;;68020:65:0;;28737:2:1;68020:65:0;;;28719:21:1;28776:2;28756:18;;;28749:30;-1:-1:-1;;;28795:18:1;;;28788:40;28845:18;;68020:65:0;28535:334:1;68020:65:0;68133:27;;;;:12;:27;;;;;;:31;68104:21;;;;;:25;:60;68096:82;;;;-1:-1:-1;;;68096:82:0;;29076:2:1;68096:82:0;;;29058:21:1;29115:1;29095:18;;;29088:29;-1:-1:-1;;;29133:18:1;;;29126:38;29181:18;;68096:82:0;28874:331:1;68096:82:0;68197:40;68206:13;68220:16;68197:8;:40::i;:::-;68189:64;;;;-1:-1:-1;;;68189:64:0;;;;;;;:::i;:::-;68274:25;68302:27;;;:15;:27;;;;;;68374:33;;;;;68436:20;;68421:12;;-1:-1:-1;;;;;68436:20:0;;;-1:-1:-1;;;68421:12:0;;;;;;:35;68418:435;;;68496:20;;68480:12;;-1:-1:-1;;;;;68496:20:0;;;;68480:14;;-1:-1:-1;;;68480:12:0;;;68496:20;68480:14;:::i;:::-;-1:-1:-1;;;;;68480:36:0;;68472:45;;;;;;68555:14;;68532:37;;-1:-1:-1;;68532:37:0;-1:-1:-1;;;;;68555:14:0;;;68532:37;;;68584:33;68598:7;68606:10;68584:13;:33::i;:::-;68418:435;;;68668:14;;68647:18;;-1:-1:-1;;;;;68668:14:0;;;-1:-1:-1;;;68647:18:0;;;;;;:35;68644:209;;;68730:14;;68706:18;;-1:-1:-1;;;;;68730:14:0;;;;68706:20;;-1:-1:-1;;;68706:18:0;;;68730:14;68706:20;:::i;:::-;-1:-1:-1;;;;;68706:38:0;;68698:47;;;;;;68781:12;;68760:33;;-1:-1:-1;;;;68760:33:0;-1:-1:-1;;;68781:12:0;;;;-1:-1:-1;;;;;68781:12:0;68760:33;;;;;;68808;68822:7;68830:10;68808:13;:33::i;:::-;68868:21;;;;:12;:21;;;;;:43;;:34;;:41;:43::i;:::-;68865:93;;68932:14;68938:7;68932:5;:14::i;:::-;67832:1135;;67726:1241;;;;:::o;62550:192::-;62644:22;62669:21;;;:12;:21;;;;;62616:16;;62708:26;:17;;;:24;:26::i;62953:395::-;63032:18;63112:21;;;:12;:21;;;;;63032:18;;;;63160:26;:17;;;:24;:26::i;:::-;63152:5;:34;63144:58;;;;-1:-1:-1;;;63144:58:0;;29412:2:1;63144:58:0;;;29394:21:1;29451:2;29431:18;;;29424:30;-1:-1:-1;;;29470:18:1;;;29463:42;29522:18;;63144:58:0;29210:336:1;63144:58:0;63226:27;:17;;;63247:5;63226:20;:27::i;:::-;62809:6;62863:27;;;:15;:27;;;;;62909:14;62863:27;;-1:-1:-1;;;;;62909:14:0;;;;-1:-1:-1;;;;62924:12:0;;;;;;;-1:-1:-1;62953:395:0;-1:-1:-1;;;;62953:395:0:o;14842:283::-;14159:12;;-1:-1:-1;;;;;14159:12:0;14145:10;:26;14137:54;;;;-1:-1:-1;;;14137:54:0;;29753:2:1;14137:54:0;;;29735:21:1;29792:2;29772:18;;;29765:30;-1:-1:-1;;;29811:18:1;;;29804:46;29867:18;;14137:54:0;29551:340:1;14137:54:0;14914:5:::1;::::0;;14921:12;14905:29:::1;::::0;::::1;::::0;::::1;::::0;-1:-1:-1;;;;;14914:5:0;;::::1;::::0;14921:12;::::1;::::0;14905:29:::1;:::i;:::-;;;;;;;;14953:12;::::0;::::1;14945:20:::0;;-1:-1:-1;;;;;;14945:20:0::1;-1:-1:-1::0;;;;;14953:12:0;;::::1;14945:20:::0;;::::1;::::0;;15030:46:::1;::::0;14953:12;;15030:46:::1;::::0;::::1;::::0;14953:12;;;15030:46:::1;:::i;:::-;;;;;;;;15087:12;:30:::0;;-1:-1:-1;;;;;;15087:30:0::1;-1:-1:-1::0;;;;;15087:30:0;;;::::1;::::0;;;::::1;::::0;;14842:283::o;66805:84::-;14271:5;;-1:-1:-1;;;;;14271:5:0;14257:10;:19;;:42;;-1:-1:-1;14294:5:0;;-1:-1:-1;;;;;14294:5:0;14280:10;:19;14257:42;14249:63;;;;-1:-1:-1;;;14249:63:0;;;;;;;:::i;:::-;66866:11:::1;:15:::0;;-1:-1:-1;;66866:15:0::1;-1:-1:-1::0;;;;;66866:15:0;;;::::1;::::0;;;::::1;::::0;;66805:84::o;14347:174::-;14054:5;;-1:-1:-1;;;;;14054:5:0;14040:10;:19;14032:40;;;;-1:-1:-1;;;14032:40:0;;;;;;;:::i;:::-;14446:12:::1;::::0;14430:44:::1;::::0;::::1;::::0;::::1;::::0;-1:-1:-1;;;;;14446:12:0;;::::1;::::0;14460:13;;14430:44:::1;:::i;63901:147::-:0;63971:7;63997:21;;;:12;:21;;;;;:43;;:34;;:41;:43::i;70663:731::-;70741:22;70766:21;;;:12;:21;;;;;;70741:22;;70863:368;70887:26;;;70863:368;;;70952:11;;70964:5;70952:18;;;;;;;:::i;:::-;;;;;;;70939:31;;70988:29;70997:7;71006:10;70988:8;:29::i;:::-;70985:235;;;71048:27;;;;:15;:27;;;;;71097:12;;71048:27;;-1:-1:-1;71113:15:0;-1:-1:-1;;;71097:12:0;;;-1:-1:-1;;;;;71097:12:0;:31;71094:111;;71152:33;71166:7;71174:10;71152:13;:33::i;:::-;70915:7;;;;:::i;:::-;;;;70863:368;;;;71254:26;:4;:17;;:24;:26::i;:::-;71251:136;;71310:15;71317:7;71310:6;:15::i;:::-;71309:16;71301:45;;;;-1:-1:-1;;;71301:45:0;;30098:2:1;71301:45:0;;;30080:21:1;30137:2;30117:18;;;30110:30;-1:-1:-1;;;30156:18:1;;;30149:47;30213:18;;71301:45:0;29896:341:1;71301:45:0;71361:14;71367:7;71361:5;:14::i;49351:224::-;49453:4;-1:-1:-1;;;;;;49477:50:0;;-1:-1:-1;;;49477:50:0;;:90;;;49531:36;49555:11;49531:23;:36::i;45187:174::-;45262:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;45262:29:0;-1:-1:-1;;;;;45262:29:0;;;;;;;;:24;;45316:23;45262:24;45316:14;:23::i;:::-;-1:-1:-1;;;;;45307:46:0;;;;;;;;;;;45187:174;;:::o;41499:348::-;41592:4;41294:16;;;:7;:16;;;;;;-1:-1:-1;;;;;41294:16:0;41609:73;;;;-1:-1:-1;;;41609:73:0;;;;;;;:::i;:::-;41693:13;41709:23;41724:7;41709:14;:23::i;:::-;41693:39;;41762:5;-1:-1:-1;;;;;41751:16:0;:7;-1:-1:-1;;;;;41751:16:0;;:51;;;;41795:7;-1:-1:-1;;;;;41771:31:0;:20;41783:7;41771:11;:20::i;:::-;-1:-1:-1;;;;;41771:31:0;;41751:51;:87;;;-1:-1:-1;;;;;;38591:25:0;;;38567:4;38591:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;41806:32;41743:96;41499:348;-1:-1:-1;;;;41499:348:0:o;44491:578::-;44650:4;-1:-1:-1;;;;;44623:31:0;:23;44638:7;44623:14;:23::i;:::-;-1:-1:-1;;;;;44623:31:0;;44615:85;;;;-1:-1:-1;;;44615:85:0;;30857:2:1;44615:85:0;;;30839:21:1;30896:2;30876:18;;;30869:30;30935:34;30915:18;;;30908:62;-1:-1:-1;;;30986:18:1;;;30979:39;31035:19;;44615:85:0;30655:405:1;44615:85:0;-1:-1:-1;;;;;44719:16:0;;44711:65;;;;-1:-1:-1;;;44711:65:0;;31267:2:1;44711:65:0;;;31249:21:1;31306:2;31286:18;;;31279:30;31345:34;31325:18;;;31318:62;-1:-1:-1;;;31396:18:1;;;31389:34;31440:19;;44711:65:0;31065:400:1;44711:65:0;44789:39;44810:4;44816:2;44820:7;44789:20;:39::i;:::-;44893:29;44910:1;44914:7;44893:8;:29::i;:::-;-1:-1:-1;;;;;44935:15:0;;;;;;:9;:15;;;;;:20;;44954:1;;44935:15;:20;;44954:1;;44935:20;:::i;:::-;;;;-1:-1:-1;;;;;;;44966:13:0;;;;;;:9;:13;;;;;:18;;44983:1;;44966:13;:18;;44983:1;;44966:18;:::i;:::-;;;;-1:-1:-1;;44995:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;44995:21:0;-1:-1:-1;;;;;44995:21:0;;;;;;;;;45034:27;;44995:16;;45034:27;;;;;;;44491:578;;;:::o;11115:114::-;11175:7;11202:19;11210:3;4144:18;;4061:109;11583:137;11654:7;11689:22;11693:3;11705:5;11689:3;:22::i;10883:146::-;10960:4;3943:19;;;:12;;;:19;;;;;;:24;;10984:37;3846:129;12270:263;12330:16;12359:22;12384:19;12392:3;12384:7;:19::i;67498:220::-;67603:7;67628:24;67637:4;67642:5;67648:3;67628:8;:24::i;:::-;;67663:22;67673:2;67677:7;;67663:9;:22::i;:::-;-1:-1:-1;67703:7:0;;67498:220;;;;;;:::o;68975:296::-;69059:27;;;;:15;:27;;;;;;;;69052:34;;-1:-1:-1;;;;;;69052:34:0;;;69097:21;;;:12;:21;;;;;:53;;:34;;69075:10;69097:41;:53::i;:::-;-1:-1:-1;69184:16:0;;;69198:1;69184:16;;;;;;;;;69161:20;;69184:16;;;;;;;;;;;-1:-1:-1;69184:16:0;69161:39;;69220:10;69211:3;69215:1;69211:6;;;;;;;;:::i;:::-;;;;;;:19;;;;;69246:17;69259:3;69246:17;;;;;;:::i;:::-;;;;;;;;69041:230;68975:296;;:::o;69730:137::-;69799:21;69812:7;69799:12;:21::i;:::-;69838;;;;:12;:21;;;;;69831:28;;;;;;;;-1:-1:-1;;69831:28:0;;;69838:21;69831:28;;;69838:21;69831:28;69838:21;69831:28;;69838:21;69831:28;:::i;:::-;;;;;;;69730:137;:::o;67197:293::-;67277:13;:15;;;:13;:15;;;:::i;:::-;;;;-1:-1:-1;;67336:19:0;;;;;;;;-1:-1:-1;;;;;67336:19:0;;;;;;;;;;;;;;;67319:13;;;-1:-1:-1;67303:30:0;;;:15;:30;;;;;:52;;;;;;;;-1:-1:-1;;;67303:52:0;-1:-1:-1;;;;;;67303:52:0;;;;;;;;;;;;;;;;67405:13;67366:21;;;:12;:21;;;;;;;:53;;:34;;;;;:38;:53::i;:::-;-1:-1:-1;67450:13:0;;67435:47;;;31827:25:1;;;31883:2;31868:18;;31861:34;;;-1:-1:-1;;;;;31968:15:1;;;31948:18;;;31941:43;;;;32020:15;;32015:2;32000:18;;31993:43;67435:47:0;;31814:3:1;31799:19;67435:47:0;31600:442:1;61411:409:0;61546:35;;-1:-1:-1;;;61546:35:0;;;;;3877:25:1;;;61514:4:0;;;;-1:-1:-1;;;;;61546:26:0;;;;;3850:18:1;;61546:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61530:51;-1:-1:-1;;;;;;61600:19:0;;61592:75;;;;-1:-1:-1;;;61592:75:0;;;;;;;:::i;:::-;61697:5;-1:-1:-1;;;;;61686:16:0;:7;-1:-1:-1;;;;;61686:16:0;;:70;;;-1:-1:-1;61706:39:0;;-1:-1:-1;;;61706:39:0;;;;;3877:25:1;;;-1:-1:-1;;;;;61706:50:0;;;;:30;;;;;;3850:18:1;;61706:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;61706:50:0;;61686:70;:125;;;-1:-1:-1;61760:51:0;;-1:-1:-1;;;61760:51:0;;-1:-1:-1;;;;;61760:35:0;;;;;:51;;61796:5;;61803:7;;61760:51;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61678:134;61411:409;-1:-1:-1;;;;;61411:409:0:o;69875:645::-;69972:41;30809:10;69991:12;30729:98;69972:41;:83;;;;70017:38;70036:9;70047:7;70017:18;:38::i;:::-;69964:118;;;;-1:-1:-1;;;69964:118:0;;20906:2:1;69964:118:0;;;20888:21:1;20945:2;20925:18;;;20918:30;-1:-1:-1;;;20964:18:1;;;20957:52;21026:18;;69964:118:0;20704:346:1;69964:118:0;70093:22;70118:21;;;:12;:21;;;;;;;;70178:27;;;:15;:27;;;;;;70224:12;;70240:15;-1:-1:-1;;;70224:12:0;;;-1:-1:-1;;;;;70224:12:0;:31;;70216:54;;;;-1:-1:-1;;;70216:54:0;;32499:2:1;70216:54:0;;;32481:21:1;32538:2;32518:18;;;32511:30;-1:-1:-1;;;32557:18:1;;;32550:41;32608:18;;70216:54:0;32297:335:1;70216:54:0;70289:14;;70307:15;-1:-1:-1;;;;;70289:14:0;;;:33;;70281:58;;;;-1:-1:-1;;;70281:58:0;;32839:2:1;70281:58:0;;;32821:21:1;32878:2;32858:18;;;32851:30;-1:-1:-1;;;32897:18:1;;;32890:43;32950:18;;70281:58:0;32637:337:1;70281:58:0;70358:38;:17;;;70385:10;70358:26;:38::i;:::-;70350:62;;;;-1:-1:-1;;;70350:62:0;;;;;;;:::i;:::-;70442:8;;70423:28;;;;:18;:28;;;;;;;;;:33;;-1:-1:-1;;;;;;70423:33:0;-1:-1:-1;;;;;70423:33:0;;;;;;;;70472:40;;70480:9;33248:34:1;;33298:18;;;33291:43;33350:18;;;33343:34;;;33408:2;33393:18;;33386:34;;;70472:40:0;;33197:3:1;33182:19;70472:40:0;;;;;;;69953:567;;69875:645;;;:::o;40577:315::-;40734:28;40744:4;40750:2;40754:7;40734:9;:28::i;:::-;40781:48;40804:4;40810:2;40814:7;40823:5;40781:22;:48::i;:::-;40773:111;;;;-1:-1:-1;;;40773:111:0;;;;;;;:::i;69282:440::-;69334:22;69359:17;;;:12;:17;;;;;;69404:26;:17;;;:24;:26::i;:::-;69387:43;;69446:13;69441:127;69473:6;69465:5;:14;69441:127;;;69512:15;:44;69528:27;:17;;;69549:5;69528:20;:27::i;:::-;69512:44;;;;;;;;;;;-1:-1:-1;69512:44:0;69505:51;;-1:-1:-1;;;;;;69505:51:0;;;69481:7;;;;:::i;:::-;;;;69441:127;;;;69583:40;69596:26;:4;:17;;:24;:26::i;:::-;69583:40;;;;;;:::i;:::-;;;;;;;;69641:17;;;;;;69634:24;69641:17;;69634:24;:::i;:::-;-1:-1:-1;;69684:8:0;;69676:17;;;;:7;:17;;;;;69669:24;-1:-1:-1;69704:10:0;;-1:-1:-1;69710:3:0;69704:5;:10::i;31254:723::-;31310:13;31531:10;31527:53;;-1:-1:-1;;31558:10:0;;;;;;;;;;;;-1:-1:-1;;;31558:10:0;;;;;31254:723::o;31527:53::-;31605:5;31590:12;31646:78;31653:9;;31646:78;;31679:8;;;;:::i;:::-;;-1:-1:-1;31702:10:0;;-1:-1:-1;31710:2:0;31702:10;;:::i;:::-;;;31646:78;;;31734:19;31766:6;-1:-1:-1;;;;;31756:17:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31756:17:0;;31734:39;;31784:154;31791:10;;31784:154;;31818:11;31828:1;31818:11;;:::i;:::-;;-1:-1:-1;31887:10:0;31895:2;31887:5;:10;:::i;:::-;31874:24;;:2;:24;:::i;:::-;31861:39;;31844:6;31851;31844:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;31844:56:0;;;;;;;;-1:-1:-1;31915:11:0;31924:2;31915:11;;:::i;:::-;;;31784:154;;35307:305;35409:4;-1:-1:-1;;;;;;35446:40:0;;-1:-1:-1;;;35446:40:0;;:105;;-1:-1:-1;;;;;;;35503:48:0;;-1:-1:-1;;;35503:48:0;35446:105;:158;;;-1:-1:-1;;;;;;;;;;33920:40:0;;;35568:36;33811:157;72622:247;72765:56;72803:4;72809:2;72813:7;72765:37;:56::i;:::-;72832:21;;;;:12;:21;;;;;:27;;:29;;-1:-1:-1;;;;;72832:29:0;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;72832:29:0;;;;;-1:-1:-1;;;;;72832:29:0;;;;;;;72622:247;;;:::o;4524:120::-;4591:7;4618:3;:11;;4630:5;4618:18;;;;;;;;:::i;:::-;;;;;;;;;4611:25;;4524:120;;;;:::o;5194:111::-;5250:16;5286:3;:11;;5279:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5194:111;;;:::o;66895:290::-;66994:7;:9;;66969:7;;;66994:9;;;:::i;:::-;;;;-1:-1:-1;;67052:7:0;;;67014:22;67039:21;;;:12;:21;;;;;67071:15;;;67097:10;;;:14;;-1:-1:-1;;67097:14:0;;;67134:7;;67122:30;;67142:5;67148:3;67122:11;:30::i;:::-;-1:-1:-1;;67170:7:0;;66895:290;;;;;:::o;42189:110::-;42265:26;42275:2;42279:7;42265:26;;;;;;;;;;;;:9;:26::i;10660:137::-;10730:4;10754:35;10762:3;10782:5;10754:7;:35::i;43794:360::-;43854:13;43870:23;43885:7;43870:14;:23::i;:::-;43854:39;;43906:48;43927:5;43942:1;43946:7;43906:20;:48::i;:::-;43995:29;44012:1;44016:7;43995:8;:29::i;:::-;-1:-1:-1;;;;;44037:16:0;;;;;;:9;:16;;;;;:21;;44057:1;;44037:16;:21;;44057:1;;44037:21;:::i;:::-;;;;-1:-1:-1;;44076:16:0;;;;:7;:16;;;;;;44069:23;;-1:-1:-1;;;;;;44069:23:0;;;44110:36;44084:7;;44076:16;-1:-1:-1;;;;;44110:36:0;;;;;44076:16;;44110:36;43843:311;43794:360;:::o;10353:131::-;10420:4;10444:32;10449:3;10469:5;10444:4;:32::i;45926:799::-;46081:4;-1:-1:-1;;;;;46102:13:0;;23096:20;23144:8;46098:620;;46138:72;;-1:-1:-1;;;46138:72:0;;-1:-1:-1;;;;;46138:36:0;;;;;:72;;30809:10;;46189:4;;46195:7;;46204:5;;46138:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46138:72:0;;;;;;;;-1:-1:-1;;46138:72:0;;;;;;;;;;;;:::i;:::-;;;46134:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46380:13:0;;46376:272;;46423:60;;-1:-1:-1;;;46423:60:0;;;;;;;:::i;46376:272::-;46598:6;46592:13;46583:6;46579:2;46575:15;46568:38;46134:529;-1:-1:-1;;;;;;46261:51:0;-1:-1:-1;;;46261:51:0;;-1:-1:-1;46254:58:0;;46098:620;-1:-1:-1;46702:4:0;46695:11;;51027:589;-1:-1:-1;;;;;51233:18:0;;51229:187;;51268:40;51300:7;52443:10;:17;;52416:24;;;;:15;:24;;;;;:44;;;52471:24;;;;;;;;;;;;52339:164;51268:40;51229:187;;;51338:2;-1:-1:-1;;;;;51330:10:0;:4;-1:-1:-1;;;;;51330:10:0;;51326:90;;51357:47;51390:4;51396:7;51357:32;:47::i;:::-;-1:-1:-1;;;;;51430:16:0;;51426:183;;51463:45;51500:7;51463:36;:45::i;51426:183::-;51536:4;-1:-1:-1;;;;;51530:10:0;:2;-1:-1:-1;;;;;51530:10:0;;51526:83;;51557:40;51585:2;51589:7;51557:27;:40::i;42526:321::-;42656:18;42662:2;42666:7;42656:5;:18::i;:::-;42707:54;42738:1;42742:2;42746:7;42755:5;42707:22;:54::i;:::-;42685:154;;;;-1:-1:-1;;;42685:154:0;;;;;;;:::i;2340:1420::-;2406:4;2545:19;;;:12;;;:19;;;;;;2581:15;;2577:1176;;2956:21;2980:14;2993:1;2980:10;:14;:::i;:::-;3029:18;;2956:38;;-1:-1:-1;3009:17:0;;3029:22;;3050:1;;3029:22;:::i;:::-;3009:42;;3085:13;3072:9;:26;3068:405;;3119:17;3139:3;:11;;3151:9;3139:22;;;;;;;;:::i;:::-;;;;;;;;;3119:42;;3293:9;3264:3;:11;;3276:13;3264:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;3378:23;;;:12;;;:23;;;;;:36;;;3068:405;3554:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;3649:3;:12;;:19;3662:5;3649:19;;;;;;;;;;;3642:26;;;3692:4;3685:11;;;;;;;2577:1176;3736:5;3729:12;;;;;1750:414;1813:4;3943:19;;;:12;;;:19;;;;;;1830:327;;-1:-1:-1;1873:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;2056:18;;2034:19;;;:12;;;:19;;;;;;:40;;;;2089:11;;1830:327;-1:-1:-1;2140:5:0;2133:12;;53130:988;53396:22;53446:1;53421:22;53438:4;53421:16;:22::i;:::-;:26;;;;:::i;:::-;53458:18;53479:26;;;:17;:26;;;;;;53396:51;;-1:-1:-1;53612:28:0;;;53608:328;;-1:-1:-1;;;;;53679:18:0;;53657:19;53679:18;;;:12;:18;;;;;;;;:34;;;;;;;;;53730:30;;;;;;:44;;;53847:30;;:17;:30;;;;;:43;;;53608:328;-1:-1:-1;54032:26:0;;;;:17;:26;;;;;;;;54025:33;;;-1:-1:-1;;;;;54076:18:0;;;;;:12;:18;;;;;:34;;;;;;;54069:41;53130:988::o;54413:1079::-;54691:10;:17;54666:22;;54691:21;;54711:1;;54691:21;:::i;:::-;54723:18;54744:24;;;:15;:24;;;;;;55117:10;:26;;54666:46;;-1:-1:-1;54744:24:0;;54666:46;;55117:26;;;;;;:::i;:::-;;;;;;;;;55095:48;;55181:11;55156:10;55167;55156:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;55261:28;;;:15;:28;;;;;;;:41;;;55433:24;;;;;55426:31;55468:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;54484:1008;;;54413:1079;:::o;51917:221::-;52002:14;52019:20;52036:2;52019:16;:20::i;:::-;-1:-1:-1;;;;;52050:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;52095:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;51917:221:0:o;43183:382::-;-1:-1:-1;;;;;43263:16:0;;43255:61;;;;-1:-1:-1;;;43255:61:0;;35531:2:1;43255:61:0;;;35513:21:1;;;35550:18;;;35543:30;35609:34;35589:18;;;35582:62;35661:18;;43255:61:0;35329:356:1;43255:61:0;41270:4;41294:16;;;:7;:16;;;;;;-1:-1:-1;;;;;41294:16:0;:30;43327:58;;;;-1:-1:-1;;;43327:58:0;;35892:2:1;43327:58:0;;;35874:21:1;35931:2;35911:18;;;35904:30;35970;35950:18;;;35943:58;36018:18;;43327:58:0;35690:352:1;43327:58:0;43398:45;43427:1;43431:2;43435:7;43398:20;:45::i;:::-;-1:-1:-1;;;;;43456:13:0;;;;;;:9;:13;;;;;:18;;43473:1;;43456:13;:18;;43473:1;;43456:18;:::i;:::-;;;;-1:-1:-1;;43485:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;43485:21:0;-1:-1:-1;;;;;43485:21:0;;;;;;;;43524:33;;43485:16;;;43524:33;;43485:16;;43524:33;43183:382;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;;;;;14:118:1;100:5;93:13;86:21;79:5;76:32;66:60;;122:1;119;112:12;137:241;193:6;246:2;234:9;225:7;221:23;217:32;214:52;;;262:1;259;252:12;214:52;301:9;288:23;320:28;342:5;320:28;:::i;383:131::-;-1:-1:-1;;;;;;457:32:1;;447:43;;437:71;;504:1;501;494:12;519:245;577:6;630:2;618:9;609:7;605:23;601:32;598:52;;;646:1;643;636:12;598:52;685:9;672:23;704:30;728:5;704:30;:::i;961:258::-;1033:1;1043:113;1057:6;1054:1;1051:13;1043:113;;;1133:11;;;1127:18;1114:11;;;1107:39;1079:2;1072:10;1043:113;;;1174:6;1171:1;1168:13;1165:48;;;-1:-1:-1;;1209:1:1;1191:16;;1184:27;961:258::o;1224:269::-;1277:3;1315:5;1309:12;1342:6;1337:3;1330:19;1358:63;1414:6;1407:4;1402:3;1398:14;1391:4;1384:5;1380:16;1358:63;:::i;:::-;1475:2;1454:15;-1:-1:-1;;1450:29:1;1441:39;;;;1482:4;1437:50;;1224:269;-1:-1:-1;;1224:269:1:o;1498:231::-;1647:2;1636:9;1629:21;1610:4;1667:56;1719:2;1708:9;1704:18;1696:6;1667:56;:::i;1734:180::-;1793:6;1846:2;1834:9;1825:7;1821:23;1817:32;1814:52;;;1862:1;1859;1852:12;1814:52;-1:-1:-1;1885:23:1;;1734:180;-1:-1:-1;1734:180:1:o;2127:131::-;-1:-1:-1;;;;;2202:31:1;;2192:42;;2182:70;;2248:1;2245;2238:12;2263:315;2331:6;2339;2392:2;2380:9;2371:7;2367:23;2363:32;2360:52;;;2408:1;2405;2398:12;2360:52;2447:9;2434:23;2466:31;2491:5;2466:31;:::i;:::-;2516:5;2568:2;2553:18;;;;2540:32;;-1:-1:-1;;;2263:315:1:o;2583:936::-;2680:6;2688;2696;2704;2712;2765:3;2753:9;2744:7;2740:23;2736:33;2733:53;;;2782:1;2779;2772:12;2733:53;2821:9;2808:23;2840:31;2865:5;2840:31;:::i;:::-;2890:5;-1:-1:-1;2947:2:1;2932:18;;2919:32;2960:33;2919:32;2960:33;:::i;:::-;3012:7;-1:-1:-1;3066:2:1;3051:18;;3038:32;;-1:-1:-1;3121:2:1;3106:18;;3093:32;-1:-1:-1;;;;;3174:14:1;;;3171:34;;;3201:1;3198;3191:12;3171:34;3239:6;3228:9;3224:22;3214:32;;3284:7;3277:4;3273:2;3269:13;3265:27;3255:55;;3306:1;3303;3296:12;3255:55;3346:2;3333:16;3372:2;3364:6;3361:14;3358:34;;;3388:1;3385;3378:12;3358:34;3433:7;3428:2;3419:6;3415:2;3411:15;3407:24;3404:37;3401:57;;;3454:1;3451;3444:12;3401:57;2583:936;;;;-1:-1:-1;2583:936:1;;-1:-1:-1;3485:2:1;3477:11;;3507:6;2583:936;-1:-1:-1;;;2583:936:1:o;4095:456::-;4172:6;4180;4188;4241:2;4229:9;4220:7;4216:23;4212:32;4209:52;;;4257:1;4254;4247:12;4209:52;4296:9;4283:23;4315:31;4340:5;4315:31;:::i;:::-;4365:5;-1:-1:-1;4422:2:1;4407:18;;4394:32;4435:33;4394:32;4435:33;:::i;:::-;4095:456;;4487:7;;-1:-1:-1;;;4541:2:1;4526:18;;;;4513:32;;4095:456::o;4761:248::-;4829:6;4837;4890:2;4878:9;4869:7;4865:23;4861:32;4858:52;;;4906:1;4903;4896:12;4858:52;-1:-1:-1;;4929:23:1;;;4999:2;4984:18;;;4971:32;;-1:-1:-1;4761:248:1:o;5014:435::-;5067:3;5105:5;5099:12;5132:6;5127:3;5120:19;5158:4;5187:2;5182:3;5178:12;5171:19;;5224:2;5217:5;5213:14;5245:1;5255:169;5269:6;5266:1;5263:13;5255:169;;;5330:13;;5318:26;;5364:12;;;;5399:15;;;;5291:1;5284:9;5255:169;;;-1:-1:-1;5440:3:1;;5014:435;-1:-1:-1;;;;;5014:435:1:o;5454:459::-;5506:3;5544:5;5538:12;5571:6;5566:3;5559:19;5597:4;5626:2;5621:3;5617:12;5610:19;;5663:2;5656:5;5652:14;5684:1;5694:194;5708:6;5705:1;5702:13;5694:194;;;5773:13;;-1:-1:-1;;;;;5769:38:1;5757:51;;5828:12;;;;5863:15;;;;5730:1;5723:9;5694:194;;5918:831;6303:6;6292:9;6285:25;6346:3;6341:2;6330:9;6326:18;6319:31;6266:4;6373:57;6425:3;6414:9;6410:19;6402:6;6373:57;:::i;:::-;6478:9;6470:6;6466:22;6461:2;6450:9;6446:18;6439:50;6512:43;6548:6;6540;6512:43;:::i;:::-;6498:57;;6603:9;6595:6;6591:22;6586:2;6575:9;6571:18;6564:50;6631:43;6667:6;6659;6631:43;:::i;:::-;6623:51;;;-1:-1:-1;;;;;6715:6:1;6711:31;6705:3;6694:9;6690:19;6683:60;5918:831;;;;;;;;:::o;6754:127::-;6815:10;6810:3;6806:20;6803:1;6796:31;6846:4;6843:1;6836:15;6870:4;6867:1;6860:15;6886:632;6951:5;-1:-1:-1;;;;;7022:2:1;7014:6;7011:14;7008:40;;;7028:18;;:::i;:::-;7103:2;7097:9;7071:2;7157:15;;-1:-1:-1;;7153:24:1;;;7179:2;7149:33;7145:42;7133:55;;;7203:18;;;7223:22;;;7200:46;7197:72;;;7249:18;;:::i;:::-;7289:10;7285:2;7278:22;7318:6;7309:15;;7348:6;7340;7333:22;7388:3;7379:6;7374:3;7370:16;7367:25;7364:45;;;7405:1;7402;7395:12;7364:45;7455:6;7450:3;7443:4;7435:6;7431:17;7418:44;7510:1;7503:4;7494:6;7486;7482:19;7478:30;7471:41;;;;6886:632;;;;;:::o;7523:222::-;7566:5;7619:3;7612:4;7604:6;7600:17;7596:27;7586:55;;7637:1;7634;7627:12;7586:55;7659:80;7735:3;7726:6;7713:20;7706:4;7698:6;7694:17;7659:80;:::i;7750:322::-;7819:6;7872:2;7860:9;7851:7;7847:23;7843:32;7840:52;;;7888:1;7885;7878:12;7840:52;7928:9;7915:23;-1:-1:-1;;;;;7953:6:1;7950:30;7947:50;;;7993:1;7990;7983:12;7947:50;8016;8058:7;8049:6;8038:9;8034:22;8016:50;:::i;8077:247::-;8136:6;8189:2;8177:9;8168:7;8164:23;8160:32;8157:52;;;8205:1;8202;8195:12;8157:52;8244:9;8231:23;8263:31;8288:5;8263:31;:::i;8329:171::-;8396:20;;-1:-1:-1;;;;;8445:30:1;;8435:41;;8425:69;;8490:1;8487;8480:12;8425:69;8329:171;;;:::o;8505:529::-;8598:6;8606;8614;8622;8630;8683:3;8671:9;8662:7;8658:23;8654:33;8651:53;;;8700:1;8697;8690:12;8651:53;8736:9;8723:23;8713:33;;8793:2;8782:9;8778:18;8765:32;8755:42;;8816:37;8849:2;8838:9;8834:18;8816:37;:::i;:::-;8806:47;;8872:37;8905:2;8894:9;8890:18;8872:37;:::i;:::-;8862:47;;8959:3;8948:9;8944:19;8931:33;8973:31;8998:5;8973:31;:::i;:::-;9023:5;9013:15;;;8505:529;;;;;;;;:::o;9343:383::-;9420:6;9428;9436;9489:2;9477:9;9468:7;9464:23;9460:32;9457:52;;;9505:1;9502;9495:12;9457:52;9544:9;9531:23;9563:31;9588:5;9563:31;:::i;:::-;9613:5;9665:2;9650:18;;9637:32;;-1:-1:-1;9716:2:1;9701:18;;;9688:32;;9343:383;-1:-1:-1;;;9343:383:1:o;9731:382::-;9796:6;9804;9857:2;9845:9;9836:7;9832:23;9828:32;9825:52;;;9873:1;9870;9863:12;9825:52;9912:9;9899:23;9931:31;9956:5;9931:31;:::i;:::-;9981:5;-1:-1:-1;10038:2:1;10023:18;;10010:32;10051:30;10010:32;10051:30;:::i;:::-;10100:7;10090:17;;;9731:382;;;;;:::o;10118:678::-;10215:6;10223;10231;10284:2;10272:9;10263:7;10259:23;10255:32;10252:52;;;10300:1;10297;10290:12;10252:52;10339:9;10326:23;10358:31;10383:5;10358:31;:::i;:::-;10408:5;-1:-1:-1;10464:2:1;10449:18;;10436:32;-1:-1:-1;;;;;10517:14:1;;;10514:34;;;10544:1;10541;10534:12;10514:34;10567:50;10609:7;10600:6;10589:9;10585:22;10567:50;:::i;:::-;10557:60;;10670:2;10659:9;10655:18;10642:32;10626:48;;10699:2;10689:8;10686:16;10683:36;;;10715:1;10712;10705:12;10683:36;;10738:52;10782:7;10771:8;10760:9;10756:24;10738:52;:::i;:::-;10728:62;;;10118:678;;;;;:::o;10801:795::-;10896:6;10904;10912;10920;10973:3;10961:9;10952:7;10948:23;10944:33;10941:53;;;10990:1;10987;10980:12;10941:53;11029:9;11016:23;11048:31;11073:5;11048:31;:::i;:::-;11098:5;-1:-1:-1;11155:2:1;11140:18;;11127:32;11168:33;11127:32;11168:33;:::i;:::-;11220:7;-1:-1:-1;11274:2:1;11259:18;;11246:32;;-1:-1:-1;11329:2:1;11314:18;;11301:32;-1:-1:-1;;;;;11345:30:1;;11342:50;;;11388:1;11385;11378:12;11342:50;11411:22;;11464:4;11456:13;;11452:27;-1:-1:-1;11442:55:1;;11493:1;11490;11483:12;11442:55;11516:74;11582:7;11577:2;11564:16;11559:2;11555;11551:11;11516:74;:::i;:::-;11506:84;;;10801:795;;;;;;;:::o;11601:683::-;11696:6;11704;11712;11765:2;11753:9;11744:7;11740:23;11736:32;11733:52;;;11781:1;11778;11771:12;11733:52;11817:9;11804:23;11794:33;;11878:2;11867:9;11863:18;11850:32;-1:-1:-1;;;;;11942:2:1;11934:6;11931:14;11928:34;;;11958:1;11955;11948:12;11928:34;11996:6;11985:9;11981:22;11971:32;;12041:7;12034:4;12030:2;12026:13;12022:27;12012:55;;12063:1;12060;12053:12;12012:55;12103:2;12090:16;12129:2;12121:6;12118:14;12115:34;;;12145:1;12142;12135:12;12115:34;12198:7;12193:2;12183:6;12180:1;12176:14;12172:2;12168:23;12164:32;12161:45;12158:65;;;12219:1;12216;12209:12;12158:65;12250:2;12246;12242:11;12232:21;;12272:6;12262:16;;;;;11601:683;;;;;:::o;12289:385::-;12375:6;12383;12391;12399;12452:3;12440:9;12431:7;12427:23;12423:33;12420:53;;;12469:1;12466;12459:12;12420:53;-1:-1:-1;;12492:23:1;;;12562:2;12547:18;;12534:32;;-1:-1:-1;12613:2:1;12598:18;;12585:32;;12664:2;12649:18;12636:32;;-1:-1:-1;12289:385:1;-1:-1:-1;12289:385:1:o;12679:261::-;12858:2;12847:9;12840:21;12821:4;12878:56;12930:2;12919:9;12915:18;12907:6;12878:56;:::i;13320:388::-;13388:6;13396;13449:2;13437:9;13428:7;13424:23;13420:32;13417:52;;;13465:1;13462;13455:12;13417:52;13504:9;13491:23;13523:31;13548:5;13523:31;:::i;:::-;13573:5;-1:-1:-1;13630:2:1;13615:18;;13602:32;13643:33;13602:32;13643:33;:::i;13713:184::-;13771:6;13824:2;13812:9;13803:7;13799:23;13795:32;13792:52;;;13840:1;13837;13830:12;13792:52;13863:28;13881:9;13863:28;:::i;13902:332::-;14104:2;14086:21;;;14143:1;14123:18;;;14116:29;-1:-1:-1;;;14176:2:1;14161:18;;14154:39;14225:2;14210:18;;13902:332::o;14239:380::-;14318:1;14314:12;;;;14361;;;14382:61;;14436:4;14428:6;14424:17;14414:27;;14382:61;14489:2;14481:6;14478:14;14458:18;14455:38;14452:161;;;14535:10;14530:3;14526:20;14523:1;14516:31;14570:4;14567:1;14560:15;14598:4;14595:1;14588:15;14452:161;;14239:380;;;:::o;15864:433::-;15959:12;;15927:3;;16009:4;16036:14;;;15927:3;16086:13;;16078:194;;16157:13;;-1:-1:-1;;;;;16153:38:1;16141:51;;16212:12;;;;16247:15;;;;16114:1;16107:9;16078:194;;16302:992;16699:6;16694:3;16687:19;16669:3;16725:2;16758;16753:3;16749:12;16790:6;16784:13;16855:2;16847:6;16843:15;16876:1;16886:175;16900:6;16897:1;16894:13;16886:175;;;16963:13;;16949:28;;16999:14;;;;17036:15;;;;16922:1;16915:9;16886:175;;;16890:3;;;17083:101;17130:53;17177:5;17169:6;17130:53;:::i;:::-;17122:6;17083:101;:::i;:::-;17233:3;17211:16;;;;-1:-1:-1;;;;;;17207:51:1;17193:66;;-1:-1:-1;;17286:1:1;17275:13;;;;16302:992;-1:-1:-1;;;;;;16302:992:1:o;17299:413::-;17501:2;17483:21;;;17540:2;17520:18;;;17513:30;17579:34;17574:2;17559:18;;17552:62;-1:-1:-1;;;17645:2:1;17630:18;;17623:47;17702:3;17687:19;;17299:413::o;18129:127::-;18190:10;18185:3;18181:20;18178:1;18171:31;18221:4;18218:1;18211:15;18245:4;18242:1;18235:15;18261:135;18300:3;-1:-1:-1;;18321:17:1;;18318:43;;;18341:18;;:::i;:::-;-1:-1:-1;18388:1:1;18377:13;;18261:135::o;18814:127::-;18875:10;18870:3;18866:20;18863:1;18856:31;18906:4;18903:1;18896:15;18930:4;18927:1;18920:15;19356:332;19558:2;19540:21;;;19597:1;19577:18;;;19570:29;-1:-1:-1;;;19630:2:1;19615:18;;19608:39;19679:2;19664:18;;19356:332::o;19693:304::-;-1:-1:-1;;;;;19923:15:1;;;19905:34;;19975:15;;19970:2;19955:18;;19948:43;19855:2;19840:18;;19693:304::o;21055:128::-;21095:3;21126:1;21122:6;21119:1;21116:13;21113:39;;;21132:18;;:::i;:::-;-1:-1:-1;21168:9:1;;21055:128::o;22234:236::-;22273:3;-1:-1:-1;;;;;22346:2:1;22343:1;22339:10;22376:2;22373:1;22369:10;22407:3;22403:2;22399:12;22394:3;22391:21;22388:47;;;22415:18;;:::i;:::-;22451:13;;22234:236;-1:-1:-1;;;;22234:236:1:o;22475:229::-;22514:4;-1:-1:-1;;;;;22611:10:1;;;;22581;;22633:12;;;22630:38;;;22648:18;;:::i;:::-;22685:13;;22475:229;-1:-1:-1;;;22475:229:1:o;23814:251::-;23884:6;23937:2;23925:9;23916:7;23912:23;23908:32;23905:52;;;23953:1;23950;23943:12;23905:52;23985:9;23979:16;24004:31;24029:5;24004:31;:::i;26147:185::-;26189:3;26227:5;26221:12;26242:52;26287:6;26282:3;26275:4;26268:5;26264:16;26242:52;:::i;:::-;26310:16;;;;;26147:185;-1:-1:-1;;26147:185:1:o;26337:1174::-;26513:3;26542:1;26575:6;26569:13;26605:3;26627:1;26655:9;26651:2;26647:18;26637:28;;26715:2;26704:9;26700:18;26737;26727:61;;26781:4;26773:6;26769:17;26759:27;;26727:61;26807:2;26855;26847:6;26844:14;26824:18;26821:38;26818:165;;;-1:-1:-1;;;26882:33:1;;26938:4;26935:1;26928:15;26968:4;26889:3;26956:17;26818:165;26999:18;27026:104;;;;27144:1;27139:320;;;;26992:467;;27026:104;-1:-1:-1;;27059:24:1;;27047:37;;27104:16;;;;-1:-1:-1;27026:104:1;;27139:320;26094:1;26087:14;;;26131:4;26118:18;;27234:1;27248:165;27262:6;27259:1;27256:13;27248:165;;;27340:14;;27327:11;;;27320:35;27383:16;;;;27277:10;;27248:165;;;27252:3;;27442:6;27437:3;27433:16;27426:23;;26992:467;;;;;;;27475:30;27501:3;27493:6;27475:30;:::i;28194:336::-;28396:2;28378:21;;;28435:2;28415:18;;;28408:30;-1:-1:-1;;;28469:2:1;28454:18;;28447:42;28521:2;28506:18;;28194:336::o;30242:408::-;30444:2;30426:21;;;30483:2;30463:18;;;30456:30;30522:34;30517:2;30502:18;;30495:62;-1:-1:-1;;;30588:2:1;30573:18;;30566:42;30640:3;30625:19;;30242:408::o;31470:125::-;31510:4;31538:1;31535;31532:8;31529:34;;;31543:18;;:::i;:::-;-1:-1:-1;31580:9:1;;31470:125::o;32047:245::-;32114:6;32167:2;32155:9;32146:7;32142:23;32138:32;32135:52;;;32183:1;32180;32173:12;32135:52;32215:9;32209:16;32234:28;32256:5;32234:28;:::i;33431:414::-;33633:2;33615:21;;;33672:2;33652:18;;;33645:30;33711:34;33706:2;33691:18;;33684:62;-1:-1:-1;;;33777:2:1;33762:18;;33755:48;33835:3;33820:19;;33431:414::o;33850:127::-;33911:10;33906:3;33902:20;33899:1;33892:31;33942:4;33939:1;33932:15;33966:4;33963:1;33956:15;33982:120;34022:1;34048;34038:35;;34053:18;;:::i;:::-;-1:-1:-1;34087:9:1;;33982:120::o;34107:112::-;34139:1;34165;34155:35;;34170:18;;:::i;:::-;-1:-1:-1;34204:9:1;;34107:112::o;34224:209::-;34262:3;-1:-1:-1;;;;;34343:2:1;34336:5;34332:14;34370:2;34361:7;34358:15;34355:41;;;34376:18;;:::i;:::-;34425:1;34412:15;;34224:209;-1:-1:-1;;;34224:209:1:o;34438:500::-;-1:-1:-1;;;;;34707:15:1;;;34689:34;;34759:15;;34754:2;34739:18;;34732:43;34806:2;34791:18;;34784:34;;;34854:3;34849:2;34834:18;;34827:31;;;34632:4;;34875:57;;34912:19;;34904:6;34875:57;:::i;:::-;34867:65;34438:500;-1:-1:-1;;;;;;34438:500:1:o;34943:249::-;35012:6;35065:2;35053:9;35044:7;35040:23;35036:32;35033:52;;;35081:1;35078;35071:12;35033:52;35113:9;35107:16;35132:30;35156:5;35132:30;:::i;35197:127::-;35258:10;35253:3;35249:20;35246:1;35239:31;35289:4;35286:1;35279:15;35313:4;35310:1;35303:15

Swarm Source

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