Contract 0x55698217174ddd209d25c9e6b974e3a201b470bb

Txn Hash Method
Block
From
To
Value [Txn Fee]
0xc86bdc6f17d6898e6f354555314b53d27bd3b8ac18d8d51f703f58102cfe9851Stake Tokens119581182022-01-21 11:38:071 day 14 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.00050464 2.5
0x748245030ce23503bbaedc1a4d4dd10e4af8d96f1161ed05df6be43bfdd7f927Stake Tokens119575662022-01-21 11:10:311 day 15 hrs ago0xa4b3b69b49292bfb2cf62c7762cd8b6c7b898b5c IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.00046814 2.5
0x01786f6888cdd17dd9d9c1b33eca054185a8c61b776eb9f75b9ec57bdf208305Unstake Tokens119575442022-01-21 11:09:251 day 15 hrs ago0xa4b3b69b49292bfb2cf62c7762cd8b6c7b898b5c IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.000330605 2.5
0x819b9b7bcef01737a340f4c9fda1b2208ab672fdd38ad246c2f03557bf5f584eUnstake Tokens119570992022-01-21 10:47:101 day 15 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.00029382 2.5
0x4065dab52d745d22784866eebe1eb55564fc57937cebaf68a0ffb7c34af604e0Stake Tokens119569452022-01-21 10:39:281 day 15 hrs ago0xa4b3b69b49292bfb2cf62c7762cd8b6c7b898b5c IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.00042539 2.5
0x23b83ec414b52791e10aca948be97da6e571ec161484a843f91f429c4a155815Stake Tokens119568052022-01-21 10:32:281 day 15 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.00050464 2.5
0x43c9de9d787f714eceae2c3eb8c4f1287026d9ce41627571c81969802b67f6e7Unstake Tokens119566612022-01-21 10:25:161 day 15 hrs ago0xa4b3b69b49292bfb2cf62c7762cd8b6c7b898b5c IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.000330605 2.5
0xfb600ccabd720e516a27a28c0d73f70af6361c42d0225d221b4e425acf75e7eaUnstake Tokens119566522022-01-21 10:24:491 day 15 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.00029379 2.5
0x79b6d30c805914fb96d1238a4780ef843d5465d04070e94b2e0ac106e563fc41Unstake Tokens119566452022-01-21 10:24:281 day 15 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.000312355 2.5
0x9a9982dccec6c8283f3562eebe49916ff4f19947fdd8fb3ac2d5d31953cdaf7cUnstake Tokens119566402022-01-21 10:24:131 day 15 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.0003998 2.5
0x206487f64f49e6addf047007749c5325dde4d61533e2591e30b0d5ed7b1e30d0Unstake Tokens119566322022-01-21 10:23:491 day 15 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.000293765 2.5
0x8a83f63fc3db925a51ee58893c0bdff4a54d264062d0f0b4a54abf10891f480fUnstake Tokens119566272022-01-21 10:23:341 day 15 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.00033488 2.5
0x03fa5d13798ca66e126285731d3488f59ec469a623a6583aaf3052a598c93335Unstake Tokens119566232022-01-21 10:23:221 day 15 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.00036405 2.5
0xda5009f72fb0f9fef26b9093c99e389a14b52eed2298a86e5625bc03fb9a3cf7Unstake Tokens119566152022-01-21 10:22:581 day 15 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.000293765 2.5
0x716c164f49355f297f610d439c3659ab65c10b4d2817275ef1ca6bc33d35650aUnstake Tokens119566052022-01-21 10:22:281 day 15 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.000293765 2.5
0x4f822b02ecfc9904fdf18729204930a42924c30bffbfb5c5b5102d8180cf9ce6Stake Tokens119562392022-01-21 10:04:101 day 16 hrs ago0xa4b3b69b49292bfb2cf62c7762cd8b6c7b898b5c IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.00042539 2.5
0x55fe78b82c80c178b31a51fd30918c2b9ad13a0e84f2609743ed894bb1db256fUnstake Tokens119562232022-01-21 10:03:221 day 16 hrs ago0xa4b3b69b49292bfb2cf62c7762cd8b6c7b898b5c IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.00037279 2.5
0xfde9d645deb10e42bece3a2de39a006e344476407ddfa34dfb8d69364f7faca3Unstake Tokens119557062022-01-21 9:37:311 day 16 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.00031207 2.5
0x787003685e8b917bfd878a2ca6e519f0d99f14e36ab2a2078e72a523f438a7b8Unstake Tokens119556972022-01-21 9:37:041 day 16 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.00035505 2.5
0x5808e38c640c39d76018b055014e545ef480b8c490a5c81b27a50f1542ac9153Unstake Tokens119556922022-01-21 9:36:491 day 16 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.000294305 2.5
0x24f6fc9dc9140e90142f00e44433ada9c2e50df80be1d76ac019a84c2fa4fbc7Unstake Tokens119556882022-01-21 9:36:371 day 16 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.00043586 2.5
0x3c0c93f4e37f9c2b7b85ea781f1c10ecd19426b159738ec962f8e28d07930a69Unstake Tokens119554252022-01-21 9:23:281 day 16 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.000377655 2.5
0x0409525252c33003c08af52b16b15c44709b3728da075659fac210640f249914Unstake Tokens119554182022-01-21 9:23:071 day 16 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.00035705 2.5
0x7abb575b3dfa7451ebd77f9e458eeb0b2754a2fcc75c8e60f9736d6ac90b2469Unstake Tokens119553922022-01-21 9:21:491 day 16 hrs ago0xa4b3b69b49292bfb2cf62c7762cd8b6c7b898b5c IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.000293765 2.5
0x3253f919ac0c21cec4952a4fdda5a2d41b553ff84eb1b95a53ac6737762d85c7Stake Tokens119552502022-01-21 9:14:431 day 17 hrs ago0x43db12dcb7263383a8a4f9317fc1b70176453f56 IN 0x55698217174ddd209d25c9e6b974e3a201b470bb0 HT0.000488175 2.5
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xc86bdc6f17d6898e6f354555314b53d27bd3b8ac18d8d51f703f58102cfe9851119581182022-01-21 11:38:071 day 14 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x7cb0912cd3a3a5373450d485c6bda6234ea6d3d60 HT
0xc86bdc6f17d6898e6f354555314b53d27bd3b8ac18d8d51f703f58102cfe9851119581182022-01-21 11:38:071 day 14 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x7cb0912cd3a3a5373450d485c6bda6234ea6d3d60 HT
0x748245030ce23503bbaedc1a4d4dd10e4af8d96f1161ed05df6be43bfdd7f927119575662022-01-21 11:10:311 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x7cb0912cd3a3a5373450d485c6bda6234ea6d3d60 HT
0x748245030ce23503bbaedc1a4d4dd10e4af8d96f1161ed05df6be43bfdd7f927119575662022-01-21 11:10:311 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x7cb0912cd3a3a5373450d485c6bda6234ea6d3d60 HT
0x01786f6888cdd17dd9d9c1b33eca054185a8c61b776eb9f75b9ec57bdf208305119575442022-01-21 11:09:251 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x7cb0912cd3a3a5373450d485c6bda6234ea6d3d60 HT
0x819b9b7bcef01737a340f4c9fda1b2208ab672fdd38ad246c2f03557bf5f584e119570992022-01-21 10:47:101 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x7cb0912cd3a3a5373450d485c6bda6234ea6d3d60 HT
0x4065dab52d745d22784866eebe1eb55564fc57937cebaf68a0ffb7c34af604e0119569452022-01-21 10:39:281 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x7cb0912cd3a3a5373450d485c6bda6234ea6d3d60 HT
0x4065dab52d745d22784866eebe1eb55564fc57937cebaf68a0ffb7c34af604e0119569452022-01-21 10:39:281 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x7cb0912cd3a3a5373450d485c6bda6234ea6d3d60 HT
0x23b83ec414b52791e10aca948be97da6e571ec161484a843f91f429c4a155815119568052022-01-21 10:32:281 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x7cb0912cd3a3a5373450d485c6bda6234ea6d3d60 HT
0x23b83ec414b52791e10aca948be97da6e571ec161484a843f91f429c4a155815119568052022-01-21 10:32:281 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x7cb0912cd3a3a5373450d485c6bda6234ea6d3d60 HT
0x43c9de9d787f714eceae2c3eb8c4f1287026d9ce41627571c81969802b67f6e7119566612022-01-21 10:25:161 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x7cb0912cd3a3a5373450d485c6bda6234ea6d3d60 HT
0xfb600ccabd720e516a27a28c0d73f70af6361c42d0225d221b4e425acf75e7ea119566522022-01-21 10:24:491 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0xf2c16019ff550037e924f9503fab12445b32e0fc0 HT
0x79b6d30c805914fb96d1238a4780ef843d5465d04070e94b2e0ac106e563fc41119566452022-01-21 10:24:281 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x7cb0912cd3a3a5373450d485c6bda6234ea6d3d60 HT
0x9a9982dccec6c8283f3562eebe49916ff4f19947fdd8fb3ac2d5d31953cdaf7c119566402022-01-21 10:24:131 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0xe6f11de143270e2886582c37f5ecc4d4ad9f18320 HT
0x206487f64f49e6addf047007749c5325dde4d61533e2591e30b0d5ed7b1e30d0119566322022-01-21 10:23:491 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb0x5b23f4dad0b46a16b961ffe69c10ee149eac10120 HT
0x8a83f63fc3db925a51ee58893c0bdff4a54d264062d0f0b4a54abf10891f480f119566272022-01-21 10:23:341 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb0x31890520e11558b340d3f3fb8539ccd1d01c4d720 HT
0x03fa5d13798ca66e126285731d3488f59ec469a623a6583aaf3052a598c93335119566232022-01-21 10:23:221 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x1fb3522017c4983723cdefc633538c91bff01a310 HT
0xda5009f72fb0f9fef26b9093c99e389a14b52eed2298a86e5625bc03fb9a3cf7119566152022-01-21 10:22:581 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb0x31890520e11558b340d3f3fb8539ccd1d01c4d720 HT
0x716c164f49355f297f610d439c3659ab65c10b4d2817275ef1ca6bc33d35650a119566052022-01-21 10:22:281 day 15 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb0x5b23f4dad0b46a16b961ffe69c10ee149eac10120 HT
0x4f822b02ecfc9904fdf18729204930a42924c30bffbfb5c5b5102d8180cf9ce6119562392022-01-21 10:04:101 day 16 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x7cb0912cd3a3a5373450d485c6bda6234ea6d3d60 HT
0x4f822b02ecfc9904fdf18729204930a42924c30bffbfb5c5b5102d8180cf9ce6119562392022-01-21 10:04:101 day 16 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x7cb0912cd3a3a5373450d485c6bda6234ea6d3d60 HT
0x55fe78b82c80c178b31a51fd30918c2b9ad13a0e84f2609743ed894bb1db256f119562232022-01-21 10:03:221 day 16 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x7cb0912cd3a3a5373450d485c6bda6234ea6d3d60 HT
0xfde9d645deb10e42bece3a2de39a006e344476407ddfa34dfb8d69364f7faca3119557062022-01-21 9:37:311 day 16 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb 0x7cb0912cd3a3a5373450d485c6bda6234ea6d3d60 HT
0x787003685e8b917bfd878a2ca6e519f0d99f14e36ab2a2078e72a523f438a7b8119556972022-01-21 9:37:041 day 16 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb0x31890520e11558b340d3f3fb8539ccd1d01c4d720 HT
0x5808e38c640c39d76018b055014e545ef480b8c490a5c81b27a50f1542ac9153119556922022-01-21 9:36:491 day 16 hrs ago 0x55698217174ddd209d25c9e6b974e3a201b470bb0x13cee9409a013d289dea618aa61b6c87008937690 HT
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
NFTFarm

Compiler Version
v0.6.6+commit.6c089d02

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at hecoinfo.com on 2021-12-29
*/

pragma solidity ^0.6.0;


// import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
// import "@openzeppelin/contracts/access/Ownable.sol";
// import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";


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

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

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

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

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

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

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

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

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

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

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

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

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

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

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

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

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

        return c;
    }

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

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

        return c;
    }

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

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

/**
 * @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 in extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

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

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

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

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

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

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

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

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

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

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

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

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

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

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

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

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

            bytes32 lastvalue = set._values[lastIndex];

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

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

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

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

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

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


    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

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

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

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

    struct MapEntry {
        bytes32 _key;
        bytes32 _value;
    }

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

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

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

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

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

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

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

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

            MapEntry storage lastEntry = map._entries[lastIndex];

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

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

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function _get(Map storage map, bytes32 key) private view returns (bytes32) {
        return _get(map, key, "EnumerableMap: nonexistent key");
    }

    /**
     * @dev Same as {_get}, with a custom error message when `key` is not in the map.
     */
    function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    // UintToAddressMap

    struct UintToAddressMap {
        Map _inner;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/**
 * @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].
 */
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 () internal {
        _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;
    }
}


contract NFTFarm is Ownable, ReentrancyGuard{
    using SafeMath for uint256;

    string public name = "NFT Farm";

    address[] public adminList;

    address[] public allowedTokens;

    // nft info
    struct NFTInfo{
        address NFTToken;
        uint256 NFTTokenID;
    }
    
    // pool > user > NFTInfo[]
    mapping(uint256 => mapping(address => NFTInfo[])) public stakingBalance;

    event AddAllowedTokens(address _token);
    event StakeTokens(address _token, uint256 _tokenID, uint256 _pool);
    event StakeTokensMulti(address[] _tokenList, uint256[] _tokenIDList, uint256 _pool);
    event UnstakeTokens(address _token, uint256 _tokenID, uint256 _pool);
    event UnstakeTokensMulti(uint256 _pool);

    constructor() public {
        adminList.push(msg.sender);
    }

    function addAllowedTokens(address _token) public nonReentrant {
        require(onlyAdmin(msg.sender), "Only administrators can operate");
        require(_token != address(0), "token is zero address");

        if (tokenIsAllowed(_token) == false) {
            allowedTokens.push(_token);
            emit AddAllowedTokens(_token);
        }
    }

    function tokenIsAllowed(address _token) public view returns (bool) {
        for ( uint256 nIndex = 0; nIndex < allowedTokens.length; nIndex++ ) {
            if (allowedTokens[nIndex] == _token) {
                return true;
            }
        }
        return false;
    }

    function getAllowedTokens() public view returns (address[] memory) {
        return allowedTokens;
    }

    function setAllowedTokens(address[] memory _tokenList) public nonReentrant {
        require(onlyAdmin(msg.sender), "Only administrators can operate");
        require(_tokenList.length > 0, "_tokenList is empty");
        
        for ( uint256 nIndex = 0; nIndex < _tokenList.length; nIndex++){
            require(_tokenList[nIndex] != address(0), "token is empty");
        }

        allowedTokens = _tokenList;
    }

    // Staking Tokens
    function stakeTokens(address _token, uint256 _tokenID, uint256 _pool) public nonReentrant returns (uint256) {
        require(tokenIsAllowed(_token) == true, "token not allow");
        require(IERC721(_token).ownerOf(_tokenID) == msg.sender, "nft tokenID is error");

        stakingBalance[_pool][msg.sender].push(NFTInfo(_token, _tokenID));

        IERC721(_token).transferFrom(msg.sender, address(this), _tokenID);

        emit StakeTokens(_token, _tokenID, _pool);

        return stakingBalance[_pool][msg.sender].length;
    }

    // Staking Tokens Multi
    function stakeTokensMulti(address[] memory _tokenList, uint256[] memory _tokenIDList, uint256 _pool) public nonReentrant returns (uint256) {
        require(_tokenList.length > 0, "_tokenList is empty");
        require(_tokenList.length == _tokenIDList.length, "Inconsistent array length");

        for( uint256 nIndex = 0; nIndex < _tokenList.length; nIndex++ ){
            address _token = _tokenList[nIndex];
            uint256 _tokenID = _tokenIDList[nIndex];

            require(tokenIsAllowed(_token) == true, "token not allow");
            require(IERC721(_token).ownerOf(_tokenID) == msg.sender, "nft tokenID is error");

            stakingBalance[_pool][msg.sender].push(NFTInfo(_token, _tokenID));

            IERC721(_token).transferFrom(msg.sender, address(this), _tokenID);
        }

        emit StakeTokensMulti(_tokenList, _tokenIDList, _pool);

        return stakingBalance[_pool][msg.sender].length;
    }

    // Unstaking Tokens (Withdraw)
    function unstakeTokens(address _token, uint256 _tokenID, uint256 _pool) public nonReentrant {
        require(_token != address(0), "token is zero address");

        uint256 _len = stakingBalance[_pool][msg.sender].length;

        bool isExists = false;
        uint256 nIndexValid;

        for( uint256 nIndex = 0; nIndex < _len; nIndex++ ){
            if( (stakingBalance[_pool][msg.sender][nIndex].NFTToken == _token) && (stakingBalance[_pool][msg.sender][nIndex].NFTTokenID == _tokenID) ){
                isExists = true;
                nIndexValid = nIndex;
            }
        }

        require(isExists, "tokenID not Found");
        resetUserStakingList(msg.sender, _pool, nIndexValid);
        IERC721(_token).transferFrom(address(this), msg.sender, _tokenID);

        emit UnstakeTokens(_token, _tokenID, _pool);
    }

    // Unstaking Tokens Multi (Withdraw)
    function unstakeTokensMulti(uint256 _pool) public nonReentrant{
        uint256 _len = stakingBalance[_pool][msg.sender].length;
        require(_len > 0, "staking balance cannot be 0");

        for( uint256 nIn = _len; nIn > 0; nIn-- ){
            uint256 nIndex = nIn-1;
            address _token = stakingBalance[_pool][msg.sender][nIndex].NFTToken;
            uint256 _tokenID = stakingBalance[_pool][msg.sender][nIndex].NFTTokenID;

            stakingBalance[_pool][msg.sender].pop();
            IERC721(_token).transferFrom(address(this), msg.sender, _tokenID);
        }

        emit UnstakeTokensMulti(_pool);
    }

    function resetUserStakingList(address _user, uint256 _pool, uint256 _key) private {
        uint256 _len = stakingBalance[_pool][_user].length;

        if(_key < _len) {
            for (uint256 i = _key; i < _len-1; i++){
                stakingBalance[_pool][_user][i] = stakingBalance[_pool][_user][i+1];
            }
            stakingBalance[_pool][_user].pop();
        }
    }

    function getUserStakingList(address _user, uint256 _pool) public view returns (address[] memory, uint256[] memory) {
        uint256 _len = stakingBalance[_pool][_user].length;

        address[] memory _tokenList = new address[](_len);
        uint256[] memory _tokenIDList = new uint256[](_len);

        for( uint256 nIndex = 0; nIndex < _len; nIndex++ ){
            _tokenList[nIndex] = stakingBalance[_pool][_user][nIndex].NFTToken;
            _tokenIDList[nIndex] = stakingBalance[_pool][_user][nIndex].NFTTokenID;
        }

        return (_tokenList, _tokenIDList);
    }

    function getUserStakingLen(address _user, uint256 _pool) public view returns (uint256) {
        return stakingBalance[_pool][_user].length;
    }

    function setAdminList(address[] calldata _list) external onlyOwner nonReentrant {
        require(_list.length > 0, "_list is empty");
        
        for ( uint256 nIndex = 0; nIndex < _list.length; nIndex++){
            require(_list[nIndex] != address(0), "admin is empty");
        }
        adminList = _list;
    }

    function getAdminList() public view returns (address[] memory) {
        return adminList;
    }

    function onlyAdmin(address _admin) internal view returns (bool) {
        for ( uint256 nIndex = 0; nIndex < adminList.length; nIndex++){
            if (adminList[nIndex] == _admin) {
                return true;
            }
        }
        return false;
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"}],"name":"AddAllowedTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_pool","type":"uint256"}],"name":"StakeTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"_tokenList","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"_tokenIDList","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"_pool","type":"uint256"}],"name":"StakeTokensMulti","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_pool","type":"uint256"}],"name":"UnstakeTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_pool","type":"uint256"}],"name":"UnstakeTokensMulti","type":"event"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"addAllowedTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"adminList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allowedTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAdminList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowedTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_pool","type":"uint256"}],"name":"getUserStakingLen","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_pool","type":"uint256"}],"name":"getUserStakingList","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_list","type":"address[]"}],"name":"setAdminList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokenList","type":"address[]"}],"name":"setAllowedTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenID","type":"uint256"},{"internalType":"uint256","name":"_pool","type":"uint256"}],"name":"stakeTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokenList","type":"address[]"},{"internalType":"uint256[]","name":"_tokenIDList","type":"uint256[]"},{"internalType":"uint256","name":"_pool","type":"uint256"}],"name":"stakeTokensMulti","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakingBalance","outputs":[{"internalType":"address","name":"NFTToken","type":"address"},{"internalType":"uint256","name":"NFTTokenID","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"tokenIsAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenID","type":"uint256"},{"internalType":"uint256","name":"_pool","type":"uint256"}],"name":"unstakeTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pool","type":"uint256"}],"name":"unstakeTokensMulti","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526040518060400160405280600881526020017f4e4654204661726d000000000000000000000000000000000000000000000000815250600290805190602001906200005192919062000188565b503480156200005f57600080fd5b506000620000726200018060201b60201c565b9050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350600180819055506003339080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062000237565b600033905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620001cb57805160ff1916838001178555620001fc565b82800160010185558215620001fc579182015b82811115620001fb578251825591602001919060010190620001de565b5b5090506200020b91906200020f565b5090565b6200023491905b808211156200023057600081600090555060010162000216565b5090565b90565b61347580620002476000396000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c8063715018a6116100ad578063d0df736d11610071578063d0df736d146107f4578063d9f774fc14610893578063dd5b8467146108f2578063f2136f121461094e578063f2fde38b146109b057610121565b8063715018a6146105e4578063825ddc9f146105ee5780638da5cb5b146106d9578063ad1286c814610723578063b04e57e81461079c57610121565b8063171e44ea116100f4578063171e44ea146102e2578063234f19c81461032657806357921ae8146103de5780635e5f2e26146105485780636888e851146105b657610121565b8063024ece891461012657806306fdde03146101855780630cff8e8f1461020857806311117fc814610274575b600080fd5b61012e6109f4565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610171578082015181840152602081019050610156565b505050509050019250505060405180910390f35b61018d610a82565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101cd5780820151818401526020810190506101b2565b50505050905090810190601f1680156101fa5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61025e6004803603606081101561021e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050610b20565b6040518082815260200191505060405180910390f35b6102a06004803603602081101561028a57600080fd5b8101908080359060200190929190505050610ff2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610324600480360360208110156102f857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061102e565b005b6103dc6004803603602081101561033c57600080fd5b810190808035906020019064010000000081111561035957600080fd5b82018360208201111561036b57600080fd5b8035906020019184602083028401116401000000008311171561038d57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192905050506112b3565b005b610532600480360360608110156103f457600080fd5b810190808035906020019064010000000081111561041157600080fd5b82018360208201111561042357600080fd5b8035906020019184602083028401116401000000008311171561044557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156104a557600080fd5b8201836020820111156104b757600080fd5b803590602001918460208302840111640100000000831117156104d957600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019092919050505061151a565b6040518082815260200191505060405180910390f35b6105746004803603602081101561055e57600080fd5b8101908080359060200190929190505050611b7f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105e2600480360360208110156105cc57600080fd5b8101908080359060200190929190505050611bbb565b005b6105ec611feb565b005b61063a6004803603604081101561060457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612173565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015610681578082015181840152602081019050610666565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156106c35780820151818401526020810190506106a8565b5050505090500194505050505060405180910390f35b6106e16123e8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61079a6004803603602081101561073957600080fd5b810190808035906020019064010000000081111561075657600080fd5b82018360208201111561076857600080fd5b8035906020019184602083028401116401000000008311171561078a57600080fd5b9091929391929390505050612411565b005b6107f2600480360360608110156107b257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291905050506126db565b005b61084a6004803603606081101561080a57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612b8c565b604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b61089b612bf7565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156108de5780820151818401526020810190506108c3565b505050509050019250505060405180910390f35b6109346004803603602081101561090857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612c85565b604051808215151515815260200191505060405180910390f35b61099a6004803603604081101561096457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612d27565b6040518082815260200191505060405180910390f35b6109f2600480360360208110156109c657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612d85565b005b60606004805480602002602001604051908101604052809291908181526020018280548015610a7857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610a2e575b5050505050905090565b60028054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610b185780601f10610aed57610100808354040283529160200191610b18565b820191906000526020600020905b815481529060010190602001808311610afb57829003601f168201915b505050505081565b600060026001541415610b9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260018190555060011515610bb085612c85565b151514610c25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f746f6b656e206e6f7420616c6c6f77000000000000000000000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610c8d57600080fd5b505afa158015610ca1573d6000803e3d6000fd5b505050506040513d6020811015610cb757600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614610d51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f6e667420746f6b656e4944206973206572726f7200000000000000000000000081525060200191505060405180910390fd5b6005600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180604001604052808673ffffffffffffffffffffffffffffffffffffffff16815260200185815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015550508373ffffffffffffffffffffffffffffffffffffffff166323b872dd3330866040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015610f0357600080fd5b505af1158015610f17573d6000803e3d6000fd5b505050507f106d46085b22b31d658796e9924cf39946b4105bdb86f8afba3d60d71c3cc591848484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a16005600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050600180819055509392505050565b60038181548110610fff57fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260015414156110a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026001819055506110b833612f92565b61112a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4f6e6c792061646d696e6973747261746f72732063616e206f7065726174650081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156111cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f746f6b656e206973207a65726f2061646472657373000000000000000000000081525060200191505060405180910390fd5b600015156111da82612c85565b151514156112a9576004819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f4eec973584b9930388bebeff27c40485ca0a973c42e435e870dbdcb4623e4f6681604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b6001808190555050565b6002600154141561132c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260018190555061133d33612f92565b6113af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4f6e6c792061646d696e6973747261746f72732063616e206f7065726174650081525060200191505060405180910390fd5b6000815111611426576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f5f746f6b656e4c69737420697320656d7074790000000000000000000000000081525060200191505060405180910390fd5b60008090505b81518110156114f857600073ffffffffffffffffffffffffffffffffffffffff1682828151811061145957fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614156114eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f746f6b656e20697320656d70747900000000000000000000000000000000000081525060200191505060405180910390fd5b808060010191505061142c565b50806004908051906020019061150f9291906132ac565b506001808190555050565b600060026001541415611595576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026001819055506000845111611614576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f5f746f6b656e4c69737420697320656d7074790000000000000000000000000081525060200191505060405180910390fd5b825184511461168b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f496e636f6e73697374656e74206172726179206c656e6774680000000000000081525060200191505060405180910390fd5b60008090505b8451811015611a515760008582815181106116a857fe5b6020026020010151905060008583815181106116c057fe5b60200260200101519050600115156116d783612c85565b15151461174c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f746f6b656e206e6f7420616c6c6f77000000000000000000000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156117b457600080fd5b505afa1580156117c8573d6000803e3d6000fd5b505050506040513d60208110156117de57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614611878576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f6e667420746f6b656e4944206973206572726f7200000000000000000000000081525060200191505060405180910390fd5b6005600086815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180604001604052808473ffffffffffffffffffffffffffffffffffffffff16815260200183815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015550508173ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015611a2a57600080fd5b505af1158015611a3e573d6000803e3d6000fd5b5050505050508080600101915050611691565b507fe54a390955c95c8abc5a8a237f45af819d984f95d8ddd5a840bbee5dba9a18b9848484604051808060200180602001848152602001838103835286818151815260200191508051906020019060200280838360005b83811015611ac3578082015181840152602081019050611aa8565b50505050905001838103825285818151815260200191508051906020019060200280838360005b83811015611b05578082015181840152602081019050611aea565b505050509050019550505050505060405180910390a16005600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050600180819055509392505050565b60048181548110611b8c57fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60026001541415611c34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260018190555060006005600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050905060008111611d0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f7374616b696e672062616c616e63652063616e6e6f742062652030000000000081525060200191505060405180910390fd5b60008190505b6000811115611fa857600060018203905060006005600086815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110611d7e57fe5b906000526020600020906002020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060006005600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208381548110611e0f57fe5b90600052602060002090600202016001015490506005600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480611e7c57fe5b6001900381819060005260206000209060020201600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160009055505090558173ffffffffffffffffffffffffffffffffffffffff166323b872dd3033846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015611f7f57600080fd5b505af1158015611f93573d6000803e3d6000fd5b50505050505050808060019003915050611d10565b507fef58fe3f91d4c73baffafcc7e51e6c71902c6c3daf23f97e4432dcd1ffae0a62826040518082815260200191505060405180910390a1506001808190555050565b611ff3613034565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146120b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60608060006005600085815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050905060608167ffffffffffffffff811180156121e757600080fd5b506040519080825280602002602001820160405280156122165781602001602082028036833780820191505090505b50905060608267ffffffffffffffff8111801561223257600080fd5b506040519080825280602002602001820160405280156122615781602001602082028036833780820191505090505b50905060008090505b838110156123d7576005600088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081815481106122cd57fe5b906000526020600020906002020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683828151811061230b57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506005600088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081815481106123a057fe5b9060005260206000209060020201600101548282815181106123be57fe5b602002602001018181525050808060010191505061226a565b508181945094505050509250929050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b612419613034565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146124da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026001541415612553576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600181905550600082829050116125d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f5f6c69737420697320656d70747900000000000000000000000000000000000081525060200191505060405180910390fd5b60008090505b828290508110156126bd57600073ffffffffffffffffffffffffffffffffffffffff1683838381811061260957fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156126b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f61646d696e20697320656d70747900000000000000000000000000000000000081525060200191505060405180910390fd5b80806001019150506125da565b508181600391906126cf929190613336565b50600180819055505050565b60026001541415612754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600181905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156127ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f746f6b656e206973207a65726f2061646472657373000000000000000000000081525060200191505060405180910390fd5b60006005600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090506000809050600080600090505b838110156129b8578673ffffffffffffffffffffffffffffffffffffffff166005600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106128de57fe5b906000526020600020906002020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614801561299e5750856005600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061298a57fe5b906000526020600020906002020160010154145b156129ab57600192508091505b8080600101915050612864565b5081612a2c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f746f6b656e4944206e6f7420466f756e6400000000000000000000000000000081525060200191505060405180910390fd5b612a3733858361303c565b8573ffffffffffffffffffffffffffffffffffffffff166323b872dd3033886040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015612af257600080fd5b505af1158015612b06573d6000803e3d6000fd5b505050507f5088bc45f380ed0275b374e62bdb9498bfc6b73641204086e7919df7b1b42c7c868686604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a150505060018081905550505050565b60056020528260005260406000206020528160005260406000208181548110612bb157fe5b906000526020600020906002020160009250925050508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154905082565b60606003805480602002602001604051908101604052809291908181526020018280548015612c7b57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311612c31575b5050505050905090565b600080600090505b600480549050811015612d1c578273ffffffffffffffffffffffffffffffffffffffff1660048281548110612cbe57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415612d0f576001915050612d22565b8080600101915050612c8d565b50600090505b919050565b60006005600083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050905092915050565b612d8d613034565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612e4e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612ed4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061341a6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600090505b600380549050811015613029578273ffffffffffffffffffffffffffffffffffffffff1660038281548110612fcb57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561301c57600191505061302f565b8080600101915050612f9a565b50600090505b919050565b600033905090565b60006005600084815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050808210156132a65760008290505b60018203811015613203576005600085815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600182018154811061310b57fe5b90600052602060002090600202016005600086815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061317457fe5b90600052602060002090600202016000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001820154816001015590505080806001019150506130a2565b506005600084815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548061325d57fe5b6001900381819060005260206000209060020201600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160009055505090555b50505050565b828054828255906000526020600020908101928215613325579160200282015b828111156133245782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550916020019190600101906132cc565b5b50905061333291906133d6565b5090565b8280548282559060005260206000209081019282156133c5579160200282015b828111156133c457823573ffffffffffffffffffffffffffffffffffffffff168260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555091602001919060010190613356565b5b5090506133d291906133d6565b5090565b61341691905b8082111561341257600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506001016133dc565b5090565b9056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373a26469706673582212206b734bfd9a42cdd70358585a55c0e37c8c0115f458274f3fbc072b8b44cf73ad64736f6c63430006060033

Deployed ByteCode Sourcemap

43877:7078:0:-:0;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;43877:7078:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;9;2:12;45359:106:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;45359:106:0;;;;;;;;;;;;;;;;;43963:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;43963:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45935:546;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;45935:546:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;44003:26;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;44003:26:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;44701:357;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;44701:357:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;45473:431;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;45473:431:0;;;;;;;;;;27:11:-1;14;11:28;8:2;;;52:1;49;42:12;8:2;45473:431:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;45473:431:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;45473:431:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;45473:431:0;;;;;;;;;;;;;;;:::i;:::-;;46518:952;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;46518:952:0;;;;;;;;;;27:11:-1;14;11:28;8:2;;;52:1;49;42:12;8:2;46518:952:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;46518:952:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;46518:952:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;46518:952:0;;;;;;;;;;;;;;;;;27:11:-1;14;11:28;8:2;;;52:1;49;42:12;8:2;46518:952:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;46518:952:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;46518:952:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;46518:952:0;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;44038:30;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;44038:30:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;48422:644;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;48422:644:0;;;;;;;;;;;;;;;;;:::i;:::-;;40724:148;;;:::i;:::-;;49477:594;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;49477:594:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;49477:594:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;49477:594:0;;;;;;;;;;;;;;;;;;;40082:79;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;50235:329;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;50235:329:0;;;;;;;;;;27:11:-1;14;11:28;8:2;;;52:1;49;42:12;8:2;50235:329:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;50235:329:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;50235:329:0;;;;;;;;;;;;:::i;:::-;;47514:858;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;47514:858:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;44216:71;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;44216:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50572:98;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;50572:98:0;;;;;;;;;;;;;;;;;45066:285;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;45066:285:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;50079:148;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;50079:148:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;41027:244;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;41027:244:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;45359:106;45408:16;45444:13;45437:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45359:106;:::o;43963:31::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;45935:546::-;46034:7;42920:1;43526:7;;:19;;43518:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42920:1;43659:7;:18;;;;46088:4:::1;46062:30;;:22;46077:6;46062:14;:22::i;:::-;:30;;;46054:58;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;46168:10;46131:47;;46139:6;46131:23;;;46155:8;46131:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;46131:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;46131:33:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;46131:33:0;;;;;;;;;;;;;;;;:47;;;46123:80;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;46216:14;:21;46231:5;46216:21;;;;;;;;;;;:33;46238:10;46216:33;;;;;;;;;;;;;;;46255:25;;;;;;;;46263:6;46255:25;;;;;;46271:8;46255:25;;::::0;46216:65:::1;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;46216:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46302:6;46294:28;;;46323:10;46343:4;46350:8;46294:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;46294:65:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;46294:65:0;;;;46377:36;46389:6;46397:8;46407:5;46377:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46433:14;:21;46448:5;46433:21;;;;;;;;;;;:33;46455:10;46433:33;;;;;;;;;;;;;;;:40;;;;46426:47;;42876:1:::0;43838:7;:22;;;;45935:546;;;;;:::o;44003:26::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;44701:357::-;42920:1;43526:7;;:19;;43518:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42920:1;43659:7;:18;;;;44782:21:::1;44792:10;44782:9;:21::i;:::-;44774:65;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;44876:1;44858:20;;:6;:20;;;;44850:54;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;44947:5;44921:31;;:22;44936:6;44921:14;:22::i;:::-;:31;;;44917:134;;;44969:13;44988:6;44969:26;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;44969:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45015:24;45032:6;45015:24;;;;;;;;;;;;;;;;;;;;;;44917:134;42876:1:::0;43838:7;:22;;;;44701:357;:::o;45473:431::-;42920:1;43526:7;;:19;;43518:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42920:1;43659:7;:18;;;;45567:21:::1;45577:10;45567:9;:21::i;:::-;45559:65;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;45663:1;45643:10;:17;:21;45635:53;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;45715:14;45732:1:::0;45715:18:::1;;45709:149;45744:10;:17;45735:6;:26;45709:149;;;45825:1;45795:32;;:10;45806:6;45795:18;;;;;;;;;;;;;;:32;;;;45787:59;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;45763:8;;;;;;;45709:149;;;;45886:10;45870:13;:26;;;;;;;;;;;;:::i;:::-;;42876:1:::0;43838:7;:22;;;;45473:431;:::o;46518:952::-;46648:7;42920:1;43526:7;;:19;;43518:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42920:1;43659:7;:18;;;;46696:1:::1;46676:10;:17;:21;46668:53;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;46761:12;:19;46740:10;:17;:40;46732:78;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;46828:14;46845:1:::0;46828:18:::1;;46823:513;46857:10;:17;46848:6;:26;46823:513;;;46901:14;46918:10;46929:6;46918:18;;;;;;;;;;;;;;46901:35;;46951:16;46970:12;46983:6;46970:20;;;;;;;;;;;;;;46951:39;;47041:4;47015:30;;:22;47030:6;47015:14;:22::i;:::-;:30;;;47007:58;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;47125:10;47088:47;;47096:6;47088:23;;;47112:8;47088:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;47088:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;47088:33:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;47088:33:0;;;;;;;;;;;;;;;;:47;;;47080:80;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;47177:14;:21;47192:5;47177:21;;;;;;;;;;;:33;47199:10;47177:33;;;;;;;;;;;;;;;47216:25;;;;;;;;47224:6;47216:25;;;;;;47232:8;47216:25;;::::0;47177:65:::1;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;47177:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47267:6;47259:28;;;47288:10;47308:4;47315:8;47259:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;47259:65:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;47259:65:0;;;;46823:513;;46876:8;;;;;;;46823:513;;;;47353:49;47370:10;47382:12;47396:5;47353:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;47353:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;47353:49:0;;;;;;;;;;;;;;;;;;;;47422:14;:21;47437:5;47422:21;;;;;;;;;;;:33;47444:10;47422:33;;;;;;;;;;;;;;;:40;;;;47415:47;;42876:1:::0;43838:7;:22;;;;46518:952;;;;;:::o;44038:30::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;48422:644::-;42920:1;43526:7;;:19;;43518:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42920:1;43659:7;:18;;;;48495:12:::1;48510:14;:21;48525:5;48510:21;;;;;;;;;;;:33;48532:10;48510:33;;;;;;;;;;;;;;;:40;;;;48495:55;;48576:1;48569:4;:8;48561:48;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;48627:11;48641:4;48627:18;;48622:394;48653:1;48647:3;:7;48622:394;;;48678:14;48699:1;48695:3;:5;48678:22;;48715:14;48732;:21;48747:5;48732:21;;;;;;;;;;;:33;48754:10;48732:33;;;;;;;;;;;;;;;48766:6;48732:41;;;;;;;;;;;;;;;;;;:50;;;;;;;;;;;;48715:67;;48797:16;48816:14;:21;48831:5;48816:21;;;;;;;;;;;:33;48838:10;48816:33;;;;;;;;;;;;;;;48850:6;48816:41;;;;;;;;;;;;;;;;;;:52;;;48797:71;;48885:14;:21;48900:5;48885:21;;;;;;;;;;;:33;48907:10;48885:33;;;;;;;;;;;;;;;:39;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;48947:6;48939:28;;;48976:4;48983:10;48995:8;48939:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;48939:65:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;48939:65:0;;;;48622:394;;;48656:5;;;;;;;;48622:394;;;;49033:25;49052:5;49033:25;;;;;;;;;;;;;;;;;;43690:1;42876::::0;43838:7;:22;;;;48422:644;:::o;40724:148::-;40304:12;:10;:12::i;:::-;40294:22;;:6;;;;;;;;;;;:22;;;40286:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40831:1:::1;40794:40;;40815:6;::::0;::::1;;;;;;;;;40794:40;;;;;;;;;;;;40862:1;40845:6:::0;::::1;:19;;;;;;;;;;;;;;;;;;40724:148::o:0;49477:594::-;49556:16;49574;49603:12;49618:14;:21;49633:5;49618:21;;;;;;;;;;;:28;49640:5;49618:28;;;;;;;;;;;;;;;:35;;;;49603:50;;49666:27;49710:4;49696:19;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;49696:19:0;;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;125:4;109:14;101:6;88:42;156:4;148:6;144:17;134:27;;0:165;49696:19:0;;;;49666:49;;49726:29;49772:4;49758:19;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;49758:19:0;;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;125:4;109:14;101:6;88:42;156:4;148:6;144:17;134:27;;0:165;49758:19:0;;;;49726:51;;49795:14;49812:1;49795:18;;49790:228;49824:4;49815:6;:13;49790:228;;;49876:14;:21;49891:5;49876:21;;;;;;;;;;;:28;49898:5;49876:28;;;;;;;;;;;;;;;49905:6;49876:36;;;;;;;;;;;;;;;;;;:45;;;;;;;;;;;;49855:10;49866:6;49855:18;;;;;;;;;;;;;:66;;;;;;;;;;;49959:14;:21;49974:5;49959:21;;;;;;;;;;;:28;49981:5;49959:28;;;;;;;;;;;;;;;49988:6;49959:36;;;;;;;;;;;;;;;;;;:47;;;49936:12;49949:6;49936:20;;;;;;;;;;;;;:70;;;;;49830:8;;;;;;;49790:228;;;;50038:10;50050:12;50030:33;;;;;;;49477:594;;;;;:::o;40082:79::-;40120:7;40147:6;;;;;;;;;;;40140:13;;40082:79;:::o;50235:329::-;40304:12;:10;:12::i;:::-;40294:22;;:6;;;;;;;;;;;:22;;;40286:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42920:1:::1;43526:7;;:19;;43518:63;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;42920:1;43659:7;:18;;;;50349:1:::2;50334:5;;:12;;:16;50326:43;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;50396:14;50413:1:::0;50396:18:::2;;50390:139;50425:5;;:12;;50416:6;:21;50390:139;;;50496:1;50471:27;;:5;;50477:6;50471:13;;;;;;;;;;;;;;;:27;;;;50463:54;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;50439:8;;;;;;;50390:139;;;;50551:5;;50539:9;:17;;;;;;;:::i;:::-;;42876:1:::1;43838:7:::0;:22:::1;;;;50235:329:::0;;:::o;47514:858::-;42920:1;43526:7;;:19;;43518:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42920:1;43659:7;:18;;;;47643:1:::1;47625:20;;:6;:20;;;;47617:54;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;47684:12;47699:14;:21;47714:5;47699:21;;;;;;;;;;;:33;47721:10;47699:33;;;;;;;;;;;;;;;:40;;;;47684:55;;47752:13;47768:5:::0;47752:21:::1;;47784:19;47821:14:::0;47838:1:::1;47821:18;;47816:303;47850:4;47841:6;:13;47816:303;;;47940:6;47886:60;;:14;:21;47901:5;47886:21;;;;;;;;;;;:33;47908:10;47886:33;;;;;;;;;;;;;;;47920:6;47886:41;;;;;;;;;;;;;;;;;;:50;;;;;;;;;;;;:60;;;47885:132;;;;;48008:8;47952:14;:21;47967:5;47952:21;;;;;;;;;;;:33;47974:10;47952:33;;;;;;;;;;;;;;;47986:6;47952:41;;;;;;;;;;;;;;;;;;:52;;;:64;47885:132;47881:227;;;48049:4;48038:15;;48086:6;48072:20;;47881:227;47856:8;;;;;;;47816:303;;;;48139:8;48131:38;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;48180:52;48201:10;48213:5;48220:11;48180:20;:52::i;:::-;48251:6;48243:28;;;48280:4;48287:10;48299:8;48243:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;48243:65:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;48243:65:0;;;;48326:38;48340:6;48348:8;48358:5;48326:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43690:1;;;42876::::0;43838:7;:22;;;;47514:858;;;:::o;44216:71::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;50572:98::-;50617:16;50653:9;50646:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50572:98;:::o;45066:285::-;45127:4;45150:14;45167:1;45150:18;;45144:177;45179:13;:20;;;;45170:6;:29;45144:177;;;45256:6;45231:31;;:13;45245:6;45231:21;;;;;;;;;;;;;;;;;;;;;;;;;:31;;;45227:83;;;45290:4;45283:11;;;;;45227:83;45201:8;;;;;;;45144:177;;;;45338:5;45331:12;;45066:285;;;;:::o;50079:148::-;50157:7;50184:14;:21;50199:5;50184:21;;;;;;;;;;;:28;50206:5;50184:28;;;;;;;;;;;;;;;:35;;;;50177:42;;50079:148;;;;:::o;41027:244::-;40304:12;:10;:12::i;:::-;40294:22;;:6;;;;;;;;;;;:22;;;40286:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41136:1:::1;41116:22;;:8;:22;;;;41108:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41226:8;41197:38;;41218:6;::::0;::::1;;;;;;;;;41197:38;;;;;;;;;;;;41255:8;41246:6;::::0;:17:::1;;;;;;;;;;;;;;;;;;41027:244:::0;:::o;50678:272::-;50736:4;50759:14;50776:1;50759:18;;50753:167;50788:9;:16;;;;50779:6;:25;50753:167;;;50855:6;50834:27;;:9;50844:6;50834:17;;;;;;;;;;;;;;;;;;;;;;;;;:27;;;50830:79;;;50889:4;50882:11;;;;;50830:79;50806:8;;;;;;;50753:167;;;;50937:5;50930:12;;50678:272;;;;:::o;759:106::-;812:15;847:10;840:17;;759:106;:::o;49074:395::-;49167:12;49182:14;:21;49197:5;49182:21;;;;;;;;;;;:28;49204:5;49182:28;;;;;;;;;;;;;;;:35;;;;49167:50;;49240:4;49233;:11;49230:232;;;49266:9;49278:4;49266:16;;49261:141;49293:1;49288:4;:6;49284:1;:10;49261:141;;;49353:14;:21;49368:5;49353:21;;;;;;;;;;;:28;49375:5;49353:28;;;;;;;;;;;;;;;49384:1;49382;:3;49353:33;;;;;;;;;;;;;;;;;;49319:14;:21;49334:5;49319:21;;;;;;;;;;;:28;49341:5;49319:28;;;;;;;;;;;;;;;49348:1;49319:31;;;;;;;;;;;;;;;;;;:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49296:3;;;;;;;49261:141;;;;49416:14;:21;49431:5;49416:21;;;;;;;;;;;:28;49438:5;49416:28;;;;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49230:232;49074:395;;;;:::o;43877:7078::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

ipfs://6b734bfd9a42cdd70358585a55c0e37c8c0115f458274f3fbc072b8b44cf73ad
Block Transaction Gas Used Reward
Age Block Fee Address Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading