ETH Price: $2,605.81 (+0.61%)

Token

BitStake (BitStake)
 

Overview

Max Total Supply

500 BitStake

Holders

53

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

0x1b1289c299d07deac5cfc058cbee5fe7ba045bd4
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
BitStake

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-06-16
*/

// SPDX-License-Identifier: MIT
// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

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


// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

// File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol


// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;


/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

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


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

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


// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

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

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

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

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(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");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

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


// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @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
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

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

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

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

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

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

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

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

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

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

// File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;



/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

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


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

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


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


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

// File: @openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.0;


/**
 * @dev _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {
    /**
     * @dev Handles the receipt of a single ERC1155 token type. This function is
     * called at the end of a `safeTransferFrom` after the balance has been updated.
     *
     * NOTE: To accept the transfer, this must return
     * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
     * (i.e. 0xf23a6e61, or its own function selector).
     *
     * @param operator The address which initiated the transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param id The ID of the token being transferred
     * @param value The amount of tokens being transferred
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
     */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
     * @dev Handles the receipt of a multiple ERC1155 token types. This function
     * is called at the end of a `safeBatchTransferFrom` after the balances have
     * been updated.
     *
     * NOTE: To accept the transfer(s), this must return
     * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
     * (i.e. 0xbc197c81, or its own function selector).
     *
     * @param operator The address which initiated the batch transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param ids An array containing ids of each token being transferred (order and length must match values array)
     * @param values An array containing amounts of each token being transferred (order and length must match ids array)
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
     */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/contracts/token/ERC1155/IERC1155.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

// File: @openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface of the optional ERC1155MetadataExtension interface, as defined
 * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155MetadataURI is IERC1155 {
    /**
     * @dev Returns the URI for token type `id`.
     *
     * If the `\{id\}` substring is present in the URI, it must be replaced by
     * clients with the actual token type ID.
     */
    function uri(uint256 id) external view returns (string memory);
}

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


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/ERC1155.sol)

pragma solidity ^0.8.0;







/**
 * @dev Implementation of the basic standard multi-token.
 * See https://eips.ethereum.org/EIPS/eip-1155
 * Originally based on code by Enjin: https://github.com/enjin/erc-1155
 *
 * _Available since v3.1._
 */
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
    using Address for address;

    // Mapping from token ID to account balances
    mapping(uint256 => mapping(address => uint256)) private _balances;

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

    // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
    string private _uri;

    /**
     * @dev See {_setURI}.
     */
    constructor(string memory uri_) {
        _setURI(uri_);
    }

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

    /**
     * @dev See {IERC1155MetadataURI-uri}.
     *
     * This implementation returns the same URI for *all* token types. It relies
     * on the token type ID substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * Clients calling this function must replace the `\{id\}` substring with the
     * actual token type ID.
     */
    function uri(uint256) public view virtual override returns (string memory) {
        return _uri;
    }

    /**
     * @dev See {IERC1155-balanceOf}.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
        require(account != address(0), "ERC1155: balance query for the zero address");
        return _balances[id][account];
    }

    /**
     * @dev See {IERC1155-balanceOfBatch}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
        public
        view
        virtual
        override
        returns (uint256[] memory)
    {
        require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");

        uint256[] memory batchBalances = new uint256[](accounts.length);

        for (uint256 i = 0; i < accounts.length; ++i) {
            batchBalances[i] = balanceOf(accounts[i], ids[i]);
        }

        return batchBalances;
    }

    /**
     * @dev See {IERC1155-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

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

    /**
     * @dev See {IERC1155-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: caller is not owner nor approved"
        );
        _safeTransferFrom(from, to, id, amount, data);
    }

    /**
     * @dev See {IERC1155-safeBatchTransferFrom}.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: transfer caller is not owner nor approved"
        );
        _safeBatchTransferFrom(from, to, ids, amounts, data);
    }

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }
        _balances[id][to] += amount;

        emit TransferSingle(operator, from, to, id, amount);

        _afterTokenTransfer(operator, from, to, ids, amounts, data);

        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
            _balances[id][to] += amount;
        }

        emit TransferBatch(operator, from, to, ids, amounts);

        _afterTokenTransfer(operator, from, to, ids, amounts, data);

        _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
    }

    /**
     * @dev Sets a new URI for all token types, by relying on the token type ID
     * substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * By this mechanism, any occurrence of the `\{id\}` substring in either the
     * URI or any of the amounts in the JSON file at said URI will be replaced by
     * clients with the token type ID.
     *
     * For example, the `https://token-cdn-domain/\{id\}.json` URI would be
     * interpreted by clients as
     * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
     * for token type ID 0x4cce0.
     *
     * See {uri}.
     *
     * Because these URIs cannot be meaningfully represented by the {URI} event,
     * this function emits no events.
     */
    function _setURI(string memory newuri) internal virtual {
        _uri = newuri;
    }

    /**
     * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _mint(
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        _balances[id][to] += amount;
        emit TransferSingle(operator, address(0), to, id, amount);

        _afterTokenTransfer(operator, address(0), to, ids, amounts, data);

        _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _mintBatch(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; i++) {
            _balances[ids[i]][to] += amounts[i];
        }

        emit TransferBatch(operator, address(0), to, ids, amounts);

        _afterTokenTransfer(operator, address(0), to, ids, amounts, data);

        _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
    }

    /**
     * @dev Destroys `amount` tokens of token type `id` from `from`
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `from` must have at least `amount` tokens of token type `id`.
     */
    function _burn(
        address from,
        uint256 id,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC1155: burn from the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, from, address(0), ids, amounts, "");

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }

        emit TransferSingle(operator, from, address(0), id, amount);

        _afterTokenTransfer(operator, from, address(0), ids, amounts, "");
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     */
    function _burnBatch(
        address from,
        uint256[] memory ids,
        uint256[] memory amounts
    ) internal virtual {
        require(from != address(0), "ERC1155: burn from the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, address(0), ids, amounts, "");

        for (uint256 i = 0; i < ids.length; i++) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
        }

        emit TransferBatch(operator, from, address(0), ids, amounts);

        _afterTokenTransfer(operator, from, address(0), ids, amounts, "");
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits a {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC1155: setting approval status for self");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `id` and `amount` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {}

    /**
     * @dev Hook that is called after any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `id` and `amount` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {}

    function _doSafeTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
                if (response != IERC1155Receiver.onERC1155Received.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non ERC1155Receiver implementer");
            }
        }
    }

    function _doSafeBatchTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
                bytes4 response
            ) {
                if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non ERC1155Receiver implementer");
            }
        }
    }

    function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
        uint256[] memory array = new uint256[](1);
        array[0] = element;

        return array;
    }
}

// File: @openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)

pragma solidity ^0.8.0;


/**
 * @dev Extension of ERC1155 that adds tracking of total supply per id.
 *
 * Useful for scenarios where Fungible and Non-fungible tokens have to be
 * clearly identified. Note: While a totalSupply of 1 might mean the
 * corresponding is an NFT, there is no guarantees that no other token with the
 * same id are not going to be minted.
 */
abstract contract ERC1155Supply is ERC1155 {
    mapping(uint256 => uint256) private _totalSupply;

    /**
     * @dev Total amount of tokens in with a given id.
     */
    function totalSupply(uint256 id) public view virtual returns (uint256) {
        return _totalSupply[id];
    }

    /**
     * @dev Indicates whether any token exist with a given id, or not.
     */
    function exists(uint256 id) public view virtual returns (bool) {
        return ERC1155Supply.totalSupply(id) > 0;
    }

    /**
     * @dev See {ERC1155-_beforeTokenTransfer}.
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual override {
        super._beforeTokenTransfer(operator, from, to, ids, amounts, data);

        if (from == address(0)) {
            for (uint256 i = 0; i < ids.length; ++i) {
                _totalSupply[ids[i]] += amounts[i];
            }
        }

        if (to == address(0)) {
            for (uint256 i = 0; i < ids.length; ++i) {
                uint256 id = ids[i];
                uint256 amount = amounts[i];
                uint256 supply = _totalSupply[id];
                require(supply >= amount, "ERC1155: burn amount exceeds totalSupply");
                unchecked {
                    _totalSupply[id] = supply - amount;
                }
            }
        }
    }
}

// File: Bit.sol


pragma solidity ^0.8.4;








library StringLibrary {

    function castString(string memory _a, string memory _b, string memory _c) internal pure returns (string memory) {
        bytes memory _ba = bytes(_a);
        bytes memory _bb = bytes(_b);
        bytes memory _bc = bytes(_c);
        bytes memory bbb = new bytes(_ba.length + _bb.length + _bc.length);
        uint k = 0;
        for (uint i = 0; i < _ba.length; i++) bbb[k++] = _ba[i];
        for (uint i = 0; i < _bb.length; i++) bbb[k++] = _bb[i];
        for (uint i = 0; i < _bc.length; i++) bbb[k++] = _bc[i];
        return string(bbb);
    }
    
}

contract BitStake is ERC1155, Ownable, ERC1155Supply {

    using SafeERC20 for IERC20;
    using StringLibrary for string;
    using Strings for uint256;

    mapping(uint256 => string) private _tokenURIs;

    IERC20 public usdt;
    IERC20 public feeToken;

    address public usdtContract;
    address public feeTokenContract;

    address public collectNFT;
    address public collectUSDT;
    address public collectFeeToken;

    /**
     * @param _usdt USDT地址
     * @param _feeToken 手续费Token地址
     */
    constructor(
        address _usdt,
        address _feeToken,
        address _collectNFT,
        address _collectUSDT,
        address _collectFeeToken
    ) ERC1155("http://nft.ahjsc.top/") {
        require(
            _usdt != address(0) && _feeToken != address(0),
            "address is zero"
        );

        usdt = IERC20(_usdt);
        feeToken = IERC20(_feeToken);
        usdtContract=_usdt;
        feeTokenContract=_feeToken;
        collectNFT = _collectNFT;
        collectUSDT = _collectUSDT;
        collectFeeToken = _collectFeeToken;

    }

    string private _name = "BitStake";
    string private _symbol = "BitStake";

    function name() public view virtual returns (string memory) {
        return _name;
    }

    function symbol() public view virtual returns (string memory) {
        return _symbol;
    }


    function setFor(uint256 startId,uint256 endId,address _myAddress) public onlyOwner{

        string memory  startString ="http://nft.ahjsc.top/bitstake/json/";
        string memory  endString =".json";

        for(uint i=startId;i< endId;i++){

            setURI(i,startString.castString(i.toString(),endString));
            mint(_myAddress,i,1,"0x00");
            
        }

    }

    function uri(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        return _tokenURIs[tokenId];
    }

    function setURI(uint256 tokenId, string memory newuri) public onlyOwner {
        _tokenURIs[tokenId] = newuri;
    }

    /**
     * @dev 设置收集Token的钱包地址
     * @param collectAddress 收集各个Token的钱包地址,0-收集NFT的地址,1-收集USDT的地址,2-收集手续费的地址
     */
    function setCollectAddress(address[] memory collectAddress)
        external
        onlyOwner
    {
        require(collectAddress.length == 3, "address length error");
        collectNFT = collectAddress[0];
        collectUSDT = collectAddress[1];
        collectFeeToken = collectAddress[2];
    }

    function lookCollectAddress() public view virtual returns (address _nftAddress,address _usdtAddress,address _feeAddress) {
        return (collectNFT,collectUSDT,collectFeeToken);
    }

    /**
     * @dev 设置USDT和FeeToken地址
     * @param _usdt USDT地址
     * @param _feeToken X币地址
     */
    function setUAndFeeToken(address _usdt, address _feeToken)
        external
        onlyOwner
    {
        require(
            _usdt != address(0) && _feeToken != address(0),
            "address is zero"
        );
        usdtContract = _usdt;
        feeTokenContract = _feeToken;
        usdt = IERC20(_usdt);
        feeToken = IERC20(_feeToken);
    }

    function lookUAndFeeToken() public view virtual returns (address _usdtContract,address _feeTokenContract) {
        return (usdtContract,feeTokenContract);
    }

    function mint(
        address account,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public onlyOwner {
        _mint(account, id, amount, data);
    }

    function mintBatch(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public onlyOwner {
        _mintBatch(to, ids, amounts, data);
    }

    function bulkMint(
        address[] memory to,
        uint256 id,
        bytes memory data
    ) public onlyOwner {
        uint256 n = to.length;

        for (uint256 i = 0; i < n; ) {
            _mint(to[i], id, 1, data);

            unchecked {
                ++i;
            }
        }
    }

    // The following functions are overrides required by Solidity.

    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal override(ERC1155, ERC1155Supply) {
        super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
    }

    function burn(
        address account,
        uint256 id,
        uint256 value
    ) public virtual {
        require(
            account == _msgSender() || isApprovedForAll(account, _msgSender()),
            "ERC1155: caller is not owner nor approved"
        );

        _burn(account, id, value);
    }

    function burnBatch(
        address account,
        uint256[] memory ids,
        uint256[] memory values
    ) public virtual {
        require(
            account == _msgSender() || isApprovedForAll(account, _msgSender()),
            "ERC1155: caller is not owner nor approved"
        );

        _burnBatch(account, ids, values);
    }

    using ECDSA for bytes32;
    string signCotent = "HelloWorld";

    function setSigner(string memory _signCotent) public {
        signCotent = _signCotent;
    }

    function getSigner() public view returns (string memory) {
        return signCotent;
    }

    function isMessageValid(bytes memory _signature, address _myAddress)
        public
        view
        returns (address, bool)
    {
        // 1. 对签名信息进行 abi 编码
        bytes memory abiEncode = abi.encodePacked(signCotent);

        // 2. 再进行 keccak256 Hash运算
        bytes32 messagehash = keccak256(abiEncode);

        // 3. 添加前缀,可以将计算出的以太坊特定的签名。这可以防止恶意 DApp 可以签署任意数据(例如交易)并使用签名来冒充受害者的滥用行为。
        bytes32 ethSignedMessageHash = ECDSA.toEthSignedMessageHash(
            messagehash
        );

        // 4. 从签名恢复地址
        address signer = ECDSA.recover(ethSignedMessageHash, _signature);

        if (_myAddress == signer) {
            return (signer, true);
        } else {
            return (signer, false);
        }
    }

    /**
     * @dev 抵押NFT(卖NFT)
     * @param from NFT所在地址
     * @param id tokenId
     * @param amount 数量
     * @param amountF 手续费Token收取数量(X币数量)
     */
    function depositNFT(
        address from,
        uint256 id,
        uint256 amount,
        uint256 amountF
    ) public {
        // require(
        //     feeToken.balanceOf(from) >= amountF,
        //     "Insufficient FeeToken Quantity"
        // );
        // require(
        //     feeToken.allowance(from, address(this)) >= amountF,
        //     "transfer amount exceeds allowance"
        // );
        safeTransferFrom(from, collectNFT, id, amount, "");
        feeToken.safeTransferFrom(from, collectFeeToken, amountF);
    }

    /**
     * @dev 购买NFT
	 * @param amountU 需要支付USDT数量
	 * @param amountF 需要支付X币数量
     */
    function buyNFT(
        uint256 amountU,
        uint256 amountF
    ) public  {

        address owner = _msgSender();
        
        //     require(
        //         usdt.balanceOf(owner) >= amountU,
        //         "Insufficient USDT Quantity"
        //     );
        //    require(
        //         feeToken.balanceOf(owner) >= amountF,
        //         "Insufficient FeeToken Quantity"
        //     );
        //     require(
        //         usdt.allowance(owner, address(this)) >= amountU,
        //         "usdt transfer amount exceeds allowance"
        //     );
        //     require(
        //         feeToken.allowance(owner, address(this)) >= amountF,
        //         "feeToken transfer amount exceeds allowance"
        //     );

        usdt.safeTransferFrom(owner, collectUSDT, amountU);
        feeToken.safeTransferFrom(owner, collectFeeToken, amountF);

    }

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_usdt","type":"address"},{"internalType":"address","name":"_feeToken","type":"address"},{"internalType":"address","name":"_collectNFT","type":"address"},{"internalType":"address","name":"_collectUSDT","type":"address"},{"internalType":"address","name":"_collectFeeToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"to","type":"address[]"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"bulkMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"burnBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountU","type":"uint256"},{"internalType":"uint256","name":"amountF","type":"uint256"}],"name":"buyNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectFeeToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collectNFT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collectUSDT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"amountF","type":"uint256"}],"name":"depositNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeTokenContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSigner","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"address","name":"_myAddress","type":"address"}],"name":"isMessageValid","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lookCollectAddress","outputs":[{"internalType":"address","name":"_nftAddress","type":"address"},{"internalType":"address","name":"_usdtAddress","type":"address"},{"internalType":"address","name":"_feeAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lookUAndFeeToken","outputs":[{"internalType":"address","name":"_usdtContract","type":"address"},{"internalType":"address","name":"_feeTokenContract","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mintBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"collectAddress","type":"address[]"}],"name":"setCollectAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startId","type":"uint256"},{"internalType":"uint256","name":"endId","type":"uint256"},{"internalType":"address","name":"_myAddress","type":"address"}],"name":"setFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_signCotent","type":"string"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_usdt","type":"address"},{"internalType":"address","name":"_feeToken","type":"address"}],"name":"setUAndFeeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"newuri","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdt","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdtContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60c060405260086080819052674269745374616b6560c01b60a09081526200002b91600d919062000256565b50604080518082019091526008808252674269745374616b6560c01b60209092019182526200005d91600e9162000256565b5060408051808201909152600a8082526912195b1b1bd5dbdc9b1960b21b60209092019182526200009191600f9162000256565b503480156200009f57600080fd5b5060405162003b4638038062003b46833981016040819052620000c29162000319565b60408051808201909152601581527f687474703a2f2f6e66742e61686a73632e746f702f000000000000000000000060208201526200010181620001eb565b506200010d3362000204565b6001600160a01b038516158015906200012e57506001600160a01b03841615155b620001715760405162461bcd60e51b815260206004820152600f60248201526e61646472657373206973207a65726f60881b604482015260640160405180910390fd5b600680546001600160a01b039687166001600160a01b031991821681179092556007805496881696821687179055600880548216909217909155600980548216909517909455600a805493861693851693909317909255600b8054918516918416919091179055600c8054919093169116179055620003c5565b80516200020090600290602084019062000256565b5050565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620002649062000388565b90600052602060002090601f016020900481019282620002885760008555620002d3565b82601f10620002a357805160ff1916838001178555620002d3565b82800160010185558215620002d3579182015b82811115620002d3578251825591602001919060010190620002b6565b50620002e1929150620002e5565b5090565b5b80821115620002e15760008155600101620002e6565b80516001600160a01b03811681146200031457600080fd5b919050565b600080600080600060a0868803121562000331578081fd5b6200033c86620002fc565b94506200034c60208701620002fc565b93506200035c60408701620002fc565b92506200036c60608701620002fc565b91506200037c60808701620002fc565b90509295509295909350565b600181811c908216806200039d57607f821691505b60208210811415620003bf57634e487b7160e01b600052602260045260246000fd5b50919050565b61377180620003d56000396000f3fe608060405234801561001057600080fd5b50600436106102315760003560e01c8063731133e911610130578063d93df696116100b8578063f242432a1161007c578063f242432a14610569578063f2fde38b1461057c578063f5298aca1461058f578063f6c79283146105a2578063fc4d2620146105b557600080fd5b8063d93df696146104c1578063e985e9c5146104d4578063ea6f7a1214610510578063ec0e7fb614610543578063f092ebf71461055657600080fd5b806395d89b41116100ff57806395d89b4114610460578063a22cb46514610468578063b779e9871461047b578063bcb121031461048e578063bd85b039146104a157600080fd5b8063731133e9146104215780637ac3c02f14610434578063862440e21461043c5780638da5cb5b1461044f57600080fd5b80633b91ac24116101be578063611509231161018257806361150923146103cd578063647846a5146103e05780636b20c454146103f35780636d07904514610406578063715018a61461041957600080fd5b80633b91ac241461033f578063479469f9146103525780634e1273f4146103785780634f558e7914610398578063576d3e74146103ba57600080fd5b80631d85bf03116102055780631d85bf03146102a75780631f7fdffa146102bc5780632c38ba0c146102cf5780632eb2c2d6146103015780632f48ab7d1461031457600080fd5b8062fdd58e1461023657806301ffc9a71461025c57806306fdde031461027f5780630e89341c14610294575b600080fd5b610249610244366004612d36565b6105c8565b6040519081526020015b60405180910390f35b61026f61026a366004612f28565b61065f565b6040519015158152602001610253565b6102876106b1565b6040516102539190613271565b6102876102a2366004612fd4565b610743565b6102ba6102b5366004613026565b6107e5565b005b6102ba6102ca366004612c6c565b61082a565b6102e26102dd366004612f60565b610866565b604080516001600160a01b039093168352901515602083015201610253565b6102ba61030f366004612af5565b61093f565b600654610327906001600160a01b031681565b6040516001600160a01b039091168152602001610253565b600a54610327906001600160a01b031681565b600854600954604080516001600160a01b03938416815292909116602083015201610253565b61038b610386366004612e4d565b6109d6565b6040516102539190613230565b61026f6103a6366004612fd4565b600090815260046020526040902054151590565b600c54610327906001600160a01b031681565b600854610327906001600160a01b031681565b600754610327906001600160a01b031681565b6102ba610401366004612bfc565b610b37565b600954610327906001600160a01b031681565b6102ba610b7a565b6102ba61042f366004612d91565b610bb0565b610287610be6565b6102ba61044a366004612fec565b610bf5565b6003546001600160a01b0316610327565b610287610c3e565b6102ba610476366004612d00565b610c4d565b6102ba610489366004612de3565b610c5c565b600b54610327906001600160a01b031681565b6102496104af366004612fd4565b60009081526004602052604090205490565b6102ba6104cf366004612e1b565b610cac565b61026f6104e2366004612ac3565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205460ff1690565b600a54600b54600c54604080516001600160a01b0394851681529284166020840152921691810191909152606001610253565b6102ba610551366004612fa2565b610e0e565b6102ba610564366004612ac3565b610e21565b6102ba610577366004612b9a565b610ef0565b6102ba61058a366004612aa9565b610f35565b6102ba61059d366004612d5f565b610fd0565b6102ba6105b0366004612ead565b611013565b6102ba6105c3366004613047565b611086565b60006001600160a01b0383166106395760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b60648201526084015b60405180910390fd5b506000908152602081815260408083206001600160a01b03949094168352929052205490565b60006001600160e01b03198216636cdb3d1360e11b148061069057506001600160e01b031982166303a24d0760e21b145b806106ab57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600d80546106c09061357b565b80601f01602080910402602001604051908101604052809291908181526020018280546106ec9061357b565b80156107395780601f1061070e57610100808354040283529160200191610739565b820191906000526020600020905b81548152906001019060200180831161071c57829003601f168201915b5050505050905090565b60008181526005602052604090208054606091906107609061357b565b80601f016020809104026020016040519081016040528092919081815260200182805461078c9061357b565b80156107d95780601f106107ae576101008083540402835291602001916107d9565b820191906000526020600020905b8154815290600101906020018083116107bc57829003601f168201915b50505050509050919050565b600b546006543391610806916001600160a01b03908116918491168661114f565b600c54600754610825916001600160a01b03918216918491168561114f565b505050565b6003546001600160a01b031633146108545760405162461bcd60e51b81526004016106309061342b565b610860848484846111a9565b50505050565b6000806000600f60405160200161087d91906130fd565b60408051601f198184030181529190528051602082012090915060006108f0826040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905060006108fe828961131f565b9050806001600160a01b0316876001600160a01b031614156109295794506001935061093892505050565b94506000935061093892505050565b9250929050565b6001600160a01b03851633148061095b575061095b85336104e2565b6109c25760405162461bcd60e51b815260206004820152603260248201527f455243313135353a207472616e736665722063616c6c6572206973206e6f74206044820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b6064820152608401610630565b6109cf858585858561133b565b5050505050565b60608151835114610a3b5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b6064820152608401610630565b600083516001600160401b03811115610a6457634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610a8d578160200160208202803683370190505b50905060005b8451811015610b2f57610af4858281518110610abf57634e487b7160e01b600052603260045260246000fd5b6020026020010151858381518110610ae757634e487b7160e01b600052603260045260246000fd5b60200260200101516105c8565b828281518110610b1457634e487b7160e01b600052603260045260246000fd5b6020908102919091010152610b28816135e2565b9050610a93565b509392505050565b6001600160a01b038316331480610b535750610b5383336104e2565b610b6f5760405162461bcd60e51b815260040161063090613310565b6108258383836114f9565b6003546001600160a01b03163314610ba45760405162461bcd60e51b81526004016106309061342b565b610bae60006116b1565b565b6003546001600160a01b03163314610bda5760405162461bcd60e51b81526004016106309061342b565b61086084848484611703565b6060600f80546106c09061357b565b6003546001600160a01b03163314610c1f5760405162461bcd60e51b81526004016106309061342b565b60008281526005602090815260409091208251610825928401906128a4565b6060600e80546106c09061357b565b610c583383836117ec565b5050565b610c8d84600a60009054906101000a90046001600160a01b0316858560405180602001604052806000815250610ef0565b600c54600754610860916001600160a01b03918216918791168461114f565b6003546001600160a01b03163314610cd65760405162461bcd60e51b81526004016106309061342b565b8051600314610d1e5760405162461bcd60e51b815260206004820152601460248201527330b2323932b9b9903632b733ba341032b93937b960611b6044820152606401610630565b80600081518110610d3f57634e487b7160e01b600052603260045260246000fd5b6020026020010151600a60006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080600181518110610d8e57634e487b7160e01b600052603260045260246000fd5b6020026020010151600b60006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080600281518110610ddd57634e487b7160e01b600052603260045260246000fd5b6020026020010151600c60006101000a8154816001600160a01b0302191690836001600160a01b0316021790555050565b8051610c5890600f9060208401906128a4565b6003546001600160a01b03163314610e4b5760405162461bcd60e51b81526004016106309061342b565b6001600160a01b03821615801590610e6b57506001600160a01b03811615155b610ea95760405162461bcd60e51b815260206004820152600f60248201526e61646472657373206973207a65726f60881b6044820152606401610630565b600880546001600160a01b039384166001600160a01b0319918216811790925560098054939094169281168317909355600680548416909117905560078054909216179055565b6001600160a01b038516331480610f0c5750610f0c85336104e2565b610f285760405162461bcd60e51b815260040161063090613310565b6109cf85858585856118cd565b6003546001600160a01b03163314610f5f5760405162461bcd60e51b81526004016106309061342b565b6001600160a01b038116610fc45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610630565b610fcd816116b1565b50565b6001600160a01b038316331480610fec5750610fec83336104e2565b6110085760405162461bcd60e51b815260040161063090613310565b610825838383611a05565b6003546001600160a01b0316331461103d5760405162461bcd60e51b81526004016106309061342b565b825160005b818110156109cf5761107e85828151811061106d57634e487b7160e01b600052603260045260246000fd5b602002602001015185600186611703565b600101611042565b6003546001600160a01b031633146110b05760405162461bcd60e51b81526004016106309061342b565b600060405180606001604052806023815260200161371960239139604080518082019091526005815264173539b7b760d91b6020820152909150845b848110156111475761110c8161044a61110484611b1d565b869086611c3e565b61113584826001604051806040016040528060048152602001630307830360e41b815250610bb0565b8061113f816135e2565b9150506110ec565b505050505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610860908590611e78565b6001600160a01b0384166111cf5760405162461bcd60e51b8152600401610630906134a8565b81518351146111f05760405162461bcd60e51b815260040161063090613460565b3361120081600087878787611f4a565b60005b84518110156112b75783818151811061122c57634e487b7160e01b600052603260045260246000fd5b602002602001015160008087848151811061125757634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b03168152602001908152602001600020600082825461129f919061350c565b909155508190506112af816135e2565b915050611203565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051611308929190613243565b60405180910390a46109cf81600087878787611f58565b600080600061132e85856120c3565b91509150610b2f81612130565b815183511461135c5760405162461bcd60e51b815260040161063090613460565b6001600160a01b0384166113825760405162461bcd60e51b815260040161063090613359565b33611391818787878787611f4a565b60005b84518110156114935760008582815181106113bf57634e487b7160e01b600052603260045260246000fd5b6020026020010151905060008583815181106113eb57634e487b7160e01b600052603260045260246000fd5b602090810291909101810151600084815280835260408082206001600160a01b038e16835290935291909120549091508181101561143b5760405162461bcd60e51b8152600401610630906133e1565b6000838152602081815260408083206001600160a01b038e8116855292528083208585039055908b1682528120805484929061147890849061350c565b925050819055505050508061148c906135e2565b9050611394565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516114e3929190613243565b60405180910390a4611147818787878787611f58565b6001600160a01b03831661151f5760405162461bcd60e51b81526004016106309061339e565b80518251146115405760405162461bcd60e51b815260040161063090613460565b600033905061156381856000868660405180602001604052806000815250611f4a565b60005b835181101561164457600084828151811061159157634e487b7160e01b600052603260045260246000fd5b6020026020010151905060008483815181106115bd57634e487b7160e01b600052603260045260246000fd5b602090810291909101810151600084815280835260408082206001600160a01b038c16835290935291909120549091508181101561160d5760405162461bcd60e51b8152600401610630906132cc565b6000928352602083815260408085206001600160a01b038b168652909152909220910390558061163c816135e2565b915050611566565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051611695929190613243565b60405180910390a4604080516020810190915260009052610860565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0384166117295760405162461bcd60e51b8152600401610630906134a8565b33600061173585612331565b9050600061174285612331565b905061175383600089858589611f4a565b6000868152602081815260408083206001600160a01b038b1684529091528120805487929061178390849061350c565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46117e38360008989898961238a565b50505050505050565b816001600160a01b0316836001600160a01b031614156118605760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b6064820152608401610630565b6001600160a01b03838116600081815260016020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0384166118f35760405162461bcd60e51b815260040161063090613359565b3360006118ff85612331565b9050600061190c85612331565b905061191c838989858589611f4a565b6000868152602081815260408083206001600160a01b038c1684529091529020548581101561195d5760405162461bcd60e51b8152600401610630906133e1565b6000878152602081815260408083206001600160a01b038d8116855292528083208985039055908a1682528120805488929061199a90849061350c565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46119fa848a8a8a8a8a61238a565b505050505050505050565b6001600160a01b038316611a2b5760405162461bcd60e51b81526004016106309061339e565b336000611a3784612331565b90506000611a4484612331565b9050611a6483876000858560405180602001604052806000815250611f4a565b6000858152602081815260408083206001600160a01b038a16845290915290205484811015611aa55760405162461bcd60e51b8152600401610630906132cc565b6000868152602081815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46040805160208101909152600090526117e3565b606081611b415750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611b6b5780611b55816135e2565b9150611b649050600a83613524565b9150611b45565b6000816001600160401b03811115611b9357634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611bbd576020820181803683370190505b5090505b8415611c3657611bd2600183613538565b9150611bdf600a866135fd565b611bea90603061350c565b60f81b818381518110611c0d57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350611c2f600a86613524565b9450611bc1565b949350505050565b8051825184516060928692869286926000929091611c5c919061350c565b611c66919061350c565b6001600160401b03811115611c8b57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611cb5576020820181803683370190505b5090506000805b8551811015611d4857858181518110611ce557634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b0319168383611cff816135e2565b945081518110611d1f57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535080611d40816135e2565b915050611cbc565b5060005b8451811015611dd857848181518110611d7557634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b0319168383611d8f816135e2565b945081518110611daf57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535080611dd0816135e2565b915050611d4c565b5060005b8351811015611e6857838181518110611e0557634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b0319168383611e1f816135e2565b945081518110611e3f57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535080611e60816135e2565b915050611ddc565b50909450505050505b9392505050565b6000611ecd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166124549092919063ffffffff16565b8051909150156108255780806020019051810190611eeb9190612f0c565b6108255760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610630565b611147868686868686612463565b6001600160a01b0384163b156111475760405163bc197c8160e01b81526001600160a01b0385169063bc197c8190611f9c9089908990889088908890600401613198565b602060405180830381600087803b158015611fb657600080fd5b505af1925050508015611fe6575060408051601f3d908101601f19168201909252611fe391810190612f44565b60015b61209357611ff2613653565b806308c379a0141561202c575061200761366b565b80612012575061202e565b8060405162461bcd60e51b81526004016106309190613271565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e20455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b6064820152608401610630565b6001600160e01b0319811663bc197c8160e01b146117e35760405162461bcd60e51b815260040161063090613284565b6000808251604114156120fa5760208301516040840151606085015160001a6120ee87828585612614565b94509450505050610938565b8251604014156121245760208301516040840151612119868383612701565b935093505050610938565b50600090506002610938565b600081600481111561215257634e487b7160e01b600052602160045260246000fd5b141561215b5750565b600181600481111561217d57634e487b7160e01b600052602160045260246000fd5b14156121cb5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610630565b60028160048111156121ed57634e487b7160e01b600052602160045260246000fd5b141561223b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610630565b600381600481111561225d57634e487b7160e01b600052602160045260246000fd5b14156122b65760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610630565b60048160048111156122d857634e487b7160e01b600052602160045260246000fd5b1415610fcd5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610630565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061237957634e487b7160e01b600052603260045260246000fd5b602090810291909101015292915050565b6001600160a01b0384163b156111475760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906123ce90899089908890889088906004016131f6565b602060405180830381600087803b1580156123e857600080fd5b505af1925050508015612418575060408051601f3d908101601f1916820190925261241591810190612f44565b60015b61242457611ff2613653565b6001600160e01b0319811663f23a6e6160e01b146117e35760405162461bcd60e51b815260040161063090613284565b6060611c36848460008561273a565b6001600160a01b0385166125065760005b83518110156125045782818151811061249d57634e487b7160e01b600052603260045260246000fd5b6020026020010151600460008684815181106124c957634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060008282546124ee919061350c565b909155506124fd9050816135e2565b9050612474565b505b6001600160a01b0384166111475760005b83518110156117e357600084828151811061254257634e487b7160e01b600052603260045260246000fd5b60200260200101519050600084838151811061256e57634e487b7160e01b600052603260045260246000fd5b60200260200101519050600060046000848152602001908152602001600020549050818110156125f15760405162461bcd60e51b815260206004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f74604482015267616c537570706c7960c01b6064820152608401610630565b6000928352600460205260409092209103905561260d816135e2565b9050612517565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561264b57506000905060036126f8565b8460ff16601b1415801561266357508460ff16601c14155b1561267457506000905060046126f8565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156126c8573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166126f1576000600192509250506126f8565b9150600090505b94509492505050565b6000806001600160ff1b0383168161271e60ff86901c601b61350c565b905061272c87828885612614565b935093505050935093915050565b60608247101561279b5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610630565b6001600160a01b0385163b6127f25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610630565b600080866001600160a01b0316858760405161280e91906130e1565b60006040518083038185875af1925050503d806000811461284b576040519150601f19603f3d011682016040523d82523d6000602084013e612850565b606091505b509150915061286082828661286b565b979650505050505050565b6060831561287a575081611e71565b82511561288a5782518084602001fd5b8160405162461bcd60e51b81526004016106309190613271565b8280546128b09061357b565b90600052602060002090601f0160209004810192826128d25760008555612918565b82601f106128eb57805160ff1916838001178555612918565b82800160010185558215612918579182015b828111156129185782518255916020019190600101906128fd565b50612924929150612928565b5090565b5b808211156129245760008155600101612929565b80356001600160a01b038116811461295457600080fd5b919050565b600082601f830112612969578081fd5b81356020612976826134e9565b60405161298382826135b6565b8381528281019150858301600585901b870184018810156129a2578586fd5b855b858110156129c7576129b58261293d565b845292840192908401906001016129a4565b5090979650505050505050565b600082601f8301126129e4578081fd5b813560206129f1826134e9565b6040516129fe82826135b6565b8381528281019150858301600585901b87018401881015612a1d578586fd5b855b858110156129c757813584529284019290840190600101612a1f565b600082601f830112612a4b578081fd5b81356001600160401b03811115612a6457612a6461363d565b604051612a7b601f8301601f1916602001826135b6565b818152846020838601011115612a8f578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215612aba578081fd5b611e718261293d565b60008060408385031215612ad5578081fd5b612ade8361293d565b9150612aec6020840161293d565b90509250929050565b600080600080600060a08688031215612b0c578081fd5b612b158661293d565b9450612b236020870161293d565b935060408601356001600160401b0380821115612b3e578283fd5b612b4a89838a016129d4565b94506060880135915080821115612b5f578283fd5b612b6b89838a016129d4565b93506080880135915080821115612b80578283fd5b50612b8d88828901612a3b565b9150509295509295909350565b600080600080600060a08688031215612bb1578081fd5b612bba8661293d565b9450612bc86020870161293d565b9350604086013592506060860135915060808601356001600160401b03811115612bf0578182fd5b612b8d88828901612a3b565b600080600060608486031215612c10578283fd5b612c198461293d565b925060208401356001600160401b0380821115612c34578384fd5b612c40878388016129d4565b93506040860135915080821115612c55578283fd5b50612c62868287016129d4565b9150509250925092565b60008060008060808587031215612c81578384fd5b612c8a8561293d565b935060208501356001600160401b0380821115612ca5578485fd5b612cb1888389016129d4565b94506040870135915080821115612cc6578384fd5b612cd2888389016129d4565b93506060870135915080821115612ce7578283fd5b50612cf487828801612a3b565b91505092959194509250565b60008060408385031215612d12578081fd5b612d1b8361293d565b91506020830135612d2b816136f4565b809150509250929050565b60008060408385031215612d48578182fd5b612d518361293d565b946020939093013593505050565b600080600060608486031215612d73578081fd5b612d7c8461293d565b95602085013595506040909401359392505050565b60008060008060808587031215612da6578182fd5b612daf8561293d565b9350602085013592506040850135915060608501356001600160401b03811115612dd7578182fd5b612cf487828801612a3b565b60008060008060808587031215612df8578182fd5b612e018561293d565b966020860135965060408601359560600135945092505050565b600060208284031215612e2c578081fd5b81356001600160401b03811115612e41578182fd5b611c3684828501612959565b60008060408385031215612e5f578182fd5b82356001600160401b0380821115612e75578384fd5b612e8186838701612959565b93506020850135915080821115612e96578283fd5b50612ea3858286016129d4565b9150509250929050565b600080600060608486031215612ec1578081fd5b83356001600160401b0380821115612ed7578283fd5b612ee387838801612959565b9450602086013593506040860135915080821115612eff578283fd5b50612c6286828701612a3b565b600060208284031215612f1d578081fd5b8151611e71816136f4565b600060208284031215612f39578081fd5b8135611e7181613702565b600060208284031215612f55578081fd5b8151611e7181613702565b60008060408385031215612f72578182fd5b82356001600160401b03811115612f87578283fd5b612f9385828601612a3b565b925050612aec6020840161293d565b600060208284031215612fb3578081fd5b81356001600160401b03811115612fc8578182fd5b611c3684828501612a3b565b600060208284031215612fe5578081fd5b5035919050565b60008060408385031215612ffe578182fd5b8235915060208301356001600160401b0381111561301a578182fd5b612ea385828601612a3b565b60008060408385031215613038578182fd5b50508035926020909101359150565b60008060006060848603121561305b578081fd5b83359250602084013591506130726040850161293d565b90509250925092565b6000815180845260208085019450808401835b838110156130aa5781518752958201959082019060010161308e565b509495945050505050565b600081518084526130cd81602086016020860161354f565b601f01601f19169290920160200192915050565b600082516130f381846020870161354f565b9190910192915050565b600080835482600182811c91508083168061311957607f831692505b602080841082141561313957634e487b7160e01b87526022600452602487fd5b81801561314d576001811461315e5761318a565b60ff1986168952848901965061318a565b60008a815260209020885b868110156131825781548b820152908501908301613169565b505084890196505b509498975050505050505050565b6001600160a01b0386811682528516602082015260a0604082018190526000906131c49083018661307b565b82810360608401526131d6818661307b565b905082810360808401526131ea81856130b5565b98975050505050505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a060808201819052600090612860908301846130b5565b602081526000611e71602083018461307b565b604081526000613256604083018561307b565b8281036020840152613268818561307b565b95945050505050565b602081526000611e7160208301846130b5565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b60208082526024908201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604082015263616e636560e01b606082015260800190565b60208082526029908201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260408201526808185c1c1c9bdd995960ba1b606082015260800190565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b60208082526023908201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260408201526265737360e81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60006001600160401b038211156135025761350261363d565b5060051b60200190565b6000821982111561351f5761351f613611565b500190565b60008261353357613533613627565b500490565b60008282101561354a5761354a613611565b500390565b60005b8381101561356a578181015183820152602001613552565b838111156108605750506000910152565b600181811c9082168061358f57607f821691505b602082108114156135b057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8201601f191681016001600160401b03811182821017156135db576135db61363d565b6040525050565b60006000198214156135f6576135f6613611565b5060010190565b60008261360c5761360c613627565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600060033d111561366857600481823e5160e01c5b90565b600060443d10156136795790565b6040516003193d81016004833e81513d6001600160401b0381602484011181841117156136a857505050505090565b82850191508151818111156136c05750505050505090565b843d87010160208285010111156136da5750505050505090565b6136e9602082860101876135b6565b509095945050505050565b8015158114610fcd57600080fd5b6001600160e01b031981168114610fcd57600080fdfe687474703a2f2f6e66742e61686a73632e746f702f6269747374616b652f6a736f6e2fa2646970667358221220f9c047f1c465e235ecdbac9e4e100a65f514038b174c92282661a4105c77487f64736f6c6343000804003300000000000000000000000055d398326f99059ff775485246999027b31979550000000000000000000000003d2ee26046aeb0d039ab080f05604629edd275270000000000000000000000001b1289c299d07deac5cfc058cbee5fe7ba045bd40000000000000000000000001b1289c299d07deac5cfc058cbee5fe7ba045bd40000000000000000000000001b1289c299d07deac5cfc058cbee5fe7ba045bd4

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102315760003560e01c8063731133e911610130578063d93df696116100b8578063f242432a1161007c578063f242432a14610569578063f2fde38b1461057c578063f5298aca1461058f578063f6c79283146105a2578063fc4d2620146105b557600080fd5b8063d93df696146104c1578063e985e9c5146104d4578063ea6f7a1214610510578063ec0e7fb614610543578063f092ebf71461055657600080fd5b806395d89b41116100ff57806395d89b4114610460578063a22cb46514610468578063b779e9871461047b578063bcb121031461048e578063bd85b039146104a157600080fd5b8063731133e9146104215780637ac3c02f14610434578063862440e21461043c5780638da5cb5b1461044f57600080fd5b80633b91ac24116101be578063611509231161018257806361150923146103cd578063647846a5146103e05780636b20c454146103f35780636d07904514610406578063715018a61461041957600080fd5b80633b91ac241461033f578063479469f9146103525780634e1273f4146103785780634f558e7914610398578063576d3e74146103ba57600080fd5b80631d85bf03116102055780631d85bf03146102a75780631f7fdffa146102bc5780632c38ba0c146102cf5780632eb2c2d6146103015780632f48ab7d1461031457600080fd5b8062fdd58e1461023657806301ffc9a71461025c57806306fdde031461027f5780630e89341c14610294575b600080fd5b610249610244366004612d36565b6105c8565b6040519081526020015b60405180910390f35b61026f61026a366004612f28565b61065f565b6040519015158152602001610253565b6102876106b1565b6040516102539190613271565b6102876102a2366004612fd4565b610743565b6102ba6102b5366004613026565b6107e5565b005b6102ba6102ca366004612c6c565b61082a565b6102e26102dd366004612f60565b610866565b604080516001600160a01b039093168352901515602083015201610253565b6102ba61030f366004612af5565b61093f565b600654610327906001600160a01b031681565b6040516001600160a01b039091168152602001610253565b600a54610327906001600160a01b031681565b600854600954604080516001600160a01b03938416815292909116602083015201610253565b61038b610386366004612e4d565b6109d6565b6040516102539190613230565b61026f6103a6366004612fd4565b600090815260046020526040902054151590565b600c54610327906001600160a01b031681565b600854610327906001600160a01b031681565b600754610327906001600160a01b031681565b6102ba610401366004612bfc565b610b37565b600954610327906001600160a01b031681565b6102ba610b7a565b6102ba61042f366004612d91565b610bb0565b610287610be6565b6102ba61044a366004612fec565b610bf5565b6003546001600160a01b0316610327565b610287610c3e565b6102ba610476366004612d00565b610c4d565b6102ba610489366004612de3565b610c5c565b600b54610327906001600160a01b031681565b6102496104af366004612fd4565b60009081526004602052604090205490565b6102ba6104cf366004612e1b565b610cac565b61026f6104e2366004612ac3565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205460ff1690565b600a54600b54600c54604080516001600160a01b0394851681529284166020840152921691810191909152606001610253565b6102ba610551366004612fa2565b610e0e565b6102ba610564366004612ac3565b610e21565b6102ba610577366004612b9a565b610ef0565b6102ba61058a366004612aa9565b610f35565b6102ba61059d366004612d5f565b610fd0565b6102ba6105b0366004612ead565b611013565b6102ba6105c3366004613047565b611086565b60006001600160a01b0383166106395760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b60648201526084015b60405180910390fd5b506000908152602081815260408083206001600160a01b03949094168352929052205490565b60006001600160e01b03198216636cdb3d1360e11b148061069057506001600160e01b031982166303a24d0760e21b145b806106ab57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600d80546106c09061357b565b80601f01602080910402602001604051908101604052809291908181526020018280546106ec9061357b565b80156107395780601f1061070e57610100808354040283529160200191610739565b820191906000526020600020905b81548152906001019060200180831161071c57829003601f168201915b5050505050905090565b60008181526005602052604090208054606091906107609061357b565b80601f016020809104026020016040519081016040528092919081815260200182805461078c9061357b565b80156107d95780601f106107ae576101008083540402835291602001916107d9565b820191906000526020600020905b8154815290600101906020018083116107bc57829003601f168201915b50505050509050919050565b600b546006543391610806916001600160a01b03908116918491168661114f565b600c54600754610825916001600160a01b03918216918491168561114f565b505050565b6003546001600160a01b031633146108545760405162461bcd60e51b81526004016106309061342b565b610860848484846111a9565b50505050565b6000806000600f60405160200161087d91906130fd565b60408051601f198184030181529190528051602082012090915060006108f0826040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905060006108fe828961131f565b9050806001600160a01b0316876001600160a01b031614156109295794506001935061093892505050565b94506000935061093892505050565b9250929050565b6001600160a01b03851633148061095b575061095b85336104e2565b6109c25760405162461bcd60e51b815260206004820152603260248201527f455243313135353a207472616e736665722063616c6c6572206973206e6f74206044820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b6064820152608401610630565b6109cf858585858561133b565b5050505050565b60608151835114610a3b5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b6064820152608401610630565b600083516001600160401b03811115610a6457634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610a8d578160200160208202803683370190505b50905060005b8451811015610b2f57610af4858281518110610abf57634e487b7160e01b600052603260045260246000fd5b6020026020010151858381518110610ae757634e487b7160e01b600052603260045260246000fd5b60200260200101516105c8565b828281518110610b1457634e487b7160e01b600052603260045260246000fd5b6020908102919091010152610b28816135e2565b9050610a93565b509392505050565b6001600160a01b038316331480610b535750610b5383336104e2565b610b6f5760405162461bcd60e51b815260040161063090613310565b6108258383836114f9565b6003546001600160a01b03163314610ba45760405162461bcd60e51b81526004016106309061342b565b610bae60006116b1565b565b6003546001600160a01b03163314610bda5760405162461bcd60e51b81526004016106309061342b565b61086084848484611703565b6060600f80546106c09061357b565b6003546001600160a01b03163314610c1f5760405162461bcd60e51b81526004016106309061342b565b60008281526005602090815260409091208251610825928401906128a4565b6060600e80546106c09061357b565b610c583383836117ec565b5050565b610c8d84600a60009054906101000a90046001600160a01b0316858560405180602001604052806000815250610ef0565b600c54600754610860916001600160a01b03918216918791168461114f565b6003546001600160a01b03163314610cd65760405162461bcd60e51b81526004016106309061342b565b8051600314610d1e5760405162461bcd60e51b815260206004820152601460248201527330b2323932b9b9903632b733ba341032b93937b960611b6044820152606401610630565b80600081518110610d3f57634e487b7160e01b600052603260045260246000fd5b6020026020010151600a60006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080600181518110610d8e57634e487b7160e01b600052603260045260246000fd5b6020026020010151600b60006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080600281518110610ddd57634e487b7160e01b600052603260045260246000fd5b6020026020010151600c60006101000a8154816001600160a01b0302191690836001600160a01b0316021790555050565b8051610c5890600f9060208401906128a4565b6003546001600160a01b03163314610e4b5760405162461bcd60e51b81526004016106309061342b565b6001600160a01b03821615801590610e6b57506001600160a01b03811615155b610ea95760405162461bcd60e51b815260206004820152600f60248201526e61646472657373206973207a65726f60881b6044820152606401610630565b600880546001600160a01b039384166001600160a01b0319918216811790925560098054939094169281168317909355600680548416909117905560078054909216179055565b6001600160a01b038516331480610f0c5750610f0c85336104e2565b610f285760405162461bcd60e51b815260040161063090613310565b6109cf85858585856118cd565b6003546001600160a01b03163314610f5f5760405162461bcd60e51b81526004016106309061342b565b6001600160a01b038116610fc45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610630565b610fcd816116b1565b50565b6001600160a01b038316331480610fec5750610fec83336104e2565b6110085760405162461bcd60e51b815260040161063090613310565b610825838383611a05565b6003546001600160a01b0316331461103d5760405162461bcd60e51b81526004016106309061342b565b825160005b818110156109cf5761107e85828151811061106d57634e487b7160e01b600052603260045260246000fd5b602002602001015185600186611703565b600101611042565b6003546001600160a01b031633146110b05760405162461bcd60e51b81526004016106309061342b565b600060405180606001604052806023815260200161371960239139604080518082019091526005815264173539b7b760d91b6020820152909150845b848110156111475761110c8161044a61110484611b1d565b869086611c3e565b61113584826001604051806040016040528060048152602001630307830360e41b815250610bb0565b8061113f816135e2565b9150506110ec565b505050505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610860908590611e78565b6001600160a01b0384166111cf5760405162461bcd60e51b8152600401610630906134a8565b81518351146111f05760405162461bcd60e51b815260040161063090613460565b3361120081600087878787611f4a565b60005b84518110156112b75783818151811061122c57634e487b7160e01b600052603260045260246000fd5b602002602001015160008087848151811061125757634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b03168152602001908152602001600020600082825461129f919061350c565b909155508190506112af816135e2565b915050611203565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051611308929190613243565b60405180910390a46109cf81600087878787611f58565b600080600061132e85856120c3565b91509150610b2f81612130565b815183511461135c5760405162461bcd60e51b815260040161063090613460565b6001600160a01b0384166113825760405162461bcd60e51b815260040161063090613359565b33611391818787878787611f4a565b60005b84518110156114935760008582815181106113bf57634e487b7160e01b600052603260045260246000fd5b6020026020010151905060008583815181106113eb57634e487b7160e01b600052603260045260246000fd5b602090810291909101810151600084815280835260408082206001600160a01b038e16835290935291909120549091508181101561143b5760405162461bcd60e51b8152600401610630906133e1565b6000838152602081815260408083206001600160a01b038e8116855292528083208585039055908b1682528120805484929061147890849061350c565b925050819055505050508061148c906135e2565b9050611394565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516114e3929190613243565b60405180910390a4611147818787878787611f58565b6001600160a01b03831661151f5760405162461bcd60e51b81526004016106309061339e565b80518251146115405760405162461bcd60e51b815260040161063090613460565b600033905061156381856000868660405180602001604052806000815250611f4a565b60005b835181101561164457600084828151811061159157634e487b7160e01b600052603260045260246000fd5b6020026020010151905060008483815181106115bd57634e487b7160e01b600052603260045260246000fd5b602090810291909101810151600084815280835260408082206001600160a01b038c16835290935291909120549091508181101561160d5760405162461bcd60e51b8152600401610630906132cc565b6000928352602083815260408085206001600160a01b038b168652909152909220910390558061163c816135e2565b915050611566565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051611695929190613243565b60405180910390a4604080516020810190915260009052610860565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0384166117295760405162461bcd60e51b8152600401610630906134a8565b33600061173585612331565b9050600061174285612331565b905061175383600089858589611f4a565b6000868152602081815260408083206001600160a01b038b1684529091528120805487929061178390849061350c565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46117e38360008989898961238a565b50505050505050565b816001600160a01b0316836001600160a01b031614156118605760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b6064820152608401610630565b6001600160a01b03838116600081815260016020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0384166118f35760405162461bcd60e51b815260040161063090613359565b3360006118ff85612331565b9050600061190c85612331565b905061191c838989858589611f4a565b6000868152602081815260408083206001600160a01b038c1684529091529020548581101561195d5760405162461bcd60e51b8152600401610630906133e1565b6000878152602081815260408083206001600160a01b038d8116855292528083208985039055908a1682528120805488929061199a90849061350c565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46119fa848a8a8a8a8a61238a565b505050505050505050565b6001600160a01b038316611a2b5760405162461bcd60e51b81526004016106309061339e565b336000611a3784612331565b90506000611a4484612331565b9050611a6483876000858560405180602001604052806000815250611f4a565b6000858152602081815260408083206001600160a01b038a16845290915290205484811015611aa55760405162461bcd60e51b8152600401610630906132cc565b6000868152602081815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46040805160208101909152600090526117e3565b606081611b415750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611b6b5780611b55816135e2565b9150611b649050600a83613524565b9150611b45565b6000816001600160401b03811115611b9357634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611bbd576020820181803683370190505b5090505b8415611c3657611bd2600183613538565b9150611bdf600a866135fd565b611bea90603061350c565b60f81b818381518110611c0d57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350611c2f600a86613524565b9450611bc1565b949350505050565b8051825184516060928692869286926000929091611c5c919061350c565b611c66919061350c565b6001600160401b03811115611c8b57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611cb5576020820181803683370190505b5090506000805b8551811015611d4857858181518110611ce557634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b0319168383611cff816135e2565b945081518110611d1f57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535080611d40816135e2565b915050611cbc565b5060005b8451811015611dd857848181518110611d7557634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b0319168383611d8f816135e2565b945081518110611daf57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535080611dd0816135e2565b915050611d4c565b5060005b8351811015611e6857838181518110611e0557634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b0319168383611e1f816135e2565b945081518110611e3f57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535080611e60816135e2565b915050611ddc565b50909450505050505b9392505050565b6000611ecd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166124549092919063ffffffff16565b8051909150156108255780806020019051810190611eeb9190612f0c565b6108255760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610630565b611147868686868686612463565b6001600160a01b0384163b156111475760405163bc197c8160e01b81526001600160a01b0385169063bc197c8190611f9c9089908990889088908890600401613198565b602060405180830381600087803b158015611fb657600080fd5b505af1925050508015611fe6575060408051601f3d908101601f19168201909252611fe391810190612f44565b60015b61209357611ff2613653565b806308c379a0141561202c575061200761366b565b80612012575061202e565b8060405162461bcd60e51b81526004016106309190613271565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e20455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b6064820152608401610630565b6001600160e01b0319811663bc197c8160e01b146117e35760405162461bcd60e51b815260040161063090613284565b6000808251604114156120fa5760208301516040840151606085015160001a6120ee87828585612614565b94509450505050610938565b8251604014156121245760208301516040840151612119868383612701565b935093505050610938565b50600090506002610938565b600081600481111561215257634e487b7160e01b600052602160045260246000fd5b141561215b5750565b600181600481111561217d57634e487b7160e01b600052602160045260246000fd5b14156121cb5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610630565b60028160048111156121ed57634e487b7160e01b600052602160045260246000fd5b141561223b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610630565b600381600481111561225d57634e487b7160e01b600052602160045260246000fd5b14156122b65760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610630565b60048160048111156122d857634e487b7160e01b600052602160045260246000fd5b1415610fcd5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610630565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061237957634e487b7160e01b600052603260045260246000fd5b602090810291909101015292915050565b6001600160a01b0384163b156111475760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906123ce90899089908890889088906004016131f6565b602060405180830381600087803b1580156123e857600080fd5b505af1925050508015612418575060408051601f3d908101601f1916820190925261241591810190612f44565b60015b61242457611ff2613653565b6001600160e01b0319811663f23a6e6160e01b146117e35760405162461bcd60e51b815260040161063090613284565b6060611c36848460008561273a565b6001600160a01b0385166125065760005b83518110156125045782818151811061249d57634e487b7160e01b600052603260045260246000fd5b6020026020010151600460008684815181106124c957634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060008282546124ee919061350c565b909155506124fd9050816135e2565b9050612474565b505b6001600160a01b0384166111475760005b83518110156117e357600084828151811061254257634e487b7160e01b600052603260045260246000fd5b60200260200101519050600084838151811061256e57634e487b7160e01b600052603260045260246000fd5b60200260200101519050600060046000848152602001908152602001600020549050818110156125f15760405162461bcd60e51b815260206004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f74604482015267616c537570706c7960c01b6064820152608401610630565b6000928352600460205260409092209103905561260d816135e2565b9050612517565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561264b57506000905060036126f8565b8460ff16601b1415801561266357508460ff16601c14155b1561267457506000905060046126f8565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156126c8573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166126f1576000600192509250506126f8565b9150600090505b94509492505050565b6000806001600160ff1b0383168161271e60ff86901c601b61350c565b905061272c87828885612614565b935093505050935093915050565b60608247101561279b5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610630565b6001600160a01b0385163b6127f25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610630565b600080866001600160a01b0316858760405161280e91906130e1565b60006040518083038185875af1925050503d806000811461284b576040519150601f19603f3d011682016040523d82523d6000602084013e612850565b606091505b509150915061286082828661286b565b979650505050505050565b6060831561287a575081611e71565b82511561288a5782518084602001fd5b8160405162461bcd60e51b81526004016106309190613271565b8280546128b09061357b565b90600052602060002090601f0160209004810192826128d25760008555612918565b82601f106128eb57805160ff1916838001178555612918565b82800160010185558215612918579182015b828111156129185782518255916020019190600101906128fd565b50612924929150612928565b5090565b5b808211156129245760008155600101612929565b80356001600160a01b038116811461295457600080fd5b919050565b600082601f830112612969578081fd5b81356020612976826134e9565b60405161298382826135b6565b8381528281019150858301600585901b870184018810156129a2578586fd5b855b858110156129c7576129b58261293d565b845292840192908401906001016129a4565b5090979650505050505050565b600082601f8301126129e4578081fd5b813560206129f1826134e9565b6040516129fe82826135b6565b8381528281019150858301600585901b87018401881015612a1d578586fd5b855b858110156129c757813584529284019290840190600101612a1f565b600082601f830112612a4b578081fd5b81356001600160401b03811115612a6457612a6461363d565b604051612a7b601f8301601f1916602001826135b6565b818152846020838601011115612a8f578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215612aba578081fd5b611e718261293d565b60008060408385031215612ad5578081fd5b612ade8361293d565b9150612aec6020840161293d565b90509250929050565b600080600080600060a08688031215612b0c578081fd5b612b158661293d565b9450612b236020870161293d565b935060408601356001600160401b0380821115612b3e578283fd5b612b4a89838a016129d4565b94506060880135915080821115612b5f578283fd5b612b6b89838a016129d4565b93506080880135915080821115612b80578283fd5b50612b8d88828901612a3b565b9150509295509295909350565b600080600080600060a08688031215612bb1578081fd5b612bba8661293d565b9450612bc86020870161293d565b9350604086013592506060860135915060808601356001600160401b03811115612bf0578182fd5b612b8d88828901612a3b565b600080600060608486031215612c10578283fd5b612c198461293d565b925060208401356001600160401b0380821115612c34578384fd5b612c40878388016129d4565b93506040860135915080821115612c55578283fd5b50612c62868287016129d4565b9150509250925092565b60008060008060808587031215612c81578384fd5b612c8a8561293d565b935060208501356001600160401b0380821115612ca5578485fd5b612cb1888389016129d4565b94506040870135915080821115612cc6578384fd5b612cd2888389016129d4565b93506060870135915080821115612ce7578283fd5b50612cf487828801612a3b565b91505092959194509250565b60008060408385031215612d12578081fd5b612d1b8361293d565b91506020830135612d2b816136f4565b809150509250929050565b60008060408385031215612d48578182fd5b612d518361293d565b946020939093013593505050565b600080600060608486031215612d73578081fd5b612d7c8461293d565b95602085013595506040909401359392505050565b60008060008060808587031215612da6578182fd5b612daf8561293d565b9350602085013592506040850135915060608501356001600160401b03811115612dd7578182fd5b612cf487828801612a3b565b60008060008060808587031215612df8578182fd5b612e018561293d565b966020860135965060408601359560600135945092505050565b600060208284031215612e2c578081fd5b81356001600160401b03811115612e41578182fd5b611c3684828501612959565b60008060408385031215612e5f578182fd5b82356001600160401b0380821115612e75578384fd5b612e8186838701612959565b93506020850135915080821115612e96578283fd5b50612ea3858286016129d4565b9150509250929050565b600080600060608486031215612ec1578081fd5b83356001600160401b0380821115612ed7578283fd5b612ee387838801612959565b9450602086013593506040860135915080821115612eff578283fd5b50612c6286828701612a3b565b600060208284031215612f1d578081fd5b8151611e71816136f4565b600060208284031215612f39578081fd5b8135611e7181613702565b600060208284031215612f55578081fd5b8151611e7181613702565b60008060408385031215612f72578182fd5b82356001600160401b03811115612f87578283fd5b612f9385828601612a3b565b925050612aec6020840161293d565b600060208284031215612fb3578081fd5b81356001600160401b03811115612fc8578182fd5b611c3684828501612a3b565b600060208284031215612fe5578081fd5b5035919050565b60008060408385031215612ffe578182fd5b8235915060208301356001600160401b0381111561301a578182fd5b612ea385828601612a3b565b60008060408385031215613038578182fd5b50508035926020909101359150565b60008060006060848603121561305b578081fd5b83359250602084013591506130726040850161293d565b90509250925092565b6000815180845260208085019450808401835b838110156130aa5781518752958201959082019060010161308e565b509495945050505050565b600081518084526130cd81602086016020860161354f565b601f01601f19169290920160200192915050565b600082516130f381846020870161354f565b9190910192915050565b600080835482600182811c91508083168061311957607f831692505b602080841082141561313957634e487b7160e01b87526022600452602487fd5b81801561314d576001811461315e5761318a565b60ff1986168952848901965061318a565b60008a815260209020885b868110156131825781548b820152908501908301613169565b505084890196505b509498975050505050505050565b6001600160a01b0386811682528516602082015260a0604082018190526000906131c49083018661307b565b82810360608401526131d6818661307b565b905082810360808401526131ea81856130b5565b98975050505050505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a060808201819052600090612860908301846130b5565b602081526000611e71602083018461307b565b604081526000613256604083018561307b565b8281036020840152613268818561307b565b95945050505050565b602081526000611e7160208301846130b5565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b60208082526024908201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604082015263616e636560e01b606082015260800190565b60208082526029908201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260408201526808185c1c1c9bdd995960ba1b606082015260800190565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b60208082526023908201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260408201526265737360e81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60006001600160401b038211156135025761350261363d565b5060051b60200190565b6000821982111561351f5761351f613611565b500190565b60008261353357613533613627565b500490565b60008282101561354a5761354a613611565b500390565b60005b8381101561356a578181015183820152602001613552565b838111156108605750506000910152565b600181811c9082168061358f57607f821691505b602082108114156135b057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8201601f191681016001600160401b03811182821017156135db576135db61363d565b6040525050565b60006000198214156135f6576135f6613611565b5060010190565b60008261360c5761360c613627565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600060033d111561366857600481823e5160e01c5b90565b600060443d10156136795790565b6040516003193d81016004833e81513d6001600160401b0381602484011181841117156136a857505050505090565b82850191508151818111156136c05750505050505090565b843d87010160208285010111156136da5750505050505090565b6136e9602082860101876135b6565b509095945050505050565b8015158114610fcd57600080fd5b6001600160e01b031981168114610fcd57600080fdfe687474703a2f2f6e66742e61686a73632e746f702f6269747374616b652f6a736f6e2fa2646970667358221220f9c047f1c465e235ecdbac9e4e100a65f514038b174c92282661a4105c77487f64736f6c63430008040033

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

00000000000000000000000055d398326f99059ff775485246999027b31979550000000000000000000000003d2ee26046aeb0d039ab080f05604629edd275270000000000000000000000001b1289c299d07deac5cfc058cbee5fe7ba045bd40000000000000000000000001b1289c299d07deac5cfc058cbee5fe7ba045bd40000000000000000000000001b1289c299d07deac5cfc058cbee5fe7ba045bd4

-----Decoded View---------------
Arg [0] : _usdt (address): 0x55d398326f99059fF775485246999027B3197955
Arg [1] : _feeToken (address): 0x3D2eE26046aeB0d039aB080F05604629eDD27527
Arg [2] : _collectNFT (address): 0x1b1289C299d07deAc5cFc058CBEe5fe7ba045Bd4
Arg [3] : _collectUSDT (address): 0x1b1289C299d07deAc5cFc058CBEe5fe7ba045Bd4
Arg [4] : _collectFeeToken (address): 0x1b1289C299d07deAc5cFc058CBEe5fe7ba045Bd4

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 00000000000000000000000055d398326f99059ff775485246999027b3197955
Arg [1] : 0000000000000000000000003d2ee26046aeb0d039ab080f05604629edd27527
Arg [2] : 0000000000000000000000001b1289c299d07deac5cfc058cbee5fe7ba045bd4
Arg [3] : 0000000000000000000000001b1289c299d07deac5cfc058cbee5fe7ba045bd4
Arg [4] : 0000000000000000000000001b1289c299d07deac5cfc058cbee5fe7ba045bd4


Deployed Bytecode Sourcemap

60090:8428:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41955:231;;;;;;:::i;:::-;;:::i;:::-;;;29601:25:1;;;29589:2;29574:18;41955:231:0;;;;;;;;40978:310;;;;;;:::i;:::-;;:::i;:::-;;;18687:14:1;;18680:22;18662:41;;18650:2;18635:18;40978:310:0;18617:92:1;61319:91:0;;;:::i;:::-;;;;;;;:::i;61930:178::-;;;;;;:::i;:::-;;:::i;67580:933::-;;;;;;:::i;:::-;;:::i;:::-;;63832:211;;;;;;:::i;:::-;;:::i;65750:921::-;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;17683:32:1;;;17665:51;;17759:14;;17752:22;17747:2;17732:18;;17725:50;17638:18;65750:921:0;17620:161:1;43894:442:0;;;;;;:::i;:::-;;:::i;60310:18::-;;;;;-1:-1:-1;;;;;60310:18:0;;;;;;-1:-1:-1;;;;;14979:32:1;;;14961:51;;14949:2;14934:18;60310::0;14916:102:1;60440:25:0;;;;;-1:-1:-1;;;;;60440:25:0;;;63464:163;63589:12;;63602:16;;63464:163;;;-1:-1:-1;;;;;63589:12:0;;;15235:34:1;;63602:16:0;;;;15300:2:1;15285:18;;15278:43;15170:18;63464:163:0;15152:175:1;42352:524:0;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;58286:122::-;;;;;;:::i;:::-;58343:4;58164:16;;;:12;:16;;;;;;-1:-1:-1;;;58286:122:0;60505:30;;;;;-1:-1:-1;;;;;60505:30:0;;;60366:27;;;;;-1:-1:-1;;;;;60366:27:0;;;60335:22;;;;;-1:-1:-1;;;;;60335:22:0;;;65113:353;;;;;;:::i;:::-;;:::i;60400:31::-;;;;;-1:-1:-1;;;;;60400:31:0;;;17176:103;;;:::i;63635:189::-;;;;;;:::i;:::-;;:::i;65649:93::-;;;:::i;62116:119::-;;;;;;:::i;:::-;;:::i;16525:87::-;16598:6;;-1:-1:-1;;;;;16598:6:0;16525:87;;61418:95;;;:::i;42949:155::-;;;;;;:::i;:::-;;:::i;66885:560::-;;;;;;:::i;:::-;;:::i;60472:26::-;;;;;-1:-1:-1;;;;;60472:26:0;;;58075:113;;;;;;:::i;:::-;58137:7;58164:16;;;:12;:16;;;;;;;58075:113;62446:309;;;;;;:::i;:::-;;:::i;43176:168::-;;;;;;:::i;:::-;-1:-1:-1;;;;;43299:27:0;;;43275:4;43299:27;;;:18;:27;;;;;;;;:37;;;;;;;;;;;;;;;43176:168;62763:187;62903:10;;62914:11;;62926:15;;62763:187;;;-1:-1:-1;;;;;62903:10:0;;;15572:34:1;;62914:11:0;;;15637:2:1;15622:18;;15615:43;62926:15:0;;15674:18:1;;;15667:43;;;;15522:2;15507:18;62763:187:0;15489:227:1;65545:96:0;;;;;;:::i;:::-;;:::i;63085:371::-;;;;;;:::i;:::-;;:::i;43416:401::-;;;;;;:::i;:::-;;:::i;17434:201::-;;;;;;:::i;:::-;;:::i;64784:321::-;;;;;;:::i;:::-;;:::i;64051:318::-;;;;;;:::i;:::-;;:::i;61523:399::-;;;;;;:::i;:::-;;:::i;41955:231::-;42041:7;-1:-1:-1;;;;;42069:21:0;;42061:77;;;;-1:-1:-1;;;42061:77:0;;21307:2:1;42061:77:0;;;21289:21:1;21346:2;21326:18;;;21319:30;21385:34;21365:18;;;21358:62;-1:-1:-1;;;21436:18:1;;;21429:41;21487:19;;42061:77:0;;;;;;;;;-1:-1:-1;42156:9:0;:13;;;;;;;;;;;-1:-1:-1;;;;;42156:22:0;;;;;;;;;;;;41955:231::o;40978:310::-;41080:4;-1:-1:-1;;;;;;41117:41:0;;-1:-1:-1;;;41117:41:0;;:110;;-1:-1:-1;;;;;;;41175:52:0;;-1:-1:-1;;;41175:52:0;41117:110;:163;;;-1:-1:-1;;;;;;;;;;32380:40:0;;;41244:36;41097:183;40978:310;-1:-1:-1;;40978:310:0:o;61319:91::-;61364:13;61397:5;61390:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61319:91;:::o;61930:178::-;62081:19;;;;:10;:19;;;;;62074:26;;62043:13;;62081:19;62074:26;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61930:178;;;:::o;67580:933::-;68413:11;;68384:4;;15329:10;;68384:50;;-1:-1:-1;;;;;68384:4:0;;;;15329:10;;68413:11;68426:7;68384:21;:50::i;:::-;68478:15;;68445:8;;:58;;-1:-1:-1;;;;;68445:8:0;;;;68471:5;;68478:15;68495:7;68445:25;:58::i;:::-;67580:933;;;:::o;63832:211::-;16598:6;;-1:-1:-1;;;;;16598:6:0;15329:10;16745:23;16737:68;;;;-1:-1:-1;;;16737:68:0;;;;;;;:::i;:::-;64001:34:::1;64012:2;64016:3;64021:7;64030:4;64001:10;:34::i;:::-;63832:211:::0;;;;:::o;65750:921::-;65867:7;65876:4;65946:22;65988:10;65971:28;;;;;;;;:::i;:::-;;;;-1:-1:-1;;65971:28:0;;;;;;;;;66080:20;;65971:28;66080:20;;;65971:28;;-1:-1:-1;66058:19:0;66343:65;66080:20;13457:58;;14672:66:1;13457:58:0;;;14660:79:1;14755:12;;;14748:28;;;13324:7:0;;14792:12:1;;13457:58:0;;;;;;;;;;;;13447:69;;;;;;13440:76;;13255:269;;;;66343:65;66312:96;;66458:14;66475:47;66489:20;66511:10;66475:13;:47::i;:::-;66458:64;;66553:6;-1:-1:-1;;;;;66539:20:0;:10;-1:-1:-1;;;;;66539:20:0;;66535:129;;;66584:6;-1:-1:-1;66592:4:0;;-1:-1:-1;66576:21:0;;-1:-1:-1;;;66576:21:0;66535:129;66638:6;-1:-1:-1;66646:5:0;;-1:-1:-1;66630:22:0;;-1:-1:-1;;;66630:22:0;65750:921;;;;;;:::o;43894:442::-;-1:-1:-1;;;;;44127:20:0;;15329:10;44127:20;;:60;;-1:-1:-1;44151:36:0;44168:4;15329:10;43176:168;:::i;44151:36::-;44105:160;;;;-1:-1:-1;;;44105:160:0;;24850:2:1;44105:160:0;;;24832:21:1;24889:2;24869:18;;;24862:30;24928:34;24908:18;;;24901:62;-1:-1:-1;;;24979:18:1;;;24972:48;25037:19;;44105:160:0;24822:240:1;44105:160:0;44276:52;44299:4;44305:2;44309:3;44314:7;44323:4;44276:22;:52::i;:::-;43894:442;;;;;:::o;42352:524::-;42508:16;42569:3;:10;42550:8;:15;:29;42542:83;;;;-1:-1:-1;;;42542:83:0;;28436:2:1;42542:83:0;;;28418:21:1;28475:2;28455:18;;;28448:30;28514:34;28494:18;;;28487:62;-1:-1:-1;;;28565:18:1;;;28558:39;28614:19;;42542:83:0;28408:231:1;42542:83:0;42638:30;42685:8;:15;-1:-1:-1;;;;;42671:30:0;;;;;-1:-1:-1;;;42671:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42671:30:0;;42638:63;;42719:9;42714:122;42738:8;:15;42734:1;:19;42714:122;;;42794:30;42804:8;42813:1;42804:11;;;;;;-1:-1:-1;;;42804:11:0;;;;;;;;;;;;;;;42817:3;42821:1;42817:6;;;;;;-1:-1:-1;;;42817:6:0;;;;;;;;;;;;;;;42794:9;:30::i;:::-;42775:13;42789:1;42775:16;;;;;;-1:-1:-1;;;42775:16:0;;;;;;;;;;;;;;;;;;:49;42755:3;;;:::i;:::-;;;42714:122;;;-1:-1:-1;42855:13:0;42352:524;-1:-1:-1;;;42352:524:0:o;65113:353::-;-1:-1:-1;;;;;65278:23:0;;15329:10;65278:23;;:66;;-1:-1:-1;65305:39:0;65322:7;15329:10;43176:168;:::i;65305:39::-;65256:157;;;;-1:-1:-1;;;65256:157:0;;;;;;;:::i;:::-;65426:32;65437:7;65446:3;65451:6;65426:10;:32::i;17176:103::-;16598:6;;-1:-1:-1;;;;;16598:6:0;15329:10;16745:23;16737:68;;;;-1:-1:-1;;;16737:68:0;;;;;;;:::i;:::-;17241:30:::1;17268:1;17241:18;:30::i;:::-;17176:103::o:0;63635:189::-;16598:6;;-1:-1:-1;;;;;16598:6:0;15329:10;16745:23;16737:68;;;;-1:-1:-1;;;16737:68:0;;;;;;;:::i;:::-;63784:32:::1;63790:7;63799:2;63803:6;63811:4;63784:5;:32::i;65649:93::-:0;65691:13;65724:10;65717:17;;;;;:::i;62116:119::-;16598:6;;-1:-1:-1;;;;;16598:6:0;15329:10;16745:23;16737:68;;;;-1:-1:-1;;;16737:68:0;;;;;;;:::i;:::-;62199:19:::1;::::0;;;:10:::1;:19;::::0;;;;;;;:28;;::::1;::::0;;::::1;::::0;::::1;:::i;61418:95::-:0;61465:13;61498:7;61491:14;;;;;:::i;42949:155::-;43044:52;15329:10;43077:8;43087;43044:18;:52::i;:::-;42949:155;;:::o;66885:560::-;67319:50;67336:4;67342:10;;;;;;;;;-1:-1:-1;;;;;67342:10:0;67354:2;67358:6;67319:50;;;;;;;;;;;;:16;:50::i;:::-;67412:15;;67380:8;;:57;;-1:-1:-1;;;;;67380:8:0;;;;67406:4;;67412:15;67429:7;67380:25;:57::i;62446:309::-;16598:6;;-1:-1:-1;;;;;16598:6:0;15329:10;16745:23;16737:68;;;;-1:-1:-1;;;16737:68:0;;;;;;;:::i;:::-;62567:14:::1;:21;62592:1;62567:26;62559:59;;;::::0;-1:-1:-1;;;62559:59:0;;23751:2:1;62559:59:0::1;::::0;::::1;23733:21:1::0;23790:2;23770:18;;;23763:30;-1:-1:-1;;;23809:18:1;;;23802:50;23869:18;;62559:59:0::1;23723:170:1::0;62559:59:0::1;62642:14;62657:1;62642:17;;;;;;-1:-1:-1::0;;;62642:17:0::1;;;;;;;;;;;;;;;62629:10;;:30;;;;;-1:-1:-1::0;;;;;62629:30:0::1;;;;;-1:-1:-1::0;;;;;62629:30:0::1;;;;;;62684:14;62699:1;62684:17;;;;;;-1:-1:-1::0;;;62684:17:0::1;;;;;;;;;;;;;;;62670:11;;:31;;;;;-1:-1:-1::0;;;;;62670:31:0::1;;;;;-1:-1:-1::0;;;;;62670:31:0::1;;;;;;62730:14;62745:1;62730:17;;;;;;-1:-1:-1::0;;;62730:17:0::1;;;;;;;;;;;;;;;62712:15;;:35;;;;;-1:-1:-1::0;;;;;62712:35:0::1;;;;;-1:-1:-1::0;;;;;62712:35:0::1;;;;;;62446:309:::0;:::o;65545:96::-;65609:24;;;;:10;;:24;;;;;:::i;63085:371::-;16598:6;;-1:-1:-1;;;;;16598:6:0;15329:10;16745:23;16737:68;;;;-1:-1:-1;;;16737:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;63219:19:0;::::1;::::0;;::::1;::::0;:46:::1;;-1:-1:-1::0;;;;;;63242:23:0;::::1;::::0;::::1;63219:46;63197:111;;;::::0;-1:-1:-1;;;63197:111:0;;24100:2:1;63197:111:0::1;::::0;::::1;24082:21:1::0;24139:2;24119:18;;;24112:30;-1:-1:-1;;;24158:18:1;;;24151:45;24213:18;;63197:111:0::1;24072:165:1::0;63197:111:0::1;63319:12;:20:::0;;-1:-1:-1;;;;;63319:20:0;;::::1;-1:-1:-1::0;;;;;;63319:20:0;;::::1;::::0;::::1;::::0;;;63350:16:::1;:28:::0;;;;;::::1;::::0;;::::1;::::0;::::1;::::0;;;63389:4:::1;:20:::0;;;::::1;::::0;;::::1;::::0;;63420:8:::1;:28:::0;;;;::::1;;::::0;;63085:371::o;43416:401::-;-1:-1:-1;;;;;43624:20:0;;15329:10;43624:20;;:60;;-1:-1:-1;43648:36:0;43665:4;15329:10;43176:168;:::i;43648:36::-;43602:151;;;;-1:-1:-1;;;43602:151:0;;;;;;;:::i;:::-;43764:45;43782:4;43788:2;43792;43796:6;43804:4;43764:17;:45::i;17434:201::-;16598:6;;-1:-1:-1;;;;;16598:6:0;15329:10;16745:23;16737:68;;;;-1:-1:-1;;;16737:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;17523:22:0;::::1;17515:73;;;::::0;-1:-1:-1;;;17515:73:0;;21719:2:1;17515:73:0::1;::::0;::::1;21701:21:1::0;21758:2;21738:18;;;21731:30;21797:34;21777:18;;;21770:62;-1:-1:-1;;;21848:18:1;;;21841:36;21894:19;;17515:73:0::1;21691:228:1::0;17515:73:0::1;17599:28;17618:8;17599:18;:28::i;:::-;17434:201:::0;:::o;64784:321::-;-1:-1:-1;;;;;64924:23:0;;15329:10;64924:23;;:66;;-1:-1:-1;64951:39:0;64968:7;15329:10;43176:168;:::i;64951:39::-;64902:157;;;;-1:-1:-1;;;64902:157:0;;;;;;;:::i;:::-;65072:25;65078:7;65087:2;65091:5;65072;:25::i;64051:318::-;16598:6;;-1:-1:-1;;;;;16598:6:0;15329:10;16745:23;16737:68;;;;-1:-1:-1;;;16737:68:0;;;;;;;:::i;:::-;64195:9;;64183::::1;64217:145;64241:1;64237;:5;64217:145;;;64261:25;64267:2;64270:1;64267:5;;;;;;-1:-1:-1::0;;;64267:5:0::1;;;;;;;;;;;;;;;64274:2;64278:1;64281:4;64261:5;:25::i;:::-;64332:3;;64217:145;;61523:399:::0;16598:6;;-1:-1:-1;;;;;16598:6:0;15329:10;16745:23;16737:68;;;;-1:-1:-1;;;16737:68:0;;;;;;;:::i;:::-;61618:26:::1;:65;;;;;;;;;;;;;;;;;61694:33;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;61694:33:0::1;::::0;::::1;::::0;61618:65;;-1:-1:-1;61751:7:0;61740:173:::1;61762:5;61759:1;:8;61740:173;;;61789:56;61796:1;61798:46;61821:12;:1;:10;:12::i;:::-;61798:11:::0;;61834:9;61798:22:::1;:46::i;61789:56::-;61860:27;61865:10;61876:1;61878;61860:27;;;;;;;;;;;;;-1:-1:-1::0;;;61860:27:0::1;;::::0;:4:::1;:27::i;:::-;61768:3:::0;::::1;::::0;::::1;:::i;:::-;;;;61740:173;;;;16816:1;;61523:399:::0;;;:::o;27412:248::-;27583:68;;;-1:-1:-1;;;;;16810:15:1;;;27583:68:0;;;16792:34:1;16862:15;;16842:18;;;16835:43;16894:18;;;;16887:34;;;27583:68:0;;;;;;;;;;16727:18:1;;;;27583:68:0;;;;;;;;-1:-1:-1;;;;;27583:68:0;-1:-1:-1;;;27583:68:0;;;27556:96;;27576:5;;27556:19;:96::i;49681:813::-;-1:-1:-1;;;;;49859:16:0;;49851:62;;;;-1:-1:-1;;;49851:62:0;;;;;;;:::i;:::-;49946:7;:14;49932:3;:10;:28;49924:81;;;;-1:-1:-1;;;49924:81:0;;;;;;;:::i;:::-;15329:10;50062:66;15329:10;50018:16;50105:2;50109:3;50114:7;50123:4;50062:20;:66::i;:::-;50146:9;50141:103;50165:3;:10;50161:1;:14;50141:103;;;50222:7;50230:1;50222:10;;;;;;-1:-1:-1;;;50222:10:0;;;;;;;;;;;;;;;50197:9;:17;50207:3;50211:1;50207:6;;;;;;-1:-1:-1;;;50207:6:0;;;;;;;;;;;;;;;50197:17;;;;;;;;;;;:21;50215:2;-1:-1:-1;;;;;50197:21:0;-1:-1:-1;;;;;50197:21:0;;;;;;;;;;;;;:35;;;;;;;:::i;:::-;;;;-1:-1:-1;50177:3:0;;-1:-1:-1;50177:3:0;;;:::i;:::-;;;;50141:103;;;;50297:2;-1:-1:-1;;;;;50261:53:0;50293:1;-1:-1:-1;;;;;50261:53:0;50275:8;-1:-1:-1;;;;;50261:53:0;;50301:3;50306:7;50261:53;;;;;;;:::i;:::-;;;;;;;;50405:81;50441:8;50459:1;50463:2;50467:3;50472:7;50481:4;50405:35;:81::i;9453:231::-;9531:7;9552:17;9571:18;9593:27;9604:4;9610:9;9593:10;:27::i;:::-;9551:69;;;;9631:18;9643:5;9631:11;:18::i;46132:1146::-;46359:7;:14;46345:3;:10;:28;46337:81;;;;-1:-1:-1;;;46337:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;46437:16:0;;46429:66;;;;-1:-1:-1;;;46429:66:0;;;;;;;:::i;:::-;15329:10;46552:60;15329:10;46583:4;46589:2;46593:3;46598:7;46607:4;46552:20;:60::i;:::-;46630:9;46625:421;46649:3;:10;46645:1;:14;46625:421;;;46681:10;46694:3;46698:1;46694:6;;;;;;-1:-1:-1;;;46694:6:0;;;;;;;;;;;;;;;46681:19;;46715:14;46732:7;46740:1;46732:10;;;;;;-1:-1:-1;;;46732:10:0;;;;;;;;;;;;;;;;;;;;46759:19;46781:13;;;;;;;;;;-1:-1:-1;;;;;46781:19:0;;;;;;;;;;;;46732:10;;-1:-1:-1;46823:21:0;;;;46815:76;;;;-1:-1:-1;;;46815:76:0;;;;;;;:::i;:::-;46935:9;:13;;;;;;;;;;;-1:-1:-1;;;;;46935:19:0;;;;;;;;;;46957:20;;;46935:42;;47007:17;;;;;;;:27;;46957:20;;46935:9;47007:27;;46957:20;;47007:27;:::i;:::-;;;;;;;;46625:421;;;46661:3;;;;:::i;:::-;;;46625:421;;;;47093:2;-1:-1:-1;;;;;47063:47:0;47087:4;-1:-1:-1;;;;;47063:47:0;47077:8;-1:-1:-1;;;;;47063:47:0;;47097:3;47102:7;47063:47;;;;;;;:::i;:::-;;;;;;;;47195:75;47231:8;47241:4;47247:2;47251:3;47256:7;47265:4;47195:35;:75::i;51755:969::-;-1:-1:-1;;;;;51907:18:0;;51899:66;;;;-1:-1:-1;;;51899:66:0;;;;;;;:::i;:::-;51998:7;:14;51984:3;:10;:28;51976:81;;;;-1:-1:-1;;;51976:81:0;;;;;;;:::i;:::-;52070:16;15329:10;52070:31;;52114:66;52135:8;52145:4;52159:1;52163:3;52168:7;52114:66;;;;;;;;;;;;:20;:66::i;:::-;52198:9;52193:373;52217:3;:10;52213:1;:14;52193:373;;;52249:10;52262:3;52266:1;52262:6;;;;;;-1:-1:-1;;;52262:6:0;;;;;;;;;;;;;;;52249:19;;52283:14;52300:7;52308:1;52300:10;;;;;;-1:-1:-1;;;52300:10:0;;;;;;;;;;;;;;;;;;;;52327:19;52349:13;;;;;;;;;;-1:-1:-1;;;;;52349:19:0;;;;;;;;;;;;52300:10;;-1:-1:-1;52391:21:0;;;;52383:70;;;;-1:-1:-1;;;52383:70:0;;;;;;;:::i;:::-;52497:9;:13;;;;;;;;;;;-1:-1:-1;;;;;52497:19:0;;;;;;;;;;52519:20;;52497:42;;52229:3;;;;:::i;:::-;;;;52193:373;;;;52621:1;-1:-1:-1;;;;;52583:55:0;52607:4;-1:-1:-1;;;;;52583:55:0;52597:8;-1:-1:-1;;;;;52583:55:0;;52625:3;52630:7;52583:55;;;;;;;:::i;:::-;;;;;;;;52651:65;;;;;;;;;52695:1;52651:65;;;61523:399;17795:191;17888:6;;;-1:-1:-1;;;;;17905:17:0;;;-1:-1:-1;;;;;;17905:17:0;;;;;;;17938:40;;17888:6;;;17905:17;17888:6;;17938:40;;17869:16;;17938:40;17795:191;;:::o;48596:729::-;-1:-1:-1;;;;;48749:16:0;;48741:62;;;;-1:-1:-1;;;48741:62:0;;;;;;;:::i;:::-;15329:10;48816:16;48881:21;48899:2;48881:17;:21::i;:::-;48858:44;;48913:24;48940:25;48958:6;48940:17;:25::i;:::-;48913:52;;48978:66;48999:8;49017:1;49021:2;49025:3;49030:7;49039:4;48978:20;:66::i;:::-;49057:9;:13;;;;;;;;;;;-1:-1:-1;;;;;49057:17:0;;;;;;;;;:27;;49078:6;;49057:9;:27;;49078:6;;49057:27;:::i;:::-;;;;-1:-1:-1;;49100:52:0;;;29811:25:1;;;29867:2;29852:18;;29845:34;;;-1:-1:-1;;;;;49100:52:0;;;;49133:1;;49100:52;;;;;;29784:18:1;49100:52:0;;;;;;;49243:74;49274:8;49292:1;49296:2;49300;49304:6;49312:4;49243:30;:74::i;:::-;48596:729;;;;;;;:::o;52866:331::-;53021:8;-1:-1:-1;;;;;53012:17:0;:5;-1:-1:-1;;;;;53012:17:0;;;53004:71;;;;-1:-1:-1;;;53004:71:0;;27615:2:1;53004:71:0;;;27597:21:1;27654:2;27634:18;;;27627:30;27693:34;27673:18;;;27666:62;-1:-1:-1;;;27744:18:1;;;27737:39;27793:19;;53004:71:0;27587:231:1;53004:71:0;-1:-1:-1;;;;;53086:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;53086:46:0;;;;;;;;;;53148:41;;18662::1;;;53148::0;;18635:18:1;53148:41:0;;;;;;;52866:331;;;:::o;44800:974::-;-1:-1:-1;;;;;44988:16:0;;44980:66;;;;-1:-1:-1;;;44980:66:0;;;;;;;:::i;:::-;15329:10;45059:16;45124:21;45142:2;45124:17;:21::i;:::-;45101:44;;45156:24;45183:25;45201:6;45183:17;:25::i;:::-;45156:52;;45221:60;45242:8;45252:4;45258:2;45262:3;45267:7;45276:4;45221:20;:60::i;:::-;45294:19;45316:13;;;;;;;;;;;-1:-1:-1;;;;;45316:19:0;;;;;;;;;;45354:21;;;;45346:76;;;;-1:-1:-1;;;45346:76:0;;;;;;;:::i;:::-;45458:9;:13;;;;;;;;;;;-1:-1:-1;;;;;45458:19:0;;;;;;;;;;45480:20;;;45458:42;;45522:17;;;;;;;:27;;45480:20;;45458:9;45522:27;;45480:20;;45522:27;:::i;:::-;;;;-1:-1:-1;;45567:46:0;;;29811:25:1;;;29867:2;29852:18;;29845:34;;;-1:-1:-1;;;;;45567:46:0;;;;;;;;;;;;;;29784:18:1;45567:46:0;;;;;;;45698:68;45729:8;45739:4;45745:2;45749;45753:6;45761:4;45698:30;:68::i;:::-;44800:974;;;;;;;;;:::o;50744:808::-;-1:-1:-1;;;;;50871:18:0;;50863:66;;;;-1:-1:-1;;;50863:66:0;;;;;;;:::i;:::-;15329:10;50942:16;51007:21;51025:2;51007:17;:21::i;:::-;50984:44;;51039:24;51066:25;51084:6;51066:17;:25::i;:::-;51039:52;;51104:66;51125:8;51135:4;51149:1;51153:3;51158:7;51104:66;;;;;;;;;;;;:20;:66::i;:::-;51183:19;51205:13;;;;;;;;;;;-1:-1:-1;;;;;51205:19:0;;;;;;;;;;51243:21;;;;51235:70;;;;-1:-1:-1;;;51235:70:0;;;;;;;:::i;:::-;51341:9;:13;;;;;;;;;;;-1:-1:-1;;;;;51341:19:0;;;;;;;;;;;;51363:20;;;51341:42;;51412:54;;29811:25:1;;;29852:18;;;29845:34;;;51341:19:0;;51412:54;;;;;;29784:18:1;51412:54:0;;;;;;;51479:65;;;;;;;;;51523:1;51479:65;;;61523:399;3277:723;3333:13;3554:10;3550:53;;-1:-1:-1;;3581:10:0;;;;;;;;;;;;-1:-1:-1;;;3581:10:0;;;;;3277:723::o;3550:53::-;3628:5;3613:12;3669:78;3676:9;;3669:78;;3702:8;;;;:::i;:::-;;-1:-1:-1;3725:10:0;;-1:-1:-1;3733:2:0;3725:10;;:::i;:::-;;;3669:78;;;3757:19;3789:6;-1:-1:-1;;;;;3779:17:0;;;;;-1:-1:-1;;;3779:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3779:17:0;;3757:39;;3807:154;3814:10;;3807:154;;3841:11;3851:1;3841:11;;:::i;:::-;;-1:-1:-1;3910:10:0;3918:2;3910:5;:10;:::i;:::-;3897:24;;:2;:24;:::i;:::-;3884:39;;3867:6;3874;3867:14;;;;;;-1:-1:-1;;;3867:14:0;;;;;;;;;;;;:56;-1:-1:-1;;;;;3867:56:0;;;;;;;;-1:-1:-1;3938:11:0;3947:2;3938:11;;:::i;:::-;;;3807:154;;;3985:6;3277:723;-1:-1:-1;;;;3277:723:0:o;59515:562::-;59810:10;;59797;;59784;;59612:13;;59663:2;;59702;;59741;;59638:16;;59810:10;;59784:23;;59797:10;59784:23;:::i;:::-;:36;;;;:::i;:::-;-1:-1:-1;;;;;59774:47:0;;;;;-1:-1:-1;;;59774:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59774:47:0;;59755:66;;59832:6;59858;59853:55;59874:3;:10;59870:1;:14;59853:55;;;59902:3;59906:1;59902:6;;;;;;-1:-1:-1;;;59902:6:0;;;;;;;;;;;;;-1:-1:-1;;;;;;59902:6:0;59891:3;59895;;;;:::i;:::-;;;59891:8;;;;;;-1:-1:-1;;;59891:8:0;;;;;;;;;;;;:17;-1:-1:-1;;;;;59891:17:0;;;;;;;;-1:-1:-1;59886:3:0;;;;:::i;:::-;;;;59853:55;;;;59924:6;59919:55;59940:3;:10;59936:1;:14;59919:55;;;59968:3;59972:1;59968:6;;;;;;-1:-1:-1;;;59968:6:0;;;;;;;;;;;;;-1:-1:-1;;;;;;59968:6:0;59957:3;59961;;;;:::i;:::-;;;59957:8;;;;;;-1:-1:-1;;;59957:8:0;;;;;;;;;;;;:17;-1:-1:-1;;;;;59957:17:0;;;;;;;;-1:-1:-1;59952:3:0;;;;:::i;:::-;;;;59919:55;;;;59990:6;59985:55;60006:3;:10;60002:1;:14;59985:55;;;60034:3;60038:1;60034:6;;;;;;-1:-1:-1;;;60034:6:0;;;;;;;;;;;;;-1:-1:-1;;;;;;60034:6:0;60023:3;60027;;;;:::i;:::-;;;60023:8;;;;;;-1:-1:-1;;;60023:8:0;;;;;;;;;;;;:17;-1:-1:-1;;;;;60023:17:0;;;;;;;;-1:-1:-1;60018:3:0;;;;:::i;:::-;;;;59985:55;;;-1:-1:-1;60065:3:0;;-1:-1:-1;;;;;59515:562:0;;;;;;:::o;29766:716::-;30190:23;30216:69;30244:4;30216:69;;;;;;;;;;;;;;;;;30224:5;-1:-1:-1;;;;;30216:27:0;;;:69;;;;;:::i;:::-;30300:17;;30190:95;;-1:-1:-1;30300:21:0;30296:179;;30397:10;30386:30;;;;;;;;;;;;:::i;:::-;30378:85;;;;-1:-1:-1;;;30378:85:0;;28025:2:1;30378:85:0;;;28007:21:1;28064:2;28044:18;;;28037:30;28103:34;28083:18;;;28076:62;-1:-1:-1;;;28154:18:1;;;28147:40;28204:19;;30378:85:0;27997:232:1;64447:329:0;64702:66;64729:8;64739:4;64745:2;64749:3;64754:7;64763:4;64702:26;:66::i;56309:813::-;-1:-1:-1;;;;;56549:13:0;;19521:19;:23;56545:570;;56585:79;;-1:-1:-1;;;56585:79:0;;-1:-1:-1;;;;;56585:43:0;;;;;:79;;56629:8;;56639:4;;56645:3;;56650:7;;56659:4;;56585:79;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56585:79:0;;;;;;;;-1:-1:-1;;56585:79:0;;;;;;;;;;;;:::i;:::-;;;56581:523;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;56977:6;56970:14;;-1:-1:-1;;;56970:14:0;;;;;;;;:::i;56581:523::-;;;57026:62;;-1:-1:-1;;;57026:62:0;;20117:2:1;57026:62:0;;;20099:21:1;20156:2;20136:18;;;20129:30;20195:34;20175:18;;;20168:62;-1:-1:-1;;;20246:18:1;;;20239:50;20306:19;;57026:62:0;20089:242:1;56581:523:0;-1:-1:-1;;;;;;56746:60:0;;-1:-1:-1;;;56746:60:0;56742:159;;56831:50;;-1:-1:-1;;;56831:50:0;;;;;;;:::i;7343:1308::-;7424:7;7433:12;7658:9;:16;7678:2;7658:22;7654:990;;;7954:4;7939:20;;7933:27;8004:4;7989:20;;7983:27;8062:4;8047:20;;8041:27;7697:9;8033:36;8105:25;8116:4;8033:36;7933:27;7983;8105:10;:25::i;:::-;8098:32;;;;;;;;;7654:990;8152:9;:16;8172:2;8152:22;8148:496;;;8427:4;8412:20;;8406:27;8478:4;8463:20;;8457:27;8520:23;8531:4;8406:27;8457;8520:10;:23::i;:::-;8513:30;;;;;;;;8148:496;-1:-1:-1;8592:1:0;;-1:-1:-1;8596:35:0;8576:56;;5614:643;5692:20;5683:5;:29;;;;;;-1:-1:-1;;;5683:29:0;;;;;;;;;;5679:571;;;5614:643;:::o;5679:571::-;5790:29;5781:5;:38;;;;;;-1:-1:-1;;;5781:38:0;;;;;;;;;;5777:473;;;5836:34;;-1:-1:-1;;;5836:34:0;;19764:2:1;5836:34:0;;;19746:21:1;19803:2;19783:18;;;19776:30;19842:26;19822:18;;;19815:54;19886:18;;5836:34:0;19736:174:1;5777:473:0;5901:35;5892:5;:44;;;;;;-1:-1:-1;;;5892:44:0;;;;;;;;;;5888:362;;;5953:41;;-1:-1:-1;;;5953:41:0;;20947:2:1;5953:41:0;;;20929:21:1;20986:2;20966:18;;;20959:30;21025:33;21005:18;;;20998:61;21076:18;;5953:41:0;20919:181:1;5888:362:0;6025:30;6016:5;:39;;;;;;-1:-1:-1;;;6016:39:0;;;;;;;;;;6012:238;;;6072:44;;-1:-1:-1;;;6072:44:0;;22941:2:1;6072:44:0;;;22923:21:1;22980:2;22960:18;;;22953:30;23019:34;22999:18;;;22992:62;-1:-1:-1;;;23070:18:1;;;23063:32;23112:19;;6072:44:0;22913:224:1;6012:238:0;6147:30;6138:5;:39;;;;;;-1:-1:-1;;;6138:39:0;;;;;;;;;;6134:116;;;6194:44;;-1:-1:-1;;;6194:44:0;;25269:2:1;6194:44:0;;;25251:21:1;25308:2;25288:18;;;25281:30;25347:34;25327:18;;;25320:62;-1:-1:-1;;;25398:18:1;;;25391:32;25440:19;;6194:44:0;25241:224:1;57130:198:0;57250:16;;;57264:1;57250:16;;;;;;;;;57196;;57225:22;;57250:16;;;;;;;;;;;;-1:-1:-1;57250:16:0;57225:41;;57288:7;57277:5;57283:1;57277:8;;;;;;-1:-1:-1;;;57277:8:0;;;;;;;;;;;;;;;;;;:18;57315:5;57130:198;-1:-1:-1;;57130:198:0:o;55557:744::-;-1:-1:-1;;;;;55772:13:0;;19521:19;:23;55768:526;;55808:72;;-1:-1:-1;;;55808:72:0;;-1:-1:-1;;;;;55808:38:0;;;;;:72;;55847:8;;55857:4;;55863:2;;55867:6;;55875:4;;55808:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55808:72:0;;;;;;;;-1:-1:-1;;55808:72:0;;;;;;;;;;;;:::i;:::-;;;55804:479;;;;:::i;:::-;-1:-1:-1;;;;;;55930:55:0;;-1:-1:-1;;;55930:55:0;55926:154;;56010:50;;-1:-1:-1;;;56010:50:0;;;;;;;:::i;21971:229::-;22108:12;22140:52;22162:6;22170:4;22176:1;22179:12;22140:21;:52::i;58483:931::-;-1:-1:-1;;;;;58805:18:0;;58801:160;;58845:9;58840:110;58864:3;:10;58860:1;:14;58840:110;;;58924:7;58932:1;58924:10;;;;;;-1:-1:-1;;;58924:10:0;;;;;;;;;;;;;;;58900:12;:20;58913:3;58917:1;58913:6;;;;;;-1:-1:-1;;;58913:6:0;;;;;;;;;;;;;;;58900:20;;;;;;;;;;;;:34;;;;;;;:::i;:::-;;;;-1:-1:-1;58876:3:0;;-1:-1:-1;58876:3:0;;:::i;:::-;;;58840:110;;;;58801:160;-1:-1:-1;;;;;58977:16:0;;58973:434;;59015:9;59010:386;59034:3;:10;59030:1;:14;59010:386;;;59070:10;59083:3;59087:1;59083:6;;;;;;-1:-1:-1;;;59083:6:0;;;;;;;;;;;;;;;59070:19;;59108:14;59125:7;59133:1;59125:10;;;;;;-1:-1:-1;;;59125:10:0;;;;;;;;;;;;;;;59108:27;;59154:14;59171:12;:16;59184:2;59171:16;;;;;;;;;;;;59154:33;;59224:6;59214;:16;;59206:69;;;;-1:-1:-1;;;59206:69:0;;26848:2:1;59206:69:0;;;26830:21:1;26887:2;26867:18;;;26860:30;26926:34;26906:18;;;26899:62;-1:-1:-1;;;26977:18:1;;;26970:38;27025:19;;59206:69:0;26820:230:1;59206:69:0;59327:16;;;;:12;:16;;;;;;59346:15;;59327:34;;59046:3;;;:::i;:::-;;;59010:386;;10905:1632;11036:7;;11970:66;11957:79;;11953:163;;;-1:-1:-1;12069:1:0;;-1:-1:-1;12073:30:0;12053:51;;11953:163;12130:1;:7;;12135:2;12130:7;;:18;;;;;12141:1;:7;;12146:2;12141:7;;12130:18;12126:102;;;-1:-1:-1;12181:1:0;;-1:-1:-1;12185:30:0;12165:51;;12126:102;12342:24;;;12325:14;12342:24;;;;;;;;;18941:25:1;;;19014:4;19002:17;;18982:18;;;18975:45;;;;19036:18;;;19029:34;;;19079:18;;;19072:34;;;12342:24:0;;18913:19:1;;12342:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;12342:24:0;;-1:-1:-1;;12342:24:0;;;-1:-1:-1;;;;;;;12381:20:0;;12377:103;;12434:1;12438:29;12418:50;;;;;;;12377:103;12500:6;-1:-1:-1;12508:20:0;;-1:-1:-1;10905:1632:0;;;;;;;;:::o;9947:344::-;10061:7;;-1:-1:-1;;;;;10107:80:0;;10061:7;10214:25;10230:3;10215:18;;;10237:2;10214:25;:::i;:::-;10198:42;;10258:25;10269:4;10275:1;10278;10281;10258:10;:25::i;:::-;10251:32;;;;;;9947:344;;;;;;:::o;23091:510::-;23261:12;23319:5;23294:21;:30;;23286:81;;;;-1:-1:-1;;;23286:81:0;;23344:2:1;23286:81:0;;;23326:21:1;23383:2;23363:18;;;23356:30;23422:34;23402:18;;;23395:62;-1:-1:-1;;;23473:18:1;;;23466:36;23519:19;;23286:81:0;23316:228:1;23286:81:0;-1:-1:-1;;;;;19521:19:0;;;23378:60;;;;-1:-1:-1;;;23378:60:0;;27257:2:1;23378:60:0;;;27239:21:1;27296:2;27276:18;;;27269:30;27335:31;27315:18;;;27308:59;27384:18;;23378:60:0;27229:179:1;23378:60:0;23452:12;23466:23;23493:6;-1:-1:-1;;;;;23493:11:0;23512:5;23519:4;23493:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23451:73;;;;23542:51;23559:7;23568:10;23580:12;23542:16;:51::i;:::-;23535:58;23091:510;-1:-1:-1;;;;;;;23091:510:0:o;25777:712::-;25927:12;25956:7;25952:530;;;-1:-1:-1;25987:10:0;25980:17;;25952:530;26101:17;;:21;26097:374;;26299:10;26293:17;26360:15;26347:10;26343:2;26339:19;26332:44;26247:148;26442:12;26435:20;;-1:-1:-1;;;26435:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:173:1;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:2;;177:1;174;167:12;111:2;63:124;;;:::o;192:761::-;246:5;299:3;292:4;284:6;280:17;276:27;266:2;;321:5;314;307:20;266:2;361:6;348:20;387:4;410:43;450:2;410:43;:::i;:::-;482:2;476:9;494:31;522:2;514:6;494:31;:::i;:::-;560:18;;;594:15;;;;-1:-1:-1;629:15:1;;;679:1;675:10;;;663:23;;659:32;;656:41;-1:-1:-1;653:2:1;;;714:5;707;700:20;653:2;740:5;754:169;768:2;765:1;762:9;754:169;;;825:23;844:3;825:23;:::i;:::-;813:36;;869:12;;;;901;;;;786:1;779:9;754:169;;;-1:-1:-1;941:6:1;;256:697;-1:-1:-1;;;;;;;256:697:1:o;958:755::-;1012:5;1065:3;1058:4;1050:6;1046:17;1042:27;1032:2;;1087:5;1080;1073:20;1032:2;1127:6;1114:20;1153:4;1176:43;1216:2;1176:43;:::i;:::-;1248:2;1242:9;1260:31;1288:2;1280:6;1260:31;:::i;:::-;1326:18;;;1360:15;;;;-1:-1:-1;1395:15:1;;;1445:1;1441:10;;;1429:23;;1425:32;;1422:41;-1:-1:-1;1419:2:1;;;1480:5;1473;1466:20;1419:2;1506:5;1520:163;1534:2;1531:1;1528:9;1520:163;;;1591:17;;1579:30;;1629:12;;;;1661;;;;1552:1;1545:9;1520:163;;1718:575;1760:5;1813:3;1806:4;1798:6;1794:17;1790:27;1780:2;;1835:5;1828;1821:20;1780:2;1875:6;1862:20;-1:-1:-1;;;;;1897:2:1;1894:26;1891:2;;;1923:18;;:::i;:::-;1972:2;1966:9;1984:67;2039:2;2020:13;;-1:-1:-1;;2016:27:1;2045:4;2012:38;1966:9;1984:67;:::i;:::-;2075:2;2067:6;2060:18;2121:3;2114:4;2109:2;2101:6;2097:15;2093:26;2090:35;2087:2;;;2142:5;2135;2128:20;2087:2;2210;2203:4;2195:6;2191:17;2184:4;2176:6;2172:17;2159:54;2233:15;;;2250:4;2229:26;2222:41;;;;2237:6;1770:523;-1:-1:-1;;1770:523:1:o;2298:196::-;2357:6;2410:2;2398:9;2389:7;2385:23;2381:32;2378:2;;;2431:6;2423;2416:22;2378:2;2459:29;2478:9;2459:29;:::i;2499:270::-;2567:6;2575;2628:2;2616:9;2607:7;2603:23;2599:32;2596:2;;;2649:6;2641;2634:22;2596:2;2677:29;2696:9;2677:29;:::i;:::-;2667:39;;2725:38;2759:2;2748:9;2744:18;2725:38;:::i;:::-;2715:48;;2586:183;;;;;:::o;2774:983::-;2928:6;2936;2944;2952;2960;3013:3;3001:9;2992:7;2988:23;2984:33;2981:2;;;3035:6;3027;3020:22;2981:2;3063:29;3082:9;3063:29;:::i;:::-;3053:39;;3111:38;3145:2;3134:9;3130:18;3111:38;:::i;:::-;3101:48;;3200:2;3189:9;3185:18;3172:32;-1:-1:-1;;;;;3264:2:1;3256:6;3253:14;3250:2;;;3285:6;3277;3270:22;3250:2;3313:61;3366:7;3357:6;3346:9;3342:22;3313:61;:::i;:::-;3303:71;;3427:2;3416:9;3412:18;3399:32;3383:48;;3456:2;3446:8;3443:16;3440:2;;;3477:6;3469;3462:22;3440:2;3505:63;3560:7;3549:8;3538:9;3534:24;3505:63;:::i;:::-;3495:73;;3621:3;3610:9;3606:19;3593:33;3577:49;;3651:2;3641:8;3638:16;3635:2;;;3672:6;3664;3657:22;3635:2;;3700:51;3743:7;3732:8;3721:9;3717:24;3700:51;:::i;:::-;3690:61;;;2971:786;;;;;;;;:::o;3762:626::-;3866:6;3874;3882;3890;3898;3951:3;3939:9;3930:7;3926:23;3922:33;3919:2;;;3973:6;3965;3958:22;3919:2;4001:29;4020:9;4001:29;:::i;:::-;3991:39;;4049:38;4083:2;4072:9;4068:18;4049:38;:::i;:::-;4039:48;;4134:2;4123:9;4119:18;4106:32;4096:42;;4185:2;4174:9;4170:18;4157:32;4147:42;;4240:3;4229:9;4225:19;4212:33;-1:-1:-1;;;;;4260:6:1;4257:30;4254:2;;;4305:6;4297;4290:22;4254:2;4333:49;4374:7;4365:6;4354:9;4350:22;4333:49;:::i;4393:699::-;4520:6;4528;4536;4589:2;4577:9;4568:7;4564:23;4560:32;4557:2;;;4610:6;4602;4595:22;4557:2;4638:29;4657:9;4638:29;:::i;:::-;4628:39;;4718:2;4707:9;4703:18;4690:32;-1:-1:-1;;;;;4782:2:1;4774:6;4771:14;4768:2;;;4803:6;4795;4788:22;4768:2;4831:61;4884:7;4875:6;4864:9;4860:22;4831:61;:::i;:::-;4821:71;;4945:2;4934:9;4930:18;4917:32;4901:48;;4974:2;4964:8;4961:16;4958:2;;;4995:6;4987;4980:22;4958:2;;5023:63;5078:7;5067:8;5056:9;5052:24;5023:63;:::i;:::-;5013:73;;;4547:545;;;;;:::o;5097:908::-;5242:6;5250;5258;5266;5319:3;5307:9;5298:7;5294:23;5290:33;5287:2;;;5341:6;5333;5326:22;5287:2;5369:29;5388:9;5369:29;:::i;:::-;5359:39;;5449:2;5438:9;5434:18;5421:32;-1:-1:-1;;;;;5513:2:1;5505:6;5502:14;5499:2;;;5534:6;5526;5519:22;5499:2;5562:61;5615:7;5606:6;5595:9;5591:22;5562:61;:::i;:::-;5552:71;;5676:2;5665:9;5661:18;5648:32;5632:48;;5705:2;5695:8;5692:16;5689:2;;;5726:6;5718;5711:22;5689:2;5754:63;5809:7;5798:8;5787:9;5783:24;5754:63;:::i;:::-;5744:73;;5870:2;5859:9;5855:18;5842:32;5826:48;;5899:2;5889:8;5886:16;5883:2;;;5920:6;5912;5905:22;5883:2;;5948:51;5991:7;5980:8;5969:9;5965:24;5948:51;:::i;:::-;5938:61;;;5277:728;;;;;;;:::o;6010:325::-;6075:6;6083;6136:2;6124:9;6115:7;6111:23;6107:32;6104:2;;;6157:6;6149;6142:22;6104:2;6185:29;6204:9;6185:29;:::i;:::-;6175:39;;6264:2;6253:9;6249:18;6236:32;6277:28;6299:5;6277:28;:::i;:::-;6324:5;6314:15;;;6094:241;;;;;:::o;6340:264::-;6408:6;6416;6469:2;6457:9;6448:7;6444:23;6440:32;6437:2;;;6490:6;6482;6475:22;6437:2;6518:29;6537:9;6518:29;:::i;:::-;6508:39;6594:2;6579:18;;;;6566:32;;-1:-1:-1;;;6427:177:1:o;6609:332::-;6686:6;6694;6702;6755:2;6743:9;6734:7;6730:23;6726:32;6723:2;;;6776:6;6768;6761:22;6723:2;6804:29;6823:9;6804:29;:::i;:::-;6794:39;6880:2;6865:18;;6852:32;;-1:-1:-1;6931:2:1;6916:18;;;6903:32;;6713:228;-1:-1:-1;;;6713:228:1:o;6946:551::-;7041:6;7049;7057;7065;7118:3;7106:9;7097:7;7093:23;7089:33;7086:2;;;7140:6;7132;7125:22;7086:2;7168:29;7187:9;7168:29;:::i;:::-;7158:39;;7244:2;7233:9;7229:18;7216:32;7206:42;;7295:2;7284:9;7280:18;7267:32;7257:42;;7350:2;7339:9;7335:18;7322:32;-1:-1:-1;;;;;7369:6:1;7366:30;7363:2;;;7414:6;7406;7399:22;7363:2;7442:49;7483:7;7474:6;7463:9;7459:22;7442:49;:::i;7502:401::-;7588:6;7596;7604;7612;7665:3;7653:9;7644:7;7640:23;7636:33;7633:2;;;7687:6;7679;7672:22;7633:2;7715:29;7734:9;7715:29;:::i;:::-;7705:39;7791:2;7776:18;;7763:32;;-1:-1:-1;7842:2:1;7827:18;;7814:32;;7893:2;7878:18;7865:32;;-1:-1:-1;7623:280:1;-1:-1:-1;;;7623:280:1:o;7908:368::-;7992:6;8045:2;8033:9;8024:7;8020:23;8016:32;8013:2;;;8066:6;8058;8051:22;8013:2;8111:9;8098:23;-1:-1:-1;;;;;8136:6:1;8133:30;8130:2;;;8181:6;8173;8166:22;8130:2;8209:61;8262:7;8253:6;8242:9;8238:22;8209:61;:::i;8281:625::-;8399:6;8407;8460:2;8448:9;8439:7;8435:23;8431:32;8428:2;;;8481:6;8473;8466:22;8428:2;8526:9;8513:23;-1:-1:-1;;;;;8596:2:1;8588:6;8585:14;8582:2;;;8617:6;8609;8602:22;8582:2;8645:61;8698:7;8689:6;8678:9;8674:22;8645:61;:::i;:::-;8635:71;;8759:2;8748:9;8744:18;8731:32;8715:48;;8788:2;8778:8;8775:16;8772:2;;;8809:6;8801;8794:22;8772:2;;8837:63;8892:7;8881:8;8870:9;8866:24;8837:63;:::i;:::-;8827:73;;;8418:488;;;;;:::o;8911:665::-;9022:6;9030;9038;9091:2;9079:9;9070:7;9066:23;9062:32;9059:2;;;9112:6;9104;9097:22;9059:2;9157:9;9144:23;-1:-1:-1;;;;;9227:2:1;9219:6;9216:14;9213:2;;;9248:6;9240;9233:22;9213:2;9276:61;9329:7;9320:6;9309:9;9305:22;9276:61;:::i;:::-;9266:71;;9384:2;9373:9;9369:18;9356:32;9346:42;;9441:2;9430:9;9426:18;9413:32;9397:48;;9470:2;9460:8;9457:16;9454:2;;;9491:6;9483;9476:22;9454:2;;9519:51;9562:7;9551:8;9540:9;9536:24;9519:51;:::i;9581:255::-;9648:6;9701:2;9689:9;9680:7;9676:23;9672:32;9669:2;;;9722:6;9714;9707:22;9669:2;9759:9;9753:16;9778:28;9800:5;9778:28;:::i;9841:255::-;9899:6;9952:2;9940:9;9931:7;9927:23;9923:32;9920:2;;;9973:6;9965;9958:22;9920:2;10017:9;10004:23;10036:30;10060:5;10036:30;:::i;10101:259::-;10170:6;10223:2;10211:9;10202:7;10198:23;10194:32;10191:2;;;10244:6;10236;10229:22;10191:2;10281:9;10275:16;10300:30;10324:5;10300:30;:::i;10365:414::-;10442:6;10450;10503:2;10491:9;10482:7;10478:23;10474:32;10471:2;;;10524:6;10516;10509:22;10471:2;10569:9;10556:23;-1:-1:-1;;;;;10594:6:1;10591:30;10588:2;;;10639:6;10631;10624:22;10588:2;10667:49;10708:7;10699:6;10688:9;10684:22;10667:49;:::i;:::-;10657:59;;;10735:38;10769:2;10758:9;10754:18;10735:38;:::i;10784:341::-;10853:6;10906:2;10894:9;10885:7;10881:23;10877:32;10874:2;;;10927:6;10919;10912:22;10874:2;10972:9;10959:23;-1:-1:-1;;;;;10997:6:1;10994:30;10991:2;;;11042:6;11034;11027:22;10991:2;11070:49;11111:7;11102:6;11091:9;11087:22;11070:49;:::i;11130:190::-;11189:6;11242:2;11230:9;11221:7;11217:23;11213:32;11210:2;;;11263:6;11255;11248:22;11210:2;-1:-1:-1;11291:23:1;;11200:120;-1:-1:-1;11200:120:1:o;11325:409::-;11403:6;11411;11464:2;11452:9;11443:7;11439:23;11435:32;11432:2;;;11485:6;11477;11470:22;11432:2;11526:9;11513:23;11503:33;;11587:2;11576:9;11572:18;11559:32;-1:-1:-1;;;;;11606:6:1;11603:30;11600:2;;;11651:6;11643;11636:22;11600:2;11679:49;11720:7;11711:6;11700:9;11696:22;11679:49;:::i;11739:258::-;11807:6;11815;11868:2;11856:9;11847:7;11843:23;11839:32;11836:2;;;11889:6;11881;11874:22;11836:2;-1:-1:-1;;11917:23:1;;;11987:2;11972:18;;;11959:32;;-1:-1:-1;11826:171:1:o;12002:332::-;12079:6;12087;12095;12148:2;12136:9;12127:7;12123:23;12119:32;12116:2;;;12169:6;12161;12154:22;12116:2;12210:9;12197:23;12187:33;;12267:2;12256:9;12252:18;12239:32;12229:42;;12290:38;12324:2;12313:9;12309:18;12290:38;:::i;:::-;12280:48;;12106:228;;;;;:::o;12339:437::-;12392:3;12430:5;12424:12;12457:6;12452:3;12445:19;12483:4;12512:2;12507:3;12503:12;12496:19;;12549:2;12542:5;12538:14;12570:3;12582:169;12596:6;12593:1;12590:13;12582:169;;;12657:13;;12645:26;;12691:12;;;;12726:15;;;;12618:1;12611:9;12582:169;;;-1:-1:-1;12767:3:1;;12400:376;-1:-1:-1;;;;;12400:376:1:o;12781:257::-;12822:3;12860:5;12854:12;12887:6;12882:3;12875:19;12903:63;12959:6;12952:4;12947:3;12943:14;12936:4;12929:5;12925:16;12903:63;:::i;:::-;13020:2;12999:15;-1:-1:-1;;12995:29:1;12986:39;;;;13027:4;12982:50;;12830:208;-1:-1:-1;;12830:208:1:o;13043:274::-;13172:3;13210:6;13204:13;13226:53;13272:6;13267:3;13260:4;13252:6;13248:17;13226:53;:::i;:::-;13295:16;;;;;13180:137;-1:-1:-1;;13180:137:1:o;13322:1103::-;13450:3;13479;13514:6;13508:13;13544:3;13566:1;13594:9;13590:2;13586:18;13576:28;;13654:2;13643:9;13639:18;13676;13666:2;;13720:4;13712:6;13708:17;13698:27;;13666:2;13746;13794;13786:6;13783:14;13763:18;13760:38;13757:2;;;-1:-1:-1;;;13821:33:1;;13877:4;13874:1;13867:15;13907:4;13828:3;13895:17;13757:2;13938:18;13965:104;;;;14083:1;14078:322;;;;13931:469;;13965:104;-1:-1:-1;;13998:24:1;;13986:37;;14043:16;;;;-1:-1:-1;13965:104:1;;14078:322;30125:4;30144:17;;;30194:4;30178:21;;14173:3;14189:165;14203:6;14200:1;14197:13;14189:165;;;14281:14;;14268:11;;;14261:35;14324:16;;;;14218:10;;14189:165;;;14193:3;;14383:6;14378:3;14374:16;14367:23;;13931:469;-1:-1:-1;14416:3:1;;13458:967;-1:-1:-1;;;;;;;;13458:967:1:o;15721:826::-;-1:-1:-1;;;;;16118:15:1;;;16100:34;;16170:15;;16165:2;16150:18;;16143:43;16080:3;16217:2;16202:18;;16195:31;;;16043:4;;16249:57;;16286:19;;16278:6;16249:57;:::i;:::-;16354:9;16346:6;16342:22;16337:2;16326:9;16322:18;16315:50;16388:44;16425:6;16417;16388:44;:::i;:::-;16374:58;;16481:9;16473:6;16469:22;16463:3;16452:9;16448:19;16441:51;16509:32;16534:6;16526;16509:32;:::i;:::-;16501:40;16052:495;-1:-1:-1;;;;;;;;16052:495:1:o;16932:560::-;-1:-1:-1;;;;;17229:15:1;;;17211:34;;17281:15;;17276:2;17261:18;;17254:43;17328:2;17313:18;;17306:34;;;17371:2;17356:18;;17349:34;;;17191:3;17414;17399:19;;17392:32;;;17154:4;;17441:45;;17466:19;;17458:6;17441:45;:::i;17786:261::-;17965:2;17954:9;17947:21;17928:4;17985:56;18037:2;18026:9;18022:18;18014:6;17985:56;:::i;18052:465::-;18309:2;18298:9;18291:21;18272:4;18335:56;18387:2;18376:9;18372:18;18364:6;18335:56;:::i;:::-;18439:9;18431:6;18427:22;18422:2;18411:9;18407:18;18400:50;18467:44;18504:6;18496;18467:44;:::i;:::-;18459:52;18281:236;-1:-1:-1;;;;;18281:236:1:o;19338:219::-;19487:2;19476:9;19469:21;19450:4;19507:44;19547:2;19536:9;19532:18;19524:6;19507:44;:::i;20336:404::-;20538:2;20520:21;;;20577:2;20557:18;;;20550:30;20616:34;20611:2;20596:18;;20589:62;-1:-1:-1;;;20682:2:1;20667:18;;20660:38;20730:3;20715:19;;20510:230::o;21924:400::-;22126:2;22108:21;;;22165:2;22145:18;;;22138:30;22204:34;22199:2;22184:18;;22177:62;-1:-1:-1;;;22270:2:1;22255:18;;22248:34;22314:3;22299:19;;22098:226::o;22329:405::-;22531:2;22513:21;;;22570:2;22550:18;;;22543:30;22609:34;22604:2;22589:18;;22582:62;-1:-1:-1;;;22675:2:1;22660:18;;22653:39;22724:3;22709:19;;22503:231::o;24242:401::-;24444:2;24426:21;;;24483:2;24463:18;;;24456:30;24522:34;24517:2;24502:18;;24495:62;-1:-1:-1;;;24588:2:1;24573:18;;24566:35;24633:3;24618:19;;24416:227::o;25470:399::-;25672:2;25654:21;;;25711:2;25691:18;;;25684:30;25750:34;25745:2;25730:18;;25723:62;-1:-1:-1;;;25816:2:1;25801:18;;25794:33;25859:3;25844:19;;25644:225::o;25874:406::-;26076:2;26058:21;;;26115:2;26095:18;;;26088:30;26154:34;26149:2;26134:18;;26127:62;-1:-1:-1;;;26220:2:1;26205:18;;26198:40;26270:3;26255:19;;26048:232::o;26285:356::-;26487:2;26469:21;;;26506:18;;;26499:30;26565:34;26560:2;26545:18;;26538:62;26632:2;26617:18;;26459:182::o;28644:404::-;28846:2;28828:21;;;28885:2;28865:18;;;28858:30;28924:34;28919:2;28904:18;;28897:62;-1:-1:-1;;;28990:2:1;28975:18;;28968:38;29038:3;29023:19;;28818:230::o;29053:397::-;29255:2;29237:21;;;29294:2;29274:18;;;29267:30;29333:34;29328:2;29313:18;;29306:62;-1:-1:-1;;;29399:2:1;29384:18;;29377:31;29440:3;29425:19;;29227:223::o;29890:183::-;29950:4;-1:-1:-1;;;;;29975:6:1;29972:30;29969:2;;;30005:18;;:::i;:::-;-1:-1:-1;30050:1:1;30046:14;30062:4;30042:25;;29959:114::o;30210:128::-;30250:3;30281:1;30277:6;30274:1;30271:13;30268:2;;;30287:18;;:::i;:::-;-1:-1:-1;30323:9:1;;30258:80::o;30343:120::-;30383:1;30409;30399:2;;30414:18;;:::i;:::-;-1:-1:-1;30448:9:1;;30389:74::o;30468:125::-;30508:4;30536:1;30533;30530:8;30527:2;;;30541:18;;:::i;:::-;-1:-1:-1;30578:9:1;;30517:76::o;30598:258::-;30670:1;30680:113;30694:6;30691:1;30688:13;30680:113;;;30770:11;;;30764:18;30751:11;;;30744:39;30716:2;30709:10;30680:113;;;30811:6;30808:1;30805:13;30802:2;;;-1:-1:-1;;30846:1:1;30828:16;;30821:27;30651:205::o;30861:380::-;30940:1;30936:12;;;;30983;;;31004:2;;31058:4;31050:6;31046:17;31036:27;;31004:2;31111;31103:6;31100:14;31080:18;31077:38;31074:2;;;31157:10;31152:3;31148:20;31145:1;31138:31;31192:4;31189:1;31182:15;31220:4;31217:1;31210:15;31074:2;;30916:325;;;:::o;31246:249::-;31356:2;31337:13;;-1:-1:-1;;31333:27:1;31321:40;;-1:-1:-1;;;;;31376:34:1;;31412:22;;;31373:62;31370:2;;;31438:18;;:::i;:::-;31474:2;31467:22;-1:-1:-1;;31293:202:1:o;31500:135::-;31539:3;-1:-1:-1;;31560:17:1;;31557:2;;;31580:18;;:::i;:::-;-1:-1:-1;31627:1:1;31616:13;;31547:88::o;31640:112::-;31672:1;31698;31688:2;;31703:18;;:::i;:::-;-1:-1:-1;31737:9:1;;31678:74::o;31757:127::-;31818:10;31813:3;31809:20;31806:1;31799:31;31849:4;31846:1;31839:15;31873:4;31870:1;31863:15;31889:127;31950:10;31945:3;31941:20;31938:1;31931:31;31981:4;31978:1;31971:15;32005:4;32002:1;31995:15;32021:127;32082:10;32077:3;32073:20;32070:1;32063:31;32113:4;32110:1;32103:15;32137:4;32134:1;32127:15;32153:185;32188:3;32230:1;32212:16;32209:23;32206:2;;;32280:1;32275:3;32270;32255:27;32311:10;32306:3;32302:20;32206:2;32196:142;:::o;32343:671::-;32382:3;32424:4;32406:16;32403:26;32400:2;;;32390:624;:::o;32400:2::-;32466;32460:9;-1:-1:-1;;32531:16:1;32527:25;;32524:1;32460:9;32503:50;32582:4;32576:11;32606:16;-1:-1:-1;;;;;32712:2:1;32705:4;32697:6;32693:17;32690:25;32685:2;32677:6;32674:14;32671:45;32668:2;;;32719:5;;;;;32390:624;:::o;32668:2::-;32756:6;32750:4;32746:17;32735:28;;32792:3;32786:10;32819:2;32811:6;32808:14;32805:2;;;32825:5;;;;;;32390:624;:::o;32805:2::-;32909;32890:16;32884:4;32880:27;32876:36;32869:4;32860:6;32855:3;32851:16;32847:27;32844:69;32841:2;;;32916:5;;;;;;32390:624;:::o;32841:2::-;32932:57;32983:4;32974:6;32966;32962:19;32958:30;32952:4;32932:57;:::i;:::-;-1:-1:-1;33005:3:1;;32390:624;-1:-1:-1;;;;;32390:624:1:o;33019:118::-;33105:5;33098:13;33091:21;33084:5;33081:32;33071:2;;33127:1;33124;33117:12;33142:131;-1:-1:-1;;;;;;33216:32:1;;33206:43;;33196:2;;33263:1;33260;33253:12

Swarm Source

ipfs://f9c047f1c465e235ecdbac9e4e100a65f514038b174c92282661a4105c77487f
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.