ETH Price: $3,936.57 (-1.14%)

Token

LEEDO LP - Squid Game Card (LeedoSquidGameCardLP)
 

Overview

Max Total Supply

8,772 LeedoSquidGameCardLP

Holders

288

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
bholder.eth
Balance
1 LeedoSquidGameCardLP
0x81f3389cbc7f7ce7bd94857d466952ea1a463255
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:
LeedoNftVault

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-11-05
*/

// SPDX-License-Identifier: MIT

// 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/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/access/Ownable.sol



pragma solidity ^0.8.0;


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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_msgSender());
    }

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

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

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

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

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// 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/token/ERC721/IERC721Receiver.sol



pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/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/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/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/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/IERC721Metadata.sol



pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

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

// File: @openzeppelin/contracts/token/ERC721/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/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/token/ERC20/IERC20.sol



pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// File: @openzeppelin/contracts/utils/math/Math.sol



pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a / b + (a % b == 0 ? 0 : 1);
    }
}

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



pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

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

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

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

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

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

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

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

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

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

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

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

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

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

pragma solidity ^0.8.0;

/**
 * @dev Contract module that works as staking vault for NFT
 *
 *  _              ______      
 * | |             |  _  \     
 * | |     ___  ___| | | |___  
 * | |    / _ \/ _ \ | | / _ \ 
 * | |___|  __/  __/ |/ / (_) |
 * \_____/\___|\___|___/ \___/ 
 * LEEDO Project
 */

interface ILeedoNft {
    event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
    event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
    event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
    function balanceOf(address _owner) external view returns (uint256);
    function ownerOf(uint256 _tokenId) external view returns (address);
    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes memory data) external payable;
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
    function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
    function approve(address _approved, uint256 _tokenId) external payable;
    function setApprovalForAll(address _operator, bool _approved) external;
    function getApproved(uint256 _tokenId) external view returns (address);
    function isApprovedForAll(address _owner, address _operator) external view returns (bool);
    
    function claim() external;
    function ownerClaim(uint256 _tokenId) external;
    function tokenByIndex(uint256 index) external view returns (uint256);
    function totalSupply() external view returns (uint256);
    function getConsonantsIndex(uint256 _tokenId) external view returns (uint8[3] memory);  
    function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
    function getConsonants(uint256 _tokenId) external view returns (string[3] memory);
    function getGenes(uint256 _tokenId) external view returns (uint8[8] memory);    
    function tokenURI(uint256 _tokenId) external view returns (string memory);    
}

interface ILeedoERC20 {
    function mintNftVaultRewards(address _to, uint _amount) external returns (bool);
}

contract LeedoNftVault is ERC721Enumerable, Ownable, ReentrancyGuard { 
    using SafeMath for uint;
    
    bool public daoInitialized = false;
    bool public transferAllowed = false; //by default regular transfer of staked NFTs are not allowed except bridge transfer
    address private _nftAddr;
    address private _erc20Addr; 
    address private _bridgeAddr;
    address private _daoAddr;
    
    uint public expiration = block.number + 365 days;
    uint public rate = 5194874553201880; //per card per block reward rate in wei        
    mapping(address => uint) public lastBlocks; //address => lastBlock claimed
    mapping(address => uint) public totalClaims; // address => total paid    
    mapping(uint => uint) private bridgeBlocks; //brodge tokenId => lastBlock claimed

    modifier onlyDao() {
        require(_daoAddr == _msgSender(), "VAULT: caller is not the DAO address!");
        _;
    } 
    
    //nftAddr = 0xed8a775Fde8454c99Eb4e511D7D4D6b969024C5d; //mainnet
    constructor(address _nftAddress, address _erc20Address, address _bridgeAddress) 
        ERC721("LEEDO LP - Squid Game Card", "LeedoSquidGameCardLP") {
        _nftAddr = _nftAddress;
        _erc20Addr = _erc20Address;
        _bridgeAddr = _bridgeAddress;
    }
    
    function setBridgeAddr(address _bridgeAddress) public onlyOwner {
        require(!daoInitialized, 'NftVault: DAO is already initialized');
        _bridgeAddr = _bridgeAddress;
    }
    
    function setErc20Addr(address _erc20Address) public onlyOwner {
        require(!daoInitialized, 'NftVault: DAO is already initialized');
        _erc20Addr = _erc20Address;
    }
        
        
    function initializeDao(address _daoAddress) public onlyOwner {
        require(!daoInitialized, 'NftVault: DAO is already initialized');
        _daoAddr = _daoAddress;
        daoInitialized = true;
    }
    
    function setBridgeAddrByDao(address _bridgeAddress) public onlyDao() {
        _bridgeAddr = _bridgeAddress;
    }
    
    function setErc20AddrByDao(address _erc20Address) public onlyDao() {
        _erc20Addr = _erc20Address;
    }    
    
    function setAllowTransfer(bool _bool) public onlyDao() {
        transferAllowed = _bool;
    }
    
    function setDaoAddr(address _daoAddress) public onlyDao() {
        _daoAddr = _daoAddress;
    }
    
    function setRate(uint256 _rate) public onlyDao() {
        rate = _rate;
    }

    function setExpiration(uint256 _expiration) public onlyDao() {
        expiration = block.number + _expiration;
    }
    
    function calcRewards(address account) public view returns (uint) {
        require(Math.min(block.number, expiration) >= lastBlocks[account], "Invalid blocks");
        uint blockCount = Math.min(block.number, expiration) - lastBlocks[account];
        return rate.mul(balanceOf(account)).mul(blockCount) ;
    }
    
    function calcBridgeRewards(uint tokenId) public view returns (uint) {
        require(Math.min(block.number, expiration) >= bridgeBlocks[tokenId], "Invalid blocks");
        uint blockCount = Math.min(block.number, expiration) - bridgeBlocks[tokenId];
        return rate.mul(blockCount);
    }    
    
    function claimRewards() public {
        _claimRewards(_msgSender());
    } 
    
    function _claimRewards(address account) private nonReentrant {
        uint amount = calcRewards(account);
        uint blockCur = Math.min(block.number, expiration);
        lastBlocks[_msgSender()] = blockCur;
        if (amount > 0) {
            totalClaims[_msgSender()] = totalClaims[_msgSender()].add(amount);
            require(ILeedoERC20(_erc20Addr).mintNftVaultRewards(account, amount), 'NftVault: Leedo Minting failed');
        }        
    }  
    
    function _claimBridgeRewards(uint tokenId, address to) private nonReentrant {
        uint amount = calcBridgeRewards(tokenId);
        uint blockCur = Math.min(block.number, expiration);
        bridgeBlocks[tokenId] = blockCur;
        if (amount > 0) {
            totalClaims[to] = totalClaims[to].add(amount);
            require(ILeedoERC20(_erc20Addr).mintNftVaultRewards(to, amount), 'NftVault: Leedo Minting failed');
        }        
    }       
    
    function stake(uint256[] calldata tokenIds) external returns (bool) {
        claimRewards();
        ILeedoNft nft = ILeedoNft(_nftAddr);

        for (uint256 i; i < tokenIds.length; i++) {
            uint tokenId = tokenIds[i];
            require(!_exists(tokenId), 'NftVault: The tokenId already exists');
            require(nft.ownerOf(tokenId) == _msgSender(), 'NftVault: Owner is differenent' );
            ILeedoNft(_nftAddr).safeTransferFrom(
                _msgSender(),
                address(this),
                tokenId,
                ""
            );
            require(safeMint(_msgSender(), tokenId), 'NftValut: Staking failed');
        }
        return true;
    }
    
    function stakeByCount(uint256 _count) external returns (uint256[] memory){
        claimRewards();
        ILeedoNft nft = ILeedoNft(_nftAddr);
        
        require(_count <= nft.balanceOf(_msgSender()), 'NftVault: Count is more than the owner has');
        uint256[] memory tokenIds = new uint256[] (_count);

        for (uint256 i; i < _count; i++) {
            tokenIds[i] = nft.tokenOfOwnerByIndex(_msgSender(), i);
        }
        
        for (uint256 i; i < tokenIds.length; i++) {
            ILeedoNft(_nftAddr).safeTransferFrom(
                _msgSender(),
                address(this),
                tokenIds[i],
                ""
            );
            require(safeMint(_msgSender(), tokenIds[i]), 'NftVault: Staking failed');
        }
        return tokenIds;
    }       
    
    function safeMint(address _to, uint _tokenId) private nonReentrant returns (bool) {
        _safeMint(_to, _tokenId);
        return true;
    }   
    
    function withdraw(uint256[] calldata _tokenIds) external {
        claimRewards();

        for (uint256 i; i < _tokenIds.length; i++) {
            uint tokenId = _tokenIds[i];
            require(ownerOf(tokenId) == _msgSender(), 'NftVault: LP owner is different');            
            _burn(tokenId);
            ILeedoNft(_nftAddr).safeTransferFrom(
                address(this),
                _msgSender(),
                tokenId,
                ""
            );            
        }
    }

    function tokensOf(address _account) public view returns (uint[] memory) {
        uint[] memory tokenIds = new uint256[] (balanceOf(_account));
        for (uint i; i<balanceOf(_account); i++) {
            tokenIds[i] = tokenOfOwnerByIndex(_account, i);
        }
        return tokenIds;
    }
    
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);    
        if (from != address(0) && to != address(0)) {
            if (from != _bridgeAddr && to != _bridgeAddr) {
                require(transferAllowed, 'NftVault: Regular transfer is not allowed');
                _claimRewards(from);
                _claimRewards(to);
                
            } else if (to == _bridgeAddr) {
                _claimRewards(from);
                bridgeBlocks[tokenId] = Math.min(block.number, expiration);
                
            } else if (from == _bridgeAddr) {
                _claimRewards(to);
                _claimBridgeRewards(tokenId, to);
            }
        }
    }
    
    function daoAddr() external view returns (address) {
        return _daoAddr;
    }
    
    function nftAddr() external view returns (address) {
        return _nftAddr;
    }
    
    function erc20Addr() external view returns (address) {
        return _erc20Addr;
    }
    
    function bridgeAddr() external view returns (address) {
        return _bridgeAddr;
    }    

    function getConsonantsIndex(uint256 _tokenId) public view returns (uint8[3] memory) {
        return ILeedoNft(_nftAddr).getConsonantsIndex(_tokenId);
    }  

    function getConsonants(uint256 _tokenId) public view returns (string[3] memory) {
        return ILeedoNft(_nftAddr).getConsonants(_tokenId);
    }

    function getGenes(uint256 _tokenId) public view returns (uint8[8] memory) {
        return ILeedoNft(_nftAddr).getGenes(_tokenId);
    }
    
    function tokenURI(uint256 _tokenId) override public view returns (string memory) {
        
        string[9] memory parts;
        string[27] memory attrParts;
        string memory ojingeo;
        string memory sameConsonants;
        uint8[8] memory geneArray = getGenes(_tokenId);
        string[3] memory consArray = getConsonants(_tokenId);
        uint8[3] memory consIndex = getConsonantsIndex(_tokenId);        
        if (consIndex[0] == 7 && consIndex[1] == 14 && consIndex[2] == 4) {
            ojingeo = 'Y';
        } else {
            ojingeo = 'N';
        }
        if (consIndex[0] == consIndex[1] && consIndex[0] == consIndex[2]) {
            sameConsonants = 'Y';
        } else {
            sameConsonants = 'N';
        }

        parts[0] = '<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 350 220">';
        parts[1] = '<style>.base {font-family: Verdana; fill: white;}</style>';
        parts[2] = '<rect width="100%" height="100%" fill="#458B74" />';
        parts[3] = '<text x="50%" y="100" dominant-baseline="middle" text-anchor="middle" class="base" style="font-size:700%; letter-spacing: -0.2em;">';
        parts[4] = string(abi.encodePacked(consArray[0], ' ', consArray[1], ' ', consArray[2]));
        parts[5] = '</text><text x="50%" y="180" dominant-baseline="middle" text-anchor="middle" class="base" style="font-size:150%;">&#937; ';
        parts[6] = string(abi.encodePacked(toString(geneArray[0]), toString(geneArray[1]), toString(geneArray[2]), toString(geneArray[3]), ' '));
        parts[7] = string(abi.encodePacked(toString(geneArray[4]), toString(geneArray[5]), toString(geneArray[6]), toString(geneArray[7]) ));
        parts[8] ='</text></svg>';
        
        string memory output = string(abi.encodePacked(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6], parts[7], parts[8]));

        attrParts[0] = '[{"trait_type": "Left Consonant", "value": "';
        attrParts[1] = consArray[0];
        attrParts[2] = '"}, {"trait_type": "Center Consonant", "value": "';
        attrParts[3] = consArray[1];
        attrParts[4] = '"}, {"trait_type": "Right Consonant", "value": "';        
        attrParts[5] = consArray[2];
        attrParts[6] = '"}, {"trait_type": "Gene0", "value": "';
        attrParts[7] = toString(geneArray[0]);
        attrParts[8] = '"}, {"trait_type": "Gene1", "value": "';
        attrParts[9] = toString(geneArray[1]);
        attrParts[10] = '"}, {"trait_type": "Gene2", "value": "';        
        attrParts[11] = toString(geneArray[2]);
        attrParts[12] = '"}, {"trait_type": "Gene3", "value": "';        
        attrParts[13] = toString(geneArray[3]);
        attrParts[14] = '"}, {"trait_type": "Gene4", "value": "';        
        attrParts[15] = toString(geneArray[4]);
        attrParts[16] = '"}, {"trait_type": "Gene5", "value": "';        
        attrParts[17] = toString(geneArray[5]);
        attrParts[18] = '"}, {"trait_type": "Gene6", "value": "';        
        attrParts[19] = toString(geneArray[6]);
        attrParts[20] = '"}, {"trait_type": "Gene7", "value": "';        
        attrParts[21] = toString(geneArray[7]);
        attrParts[22] = '"}, {"trait_type": "Ojingeo", "value": "';        
        attrParts[23] = ojingeo;
        attrParts[24] = '"}, {"trait_type": "Same Consonants", "value": "';        
        attrParts[25] = sameConsonants;
        attrParts[26] = '"}]';
        
        string memory attrs = string(abi.encodePacked(attrParts[0], attrParts[1], attrParts[2], attrParts[3], attrParts[4], attrParts[5], attrParts[6], attrParts[7]));
        attrs = string(abi.encodePacked(attrs, attrParts[8], attrParts[9], attrParts[10], attrParts[11], attrParts[12], attrParts[13], attrParts[14]));        
        attrs = string(abi.encodePacked(attrs, attrParts[15], attrParts[16], attrParts[17], attrParts[18], attrParts[19], attrParts[20]));        
        attrs = string(abi.encodePacked(attrs, attrParts[21], attrParts[22], attrParts[23], attrParts[24], attrParts[25], attrParts[26]));        

        string memory json = Base64.encode(bytes(string(abi.encodePacked('{"name": "LEEDO LP - Squid Game Card NFT #', toString(_tokenId), '", "attributes": ', attrs ,', "description": "The squid game cards are invitation to enter the adventurous and mysterious metaverse games. Genes characteristics and other functionality are intentionally omitted for unlimited imagination and community-driven game development. Start your journey now!", "image": "data:image/svg+xml;base64,', Base64.encode(bytes(output)), '"}'))));
        output = string(abi.encodePacked('data:application/json;base64,', json));
        return output;
    }    
       
    //function tokenURI(uint256 _tokenId) public override view returns (string memory) {
    //    return ILeedoNft(_nftAddr).tokenURI(_tokenId);
    //}    

    function onERC721Received(
        address, 
        address, 
        uint256, 
        bytes calldata
        ) pure external returns(bytes4) {
        return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));
    }
    
    function toString(uint256 value) internal pure returns (string memory) {
    // Inspired by OraclizeAPI's implementation - MIT license
    // 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);
    }    
    
}
/// [MIT License]
/// @title Base64
/// @notice Provides a function for encoding some bytes in base64
/// @author Brecht Devos <[email protected]>
library Base64 {
    bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /// @notice Encodes some bytes to the base64 representation
    function encode(bytes memory data) internal pure returns (string memory) {
        uint256 len = data.length;
        if (len == 0) return "";

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((len + 2) / 3);

        // Add some extra buffer at the end
        bytes memory result = new bytes(encodedLen + 32);

        bytes memory table = TABLE;

        assembly {
            let tablePtr := add(table, 1)
            let resultPtr := add(result, 32)

            for {
                let i := 0
            } lt(i, len) {

            } {
                i := add(i, 3)
                let input := and(mload(add(data, i)), 0xffffff)

                let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
                out := shl(224, out)

                mstore(resultPtr, out)

                resultPtr := add(resultPtr, 4)
            }

            switch mod(len, 3)
            case 1 {
                mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
            }
            case 2 {
                mstore(sub(resultPtr, 1), shl(248, 0x3d))
            }

            mstore(result, encodedLen)
        }

        return string(result);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_nftAddress","type":"address"},{"internalType":"address","name":"_erc20Address","type":"address"},{"internalType":"address","name":"_bridgeAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bridgeAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"calcBridgeRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"calcRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"daoAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"daoInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"erc20Addr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"expiration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getConsonants","outputs":[{"internalType":"string[3]","name":"","type":"string[3]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getConsonantsIndex","outputs":[{"internalType":"uint8[3]","name":"","type":"uint8[3]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getGenes","outputs":[{"internalType":"uint8[8]","name":"","type":"uint8[8]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_daoAddress","type":"address"}],"name":"initializeDao","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":"address","name":"","type":"address"}],"name":"lastBlocks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","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":"rate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"bool","name":"_bool","type":"bool"}],"name":"setAllowTransfer","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":"address","name":"_bridgeAddress","type":"address"}],"name":"setBridgeAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_bridgeAddress","type":"address"}],"name":"setBridgeAddrByDao","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_daoAddress","type":"address"}],"name":"setDaoAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_erc20Address","type":"address"}],"name":"setErc20Addr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_erc20Address","type":"address"}],"name":"setErc20AddrByDao","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_expiration","type":"uint256"}],"name":"setExpiration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rate","type":"uint256"}],"name":"setRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"stake","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"stakeByCount","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"tokensOf","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalClaims","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"transferAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052600c805461ffff191690556200001f436301e1338062000259565b601055661274b5fc6574d86011553480156200003a57600080fd5b5060405162004adf38038062004adf8339810160408190526200005d916200029d565b604080518082018252601a81527f4c4545444f204c50202d2053717569642047616d65204361726400000000000060208083019182528351808501909452601484527f4c6565646f537175696447616d65436172644c50000000000000000000000000908401528151919291620000d791600091620001b3565b508051620000ed906001906020840190620001b3565b5050506200010a620001046200015d60201b60201c565b62000161565b6001600b55600c80546001600160a01b03948516620100000262010000600160b01b0319909116179055600d80549284166001600160a01b0319938416179055600e805491909316911617905562000324565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620001c190620002e7565b90600052602060002090601f016020900481019282620001e5576000855562000230565b82601f106200020057805160ff191683800117855562000230565b8280016001018555821562000230579182015b828111156200023057825182559160200191906001019062000213565b506200023e92915062000242565b5090565b5b808211156200023e576000815560010162000243565b600082198211156200027b57634e487b7160e01b600052601160045260246000fd5b500190565b80516001600160a01b03811681146200029857600080fd5b919050565b600080600060608486031215620002b357600080fd5b620002be8462000280565b9250620002ce6020850162000280565b9150620002de6040850162000280565b90509250925092565b600181811c90821680620002fc57607f821691505b602082108114156200031e57634e487b7160e01b600052602260045260246000fd5b50919050565b6147ab80620003346000396000f3fe608060405234801561001057600080fd5b50600436106102bb5760003560e01c80635a3f267211610182578063a22cb465116100e9578063bab607e5116100a2578063cb8af7451161007c578063cb8af74514610686578063e985e9c5146106a6578063f2fde38b146106e2578063fbd6869f146106f557600080fd5b8063bab607e51461064d578063bf03fadc14610660578063c87b56dd1461067357600080fd5b8063a22cb465146105c3578063a2e4b12e146105d6578063a8d2e46a146105f6578063ae1c786814610607578063b88d4fde1461061a578063ba89696d1461062d57600080fd5b8063740f1e181161013b578063740f1e181461055c5780638da5cb5b1461057357806391874ef71461058457806391da52281461059557806395d89b41146105a8578063983d95ce146105b057600080fd5b80635a3f2672146104db5780635f71dadc146104fb5780636352211e1461051b578063696242dd1461052e57806370a0823114610541578063715018a61461055457600080fd5b80632f7b73de1161022657806342842e0e116101df57806342842e0e146104795780634665096d1461048c5780634dc076d6146104955780634f6ccce7146104a8578063515a20ba146104bb57806355d4b56f146104ce57600080fd5b80632f7b73de14610408578063317e3ce01461041b57806334fcf4371461042c57806334fec4671461043f578063372500ab146104515780634054ed901461045957600080fd5b806313ffff011161027857806313ffff0114610363578063150b7a021461037657806318160ddd146103c757806323b872dd146103d95780632c4e722e146103ec5780632f745c59146103f557600080fd5b806301ffc9a7146102c057806306fdde03146102e8578063081812fc146102fd578063095ea7b3146103285780630b81e2161461033d5780630fbf0a9314610350575b600080fd5b6102d36102ce36600461334b565b610708565b60405190151581526020015b60405180910390f35b6102f0610733565b6040516102df91906133c0565b61031061030b3660046133d3565b6107c5565b6040516001600160a01b0390911681526020016102df565b61033b610336366004613401565b61085f565b005b61033b61034b36600461343b565b610975565b6102d361035e366004613458565b6109b9565b61033b6103713660046134cd565b610c2e565b6103ae6103843660046134ea565b7f150b7a023d4804d13e8c85fb27262cb750cf6ba9f9dd3bb30d90f482ceeb4b1f95945050505050565b6040516001600160e01b031990911681526020016102df565b6008545b6040519081526020016102df565b61033b6103e7366004613589565b610c9d565b6103cb60115481565b6103cb610403366004613401565b610cce565b61033b6104163660046134cd565b610d64565b600d546001600160a01b0316610310565b61033b61043a3660046133d3565b610de0565b600c546102d390610100900460ff1681565b61033b610e0f565b6103cb6104673660046134cd565b60136020526000908152604090205481565b61033b610487366004613589565b610e1a565b6103cb60105481565b61033b6104a33660046134cd565b610e35565b6103cb6104b63660046133d3565b610ea4565b61033b6104c93660046133d3565b610f37565b600c546102d39060ff1681565b6104ee6104e93660046134cd565b610f71565b6040516102df91906135ca565b6103cb6105093660046134cd565b60126020526000908152604090205481565b6103106105293660046133d3565b611015565b61033b61053c3660046134cd565b61108c565b6103cb61054f3660046134cd565b6110b6565b61033b61113d565b600c546201000090046001600160a01b0316610310565b600a546001600160a01b0316610310565b600e546001600160a01b0316610310565b6104ee6105a33660046133d3565b611171565b6102f061149b565b61033b6105be366004613458565b6114aa565b61033b6105d136600461360e565b6115d0565b6105e96105e43660046133d3565b611695565b6040516102df9190613647565b600f546001600160a01b0316610310565b6103cb6106153660046134cd565b61171f565b61033b610628366004613714565b6117de565b61064061063b3660046133d3565b611816565b6040516102df91906137c3565b61033b61065b3660046134cd565b6118a3565b6103cb61066e3660046133d3565b6118ef565b6102f06106813660046133d3565b611982565b6106996106943660046133d3565b6120e1565b6040516102df9190613810565b6102d36106b436600461383b565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61033b6106f03660046134cd565b61216a565b61033b6107033660046134cd565b612205565b60006001600160e01b0319821663780e9d6360e01b148061072d575061072d8261222f565b92915050565b60606000805461074290613869565b80601f016020809104026020016040519081016040528092919081815260200182805461076e90613869565b80156107bb5780601f10610790576101008083540402835291602001916107bb565b820191906000526020600020905b81548152906001019060200180831161079e57829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166108435760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061086a82611015565b9050806001600160a01b0316836001600160a01b031614156108d85760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161083a565b336001600160a01b03821614806108f457506108f481336106b4565b6109665760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161083a565b610970838361227f565b505050565b600f546001600160a01b0316331461099f5760405162461bcd60e51b815260040161083a906138a4565b600c80549115156101000261ff0019909216919091179055565b60006109c3610e0f565b600c546201000090046001600160a01b031660005b83811015610c235760008585838181106109f4576109f46138e9565b905060200201359050610a1e816000908152600260205260409020546001600160a01b0316151590565b15610a775760405162461bcd60e51b8152602060048201526024808201527f4e66745661756c743a2054686520746f6b656e496420616c72656164792065786044820152636973747360e01b606482015260840161083a565b336040516331a9108f60e11b8152600481018390526001600160a01b0391821691851690636352211e9060240160206040518083038186803b158015610abc57600080fd5b505afa158015610ad0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af491906138ff565b6001600160a01b031614610b4a5760405162461bcd60e51b815260206004820152601e60248201527f4e66745661756c743a204f776e657220697320646966666572656e656e740000604482015260640161083a565b600c546201000090046001600160a01b031663b88d4fde3330846040518463ffffffff1660e01b8152600401610b829392919061391c565b600060405180830381600087803b158015610b9c57600080fd5b505af1158015610bb0573d6000803e3d6000fd5b50505050610bc4610bbe3390565b826122ed565b610c105760405162461bcd60e51b815260206004820152601860248201527f4e667456616c75743a205374616b696e67206661696c65640000000000000000604482015260640161083a565b5080610c1b81613965565b9150506109d8565b506001949350505050565b600a546001600160a01b03163314610c585760405162461bcd60e51b815260040161083a90613980565b600c5460ff1615610c7b5760405162461bcd60e51b815260040161083a906139b5565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b610ca7338261232e565b610cc35760405162461bcd60e51b815260040161083a906139f9565b610970838383612425565b6000610cd9836110b6565b8210610d3b5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161083a565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600a546001600160a01b03163314610d8e5760405162461bcd60e51b815260040161083a90613980565b600c5460ff1615610db15760405162461bcd60e51b815260040161083a906139b5565b600f80546001600160a01b0319166001600160a01b0392909216919091179055600c805460ff19166001179055565b600f546001600160a01b03163314610e0a5760405162461bcd60e51b815260040161083a906138a4565b601155565b610e18336125d0565b565b610970838383604051806020016040528060008152506117de565b600a546001600160a01b03163314610e5f5760405162461bcd60e51b815260040161083a90613980565b600c5460ff1615610e825760405162461bcd60e51b815260040161083a906139b5565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610eaf60085490565b8210610f125760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161083a565b60088281548110610f2557610f256138e9565b90600052602060002001549050919050565b600f546001600160a01b03163314610f615760405162461bcd60e51b815260040161083a906138a4565b610f6b8143613a4a565b60105550565b60606000610f7e836110b6565b67ffffffffffffffff811115610f9657610f9661367c565b604051908082528060200260200182016040528015610fbf578160200160208202803683370190505b50905060005b610fce846110b6565b81101561100e57610fdf8482610cce565b828281518110610ff157610ff16138e9565b60209081029190910101528061100681613965565b915050610fc5565b5092915050565b6000818152600260205260408120546001600160a01b03168061072d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b606482015260840161083a565b600f546001600160a01b03163314610c7b5760405162461bcd60e51b815260040161083a906138a4565b60006001600160a01b0382166111215760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161083a565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b031633146111675760405162461bcd60e51b815260040161083a90613980565b610e18600061273f565b606061117b610e0f565b600c546201000090046001600160a01b0316806370a08231336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b1580156111d357600080fd5b505afa1580156111e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061120b9190613a62565b83111561126d5760405162461bcd60e51b815260206004820152602a60248201527f4e66745661756c743a20436f756e74206973206d6f7265207468616e20746865604482015269206f776e65722068617360b01b606482015260840161083a565b60008367ffffffffffffffff8111156112885761128861367c565b6040519080825280602002602001820160405280156112b1578160200160208202803683370190505b50905060005b8481101561137c576001600160a01b038316632f745c59336040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024810184905260440160206040518083038186803b15801561131557600080fd5b505afa158015611329573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134d9190613a62565b82828151811061135f5761135f6138e9565b60209081029190910101528061137481613965565b9150506112b7565b5060005b815181101561149357600c546201000090046001600160a01b031663b88d4fde33308585815181106113b4576113b46138e9565b60200260200101516040518463ffffffff1660e01b81526004016113da9392919061391c565b600060405180830381600087803b1580156113f457600080fd5b505af1158015611408573d6000803e3d6000fd5b505050506114356114163390565b838381518110611428576114286138e9565b60200260200101516122ed565b6114815760405162461bcd60e51b815260206004820152601860248201527f4e66745661756c743a205374616b696e67206661696c65640000000000000000604482015260640161083a565b8061148b81613965565b915050611380565b509392505050565b60606001805461074290613869565b6114b2610e0f565b60005b818110156109705760008383838181106114d1576114d16138e9565b9050602002013590506114e13390565b6001600160a01b03166114f382611015565b6001600160a01b0316146115495760405162461bcd60e51b815260206004820152601f60248201527f4e66745661756c743a204c50206f776e657220697320646966666572656e7400604482015260640161083a565b61155281612791565b600c546201000090046001600160a01b031663b88d4fde3033846040518463ffffffff1660e01b815260040161158a9392919061391c565b600060405180830381600087803b1580156115a457600080fd5b505af11580156115b8573d6000803e3d6000fd5b505050505080806115c890613965565b9150506114b5565b6001600160a01b0382163314156116295760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161083a565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61169d61329b565b600c54604051635172589760e11b815260048101849052620100009091046001600160a01b03169063a2e4b12e906024016101006040518083038186803b1580156116e757600080fd5b505afa1580156116fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072d9190613a91565b6001600160a01b038116600090815260126020526040812054601054611746904390612838565b10156117855760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420626c6f636b7360901b604482015260640161083a565b6001600160a01b0382166000908152601260205260408120546010546117ac904390612838565b6117b69190613b17565b90506117d7816117d16117c8866110b6565b6011549061284e565b9061284e565b9392505050565b6117e8338361232e565b6118045760405162461bcd60e51b815260040161083a906139f9565b6118108484848461285a565b50505050565b61181e6132ba565b600c5460405163ba89696d60e01b815260048101849052620100009091046001600160a01b03169063ba89696d9060240160006040518083038186803b15801561186757600080fd5b505afa15801561187b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261072d9190810190613b2e565b600f546001600160a01b031633146118cd5760405162461bcd60e51b815260040161083a906138a4565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b60008181526014602052604081205460105461190c904390612838565b101561194b5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420626c6f636b7360901b604482015260640161083a565b600082815260146020526040812054601054611968904390612838565b6119729190613b17565b6011549091506117d7908261284e565b606061198c6132e1565b6119946132fc565b60608060006119a287611695565b905060006119af88611816565b905060006119bc896120e1565b805190915060ff1660071480156119dd5750806001602002015160ff16600e145b80156119f35750806002602002015160ff166004145b15611a1957604051806040016040528060018152602001605960f81b8152509450611a36565b604051806040016040528060018152602001602760f91b81525094505b6020810151815160ff9081169116148015611a5c57506040810151815160ff9081169116145b15611a8257604051806040016040528060018152602001605960f81b8152509350611a9f565b604051806040016040528060018152602001602760f91b81525093505b6040518060a0016040528060628152602001614714606291398752604080516060810190915260398082526143ae602083013987600160200201819052506040518060600160405280603281526020016146e260329139604080890191909152805160c08101909152608380825261459f6020830139606088015281516020838101516040808601519051611b35949301613c1f565b60408051808303601f190181529181526080890191909152805160a0810190915260798082526144b4602083013960a0880152611b7c8360005b602002015160ff1661288d565b611b87846001611b6f565b611b92856002611b6f565b611b9d866003611b6f565b604051602001611bb09493929190613c79565b60408051808303601f1901815291905260c0880152611bd0836004611b6f565b611bdb846005611b6f565b611be6856006611b6f565b611bf1866007611b6f565b604051602001611c049493929190613cdc565b60408051808303601f1901815291815260e08901919091528051808201909152600d81526c1e17ba32bc3a1f1e17b9bb339f60991b60208201528760086020020152600087816020020151886001602002015189600260200201518a600360200201518b600460200201518c600560200201518d600660200201518e600760200201518f60086020020151604051602001611ca799989796959493929190613d33565b60408051601f1981840301815260608301909152602c808352909250614448602083013987528251602080890191909152604080516060810190915260318082529091614417908301398760026020020152826001602002015187600360200201819052506040518060600160405280603081526020016143e760309139608088015260408084015160a08901528051606081019091526026808252614553602083013960c0880152611d5b846000611b6f565b60e08801526040805160608101909152602680825261464a6020830139610100880152611d89846001611b6f565b6101208801526040805160608101909152602680825261452d6020830139610140880152611db8846002611b6f565b610160880152604080516060810190915260268082526145796020830139610180880152611de7846003611b6f565b6101a08801526040805160608101909152602680825261469660208301396101c0880152611e16846004611b6f565b6101e0880152604080516060810190915260268082526143886020830139610200880152611e45846005611b6f565b610220880152604080516060810190915260268082526146bc6020830139610240880152611e74846006611b6f565b610260880152604080516060810190915260268082526146706020830139610280880152611ea3846007611b6f565b6102a08801526040805160608101909152602880825261462260208301396102c08801526102e087018690526040805160608101909152603080825261435860208301396103008801526103208701859052604080518082019091526003815262227d5d60e81b602082015287601a6020020152600087816020020151886001602002015189600260200201518a600360200201518b600460200201518c600560200201518d600660200201518e60076020020151604051602001611f6f989796959493929190613df4565b60408051601f19818403018152919052905080886008602002015189600960200201518a600a60200201518b600b60200201518c600c60200201518d600d60200201518e600e6020020151604051602001611fd1989796959493929190613df4565b60408051808303601f19018152908290526101e08a01516102008b01516102208c01516102408d01516102608e01516102808f015195975061201896889690602001613e99565b60408051808303601f19018152908290526102a08a01516102c08b01516102e08c01516103008d01516103208e01516103408f015195975061205f96889690602001613e99565b604051602081830303815290604052905060006120ae61207e8d61288d565b836120888661298b565b60405160200161209a93929190613f2b565b60405160208183030381529060405261298b565b9050806040516020016120c1919061414d565b60408051601f198184030181529190529c9b505050505050505050505050565b6120e9613317565b600c5460405163cb8af74560e01b815260048101849052620100009091046001600160a01b03169063cb8af7459060240160606040518083038186803b15801561213257600080fd5b505afa158015612146573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072d9190614192565b600a546001600160a01b031633146121945760405162461bcd60e51b815260040161083a90613980565b6001600160a01b0381166121f95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161083a565b6122028161273f565b50565b600f546001600160a01b03163314610e825760405162461bcd60e51b815260040161083a906138a4565b60006001600160e01b031982166380ac58cd60e01b148061226057506001600160e01b03198216635b5e139f60e01b145b8061072d57506301ffc9a760e01b6001600160e01b031983161461072d565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906122b482611015565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006002600b5414156123125760405162461bcd60e51b815260040161083a906141ee565b6002600b556123218383612af1565b50600180600b5592915050565b6000818152600260205260408120546001600160a01b03166123a75760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161083a565b60006123b283611015565b9050806001600160a01b0316846001600160a01b031614806123ed5750836001600160a01b03166123e2846107c5565b6001600160a01b0316145b8061241d57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661243882611015565b6001600160a01b0316146124a05760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161083a565b6001600160a01b0382166125025760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161083a565b61250d838383612b0f565b61251860008261227f565b6001600160a01b0383166000908152600360205260408120805460019290612541908490613b17565b90915550506001600160a01b038216600090815260036020526040812080546001929061256f908490613a4a565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6002600b5414156125f35760405162461bcd60e51b815260040161083a906141ee565b6002600b5560006126038261171f565b9050600061261343601054612838565b3360009081526012602052604090208190559050811561273557336000908152601360205260409020546126479083612c53565b60136000336001600160a01b0390811682526020820192909252604090810160002092909255600d549151633bf8968160e01b8152858216600482015260248101859052911690633bf8968190604401602060405180830381600087803b1580156126b157600080fd5b505af11580156126c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126e99190614225565b6127355760405162461bcd60e51b815260206004820152601e60248201527f4e66745661756c743a204c6565646f204d696e74696e67206661696c65640000604482015260640161083a565b50506001600b5550565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600061279c82611015565b90506127aa81600084612b0f565b6127b560008361227f565b6001600160a01b03811660009081526003602052604081208054600192906127de908490613b17565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600081831061284757816117d7565b5090919050565b60006117d78284614242565b612865848484612425565b61287184848484612c5f565b6118105760405162461bcd60e51b815260040161083a90614261565b6060816128b15750506040805180820190915260018152600360fc1b602082015290565b8160005b81156128db57806128c581613965565b91506128d49050600a836142c9565b91506128b5565b60008167ffffffffffffffff8111156128f6576128f661367c565b6040519080825280601f01601f191660200182016040528015612920576020820181803683370190505b5090505b841561241d57612935600183613b17565b9150612942600a866142dd565b61294d906030613a4a565b60f81b818381518110612962576129626138e9565b60200101906001600160f81b031916908160001a905350612984600a866142c9565b9450612924565b8051606090806129ab575050604080516020810190915260008152919050565b600060036129ba836002613a4a565b6129c491906142c9565b6129cf906004614242565b905060006129de826020613a4a565b67ffffffffffffffff8111156129f6576129f661367c565b6040519080825280601f01601f191660200182016040528015612a20576020820181803683370190505b5090506000604051806060016040528060408152602001614474604091399050600181016020830160005b86811015612aac576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b835260049092019101612a4b565b506003860660018114612ac65760028114612ad757612ae3565b613d3d60f01b600119830152612ae3565b603d60f81b6000198301525b505050918152949350505050565b612b0b828260405180602001604052806000815250612d61565b5050565b612b1a838383612d94565b6001600160a01b03831615801590612b3a57506001600160a01b03821615155b1561097057600e546001600160a01b03848116911614801590612b6b5750600e546001600160a01b03838116911614155b15612beb57600c54610100900460ff16612bd95760405162461bcd60e51b815260206004820152602960248201527f4e66745661756c743a20526567756c6172207472616e73666572206973206e6f6044820152681d08185b1b1bddd95960ba1b606482015260840161083a565b612be2836125d0565b610970826125d0565b600e546001600160a01b0383811691161415612c2a57612c0a836125d0565b612c1643601054612838565b600082815260146020526040902055505050565b600e546001600160a01b038481169116141561097057612c49826125d0565b6109708183612e4c565b60006117d78284613a4a565b60006001600160a01b0384163b15610c2357604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612ca39033908990889088906004016142f1565b602060405180830381600087803b158015612cbd57600080fd5b505af1925050508015612ced575060408051601f3d908101601f19168201909252612cea91810190614324565b60015b612d47573d808015612d1b576040519150601f19603f3d011682016040523d82523d6000602084013e612d20565b606091505b508051612d3f5760405162461bcd60e51b815260040161083a90614261565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061241d565b612d6b8383612fbd565b612d786000848484612c5f565b6109705760405162461bcd60e51b815260040161083a90614261565b6001600160a01b038316612def57612dea81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612e12565b816001600160a01b0316836001600160a01b031614612e1257612e12838261310b565b6001600160a01b038216612e2957610970816131a8565b826001600160a01b0316826001600160a01b031614610970576109708282613257565b6002600b541415612e6f5760405162461bcd60e51b815260040161083a906141ee565b6002600b556000612e7f836118ef565b90506000612e8f43601054612838565b600085815260146020526040902081905590508115612fb2576001600160a01b038316600090815260136020526040902054612ecb9083612c53565b6001600160a01b038481166000818152601360205260409081902093909355600d549251633bf8968160e01b8152600481019190915260248101859052911690633bf8968190604401602060405180830381600087803b158015612f2e57600080fd5b505af1158015612f42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f669190614225565b612fb25760405162461bcd60e51b815260206004820152601e60248201527f4e66745661756c743a204c6565646f204d696e74696e67206661696c65640000604482015260640161083a565b50506001600b555050565b6001600160a01b0382166130135760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161083a565b6000818152600260205260409020546001600160a01b0316156130785760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161083a565b61308460008383612b0f565b6001600160a01b03821660009081526003602052604081208054600192906130ad908490613a4a565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001613118846110b6565b6131229190613b17565b600083815260076020526040902054909150808214613175576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906131ba90600190613b17565b600083815260096020526040812054600880549394509092849081106131e2576131e26138e9565b906000526020600020015490508060088381548110613203576132036138e9565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061323b5761323b614341565b6001900381819060005260206000200160009055905550505050565b6000613262836110b6565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6040518061010001604052806008906020820280368337509192915050565b60405180606001604052806003905b60608152602001906001900390816132c95790505090565b604080516101208101909152606081526008602082016132c9565b60408051610360810190915260608152601a602082016132c9565b60405180606001604052806003906020820280368337509192915050565b6001600160e01b03198116811461220257600080fd5b60006020828403121561335d57600080fd5b81356117d781613335565b60005b8381101561338357818101518382015260200161336b565b838111156118105750506000910152565b600081518084526133ac816020860160208601613368565b601f01601f19169290920160200192915050565b6020815260006117d76020830184613394565b6000602082840312156133e557600080fd5b5035919050565b6001600160a01b038116811461220257600080fd5b6000806040838503121561341457600080fd5b823561341f816133ec565b946020939093013593505050565b801515811461220257600080fd5b60006020828403121561344d57600080fd5b81356117d78161342d565b6000806020838503121561346b57600080fd5b823567ffffffffffffffff8082111561348357600080fd5b818501915085601f83011261349757600080fd5b8135818111156134a657600080fd5b8660208260051b85010111156134bb57600080fd5b60209290920196919550909350505050565b6000602082840312156134df57600080fd5b81356117d7816133ec565b60008060008060006080868803121561350257600080fd5b853561350d816133ec565b9450602086013561351d816133ec565b935060408601359250606086013567ffffffffffffffff8082111561354157600080fd5b818801915088601f83011261355557600080fd5b81358181111561356457600080fd5b89602082850101111561357657600080fd5b9699959850939650602001949392505050565b60008060006060848603121561359e57600080fd5b83356135a9816133ec565b925060208401356135b9816133ec565b929592945050506040919091013590565b6020808252825182820181905260009190848201906040850190845b81811015613602578351835292840192918401916001016135e6565b50909695505050505050565b6000806040838503121561362157600080fd5b823561362c816133ec565b9150602083013561363c8161342d565b809150509250929050565b6101008101818360005b600881101561367357815160ff16835260209283019290910190600101613651565b50505092915050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156136b5576136b561367c565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156136e4576136e461367c565b604052919050565b600067ffffffffffffffff8211156137065761370661367c565b50601f01601f191660200190565b6000806000806080858703121561372a57600080fd5b8435613735816133ec565b93506020850135613745816133ec565b925060408501359150606085013567ffffffffffffffff81111561376857600080fd5b8501601f8101871361377957600080fd5b803561378c613787826136ec565b6136bb565b8181528860208385010111156137a157600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b60208082526000906080830183820185845b600381101561380457601f198785030183526137f2848351613394565b935091840191908401906001016137d5565b50919695505050505050565b60608101818360005b600381101561367357815160ff16835260209283019290910190600101613819565b6000806040838503121561384e57600080fd5b8235613859816133ec565b9150602083013561363c816133ec565b600181811c9082168061387d57607f821691505b6020821081141561389e57634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526025908201527f5641554c543a2063616c6c6572206973206e6f74207468652044414f20616464604082015264726573732160d81b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561391157600080fd5b81516117d7816133ec565b6001600160a01b039384168152919092166020820152604081019190915260806060820181905260009082015260a00190565b634e487b7160e01b600052601160045260246000fd5b60006000198214156139795761397961394f565b5060010190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526024908201527f4e66745661756c743a2044414f20697320616c726561647920696e697469616c6040820152631a5e995960e21b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60008219821115613a5d57613a5d61394f565b500190565b600060208284031215613a7457600080fd5b5051919050565b805160ff81168114613a8c57600080fd5b919050565b6000610100808385031215613aa557600080fd5b83601f840112613ab457600080fd5b60405181810181811067ffffffffffffffff82111715613ad657613ad661367c565b604052908301908085831115613aeb57600080fd5b845b83811015613b0c57613afe81613a7b565b825260209182019101613aed565b509095945050505050565b600082821015613b2957613b2961394f565b500390565b60006020808385031215613b4157600080fd5b825167ffffffffffffffff80821115613b5957600080fd5b8185019150601f8681840112613b6e57600080fd5b613b76613692565b806060850189811115613b8857600080fd5b855b81811015613bf457805186811115613ba25760008081fd5b87018581018c13613bb35760008081fd5b8051613bc1613787826136ec565b8181528d8b838501011115613bd65760008081fd5b613be5828c83018d8601613368565b86525050928701928701613b8a565b50909998505050505050505050565b60008151613c15818560208601613368565b9290920192915050565b60008451613c31818460208901613368565b8083019050600160fd1b8082528551613c51816001850160208a01613368565b60019201918201528351613c6c816002840160208801613368565b0160020195945050505050565b60008551613c8b818460208a01613368565b855190830190613c9f818360208a01613368565b8551910190613cb2818360208901613368565b8451910190613cc5818360208801613368565b600160fd1b91019081526001019695505050505050565b60008551613cee818460208a01613368565b855190830190613d02818360208a01613368565b8551910190613d15818360208901613368565b8451910190613d28818360208801613368565b019695505050505050565b60008a51613d45818460208f01613368565b8a51613d578183860160208f01613368565b8a519184010190613d6c818360208e01613368565b8951613d7e8183850160208e01613368565b8951929091010190613d94818360208c01613368565b8751613da68183850160208c01613368565b8751929091010190613dbc818360208a01613368565b8551613dce8183850160208a01613368565b8551929091010190613de4818360208801613368565b019b9a5050505050505050505050565b600089516020613e078285838f01613368565b8a5191840191613e1a8184848f01613368565b8a51920191613e2c8184848e01613368565b8951920191613e3e8184848d01613368565b8851920191613e508184848c01613368565b8751920191613e628184848b01613368565b8651920191613e748184848a01613368565b8551920191613e868184848901613368565b919091019b9a5050505050505050505050565b600088516020613eac8285838e01613368565b895191840191613ebf8184848e01613368565b8951920191613ed18184848d01613368565b8851920191613ee38184848c01613368565b8751920191613ef58184848b01613368565b8651920191613f078184848a01613368565b8551920191613f198184848901613368565b919091019a9950505050505050505050565b7f7b226e616d65223a20224c4545444f204c50202d2053717569642047616d652081526943617264204e4654202360b01b602082015260008451613f7681602a850160208901613368565b7001116101130ba3a3934b13aba32b9911d1607d1b602a918401918201528451613fa781603b840160208901613368565b7f2c20226465736372697074696f6e223a20225468652073717569642067616d65603b92909101918201527f2063617264732061726520696e7669746174696f6e20746f20656e7465722074605b8201527f686520616476656e7475726f757320616e64206d7973746572696f7573206d65607b8201527f746176657273652067616d65732e2047656e6573206368617261637465726973609b8201527f7469637320616e64206f746865722066756e6374696f6e616c6974792061726560bb8201527f20696e74656e74696f6e616c6c79206f6d697474656420666f7220756e6c696d60db8201527f6974656420696d6167696e6174696f6e20616e6420636f6d6d756e6974792d6460fb8201527f726976656e2067616d6520646576656c6f706d656e742e20537461727420796f61011b8201527f7572206a6f75726e6579206e6f7721222c2022696d616765223a20226461746161013b820152750e9a5b5859d94bdcdd99cade1b5b0ed8985cd94d8d0b60521b61015b820152614143614135610171830186613c03565b61227d60f01b815260020190565b9695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161418581601d850160208701613368565b91909101601d0192915050565b6000606082840312156141a457600080fd5b82601f8301126141b357600080fd5b6141bb613692565b8060608401858111156141cd57600080fd5b845b81811015613b0c576141e081613a7b565b8452602093840193016141cf565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60006020828403121561423757600080fd5b81516117d78161342d565b600081600019048311821515161561425c5761425c61394f565b500290565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b6000826142d8576142d86142b3565b500490565b6000826142ec576142ec6142b3565b500690565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061414390830184613394565b60006020828403121561433657600080fd5b81516117d781613335565b634e487b7160e01b600052603160045260246000fdfe227d2c207b2274726169745f74797065223a202253616d6520436f6e736f6e616e7473222c202276616c7565223a2022227d2c207b2274726169745f74797065223a202247656e6535222c202276616c7565223a20223c7374796c653e2e62617365207b666f6e742d66616d696c793a2056657264616e613b2066696c6c3a2077686974653b7d3c2f7374796c653e227d2c207b2274726169745f74797065223a2022526967687420436f6e736f6e616e74222c202276616c7565223a2022227d2c207b2274726169745f74797065223a202243656e74657220436f6e736f6e616e74222c202276616c7565223a20225b7b2274726169745f74797065223a20224c65667420436f6e736f6e616e74222c202276616c7565223a20224142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f3c2f746578743e3c7465787420783d223530252220793d223138302220646f6d696e616e742d626173656c696e653d226d6964646c652220746578742d616e63686f723d226d6964646c652220636c6173733d226261736522207374796c653d22666f6e742d73697a653a313530253b223e26233933373b20227d2c207b2274726169745f74797065223a202247656e6532222c202276616c7565223a2022227d2c207b2274726169745f74797065223a202247656e6530222c202276616c7565223a2022227d2c207b2274726169745f74797065223a202247656e6533222c202276616c7565223a20223c7465787420783d223530252220793d223130302220646f6d696e616e742d626173656c696e653d226d6964646c652220746578742d616e63686f723d226d6964646c652220636c6173733d226261736522207374796c653d22666f6e742d73697a653a373030253b206c65747465722d73706163696e673a202d302e32656d3b223e227d2c207b2274726169745f74797065223a20224f6a696e67656f222c202276616c7565223a2022227d2c207b2274726169745f74797065223a202247656e6531222c202276616c7565223a2022227d2c207b2274726169745f74797065223a202247656e6537222c202276616c7565223a2022227d2c207b2274726169745f74797065223a202247656e6534222c202276616c7565223a2022227d2c207b2274726169745f74797065223a202247656e6536222c202276616c7565223a20223c726563742077696474683d223130302522206865696768743d2231303025222066696c6c3d222334353842373422202f3e3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d22784d696e594d696e206d656574222076696577426f783d223020302033353020323230223ea2646970667358221220241ca2ca573656e3d4cb2f404e33324c5b925920b39ec073fa9f48a696d2a23864736f6c63430008090033000000000000000000000000be5c953dd0ddb0ce033a98f36c981f1b74d3b33f0000000000000000000000003eede143adb9a80c6a44c63dad76269d33e2c8d1000000000000000000000000e6f45376f64e1f568bd1404c155e5ffd2f80f7ad

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102bb5760003560e01c80635a3f267211610182578063a22cb465116100e9578063bab607e5116100a2578063cb8af7451161007c578063cb8af74514610686578063e985e9c5146106a6578063f2fde38b146106e2578063fbd6869f146106f557600080fd5b8063bab607e51461064d578063bf03fadc14610660578063c87b56dd1461067357600080fd5b8063a22cb465146105c3578063a2e4b12e146105d6578063a8d2e46a146105f6578063ae1c786814610607578063b88d4fde1461061a578063ba89696d1461062d57600080fd5b8063740f1e181161013b578063740f1e181461055c5780638da5cb5b1461057357806391874ef71461058457806391da52281461059557806395d89b41146105a8578063983d95ce146105b057600080fd5b80635a3f2672146104db5780635f71dadc146104fb5780636352211e1461051b578063696242dd1461052e57806370a0823114610541578063715018a61461055457600080fd5b80632f7b73de1161022657806342842e0e116101df57806342842e0e146104795780634665096d1461048c5780634dc076d6146104955780634f6ccce7146104a8578063515a20ba146104bb57806355d4b56f146104ce57600080fd5b80632f7b73de14610408578063317e3ce01461041b57806334fcf4371461042c57806334fec4671461043f578063372500ab146104515780634054ed901461045957600080fd5b806313ffff011161027857806313ffff0114610363578063150b7a021461037657806318160ddd146103c757806323b872dd146103d95780632c4e722e146103ec5780632f745c59146103f557600080fd5b806301ffc9a7146102c057806306fdde03146102e8578063081812fc146102fd578063095ea7b3146103285780630b81e2161461033d5780630fbf0a9314610350575b600080fd5b6102d36102ce36600461334b565b610708565b60405190151581526020015b60405180910390f35b6102f0610733565b6040516102df91906133c0565b61031061030b3660046133d3565b6107c5565b6040516001600160a01b0390911681526020016102df565b61033b610336366004613401565b61085f565b005b61033b61034b36600461343b565b610975565b6102d361035e366004613458565b6109b9565b61033b6103713660046134cd565b610c2e565b6103ae6103843660046134ea565b7f150b7a023d4804d13e8c85fb27262cb750cf6ba9f9dd3bb30d90f482ceeb4b1f95945050505050565b6040516001600160e01b031990911681526020016102df565b6008545b6040519081526020016102df565b61033b6103e7366004613589565b610c9d565b6103cb60115481565b6103cb610403366004613401565b610cce565b61033b6104163660046134cd565b610d64565b600d546001600160a01b0316610310565b61033b61043a3660046133d3565b610de0565b600c546102d390610100900460ff1681565b61033b610e0f565b6103cb6104673660046134cd565b60136020526000908152604090205481565b61033b610487366004613589565b610e1a565b6103cb60105481565b61033b6104a33660046134cd565b610e35565b6103cb6104b63660046133d3565b610ea4565b61033b6104c93660046133d3565b610f37565b600c546102d39060ff1681565b6104ee6104e93660046134cd565b610f71565b6040516102df91906135ca565b6103cb6105093660046134cd565b60126020526000908152604090205481565b6103106105293660046133d3565b611015565b61033b61053c3660046134cd565b61108c565b6103cb61054f3660046134cd565b6110b6565b61033b61113d565b600c546201000090046001600160a01b0316610310565b600a546001600160a01b0316610310565b600e546001600160a01b0316610310565b6104ee6105a33660046133d3565b611171565b6102f061149b565b61033b6105be366004613458565b6114aa565b61033b6105d136600461360e565b6115d0565b6105e96105e43660046133d3565b611695565b6040516102df9190613647565b600f546001600160a01b0316610310565b6103cb6106153660046134cd565b61171f565b61033b610628366004613714565b6117de565b61064061063b3660046133d3565b611816565b6040516102df91906137c3565b61033b61065b3660046134cd565b6118a3565b6103cb61066e3660046133d3565b6118ef565b6102f06106813660046133d3565b611982565b6106996106943660046133d3565b6120e1565b6040516102df9190613810565b6102d36106b436600461383b565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61033b6106f03660046134cd565b61216a565b61033b6107033660046134cd565b612205565b60006001600160e01b0319821663780e9d6360e01b148061072d575061072d8261222f565b92915050565b60606000805461074290613869565b80601f016020809104026020016040519081016040528092919081815260200182805461076e90613869565b80156107bb5780601f10610790576101008083540402835291602001916107bb565b820191906000526020600020905b81548152906001019060200180831161079e57829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166108435760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061086a82611015565b9050806001600160a01b0316836001600160a01b031614156108d85760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161083a565b336001600160a01b03821614806108f457506108f481336106b4565b6109665760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161083a565b610970838361227f565b505050565b600f546001600160a01b0316331461099f5760405162461bcd60e51b815260040161083a906138a4565b600c80549115156101000261ff0019909216919091179055565b60006109c3610e0f565b600c546201000090046001600160a01b031660005b83811015610c235760008585838181106109f4576109f46138e9565b905060200201359050610a1e816000908152600260205260409020546001600160a01b0316151590565b15610a775760405162461bcd60e51b8152602060048201526024808201527f4e66745661756c743a2054686520746f6b656e496420616c72656164792065786044820152636973747360e01b606482015260840161083a565b336040516331a9108f60e11b8152600481018390526001600160a01b0391821691851690636352211e9060240160206040518083038186803b158015610abc57600080fd5b505afa158015610ad0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af491906138ff565b6001600160a01b031614610b4a5760405162461bcd60e51b815260206004820152601e60248201527f4e66745661756c743a204f776e657220697320646966666572656e656e740000604482015260640161083a565b600c546201000090046001600160a01b031663b88d4fde3330846040518463ffffffff1660e01b8152600401610b829392919061391c565b600060405180830381600087803b158015610b9c57600080fd5b505af1158015610bb0573d6000803e3d6000fd5b50505050610bc4610bbe3390565b826122ed565b610c105760405162461bcd60e51b815260206004820152601860248201527f4e667456616c75743a205374616b696e67206661696c65640000000000000000604482015260640161083a565b5080610c1b81613965565b9150506109d8565b506001949350505050565b600a546001600160a01b03163314610c585760405162461bcd60e51b815260040161083a90613980565b600c5460ff1615610c7b5760405162461bcd60e51b815260040161083a906139b5565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b610ca7338261232e565b610cc35760405162461bcd60e51b815260040161083a906139f9565b610970838383612425565b6000610cd9836110b6565b8210610d3b5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161083a565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600a546001600160a01b03163314610d8e5760405162461bcd60e51b815260040161083a90613980565b600c5460ff1615610db15760405162461bcd60e51b815260040161083a906139b5565b600f80546001600160a01b0319166001600160a01b0392909216919091179055600c805460ff19166001179055565b600f546001600160a01b03163314610e0a5760405162461bcd60e51b815260040161083a906138a4565b601155565b610e18336125d0565b565b610970838383604051806020016040528060008152506117de565b600a546001600160a01b03163314610e5f5760405162461bcd60e51b815260040161083a90613980565b600c5460ff1615610e825760405162461bcd60e51b815260040161083a906139b5565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610eaf60085490565b8210610f125760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161083a565b60088281548110610f2557610f256138e9565b90600052602060002001549050919050565b600f546001600160a01b03163314610f615760405162461bcd60e51b815260040161083a906138a4565b610f6b8143613a4a565b60105550565b60606000610f7e836110b6565b67ffffffffffffffff811115610f9657610f9661367c565b604051908082528060200260200182016040528015610fbf578160200160208202803683370190505b50905060005b610fce846110b6565b81101561100e57610fdf8482610cce565b828281518110610ff157610ff16138e9565b60209081029190910101528061100681613965565b915050610fc5565b5092915050565b6000818152600260205260408120546001600160a01b03168061072d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b606482015260840161083a565b600f546001600160a01b03163314610c7b5760405162461bcd60e51b815260040161083a906138a4565b60006001600160a01b0382166111215760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161083a565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b031633146111675760405162461bcd60e51b815260040161083a90613980565b610e18600061273f565b606061117b610e0f565b600c546201000090046001600160a01b0316806370a08231336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b1580156111d357600080fd5b505afa1580156111e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061120b9190613a62565b83111561126d5760405162461bcd60e51b815260206004820152602a60248201527f4e66745661756c743a20436f756e74206973206d6f7265207468616e20746865604482015269206f776e65722068617360b01b606482015260840161083a565b60008367ffffffffffffffff8111156112885761128861367c565b6040519080825280602002602001820160405280156112b1578160200160208202803683370190505b50905060005b8481101561137c576001600160a01b038316632f745c59336040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024810184905260440160206040518083038186803b15801561131557600080fd5b505afa158015611329573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134d9190613a62565b82828151811061135f5761135f6138e9565b60209081029190910101528061137481613965565b9150506112b7565b5060005b815181101561149357600c546201000090046001600160a01b031663b88d4fde33308585815181106113b4576113b46138e9565b60200260200101516040518463ffffffff1660e01b81526004016113da9392919061391c565b600060405180830381600087803b1580156113f457600080fd5b505af1158015611408573d6000803e3d6000fd5b505050506114356114163390565b838381518110611428576114286138e9565b60200260200101516122ed565b6114815760405162461bcd60e51b815260206004820152601860248201527f4e66745661756c743a205374616b696e67206661696c65640000000000000000604482015260640161083a565b8061148b81613965565b915050611380565b509392505050565b60606001805461074290613869565b6114b2610e0f565b60005b818110156109705760008383838181106114d1576114d16138e9565b9050602002013590506114e13390565b6001600160a01b03166114f382611015565b6001600160a01b0316146115495760405162461bcd60e51b815260206004820152601f60248201527f4e66745661756c743a204c50206f776e657220697320646966666572656e7400604482015260640161083a565b61155281612791565b600c546201000090046001600160a01b031663b88d4fde3033846040518463ffffffff1660e01b815260040161158a9392919061391c565b600060405180830381600087803b1580156115a457600080fd5b505af11580156115b8573d6000803e3d6000fd5b505050505080806115c890613965565b9150506114b5565b6001600160a01b0382163314156116295760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161083a565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61169d61329b565b600c54604051635172589760e11b815260048101849052620100009091046001600160a01b03169063a2e4b12e906024016101006040518083038186803b1580156116e757600080fd5b505afa1580156116fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072d9190613a91565b6001600160a01b038116600090815260126020526040812054601054611746904390612838565b10156117855760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420626c6f636b7360901b604482015260640161083a565b6001600160a01b0382166000908152601260205260408120546010546117ac904390612838565b6117b69190613b17565b90506117d7816117d16117c8866110b6565b6011549061284e565b9061284e565b9392505050565b6117e8338361232e565b6118045760405162461bcd60e51b815260040161083a906139f9565b6118108484848461285a565b50505050565b61181e6132ba565b600c5460405163ba89696d60e01b815260048101849052620100009091046001600160a01b03169063ba89696d9060240160006040518083038186803b15801561186757600080fd5b505afa15801561187b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261072d9190810190613b2e565b600f546001600160a01b031633146118cd5760405162461bcd60e51b815260040161083a906138a4565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b60008181526014602052604081205460105461190c904390612838565b101561194b5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420626c6f636b7360901b604482015260640161083a565b600082815260146020526040812054601054611968904390612838565b6119729190613b17565b6011549091506117d7908261284e565b606061198c6132e1565b6119946132fc565b60608060006119a287611695565b905060006119af88611816565b905060006119bc896120e1565b805190915060ff1660071480156119dd5750806001602002015160ff16600e145b80156119f35750806002602002015160ff166004145b15611a1957604051806040016040528060018152602001605960f81b8152509450611a36565b604051806040016040528060018152602001602760f91b81525094505b6020810151815160ff9081169116148015611a5c57506040810151815160ff9081169116145b15611a8257604051806040016040528060018152602001605960f81b8152509350611a9f565b604051806040016040528060018152602001602760f91b81525093505b6040518060a0016040528060628152602001614714606291398752604080516060810190915260398082526143ae602083013987600160200201819052506040518060600160405280603281526020016146e260329139604080890191909152805160c08101909152608380825261459f6020830139606088015281516020838101516040808601519051611b35949301613c1f565b60408051808303601f190181529181526080890191909152805160a0810190915260798082526144b4602083013960a0880152611b7c8360005b602002015160ff1661288d565b611b87846001611b6f565b611b92856002611b6f565b611b9d866003611b6f565b604051602001611bb09493929190613c79565b60408051808303601f1901815291905260c0880152611bd0836004611b6f565b611bdb846005611b6f565b611be6856006611b6f565b611bf1866007611b6f565b604051602001611c049493929190613cdc565b60408051808303601f1901815291815260e08901919091528051808201909152600d81526c1e17ba32bc3a1f1e17b9bb339f60991b60208201528760086020020152600087816020020151886001602002015189600260200201518a600360200201518b600460200201518c600560200201518d600660200201518e600760200201518f60086020020151604051602001611ca799989796959493929190613d33565b60408051601f1981840301815260608301909152602c808352909250614448602083013987528251602080890191909152604080516060810190915260318082529091614417908301398760026020020152826001602002015187600360200201819052506040518060600160405280603081526020016143e760309139608088015260408084015160a08901528051606081019091526026808252614553602083013960c0880152611d5b846000611b6f565b60e08801526040805160608101909152602680825261464a6020830139610100880152611d89846001611b6f565b6101208801526040805160608101909152602680825261452d6020830139610140880152611db8846002611b6f565b610160880152604080516060810190915260268082526145796020830139610180880152611de7846003611b6f565b6101a08801526040805160608101909152602680825261469660208301396101c0880152611e16846004611b6f565b6101e0880152604080516060810190915260268082526143886020830139610200880152611e45846005611b6f565b610220880152604080516060810190915260268082526146bc6020830139610240880152611e74846006611b6f565b610260880152604080516060810190915260268082526146706020830139610280880152611ea3846007611b6f565b6102a08801526040805160608101909152602880825261462260208301396102c08801526102e087018690526040805160608101909152603080825261435860208301396103008801526103208701859052604080518082019091526003815262227d5d60e81b602082015287601a6020020152600087816020020151886001602002015189600260200201518a600360200201518b600460200201518c600560200201518d600660200201518e60076020020151604051602001611f6f989796959493929190613df4565b60408051601f19818403018152919052905080886008602002015189600960200201518a600a60200201518b600b60200201518c600c60200201518d600d60200201518e600e6020020151604051602001611fd1989796959493929190613df4565b60408051808303601f19018152908290526101e08a01516102008b01516102208c01516102408d01516102608e01516102808f015195975061201896889690602001613e99565b60408051808303601f19018152908290526102a08a01516102c08b01516102e08c01516103008d01516103208e01516103408f015195975061205f96889690602001613e99565b604051602081830303815290604052905060006120ae61207e8d61288d565b836120888661298b565b60405160200161209a93929190613f2b565b60405160208183030381529060405261298b565b9050806040516020016120c1919061414d565b60408051601f198184030181529190529c9b505050505050505050505050565b6120e9613317565b600c5460405163cb8af74560e01b815260048101849052620100009091046001600160a01b03169063cb8af7459060240160606040518083038186803b15801561213257600080fd5b505afa158015612146573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072d9190614192565b600a546001600160a01b031633146121945760405162461bcd60e51b815260040161083a90613980565b6001600160a01b0381166121f95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161083a565b6122028161273f565b50565b600f546001600160a01b03163314610e825760405162461bcd60e51b815260040161083a906138a4565b60006001600160e01b031982166380ac58cd60e01b148061226057506001600160e01b03198216635b5e139f60e01b145b8061072d57506301ffc9a760e01b6001600160e01b031983161461072d565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906122b482611015565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006002600b5414156123125760405162461bcd60e51b815260040161083a906141ee565b6002600b556123218383612af1565b50600180600b5592915050565b6000818152600260205260408120546001600160a01b03166123a75760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161083a565b60006123b283611015565b9050806001600160a01b0316846001600160a01b031614806123ed5750836001600160a01b03166123e2846107c5565b6001600160a01b0316145b8061241d57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661243882611015565b6001600160a01b0316146124a05760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161083a565b6001600160a01b0382166125025760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161083a565b61250d838383612b0f565b61251860008261227f565b6001600160a01b0383166000908152600360205260408120805460019290612541908490613b17565b90915550506001600160a01b038216600090815260036020526040812080546001929061256f908490613a4a565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6002600b5414156125f35760405162461bcd60e51b815260040161083a906141ee565b6002600b5560006126038261171f565b9050600061261343601054612838565b3360009081526012602052604090208190559050811561273557336000908152601360205260409020546126479083612c53565b60136000336001600160a01b0390811682526020820192909252604090810160002092909255600d549151633bf8968160e01b8152858216600482015260248101859052911690633bf8968190604401602060405180830381600087803b1580156126b157600080fd5b505af11580156126c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126e99190614225565b6127355760405162461bcd60e51b815260206004820152601e60248201527f4e66745661756c743a204c6565646f204d696e74696e67206661696c65640000604482015260640161083a565b50506001600b5550565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600061279c82611015565b90506127aa81600084612b0f565b6127b560008361227f565b6001600160a01b03811660009081526003602052604081208054600192906127de908490613b17565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600081831061284757816117d7565b5090919050565b60006117d78284614242565b612865848484612425565b61287184848484612c5f565b6118105760405162461bcd60e51b815260040161083a90614261565b6060816128b15750506040805180820190915260018152600360fc1b602082015290565b8160005b81156128db57806128c581613965565b91506128d49050600a836142c9565b91506128b5565b60008167ffffffffffffffff8111156128f6576128f661367c565b6040519080825280601f01601f191660200182016040528015612920576020820181803683370190505b5090505b841561241d57612935600183613b17565b9150612942600a866142dd565b61294d906030613a4a565b60f81b818381518110612962576129626138e9565b60200101906001600160f81b031916908160001a905350612984600a866142c9565b9450612924565b8051606090806129ab575050604080516020810190915260008152919050565b600060036129ba836002613a4a565b6129c491906142c9565b6129cf906004614242565b905060006129de826020613a4a565b67ffffffffffffffff8111156129f6576129f661367c565b6040519080825280601f01601f191660200182016040528015612a20576020820181803683370190505b5090506000604051806060016040528060408152602001614474604091399050600181016020830160005b86811015612aac576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b835260049092019101612a4b565b506003860660018114612ac65760028114612ad757612ae3565b613d3d60f01b600119830152612ae3565b603d60f81b6000198301525b505050918152949350505050565b612b0b828260405180602001604052806000815250612d61565b5050565b612b1a838383612d94565b6001600160a01b03831615801590612b3a57506001600160a01b03821615155b1561097057600e546001600160a01b03848116911614801590612b6b5750600e546001600160a01b03838116911614155b15612beb57600c54610100900460ff16612bd95760405162461bcd60e51b815260206004820152602960248201527f4e66745661756c743a20526567756c6172207472616e73666572206973206e6f6044820152681d08185b1b1bddd95960ba1b606482015260840161083a565b612be2836125d0565b610970826125d0565b600e546001600160a01b0383811691161415612c2a57612c0a836125d0565b612c1643601054612838565b600082815260146020526040902055505050565b600e546001600160a01b038481169116141561097057612c49826125d0565b6109708183612e4c565b60006117d78284613a4a565b60006001600160a01b0384163b15610c2357604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612ca39033908990889088906004016142f1565b602060405180830381600087803b158015612cbd57600080fd5b505af1925050508015612ced575060408051601f3d908101601f19168201909252612cea91810190614324565b60015b612d47573d808015612d1b576040519150601f19603f3d011682016040523d82523d6000602084013e612d20565b606091505b508051612d3f5760405162461bcd60e51b815260040161083a90614261565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061241d565b612d6b8383612fbd565b612d786000848484612c5f565b6109705760405162461bcd60e51b815260040161083a90614261565b6001600160a01b038316612def57612dea81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612e12565b816001600160a01b0316836001600160a01b031614612e1257612e12838261310b565b6001600160a01b038216612e2957610970816131a8565b826001600160a01b0316826001600160a01b031614610970576109708282613257565b6002600b541415612e6f5760405162461bcd60e51b815260040161083a906141ee565b6002600b556000612e7f836118ef565b90506000612e8f43601054612838565b600085815260146020526040902081905590508115612fb2576001600160a01b038316600090815260136020526040902054612ecb9083612c53565b6001600160a01b038481166000818152601360205260409081902093909355600d549251633bf8968160e01b8152600481019190915260248101859052911690633bf8968190604401602060405180830381600087803b158015612f2e57600080fd5b505af1158015612f42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f669190614225565b612fb25760405162461bcd60e51b815260206004820152601e60248201527f4e66745661756c743a204c6565646f204d696e74696e67206661696c65640000604482015260640161083a565b50506001600b555050565b6001600160a01b0382166130135760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161083a565b6000818152600260205260409020546001600160a01b0316156130785760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161083a565b61308460008383612b0f565b6001600160a01b03821660009081526003602052604081208054600192906130ad908490613a4a565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001613118846110b6565b6131229190613b17565b600083815260076020526040902054909150808214613175576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906131ba90600190613b17565b600083815260096020526040812054600880549394509092849081106131e2576131e26138e9565b906000526020600020015490508060088381548110613203576132036138e9565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061323b5761323b614341565b6001900381819060005260206000200160009055905550505050565b6000613262836110b6565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6040518061010001604052806008906020820280368337509192915050565b60405180606001604052806003905b60608152602001906001900390816132c95790505090565b604080516101208101909152606081526008602082016132c9565b60408051610360810190915260608152601a602082016132c9565b60405180606001604052806003906020820280368337509192915050565b6001600160e01b03198116811461220257600080fd5b60006020828403121561335d57600080fd5b81356117d781613335565b60005b8381101561338357818101518382015260200161336b565b838111156118105750506000910152565b600081518084526133ac816020860160208601613368565b601f01601f19169290920160200192915050565b6020815260006117d76020830184613394565b6000602082840312156133e557600080fd5b5035919050565b6001600160a01b038116811461220257600080fd5b6000806040838503121561341457600080fd5b823561341f816133ec565b946020939093013593505050565b801515811461220257600080fd5b60006020828403121561344d57600080fd5b81356117d78161342d565b6000806020838503121561346b57600080fd5b823567ffffffffffffffff8082111561348357600080fd5b818501915085601f83011261349757600080fd5b8135818111156134a657600080fd5b8660208260051b85010111156134bb57600080fd5b60209290920196919550909350505050565b6000602082840312156134df57600080fd5b81356117d7816133ec565b60008060008060006080868803121561350257600080fd5b853561350d816133ec565b9450602086013561351d816133ec565b935060408601359250606086013567ffffffffffffffff8082111561354157600080fd5b818801915088601f83011261355557600080fd5b81358181111561356457600080fd5b89602082850101111561357657600080fd5b9699959850939650602001949392505050565b60008060006060848603121561359e57600080fd5b83356135a9816133ec565b925060208401356135b9816133ec565b929592945050506040919091013590565b6020808252825182820181905260009190848201906040850190845b81811015613602578351835292840192918401916001016135e6565b50909695505050505050565b6000806040838503121561362157600080fd5b823561362c816133ec565b9150602083013561363c8161342d565b809150509250929050565b6101008101818360005b600881101561367357815160ff16835260209283019290910190600101613651565b50505092915050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156136b5576136b561367c565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156136e4576136e461367c565b604052919050565b600067ffffffffffffffff8211156137065761370661367c565b50601f01601f191660200190565b6000806000806080858703121561372a57600080fd5b8435613735816133ec565b93506020850135613745816133ec565b925060408501359150606085013567ffffffffffffffff81111561376857600080fd5b8501601f8101871361377957600080fd5b803561378c613787826136ec565b6136bb565b8181528860208385010111156137a157600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b60208082526000906080830183820185845b600381101561380457601f198785030183526137f2848351613394565b935091840191908401906001016137d5565b50919695505050505050565b60608101818360005b600381101561367357815160ff16835260209283019290910190600101613819565b6000806040838503121561384e57600080fd5b8235613859816133ec565b9150602083013561363c816133ec565b600181811c9082168061387d57607f821691505b6020821081141561389e57634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526025908201527f5641554c543a2063616c6c6572206973206e6f74207468652044414f20616464604082015264726573732160d81b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561391157600080fd5b81516117d7816133ec565b6001600160a01b039384168152919092166020820152604081019190915260806060820181905260009082015260a00190565b634e487b7160e01b600052601160045260246000fd5b60006000198214156139795761397961394f565b5060010190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526024908201527f4e66745661756c743a2044414f20697320616c726561647920696e697469616c6040820152631a5e995960e21b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60008219821115613a5d57613a5d61394f565b500190565b600060208284031215613a7457600080fd5b5051919050565b805160ff81168114613a8c57600080fd5b919050565b6000610100808385031215613aa557600080fd5b83601f840112613ab457600080fd5b60405181810181811067ffffffffffffffff82111715613ad657613ad661367c565b604052908301908085831115613aeb57600080fd5b845b83811015613b0c57613afe81613a7b565b825260209182019101613aed565b509095945050505050565b600082821015613b2957613b2961394f565b500390565b60006020808385031215613b4157600080fd5b825167ffffffffffffffff80821115613b5957600080fd5b8185019150601f8681840112613b6e57600080fd5b613b76613692565b806060850189811115613b8857600080fd5b855b81811015613bf457805186811115613ba25760008081fd5b87018581018c13613bb35760008081fd5b8051613bc1613787826136ec565b8181528d8b838501011115613bd65760008081fd5b613be5828c83018d8601613368565b86525050928701928701613b8a565b50909998505050505050505050565b60008151613c15818560208601613368565b9290920192915050565b60008451613c31818460208901613368565b8083019050600160fd1b8082528551613c51816001850160208a01613368565b60019201918201528351613c6c816002840160208801613368565b0160020195945050505050565b60008551613c8b818460208a01613368565b855190830190613c9f818360208a01613368565b8551910190613cb2818360208901613368565b8451910190613cc5818360208801613368565b600160fd1b91019081526001019695505050505050565b60008551613cee818460208a01613368565b855190830190613d02818360208a01613368565b8551910190613d15818360208901613368565b8451910190613d28818360208801613368565b019695505050505050565b60008a51613d45818460208f01613368565b8a51613d578183860160208f01613368565b8a519184010190613d6c818360208e01613368565b8951613d7e8183850160208e01613368565b8951929091010190613d94818360208c01613368565b8751613da68183850160208c01613368565b8751929091010190613dbc818360208a01613368565b8551613dce8183850160208a01613368565b8551929091010190613de4818360208801613368565b019b9a5050505050505050505050565b600089516020613e078285838f01613368565b8a5191840191613e1a8184848f01613368565b8a51920191613e2c8184848e01613368565b8951920191613e3e8184848d01613368565b8851920191613e508184848c01613368565b8751920191613e628184848b01613368565b8651920191613e748184848a01613368565b8551920191613e868184848901613368565b919091019b9a5050505050505050505050565b600088516020613eac8285838e01613368565b895191840191613ebf8184848e01613368565b8951920191613ed18184848d01613368565b8851920191613ee38184848c01613368565b8751920191613ef58184848b01613368565b8651920191613f078184848a01613368565b8551920191613f198184848901613368565b919091019a9950505050505050505050565b7f7b226e616d65223a20224c4545444f204c50202d2053717569642047616d652081526943617264204e4654202360b01b602082015260008451613f7681602a850160208901613368565b7001116101130ba3a3934b13aba32b9911d1607d1b602a918401918201528451613fa781603b840160208901613368565b7f2c20226465736372697074696f6e223a20225468652073717569642067616d65603b92909101918201527f2063617264732061726520696e7669746174696f6e20746f20656e7465722074605b8201527f686520616476656e7475726f757320616e64206d7973746572696f7573206d65607b8201527f746176657273652067616d65732e2047656e6573206368617261637465726973609b8201527f7469637320616e64206f746865722066756e6374696f6e616c6974792061726560bb8201527f20696e74656e74696f6e616c6c79206f6d697474656420666f7220756e6c696d60db8201527f6974656420696d6167696e6174696f6e20616e6420636f6d6d756e6974792d6460fb8201527f726976656e2067616d6520646576656c6f706d656e742e20537461727420796f61011b8201527f7572206a6f75726e6579206e6f7721222c2022696d616765223a20226461746161013b820152750e9a5b5859d94bdcdd99cade1b5b0ed8985cd94d8d0b60521b61015b820152614143614135610171830186613c03565b61227d60f01b815260020190565b9695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161418581601d850160208701613368565b91909101601d0192915050565b6000606082840312156141a457600080fd5b82601f8301126141b357600080fd5b6141bb613692565b8060608401858111156141cd57600080fd5b845b81811015613b0c576141e081613a7b565b8452602093840193016141cf565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60006020828403121561423757600080fd5b81516117d78161342d565b600081600019048311821515161561425c5761425c61394f565b500290565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b6000826142d8576142d86142b3565b500490565b6000826142ec576142ec6142b3565b500690565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061414390830184613394565b60006020828403121561433657600080fd5b81516117d781613335565b634e487b7160e01b600052603160045260246000fdfe227d2c207b2274726169745f74797065223a202253616d6520436f6e736f6e616e7473222c202276616c7565223a2022227d2c207b2274726169745f74797065223a202247656e6535222c202276616c7565223a20223c7374796c653e2e62617365207b666f6e742d66616d696c793a2056657264616e613b2066696c6c3a2077686974653b7d3c2f7374796c653e227d2c207b2274726169745f74797065223a2022526967687420436f6e736f6e616e74222c202276616c7565223a2022227d2c207b2274726169745f74797065223a202243656e74657220436f6e736f6e616e74222c202276616c7565223a20225b7b2274726169745f74797065223a20224c65667420436f6e736f6e616e74222c202276616c7565223a20224142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f3c2f746578743e3c7465787420783d223530252220793d223138302220646f6d696e616e742d626173656c696e653d226d6964646c652220746578742d616e63686f723d226d6964646c652220636c6173733d226261736522207374796c653d22666f6e742d73697a653a313530253b223e26233933373b20227d2c207b2274726169745f74797065223a202247656e6532222c202276616c7565223a2022227d2c207b2274726169745f74797065223a202247656e6530222c202276616c7565223a2022227d2c207b2274726169745f74797065223a202247656e6533222c202276616c7565223a20223c7465787420783d223530252220793d223130302220646f6d696e616e742d626173656c696e653d226d6964646c652220746578742d616e63686f723d226d6964646c652220636c6173733d226261736522207374796c653d22666f6e742d73697a653a373030253b206c65747465722d73706163696e673a202d302e32656d3b223e227d2c207b2274726169745f74797065223a20224f6a696e67656f222c202276616c7565223a2022227d2c207b2274726169745f74797065223a202247656e6531222c202276616c7565223a2022227d2c207b2274726169745f74797065223a202247656e6537222c202276616c7565223a2022227d2c207b2274726169745f74797065223a202247656e6534222c202276616c7565223a2022227d2c207b2274726169745f74797065223a202247656e6536222c202276616c7565223a20223c726563742077696474683d223130302522206865696768743d2231303025222066696c6c3d222334353842373422202f3e3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d22784d696e594d696e206d656574222076696577426f783d223020302033353020323230223ea2646970667358221220241ca2ca573656e3d4cb2f404e33324c5b925920b39ec073fa9f48a696d2a23864736f6c63430008090033

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

000000000000000000000000be5c953dd0ddb0ce033a98f36c981f1b74d3b33f0000000000000000000000003eede143adb9a80c6a44c63dad76269d33e2c8d1000000000000000000000000e6f45376f64e1f568bd1404c155e5ffd2f80f7ad

-----Decoded View---------------
Arg [0] : _nftAddress (address): 0xBE5C953DD0ddB0Ce033a98f36C981F1B74d3B33f
Arg [1] : _erc20Address (address): 0x3eEde143aDb9a80c6a44C63dad76269D33e2C8d1
Arg [2] : _bridgeAddress (address): 0xE6F45376f64e1F568BD1404C155e5fFD2F80F7AD

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000be5c953dd0ddb0ce033a98f36c981f1b74d3b33f
Arg [1] : 0000000000000000000000003eede143adb9a80c6a44c63dad76269d33e2c8d1
Arg [2] : 000000000000000000000000e6f45376f64e1f568bd1404c155e5ffd2f80f7ad


Deployed Bytecode Sourcemap

59060:14547:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37002:224;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;37002:224:0;;;;;;;;24894:100;;;:::i;:::-;;;;;;;:::i;26453:221::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1714:32:1;;;1696:51;;1684:2;1669:18;26453:221:0;1550:203:1;25976:411:0;;;;;;:::i;:::-;;:::i;:::-;;61240:97;;;;;;:::i;:::-;;:::i;63367:711::-;;;;;;:::i;:::-;;:::i;60555:182::-;;;;;;:::i;:::-;;:::i;72624:243::-;;;;;;:::i;:::-;72798:60;72624:243;;;;;;;;;;;-1:-1:-1;;;;;;4558:33:1;;;4540:52;;4528:2;4513:18;72624:243:0;4396:202:1;37642:113:0;37730:10;:17;37642:113;;;4749:25:1;;;4737:2;4722:18;37642:113:0;4603:177:1;27343:339:0;;;;;;:::i;:::-;;:::i;59531:35::-;;;;;;37310:256;;;;;;:::i;:::-;;:::i;60763:209::-;;;;;;:::i;:::-;;:::i;66971:89::-;67042:10;;-1:-1:-1;;;;;67042:10:0;66971:89;;61460:80;;;;;;:::i;:::-;;:::i;59214:35::-;;;;;;;;;;;;62321:77;;;:::i;59701:43::-;;;;;;:::i;:::-;;;;;;;;;;;;;;27753:185;;;;;;:::i;:::-;;:::i;59476:48::-;;;;;;60357:186;;;;;;:::i;:::-;;:::i;37832:233::-;;;;;;:::i;:::-;;:::i;61548:119::-;;;;;;:::i;:::-;;:::i;59173:34::-;;;;;;;;;65617:301;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;59621:42::-;;;;;;:::i;:::-;;;;;;;;;;;;;;24588:239;;;;;;:::i;:::-;;:::i;61112:112::-;;;;;;:::i;:::-;;:::i;24318:208::-;;;;;;:::i;:::-;;:::i;4593:94::-;;;:::i;66874:85::-;66943:8;;;;;-1:-1:-1;;;;;66943:8:0;66874:85;;3942:87;4015:6;;-1:-1:-1;;;;;4015:6:0;3942:87;;67072:91;67144:11;;-1:-1:-1;;;;;67144:11:0;67072:91;;64090:819;;;;;;:::i;:::-;;:::i;25063:104::-;;;:::i;65090:519::-;;;;;;:::i;:::-;;:::i;26746:295::-;;;;;;:::i;:::-;;:::i;67500:138::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;66777:85::-;66846:8;;-1:-1:-1;;;;;66846:8:0;66777:85;;61679:316;;;;;;:::i;:::-;;:::i;28009:328::-;;;;;;:::i;:::-;;:::i;67343:149::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;61349:99::-;;;;;;:::i;:::-;;:::i;62007:298::-;;;;;;:::i;:::-;;:::i;67650:4792::-;;;;;;:::i;:::-;;:::i;67175:158::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;27112:164::-;;;;;;:::i;:::-;-1:-1:-1;;;;;27233:25:0;;;27209:4;27233:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;27112:164;4842:192;;;;;;:::i;:::-;;:::i;60984:116::-;;;;;;:::i;:::-;;:::i;37002:224::-;37104:4;-1:-1:-1;;;;;;37128:50:0;;-1:-1:-1;;;37128:50:0;;:90;;;37182:36;37206:11;37182:23;:36::i;:::-;37121:97;37002:224;-1:-1:-1;;37002:224:0:o;24894:100::-;24948:13;24981:5;24974:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24894:100;:::o;26453:221::-;26529:7;29936:16;;;:7;:16;;;;;;-1:-1:-1;;;;;29936:16:0;26549:73;;;;-1:-1:-1;;;26549:73:0;;10848:2:1;26549:73:0;;;10830:21:1;10887:2;10867:18;;;10860:30;10926:34;10906:18;;;10899:62;-1:-1:-1;;;10977:18:1;;;10970:42;11029:19;;26549:73:0;;;;;;;;;-1:-1:-1;26642:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;26642:24:0;;26453:221::o;25976:411::-;26057:13;26073:23;26088:7;26073:14;:23::i;:::-;26057:39;;26121:5;-1:-1:-1;;;;;26115:11:0;:2;-1:-1:-1;;;;;26115:11:0;;;26107:57;;;;-1:-1:-1;;;26107:57:0;;11261:2:1;26107:57:0;;;11243:21:1;11300:2;11280:18;;;11273:30;11339:34;11319:18;;;11312:62;-1:-1:-1;;;11390:18:1;;;11383:31;11431:19;;26107:57:0;11059:397:1;26107:57:0;2810:10;-1:-1:-1;;;;;26199:21:0;;;;:62;;-1:-1:-1;26224:37:0;26241:5;2810:10;27112:164;:::i;26224:37::-;26177:168;;;;-1:-1:-1;;;26177:168:0;;11663:2:1;26177:168:0;;;11645:21:1;11702:2;11682:18;;;11675:30;11741:34;11721:18;;;11714:62;11812:26;11792:18;;;11785:54;11856:19;;26177:168:0;11461:420:1;26177:168:0;26358:21;26367:2;26371:7;26358:8;:21::i;:::-;26046:341;25976:411;;:::o;61240:97::-;59907:8;;-1:-1:-1;;;;;59907:8:0;2810:10;59907:24;59899:74;;;;-1:-1:-1;;;59899:74:0;;;;;;;:::i;:::-;61306:15:::1;:23:::0;;;::::1;;;;-1:-1:-1::0;;61306:23:0;;::::1;::::0;;;::::1;::::0;;61240:97::o;63367:711::-;63429:4;63446:14;:12;:14::i;:::-;63497:8;;;;;-1:-1:-1;;;;;63497:8:0;63471:13;63519:530;63535:19;;;63519:530;;;63576:12;63591:8;;63600:1;63591:11;;;;;;;:::i;:::-;;;;;;;63576:26;;63626:16;63634:7;29912:4;29936:16;;;:7;:16;;;;;;-1:-1:-1;;;;;29936:16:0;:30;;;29847:127;63626:16;63625:17;63617:66;;;;-1:-1:-1;;;63617:66:0;;12626:2:1;63617:66:0;;;12608:21:1;12665:2;12645:18;;;12638:30;12704:34;12684:18;;;12677:62;-1:-1:-1;;;12755:18:1;;;12748:34;12799:19;;63617:66:0;12424:400:1;63617:66:0;2810:10;63706:20;;-1:-1:-1;;;63706:20:0;;;;;4749:25:1;;;-1:-1:-1;;;;;63706:36:0;;;;:11;;;;;4722:18:1;;63706:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;63706:36:0;;63698:80;;;;-1:-1:-1;;;63698:80:0;;13287:2:1;63698:80:0;;;13269:21:1;13326:2;13306:18;;;13299:30;13365:32;13345:18;;;13338:60;13415:18;;63698:80:0;13085:354:1;63698:80:0;63803:8;;;;;-1:-1:-1;;;;;63803:8:0;63793:36;2810:10;63887:4;63911:7;63793:161;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63977:31;63986:12;2810:10;;2730:98;63986:12;64000:7;63977:8;:31::i;:::-;63969:68;;;;-1:-1:-1;;;63969:68:0;;14206:2:1;63969:68:0;;;14188:21:1;14245:2;14225:18;;;14218:30;14284:26;14264:18;;;14257:54;14328:18;;63969:68:0;14004:348:1;63969:68:0;-1:-1:-1;63556:3:0;;;;:::i;:::-;;;;63519:530;;;-1:-1:-1;64066:4:0;;63367:711;-1:-1:-1;;;;63367:711:0:o;60555:182::-;4015:6;;-1:-1:-1;;;;;4015:6:0;2810:10;4162:23;4154:68;;;;-1:-1:-1;;;4154:68:0;;;;;;;:::i;:::-;60637:14:::1;::::0;::::1;;60636:15;60628:64;;;;-1:-1:-1::0;;;60628:64:0::1;;;;;;;:::i;:::-;60703:10;:26:::0;;-1:-1:-1;;;;;;60703:26:0::1;-1:-1:-1::0;;;;;60703:26:0;;;::::1;::::0;;;::::1;::::0;;60555:182::o;27343:339::-;27538:41;2810:10;27571:7;27538:18;:41::i;:::-;27530:103;;;;-1:-1:-1;;;27530:103:0;;;;;;;:::i;:::-;27646:28;27656:4;27662:2;27666:7;27646:9;:28::i;37310:256::-;37407:7;37443:23;37460:5;37443:16;:23::i;:::-;37435:5;:31;37427:87;;;;-1:-1:-1;;;37427:87:0;;16015:2:1;37427:87:0;;;15997:21:1;16054:2;16034:18;;;16027:30;16093:34;16073:18;;;16066:62;-1:-1:-1;;;16144:18:1;;;16137:41;16195:19;;37427:87:0;15813:407:1;37427:87:0;-1:-1:-1;;;;;;37532:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;37310:256::o;60763:209::-;4015:6;;-1:-1:-1;;;;;4015:6:0;2810:10;4162:23;4154:68;;;;-1:-1:-1;;;4154:68:0;;;;;;;:::i;:::-;60844:14:::1;::::0;::::1;;60843:15;60835:64;;;;-1:-1:-1::0;;;60835:64:0::1;;;;;;;:::i;:::-;60910:8;:22:::0;;-1:-1:-1;;;;;;60910:22:0::1;-1:-1:-1::0;;;;;60910:22:0;;;::::1;::::0;;;::::1;::::0;;60943:14:::1;:21:::0;;-1:-1:-1;;60943:21:0::1;-1:-1:-1::0;60943:21:0::1;::::0;;60763:209::o;61460:80::-;59907:8;;-1:-1:-1;;;;;59907:8:0;2810:10;59907:24;59899:74;;;;-1:-1:-1;;;59899:74:0;;;;;;;:::i;:::-;61520:4:::1;:12:::0;61460:80::o;62321:77::-;62363:27;2810:10;62363:13;:27::i;:::-;62321:77::o;27753:185::-;27891:39;27908:4;27914:2;27918:7;27891:39;;;;;;;;;;;;:16;:39::i;60357:186::-;4015:6;;-1:-1:-1;;;;;4015:6:0;2810:10;4162:23;4154:68;;;;-1:-1:-1;;;4154:68:0;;;;;;;:::i;:::-;60441:14:::1;::::0;::::1;;60440:15;60432:64;;;;-1:-1:-1::0;;;60432:64:0::1;;;;;;;:::i;:::-;60507:11;:28:::0;;-1:-1:-1;;;;;;60507:28:0::1;-1:-1:-1::0;;;;;60507:28:0;;;::::1;::::0;;;::::1;::::0;;60357:186::o;37832:233::-;37907:7;37943:30;37730:10;:17;;37642:113;37943:30;37935:5;:38;37927:95;;;;-1:-1:-1;;;37927:95:0;;16427:2:1;37927:95:0;;;16409:21:1;16466:2;16446:18;;;16439:30;16505:34;16485:18;;;16478:62;-1:-1:-1;;;16556:18:1;;;16549:42;16608:19;;37927:95:0;16225:408:1;37927:95:0;38040:10;38051:5;38040:17;;;;;;;;:::i;:::-;;;;;;;;;38033:24;;37832:233;;;:::o;61548:119::-;59907:8;;-1:-1:-1;;;;;59907:8:0;2810:10;59907:24;59899:74;;;;-1:-1:-1;;;59899:74:0;;;;;;;:::i;:::-;61633:26:::1;61648:11:::0;61633:12:::1;:26;:::i;:::-;61620:10;:39:::0;-1:-1:-1;61548:119:0:o;65617:301::-;65674:13;65700:22;65740:19;65750:8;65740:9;:19::i;:::-;65725:35;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65725:35:0;;65700:60;;65776:6;65771:114;65786:19;65796:8;65786:9;:19::i;:::-;65784:1;:21;65771:114;;;65841:32;65861:8;65871:1;65841:19;:32::i;:::-;65827:8;65836:1;65827:11;;;;;;;;:::i;:::-;;;;;;;;;;:46;65807:3;;;;:::i;:::-;;;;65771:114;;;-1:-1:-1;65902:8:0;65617:301;-1:-1:-1;;65617:301:0:o;24588:239::-;24660:7;24696:16;;;:7;:16;;;;;;-1:-1:-1;;;;;24696:16:0;24731:19;24723:73;;;;-1:-1:-1;;;24723:73:0;;16973:2:1;24723:73:0;;;16955:21:1;17012:2;16992:18;;;16985:30;17051:34;17031:18;;;17024:62;-1:-1:-1;;;17102:18:1;;;17095:39;17151:19;;24723:73:0;16771:405:1;61112:112:0;59907:8;;-1:-1:-1;;;;;59907:8:0;2810:10;59907:24;59899:74;;;;-1:-1:-1;;;59899:74:0;;;;;;;:::i;24318:208::-;24390:7;-1:-1:-1;;;;;24418:19:0;;24410:74;;;;-1:-1:-1;;;24410:74:0;;17383:2:1;24410:74:0;;;17365:21:1;17422:2;17402:18;;;17395:30;17461:34;17441:18;;;17434:62;-1:-1:-1;;;17512:18:1;;;17505:40;17562:19;;24410:74:0;17181:406:1;24410:74:0;-1:-1:-1;;;;;;24502:16:0;;;;;:9;:16;;;;;;;24318:208::o;4593:94::-;4015:6;;-1:-1:-1;;;;;4015:6:0;2810:10;4162:23;4154:68;;;;-1:-1:-1;;;4154:68:0;;;;;;;:::i;:::-;4658:21:::1;4676:1;4658:9;:21::i;64090:819::-:0;64146:16;64174:14;:12;:14::i;:::-;64225:8;;;;;-1:-1:-1;;;;;64225:8:0;;64273:13;2810:10;64273:27;;-1:-1:-1;;;;;;64273:27:0;;;;;;;-1:-1:-1;;;;;1714:32:1;;;64273:27:0;;;1696:51:1;1669:18;;64273:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64263:6;:37;;64255:92;;;;-1:-1:-1;;;64255:92:0;;17983:2:1;64255:92:0;;;17965:21:1;18022:2;18002:18;;;17995:30;18061:34;18041:18;;;18034:62;-1:-1:-1;;;18112:18:1;;;18105:40;18162:19;;64255:92:0;17781:406:1;64255:92:0;64358:25;64401:6;64386:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64386:22:0;;64358:50;;64426:9;64421:114;64441:6;64437:1;:10;64421:114;;;-1:-1:-1;;;;;64483:23:0;;;2810:10;64483:40;;-1:-1:-1;;;;;;64483:40:0;;;;;;;-1:-1:-1;;;;;18384:32:1;;;64483:40:0;;;18366:51:1;18433:18;;;18426:34;;;18339:18;;64483:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64469:8;64478:1;64469:11;;;;;;;;:::i;:::-;;;;;;;;;;:54;64449:3;;;;:::i;:::-;;;;64421:114;;;;64560:9;64555:321;64575:8;:15;64571:1;:19;64555:321;;;64622:8;;;;;-1:-1:-1;;;;;64622:8:0;64612:36;2810:10;64706:4;64730:8;64739:1;64730:11;;;;;;;;:::i;:::-;;;;;;;64612:165;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64800:35;64809:12;2810:10;;2730:98;64809:12;64823:8;64832:1;64823:11;;;;;;;;:::i;:::-;;;;;;;64800:8;:35::i;:::-;64792:72;;;;-1:-1:-1;;;64792:72:0;;18673:2:1;64792:72:0;;;18655:21:1;18712:2;18692:18;;;18685:30;18751:26;18731:18;;;18724:54;18795:18;;64792:72:0;18471:348:1;64792:72:0;64592:3;;;;:::i;:::-;;;;64555:321;;;-1:-1:-1;64893:8:0;64090:819;-1:-1:-1;;;64090:819:0:o;25063:104::-;25119:13;25152:7;25145:14;;;;;:::i;65090:519::-;65158:14;:12;:14::i;:::-;65190:9;65185:417;65201:20;;;65185:417;;;65243:12;65258:9;;65268:1;65258:12;;;;;;;:::i;:::-;;;;;;;65243:27;;65313:12;2810:10;;2730:98;65313:12;-1:-1:-1;;;;;65293:32:0;:16;65301:7;65293;:16::i;:::-;-1:-1:-1;;;;;65293:32:0;;65285:76;;;;-1:-1:-1;;;65285:76:0;;19026:2:1;65285:76:0;;;19008:21:1;19065:2;19045:18;;;19038:30;19104:33;19084:18;;;19077:61;19155:18;;65285:76:0;18824:355:1;65285:76:0;65388:14;65394:7;65388:5;:14::i;:::-;65427:8;;;;;-1:-1:-1;;;;;65427:8:0;65417:36;65480:4;2810:10;65535:7;65417:161;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65228:374;65223:3;;;;;:::i;:::-;;;;65185:417;;26746:295;-1:-1:-1;;;;;26849:24:0;;2810:10;26849:24;;26841:62;;;;-1:-1:-1;;;26841:62:0;;19386:2:1;26841:62:0;;;19368:21:1;19425:2;19405:18;;;19398:30;19464:27;19444:18;;;19437:55;19509:18;;26841:62:0;19184:349:1;26841:62:0;2810:10;26916:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;26916:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;26916:53:0;;;;;;;;;;26985:48;;540:41:1;;;26916:42:0;;2810:10;26985:48;;513:18:1;26985:48:0;;;;;;;26746:295;;:::o;67500:138::-;67557:15;;:::i;:::-;67602:8;;67592:38;;-1:-1:-1;;;67592:38:0;;;;;4749:25:1;;;67602:8:0;;;;-1:-1:-1;;;;;67602:8:0;;67592:28;;4722:18:1;;67592:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;61679:316::-;-1:-1:-1;;;;;61801:19:0;;61738:4;61801:19;;;:10;:19;;;;;;61786:10;;61763:34;;61772:12;;61763:8;:34::i;:::-;:57;;61755:84;;;;-1:-1:-1;;;61755:84:0;;20714:2:1;61755:84:0;;;20696:21:1;20753:2;20733:18;;;20726:30;-1:-1:-1;;;20772:18:1;;;20765:44;20826:18;;61755:84:0;20512:338:1;61755:84:0;-1:-1:-1;;;;;61905:19:0;;61850:15;61905:19;;;:10;:19;;;;;;61891:10;;61868:34;;61877:12;;61868:8;:34::i;:::-;:56;;;;:::i;:::-;61850:74;;61942:44;61975:10;61942:28;61951:18;61961:7;61951:9;:18::i;:::-;61942:4;;;:8;:28::i;:::-;:32;;:44::i;:::-;61935:51;61679:316;-1:-1:-1;;;61679:316:0:o;28009:328::-;28184:41;2810:10;28217:7;28184:18;:41::i;:::-;28176:103;;;;-1:-1:-1;;;28176:103:0;;;;;;;:::i;:::-;28290:39;28304:4;28310:2;28314:7;28323:5;28290:13;:39::i;:::-;28009:328;;;;:::o;67343:149::-;67405:16;;:::i;:::-;67451:8;;67441:43;;-1:-1:-1;;;67441:43:0;;;;;4749:25:1;;;67451:8:0;;;;-1:-1:-1;;;;;67451:8:0;;67441:33;;4722:18:1;;67441:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;67441:43:0;;;;;;;;;;;;:::i;61349:99::-;59907:8;;-1:-1:-1;;;;;59907:8:0;2810:10;59907:24;59899:74;;;;-1:-1:-1;;;59899:74:0;;;;;;;:::i;:::-;61418:8:::1;:22:::0;;-1:-1:-1;;;;;;61418:22:0::1;-1:-1:-1::0;;;;;61418:22:0;;;::::1;::::0;;;::::1;::::0;;61349:99::o;62007:298::-;62069:4;62132:21;;;:12;:21;;;;;;62117:10;;62094:34;;62103:12;;62094:8;:34::i;:::-;:59;;62086:86;;;;-1:-1:-1;;;62086:86:0;;20714:2:1;62086:86:0;;;20696:21:1;20753:2;20733:18;;;20726:30;-1:-1:-1;;;20772:18:1;;;20765:44;20826:18;;62086:86:0;20512:338:1;62086:86:0;62183:15;62238:21;;;:12;:21;;;;;;62224:10;;62201:34;;62210:12;;62201:8;:34::i;:::-;:58;;;;:::i;:::-;62277:4;;62183:76;;-1:-1:-1;62277:20:0;;62183:76;62277:8;:20::i;67650:4792::-;67716:13;67752:22;;:::i;:::-;67785:27;;:::i;:::-;67823:21;67855:28;67894:25;67922:18;67931:8;67922;:18::i;:::-;67894:46;;67951:26;67980:23;67994:8;67980:13;:23::i;:::-;67951:52;;68014:25;68042:28;68061:8;68042:18;:28::i;:::-;68093:12;;;;-1:-1:-1;68093:17:0;;68109:1;68093:17;:39;;;;-1:-1:-1;68114:9:0;68124:1;68114:12;;;;:18;;68130:2;68114:18;68093:39;:60;;;;-1:-1:-1;68136:9:0;68146:1;68136:12;;;;:17;;68152:1;68136:17;68093:60;68089:152;;;68170:13;;;;;;;;;;;;;-1:-1:-1;;;68170:13:0;;;;;68089:152;;;68216:13;;;;;;;;;;;;;-1:-1:-1;;;68216:13:0;;;;;68089:152;68271:12;;;;68255;;:28;;;;;;;:60;;;;-1:-1:-1;68303:12:0;;;;68287;;:28;;;;;;;68255:60;68251:166;;;68332:20;;;;;;;;;;;;;-1:-1:-1;;;68332:20:0;;;;;68251:166;;;68385:20;;;;;;;;;;;;;-1:-1:-1;;;68385:20:0;;;;;68251:166;68429:111;;;;;;;;;;;;;;;;;;;68551:70;;;;;;;;;;;;;;68429:8;68551:70;;;:5;68557:1;68551:8;;;:70;;;;68632:63;;;;;;;;;;;;;;;;;:8;;;;:63;;;;68706:144;;;;;;;;;;;;;68632:8;68706:144;;;:8;;;:144;68896:12;;68706:8;68915:12;;;;68934;;;;;68879:68;;;;68896:12;68879:68;;:::i;:::-;;;;;;;-1:-1:-1;;68879:68:0;;;;;;68861:8;;;:87;;;;68959:134;;;;;;;;;;;;;68861:8;68959:134;;;:8;;;:134;69139:22;69148:9;69158:1;69148:12;;;;;69139:22;;:8;:22::i;:::-;69163;69172:9;69182:1;69172:12;;69163:22;69187;69196:9;69206:1;69196:12;;69187:22;69211;69220:9;69230:1;69220:12;;69211:22;69122:117;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;69122:117:0;;;;;;69104:8;;;:136;69286:22;69295:9;69305:1;69295:12;;69286:22;69310;69319:9;69329:1;69319:12;;69310:22;69334;69343:9;69353:1;69343:12;;69334:22;69358;69367:9;69377:1;69367:12;;69358:22;69269:113;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;69269:113:0;;;;;;69251:8;;;:132;;;;69394:25;;;;;;;;;;;-1:-1:-1;;;69251:8:0;69394:25;;;69251:5;69400:1;69394:8;;;:25;69440:20;69487:5;69440:20;69487:8;;;;69497:5;69503:1;69497:8;;;;69507:5;69513:1;69507:8;;;;69517:5;69523:1;69517:8;;;;69527:5;69533:1;69527:8;;;;69537:5;69543:1;69537:8;;;;69547:5;69553:1;69547:8;;;;69557:5;69563:1;69557:8;;;;69567:5;69573:1;69567:8;;;;69470:106;;;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;69470:106:0;;;;;;69590:61;;;;;;;;;;69470:106;;-1:-1:-1;69590:61:0;69470:106;69590:61;;;;;69677:12;;69590;69662;;;:27;;;;69700:66;;;;;;;;;;;;;;;;;;;;:9;69710:1;69700:12;;;:66;69792:9;69802:1;69792:12;;;;69777:9;69787:1;69777:12;;;:27;;;;69815:65;;;;;;;;;;;;;;;;;:12;;;:65;69914:12;;;;;69899;;;:27;69937:55;;;;;;;;;;;;;69815:12;69937:55;;;:12;;;:55;70018:22;70027:9;70037:1;70027:12;;70018:22;70003:12;;;:37;70051:55;;;;;;;;;;;;;;70003:12;70051:55;;;:12;;;:55;70132:22;70141:9;70151:1;70141:12;;70132:22;70117:12;;;:37;70165:56;;;;;;;;;;;;;;70117:12;70165:56;;;:13;;;:56;70256:22;70265:9;70275:1;70265:12;;70256:22;70240:13;;;:38;70289:56;;;;;;;;;;;;;;70240:13;70289:56;;;:13;;;:56;70380:22;70389:9;70399:1;70389:12;;70380:22;70364:13;;;:38;70413:56;;;;;;;;;;;;;;70364:13;70413:56;;;:13;;;:56;70504:22;70513:9;70523:1;70513:12;;70504:22;70488:13;;;:38;70537:56;;;;;;;;;;;;;;70488:13;70537:56;;;:13;;;:56;70628:22;70637:9;70647:1;70637:12;;70628:22;70612:13;;;:38;70661:56;;;;;;;;;;;;;;70612:13;70661:56;;;:13;;;:56;70752:22;70761:9;70771:1;70761:12;;70752:22;70736:13;;;:38;70785:56;;;;;;;;;;;;;;70736:13;70785:56;;;:13;;;:56;70876:22;70885:9;70895:1;70885:12;;70876:22;70860:13;;;:38;70909:58;;;;;;;;;;;;;;70860:13;70909:58;;;:13;;;:58;70986:13;;;:23;;;71020:66;;;;;;;;;;;;;;70909:13;71020:66;;;:13;;;:66;71105:13;;;:30;;;71146:21;;;;;;;;;;;;-1:-1:-1;;;71020:13:0;71146:21;;;71020:9;71156:2;71146:13;;;:21;71188:19;71234:9;71188:19;71234:12;;;;71248:9;71258:1;71248:12;;;;71262:9;71272:1;71262:12;;;;71276:9;71286:1;71276:12;;;;71290:9;71300:1;71290:12;;;;71304:9;71314:1;71304:12;;;;71318:9;71328:1;71318:12;;;;71332:9;71342:1;71332:12;;;;71217:128;;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;71217:128:0;;;;;;;;;;-1:-1:-1;71217:128:0;71396:9;71406:1;71396:12;;;;71410:9;71420:1;71410:12;;;;71424:9;71434:2;71424:13;;;;71439:9;71449:2;71439:13;;;;71454:9;71464:2;71454:13;;;;71469:9;71479:2;71469:13;;;;71484:9;71494:2;71484:13;;;;71372:126;;;;;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;71372:126:0;;;;;;;71557:13;;;;71572;;;;71587;;;;71602;;;;71617;;;;71632;;;;71372:126;;-1:-1:-1;71533:113:0;;71372:126;;71632:13;71557;71533:113;;:::i;:::-;;;;;;;-1:-1:-1;;71533:113:0;;;;;;;71705:13;;;;71720;;;;71735;;;;71750;;;;71765;;;;71780;;;;71533:113;;-1:-1:-1;71681:113:0;;71533;;71780:13;71705;71681:113;;:::i;:::-;;;;;;;;;;;;;71666:129;;71816:18;71837:490;71927:18;71936:8;71927;:18::i;:::-;71968:5;72289:28;72309:6;72289:13;:28::i;:::-;71864:460;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;71837:13;:490::i;:::-;71816:511;;72404:4;72354:55;;;;;;;;:::i;:::-;;;;-1:-1:-1;;72354:55:0;;;;;;;;;;67650:4792;-1:-1:-1;;;;;;;;;;;;67650:4792:0:o;67175:158::-;67242:15;;:::i;:::-;67287:8;;67277:48;;-1:-1:-1;;;67277:48:0;;;;;4749:25:1;;;67287:8:0;;;;-1:-1:-1;;;;;67287:8:0;;67277:38;;4722:18:1;;67277:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;4842:192::-;4015:6;;-1:-1:-1;;;;;4015:6:0;2810:10;4162:23;4154:68;;;;-1:-1:-1;;;4154:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;4931:22:0;::::1;4923:73;;;::::0;-1:-1:-1;;;4923:73:0;;33710:2:1;4923:73:0::1;::::0;::::1;33692:21:1::0;33749:2;33729:18;;;33722:30;33788:34;33768:18;;;33761:62;-1:-1:-1;;;33839:18:1;;;33832:36;33885:19;;4923:73:0::1;33508:402:1::0;4923:73:0::1;5007:19;5017:8;5007:9;:19::i;:::-;4842:192:::0;:::o;60984:116::-;59907:8;;-1:-1:-1;;;;;59907:8:0;2810:10;59907:24;59899:74;;;;-1:-1:-1;;;59899:74:0;;;;;;;:::i;23949:305::-;24051:4;-1:-1:-1;;;;;;24088:40:0;;-1:-1:-1;;;24088:40:0;;:105;;-1:-1:-1;;;;;;;24145:48:0;;-1:-1:-1;;;24145:48:0;24088:105;:158;;;-1:-1:-1;;;;;;;;;;16037:40:0;;;24210:36;15928:157;33829:174;33904:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;33904:29:0;-1:-1:-1;;;;;33904:29:0;;;;;;;;:24;;33958:23;33904:24;33958:14;:23::i;:::-;-1:-1:-1;;;;;33949:46:0;;;;;;;;;;;33829:174;;:::o;64928:147::-;65004:4;55917:1;56513:7;;:19;;56505:63;;;;-1:-1:-1;;;56505:63:0;;;;;;;:::i;:::-;55917:1;56646:7;:18;65021:24:::1;65031:3:::0;65036:8;65021:9:::1;:24::i;:::-;-1:-1:-1::0;65063:4:0::1;55873:1:::0;56825:7;:22;64928:147;;-1:-1:-1;;64928:147:0:o;30141:348::-;30234:4;29936:16;;;:7;:16;;;;;;-1:-1:-1;;;;;29936:16:0;30251:73;;;;-1:-1:-1;;;30251:73:0;;34477:2:1;30251:73:0;;;34459:21:1;34516:2;34496:18;;;34489:30;34555:34;34535:18;;;34528:62;-1:-1:-1;;;34606:18:1;;;34599:42;34658:19;;30251:73:0;34275:408:1;30251:73:0;30335:13;30351:23;30366:7;30351:14;:23::i;:::-;30335:39;;30404:5;-1:-1:-1;;;;;30393:16:0;:7;-1:-1:-1;;;;;30393:16:0;;:51;;;;30437:7;-1:-1:-1;;;;;30413:31:0;:20;30425:7;30413:11;:20::i;:::-;-1:-1:-1;;;;;30413:31:0;;30393:51;:87;;;-1:-1:-1;;;;;;27233:25:0;;;27209:4;27233:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;30448:32;30385:96;30141:348;-1:-1:-1;;;;30141:348:0:o;33133:578::-;33292:4;-1:-1:-1;;;;;33265:31:0;:23;33280:7;33265:14;:23::i;:::-;-1:-1:-1;;;;;33265:31:0;;33257:85;;;;-1:-1:-1;;;33257:85:0;;34890:2:1;33257:85:0;;;34872:21:1;34929:2;34909:18;;;34902:30;34968:34;34948:18;;;34941:62;-1:-1:-1;;;35019:18:1;;;35012:39;35068:19;;33257:85:0;34688:405:1;33257:85:0;-1:-1:-1;;;;;33361:16:0;;33353:65;;;;-1:-1:-1;;;33353:65:0;;35300:2:1;33353:65:0;;;35282:21:1;35339:2;35319:18;;;35312:30;35378:34;35358:18;;;35351:62;-1:-1:-1;;;35429:18:1;;;35422:34;35473:19;;33353:65:0;35098:400:1;33353:65:0;33431:39;33452:4;33458:2;33462:7;33431:20;:39::i;:::-;33535:29;33552:1;33556:7;33535:8;:29::i;:::-;-1:-1:-1;;;;;33577:15:0;;;;;;:9;:15;;;;;:20;;33596:1;;33577:15;:20;;33596:1;;33577:20;:::i;:::-;;;;-1:-1:-1;;;;;;;33608:13:0;;;;;;:9;:13;;;;;:18;;33625:1;;33608:13;:18;;33625:1;;33608:18;:::i;:::-;;;;-1:-1:-1;;33637:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;33637:21:0;-1:-1:-1;;;;;33637:21:0;;;;;;;;;33676:27;;33637:16;;33676:27;;;;;;;33133:578;;;:::o;62411:465::-;55917:1;56513:7;;:19;;56505:63;;;;-1:-1:-1;;;56505:63:0;;;;;;;:::i;:::-;55917:1;56646:7;:18;62483:11:::1;62497:20;62509:7:::0;62497:11:::1;:20::i;:::-;62483:34;;62528:13;62544:34;62553:12;62567:10;;62544:8;:34::i;:::-;2810:10:::0;62589:24:::1;::::0;;;:10:::1;:24;::::0;;;;:35;;;62528:50;-1:-1:-1;62639:10:0;;62635:226:::1;;2810:10:::0;62694:25:::1;::::0;;;:11:::1;:25;::::0;;;;;:37:::1;::::0;62724:6;62694:29:::1;:37::i;:::-;62666:11;:25;2810:10:::0;-1:-1:-1;;;;;62666:25:0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;-1:-1:-1;62666:25:0;:65;;;;62766:10:::1;::::0;62754:60;;-1:-1:-1;;;62754:60:0;;18384:32:1;;;62754:60:0::1;::::0;::::1;18366:51:1::0;18433:18;;;18426:34;;;62766:10:0;::::1;::::0;62754:43:::1;::::0;18339:18:1;;62754:60:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62746:103;;;::::0;-1:-1:-1;;;62746:103:0;;35955:2:1;62746:103:0::1;::::0;::::1;35937:21:1::0;35994:2;35974:18;;;35967:30;36033:32;36013:18;;;36006:60;36083:18;;62746:103:0::1;35753:354:1::0;62746:103:0::1;-1:-1:-1::0;;55873:1:0;56825:7;:22;-1:-1:-1;62411:465:0:o;5042:173::-;5117:6;;;-1:-1:-1;;;;;5134:17:0;;;-1:-1:-1;;;;;;5134:17:0;;;;;;;5167:40;;5117:6;;;5134:17;5117:6;;5167:40;;5098:16;;5167:40;5087:128;5042:173;:::o;32436:360::-;32496:13;32512:23;32527:7;32512:14;:23::i;:::-;32496:39;;32548:48;32569:5;32584:1;32588:7;32548:20;:48::i;:::-;32637:29;32654:1;32658:7;32637:8;:29::i;:::-;-1:-1:-1;;;;;32679:16:0;;;;;;:9;:16;;;;;:21;;32699:1;;32679:16;:21;;32699:1;;32679:21;:::i;:::-;;;;-1:-1:-1;;32718:16:0;;;;:7;:16;;;;;;32711:23;;-1:-1:-1;;;;;;32711:23:0;;;32752:36;32726:7;;32718:16;-1:-1:-1;;;;;32752:36:0;;;;;32718:16;;32752:36;32485:311;32436:360;:::o;46421:106::-;46479:7;46510:1;46506;:5;:13;;46518:1;46506:13;;;-1:-1:-1;46514:1:0;;46499:20;-1:-1:-1;46421:106:0:o;50743:98::-;50801:7;50828:5;50832:1;50828;:5;:::i;29219:315::-;29376:28;29386:4;29392:2;29396:7;29376:9;:28::i;:::-;29423:48;29446:4;29452:2;29456:7;29465:5;29423:22;:48::i;:::-;29415:111;;;;-1:-1:-1;;;29415:111:0;;;;;;;:::i;72879:715::-;72935:13;73148:10;73144:53;;-1:-1:-1;;73175:10:0;;;;;;;;;;;;-1:-1:-1;;;73175:10:0;;;;;72879:715::o;73144:53::-;73222:5;73207:12;73263:78;73270:9;;73263:78;;73296:8;;;;:::i;:::-;;-1:-1:-1;73319:10:0;;-1:-1:-1;73327:2:0;73319:10;;:::i;:::-;;;73263:78;;;73351:19;73383:6;73373:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;73373:17:0;;73351:39;;73401:154;73408:10;;73401:154;;73435:11;73445:1;73435:11;;:::i;:::-;;-1:-1:-1;73504:10:0;73512:2;73504:5;:10;:::i;:::-;73491:24;;:2;:24;:::i;:::-;73478:39;;73461:6;73468;73461:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;73461:56:0;;;;;;;;-1:-1:-1;73532:11:0;73541:2;73532:11;;:::i;:::-;;;73401:154;;73956:1607;74054:11;;74014:13;;74080:8;74076:23;;-1:-1:-1;;74090:9:0;;;;;;;;;-1:-1:-1;74090:9:0;;;73956:1607;-1:-1:-1;73956:1607:0:o;74076:23::-;74151:18;74189:1;74178:7;:3;74184:1;74178:7;:::i;:::-;74177:13;;;;:::i;:::-;74172:19;;:1;:19;:::i;:::-;74151:40;-1:-1:-1;74249:19:0;74281:15;74151:40;74294:2;74281:15;:::i;:::-;74271:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;74271:26:0;;74249:48;;74310:18;74331:5;;;;;;;;;;;;;;;;;74310:26;;74400:1;74393:5;74389:13;74445:2;74437:6;74433:15;74496:1;74464:777;74519:3;74516:1;74513:10;74464:777;;;74574:1;74617:12;;;;;74611:19;74712:4;74700:2;74696:14;;;;;74678:40;;74672:47;74821:2;74817:14;;;74813:25;;74799:40;;74793:47;74950:1;74946:13;;;74942:24;;74928:39;;74922:46;75070:16;;;;75056:31;;75050:38;74748:1;74744:11;;;74842:4;74789:58;;;74780:68;74873:11;;74918:57;;;74909:67;;;;75001:11;;75046:49;;75037:59;75125:3;75121:13;75154:22;;75224:1;75209:17;;;;74567:9;74464:777;;;74468:44;75273:1;75268:3;75264:11;75294:1;75289:84;;;;75392:1;75387:82;;;;75257:212;;75289:84;-1:-1:-1;;;;;75322:17:0;;75315:43;75289:84;;75387:82;-1:-1:-1;;;;;75420:17:0;;75413:41;75257:212;-1:-1:-1;;;75485:26:0;;;75492:6;73956:1607;-1:-1:-1;;;;73956:1607:0:o;30831:110::-;30907:26;30917:2;30921:7;30907:26;;;;;;;;;;;;:9;:26::i;:::-;30831:110;;:::o;65930:835::-;66074:45;66101:4;66107:2;66111:7;66074:26;:45::i;:::-;-1:-1:-1;;;;;66138:18:0;;;;;;:38;;-1:-1:-1;;;;;;66160:16:0;;;;66138:38;66134:624;;;66205:11;;-1:-1:-1;;;;;66197:19:0;;;66205:11;;66197:19;;;;:40;;-1:-1:-1;66226:11:0;;-1:-1:-1;;;;;66220:17:0;;;66226:11;;66220:17;;66197:40;66193:554;;;66266:15;;;;;;;66258:69;;;;-1:-1:-1;;;66258:69:0;;37280:2:1;66258:69:0;;;37262:21:1;37319:2;37299:18;;;37292:30;37358:34;37338:18;;;37331:62;-1:-1:-1;;;37409:18:1;;;37402:39;37458:19;;66258:69:0;37078:405:1;66258:69:0;66346:19;66360:4;66346:13;:19::i;:::-;66384:17;66398:2;66384:13;:17::i;66193:554::-;66451:11;;-1:-1:-1;;;;;66445:17:0;;;66451:11;;66445:17;66441:306;;;66483:19;66497:4;66483:13;:19::i;:::-;66545:34;66554:12;66568:10;;66545:8;:34::i;:::-;66521:21;;;;:12;:21;;;;;:58;26046:341;25976:411;;:::o;66441:306::-;66631:11;;-1:-1:-1;;;;;66623:19:0;;;66631:11;;66623:19;66619:128;;;66663:17;66677:2;66663:13;:17::i;:::-;66699:32;66719:7;66728:2;66699:19;:32::i;50005:98::-;50063:7;50090:5;50094:1;50090;:5;:::i;34568:799::-;34723:4;-1:-1:-1;;;;;34744:13:0;;6311:20;6359:8;34740:620;;34780:72;;-1:-1:-1;;;34780:72:0;;-1:-1:-1;;;;;34780:36:0;;;;;:72;;2810:10;;34831:4;;34837:7;;34846:5;;34780:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34780:72:0;;;;;;;;-1:-1:-1;;34780:72:0;;;;;;;;;;;;:::i;:::-;;;34776:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35022:13:0;;35018:272;;35065:60;;-1:-1:-1;;;35065:60:0;;;;;;;:::i;35018:272::-;35240:6;35234:13;35225:6;35221:2;35217:15;35210:38;34776:529;-1:-1:-1;;;;;;34903:51:0;-1:-1:-1;;;34903:51:0;;-1:-1:-1;34896:58:0;;31168:321;31298:18;31304:2;31308:7;31298:5;:18::i;:::-;31349:54;31380:1;31384:2;31388:7;31397:5;31349:22;:54::i;:::-;31327:154;;;;-1:-1:-1;;;31327:154:0;;;;;;;:::i;38678:589::-;-1:-1:-1;;;;;38884:18:0;;38880:187;;38919:40;38951:7;40094:10;:17;;40067:24;;;;:15;:24;;;;;:44;;;40122:24;;;;;;;;;;;;39990:164;38919:40;38880:187;;;38989:2;-1:-1:-1;;;;;38981:10:0;:4;-1:-1:-1;;;;;38981:10:0;;38977:90;;39008:47;39041:4;39047:7;39008:32;:47::i;:::-;-1:-1:-1;;;;;39081:16:0;;39077:183;;39114:45;39151:7;39114:36;:45::i;39077:183::-;39187:4;-1:-1:-1;;;;;39181:10:0;:2;-1:-1:-1;;;;;39181:10:0;;39177:83;;39208:40;39236:2;39240:7;39208:27;:40::i;62890:458::-;55917:1;56513:7;;:19;;56505:63;;;;-1:-1:-1;;;56505:63:0;;;;;;;:::i;:::-;55917:1;56646:7;:18;62977:11:::1;62991:26;63009:7:::0;62991:17:::1;:26::i;:::-;62977:40;;63028:13;63044:34;63053:12;63067:10;;63044:8;:34::i;:::-;63089:21;::::0;;;:12:::1;:21;::::0;;;;:32;;;63028:50;-1:-1:-1;63136:10:0;;63132:201:::1;;-1:-1:-1::0;;;;;63181:15:0;::::1;;::::0;;;:11:::1;:15;::::0;;;;;:27:::1;::::0;63201:6;63181:19:::1;:27::i;:::-;-1:-1:-1::0;;;;;63163:15:0;;::::1;;::::0;;;:11:::1;:15;::::0;;;;;;:45;;;;63243:10:::1;::::0;63231:55;;-1:-1:-1;;;63231:55:0;;::::1;::::0;::::1;18366:51:1::0;;;;18433:18;;;18426:34;;;63243:10:0;::::1;::::0;63231:43:::1;::::0;18339:18:1;;63231:55:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63223:98;;;::::0;-1:-1:-1;;;63223:98:0;;35955:2:1;63223:98:0::1;::::0;::::1;35937:21:1::0;35994:2;35974:18;;;35967:30;36033:32;36013:18;;;36006:60;36083:18;;63223:98:0::1;35753:354:1::0;63223:98:0::1;-1:-1:-1::0;;55873:1:0;56825:7;:22;-1:-1:-1;;62890:458:0:o;31825:382::-;-1:-1:-1;;;;;31905:16:0;;31897:61;;;;-1:-1:-1;;;31897:61:0;;38449:2:1;31897:61:0;;;38431:21:1;;;38468:18;;;38461:30;38527:34;38507:18;;;38500:62;38579:18;;31897:61:0;38247:356:1;31897:61:0;29912:4;29936:16;;;:7;:16;;;;;;-1:-1:-1;;;;;29936:16:0;:30;31969:58;;;;-1:-1:-1;;;31969:58:0;;38810:2:1;31969:58:0;;;38792:21:1;38849:2;38829:18;;;38822:30;38888;38868:18;;;38861:58;38936:18;;31969:58:0;38608:352:1;31969:58:0;32040:45;32069:1;32073:2;32077:7;32040:20;:45::i;:::-;-1:-1:-1;;;;;32098:13:0;;;;;;:9;:13;;;;;:18;;32115:1;;32098:13;:18;;32115:1;;32098:18;:::i;:::-;;;;-1:-1:-1;;32127:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;32127:21:0;-1:-1:-1;;;;;32127:21:0;;;;;;;;32166:33;;32127:16;;;32166:33;;32127:16;;32166:33;31825:382;;:::o;40781:988::-;41047:22;41097:1;41072:22;41089:4;41072:16;:22::i;:::-;:26;;;;:::i;:::-;41109:18;41130:26;;;:17;:26;;;;;;41047:51;;-1:-1:-1;41263:28:0;;;41259:328;;-1:-1:-1;;;;;41330:18:0;;41308:19;41330:18;;;:12;:18;;;;;;;;:34;;;;;;;;;41381:30;;;;;;:44;;;41498:30;;:17;:30;;;;;:43;;;41259:328;-1:-1:-1;41683:26:0;;;;:17;:26;;;;;;;;41676:33;;;-1:-1:-1;;;;;41727:18:0;;;;;:12;:18;;;;;:34;;;;;;;41720:41;40781:988::o;42064:1079::-;42342:10;:17;42317:22;;42342:21;;42362:1;;42342:21;:::i;:::-;42374:18;42395:24;;;:15;:24;;;;;;42768:10;:26;;42317:46;;-1:-1:-1;42395:24:0;;42317:46;;42768:26;;;;;;:::i;:::-;;;;;;;;;42746:48;;42832:11;42807:10;42818;42807:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;42912:28;;;:15;:28;;;;;;;:41;;;43084:24;;;;;43077:31;43119:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;42135:1008;;;42064:1079;:::o;39568:221::-;39653:14;39670:20;39687:2;39670:16;:20::i;:::-;-1:-1:-1;;;;;39701:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;39746:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;39568:221:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:269::-;908:3;946:5;940:12;973:6;968:3;961:19;989:63;1045:6;1038:4;1033:3;1029:14;1022:4;1015:5;1011:16;989:63;:::i;:::-;1106:2;1085:15;-1:-1:-1;;1081:29:1;1072:39;;;;1113:4;1068:50;;855:269;-1:-1:-1;;855:269:1:o;1129:231::-;1278:2;1267:9;1260:21;1241:4;1298:56;1350:2;1339:9;1335:18;1327:6;1298:56;:::i;1365:180::-;1424:6;1477:2;1465:9;1456:7;1452:23;1448:32;1445:52;;;1493:1;1490;1483:12;1445:52;-1:-1:-1;1516:23:1;;1365:180;-1:-1:-1;1365:180:1:o;1758:131::-;-1:-1:-1;;;;;1833:31:1;;1823:42;;1813:70;;1879:1;1876;1869:12;1894:315;1962:6;1970;2023:2;2011:9;2002:7;1998:23;1994:32;1991:52;;;2039:1;2036;2029:12;1991:52;2078:9;2065:23;2097:31;2122:5;2097:31;:::i;:::-;2147:5;2199:2;2184:18;;;;2171:32;;-1:-1:-1;;;1894:315:1:o;2214:118::-;2300:5;2293:13;2286:21;2279:5;2276:32;2266:60;;2322:1;2319;2312:12;2337:241;2393:6;2446:2;2434:9;2425:7;2421:23;2417:32;2414:52;;;2462:1;2459;2452:12;2414:52;2501:9;2488:23;2520:28;2542:5;2520:28;:::i;2583:615::-;2669:6;2677;2730:2;2718:9;2709:7;2705:23;2701:32;2698:52;;;2746:1;2743;2736:12;2698:52;2786:9;2773:23;2815:18;2856:2;2848:6;2845:14;2842:34;;;2872:1;2869;2862:12;2842:34;2910:6;2899:9;2895:22;2885:32;;2955:7;2948:4;2944:2;2940:13;2936:27;2926:55;;2977:1;2974;2967:12;2926:55;3017:2;3004:16;3043:2;3035:6;3032:14;3029:34;;;3059:1;3056;3049:12;3029:34;3112:7;3107:2;3097:6;3094:1;3090:14;3086:2;3082:23;3078:32;3075:45;3072:65;;;3133:1;3130;3123:12;3072:65;3164:2;3156:11;;;;;3186:6;;-1:-1:-1;2583:615:1;;-1:-1:-1;;;;2583:615:1:o;3203:247::-;3262:6;3315:2;3303:9;3294:7;3290:23;3286:32;3283:52;;;3331:1;3328;3321:12;3283:52;3370:9;3357:23;3389:31;3414:5;3389:31;:::i;3455:936::-;3552:6;3560;3568;3576;3584;3637:3;3625:9;3616:7;3612:23;3608:33;3605:53;;;3654:1;3651;3644:12;3605:53;3693:9;3680:23;3712:31;3737:5;3712:31;:::i;:::-;3762:5;-1:-1:-1;3819:2:1;3804:18;;3791:32;3832:33;3791:32;3832:33;:::i;:::-;3884:7;-1:-1:-1;3938:2:1;3923:18;;3910:32;;-1:-1:-1;3993:2:1;3978:18;;3965:32;4016:18;4046:14;;;4043:34;;;4073:1;4070;4063:12;4043:34;4111:6;4100:9;4096:22;4086:32;;4156:7;4149:4;4145:2;4141:13;4137:27;4127:55;;4178:1;4175;4168:12;4127:55;4218:2;4205:16;4244:2;4236:6;4233:14;4230:34;;;4260:1;4257;4250:12;4230:34;4305:7;4300:2;4291:6;4287:2;4283:15;4279:24;4276:37;4273:57;;;4326:1;4323;4316:12;4273:57;3455:936;;;;-1:-1:-1;3455:936:1;;-1:-1:-1;4357:2:1;4349:11;;4379:6;3455:936;-1:-1:-1;;;3455:936:1:o;4785:456::-;4862:6;4870;4878;4931:2;4919:9;4910:7;4906:23;4902:32;4899:52;;;4947:1;4944;4937:12;4899:52;4986:9;4973:23;5005:31;5030:5;5005:31;:::i;:::-;5055:5;-1:-1:-1;5112:2:1;5097:18;;5084:32;5125:33;5084:32;5125:33;:::i;:::-;4785:456;;5177:7;;-1:-1:-1;;;5231:2:1;5216:18;;;;5203:32;;4785:456::o;5246:632::-;5417:2;5469:21;;;5539:13;;5442:18;;;5561:22;;;5388:4;;5417:2;5640:15;;;;5614:2;5599:18;;;5388:4;5683:169;5697:6;5694:1;5691:13;5683:169;;;5758:13;;5746:26;;5827:15;;;;5792:12;;;;5719:1;5712:9;5683:169;;;-1:-1:-1;5869:3:1;;5246:632;-1:-1:-1;;;;;;5246:632:1:o;5883:382::-;5948:6;5956;6009:2;5997:9;5988:7;5984:23;5980:32;5977:52;;;6025:1;6022;6015:12;5977:52;6064:9;6051:23;6083:31;6108:5;6083:31;:::i;:::-;6133:5;-1:-1:-1;6190:2:1;6175:18;;6162:32;6203:30;6162:32;6203:30;:::i;:::-;6252:7;6242:17;;;5883:382;;;;;:::o;6270:502::-;6446:3;6431:19;;6435:9;6527:6;6404:4;6561:205;6575:4;6572:1;6569:11;6561:205;;;6638:13;;6653:4;6634:24;6622:37;;6682:4;6706:12;;;;6741:15;;;;6595:1;6588:9;6561:205;;;6565:3;;;6270:502;;;;:::o;6777:127::-;6838:10;6833:3;6829:20;6826:1;6819:31;6869:4;6866:1;6859:15;6893:4;6890:1;6883:15;6909:251;6981:2;6975:9;7023:2;7011:15;;7056:18;7041:34;;7077:22;;;7038:62;7035:88;;;7103:18;;:::i;:::-;7139:2;7132:22;6909:251;:::o;7165:275::-;7236:2;7230:9;7301:2;7282:13;;-1:-1:-1;;7278:27:1;7266:40;;7336:18;7321:34;;7357:22;;;7318:62;7315:88;;;7383:18;;:::i;:::-;7419:2;7412:22;7165:275;;-1:-1:-1;7165:275:1:o;7445:186::-;7493:4;7526:18;7518:6;7515:30;7512:56;;;7548:18;;:::i;:::-;-1:-1:-1;7614:2:1;7593:15;-1:-1:-1;;7589:29:1;7620:4;7585:40;;7445:186::o;7636:1016::-;7731:6;7739;7747;7755;7808:3;7796:9;7787:7;7783:23;7779:33;7776:53;;;7825:1;7822;7815:12;7776:53;7864:9;7851:23;7883:31;7908:5;7883:31;:::i;:::-;7933:5;-1:-1:-1;7990:2:1;7975:18;;7962:32;8003:33;7962:32;8003:33;:::i;:::-;8055:7;-1:-1:-1;8109:2:1;8094:18;;8081:32;;-1:-1:-1;8164:2:1;8149:18;;8136:32;8191:18;8180:30;;8177:50;;;8223:1;8220;8213:12;8177:50;8246:22;;8299:4;8291:13;;8287:27;-1:-1:-1;8277:55:1;;8328:1;8325;8318:12;8277:55;8364:2;8351:16;8389:48;8405:31;8433:2;8405:31;:::i;:::-;8389:48;:::i;:::-;8460:2;8453:5;8446:17;8500:7;8495:2;8490;8486;8482:11;8478:20;8475:33;8472:53;;;8521:1;8518;8511:12;8472:53;8576:2;8571;8567;8563:11;8558:2;8551:5;8547:14;8534:45;8620:1;8615:2;8610;8603:5;8599:14;8595:23;8588:34;8641:5;8631:15;;;;;7636:1016;;;;;;;:::o;8657:700::-;8844:2;8896:21;;;8815:4;;9003:3;8988:19;;8869:18;;;9030:6;8815:4;9064:264;9078:4;9075:1;9072:11;9064:264;;;9169:2;9165:7;9153:9;9145:6;9141:22;9137:36;9132:3;9125:49;9197:51;9241:6;9232;9226:13;9197:51;:::i;:::-;9187:61;-1:-1:-1;9306:12:1;;;;9271:15;;;;9098:1;9091:9;9064:264;;;-1:-1:-1;9345:6:1;;8657:700;-1:-1:-1;;;;;;8657:700:1:o;9362:501::-;9538:2;9523:18;;9527:9;9618:6;9496:4;9652:205;9666:4;9663:1;9660:11;9652:205;;;9729:13;;9744:4;9725:24;9713:37;;9773:4;9797:12;;;;9832:15;;;;9686:1;9679:9;9652:205;;9868:388;9936:6;9944;9997:2;9985:9;9976:7;9972:23;9968:32;9965:52;;;10013:1;10010;10003:12;9965:52;10052:9;10039:23;10071:31;10096:5;10071:31;:::i;:::-;10121:5;-1:-1:-1;10178:2:1;10163:18;;10150:32;10191:33;10150:32;10191:33;:::i;10261:380::-;10340:1;10336:12;;;;10383;;;10404:61;;10458:4;10450:6;10446:17;10436:27;;10404:61;10511:2;10503:6;10500:14;10480:18;10477:38;10474:161;;;10557:10;10552:3;10548:20;10545:1;10538:31;10592:4;10589:1;10582:15;10620:4;10617:1;10610:15;10474:161;;10261:380;;;:::o;11886:401::-;12088:2;12070:21;;;12127:2;12107:18;;;12100:30;12166:34;12161:2;12146:18;;12139:62;-1:-1:-1;;;12232:2:1;12217:18;;12210:35;12277:3;12262:19;;11886:401::o;12292:127::-;12353:10;12348:3;12344:20;12341:1;12334:31;12384:4;12381:1;12374:15;12408:4;12405:1;12398:15;12829:251;12899:6;12952:2;12940:9;12931:7;12927:23;12923:32;12920:52;;;12968:1;12965;12958:12;12920:52;13000:9;12994:16;13019:31;13044:5;13019:31;:::i;13444:555::-;-1:-1:-1;;;;;13767:15:1;;;13749:34;;13819:15;;;;13814:2;13799:18;;13792:43;13866:2;13851:18;;13844:34;;;;13914:3;13909:2;13894:18;;13887:31;;;13692:4;13934:19;;;13927:30;13729:3;13974:19;;13444:555::o;14357:127::-;14418:10;14413:3;14409:20;14406:1;14399:31;14449:4;14446:1;14439:15;14473:4;14470:1;14463:15;14489:135;14528:3;-1:-1:-1;;14549:17:1;;14546:43;;;14569:18;;:::i;:::-;-1:-1:-1;14616:1:1;14605:13;;14489:135::o;14629:356::-;14831:2;14813:21;;;14850:18;;;14843:30;14909:34;14904:2;14889:18;;14882:62;14976:2;14961:18;;14629:356::o;14990:400::-;15192:2;15174:21;;;15231:2;15211:18;;;15204:30;15270:34;15265:2;15250:18;;15243:62;-1:-1:-1;;;15336:2:1;15321:18;;15314:34;15380:3;15365:19;;14990:400::o;15395:413::-;15597:2;15579:21;;;15636:2;15616:18;;;15609:30;15675:34;15670:2;15655:18;;15648:62;-1:-1:-1;;;15741:2:1;15726:18;;15719:47;15798:3;15783:19;;15395:413::o;16638:128::-;16678:3;16709:1;16705:6;16702:1;16699:13;16696:39;;;16715:18;;:::i;:::-;-1:-1:-1;16751:9:1;;16638:128::o;17592:184::-;17662:6;17715:2;17703:9;17694:7;17690:23;17686:32;17683:52;;;17731:1;17728;17721:12;17683:52;-1:-1:-1;17754:16:1;;17592:184;-1:-1:-1;17592:184:1:o;19538:160::-;19615:13;;19668:4;19657:16;;19647:27;;19637:55;;19688:1;19685;19678:12;19637:55;19538:160;;;:::o;19703:804::-;19794:6;19825:3;19869:2;19857:9;19848:7;19844:23;19840:32;19837:52;;;19885:1;19882;19875:12;19837:52;19934:7;19927:4;19916:9;19912:20;19908:34;19898:62;;19956:1;19953;19946:12;19898:62;19989:2;19983:9;20031:2;20023:6;20019:15;20100:6;20088:10;20085:22;20064:18;20052:10;20049:34;20046:62;20043:88;;;20111:18;;:::i;:::-;20147:2;20140:22;20211:18;;;;20182:6;20241:19;;;20238:39;;;20273:1;20270;20263:12;20238:39;20297:9;20315:161;20331:6;20326:3;20323:15;20315:161;;;20399:32;20427:3;20399:32;:::i;:::-;20387:45;;20461:4;20452:14;;;;20348;20315:161;;;-1:-1:-1;20495:6:1;;19703:804;-1:-1:-1;;;;;19703:804:1:o;20855:125::-;20895:4;20923:1;20920;20917:8;20914:34;;;20928:18;;:::i;:::-;-1:-1:-1;20965:9:1;;20855:125::o;20985:1464::-;21088:6;21119:2;21162;21150:9;21141:7;21137:23;21133:32;21130:52;;;21178:1;21175;21168:12;21130:52;21211:9;21205:16;21240:18;21281:2;21273:6;21270:14;21267:34;;;21297:1;21294;21287:12;21267:34;21335:6;21324:9;21320:22;21310:32;;21361:4;21401:7;21396:2;21392;21388:11;21384:25;21374:53;;21423:1;21420;21413:12;21374:53;21447:22;;:::i;:::-;21491:3;21525:2;21521;21517:11;21551:7;21543:6;21540:19;21537:39;;;21572:1;21569;21562:12;21537:39;21596:2;21607:812;21623:6;21618:3;21615:15;21607:812;;;21702:3;21696:10;21738:2;21725:11;21722:19;21719:109;;;21782:1;21811:2;21807;21800:14;21719:109;21851:20;;21898:11;;;21894:25;-1:-1:-1;21884:123:1;;21961:1;21990:2;21986;21979:14;21884:123;22036:2;22030:9;22065:48;22081:31;22109:2;22081:31;:::i;22065:48::-;22140:2;22133:5;22126:17;22184:7;22179:2;22174;22170;22166:11;22162:20;22159:33;22156:123;;;22233:1;22262:2;22258;22251:14;22156:123;22292:54;22343:2;22338;22331:5;22327:14;22322:2;22318;22314:11;22292:54;:::i;:::-;22359:18;;-1:-1:-1;;22397:12:1;;;;21640;;21607:812;;;-1:-1:-1;22438:5:1;;20985:1464;-1:-1:-1;;;;;;;;;20985:1464:1:o;22454:185::-;22496:3;22534:5;22528:12;22549:52;22594:6;22589:3;22582:4;22575:5;22571:16;22549:52;:::i;:::-;22617:16;;;;;22454:185;-1:-1:-1;;22454:185:1:o;22644:960::-;23073:3;23111:6;23105:13;23127:53;23173:6;23168:3;23161:4;23153:6;23149:17;23127:53;:::i;:::-;23211:6;23206:3;23202:16;23189:29;;-1:-1:-1;;;23263:2:1;23256:5;23249:17;23297:6;23291:13;23313:65;23369:8;23365:1;23358:5;23354:13;23347:4;23339:6;23335:17;23313:65;:::i;:::-;23441:1;23397:20;;23433:10;;;23426:22;23473:13;;23495:62;23473:13;23544:1;23536:10;;23529:4;23517:17;;23495:62;:::i;:::-;23577:17;23596:1;23573:25;;22644:960;-1:-1:-1;;;;;22644:960:1:o;23609:1021::-;23985:3;24023:6;24017:13;24039:53;24085:6;24080:3;24073:4;24065:6;24061:17;24039:53;:::i;:::-;24155:13;;24114:16;;;;24177:57;24155:13;24114:16;24211:4;24199:17;;24177:57;:::i;:::-;24301:13;;24256:20;;;24323:57;24301:13;24256:20;24357:4;24345:17;;24323:57;:::i;:::-;24447:13;;24402:20;;;24469:57;24447:13;24402:20;24503:4;24491:17;;24469:57;:::i;:::-;-1:-1:-1;;;24548:20:1;;24577:18;;;24622:1;24611:13;;23609:1021;-1:-1:-1;;;;;;23609:1021:1:o;24635:858::-;24910:3;24948:6;24942:13;24964:53;25010:6;25005:3;24998:4;24990:6;24986:17;24964:53;:::i;:::-;25080:13;;25039:16;;;;25102:57;25080:13;25039:16;25136:4;25124:17;;25102:57;:::i;:::-;25226:13;;25181:20;;;25248:57;25226:13;25181:20;25282:4;25270:17;;25248:57;:::i;:::-;25372:13;;25327:20;;;25394:57;25372:13;25327:20;25428:4;25416:17;;25394:57;:::i;:::-;25467:20;;24635:858;-1:-1:-1;;;;;;24635:858:1:o;25498:1767::-;26013:3;26051:6;26045:13;26067:53;26113:6;26108:3;26101:4;26093:6;26089:17;26067:53;:::i;:::-;26151:6;26145:13;26167:68;26226:8;26217:6;26212:3;26208:16;26201:4;26193:6;26189:17;26167:68;:::i;:::-;26313:13;;26261:16;;;26257:31;;26335:57;26313:13;26257:31;26369:4;26357:17;;26335:57;:::i;:::-;26423:6;26417:13;26439:72;26502:8;26491;26484:5;26480:20;26473:4;26465:6;26461:17;26439:72;:::i;:::-;26593:13;;26537:20;;;;26533:35;;26615:57;26593:13;26533:35;26649:4;26637:17;;26615:57;:::i;:::-;26703:6;26697:13;26719:72;26782:8;26771;26764:5;26760:20;26753:4;26745:6;26741:17;26719:72;:::i;:::-;26873:13;;26817:20;;;;26813:35;;26895:57;26873:13;26813:35;26929:4;26917:17;;26895:57;:::i;:::-;26983:6;26977:13;26999:72;27062:8;27051;27044:5;27040:20;27033:4;27025:6;27021:17;26999:72;:::i;:::-;27150:13;;27094:20;;;;27090:35;;27172:54;27150:13;27090:35;27206:4;27194:17;;27172:54;:::i;:::-;27242:17;;25498:1767;-1:-1:-1;;;;;;;;;;;25498:1767:1:o;27270:1641::-;27737:3;27775:6;27769:13;27801:4;27814:51;27858:6;27853:3;27848:2;27840:6;27836:15;27814:51;:::i;:::-;27928:13;;27887:16;;;;27950:55;27928:13;27887:16;27972:15;;;27950:55;:::i;:::-;28072:13;;28027:20;;;28094:55;28072:13;28027:20;28116:15;;;28094:55;:::i;:::-;28216:13;;28171:20;;;28238:55;28216:13;28171:20;28260:15;;;28238:55;:::i;:::-;28360:13;;28315:20;;;28382:55;28360:13;28315:20;28404:15;;;28382:55;:::i;:::-;28504:13;;28459:20;;;28526:55;28504:13;28459:20;28548:15;;;28526:55;:::i;:::-;28648:13;;28603:20;;;28670:55;28648:13;28603:20;28692:15;;;28670:55;:::i;:::-;28792:13;;28747:20;;;28814:55;28792:13;28747:20;28836:15;;;28814:55;:::i;:::-;28885:20;;;;;27270:1641;-1:-1:-1;;;;;;;;;;;27270:1641:1:o;28916:1449::-;29335:3;29373:6;29367:13;29399:4;29412:51;29456:6;29451:3;29446:2;29438:6;29434:15;29412:51;:::i;:::-;29526:13;;29485:16;;;;29548:55;29526:13;29485:16;29570:15;;;29548:55;:::i;:::-;29670:13;;29625:20;;;29692:55;29670:13;29625:20;29714:15;;;29692:55;:::i;:::-;29814:13;;29769:20;;;29836:55;29814:13;29769:20;29858:15;;;29836:55;:::i;:::-;29958:13;;29913:20;;;29980:55;29958:13;29913:20;30002:15;;;29980:55;:::i;:::-;30102:13;;30057:20;;;30124:55;30102:13;30057:20;30146:15;;;30124:55;:::i;:::-;30246:13;;30201:20;;;30268:55;30246:13;30201:20;30290:15;;;30268:55;:::i;:::-;30339:20;;;;;28916:1449;-1:-1:-1;;;;;;;;;;28916:1449:1:o;30500:1925::-;31161:66;31156:3;31149:79;-1:-1:-1;;;31253:2:1;31248:3;31244:12;31237:34;31131:3;31300:6;31294:13;31316:60;31369:6;31364:2;31359:3;31355:12;31350:2;31342:6;31338:15;31316:60;:::i;:::-;-1:-1:-1;;;31435:2:1;31395:16;;;31427:11;;;31420:67;31512:13;;31534:61;31512:13;31581:2;31573:11;;31568:2;31556:15;;31534:61;:::i;:::-;31660:66;31655:2;31614:17;;;;31647:11;;;31640:87;31756:34;31751:2;31743:11;;31736:55;31821:34;31815:3;31807:12;;31800:56;31886:34;31880:3;31872:12;;31865:56;31951:34;31945:3;31937:12;;31930:56;32016:34;32010:3;32002:12;;31995:56;32081:34;32075:3;32067:12;;32060:56;32146:34;32140:3;32132:12;;32125:56;32211:66;32205:3;32197:12;;32190:88;-1:-1:-1;;;32302:3:1;32294:12;;32287:46;32349:70;32379:39;32413:3;32405:12;;32397:6;32379:39;:::i;:::-;-1:-1:-1;;;30435:27:1;;30487:1;30478:11;;30370:125;32349:70;32342:77;30500:1925;-1:-1:-1;;;;;;30500:1925:1:o;32430:448::-;32692:31;32687:3;32680:44;32662:3;32753:6;32747:13;32769:62;32824:6;32819:2;32814:3;32810:12;32803:4;32795:6;32791:17;32769:62;:::i;:::-;32851:16;;;;32869:2;32847:25;;32430:448;-1:-1:-1;;32430:448:1:o;32883:620::-;32974:6;33027:2;33015:9;33006:7;33002:23;32998:32;32995:52;;;33043:1;33040;33033:12;32995:52;33092:7;33085:4;33074:9;33070:20;33066:34;33056:62;;33114:1;33111;33104:12;33056:62;33138:22;;:::i;:::-;33182:3;33223:2;33212:9;33208:18;33249:7;33241:6;33238:19;33235:39;;;33270:1;33267;33260:12;33235:39;33294:9;33312:161;33328:6;33323:3;33320:15;33312:161;;;33396:32;33424:3;33396:32;:::i;:::-;33384:45;;33458:4;33449:14;;;;33345;33312:161;;33915:355;34117:2;34099:21;;;34156:2;34136:18;;;34129:30;34195:33;34190:2;34175:18;;34168:61;34261:2;34246:18;;33915:355::o;35503:245::-;35570:6;35623:2;35611:9;35602:7;35598:23;35594:32;35591:52;;;35639:1;35636;35629:12;35591:52;35671:9;35665:16;35690:28;35712:5;35690:28;:::i;36112:168::-;36152:7;36218:1;36214;36210:6;36206:14;36203:1;36200:21;36195:1;36188:9;36181:17;36177:45;36174:71;;;36225:18;;:::i;:::-;-1:-1:-1;36265:9:1;;36112:168::o;36285:414::-;36487:2;36469:21;;;36526:2;36506:18;;;36499:30;36565:34;36560:2;36545:18;;36538:62;-1:-1:-1;;;36631:2:1;36616:18;;36609:48;36689:3;36674:19;;36285:414::o;36704:127::-;36765:10;36760:3;36756:20;36753:1;36746:31;36796:4;36793:1;36786:15;36820:4;36817:1;36810:15;36836:120;36876:1;36902;36892:35;;36907:18;;:::i;:::-;-1:-1:-1;36941:9:1;;36836:120::o;36961:112::-;36993:1;37019;37009:35;;37024:18;;:::i;:::-;-1:-1:-1;37058:9:1;;36961:112::o;37488:500::-;-1:-1:-1;;;;;37757:15:1;;;37739:34;;37809:15;;37804:2;37789:18;;37782:43;37856:2;37841:18;;37834:34;;;37904:3;37899:2;37884:18;;37877:31;;;37682:4;;37925:57;;37962:19;;37954:6;37925:57;:::i;37993:249::-;38062:6;38115:2;38103:9;38094:7;38090:23;38086:32;38083:52;;;38131:1;38128;38121:12;38083:52;38163:9;38157:16;38182:30;38206:5;38182:30;:::i;38965:127::-;39026:10;39021:3;39017:20;39014:1;39007:31;39057:4;39054:1;39047:15;39081:4;39078:1;39071:15

Swarm Source

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