ETH Price: $1,904.96 (+2.46%)
 

Overview

Max Total Supply

94 CASHRUSH

Holders

57

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
ultrawox.eth
Balance
1 CASHRUSH
0xa2964b09b31b8cff7c0187c1d5cba51176c6d3b7
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:
CashRushNft

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-04-01
*/

// Dependency file: @openzeppelin/contracts/utils/introspection/IERC165.sol

// SPDX-License-Identifier: MIT
// 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);
}


// Dependency file: @openzeppelin/contracts/token/ERC721/IERC721.sol

// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

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

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

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

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

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

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


// Dependency file: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol

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

// pragma solidity ^0.8.0;

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


// Dependency file: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol

// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

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

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

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


// Dependency file: @openzeppelin/contracts/utils/Address.sol

// OpenZeppelin Contracts (last updated v4.8.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 functionCallWithValue(target, data, 0, "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");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or 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 {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // 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
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}


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


// Dependency file: @openzeppelin/contracts/utils/math/Math.sol

// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

// pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

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

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

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

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

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10**64) {
                value /= 10**64;
                result += 64;
            }
            if (value >= 10**32) {
                value /= 10**32;
                result += 32;
            }
            if (value >= 10**16) {
                value /= 10**16;
                result += 16;
            }
            if (value >= 10**8) {
                value /= 10**8;
                result += 8;
            }
            if (value >= 10**4) {
                value /= 10**4;
                result += 4;
            }
            if (value >= 10**2) {
                value /= 10**2;
                result += 2;
            }
            if (value >= 10**1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}


// Dependency file: @openzeppelin/contracts/utils/Strings.sol

// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/utils/math/Math.sol";

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @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] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}


// Dependency file: @openzeppelin/contracts/utils/introspection/ERC165.sol

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

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

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


// Dependency file: @openzeppelin/contracts/token/ERC721/ERC721.sol

// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
// import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
// import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
// import "@openzeppelin/contracts/utils/Address.sol";
// import "@openzeppelin/contracts/utils/Context.sol";
// import "@openzeppelin/contracts/utils/Strings.sol";
// import "@openzeppelin/contracts/utils/introspection/ERC165.sol";

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: address zero is not a valid owner");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _ownerOf(tokenId);
        require(owner != address(0), "ERC721: invalid token ID");
        return owner;
    }

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        _requireMinted(tokenId);

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

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

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

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

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

    /**
     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

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

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

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

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

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

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

        // Check that tokenId was not minted by `_beforeTokenTransfer` hook
        require(!_exists(tokenId), "ERC721: token already minted");

        unchecked {
            // Will not overflow unless all 2**256 token ids are minted to the same owner.
            // Given that tokens are minted one by one, it is impossible in practice that
            // this ever happens. Might change if we allow batch minting.
            // The ERC fails to describe this case.
            _balances[to] += 1;
        }

        _owners[tokenId] = to;

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

        _afterTokenTransfer(address(0), to, tokenId, 1);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     * This is an internal function that does not check if the sender is authorized to operate on the token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

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

        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
        owner = ERC721.ownerOf(tokenId);

        // Clear approvals
        delete _tokenApprovals[tokenId];

        unchecked {
            // Cannot overflow, as that would require more tokens to be burned/transferred
            // out than the owner initially received through minting and transferring in.
            _balances[owner] -= 1;
        }
        delete _owners[tokenId];

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

        _afterTokenTransfer(owner, address(0), tokenId, 1);
    }

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

        _beforeTokenTransfer(from, to, tokenId, 1);

        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");

        // Clear approvals from the previous owner
        delete _tokenApprovals[tokenId];

        unchecked {
            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
            // `from`'s balance is the number of token held, which is at least one before the current
            // transfer.
            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
            // all 2**256 token ids to be minted, which in practice is impossible.
            _balances[from] -= 1;
            _balances[to] += 1;
        }
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId, 1);
    }

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

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
     * - When `from` is zero, the tokens will be minted for `to`.
     * - When `to` is zero, ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256, /* firstTokenId */
        uint256 batchSize
    ) internal virtual {
        if (batchSize > 1) {
            if (from != address(0)) {
                _balances[from] -= batchSize;
            }
            if (to != address(0)) {
                _balances[to] += batchSize;
            }
        }
    }

    /**
     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
     * - When `from` is zero, the tokens were minted for `to`.
     * - When `to` is zero, ``from``'s tokens were burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual {}
}


// Dependency file: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol

// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

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

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


// Dependency file: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol

// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol)

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
// import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";

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

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

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

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

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

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

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

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

    /**
     * @dev See {ERC721-_beforeTokenTransfer}.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, firstTokenId, batchSize);

        if (batchSize > 1) {
            // Will only trigger during construction. Batch transferring (minting) is not available afterwards.
            revert("ERC721Enumerable: consecutive transfers not supported");
        }

        uint256 tokenId = firstTokenId;

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

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

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

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

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

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

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

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

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

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

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

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

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


// Dependency file: @openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol

// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Burnable.sol)

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
// import "@openzeppelin/contracts/utils/Context.sol";

/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be burned (destroyed).
 */
abstract contract ERC721Burnable is Context, ERC721 {
    /**
     * @dev Burns `tokenId`. See {ERC721-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");
        _burn(tokenId);
    }
}


// Dependency file: @openzeppelin/contracts/interfaces/IERC2981.sol

// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}


// Dependency file: @openzeppelin/contracts/token/common/ERC2981.sol

// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol)

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/interfaces/IERC2981.sol";
// import "@openzeppelin/contracts/utils/introspection/ERC165.sol";

/**
 * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
 *
 * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
 * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
 *
 * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
 * fee is specified in basis points by default.
 *
 * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
 * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
 * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
 *
 * _Available since v4.5._
 */
abstract contract ERC2981 is IERC2981, ERC165 {
    struct RoyaltyInfo {
        address receiver;
        uint96 royaltyFraction;
    }

    RoyaltyInfo private _defaultRoyaltyInfo;
    mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;

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

    /**
     * @inheritdoc IERC2981
     */
    function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) {
        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];

        if (royalty.receiver == address(0)) {
            royalty = _defaultRoyaltyInfo;
        }

        uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator();

        return (royalty.receiver, royaltyAmount);
    }

    /**
     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
     * override.
     */
    function _feeDenominator() internal pure virtual returns (uint96) {
        return 10000;
    }

    /**
     * @dev Sets the royalty information that all ids in this contract will default to.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: invalid receiver");

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Removes default royalty information.
     */
    function _deleteDefaultRoyalty() internal virtual {
        delete _defaultRoyaltyInfo;
    }

    /**
     * @dev Sets the royalty information for a specific token id, overriding the global default.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(
        uint256 tokenId,
        address receiver,
        uint96 feeNumerator
    ) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: Invalid parameters");

        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Resets royalty information for the token id back to the global default.
     */
    function _resetTokenRoyalty(uint256 tokenId) internal virtual {
        delete _tokenRoyaltyInfo[tokenId];
    }
}


// Dependency file: operator-filter-registry/src/IOperatorFilterRegistry.sol

// pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    /**
     * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns
     *         true if supplied registrant address is not registered.
     */
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);

    /**
     * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.
     */
    function register(address registrant) external;

    /**
     * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes.
     */
    function registerAndSubscribe(address registrant, address subscription) external;

    /**
     * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another
     *         address without subscribing.
     */
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;

    /**
     * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.
     *         Note that this does not remove any filtered addresses or codeHashes.
     *         Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.
     */
    function unregister(address addr) external;

    /**
     * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.
     */
    function updateOperator(address registrant, address operator, bool filtered) external;

    /**
     * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.
     */
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;

    /**
     * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.
     */
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;

    /**
     * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.
     */
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;

    /**
     * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous
     *         subscription if present.
     *         Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,
     *         subscriptions will not be forwarded. Instead the former subscription's existing entries will still be
     *         used.
     */
    function subscribe(address registrant, address registrantToSubscribe) external;

    /**
     * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.
     */
    function unsubscribe(address registrant, bool copyExistingEntries) external;

    /**
     * @notice Get the subscription address of a given registrant, if any.
     */
    function subscriptionOf(address addr) external returns (address registrant);

    /**
     * @notice Get the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscribers(address registrant) external returns (address[] memory);

    /**
     * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscriberAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.
     */
    function copyEntriesOf(address registrant, address registrantToCopy) external;

    /**
     * @notice Returns true if operator is filtered by a given address or its subscription.
     */
    function isOperatorFiltered(address registrant, address operator) external returns (bool);

    /**
     * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.
     */
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);

    /**
     * @notice Returns true if a codeHash is filtered by a given address or its subscription.
     */
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);

    /**
     * @notice Returns a list of filtered operators for a given address or its subscription.
     */
    function filteredOperators(address addr) external returns (address[] memory);

    /**
     * @notice Returns the set of filtered codeHashes for a given address or its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);

    /**
     * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);

    /**
     * @notice Returns true if an address has registered
     */
    function isRegistered(address addr) external returns (bool);

    /**
     * @dev Convenience method to compute the code hash of an arbitrary contract
     */
    function codeHashOf(address addr) external returns (bytes32);
}


// Dependency file: operator-filter-registry/src/lib/Constants.sol

// pragma solidity ^0.8.17;

address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E;
address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;


// Dependency file: operator-filter-registry/src/OperatorFilterer.sol

// pragma solidity ^0.8.13;

// import {IOperatorFilterRegistry} from "operator-filter-registry/src/IOperatorFilterRegistry.sol";
// import {CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS} from "operator-filter-registry/src/lib/Constants.sol";
/**
 * @title  OperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 *         Please note that if your token contract does not provide an owner with EIP-173, it must provide
 *         administration methods on the contract itself to interact with the registry otherwise the subscription
 *         will be locked to the options set during construction.
 */

abstract contract OperatorFilterer {
    /// @dev Emitted when an operator is not allowed.
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS);

    /// @dev The constructor that is called when the contract is being deployed.
    constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (subscribe) {
                OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
                } else {
                    OPERATOR_FILTER_REGISTRY.register(address(this));
                }
            }
        }
    }

    /**
     * @dev A helper function to check if an operator is allowed.
     */
    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    /**
     * @dev A helper function to check if an operator approval is allowed.
     */
    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    /**
     * @dev A helper function to check if an operator is allowed.
     */
    function _checkFilterOperator(address operator) internal view virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            // under normal circumstances, this function will revert rather than return false, but inheriting contracts
            // may specify their own OperatorFilterRegistry implementations, which may behave differently
            if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}


// Dependency file: operator-filter-registry/src/DefaultOperatorFilterer.sol

// pragma solidity ^0.8.13;

// import {OperatorFilterer} from "operator-filter-registry/src/OperatorFilterer.sol";
// import {CANONICAL_CORI_SUBSCRIPTION} from "operator-filter-registry/src/lib/Constants.sol";
/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 * @dev    Please note that if your token contract does not provide an owner with EIP-173, it must provide
 *         administration methods on the contract itself to interact with the registry otherwise the subscription
 *         will be locked to the options set during construction.
 */

abstract contract DefaultOperatorFilterer is OperatorFilterer {
    /// @dev The constructor that is called when the contract is being deployed.
    constructor() OperatorFilterer(CANONICAL_CORI_SUBSCRIPTION, true) {}
}


// Dependency file: @openzeppelin/contracts/utils/cryptography/ECDSA.sol

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

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/utils/Strings.sol";

/**
 * @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 // Deprecated in v4.8
    }

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

    /**
     * @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) {
        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.
            /// @solidity memory-safe-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 {
            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 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));
    }
}


// Dependency file: @openzeppelin/contracts/utils/cryptography/EIP712.sol

// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/EIP712.sol)

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";

/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
 * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
 * they need in their contracts using a combination of `abi.encode` and `keccak256`.
 *
 * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
 * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
 * ({_hashTypedDataV4}).
 *
 * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
 * the chain id to protect against replay attacks on an eventual fork of the chain.
 *
 * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
 * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
 *
 * _Available since v3.4._
 */
abstract contract EIP712 {
    /* solhint-disable var-name-mixedcase */
    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
    // invalidate the cached domain separator if the chain id changes.
    bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
    uint256 private immutable _CACHED_CHAIN_ID;
    address private immutable _CACHED_THIS;

    bytes32 private immutable _HASHED_NAME;
    bytes32 private immutable _HASHED_VERSION;
    bytes32 private immutable _TYPE_HASH;

    /* solhint-enable var-name-mixedcase */

    /**
     * @dev Initializes the domain separator and parameter caches.
     *
     * The meaning of `name` and `version` is specified in
     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
     *
     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
     * - `version`: the current major version of the signing domain.
     *
     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
     * contract upgrade].
     */
    constructor(string memory name, string memory version) {
        bytes32 hashedName = keccak256(bytes(name));
        bytes32 hashedVersion = keccak256(bytes(version));
        bytes32 typeHash = keccak256(
            "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
        );
        _HASHED_NAME = hashedName;
        _HASHED_VERSION = hashedVersion;
        _CACHED_CHAIN_ID = block.chainid;
        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
        _CACHED_THIS = address(this);
        _TYPE_HASH = typeHash;
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {
            return _CACHED_DOMAIN_SEPARATOR;
        } else {
            return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
        }
    }

    function _buildDomainSeparator(
        bytes32 typeHash,
        bytes32 nameHash,
        bytes32 versionHash
    ) private view returns (bytes32) {
        return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
    }

    /**
     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
     * function returns the hash of the fully encoded EIP712 message for this domain.
     *
     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
     *
     * ```solidity
     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
     *     keccak256("Mail(address to,string contents)"),
     *     mailTo,
     *     keccak256(bytes(mailContents))
     * )));
     * address signer = ECDSA.recover(digest, signature);
     * ```
     */
    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
    }
}


// Dependency file: @openzeppelin/contracts/utils/cryptography/draft-EIP712.sol

// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/draft-EIP712.sol)

// pragma solidity ^0.8.0;

// EIP-712 is Final as of 2022-08-11. This file is deprecated.

// import "@openzeppelin/contracts/utils/cryptography/EIP712.sol";


// Dependency file: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol

// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol)

// pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 * OpenZeppelin's JavaScript library generates merkle trees that are safe
 * against this attack out of the box.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Calldata version of {verify}
     *
     * _Available since v4.7._
     */
    function verifyCalldata(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Calldata version of {processProof}
     *
     * _Available since v4.7._
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
     * respectively.
     *
     * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}


// Dependency file: @openzeppelin/contracts/utils/Counters.sol

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

// pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}


// Dependency file: @openzeppelin/contracts/utils/math/SafeCast.sol

// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.

// pragma solidity ^0.8.0;

/**
 * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */
library SafeCast {
    /**
     * @dev Returns the downcasted uint248 from uint256, reverting on
     * overflow (when the input is greater than largest uint248).
     *
     * Counterpart to Solidity's `uint248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     *
     * _Available since v4.7._
     */
    function toUint248(uint256 value) internal pure returns (uint248) {
        require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
        return uint248(value);
    }

    /**
     * @dev Returns the downcasted uint240 from uint256, reverting on
     * overflow (when the input is greater than largest uint240).
     *
     * Counterpart to Solidity's `uint240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     *
     * _Available since v4.7._
     */
    function toUint240(uint256 value) internal pure returns (uint240) {
        require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
        return uint240(value);
    }

    /**
     * @dev Returns the downcasted uint232 from uint256, reverting on
     * overflow (when the input is greater than largest uint232).
     *
     * Counterpart to Solidity's `uint232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     *
     * _Available since v4.7._
     */
    function toUint232(uint256 value) internal pure returns (uint232) {
        require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
        return uint232(value);
    }

    /**
     * @dev Returns the downcasted uint224 from uint256, reverting on
     * overflow (when the input is greater than largest uint224).
     *
     * Counterpart to Solidity's `uint224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     *
     * _Available since v4.2._
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
        return uint224(value);
    }

    /**
     * @dev Returns the downcasted uint216 from uint256, reverting on
     * overflow (when the input is greater than largest uint216).
     *
     * Counterpart to Solidity's `uint216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     *
     * _Available since v4.7._
     */
    function toUint216(uint256 value) internal pure returns (uint216) {
        require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
        return uint216(value);
    }

    /**
     * @dev Returns the downcasted uint208 from uint256, reverting on
     * overflow (when the input is greater than largest uint208).
     *
     * Counterpart to Solidity's `uint208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     *
     * _Available since v4.7._
     */
    function toUint208(uint256 value) internal pure returns (uint208) {
        require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
        return uint208(value);
    }

    /**
     * @dev Returns the downcasted uint200 from uint256, reverting on
     * overflow (when the input is greater than largest uint200).
     *
     * Counterpart to Solidity's `uint200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     *
     * _Available since v4.7._
     */
    function toUint200(uint256 value) internal pure returns (uint200) {
        require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
        return uint200(value);
    }

    /**
     * @dev Returns the downcasted uint192 from uint256, reverting on
     * overflow (when the input is greater than largest uint192).
     *
     * Counterpart to Solidity's `uint192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     *
     * _Available since v4.7._
     */
    function toUint192(uint256 value) internal pure returns (uint192) {
        require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
        return uint192(value);
    }

    /**
     * @dev Returns the downcasted uint184 from uint256, reverting on
     * overflow (when the input is greater than largest uint184).
     *
     * Counterpart to Solidity's `uint184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     *
     * _Available since v4.7._
     */
    function toUint184(uint256 value) internal pure returns (uint184) {
        require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
        return uint184(value);
    }

    /**
     * @dev Returns the downcasted uint176 from uint256, reverting on
     * overflow (when the input is greater than largest uint176).
     *
     * Counterpart to Solidity's `uint176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     *
     * _Available since v4.7._
     */
    function toUint176(uint256 value) internal pure returns (uint176) {
        require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
        return uint176(value);
    }

    /**
     * @dev Returns the downcasted uint168 from uint256, reverting on
     * overflow (when the input is greater than largest uint168).
     *
     * Counterpart to Solidity's `uint168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     *
     * _Available since v4.7._
     */
    function toUint168(uint256 value) internal pure returns (uint168) {
        require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
        return uint168(value);
    }

    /**
     * @dev Returns the downcasted uint160 from uint256, reverting on
     * overflow (when the input is greater than largest uint160).
     *
     * Counterpart to Solidity's `uint160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     *
     * _Available since v4.7._
     */
    function toUint160(uint256 value) internal pure returns (uint160) {
        require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
        return uint160(value);
    }

    /**
     * @dev Returns the downcasted uint152 from uint256, reverting on
     * overflow (when the input is greater than largest uint152).
     *
     * Counterpart to Solidity's `uint152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     *
     * _Available since v4.7._
     */
    function toUint152(uint256 value) internal pure returns (uint152) {
        require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
        return uint152(value);
    }

    /**
     * @dev Returns the downcasted uint144 from uint256, reverting on
     * overflow (when the input is greater than largest uint144).
     *
     * Counterpart to Solidity's `uint144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     *
     * _Available since v4.7._
     */
    function toUint144(uint256 value) internal pure returns (uint144) {
        require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
        return uint144(value);
    }

    /**
     * @dev Returns the downcasted uint136 from uint256, reverting on
     * overflow (when the input is greater than largest uint136).
     *
     * Counterpart to Solidity's `uint136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     *
     * _Available since v4.7._
     */
    function toUint136(uint256 value) internal pure returns (uint136) {
        require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
        return uint136(value);
    }

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v2.5._
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint120 from uint256, reverting on
     * overflow (when the input is greater than largest uint120).
     *
     * Counterpart to Solidity's `uint120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     *
     * _Available since v4.7._
     */
    function toUint120(uint256 value) internal pure returns (uint120) {
        require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
        return uint120(value);
    }

    /**
     * @dev Returns the downcasted uint112 from uint256, reverting on
     * overflow (when the input is greater than largest uint112).
     *
     * Counterpart to Solidity's `uint112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     *
     * _Available since v4.7._
     */
    function toUint112(uint256 value) internal pure returns (uint112) {
        require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
        return uint112(value);
    }

    /**
     * @dev Returns the downcasted uint104 from uint256, reverting on
     * overflow (when the input is greater than largest uint104).
     *
     * Counterpart to Solidity's `uint104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     *
     * _Available since v4.7._
     */
    function toUint104(uint256 value) internal pure returns (uint104) {
        require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
        return uint104(value);
    }

    /**
     * @dev Returns the downcasted uint96 from uint256, reverting on
     * overflow (when the input is greater than largest uint96).
     *
     * Counterpart to Solidity's `uint96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     *
     * _Available since v4.2._
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
        return uint96(value);
    }

    /**
     * @dev Returns the downcasted uint88 from uint256, reverting on
     * overflow (when the input is greater than largest uint88).
     *
     * Counterpart to Solidity's `uint88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     *
     * _Available since v4.7._
     */
    function toUint88(uint256 value) internal pure returns (uint88) {
        require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
        return uint88(value);
    }

    /**
     * @dev Returns the downcasted uint80 from uint256, reverting on
     * overflow (when the input is greater than largest uint80).
     *
     * Counterpart to Solidity's `uint80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     *
     * _Available since v4.7._
     */
    function toUint80(uint256 value) internal pure returns (uint80) {
        require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
        return uint80(value);
    }

    /**
     * @dev Returns the downcasted uint72 from uint256, reverting on
     * overflow (when the input is greater than largest uint72).
     *
     * Counterpart to Solidity's `uint72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     *
     * _Available since v4.7._
     */
    function toUint72(uint256 value) internal pure returns (uint72) {
        require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
        return uint72(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v2.5._
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint56 from uint256, reverting on
     * overflow (when the input is greater than largest uint56).
     *
     * Counterpart to Solidity's `uint56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     *
     * _Available since v4.7._
     */
    function toUint56(uint256 value) internal pure returns (uint56) {
        require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
        return uint56(value);
    }

    /**
     * @dev Returns the downcasted uint48 from uint256, reverting on
     * overflow (when the input is greater than largest uint48).
     *
     * Counterpart to Solidity's `uint48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     *
     * _Available since v4.7._
     */
    function toUint48(uint256 value) internal pure returns (uint48) {
        require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
        return uint48(value);
    }

    /**
     * @dev Returns the downcasted uint40 from uint256, reverting on
     * overflow (when the input is greater than largest uint40).
     *
     * Counterpart to Solidity's `uint40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     *
     * _Available since v4.7._
     */
    function toUint40(uint256 value) internal pure returns (uint40) {
        require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
        return uint40(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v2.5._
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint24 from uint256, reverting on
     * overflow (when the input is greater than largest uint24).
     *
     * Counterpart to Solidity's `uint24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     *
     * _Available since v4.7._
     */
    function toUint24(uint256 value) internal pure returns (uint24) {
        require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
        return uint24(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v2.5._
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     *
     * _Available since v2.5._
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     *
     * _Available since v3.0._
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int248 from int256, reverting on
     * overflow (when the input is less than smallest int248 or
     * greater than largest int248).
     *
     * Counterpart to Solidity's `int248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     *
     * _Available since v4.7._
     */
    function toInt248(int256 value) internal pure returns (int248 downcasted) {
        downcasted = int248(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
    }

    /**
     * @dev Returns the downcasted int240 from int256, reverting on
     * overflow (when the input is less than smallest int240 or
     * greater than largest int240).
     *
     * Counterpart to Solidity's `int240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     *
     * _Available since v4.7._
     */
    function toInt240(int256 value) internal pure returns (int240 downcasted) {
        downcasted = int240(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
    }

    /**
     * @dev Returns the downcasted int232 from int256, reverting on
     * overflow (when the input is less than smallest int232 or
     * greater than largest int232).
     *
     * Counterpart to Solidity's `int232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     *
     * _Available since v4.7._
     */
    function toInt232(int256 value) internal pure returns (int232 downcasted) {
        downcasted = int232(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
    }

    /**
     * @dev Returns the downcasted int224 from int256, reverting on
     * overflow (when the input is less than smallest int224 or
     * greater than largest int224).
     *
     * Counterpart to Solidity's `int224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     *
     * _Available since v4.7._
     */
    function toInt224(int256 value) internal pure returns (int224 downcasted) {
        downcasted = int224(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
    }

    /**
     * @dev Returns the downcasted int216 from int256, reverting on
     * overflow (when the input is less than smallest int216 or
     * greater than largest int216).
     *
     * Counterpart to Solidity's `int216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     *
     * _Available since v4.7._
     */
    function toInt216(int256 value) internal pure returns (int216 downcasted) {
        downcasted = int216(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
    }

    /**
     * @dev Returns the downcasted int208 from int256, reverting on
     * overflow (when the input is less than smallest int208 or
     * greater than largest int208).
     *
     * Counterpart to Solidity's `int208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     *
     * _Available since v4.7._
     */
    function toInt208(int256 value) internal pure returns (int208 downcasted) {
        downcasted = int208(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
    }

    /**
     * @dev Returns the downcasted int200 from int256, reverting on
     * overflow (when the input is less than smallest int200 or
     * greater than largest int200).
     *
     * Counterpart to Solidity's `int200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     *
     * _Available since v4.7._
     */
    function toInt200(int256 value) internal pure returns (int200 downcasted) {
        downcasted = int200(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
    }

    /**
     * @dev Returns the downcasted int192 from int256, reverting on
     * overflow (when the input is less than smallest int192 or
     * greater than largest int192).
     *
     * Counterpart to Solidity's `int192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     *
     * _Available since v4.7._
     */
    function toInt192(int256 value) internal pure returns (int192 downcasted) {
        downcasted = int192(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
    }

    /**
     * @dev Returns the downcasted int184 from int256, reverting on
     * overflow (when the input is less than smallest int184 or
     * greater than largest int184).
     *
     * Counterpart to Solidity's `int184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     *
     * _Available since v4.7._
     */
    function toInt184(int256 value) internal pure returns (int184 downcasted) {
        downcasted = int184(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
    }

    /**
     * @dev Returns the downcasted int176 from int256, reverting on
     * overflow (when the input is less than smallest int176 or
     * greater than largest int176).
     *
     * Counterpart to Solidity's `int176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     *
     * _Available since v4.7._
     */
    function toInt176(int256 value) internal pure returns (int176 downcasted) {
        downcasted = int176(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
    }

    /**
     * @dev Returns the downcasted int168 from int256, reverting on
     * overflow (when the input is less than smallest int168 or
     * greater than largest int168).
     *
     * Counterpart to Solidity's `int168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     *
     * _Available since v4.7._
     */
    function toInt168(int256 value) internal pure returns (int168 downcasted) {
        downcasted = int168(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
    }

    /**
     * @dev Returns the downcasted int160 from int256, reverting on
     * overflow (when the input is less than smallest int160 or
     * greater than largest int160).
     *
     * Counterpart to Solidity's `int160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     *
     * _Available since v4.7._
     */
    function toInt160(int256 value) internal pure returns (int160 downcasted) {
        downcasted = int160(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
    }

    /**
     * @dev Returns the downcasted int152 from int256, reverting on
     * overflow (when the input is less than smallest int152 or
     * greater than largest int152).
     *
     * Counterpart to Solidity's `int152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     *
     * _Available since v4.7._
     */
    function toInt152(int256 value) internal pure returns (int152 downcasted) {
        downcasted = int152(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
    }

    /**
     * @dev Returns the downcasted int144 from int256, reverting on
     * overflow (when the input is less than smallest int144 or
     * greater than largest int144).
     *
     * Counterpart to Solidity's `int144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     *
     * _Available since v4.7._
     */
    function toInt144(int256 value) internal pure returns (int144 downcasted) {
        downcasted = int144(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
    }

    /**
     * @dev Returns the downcasted int136 from int256, reverting on
     * overflow (when the input is less than smallest int136 or
     * greater than largest int136).
     *
     * Counterpart to Solidity's `int136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     *
     * _Available since v4.7._
     */
    function toInt136(int256 value) internal pure returns (int136 downcasted) {
        downcasted = int136(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v3.1._
     */
    function toInt128(int256 value) internal pure returns (int128 downcasted) {
        downcasted = int128(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
    }

    /**
     * @dev Returns the downcasted int120 from int256, reverting on
     * overflow (when the input is less than smallest int120 or
     * greater than largest int120).
     *
     * Counterpart to Solidity's `int120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     *
     * _Available since v4.7._
     */
    function toInt120(int256 value) internal pure returns (int120 downcasted) {
        downcasted = int120(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
    }

    /**
     * @dev Returns the downcasted int112 from int256, reverting on
     * overflow (when the input is less than smallest int112 or
     * greater than largest int112).
     *
     * Counterpart to Solidity's `int112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     *
     * _Available since v4.7._
     */
    function toInt112(int256 value) internal pure returns (int112 downcasted) {
        downcasted = int112(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
    }

    /**
     * @dev Returns the downcasted int104 from int256, reverting on
     * overflow (when the input is less than smallest int104 or
     * greater than largest int104).
     *
     * Counterpart to Solidity's `int104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     *
     * _Available since v4.7._
     */
    function toInt104(int256 value) internal pure returns (int104 downcasted) {
        downcasted = int104(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
    }

    /**
     * @dev Returns the downcasted int96 from int256, reverting on
     * overflow (when the input is less than smallest int96 or
     * greater than largest int96).
     *
     * Counterpart to Solidity's `int96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     *
     * _Available since v4.7._
     */
    function toInt96(int256 value) internal pure returns (int96 downcasted) {
        downcasted = int96(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
    }

    /**
     * @dev Returns the downcasted int88 from int256, reverting on
     * overflow (when the input is less than smallest int88 or
     * greater than largest int88).
     *
     * Counterpart to Solidity's `int88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     *
     * _Available since v4.7._
     */
    function toInt88(int256 value) internal pure returns (int88 downcasted) {
        downcasted = int88(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
    }

    /**
     * @dev Returns the downcasted int80 from int256, reverting on
     * overflow (when the input is less than smallest int80 or
     * greater than largest int80).
     *
     * Counterpart to Solidity's `int80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     *
     * _Available since v4.7._
     */
    function toInt80(int256 value) internal pure returns (int80 downcasted) {
        downcasted = int80(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
    }

    /**
     * @dev Returns the downcasted int72 from int256, reverting on
     * overflow (when the input is less than smallest int72 or
     * greater than largest int72).
     *
     * Counterpart to Solidity's `int72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     *
     * _Available since v4.7._
     */
    function toInt72(int256 value) internal pure returns (int72 downcasted) {
        downcasted = int72(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v3.1._
     */
    function toInt64(int256 value) internal pure returns (int64 downcasted) {
        downcasted = int64(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
    }

    /**
     * @dev Returns the downcasted int56 from int256, reverting on
     * overflow (when the input is less than smallest int56 or
     * greater than largest int56).
     *
     * Counterpart to Solidity's `int56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     *
     * _Available since v4.7._
     */
    function toInt56(int256 value) internal pure returns (int56 downcasted) {
        downcasted = int56(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
    }

    /**
     * @dev Returns the downcasted int48 from int256, reverting on
     * overflow (when the input is less than smallest int48 or
     * greater than largest int48).
     *
     * Counterpart to Solidity's `int48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     *
     * _Available since v4.7._
     */
    function toInt48(int256 value) internal pure returns (int48 downcasted) {
        downcasted = int48(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
    }

    /**
     * @dev Returns the downcasted int40 from int256, reverting on
     * overflow (when the input is less than smallest int40 or
     * greater than largest int40).
     *
     * Counterpart to Solidity's `int40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     *
     * _Available since v4.7._
     */
    function toInt40(int256 value) internal pure returns (int40 downcasted) {
        downcasted = int40(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v3.1._
     */
    function toInt32(int256 value) internal pure returns (int32 downcasted) {
        downcasted = int32(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
    }

    /**
     * @dev Returns the downcasted int24 from int256, reverting on
     * overflow (when the input is less than smallest int24 or
     * greater than largest int24).
     *
     * Counterpart to Solidity's `int24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     *
     * _Available since v4.7._
     */
    function toInt24(int256 value) internal pure returns (int24 downcasted) {
        downcasted = int24(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v3.1._
     */
    function toInt16(int256 value) internal pure returns (int16 downcasted) {
        downcasted = int16(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     *
     * _Available since v3.1._
     */
    function toInt8(int256 value) internal pure returns (int8 downcasted) {
        downcasted = int8(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     *
     * _Available since v3.0._
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
        require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
        return int256(value);
    }
}


// Dependency file: @openzeppelin/contracts/utils/Checkpoints.sol

// OpenZeppelin Contracts (last updated v4.8.1) (utils/Checkpoints.sol)
// This file was procedurally generated from scripts/generate/templates/Checkpoints.js.

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/utils/math/Math.sol";
// import "@openzeppelin/contracts/utils/math/SafeCast.sol";

/**
 * @dev This library defines the `History` struct, for checkpointing values as they change at different points in
 * time, and later looking up past values by block number. See {Votes} as an example.
 *
 * To create a history of checkpoints define a variable type `Checkpoints.History` in your contract, and store a new
 * checkpoint for the current transaction block using the {push} function.
 *
 * _Available since v4.5._
 */
library Checkpoints {
    struct History {
        Checkpoint[] _checkpoints;
    }

    struct Checkpoint {
        uint32 _blockNumber;
        uint224 _value;
    }

    /**
     * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one
     * before it is returned, or zero otherwise. Because the number returned corresponds to that at the end of the
     * block, the requested block number must be in the past, excluding the current block.
     */
    function getAtBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {
        require(blockNumber < block.number, "Checkpoints: block not yet mined");
        uint32 key = SafeCast.toUint32(blockNumber);

        uint256 len = self._checkpoints.length;
        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one
     * before it is returned, or zero otherwise. Similar to {upperLookup} but optimized for the case when the searched
     * checkpoint is probably "recent", defined as being among the last sqrt(N) checkpoints where N is the number of
     * checkpoints.
     */
    function getAtProbablyRecentBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {
        require(blockNumber < block.number, "Checkpoints: block not yet mined");
        uint32 key = SafeCast.toUint32(blockNumber);

        uint256 len = self._checkpoints.length;

        uint256 low = 0;
        uint256 high = len;

        if (len > 5) {
            uint256 mid = len - Math.sqrt(len);
            if (key < _unsafeAccess(self._checkpoints, mid)._blockNumber) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);

        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Pushes a value onto a History so that it is stored as the checkpoint for the current block.
     *
     * Returns previous value and new value.
     */
    function push(History storage self, uint256 value) internal returns (uint256, uint256) {
        return _insert(self._checkpoints, SafeCast.toUint32(block.number), SafeCast.toUint224(value));
    }

    /**
     * @dev Pushes a value onto a History, by updating the latest value using binary operation `op`. The new value will
     * be set to `op(latest, delta)`.
     *
     * Returns previous value and new value.
     */
    function push(
        History storage self,
        function(uint256, uint256) view returns (uint256) op,
        uint256 delta
    ) internal returns (uint256, uint256) {
        return push(self, op(latest(self), delta));
    }

    /**
     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
     */
    function latest(History storage self) internal view returns (uint224) {
        uint256 pos = self._checkpoints.length;
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
     * in the most recent checkpoint.
     */
    function latestCheckpoint(History storage self)
        internal
        view
        returns (
            bool exists,
            uint32 _blockNumber,
            uint224 _value
        )
    {
        uint256 pos = self._checkpoints.length;
        if (pos == 0) {
            return (false, 0, 0);
        } else {
            Checkpoint memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
            return (true, ckpt._blockNumber, ckpt._value);
        }
    }

    /**
     * @dev Returns the number of checkpoint.
     */
    function length(History storage self) internal view returns (uint256) {
        return self._checkpoints.length;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
     * or by updating the last one.
     */
    function _insert(
        Checkpoint[] storage self,
        uint32 key,
        uint224 value
    ) private returns (uint224, uint224) {
        uint256 pos = self.length;

        if (pos > 0) {
            // Copying to memory is important here.
            Checkpoint memory last = _unsafeAccess(self, pos - 1);

            // Checkpoints keys must be increasing.
            require(last._blockNumber <= key, "Checkpoint: invalid key");

            // Update or push new checkpoint
            if (last._blockNumber == key) {
                _unsafeAccess(self, pos - 1)._value = value;
            } else {
                self.push(Checkpoint({_blockNumber: key, _value: value}));
            }
            return (last._value, value);
        } else {
            self.push(Checkpoint({_blockNumber: key, _value: value}));
            return (0, value);
        }
    }

    /**
     * @dev Return the index of the oldest checkpoint whose key is greater than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _upperBinaryLookup(
        Checkpoint[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._blockNumber > key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return high;
    }

    /**
     * @dev Return the index of the oldest checkpoint whose key is greater or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _lowerBinaryLookup(
        Checkpoint[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._blockNumber < key) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return high;
    }

    /**
     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
     */
    function _unsafeAccess(Checkpoint[] storage self, uint256 pos) private pure returns (Checkpoint storage result) {
        assembly {
            mstore(0, self.slot)
            result.slot := add(keccak256(0, 0x20), pos)
        }
    }

    struct Trace224 {
        Checkpoint224[] _checkpoints;
    }

    struct Checkpoint224 {
        uint32 _key;
        uint224 _value;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint.
     *
     * Returns previous value and new value.
     */
    function push(
        Trace224 storage self,
        uint32 key,
        uint224 value
    ) internal returns (uint224, uint224) {
        return _insert(self._checkpoints, key, value);
    }

    /**
     * @dev Returns the value in the oldest checkpoint with key greater or equal than the search key, or zero if there is none.
     */
    function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
    }

    /**
     * @dev Returns the value in the most recent checkpoint with key lower or equal than the search key.
     */
    function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
     */
    function latest(Trace224 storage self) internal view returns (uint224) {
        uint256 pos = self._checkpoints.length;
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
     * in the most recent checkpoint.
     */
    function latestCheckpoint(Trace224 storage self)
        internal
        view
        returns (
            bool exists,
            uint32 _key,
            uint224 _value
        )
    {
        uint256 pos = self._checkpoints.length;
        if (pos == 0) {
            return (false, 0, 0);
        } else {
            Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
            return (true, ckpt._key, ckpt._value);
        }
    }

    /**
     * @dev Returns the number of checkpoint.
     */
    function length(Trace224 storage self) internal view returns (uint256) {
        return self._checkpoints.length;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
     * or by updating the last one.
     */
    function _insert(
        Checkpoint224[] storage self,
        uint32 key,
        uint224 value
    ) private returns (uint224, uint224) {
        uint256 pos = self.length;

        if (pos > 0) {
            // Copying to memory is important here.
            Checkpoint224 memory last = _unsafeAccess(self, pos - 1);

            // Checkpoints keys must be increasing.
            require(last._key <= key, "Checkpoint: invalid key");

            // Update or push new checkpoint
            if (last._key == key) {
                _unsafeAccess(self, pos - 1)._value = value;
            } else {
                self.push(Checkpoint224({_key: key, _value: value}));
            }
            return (last._value, value);
        } else {
            self.push(Checkpoint224({_key: key, _value: value}));
            return (0, value);
        }
    }

    /**
     * @dev Return the index of the oldest checkpoint whose key is greater than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _upperBinaryLookup(
        Checkpoint224[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key > key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return high;
    }

    /**
     * @dev Return the index of the oldest checkpoint whose key is greater or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _lowerBinaryLookup(
        Checkpoint224[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key < key) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return high;
    }

    /**
     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
     */
    function _unsafeAccess(Checkpoint224[] storage self, uint256 pos)
        private
        pure
        returns (Checkpoint224 storage result)
    {
        assembly {
            mstore(0, self.slot)
            result.slot := add(keccak256(0, 0x20), pos)
        }
    }

    struct Trace160 {
        Checkpoint160[] _checkpoints;
    }

    struct Checkpoint160 {
        uint96 _key;
        uint160 _value;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint.
     *
     * Returns previous value and new value.
     */
    function push(
        Trace160 storage self,
        uint96 key,
        uint160 value
    ) internal returns (uint160, uint160) {
        return _insert(self._checkpoints, key, value);
    }

    /**
     * @dev Returns the value in the oldest checkpoint with key greater or equal than the search key, or zero if there is none.
     */
    function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
    }

    /**
     * @dev Returns the value in the most recent checkpoint with key lower or equal than the search key.
     */
    function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
     */
    function latest(Trace160 storage self) internal view returns (uint160) {
        uint256 pos = self._checkpoints.length;
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
     * in the most recent checkpoint.
     */
    function latestCheckpoint(Trace160 storage self)
        internal
        view
        returns (
            bool exists,
            uint96 _key,
            uint160 _value
        )
    {
        uint256 pos = self._checkpoints.length;
        if (pos == 0) {
            return (false, 0, 0);
        } else {
            Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
            return (true, ckpt._key, ckpt._value);
        }
    }

    /**
     * @dev Returns the number of checkpoint.
     */
    function length(Trace160 storage self) internal view returns (uint256) {
        return self._checkpoints.length;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
     * or by updating the last one.
     */
    function _insert(
        Checkpoint160[] storage self,
        uint96 key,
        uint160 value
    ) private returns (uint160, uint160) {
        uint256 pos = self.length;

        if (pos > 0) {
            // Copying to memory is important here.
            Checkpoint160 memory last = _unsafeAccess(self, pos - 1);

            // Checkpoints keys must be increasing.
            require(last._key <= key, "Checkpoint: invalid key");

            // Update or push new checkpoint
            if (last._key == key) {
                _unsafeAccess(self, pos - 1)._value = value;
            } else {
                self.push(Checkpoint160({_key: key, _value: value}));
            }
            return (last._value, value);
        } else {
            self.push(Checkpoint160({_key: key, _value: value}));
            return (0, value);
        }
    }

    /**
     * @dev Return the index of the oldest checkpoint whose key is greater than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _upperBinaryLookup(
        Checkpoint160[] storage self,
        uint96 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key > key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return high;
    }

    /**
     * @dev Return the index of the oldest checkpoint whose key is greater or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _lowerBinaryLookup(
        Checkpoint160[] storage self,
        uint96 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key < key) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return high;
    }

    /**
     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
     */
    function _unsafeAccess(Checkpoint160[] storage self, uint256 pos)
        private
        pure
        returns (Checkpoint160 storage result)
    {
        assembly {
            mstore(0, self.slot)
            result.slot := add(keccak256(0, 0x20), pos)
        }
    }
}


// Dependency file: @openzeppelin/contracts/governance/utils/IVotes.sol

// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)
// pragma solidity ^0.8.0;

/**
 * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.
 *
 * _Available since v4.5._
 */
interface IVotes {
    /**
     * @dev Emitted when an account changes their delegate.
     */
    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

    /**
     * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.
     */
    event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);

    /**
     * @dev Returns the current amount of votes that `account` has.
     */
    function getVotes(address account) external view returns (uint256);

    /**
     * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).
     */
    function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);

    /**
     * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).
     *
     * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.
     * Votes that have not been delegated are still part of total supply, even though they would not participate in a
     * vote.
     */
    function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);

    /**
     * @dev Returns the delegate that `account` has chosen.
     */
    function delegates(address account) external view returns (address);

    /**
     * @dev Delegates votes from the sender to `delegatee`.
     */
    function delegate(address delegatee) external;

    /**
     * @dev Delegates votes from signer to `delegatee`.
     */
    function delegateBySig(
        address delegatee,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;
}


// Dependency file: @openzeppelin/contracts/governance/utils/Votes.sol

// OpenZeppelin Contracts (last updated v4.8.0) (governance/utils/Votes.sol)
// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/utils/Context.sol";
// import "@openzeppelin/contracts/utils/Counters.sol";
// import "@openzeppelin/contracts/utils/Checkpoints.sol";
// import "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
// import "@openzeppelin/contracts/governance/utils/IVotes.sol";

/**
 * @dev This is a base abstract contract that tracks voting units, which are a measure of voting power that can be
 * transferred, and provides a system of vote delegation, where an account can delegate its voting units to a sort of
 * "representative" that will pool delegated voting units from different accounts and can then use it to vote in
 * decisions. In fact, voting units _must_ be delegated in order to count as actual votes, and an account has to
 * delegate those votes to itself if it wishes to participate in decisions and does not have a trusted representative.
 *
 * This contract is often combined with a token contract such that voting units correspond to token units. For an
 * example, see {ERC721Votes}.
 *
 * The full history of delegate votes is tracked on-chain so that governance protocols can consider votes as distributed
 * at a particular block number to protect against flash loans and double voting. The opt-in delegate system makes the
 * cost of this history tracking optional.
 *
 * When using this module the derived contract must implement {_getVotingUnits} (for example, make it return
 * {ERC721-balanceOf}), and can use {_transferVotingUnits} to track a change in the distribution of those units (in the
 * previous example, it would be included in {ERC721-_beforeTokenTransfer}).
 *
 * _Available since v4.5._
 */
abstract contract Votes is IVotes, Context, EIP712 {
    using Checkpoints for Checkpoints.History;
    using Counters for Counters.Counter;

    bytes32 private constant _DELEGATION_TYPEHASH =
        keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");

    mapping(address => address) private _delegation;
    mapping(address => Checkpoints.History) private _delegateCheckpoints;
    Checkpoints.History private _totalCheckpoints;

    mapping(address => Counters.Counter) private _nonces;

    /**
     * @dev Returns the current amount of votes that `account` has.
     */
    function getVotes(address account) public view virtual override returns (uint256) {
        return _delegateCheckpoints[account].latest();
    }

    /**
     * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).
     *
     * Requirements:
     *
     * - `blockNumber` must have been already mined
     */
    function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {
        return _delegateCheckpoints[account].getAtProbablyRecentBlock(blockNumber);
    }

    /**
     * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).
     *
     * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.
     * Votes that have not been delegated are still part of total supply, even though they would not participate in a
     * vote.
     *
     * Requirements:
     *
     * - `blockNumber` must have been already mined
     */
    function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {
        require(blockNumber < block.number, "Votes: block not yet mined");
        return _totalCheckpoints.getAtProbablyRecentBlock(blockNumber);
    }

    /**
     * @dev Returns the current total supply of votes.
     */
    function _getTotalSupply() internal view virtual returns (uint256) {
        return _totalCheckpoints.latest();
    }

    /**
     * @dev Returns the delegate that `account` has chosen.
     */
    function delegates(address account) public view virtual override returns (address) {
        return _delegation[account];
    }

    /**
     * @dev Delegates votes from the sender to `delegatee`.
     */
    function delegate(address delegatee) public virtual override {
        address account = _msgSender();
        _delegate(account, delegatee);
    }

    /**
     * @dev Delegates votes from signer to `delegatee`.
     */
    function delegateBySig(
        address delegatee,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override {
        require(block.timestamp <= expiry, "Votes: signature expired");
        address signer = ECDSA.recover(
            _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),
            v,
            r,
            s
        );
        require(nonce == _useNonce(signer), "Votes: invalid nonce");
        _delegate(signer, delegatee);
    }

    /**
     * @dev Delegate all of `account`'s voting units to `delegatee`.
     *
     * Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}.
     */
    function _delegate(address account, address delegatee) internal virtual {
        address oldDelegate = delegates(account);
        _delegation[account] = delegatee;

        emit DelegateChanged(account, oldDelegate, delegatee);
        _moveDelegateVotes(oldDelegate, delegatee, _getVotingUnits(account));
    }

    /**
     * @dev Transfers, mints, or burns voting units. To register a mint, `from` should be zero. To register a burn, `to`
     * should be zero. Total supply of voting units will be adjusted with mints and burns.
     */
    function _transferVotingUnits(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        if (from == address(0)) {
            _totalCheckpoints.push(_add, amount);
        }
        if (to == address(0)) {
            _totalCheckpoints.push(_subtract, amount);
        }
        _moveDelegateVotes(delegates(from), delegates(to), amount);
    }

    /**
     * @dev Moves delegated votes from one delegate to another.
     */
    function _moveDelegateVotes(
        address from,
        address to,
        uint256 amount
    ) private {
        if (from != to && amount > 0) {
            if (from != address(0)) {
                (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[from].push(_subtract, amount);
                emit DelegateVotesChanged(from, oldValue, newValue);
            }
            if (to != address(0)) {
                (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[to].push(_add, amount);
                emit DelegateVotesChanged(to, oldValue, newValue);
            }
        }
    }

    function _add(uint256 a, uint256 b) private pure returns (uint256) {
        return a + b;
    }

    function _subtract(uint256 a, uint256 b) private pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Consumes a nonce.
     *
     * Returns the current value and increments nonce.
     */
    function _useNonce(address owner) internal virtual returns (uint256 current) {
        Counters.Counter storage nonce = _nonces[owner];
        current = nonce.current();
        nonce.increment();
    }

    /**
     * @dev Returns an address nonce.
     */
    function nonces(address owner) public view virtual returns (uint256) {
        return _nonces[owner].current();
    }

    /**
     * @dev Returns the contract's {EIP712} domain separator.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32) {
        return _domainSeparatorV4();
    }

    /**
     * @dev Must return the voting units held by an account.
     */
    function _getVotingUnits(address) internal view virtual returns (uint256);
}


// Dependency file: @openzeppelin/contracts/token/ERC721/extensions/ERC721Votes.sol

// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Votes.sol)

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
// import "@openzeppelin/contracts/governance/utils/Votes.sol";

/**
 * @dev Extension of ERC721 to support voting and delegation as implemented by {Votes}, where each individual NFT counts
 * as 1 vote unit.
 *
 * Tokens do not count as votes until they are delegated, because votes must be tracked which incurs an additional cost
 * on every transfer. Token holders can either delegate to a trusted representative who will decide how to make use of
 * the votes in governance decisions, or they can delegate to themselves to be their own representative.
 *
 * _Available since v4.5._
 */
abstract contract ERC721Votes is ERC721, Votes {
    /**
     * @dev See {ERC721-_afterTokenTransfer}. Adjusts votes when tokens are transferred.
     *
     * Emits a {IVotes-DelegateVotesChanged} event.
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual override {
        _transferVotingUnits(from, to, batchSize);
        super._afterTokenTransfer(from, to, firstTokenId, batchSize);
    }

    /**
     * @dev Returns the balance of `account`.
     */
    function _getVotingUnits(address account) internal view virtual override returns (uint256) {
        return balanceOf(account);
    }
}


// Dependency file: @openzeppelin/contracts/token/ERC721/extensions/draft-ERC721Votes.sol

// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/draft-ERC721Votes.sol)

// pragma solidity ^0.8.0;

// ERC721Votes was marked as draft due to the EIP-712 dependency.
// EIP-712 is Final as of 2022-08-11. This file is deprecated.

// import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Votes.sol";


// Dependency file: @openzeppelin/contracts/access/Ownable.sol

// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/utils/Context.sol";

/**
 * @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 Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        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);
    }
}


// Dependency file: @openzeppelin/contracts/security/ReentrancyGuard.sol

// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

// pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

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


// Dependency file: contracts/CashRushNftDataStore.sol

// pragma solidity 0.8.17;

abstract contract CashRushNftDataStore {
    uint8 private constant TOTAL_CARDS = 14;

    bool public dataIsFrozen;
    mapping(uint256 => uint8) public tokenType;

    event DataFrozen(bool isFrozen);
    event TypeUpdated(uint256 indexed tokenId, uint8 prevValue, uint8 newValue);

    error ErrorIsFrozen();

    function _uploadTypes(uint256 shift, bytes memory types) internal {
        if (dataIsFrozen) revert ErrorIsFrozen();
        for (uint256 i = 0; i < types.length; i++) {
            uint256 tokenId = shift + i;
            uint8 value = uint8(types[i]);
            emit TypeUpdated(tokenId, tokenType[tokenId], value);
            tokenType[tokenId] = value;
        }
    }

    function _freezeData() internal {
        emit DataFrozen(true);
        dataIsFrozen = true;
    }

    function tokenRate(uint256 tokenId) public view returns (uint256) {
        uint8 ttype = tokenType[tokenId];
        // 100/10000 = 0.01 = 1.00%
        if (ttype == uint8(0)) {
            return 0; // Undefined NFTs - 0.00%
        }
        if (ttype >= uint8(1) && ttype <= uint8(2)) {
            return 20; // Legendary NFTs - 0.20%
        }
        if (ttype >= uint8(3) && ttype <= uint8(5)) {
            return 10; // Rare NFTs - 0.10%
        }
        if (ttype >= uint8(6) && ttype <= uint8(TOTAL_CARDS)) {
            return 5; // Common NFTs - 0.05%
        }
        return 0; // Undefined NFTs - 0.00%
    }

    function tokensMaxRate(
        uint256[] memory tokenIds
    ) public view returns (uint256 maxRate) {
        uint256 tokenMaxRate = 0; // 0 - 20
        bool[] memory set = new bool[](TOTAL_CARDS + 1);
        for (uint256 i = 0; i < tokenIds.length; i++) {
            uint256 tokenId = tokenIds[i];
            uint256 trate = tokenRate(tokenId); // 0 - 20
            uint8 ttype = tokenType[tokenId];
            set[ttype] = true;
            tokenMaxRate = _max(trate, tokenMaxRate);
        }

        // sets
        if (
            set[1] &&
            set[2] &&
            set[3] &&
            set[4] &&
            set[5] &&
            set[6] &&
            set[7] &&
            set[8] &&
            set[9] &&
            set[10] &&
            set[11] &&
            set[12] &&
            set[13] &&
            set[14]
        ) {
            return 100; // Fully-Stacked Deck - 1.00%
        }
        if (set[1] && set[2]) {
            return 30; // Set of Legendary NFTs - 0.30%
        }

        // 0.20% + 0.10%
        if (set[1] && set[5]) {
            return 30;
        }
        // 0.20% + 0.05%
        if (set[1] && set[10]) {
            return 25;
        }

        // 0.10% + 0.10%
        if (set[3] && set[5]) {
            return 20;
        }

        if (set[3] && set[4] && set[5]) {
            return 20; // Set of Rare NFTs - 0.20%
        }

        // 0.10% + 0.05%
        if (set[4] && set[10]) {
            return _max(15, tokenMaxRate);
        }
        // 0.10% +
        if (set[5]) {
            // 0.05% || 0.05%
            if (set[8] || set[11]) {
                return _max(15, tokenMaxRate);
            }
        }

        if (
            set[6] &&
            set[7] &&
            set[8] &&
            set[9] &&
            set[10] &&
            set[11] &&
            set[12] &&
            set[13] &&
            set[14]
        ) {
            return _max(15, tokenMaxRate); // Set of Common NFTs - 0.15%
        }

        // 0.05% + 0.05%
        if (set[9] && set[12]) {
            return _max(10, tokenMaxRate);
        }

        return tokenMaxRate; // cards max rate
    }

    function _max(uint256 a, uint256 b) private pure returns (uint256) {
        return a > b ? a : b;
    }
}


// Dependency file: contracts/CashRushNftStaking.sol

// pragma solidity 0.8.17;

// import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
// import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
// import "contracts/CashRushNftDataStore.sol";

abstract contract CashRushNftStaking is
    ERC721,
    ERC721Enumerable,
    CashRushNftDataStore
{
    mapping(uint256 => bool) public isStaked;
    mapping(address => uint256) public extraRate;

    event Staked(uint256 indexed tokenId);
    event Unstaked(uint256 indexed tokenId);
    event ExtraRateSetted(address indexed account, uint256 extraRate);

    error DuplicateTokenId();
    error NotTokenOwner();

    function stake(uint256[] memory tokenIds) external {
        _stake(tokenIds, true);
    }

    function unstake(uint256[] memory tokenIds) external {
        _stake(tokenIds, false);
    }

    function _stake(uint256[] memory tokenIds, bool state) private {
        if (!dataIsFrozen) revert ErrorIsFrozen();
        for (uint256 i = 0; i < tokenIds.length; i++) {
            uint256 tokenId = tokenIds[i];
            for (uint256 j = i + 1; j < tokenIds.length; j++) {
                if (tokenId == tokenIds[j]) revert DuplicateTokenId();
            }
            if (ownerOf(tokenId) != msg.sender) revert NotTokenOwner();
            if (isStaked[tokenId] != state) {
                if (state) emit Staked(tokenId);
                else emit Unstaked(tokenId);
            }
            isStaked[tokenId] = state;
        }

        extraRate[msg.sender] = accountRate(msg.sender);
        emit ExtraRateSetted(msg.sender, extraRate[msg.sender]);
    }

    function accountRate(address account) public view returns (uint256) {
        return tokensMaxRate(tokensStakedOfOwner(account));
    }

    function tokensStakedOfOwner(
        address owner
    ) public view returns (uint256[] memory) {
        uint256 tokenCount = balanceOf(owner);
        require(0 < tokenCount, "ERC721Enumerable: owner index out of bounds");
        uint256 stakedCount = 0;
        for (uint256 i = 0; i < tokenCount; i++) {
            if (isStaked[tokenOfOwnerByIndex(owner, i)]) {
                stakedCount++;
            }
        }

        uint256[] memory tokenIds = new uint256[](stakedCount);
        stakedCount = 0;
        for (uint256 i = 0; i < tokenCount; i++) {
            uint256 tokenId = tokenOfOwnerByIndex(owner, i);
            if (isStaked[tokenId]) {
                tokenIds[stakedCount] = tokenId;
                stakedCount++;
            }
        }
        return tokenIds;
    }

    modifier whenNotStaked(uint256 tokenId) {
        _requireMinted(tokenId);
        require(!isStaked[tokenId], "Token is staked");
        _;
    }

    // Override
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId,
        uint256 batchSize
    ) internal virtual override(ERC721, ERC721Enumerable) {
        super._beforeTokenTransfer(from, to, tokenId, batchSize);
    }

    function supportsInterface(
        bytes4 interfaceId
    ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {
        return super.supportsInterface(interfaceId);
    }
}


// Root file: contracts/CashRushNft.sol

pragma solidity 0.8.17;

// import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
// import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
// import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
// import "@openzeppelin/contracts/token/common/ERC2981.sol";
// import "operator-filter-registry/src/DefaultOperatorFilterer.sol";
// import "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol";
// import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
// import "@openzeppelin/contracts/token/ERC721/extensions/draft-ERC721Votes.sol";
// import "@openzeppelin/contracts/access/Ownable.sol";
// import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
// import "@openzeppelin/contracts/utils/Strings.sol";
// import "@openzeppelin/contracts/utils/Counters.sol";
// import "contracts/CashRushNftStaking.sol";

interface ITraitsShort {
    function contractURI() external view returns (string memory);

    function tokenURI(uint256 tokenId) external view returns (string memory);
}

contract CashRushNft is
    ERC721,
    ERC721Enumerable,
    ERC721Burnable,
    CashRushNftStaking,
    ERC2981,
    DefaultOperatorFilterer,
    EIP712,
    ERC721Votes,
    ReentrancyGuard,
    Ownable
{
    using Strings for uint256;
    using Counters for Counters.Counter;

    uint256 private constant DAY = 86_400;
    uint256 private constant MAX_SUPPLY = 4000;
    uint256 public FREE_MINT = 170;
    uint256 private totalMinted;
    Counters.Counter private _tokenIdCounter;

    // Metadata
    address public TRAITS;
    string private _contractURI = "https://cashrush.gg/metadata/contract.json";
    string private _baseURL = "https://cashrush.gg/metadata/";
    string private _baseExtension = ".json";
    bool private _revealed = false;
    string private _notRevealedURI =
        "https://cashrush.gg/metadata/unrevealed.json";

    // Mints
    address payable public wallet;
    // Free Mint
    bool public isActiveFreeMint = false;
    bytes32 public merkleRoot1;
    mapping(address => uint256) public minted1;
    // WL Mint
    bool public isActiveWhitelistMint = false;
    bytes32 public merkleRoot2;
    mapping(address => uint256) public minted2;
    uint256 public price2 = 0.03 ether;
    // Public Mint
    bool public isActivePublicMint = false;
    uint256 public price3 = 0.04 ether;

    uint256 public totalRewards;
    mapping(uint256 => uint256) public rewards;
    mapping(uint256 => uint256) public rewardsLastClaim;

    address public killer;
    address public killSigner;
    uint256 public immutable chainId;

    event Received(address indexed account, uint256 value);

    event Killed(uint256 indexed tokenId);
    event KillerChanged(address indexed oldKiller, address indexed newKiller);
    event KillSignerChanged(
        address indexed oldKillSigner,
        address indexed newKillSigner
    );

    error IndexOutOfBounds();
    error MintNotActive();
    error MintLimit();
    error NotAuthorized();
    error IncorrectValue();

    constructor()
        public
        ERC721("CASH RUSH", "CASHRUSH")
        EIP712("CASH RUSH", "1")
    {
        wallet = payable(0x8fa9873B72caF6215EbB5f9956d3CC67aa91F951);
        _setDefaultRoyalty(0x8fa9873B72caF6215EbB5f9956d3CC67aa91F951, 500);

        // Setting start from 1.
        _tokenIdCounter.increment();

        chainId = block.chainid;
        emit KillerChanged(killer, _msgSender());
        killer = _msgSender();
        //emit KillSignerChanged(killSigner, _msgSender());
        //killSigner = _msgSender();
    }

    // CashRush - kill
    function kill(
        uint256 tokenId,
        bytes memory signature
    ) external whenNotStaked(tokenId) {
        require(_msgSender() == killer, "Access denied");

        if (killSigner != address(0)) {
            _checkSignature(tokenId, signature);
        }

        _burn(tokenId);
        emit Killed(tokenId);
    }

    function setKiller(address newKiller) external onlyOwner {
        emit KillerChanged(killer, newKiller);
        killer = newKiller;
    }

    function setKillSigner(address newKillSigner) external onlyOwner {
        emit KillSignerChanged(killSigner, newKillSigner);
        killSigner = newKillSigner;
    }

    function _checkSignature(
        uint256 tokenId,
        bytes memory signature
    ) internal view {
        address tokenOwner = _ownerOf(tokenId);
        if (_signatureWallet(tokenId, tokenOwner, signature) != killSigner)
            revert NotAuthorized();
    }

    function _signatureWallet(
        uint256 tokenId,
        address tokenOwner,
        bytes memory signature
    ) private view returns (address) {
        return
            ECDSA.recover(
                keccak256(abi.encode(chainId, tokenId, tokenOwner)),
                signature
            );
    }

    // CashRush - Game fees distribution
    function accumulated(
        uint256[] memory tokenIds
    ) external view returns (uint256) {
        uint256 share = (totalRewards + address(this).balance) / totalMinted;
        uint256 total;
        for (uint256 i = 0; i < tokenIds.length; i++) {
            uint256 tokenId = tokenIds[i];
            if (tokenId < 1 || tokenId > totalMinted) revert IndexOutOfBounds();
            for (uint256 j = i + 1; j < tokenIds.length; j++) {
                if (tokenId == tokenIds[j]) revert DuplicateTokenId();
            }
            uint256 payedRewards = rewards[tokenId];
            if (payedRewards < share) {
                total += (share - payedRewards);
            }
        }
        return total;
    }

    function claim(uint256[] memory tokenIds) external nonReentrant {
        uint256 share = (totalRewards + address(this).balance) / totalMinted;
        uint256 total;
        for (uint256 i = 0; i < tokenIds.length; i++) {
            uint256 tokenId = tokenIds[i];
            for (uint256 j = i + 1; j < tokenIds.length; j++) {
                if (tokenId == tokenIds[j]) revert DuplicateTokenId();
            }
            if (ownerOf(tokenId) != _msgSender()) revert NotTokenOwner();
            uint256 payedRewards = rewards[tokenId];
            if (payedRewards < share) {
                uint256 toPay = share - payedRewards;
                rewards[tokenId] += toPay;
                rewardsLastClaim[tokenId] = block.timestamp;
                total += toPay;
            }
        }
        if (total > 0) {
            _sendEth(payable(_msgSender()), total);
            totalRewards += total;
        }
    }

    function claimByOwner(
        uint256[] memory tokenIds
    ) external nonReentrant onlyOwner {
        uint256 share = (totalRewards + address(this).balance) / totalMinted;
        uint256 total;
        for (uint256 i = 0; i < tokenIds.length; i++) {
            uint256 tokenId = tokenIds[i];
            if (tokenId < 1 || tokenId > totalMinted) revert IndexOutOfBounds();
            for (uint256 j = i + 1; j < tokenIds.length; j++) {
                if (tokenId == tokenIds[j]) revert DuplicateTokenId();
            }
            require(
                (rewardsLastClaim[tokenId] + DAY * 90) <= block.timestamp,
                "Not allowed"
            );
            uint256 payedRewards = rewards[tokenId];
            if (payedRewards < share) {
                uint256 toPay = share - payedRewards;
                rewards[tokenId] += toPay;
                rewardsLastClaim[tokenId] = block.timestamp;
                total += toPay;
            }
        }
        if (total > 0) {
            _sendEth(payable(_msgSender()), total);
            totalRewards += total;
        }
    }

    // CashRush - Mint
    function safeMint(
        address to,
        uint256 tokenCount
    ) external nonReentrant onlyOwner {
        require((totalSupply() + tokenCount) <= MAX_SUPPLY, "MAX_SUPPLY");
        totalMinted += tokenCount;
        for (uint256 i = 0; i < tokenCount; i++) {
            uint256 tokenId = _tokenIdCounter.current();
            _tokenIdCounter.increment();
            _safeMint(to, tokenId);
        }
    }

    function setWallet(address _wallet) external onlyOwner {
        wallet = payable(_wallet);
    }

    function setActiveFreeMint(bool status) external onlyOwner {
        isActiveFreeMint = status;
    }

    function setActiveWhitelistMint(bool status) external onlyOwner {
        isActiveWhitelistMint = status;
    }

    function setActivePublicMint(bool status) external onlyOwner {
        isActivePublicMint = status;
    }

    function freeMint(
        address account,
        bytes32[] calldata merkleProof
    ) external nonReentrant {
        if (!isActiveFreeMint || FREE_MINT == 0) revert MintNotActive();
        if (minted1[account] >= 1) revert MintLimit();
        require(
            _verify1(_leaf(account, 1), merkleProof),
            "MerkleDistributor: Invalid  merkle proof"
        );
        FREE_MINT--;
        minted1[account]++;
        totalMinted++;
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _safeMint(account, tokenId);
    }

    function whitelistMint(
        address account,
        uint256 tokenCount,
        bytes32[] calldata merkleProof
    ) external payable nonReentrant {
        if (!isActiveWhitelistMint) revert MintNotActive();
        if ((minted2[account] + tokenCount) > 5) revert MintLimit();
        require(
            _verify2(_leaf(account, 1), merkleProof),
            "MerkleDistributor: Invalid  merkle proof"
        );
        require((totalSupply() + tokenCount) <= MAX_SUPPLY, "MAX_SUPPLY");
        if (msg.value != tokenCount * price2) revert IncorrectValue();
        _sendEth(wallet, msg.value);
        minted2[account] += tokenCount;
        totalMinted += tokenCount;
        for (uint256 i = 0; i < tokenCount; i++) {
            uint256 tokenId = _tokenIdCounter.current();
            _tokenIdCounter.increment();
            _safeMint(account, tokenId);
        }
    }

    function publicMint(uint256 tokenCount) external payable nonReentrant {
        if (!isActivePublicMint) revert MintNotActive();
        require((totalSupply() + tokenCount) <= MAX_SUPPLY, "MAX_SUPPLY");
        if (msg.value != tokenCount * price3) revert IncorrectValue();
        _sendEth(wallet, msg.value);
        totalMinted += tokenCount;
        for (uint256 i = 0; i < tokenCount; i++) {
            uint256 tokenId = _tokenIdCounter.current();
            _tokenIdCounter.increment();
            _safeMint(_msgSender(), tokenId);
        }
    }

    function _sendEth(address payable recipient, uint256 amount) private {
        (bool success, ) = recipient.call{value: amount}("");
        require(success, "ETH_TRANSFER_FAILED");
    }

    function _leaf(
        address account,
        uint256 amount
    ) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked(account, amount));
    }

    function _verify1(
        bytes32 leaf,
        bytes32[] memory merkleProof
    ) internal view returns (bool) {
        return MerkleProof.verify(merkleProof, merkleRoot1, leaf);
    }

    function _verify2(
        bytes32 leaf,
        bytes32[] memory merkleProof
    ) internal view returns (bool) {
        return MerkleProof.verify(merkleProof, merkleRoot2, leaf);
    }

    function setRoot1(bytes32 merkleRoot_) external onlyOwner {
        merkleRoot1 = merkleRoot_;
    }

    function setRoot2(bytes32 merkleRoot_) external onlyOwner {
        merkleRoot2 = merkleRoot_;
    }

    receive() external payable {
        emit Received(msg.sender, msg.value);
    }

    // Extra
    function rawOwnerOf(uint256 tokenId) external view returns (address) {
        return _ownerOf(tokenId);
    }

    function tokensOfOwner(
        address owner
    ) external view returns (uint256[] memory) {
        uint256 tokenCount = balanceOf(owner);
        require(0 < tokenCount, "ERC721Enumerable: owner index out of bounds");
        uint256[] memory tokenIds = new uint256[](tokenCount);
        for (uint256 i = 0; i < tokenCount; i++) {
            tokenIds[i] = tokenOfOwnerByIndex(owner, i);
        }
        return tokenIds;
    }

    // NFTs Types
    function uploadTypes(uint256 shift, bytes memory types) external onlyOwner {
        _uploadTypes(shift, types);
    }

    function freezeData() external onlyOwner {
        _freezeData();
    }

    // Metadata
    function reveal() external onlyOwner {
        _revealed = true;
    }

    function setNotRevealedURI(string memory uri_) external onlyOwner {
        _notRevealedURI = uri_;
    }

    function contractURI() external view returns (string memory) {
        if (TRAITS != address(0)) return ITraitsShort(TRAITS).contractURI();
        return _contractURI;
    }

    function setContractURI(string memory uri_) external onlyOwner {
        _contractURI = uri_;
    }

    function tokenURI(
        uint256 tokenId
    ) public view override returns (string memory) {
        _requireMinted(tokenId);

        if (!_revealed) return _notRevealedURI;

        if (TRAITS != address(0)) return ITraitsShort(TRAITS).tokenURI(tokenId);

        return
            string(
                abi.encodePacked(_baseURL, tokenId.toString(), _baseExtension)
            );
    }

    function setBaseURI(string memory uri_) external onlyOwner {
        _baseURL = uri_;
    }

    function setBaseExtension(string memory fileExtension) external onlyOwner {
        _baseExtension = fileExtension;
    }

    function setTraits(address traits_) external onlyOwner {
        TRAITS = traits_;
    }

    // Royalty
    function setDefaultRoyalty(
        address royaltyReceiver,
        uint96 royaltyNumerator
    ) external onlyOwner {
        _setDefaultRoyalty(royaltyReceiver, royaltyNumerator);
    }

    function deleteDefaultRoyalty() external onlyOwner {
        _deleteDefaultRoyalty();
    }

    // Override
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId,
        uint256 batchSize
    ) internal override(ERC721, ERC721Enumerable, CashRushNftStaking) {
        super._beforeTokenTransfer(from, to, tokenId, batchSize);
    }

    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId,
        uint256 batchSize
    ) internal override(ERC721, ERC721Votes) {
        super._afterTokenTransfer(from, to, tokenId, batchSize);
    }

    function setApprovalForAll(
        address operator,
        bool approved
    ) public override(ERC721, IERC721) onlyAllowedOperatorApproval(operator) {
        super.setApprovalForAll(operator, approved);
    }

    function approve(
        address operator,
        uint256 tokenId
    ) public override(ERC721, IERC721) onlyAllowedOperatorApproval(operator) {
        super.approve(operator, tokenId);
    }

    function burn(uint256 tokenId) public override whenNotStaked(tokenId) {
        super.burn(tokenId);
    }

    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    )
        public
        override(ERC721, IERC721)
        whenNotStaked(tokenId)
        onlyAllowedOperator(from)
    {
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    )
        public
        override(ERC721, IERC721)
        whenNotStaked(tokenId)
        onlyAllowedOperator(from)
    {
        super.safeTransferFrom(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    )
        public
        override(ERC721, IERC721)
        whenNotStaked(tokenId)
        onlyAllowedOperator(from)
    {
        super.safeTransferFrom(from, to, tokenId, data);
    }

    function supportsInterface(
        bytes4 interfaceId
    )
        public
        view
        override(ERC721, ERC721Enumerable, CashRushNftStaking, ERC2981)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DuplicateTokenId","type":"error"},{"inputs":[],"name":"ErrorIsFrozen","type":"error"},{"inputs":[],"name":"IncorrectValue","type":"error"},{"inputs":[],"name":"IndexOutOfBounds","type":"error"},{"inputs":[],"name":"MintLimit","type":"error"},{"inputs":[],"name":"MintNotActive","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"inputs":[],"name":"NotTokenOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isFrozen","type":"bool"}],"name":"DataFrozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"extraRate","type":"uint256"}],"name":"ExtraRateSetted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldKillSigner","type":"address"},{"indexed":true,"internalType":"address","name":"newKillSigner","type":"address"}],"name":"KillSignerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Killed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldKiller","type":"address"},{"indexed":true,"internalType":"address","name":"newKiller","type":"address"}],"name":"KillerChanged","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":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Received","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"prevValue","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"newValue","type":"uint8"}],"name":"TypeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Unstaked","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FREE_MINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TRAITS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"accountRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"accumulated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"chainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"claimByOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dataIsFrozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deleteDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"extraRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"freeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"freezeData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isActiveFreeMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isActivePublicMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isActiveWhitelistMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isStaked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"kill","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"killSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"killer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot1","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot2","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"minted1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"minted2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price3","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenCount","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"rawOwnerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardsLastClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenCount","type":"uint256"}],"name":"safeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"status","type":"bool"}],"name":"setActiveFreeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"status","type":"bool"}],"name":"setActivePublicMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"status","type":"bool"}],"name":"setActiveWhitelistMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fileExtension","type":"string"}],"name":"setBaseExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri_","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri_","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"royaltyReceiver","type":"address"},{"internalType":"uint96","name":"royaltyNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newKillSigner","type":"address"}],"name":"setKillSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newKiller","type":"address"}],"name":"setKiller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri_","type":"string"}],"name":"setNotRevealedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"merkleRoot_","type":"bytes32"}],"name":"setRoot1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"merkleRoot_","type":"bytes32"}],"name":"setRoot2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"traits_","type":"address"}],"name":"setTraits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"setWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenType","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"tokensMaxRate","outputs":[{"internalType":"uint256","name":"maxRate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensStakedOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shift","type":"uint256"},{"internalType":"bytes","name":"types","type":"bytes"}],"name":"uploadTypes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wallet","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"tokenCount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60aa6016556101c0604052602a610160818152906200676061018039601a906200002a90826200065c565b5060408051808201909152601d81527f68747470733a2f2f63617368727573682e67672f6d657461646174612f0000006020820152601b906200006e90826200065c565b50604080518082019091526005815264173539b7b760d91b6020820152601c906200009a90826200065c565b50601d805460ff191690556040805160608101909152602c8082526200678a6020830139601e90620000cd90826200065c565b50601f805460ff60a01b191690556022805460ff19908116909155666a94d74f430000602555602680549091169055668e1bc9bf0400006027553480156200011457600080fd5b506040518060400160405280600981526020016808682a69040a4aaa6960bb1b815250604051806040016040528060018152602001603160f81b815250733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600981526020016808682a69040a4aaa6960bb1b8152506040518060400160405280600881526020016708682a690a4aaa6960c31b8152508160009081620001bc91906200065c565b506001620001cb82826200065c565b5050506daaeb6d7670e522a718067333cd4e3b15620003135780156200026157604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b1580156200024257600080fd5b505af115801562000257573d6000803e3d6000fd5b5050505062000313565b6001600160a01b03821615620002b25760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af29039060440162000227565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b158015620002f957600080fd5b505af11580156200030e573d6000803e3d6000fd5b505050505b5050815160209283012081519183019190912060e08290526101008190524660a0818152604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818801819052818301969096526060810194909452608080850193909352308483018190528151808603909301835260c094850190915281519190950120905291909152610120526001601455620003b43362000457565b601f80546001600160a01b031916738fa9873b72caf6215ebb5f9956d3cc67aa91f951908117909155620003eb906101f4620004a9565b620004026018620005ae60201b6200305a1760201c565b4661014052602b5460405133916001600160a01b0316907fffc9d6771ac85ad61d4a37cd4654daecd7906cd92b449f80e0d9f740a19ccf6790600090a3602b80546001600160a01b0319163317905562000728565b601580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6127106001600160601b03821611156200051d5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084015b60405180910390fd5b6001600160a01b038216620005755760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c696420726563656976657200000000000000604482015260640162000514565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600e55565b80546001019055565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620005e257607f821691505b6020821081036200060357634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200065757600081815260208120601f850160051c81016020861015620006325750805b601f850160051c820191505b8181101562000653578281556001016200063e565b5050505b505050565b81516001600160401b03811115620006785762000678620005b7565b6200069081620006898454620005cd565b8462000609565b602080601f831160018114620006c85760008415620006af5750858301515b600019600386901b1c1916600185901b17855562000653565b600085815260208120601f198616915b82811015620006f957888601518255948401946001909101908401620006d8565b5085821015620007185787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e051610100516101205161014051615fd66200078a60003960008181610c1d015261483d015260006137b901526000613808015260006137e30152600061373c01526000613766015260006137900152615fd66000f3fe6080604052600436106104c45760003560e01c806370a0823111610276578063be4699201161014f578063e64710e6116100c1578063e985e9c511610085578063e985e9c514610f6a578063eafb452314610fb3578063f2c4ce1e14610fd3578063f2fde38b14610ff3578063f301af4214611013578063f57145321461104057600080fd5b8063e64710e614610ebd578063e6c3b1f614610ed3578063e80e2a9f14610f15578063e8a3d48514610f35578063e97382bd14610f4a57600080fd5b8063da3ef23f11610113578063da3ef23f14610e07578063db065b1d14610e27578063deaa59df14610e3d578063e0dd8cb814610e5d578063e28f6cb914610e7d578063e449f34114610e9d57600080fd5b8063be46992014610d7b578063c3cda52014610d9b578063c87b56dd14610dbb578063ca34adf014610ddb578063d778c91114610df157600080fd5b80639a8a0592116101e8578063a475b5dd116101ac578063a475b5dd14610ccc578063aa1b103f14610ce1578063ae97166d14610cf6578063b05374d514610d16578063b88d4fde14610d2b578063baa51f8614610d4b57600080fd5b80639a8a059214610c0b5780639ab24eb014610c3f578063a144819414610c5f578063a22cb46514610c7f578063a2fc01ae14610c9f57600080fd5b80638c20aff61161023a5780638c20aff614610b585780638da5cb5b14610b785780638e539e8c14610b96578063938e3d7b14610bb6578063946b593114610bd657806395d89b4114610bf657600080fd5b806370a0823114610ac3578063715018a614610ae35780637ecebe0014610af85780637f81be6914610b185780638462151c14610b3857600080fd5b80633a46b1a8116103a85780634f6ccce71161031a5780635aac546d116102de5780635aac546d14610a095780635c19a95c14610a235780636352211e14610a435780636566765214610a635780636ba4c13814610a835780636f4f736614610aa357600080fd5b80634f6ccce71461095057806351c4998e14610970578063521eb2731461099057806355f804b3146109b0578063587cde1e146109d057600080fd5b806342966c681161036c57806342966c681461089057806345f02525146108b05780634b11faaf146108dd5780634b2e654c146108f05780634c2ebff6146109105780634d65b0351461093057600080fd5b80633a46b1a8146107ee5780633ab3d4f61461080e57806340a194361461082e57806341f434341461084e57806342842e0e1461087057600080fd5b80631af7c4e1116104415780632a55205a116104055780632a55205a1461070d5780632db115441461074c5780632f745c591461075f578063339480c81461077f5780633644e515146107ac57806339211e58146107c157600080fd5b80631af7c4e114610676578063222f91ee14610696578063232da117146106b757806323b872dd146106d757806327a3181d146106f757600080fd5b80630d65a6b2116104885780630d65a6b2146105d65780630e15561a146105f05780630f3bd2f6146106145780630fbf0a931461064157806318160ddd1461066157600080fd5b806301ffc9a71461050557806304634d8d1461053a57806306fdde031461055c578063081812fc1461057e578063095ea7b3146105b657600080fd5b366105005760405134815233907f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f885258749060200160405180910390a2005b600080fd5b34801561051157600080fd5b506105256105203660046153dd565b61105a565b60405190151581526020015b60405180910390f35b34801561054657600080fd5b5061055a610555366004615416565b61106b565b005b34801561056857600080fd5b50610571611081565b60405161053191906154a9565b34801561058a57600080fd5b5061059e6105993660046154bc565b611113565b6040516001600160a01b039091168152602001610531565b3480156105c257600080fd5b5061055a6105d13660046154d5565b61113a565b3480156105e257600080fd5b50600a546105259060ff1681565b3480156105fc57600080fd5b5061060660285481565b604051908152602001610531565b34801561062057600080fd5b5061063461062f3660046154ff565b611153565b604051610531919061551a565b34801561064d57600080fd5b5061055a61065c3660046155a4565b6112a2565b34801561066d57600080fd5b50600854610606565b34801561068257600080fd5b5061055a6106913660046154ff565b6112b0565b3480156106a257600080fd5b50601f5461052590600160a01b900460ff1681565b3480156106c357600080fd5b506106066106d23660046154ff565b611314565b3480156106e357600080fd5b5061055a6106f2366004615649565b611322565b34801561070357600080fd5b5061060660255481565b34801561071957600080fd5b5061072d610728366004615685565b611387565b604080516001600160a01b039093168352602083019190915201610531565b61055a61075a3660046154bc565b611435565b34801561076b57600080fd5b5061060661077a3660046154d5565b61153d565b34801561078b57600080fd5b5061060661079a3660046154ff565b600d6020526000908152604090205481565b3480156107b857600080fd5b5061060661158f565b3480156107cd57600080fd5b506106066107dc3660046154ff565b60216020526000908152604090205481565b3480156107fa57600080fd5b506106066108093660046154d5565b61159e565b34801561081a57600080fd5b50602b5461059e906001600160a01b031681565b34801561083a57600080fd5b506106066108493660046155a4565b6115c7565b34801561085a57600080fd5b5061059e6daaeb6d7670e522a718067333cd4e81565b34801561087c57600080fd5b5061055a61088b366004615649565b611ca2565b34801561089c57600080fd5b5061055a6108ab3660046154bc565b611d00565b3480156108bc57600080fd5b506106066108cb3660046154ff565b60246020526000908152604090205481565b61055a6108eb3660046156eb565b611d42565b3480156108fc57600080fd5b5061060661090b3660046154bc565b611f28565b34801561091c57600080fd5b5061055a61092b366004615752565b611fc3565b34801561093c57600080fd5b5061055a61094b3660046155a4565b611fde565b34801561095c57600080fd5b5061060661096b3660046154bc565b6121e5565b34801561097c57600080fd5b5061055a61098b3660046154bc565b612278565b34801561099c57600080fd5b50601f5461059e906001600160a01b031681565b3480156109bc57600080fd5b5061055a6109cb3660046157d4565b612285565b3480156109dc57600080fd5b5061059e6109eb3660046154ff565b6001600160a01b039081166000908152601060205260409020541690565b348015610a1557600080fd5b506026546105259060ff1681565b348015610a2f57600080fd5b5061055a610a3e3660046154ff565b612299565b348015610a4f57600080fd5b5061059e610a5e3660046154bc565b6122a4565b348015610a6f57600080fd5b5061055a610a7e3660046154ff565b612304565b348015610a8f57600080fd5b5061055a610a9e3660046155a4565b612368565b348015610aaf57600080fd5b5061055a610abe3660046154ff565b6124d3565b348015610acf57600080fd5b50610606610ade3660046154ff565b6124fd565b348015610aef57600080fd5b5061055a612583565b348015610b0457600080fd5b50610606610b133660046154ff565b612597565b348015610b2457600080fd5b5061059e610b333660046154bc565b6125b5565b348015610b4457600080fd5b50610634610b533660046154ff565b6125d2565b348015610b6457600080fd5b5061055a610b7336600461581c565b612693565b348015610b8457600080fd5b506015546001600160a01b031661059e565b348015610ba257600080fd5b50610606610bb13660046154bc565b6127f1565b348015610bc257600080fd5b5061055a610bd13660046157d4565b61284d565b348015610be257600080fd5b50610606610bf13660046155a4565b612861565b348015610c0257600080fd5b50610571612982565b348015610c1757600080fd5b506106067f000000000000000000000000000000000000000000000000000000000000000081565b348015610c4b57600080fd5b50610606610c5a3660046154ff565b612991565b348015610c6b57600080fd5b5061055a610c7a3660046154d5565b6129c1565b348015610c8b57600080fd5b5061055a610c9a36600461586e565b612a6c565b348015610cab57600080fd5b50610606610cba3660046154bc565b602a6020526000908152604090205481565b348015610cd857600080fd5b5061055a612a80565b348015610ced57600080fd5b5061055a612a97565b348015610d0257600080fd5b5061055a610d113660046158ba565b612aa9565b348015610d2257600080fd5b5061055a612abb565b348015610d3757600080fd5b5061055a610d46366004615900565b612acb565b348015610d5757600080fd5b50610525610d663660046154bc565b600c6020526000908152604090205460ff1681565b348015610d8757600080fd5b5061055a610d96366004615752565b612b32565b348015610da757600080fd5b5061055a610db6366004615967565b612b58565b348015610dc757600080fd5b50610571610dd63660046154bc565b612c85565b348015610de757600080fd5b5061060660235481565b348015610dfd57600080fd5b5061060660275481565b348015610e1357600080fd5b5061055a610e223660046157d4565b612de3565b348015610e3357600080fd5b5061060660165481565b348015610e4957600080fd5b5061055a610e583660046154ff565b612df7565b348015610e6957600080fd5b5061055a610e783660046154bc565b612e21565b348015610e8957600080fd5b5061055a610e983660046158ba565b612e2e565b348015610ea957600080fd5b5061055a610eb83660046155a4565b612f0e565b348015610ec957600080fd5b5061060660205481565b348015610edf57600080fd5b50610f03610eee3660046154bc565b600b6020526000908152604090205460ff1681565b60405160ff9091168152602001610531565b348015610f2157600080fd5b50602c5461059e906001600160a01b031681565b348015610f4157600080fd5b50610571612f19565b348015610f5657600080fd5b5060195461059e906001600160a01b031681565b348015610f7657600080fd5b50610525610f853660046159c7565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610fbf57600080fd5b5061055a610fce366004615752565b612fb5565b348015610fdf57600080fd5b5061055a610fee3660046157d4565b612fd0565b348015610fff57600080fd5b5061055a61100e3660046154ff565b612fe4565b34801561101f57600080fd5b5061060661102e3660046154bc565b60296020526000908152604090205481565b34801561104c57600080fd5b506022546105259060ff1681565b600061106582613063565b92915050565b611073613088565b61107d82826130e2565b5050565b606060008054611090906159fa565b80601f01602080910402602001604051908101604052809291908181526020018280546110bc906159fa565b80156111095780601f106110de57610100808354040283529160200191611109565b820191906000526020600020905b8154815290600101906020018083116110ec57829003601f168201915b5050505050905090565b600061111e826131df565b506000908152600460205260409020546001600160a01b031690565b816111448161323e565b61114e83836132f7565b505050565b60606000611160836124fd565b90508060001061118b5760405162461bcd60e51b815260040161118290615a2e565b60405180910390fd5b6000805b828110156111de57600c60006111a5878461153d565b815260208101919091526040016000205460ff16156111cc57816111c881615a8f565b9250505b806111d681615a8f565b91505061118f565b506000816001600160401b038111156111f9576111f961555e565b604051908082528060200260200182016040528015611222578160200160208202803683370190505b5090506000915060005b83811015611299576000611240878361153d565b6000818152600c602052604090205490915060ff1615611286578083858151811061126d5761126d615aa8565b60209081029190910101528361128281615a8f565b9450505b508061129181615a8f565b91505061122c565b50949350505050565b6112ad816001613407565b50565b6112b8613088565b602b546040516001600160a01b038084169216907fffc9d6771ac85ad61d4a37cd4654daecd7906cd92b449f80e0d9f740a19ccf6790600090a3602b80546001600160a01b0319166001600160a01b0392909216919091179055565b600061106561084983611153565b8061132c816131df565b6000818152600c602052604090205460ff161561135b5760405162461bcd60e51b815260040161118290615abe565b836001600160a01b0381163314611375576113753361323e565b6113808585856135f1565b5050505050565b6000828152600f602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925282916113fc575060408051808201909152600e546001600160a01b0381168252600160a01b90046001600160601b031660208201525b60208101516000906127109061141b906001600160601b031687615ae7565b6114259190615b14565b91519350909150505b9250929050565b61143d613623565b60265460ff166114605760405163914edb0f60e01b815260040160405180910390fd5b610fa08161146d60085490565b6114779190615b36565b11156114955760405162461bcd60e51b815260040161118290615b49565b6027546114a29082615ae7565b34146114c157604051636956f2ab60e11b815260040160405180910390fd5b601f546114d7906001600160a01b03163461367c565b80601760008282546114e99190615b36565b90915550600090505b8181101561153257600061150560185490565b9050611515601880546001019055565b61151f3382613715565b508061152a81615a8f565b9150506114f2565b506112ad6001601455565b6000611548836124fd565b82106115665760405162461bcd60e51b815260040161118290615a2e565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600061159961372f565b905090565b6001600160a01b03821660009081526011602052604081206115c09083613856565b9392505050565b600080806115d7600e6001615b6d565b60ff166001600160401b038111156115f1576115f161555e565b60405190808252806020026020018201604052801561161a578160200160208202803683370190505b50905060005b84518110156116b157600085828151811061163d5761163d615aa8565b60200260200101519050600061165282611f28565b6000838152600b6020526040902054855191925060ff169060019086908390811061167f5761167f615aa8565b911515602092830291909101909101526116998287613972565b955050505080806116a990615a8f565b915050611620565b50806001815181106116c5576116c5615aa8565b602002602001015180156116f05750806002815181106116e7576116e7615aa8565b60200260200101515b801561171357508060038151811061170a5761170a615aa8565b60200260200101515b801561173657508060048151811061172d5761172d615aa8565b60200260200101515b801561175957508060058151811061175057611750615aa8565b60200260200101515b801561177c57508060068151811061177357611773615aa8565b60200260200101515b801561179f57508060078151811061179657611796615aa8565b60200260200101515b80156117c25750806008815181106117b9576117b9615aa8565b60200260200101515b80156117e55750806009815181106117dc576117dc615aa8565b60200260200101515b8015611808575080600a815181106117ff576117ff615aa8565b60200260200101515b801561182b575080600b8151811061182257611822615aa8565b60200260200101515b801561184e575080600c8151811061184557611845615aa8565b60200260200101515b8015611871575080600d8151811061186857611868615aa8565b60200260200101515b8015611894575080600e8151811061188b5761188b615aa8565b60200260200101515b156118a3575060649392505050565b806001815181106118b6576118b6615aa8565b602002602001015180156118e15750806002815181106118d8576118d8615aa8565b60200260200101515b156118f05750601e9392505050565b8060018151811061190357611903615aa8565b6020026020010151801561192e57508060058151811061192557611925615aa8565b60200260200101515b1561193d5750601e9392505050565b8060018151811061195057611950615aa8565b6020026020010151801561197b575080600a8151811061197257611972615aa8565b60200260200101515b1561198a575060199392505050565b8060038151811061199d5761199d615aa8565b602002602001015180156119c85750806005815181106119bf576119bf615aa8565b60200260200101515b156119d7575060149392505050565b806003815181106119ea576119ea615aa8565b60200260200101518015611a15575080600481518110611a0c57611a0c615aa8565b60200260200101515b8015611a38575080600581518110611a2f57611a2f615aa8565b60200260200101515b15611a47575060149392505050565b80600481518110611a5a57611a5a615aa8565b60200260200101518015611a85575080600a81518110611a7c57611a7c615aa8565b60200260200101515b15611a9d57611a95600f83613972565b949350505050565b80600581518110611ab057611ab0615aa8565b602002602001015115611b0a5780600881518110611ad057611ad0615aa8565b602002602001015180611afa575080600b81518110611af157611af1615aa8565b60200260200101515b15611b0a57611a95600f83613972565b80600681518110611b1d57611b1d615aa8565b60200260200101518015611b48575080600781518110611b3f57611b3f615aa8565b60200260200101515b8015611b6b575080600881518110611b6257611b62615aa8565b60200260200101515b8015611b8e575080600981518110611b8557611b85615aa8565b60200260200101515b8015611bb1575080600a81518110611ba857611ba8615aa8565b60200260200101515b8015611bd4575080600b81518110611bcb57611bcb615aa8565b60200260200101515b8015611bf7575080600c81518110611bee57611bee615aa8565b60200260200101515b8015611c1a575080600d81518110611c1157611c11615aa8565b60200260200101515b8015611c3d575080600e81518110611c3457611c34615aa8565b60200260200101515b15611c4d57611a95600f83613972565b80600981518110611c6057611c60615aa8565b60200260200101518015611c8b575080600c81518110611c8257611c82615aa8565b60200260200101515b15611c9b57611a95600a83613972565b5092915050565b80611cac816131df565b6000818152600c602052604090205460ff1615611cdb5760405162461bcd60e51b815260040161118290615abe565b836001600160a01b0381163314611cf557611cf53361323e565b611380858585613988565b80611d0a816131df565b6000818152600c602052604090205460ff1615611d395760405162461bcd60e51b815260040161118290615abe565b61107d826139a3565b611d4a613623565b60225460ff16611d6d5760405163914edb0f60e01b815260040160405180910390fd5b6001600160a01b038416600090815260246020526040902054600590611d94908590615b36565b1115611db35760405163ec8e6a6360e01b815260040160405180910390fd5b611dfa611dc18560016139d1565b838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613a1992505050565b611e165760405162461bcd60e51b815260040161118290615b86565b610fa083611e2360085490565b611e2d9190615b36565b1115611e4b5760405162461bcd60e51b815260040161118290615b49565b602554611e589084615ae7565b3414611e7757604051636956f2ab60e11b815260040160405180910390fd5b601f54611e8d906001600160a01b03163461367c565b6001600160a01b03841660009081526024602052604081208054859290611eb5908490615b36565b925050819055508260176000828254611ece9190615b36565b90915550600090505b83811015611f17576000611eea60185490565b9050611efa601880546001019055565b611f048682613715565b5080611f0f81615a8f565b915050611ed7565b50611f226001601455565b50505050565b6000818152600b602052604081205460ff1680611f485750600092915050565b600160ff821610801590611f605750600260ff821611155b15611f6e5750601492915050565b600360ff821610801590611f865750600560ff821611155b15611f945750600a92915050565b600660ff821610801590611fac5750600e60ff821611155b15611fba5750600592915050565b50600092915050565b611fcb613088565b6026805460ff1916911515919091179055565b611fe6613623565b611fee613088565b6000601754476028546120019190615b36565b61200b9190615b14565b90506000805b83518110156121b057600084828151811061202e5761202e615aa8565b602002602001015190506001811080612048575060175481115b1561206657604051634e23d03560e01b815260040160405180910390fd5b6000612073836001615b36565b90505b85518110156120ca5785818151811061209157612091615aa8565b602002602001015182036120b8576040516315e8d02d60e11b815260040160405180910390fd5b806120c281615a8f565b915050612076565b50426120da62015180605a615ae7565b6000838152602a60205260409020546120f39190615b36565b111561212f5760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b6044820152606401611182565b6000818152602960205260409020548481101561219b5760006121528287615bce565b9050806029600085815260200190815260200160002060008282546121779190615b36565b90915550506000838152602a602052604090204290556121978186615b36565b9450505b505080806121a890615a8f565b915050612011565b5080156121d9576121c1338261367c565b80602860008282546121d39190615b36565b90915550505b50506112ad6001601455565b60006121f060085490565b82106122535760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401611182565b6008828154811061226657612266615aa8565b90600052602060002001549050919050565b612280613088565b602055565b61228d613088565b601b61107d8282615c27565b3361107d8183613a28565b6000818152600260205260408120546001600160a01b0316806110655760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401611182565b61230c613088565b602c546040516001600160a01b038084169216907fb39cf814d6b8fc86702226fc8ed660f3188afe02d4962e91396e1688cc54c7e090600090a3602c80546001600160a01b0319166001600160a01b0392909216919091179055565b612370613623565b6000601754476028546123839190615b36565b61238d9190615b14565b90506000805b83518110156121b05760008482815181106123b0576123b0615aa8565b6020026020010151905060008260016123c99190615b36565b90505b8551811015612420578581815181106123e7576123e7615aa8565b6020026020010151820361240e576040516315e8d02d60e11b815260040160405180910390fd5b8061241881615a8f565b9150506123cc565b503361242b826122a4565b6001600160a01b031614612452576040516359dc379f60e01b815260040160405180910390fd5b600081815260296020526040902054848110156124be5760006124758287615bce565b90508060296000858152602001908152602001600020600082825461249a9190615b36565b90915550506000838152602a602052604090204290556124ba8186615b36565b9450505b505080806124cb90615a8f565b915050612393565b6124db613088565b601980546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b0382166125675760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401611182565b506001600160a01b031660009081526003602052604090205490565b61258b613088565b6125956000613a9a565b565b6001600160a01b038116600090815260136020526040812054611065565b6000818152600260205260408120546001600160a01b0316611065565b606060006125df836124fd565b9050806000106126015760405162461bcd60e51b815260040161118290615a2e565b6000816001600160401b0381111561261b5761261b61555e565b604051908082528060200260200182016040528015612644578160200160208202803683370190505b50905060005b8281101561268b5761265c858261153d565b82828151811061266e5761266e615aa8565b60209081029190910101528061268381615a8f565b91505061264a565b509392505050565b61269b613623565b601f54600160a01b900460ff1615806126b45750601654155b156126d25760405163914edb0f60e01b815260040160405180910390fd5b6001600160a01b03831660009081526021602052604090205460011161270b5760405163ec8e6a6360e01b815260040160405180910390fd5b6127526127198460016139d1565b838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613aec92505050565b61276e5760405162461bcd60e51b815260040161118290615b86565b6016805490600061277e83615ce6565b90915550506001600160a01b03831660009081526021602052604081208054916127a783615a8f565b9091555050601780549060006127bc83615a8f565b919050555060006127cc60185490565b90506127dc601880546001019055565b6127e68482613715565b5061114e6001601455565b60004382106128425760405162461bcd60e51b815260206004820152601a60248201527f566f7465733a20626c6f636b206e6f7420796574206d696e65640000000000006044820152606401611182565b611065601283613856565b612855613088565b601a61107d8282615c27565b600080601754476028546128759190615b36565b61287f9190615b14565b90506000805b845181101561268b5760008582815181106128a2576128a2615aa8565b6020026020010151905060018110806128bc575060175481115b156128da57604051634e23d03560e01b815260040160405180910390fd5b60006128e7836001615b36565b90505b865181101561293e5786818151811061290557612905615aa8565b6020026020010151820361292c576040516315e8d02d60e11b815260040160405180910390fd5b8061293681615a8f565b9150506128ea565b506000818152602960205260409020548481101561296d576129608186615bce565b61296a9085615b36565b93505b5050808061297a90615a8f565b915050612885565b606060018054611090906159fa565b6001600160a01b03811660009081526011602052604081206129b290613afb565b6001600160e01b031692915050565b6129c9613623565b6129d1613088565b610fa0816129de60085490565b6129e89190615b36565b1115612a065760405162461bcd60e51b815260040161118290615b49565b8060176000828254612a189190615b36565b90915550600090505b81811015612a61576000612a3460185490565b9050612a44601880546001019055565b612a4e8482613715565b5080612a5981615a8f565b915050612a21565b5061107d6001601455565b81612a768161323e565b61114e8383613b2e565b612a88613088565b601d805460ff19166001179055565b612a9f613088565b6125956000600e55565b612ab1613088565b61107d8282613b39565b612ac3613088565b612595613c19565b81612ad5816131df565b6000818152600c602052604090205460ff1615612b045760405162461bcd60e51b815260040161118290615abe565b846001600160a01b0381163314612b1e57612b1e3361323e565b612b2a86868686613c5c565b505050505050565b612b3a613088565b601f8054911515600160a01b0260ff60a01b19909216919091179055565b83421115612ba85760405162461bcd60e51b815260206004820152601860248201527f566f7465733a207369676e6174757265206578706972656400000000000000006044820152606401611182565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b038816918101919091526060810186905260808101859052600090612c2290612c1a9060a00160405160208183030381529060405280519060200120613c8e565b858585613ca1565b9050612c2d81613cc9565b8614612c725760405162461bcd60e51b8152602060048201526014602482015273566f7465733a20696e76616c6964206e6f6e636560601b6044820152606401611182565b612c7c8188613a28565b50505050505050565b6060612c90826131df565b601d5460ff16612d2c57601e8054612ca7906159fa565b80601f0160208091040260200160405190810160405280929190818152602001828054612cd3906159fa565b8015612d205780601f10612cf557610100808354040283529160200191612d20565b820191906000526020600020905b815481529060010190602001808311612d0357829003601f168201915b50505050509050919050565b6019546001600160a01b031615612dae5760195460405163c87b56dd60e01b8152600481018490526001600160a01b039091169063c87b56dd90602401600060405180830381865afa158015612d86573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110659190810190615cfd565b601b612db983613cf1565b601c604051602001612dcd93929190615de6565b6040516020818303038152906040529050919050565b612deb613088565b601c61107d8282615c27565b612dff613088565b601f80546001600160a01b0319166001600160a01b0392909216919091179055565b612e29613088565b602355565b81612e38816131df565b6000818152600c602052604090205460ff1615612e675760405162461bcd60e51b815260040161118290615abe565b602b546001600160a01b0316336001600160a01b031614612eba5760405162461bcd60e51b815260206004820152600d60248201526c1058d8d95cdcc819195b9a5959609a1b6044820152606401611182565b602c546001600160a01b031615612ed557612ed58383613d83565b612ede83613dd4565b60405183907ff4a991ad9e7f9711696f7bd41529beb4c470d75788573535d4ca3f0857c79ce890600090a2505050565b6112ad816000613407565b6019546060906001600160a01b031615612fa857601960009054906101000a90046001600160a01b03166001600160a01b031663e8a3d4856040518163ffffffff1660e01b8152600401600060405180830381865afa158015612f80573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115999190810190615cfd565b601a8054611090906159fa565b612fbd613088565b6022805460ff1916911515919091179055565b612fd8613088565b601e61107d8282615c27565b612fec613088565b6001600160a01b0381166130515760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401611182565b6112ad81613a9a565b80546001019055565b60006001600160e01b0319821663152a902d60e11b1480611065575061106582613e81565b6015546001600160a01b031633146125955760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401611182565b6127106001600160601b03821611156131505760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401611182565b6001600160a01b0382166131a65760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401611182565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600e55565b6000818152600260205260409020546001600160a01b03166112ad5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401611182565b6daaeb6d7670e522a718067333cd4e3b156112ad57604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa1580156132ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132cf9190615e19565b6112ad57604051633b79c77360e21b81526001600160a01b0382166004820152602401611182565b6000613302826122a4565b9050806001600160a01b0316836001600160a01b03160361336f5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401611182565b336001600160a01b038216148061338b575061338b8133610f85565b6133fd5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401611182565b61114e8383613e8c565b600a5460ff1661342a5760405163690837d160e01b815260040160405180910390fd5b60005b825181101561359657600083828151811061344a5761344a615aa8565b6020026020010151905060008260016134639190615b36565b90505b84518110156134ba5784818151811061348157613481615aa8565b602002602001015182036134a8576040516315e8d02d60e11b815260040160405180910390fd5b806134b281615a8f565b915050613466565b50336134c5826122a4565b6001600160a01b0316146134ec576040516359dc379f60e01b815260040160405180910390fd5b6000818152600c602052604090205460ff1615158315151461356a57821561353e5760405181907feebbaa86c348cb664e392b180fd0ff2e1998af9fa833ef69a778cb0b42d3ca2790600090a261356a565b60405181907f11725367022c3ff288940f4b5473aa61c2da6a24af7363a1128ee2401e8983b290600090a25b6000908152600c60205260409020805460ff19168315151790558061358e81615a8f565b91505061342d565b506135a033611314565b336000818152600d6020526040908190208390555190917fb6bf628e496a24dda97f35748d8f57d01cd1a7c5558d35b07b6314c003c10161916135e591815260200190565b60405180910390a25050565b6135fc335b82613efa565b6136185760405162461bcd60e51b815260040161118290615e36565b61114e838383613f78565b6002601454036136755760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611182565b6002601455565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146136c9576040519150601f19603f3d011682016040523d82523d6000602084013e6136ce565b606091505b505090508061114e5760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b6044820152606401611182565b61107d8282604051806020016040528060008152506140f1565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561378857507f000000000000000000000000000000000000000000000000000000000000000046145b156137b257507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b60004382106138a75760405162461bcd60e51b815260206004820181905260248201527f436865636b706f696e74733a20626c6f636b206e6f7420796574206d696e65646044820152606401611182565b60006138b283614124565b845490915060008160058111156139105760006138ce8461418d565b6138d89085615bce565b60008981526020902090915081015463ffffffff90811690861610156139005780915061390e565b61390b816001615b36565b92505b505b600061391e88868585614275565b9050801561395a5761394388613935600184615bce565b600091825260209091200190565b5464010000000090046001600160e01b031661395d565b60005b6001600160e01b031698975050505050505050565b600081831161398157816115c0565b5090919050565b61114e83838360405180602001604052806000815250612acb565b6139ac336135f6565b6139c85760405162461bcd60e51b815260040161118290615e36565b6112ad81613dd4565b6040516bffffffffffffffffffffffff19606084901b166020820152603481018290526000906054015b60405160208183030381529060405280519060200120905092915050565b60006115c082602354856142cb565b6001600160a01b0382811660008181526010602052604080822080548686166001600160a01b0319821681179092559151919094169392849290917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a461114e8183613a95866142e1565b6142ec565b601580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006115c082602054856142cb565b80546000908015611fba57613b1583613935600184615bce565b5464010000000090046001600160e01b03169392505050565b61107d338383614429565b600a5460ff1615613b5d5760405163690837d160e01b815260040160405180910390fd5b60005b815181101561114e576000613b758285615b36565b90506000838381518110613b8b57613b8b615aa8565b602091018101516000848152600b835260409081902054815160ff909116815260f89290921c92820183905291925083917f3df5b49ff0002b561a78cc6d2628cc6cca4781ad27ae87199b341d668b9a14f3910160405180910390a26000918252600b6020526040909120805460ff191660ff90921691909117905580613c1181615a8f565b915050613b60565b604051600181527f594169f67d23ab550f7dcb2303817abb33cbf95bc48ce5467c4d54661901d80c9060200160405180910390a1600a805460ff19166001179055565b613c663383613efa565b613c825760405162461bcd60e51b815260040161118290615e36565b611f22848484846144f7565b6000611065613c9b61372f565b8361452a565b6000806000613cb287878787614551565b91509150613cbf81614615565b5095945050505050565b6001600160a01b03811660009081526013602052604090208054600181018255905b50919050565b60606000613cfe8361475f565b60010190506000816001600160401b03811115613d1d57613d1d61555e565b6040519080825280601f01601f191660200182016040528015613d47576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084613d5157509392505050565b600082815260026020526040902054602c546001600160a01b039182169116613dad848385614837565b6001600160a01b03161461114e5760405163ea8e4eb560e01b815260040160405180910390fd5b6000613ddf826122a4565b9050613def81600084600161489c565b613df8826122a4565b600083815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526003845282852080546000190190558785526002909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a461107d8160008460016148a8565b6000611065826148b4565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190613ec1826122a4565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080613f06836122a4565b9050806001600160a01b0316846001600160a01b03161480613f4d57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80611a955750836001600160a01b0316613f6684611113565b6001600160a01b031614949350505050565b826001600160a01b0316613f8b826122a4565b6001600160a01b031614613fb15760405162461bcd60e51b815260040161118290615e83565b6001600160a01b0382166140135760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401611182565b614020838383600161489c565b826001600160a01b0316614033826122a4565b6001600160a01b0316146140595760405162461bcd60e51b815260040161118290615e83565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a461114e83838360016148a8565b6140fb83836148d9565b6141086000848484614a7c565b61114e5760405162461bcd60e51b815260040161118290615ec8565b600063ffffffff8211156141895760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b6064820152608401611182565b5090565b60008160000361419f57506000919050565b600060016141ac84614b7a565b901c6001901b905060018184816141c5576141c5615afe565b048201901c905060018184816141dd576141dd615afe565b048201901c905060018184816141f5576141f5615afe565b048201901c9050600181848161420d5761420d615afe565b048201901c9050600181848161422557614225615afe565b048201901c9050600181848161423d5761423d615afe565b048201901c9050600181848161425557614255615afe565b048201901c90506115c08182858161426f5761426f615afe565b04614c0e565b60005b8183101561268b57600061428c8484614c1d565b60008781526020902090915063ffffffff86169082015463ffffffff1611156142b7578092506142c5565b6142c2816001615b36565b93505b50614278565b6000826142d88584614c38565b14949350505050565b6000611065826124fd565b816001600160a01b0316836001600160a01b03161415801561430e5750600081115b1561114e576001600160a01b0383161561439c576001600160a01b0383166000908152601160205260408120819061434990614c7d85614c89565b91509150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051614391929190918252602082015260400190565b60405180910390a250505b6001600160a01b0382161561114e576001600160a01b038216600090815260116020526040812081906143d290614cc185614c89565b91509150836001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405161441a929190918252602082015260400190565b60405180910390a25050505050565b816001600160a01b0316836001600160a01b03160361448a5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401611182565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b614502848484613f78565b61450e84848484614a7c565b611f225760405162461bcd60e51b815260040161118290615ec8565b60405161190160f01b602082015260228101839052604281018290526000906062016139fb565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115614588575060009050600361460c565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156145dc573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166146055760006001925092505061460c565b9150600090505b94509492505050565b600081600481111561462957614629615f1a565b036146315750565b600181600481111561464557614645615f1a565b036146925760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401611182565b60028160048111156146a6576146a6615f1a565b036146f35760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401611182565b600381600481111561470757614707615f1a565b036112ad5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401611182565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b831061479e5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106147ca576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106147e857662386f26fc10000830492506010015b6305f5e1008310614800576305f5e100830492506008015b612710831061481457612710830492506004015b60648310614826576064830492506002015b600a83106110655760010192915050565b604080517f000000000000000000000000000000000000000000000000000000000000000060208201529081018490526001600160a01b0383166060820152600090611a95906080016040516020818303038152906040528051906020012083614ccd565b611f2284848484614ce9565b611f2284848484614cf5565b60006001600160e01b0319821663780e9d6360e01b1480611065575061106582614d05565b6001600160a01b03821661492f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401611182565b6000818152600260205260409020546001600160a01b0316156149945760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401611182565b6149a260008383600161489c565b6000818152600260205260409020546001600160a01b031615614a075760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401611182565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a461107d6000838360016148a8565b60006001600160a01b0384163b15614b7257604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614ac0903390899088908890600401615f30565b6020604051808303816000875af1925050508015614afb575060408051601f3d908101601f19168201909252614af891810190615f6d565b60015b614b58573d808015614b29576040519150601f19603f3d011682016040523d82523d6000602084013e614b2e565b606091505b508051600003614b505760405162461bcd60e51b815260040161118290615ec8565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611a95565b506001611a95565b600080608083901c15614b8f57608092831c92015b604083901c15614ba157604092831c92015b602083901c15614bb357602092831c92015b601083901c15614bc557601092831c92015b600883901c15614bd757600892831c92015b600483901c15614be957600492831c92015b600283901c15614bfb57600292831c92015b600183901c156110655760010192915050565b600081831061398157816115c0565b6000614c2c6002848418615b14565b6115c090848416615b36565b600081815b845181101561268b57614c6982868381518110614c5c57614c5c615aa8565b6020026020010151614d55565b915080614c7581615a8f565b915050614c3d565b60006115c08284615bce565b600080614cb485614caf614c9c88613afb565b6001600160e01b0316868863ffffffff16565b614d84565b915091505b935093915050565b60006115c08284615b36565b6000806000614cdc8585614db8565b9150915061268b81614615565b611f2284848484614dfa565b614d00848483614f33565b611f22565b60006001600160e01b031982166380ac58cd60e01b1480614d3657506001600160e01b03198216635b5e139f60e01b145b8061106557506301ffc9a760e01b6001600160e01b0319831614611065565b6000818310614d715760008281526020849052604090206115c0565b60008381526020839052604090206115c0565b600080614da284614d9443614124565b614d9d86614fa3565b61500c565b6001600160e01b03918216969116945092505050565b6000808251604103614dee5760208301516040840151606085015160001a614de287828585614551565b9450945050505061142e565b5060009050600261142e565b614e06848484846151af565b6001811115614e755760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401611182565b816001600160a01b038516614ed157614ecc81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b614ef4565b836001600160a01b0316856001600160a01b031614614ef457614ef48582615237565b6001600160a01b038416614f1057614f0b816152d4565b611380565b846001600160a01b0316846001600160a01b031614611380576113808482615383565b6001600160a01b038316614f5257614f4f6012614cc183614c89565b50505b6001600160a01b038216614f7157614f6e6012614c7d83614c89565b50505b6001600160a01b0383811660009081526010602052604080822054858416835291205461114e929182169116836142ec565b60006001600160e01b038211156141895760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b6064820152608401611182565b82546000908190801561515557600061502a87613935600185615bce565b60408051808201909152905463ffffffff8082168084526401000000009092046001600160e01b0316602084015291925090871610156150ac5760405162461bcd60e51b815260206004820152601760248201527f436865636b706f696e743a20696e76616c6964206b65790000000000000000006044820152606401611182565b805163ffffffff8088169116036150f557846150cd88613935600186615bce565b80546001600160e01b03929092166401000000000263ffffffff909216919091179055615145565b6040805180820190915263ffffffff80881682526001600160e01b0380881660208085019182528b54600181018d5560008d81529190912094519151909216640100000000029216919091179101555b602001519250839150614cb99050565b50506040805180820190915263ffffffff80851682526001600160e01b0380851660208085019182528854600181018a5560008a815291822095519251909316640100000000029190931617920191909155905081614cb9565b6001811115611f22576001600160a01b038416156151f5576001600160a01b038416600090815260036020526040812080548392906151ef908490615bce565b90915550505b6001600160a01b03831615611f22576001600160a01b0383166000908152600360205260408120805483929061522c908490615b36565b909155505050505050565b60006001615244846124fd565b61524e9190615bce565b6000838152600760205260409020549091508082146152a1576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906152e690600190615bce565b6000838152600960205260408120546008805493945090928490811061530e5761530e615aa8565b90600052602060002001549050806008838154811061532f5761532f615aa8565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061536757615367615f8a565b6001900381819060005260206000200160009055905550505050565b600061538e836124fd565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160e01b0319811681146112ad57600080fd5b6000602082840312156153ef57600080fd5b81356115c0816153c7565b80356001600160a01b038116811461541157600080fd5b919050565b6000806040838503121561542957600080fd5b615432836153fa565b915060208301356001600160601b038116811461544e57600080fd5b809150509250929050565b60005b8381101561547457818101518382015260200161545c565b50506000910152565b60008151808452615495816020860160208601615459565b601f01601f19169290920160200192915050565b6020815260006115c0602083018461547d565b6000602082840312156154ce57600080fd5b5035919050565b600080604083850312156154e857600080fd5b6154f1836153fa565b946020939093013593505050565b60006020828403121561551157600080fd5b6115c0826153fa565b6020808252825182820181905260009190848201906040850190845b8181101561555257835183529284019291840191600101615536565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561559c5761559c61555e565b604052919050565b600060208083850312156155b757600080fd5b82356001600160401b03808211156155ce57600080fd5b818501915085601f8301126155e257600080fd5b8135818111156155f4576155f461555e565b8060051b9150615605848301615574565b818152918301840191848101908884111561561f57600080fd5b938501935b8385101561563d57843582529385019390850190615624565b98975050505050505050565b60008060006060848603121561565e57600080fd5b615667846153fa565b9250615675602085016153fa565b9150604084013590509250925092565b6000806040838503121561569857600080fd5b50508035926020909101359150565b60008083601f8401126156b957600080fd5b5081356001600160401b038111156156d057600080fd5b6020830191508360208260051b850101111561142e57600080fd5b6000806000806060858703121561570157600080fd5b61570a856153fa565b93506020850135925060408501356001600160401b0381111561572c57600080fd5b615738878288016156a7565b95989497509550505050565b80151581146112ad57600080fd5b60006020828403121561576457600080fd5b81356115c081615744565b60006001600160401b038211156157885761578861555e565b50601f01601f191660200190565b60006157a96157a48461576f565b615574565b90508281528383830111156157bd57600080fd5b828260208301376000602084830101529392505050565b6000602082840312156157e657600080fd5b81356001600160401b038111156157fc57600080fd5b8201601f8101841361580d57600080fd5b611a9584823560208401615796565b60008060006040848603121561583157600080fd5b61583a846153fa565b925060208401356001600160401b0381111561585557600080fd5b615861868287016156a7565b9497909650939450505050565b6000806040838503121561588157600080fd5b61588a836153fa565b9150602083013561544e81615744565b600082601f8301126158ab57600080fd5b6115c083833560208501615796565b600080604083850312156158cd57600080fd5b8235915060208301356001600160401b038111156158ea57600080fd5b6158f68582860161589a565b9150509250929050565b6000806000806080858703121561591657600080fd5b61591f856153fa565b935061592d602086016153fa565b92506040850135915060608501356001600160401b0381111561594f57600080fd5b61595b8782880161589a565b91505092959194509250565b60008060008060008060c0878903121561598057600080fd5b615989876153fa565b95506020870135945060408701359350606087013560ff811681146159ad57600080fd5b9598949750929560808101359460a0909101359350915050565b600080604083850312156159da57600080fd5b6159e3836153fa565b91506159f1602084016153fa565b90509250929050565b600181811c90821680615a0e57607f821691505b602082108103613ceb57634e487b7160e01b600052602260045260246000fd5b6020808252602b908201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560408201526a74206f6620626f756e647360a81b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600060018201615aa157615aa1615a79565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6020808252600f908201526e151bdad95b881a5cc81cdd185ad959608a1b604082015260600190565b808202811582820484141761106557611065615a79565b634e487b7160e01b600052601260045260246000fd5b600082615b3157634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561106557611065615a79565b6020808252600a90820152694d41585f535550504c5960b01b604082015260600190565b60ff818116838216019081111561106557611065615a79565b60208082526028908201527f4d65726b6c654469737472696275746f723a20496e76616c696420206d65726b604082015267363290383937b7b360c11b606082015260800190565b8181038181111561106557611065615a79565b601f82111561114e57600081815260208120601f850160051c81016020861015615c085750805b601f850160051c820191505b81811015612b2a57828155600101615c14565b81516001600160401b03811115615c4057615c4061555e565b615c5481615c4e84546159fa565b84615be1565b602080601f831160018114615c895760008415615c715750858301515b600019600386901b1c1916600185901b178555612b2a565b600085815260208120601f198616915b82811015615cb857888601518255948401946001909101908401615c99565b5085821015615cd65787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600081615cf557615cf5615a79565b506000190190565b600060208284031215615d0f57600080fd5b81516001600160401b03811115615d2557600080fd5b8201601f81018413615d3657600080fd5b8051615d446157a48261576f565b818152856020838501011115615d5957600080fd5b615d6a826020830160208601615459565b95945050505050565b60008154615d80816159fa565b60018281168015615d985760018114615dad57615ddc565b60ff1984168752821515830287019450615ddc565b8560005260208060002060005b85811015615dd35781548a820152908401908201615dba565b50505082870194505b5050505092915050565b6000615df28286615d73565b8451615e02818360208901615459565b615e0e81830186615d73565b979650505050505050565b600060208284031215615e2b57600080fd5b81516115c081615744565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090615f639083018461547d565b9695505050505050565b600060208284031215615f7f57600080fd5b81516115c0816153c7565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220ca421b430dd0f8dd7ff1a35859e4ff18fd71b913e5554e89c783c10312ccfa7764736f6c6343000811003368747470733a2f2f63617368727573682e67672f6d657461646174612f636f6e74726163742e6a736f6e68747470733a2f2f63617368727573682e67672f6d657461646174612f756e72657665616c65642e6a736f6e

Deployed Bytecode

0x6080604052600436106104c45760003560e01c806370a0823111610276578063be4699201161014f578063e64710e6116100c1578063e985e9c511610085578063e985e9c514610f6a578063eafb452314610fb3578063f2c4ce1e14610fd3578063f2fde38b14610ff3578063f301af4214611013578063f57145321461104057600080fd5b8063e64710e614610ebd578063e6c3b1f614610ed3578063e80e2a9f14610f15578063e8a3d48514610f35578063e97382bd14610f4a57600080fd5b8063da3ef23f11610113578063da3ef23f14610e07578063db065b1d14610e27578063deaa59df14610e3d578063e0dd8cb814610e5d578063e28f6cb914610e7d578063e449f34114610e9d57600080fd5b8063be46992014610d7b578063c3cda52014610d9b578063c87b56dd14610dbb578063ca34adf014610ddb578063d778c91114610df157600080fd5b80639a8a0592116101e8578063a475b5dd116101ac578063a475b5dd14610ccc578063aa1b103f14610ce1578063ae97166d14610cf6578063b05374d514610d16578063b88d4fde14610d2b578063baa51f8614610d4b57600080fd5b80639a8a059214610c0b5780639ab24eb014610c3f578063a144819414610c5f578063a22cb46514610c7f578063a2fc01ae14610c9f57600080fd5b80638c20aff61161023a5780638c20aff614610b585780638da5cb5b14610b785780638e539e8c14610b96578063938e3d7b14610bb6578063946b593114610bd657806395d89b4114610bf657600080fd5b806370a0823114610ac3578063715018a614610ae35780637ecebe0014610af85780637f81be6914610b185780638462151c14610b3857600080fd5b80633a46b1a8116103a85780634f6ccce71161031a5780635aac546d116102de5780635aac546d14610a095780635c19a95c14610a235780636352211e14610a435780636566765214610a635780636ba4c13814610a835780636f4f736614610aa357600080fd5b80634f6ccce71461095057806351c4998e14610970578063521eb2731461099057806355f804b3146109b0578063587cde1e146109d057600080fd5b806342966c681161036c57806342966c681461089057806345f02525146108b05780634b11faaf146108dd5780634b2e654c146108f05780634c2ebff6146109105780634d65b0351461093057600080fd5b80633a46b1a8146107ee5780633ab3d4f61461080e57806340a194361461082e57806341f434341461084e57806342842e0e1461087057600080fd5b80631af7c4e1116104415780632a55205a116104055780632a55205a1461070d5780632db115441461074c5780632f745c591461075f578063339480c81461077f5780633644e515146107ac57806339211e58146107c157600080fd5b80631af7c4e114610676578063222f91ee14610696578063232da117146106b757806323b872dd146106d757806327a3181d146106f757600080fd5b80630d65a6b2116104885780630d65a6b2146105d65780630e15561a146105f05780630f3bd2f6146106145780630fbf0a931461064157806318160ddd1461066157600080fd5b806301ffc9a71461050557806304634d8d1461053a57806306fdde031461055c578063081812fc1461057e578063095ea7b3146105b657600080fd5b366105005760405134815233907f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f885258749060200160405180910390a2005b600080fd5b34801561051157600080fd5b506105256105203660046153dd565b61105a565b60405190151581526020015b60405180910390f35b34801561054657600080fd5b5061055a610555366004615416565b61106b565b005b34801561056857600080fd5b50610571611081565b60405161053191906154a9565b34801561058a57600080fd5b5061059e6105993660046154bc565b611113565b6040516001600160a01b039091168152602001610531565b3480156105c257600080fd5b5061055a6105d13660046154d5565b61113a565b3480156105e257600080fd5b50600a546105259060ff1681565b3480156105fc57600080fd5b5061060660285481565b604051908152602001610531565b34801561062057600080fd5b5061063461062f3660046154ff565b611153565b604051610531919061551a565b34801561064d57600080fd5b5061055a61065c3660046155a4565b6112a2565b34801561066d57600080fd5b50600854610606565b34801561068257600080fd5b5061055a6106913660046154ff565b6112b0565b3480156106a257600080fd5b50601f5461052590600160a01b900460ff1681565b3480156106c357600080fd5b506106066106d23660046154ff565b611314565b3480156106e357600080fd5b5061055a6106f2366004615649565b611322565b34801561070357600080fd5b5061060660255481565b34801561071957600080fd5b5061072d610728366004615685565b611387565b604080516001600160a01b039093168352602083019190915201610531565b61055a61075a3660046154bc565b611435565b34801561076b57600080fd5b5061060661077a3660046154d5565b61153d565b34801561078b57600080fd5b5061060661079a3660046154ff565b600d6020526000908152604090205481565b3480156107b857600080fd5b5061060661158f565b3480156107cd57600080fd5b506106066107dc3660046154ff565b60216020526000908152604090205481565b3480156107fa57600080fd5b506106066108093660046154d5565b61159e565b34801561081a57600080fd5b50602b5461059e906001600160a01b031681565b34801561083a57600080fd5b506106066108493660046155a4565b6115c7565b34801561085a57600080fd5b5061059e6daaeb6d7670e522a718067333cd4e81565b34801561087c57600080fd5b5061055a61088b366004615649565b611ca2565b34801561089c57600080fd5b5061055a6108ab3660046154bc565b611d00565b3480156108bc57600080fd5b506106066108cb3660046154ff565b60246020526000908152604090205481565b61055a6108eb3660046156eb565b611d42565b3480156108fc57600080fd5b5061060661090b3660046154bc565b611f28565b34801561091c57600080fd5b5061055a61092b366004615752565b611fc3565b34801561093c57600080fd5b5061055a61094b3660046155a4565b611fde565b34801561095c57600080fd5b5061060661096b3660046154bc565b6121e5565b34801561097c57600080fd5b5061055a61098b3660046154bc565b612278565b34801561099c57600080fd5b50601f5461059e906001600160a01b031681565b3480156109bc57600080fd5b5061055a6109cb3660046157d4565b612285565b3480156109dc57600080fd5b5061059e6109eb3660046154ff565b6001600160a01b039081166000908152601060205260409020541690565b348015610a1557600080fd5b506026546105259060ff1681565b348015610a2f57600080fd5b5061055a610a3e3660046154ff565b612299565b348015610a4f57600080fd5b5061059e610a5e3660046154bc565b6122a4565b348015610a6f57600080fd5b5061055a610a7e3660046154ff565b612304565b348015610a8f57600080fd5b5061055a610a9e3660046155a4565b612368565b348015610aaf57600080fd5b5061055a610abe3660046154ff565b6124d3565b348015610acf57600080fd5b50610606610ade3660046154ff565b6124fd565b348015610aef57600080fd5b5061055a612583565b348015610b0457600080fd5b50610606610b133660046154ff565b612597565b348015610b2457600080fd5b5061059e610b333660046154bc565b6125b5565b348015610b4457600080fd5b50610634610b533660046154ff565b6125d2565b348015610b6457600080fd5b5061055a610b7336600461581c565b612693565b348015610b8457600080fd5b506015546001600160a01b031661059e565b348015610ba257600080fd5b50610606610bb13660046154bc565b6127f1565b348015610bc257600080fd5b5061055a610bd13660046157d4565b61284d565b348015610be257600080fd5b50610606610bf13660046155a4565b612861565b348015610c0257600080fd5b50610571612982565b348015610c1757600080fd5b506106067f000000000000000000000000000000000000000000000000000000000000000181565b348015610c4b57600080fd5b50610606610c5a3660046154ff565b612991565b348015610c6b57600080fd5b5061055a610c7a3660046154d5565b6129c1565b348015610c8b57600080fd5b5061055a610c9a36600461586e565b612a6c565b348015610cab57600080fd5b50610606610cba3660046154bc565b602a6020526000908152604090205481565b348015610cd857600080fd5b5061055a612a80565b348015610ced57600080fd5b5061055a612a97565b348015610d0257600080fd5b5061055a610d113660046158ba565b612aa9565b348015610d2257600080fd5b5061055a612abb565b348015610d3757600080fd5b5061055a610d46366004615900565b612acb565b348015610d5757600080fd5b50610525610d663660046154bc565b600c6020526000908152604090205460ff1681565b348015610d8757600080fd5b5061055a610d96366004615752565b612b32565b348015610da757600080fd5b5061055a610db6366004615967565b612b58565b348015610dc757600080fd5b50610571610dd63660046154bc565b612c85565b348015610de757600080fd5b5061060660235481565b348015610dfd57600080fd5b5061060660275481565b348015610e1357600080fd5b5061055a610e223660046157d4565b612de3565b348015610e3357600080fd5b5061060660165481565b348015610e4957600080fd5b5061055a610e583660046154ff565b612df7565b348015610e6957600080fd5b5061055a610e783660046154bc565b612e21565b348015610e8957600080fd5b5061055a610e983660046158ba565b612e2e565b348015610ea957600080fd5b5061055a610eb83660046155a4565b612f0e565b348015610ec957600080fd5b5061060660205481565b348015610edf57600080fd5b50610f03610eee3660046154bc565b600b6020526000908152604090205460ff1681565b60405160ff9091168152602001610531565b348015610f2157600080fd5b50602c5461059e906001600160a01b031681565b348015610f4157600080fd5b50610571612f19565b348015610f5657600080fd5b5060195461059e906001600160a01b031681565b348015610f7657600080fd5b50610525610f853660046159c7565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610fbf57600080fd5b5061055a610fce366004615752565b612fb5565b348015610fdf57600080fd5b5061055a610fee3660046157d4565b612fd0565b348015610fff57600080fd5b5061055a61100e3660046154ff565b612fe4565b34801561101f57600080fd5b5061060661102e3660046154bc565b60296020526000908152604090205481565b34801561104c57600080fd5b506022546105259060ff1681565b600061106582613063565b92915050565b611073613088565b61107d82826130e2565b5050565b606060008054611090906159fa565b80601f01602080910402602001604051908101604052809291908181526020018280546110bc906159fa565b80156111095780601f106110de57610100808354040283529160200191611109565b820191906000526020600020905b8154815290600101906020018083116110ec57829003601f168201915b5050505050905090565b600061111e826131df565b506000908152600460205260409020546001600160a01b031690565b816111448161323e565b61114e83836132f7565b505050565b60606000611160836124fd565b90508060001061118b5760405162461bcd60e51b815260040161118290615a2e565b60405180910390fd5b6000805b828110156111de57600c60006111a5878461153d565b815260208101919091526040016000205460ff16156111cc57816111c881615a8f565b9250505b806111d681615a8f565b91505061118f565b506000816001600160401b038111156111f9576111f961555e565b604051908082528060200260200182016040528015611222578160200160208202803683370190505b5090506000915060005b83811015611299576000611240878361153d565b6000818152600c602052604090205490915060ff1615611286578083858151811061126d5761126d615aa8565b60209081029190910101528361128281615a8f565b9450505b508061129181615a8f565b91505061122c565b50949350505050565b6112ad816001613407565b50565b6112b8613088565b602b546040516001600160a01b038084169216907fffc9d6771ac85ad61d4a37cd4654daecd7906cd92b449f80e0d9f740a19ccf6790600090a3602b80546001600160a01b0319166001600160a01b0392909216919091179055565b600061106561084983611153565b8061132c816131df565b6000818152600c602052604090205460ff161561135b5760405162461bcd60e51b815260040161118290615abe565b836001600160a01b0381163314611375576113753361323e565b6113808585856135f1565b5050505050565b6000828152600f602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925282916113fc575060408051808201909152600e546001600160a01b0381168252600160a01b90046001600160601b031660208201525b60208101516000906127109061141b906001600160601b031687615ae7565b6114259190615b14565b91519350909150505b9250929050565b61143d613623565b60265460ff166114605760405163914edb0f60e01b815260040160405180910390fd5b610fa08161146d60085490565b6114779190615b36565b11156114955760405162461bcd60e51b815260040161118290615b49565b6027546114a29082615ae7565b34146114c157604051636956f2ab60e11b815260040160405180910390fd5b601f546114d7906001600160a01b03163461367c565b80601760008282546114e99190615b36565b90915550600090505b8181101561153257600061150560185490565b9050611515601880546001019055565b61151f3382613715565b508061152a81615a8f565b9150506114f2565b506112ad6001601455565b6000611548836124fd565b82106115665760405162461bcd60e51b815260040161118290615a2e565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600061159961372f565b905090565b6001600160a01b03821660009081526011602052604081206115c09083613856565b9392505050565b600080806115d7600e6001615b6d565b60ff166001600160401b038111156115f1576115f161555e565b60405190808252806020026020018201604052801561161a578160200160208202803683370190505b50905060005b84518110156116b157600085828151811061163d5761163d615aa8565b60200260200101519050600061165282611f28565b6000838152600b6020526040902054855191925060ff169060019086908390811061167f5761167f615aa8565b911515602092830291909101909101526116998287613972565b955050505080806116a990615a8f565b915050611620565b50806001815181106116c5576116c5615aa8565b602002602001015180156116f05750806002815181106116e7576116e7615aa8565b60200260200101515b801561171357508060038151811061170a5761170a615aa8565b60200260200101515b801561173657508060048151811061172d5761172d615aa8565b60200260200101515b801561175957508060058151811061175057611750615aa8565b60200260200101515b801561177c57508060068151811061177357611773615aa8565b60200260200101515b801561179f57508060078151811061179657611796615aa8565b60200260200101515b80156117c25750806008815181106117b9576117b9615aa8565b60200260200101515b80156117e55750806009815181106117dc576117dc615aa8565b60200260200101515b8015611808575080600a815181106117ff576117ff615aa8565b60200260200101515b801561182b575080600b8151811061182257611822615aa8565b60200260200101515b801561184e575080600c8151811061184557611845615aa8565b60200260200101515b8015611871575080600d8151811061186857611868615aa8565b60200260200101515b8015611894575080600e8151811061188b5761188b615aa8565b60200260200101515b156118a3575060649392505050565b806001815181106118b6576118b6615aa8565b602002602001015180156118e15750806002815181106118d8576118d8615aa8565b60200260200101515b156118f05750601e9392505050565b8060018151811061190357611903615aa8565b6020026020010151801561192e57508060058151811061192557611925615aa8565b60200260200101515b1561193d5750601e9392505050565b8060018151811061195057611950615aa8565b6020026020010151801561197b575080600a8151811061197257611972615aa8565b60200260200101515b1561198a575060199392505050565b8060038151811061199d5761199d615aa8565b602002602001015180156119c85750806005815181106119bf576119bf615aa8565b60200260200101515b156119d7575060149392505050565b806003815181106119ea576119ea615aa8565b60200260200101518015611a15575080600481518110611a0c57611a0c615aa8565b60200260200101515b8015611a38575080600581518110611a2f57611a2f615aa8565b60200260200101515b15611a47575060149392505050565b80600481518110611a5a57611a5a615aa8565b60200260200101518015611a85575080600a81518110611a7c57611a7c615aa8565b60200260200101515b15611a9d57611a95600f83613972565b949350505050565b80600581518110611ab057611ab0615aa8565b602002602001015115611b0a5780600881518110611ad057611ad0615aa8565b602002602001015180611afa575080600b81518110611af157611af1615aa8565b60200260200101515b15611b0a57611a95600f83613972565b80600681518110611b1d57611b1d615aa8565b60200260200101518015611b48575080600781518110611b3f57611b3f615aa8565b60200260200101515b8015611b6b575080600881518110611b6257611b62615aa8565b60200260200101515b8015611b8e575080600981518110611b8557611b85615aa8565b60200260200101515b8015611bb1575080600a81518110611ba857611ba8615aa8565b60200260200101515b8015611bd4575080600b81518110611bcb57611bcb615aa8565b60200260200101515b8015611bf7575080600c81518110611bee57611bee615aa8565b60200260200101515b8015611c1a575080600d81518110611c1157611c11615aa8565b60200260200101515b8015611c3d575080600e81518110611c3457611c34615aa8565b60200260200101515b15611c4d57611a95600f83613972565b80600981518110611c6057611c60615aa8565b60200260200101518015611c8b575080600c81518110611c8257611c82615aa8565b60200260200101515b15611c9b57611a95600a83613972565b5092915050565b80611cac816131df565b6000818152600c602052604090205460ff1615611cdb5760405162461bcd60e51b815260040161118290615abe565b836001600160a01b0381163314611cf557611cf53361323e565b611380858585613988565b80611d0a816131df565b6000818152600c602052604090205460ff1615611d395760405162461bcd60e51b815260040161118290615abe565b61107d826139a3565b611d4a613623565b60225460ff16611d6d5760405163914edb0f60e01b815260040160405180910390fd5b6001600160a01b038416600090815260246020526040902054600590611d94908590615b36565b1115611db35760405163ec8e6a6360e01b815260040160405180910390fd5b611dfa611dc18560016139d1565b838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613a1992505050565b611e165760405162461bcd60e51b815260040161118290615b86565b610fa083611e2360085490565b611e2d9190615b36565b1115611e4b5760405162461bcd60e51b815260040161118290615b49565b602554611e589084615ae7565b3414611e7757604051636956f2ab60e11b815260040160405180910390fd5b601f54611e8d906001600160a01b03163461367c565b6001600160a01b03841660009081526024602052604081208054859290611eb5908490615b36565b925050819055508260176000828254611ece9190615b36565b90915550600090505b83811015611f17576000611eea60185490565b9050611efa601880546001019055565b611f048682613715565b5080611f0f81615a8f565b915050611ed7565b50611f226001601455565b50505050565b6000818152600b602052604081205460ff1680611f485750600092915050565b600160ff821610801590611f605750600260ff821611155b15611f6e5750601492915050565b600360ff821610801590611f865750600560ff821611155b15611f945750600a92915050565b600660ff821610801590611fac5750600e60ff821611155b15611fba5750600592915050565b50600092915050565b611fcb613088565b6026805460ff1916911515919091179055565b611fe6613623565b611fee613088565b6000601754476028546120019190615b36565b61200b9190615b14565b90506000805b83518110156121b057600084828151811061202e5761202e615aa8565b602002602001015190506001811080612048575060175481115b1561206657604051634e23d03560e01b815260040160405180910390fd5b6000612073836001615b36565b90505b85518110156120ca5785818151811061209157612091615aa8565b602002602001015182036120b8576040516315e8d02d60e11b815260040160405180910390fd5b806120c281615a8f565b915050612076565b50426120da62015180605a615ae7565b6000838152602a60205260409020546120f39190615b36565b111561212f5760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b6044820152606401611182565b6000818152602960205260409020548481101561219b5760006121528287615bce565b9050806029600085815260200190815260200160002060008282546121779190615b36565b90915550506000838152602a602052604090204290556121978186615b36565b9450505b505080806121a890615a8f565b915050612011565b5080156121d9576121c1338261367c565b80602860008282546121d39190615b36565b90915550505b50506112ad6001601455565b60006121f060085490565b82106122535760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401611182565b6008828154811061226657612266615aa8565b90600052602060002001549050919050565b612280613088565b602055565b61228d613088565b601b61107d8282615c27565b3361107d8183613a28565b6000818152600260205260408120546001600160a01b0316806110655760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401611182565b61230c613088565b602c546040516001600160a01b038084169216907fb39cf814d6b8fc86702226fc8ed660f3188afe02d4962e91396e1688cc54c7e090600090a3602c80546001600160a01b0319166001600160a01b0392909216919091179055565b612370613623565b6000601754476028546123839190615b36565b61238d9190615b14565b90506000805b83518110156121b05760008482815181106123b0576123b0615aa8565b6020026020010151905060008260016123c99190615b36565b90505b8551811015612420578581815181106123e7576123e7615aa8565b6020026020010151820361240e576040516315e8d02d60e11b815260040160405180910390fd5b8061241881615a8f565b9150506123cc565b503361242b826122a4565b6001600160a01b031614612452576040516359dc379f60e01b815260040160405180910390fd5b600081815260296020526040902054848110156124be5760006124758287615bce565b90508060296000858152602001908152602001600020600082825461249a9190615b36565b90915550506000838152602a602052604090204290556124ba8186615b36565b9450505b505080806124cb90615a8f565b915050612393565b6124db613088565b601980546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b0382166125675760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401611182565b506001600160a01b031660009081526003602052604090205490565b61258b613088565b6125956000613a9a565b565b6001600160a01b038116600090815260136020526040812054611065565b6000818152600260205260408120546001600160a01b0316611065565b606060006125df836124fd565b9050806000106126015760405162461bcd60e51b815260040161118290615a2e565b6000816001600160401b0381111561261b5761261b61555e565b604051908082528060200260200182016040528015612644578160200160208202803683370190505b50905060005b8281101561268b5761265c858261153d565b82828151811061266e5761266e615aa8565b60209081029190910101528061268381615a8f565b91505061264a565b509392505050565b61269b613623565b601f54600160a01b900460ff1615806126b45750601654155b156126d25760405163914edb0f60e01b815260040160405180910390fd5b6001600160a01b03831660009081526021602052604090205460011161270b5760405163ec8e6a6360e01b815260040160405180910390fd5b6127526127198460016139d1565b838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613aec92505050565b61276e5760405162461bcd60e51b815260040161118290615b86565b6016805490600061277e83615ce6565b90915550506001600160a01b03831660009081526021602052604081208054916127a783615a8f565b9091555050601780549060006127bc83615a8f565b919050555060006127cc60185490565b90506127dc601880546001019055565b6127e68482613715565b5061114e6001601455565b60004382106128425760405162461bcd60e51b815260206004820152601a60248201527f566f7465733a20626c6f636b206e6f7420796574206d696e65640000000000006044820152606401611182565b611065601283613856565b612855613088565b601a61107d8282615c27565b600080601754476028546128759190615b36565b61287f9190615b14565b90506000805b845181101561268b5760008582815181106128a2576128a2615aa8565b6020026020010151905060018110806128bc575060175481115b156128da57604051634e23d03560e01b815260040160405180910390fd5b60006128e7836001615b36565b90505b865181101561293e5786818151811061290557612905615aa8565b6020026020010151820361292c576040516315e8d02d60e11b815260040160405180910390fd5b8061293681615a8f565b9150506128ea565b506000818152602960205260409020548481101561296d576129608186615bce565b61296a9085615b36565b93505b5050808061297a90615a8f565b915050612885565b606060018054611090906159fa565b6001600160a01b03811660009081526011602052604081206129b290613afb565b6001600160e01b031692915050565b6129c9613623565b6129d1613088565b610fa0816129de60085490565b6129e89190615b36565b1115612a065760405162461bcd60e51b815260040161118290615b49565b8060176000828254612a189190615b36565b90915550600090505b81811015612a61576000612a3460185490565b9050612a44601880546001019055565b612a4e8482613715565b5080612a5981615a8f565b915050612a21565b5061107d6001601455565b81612a768161323e565b61114e8383613b2e565b612a88613088565b601d805460ff19166001179055565b612a9f613088565b6125956000600e55565b612ab1613088565b61107d8282613b39565b612ac3613088565b612595613c19565b81612ad5816131df565b6000818152600c602052604090205460ff1615612b045760405162461bcd60e51b815260040161118290615abe565b846001600160a01b0381163314612b1e57612b1e3361323e565b612b2a86868686613c5c565b505050505050565b612b3a613088565b601f8054911515600160a01b0260ff60a01b19909216919091179055565b83421115612ba85760405162461bcd60e51b815260206004820152601860248201527f566f7465733a207369676e6174757265206578706972656400000000000000006044820152606401611182565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b038816918101919091526060810186905260808101859052600090612c2290612c1a9060a00160405160208183030381529060405280519060200120613c8e565b858585613ca1565b9050612c2d81613cc9565b8614612c725760405162461bcd60e51b8152602060048201526014602482015273566f7465733a20696e76616c6964206e6f6e636560601b6044820152606401611182565b612c7c8188613a28565b50505050505050565b6060612c90826131df565b601d5460ff16612d2c57601e8054612ca7906159fa565b80601f0160208091040260200160405190810160405280929190818152602001828054612cd3906159fa565b8015612d205780601f10612cf557610100808354040283529160200191612d20565b820191906000526020600020905b815481529060010190602001808311612d0357829003601f168201915b50505050509050919050565b6019546001600160a01b031615612dae5760195460405163c87b56dd60e01b8152600481018490526001600160a01b039091169063c87b56dd90602401600060405180830381865afa158015612d86573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110659190810190615cfd565b601b612db983613cf1565b601c604051602001612dcd93929190615de6565b6040516020818303038152906040529050919050565b612deb613088565b601c61107d8282615c27565b612dff613088565b601f80546001600160a01b0319166001600160a01b0392909216919091179055565b612e29613088565b602355565b81612e38816131df565b6000818152600c602052604090205460ff1615612e675760405162461bcd60e51b815260040161118290615abe565b602b546001600160a01b0316336001600160a01b031614612eba5760405162461bcd60e51b815260206004820152600d60248201526c1058d8d95cdcc819195b9a5959609a1b6044820152606401611182565b602c546001600160a01b031615612ed557612ed58383613d83565b612ede83613dd4565b60405183907ff4a991ad9e7f9711696f7bd41529beb4c470d75788573535d4ca3f0857c79ce890600090a2505050565b6112ad816000613407565b6019546060906001600160a01b031615612fa857601960009054906101000a90046001600160a01b03166001600160a01b031663e8a3d4856040518163ffffffff1660e01b8152600401600060405180830381865afa158015612f80573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115999190810190615cfd565b601a8054611090906159fa565b612fbd613088565b6022805460ff1916911515919091179055565b612fd8613088565b601e61107d8282615c27565b612fec613088565b6001600160a01b0381166130515760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401611182565b6112ad81613a9a565b80546001019055565b60006001600160e01b0319821663152a902d60e11b1480611065575061106582613e81565b6015546001600160a01b031633146125955760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401611182565b6127106001600160601b03821611156131505760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401611182565b6001600160a01b0382166131a65760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401611182565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600e55565b6000818152600260205260409020546001600160a01b03166112ad5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401611182565b6daaeb6d7670e522a718067333cd4e3b156112ad57604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa1580156132ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132cf9190615e19565b6112ad57604051633b79c77360e21b81526001600160a01b0382166004820152602401611182565b6000613302826122a4565b9050806001600160a01b0316836001600160a01b03160361336f5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401611182565b336001600160a01b038216148061338b575061338b8133610f85565b6133fd5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401611182565b61114e8383613e8c565b600a5460ff1661342a5760405163690837d160e01b815260040160405180910390fd5b60005b825181101561359657600083828151811061344a5761344a615aa8565b6020026020010151905060008260016134639190615b36565b90505b84518110156134ba5784818151811061348157613481615aa8565b602002602001015182036134a8576040516315e8d02d60e11b815260040160405180910390fd5b806134b281615a8f565b915050613466565b50336134c5826122a4565b6001600160a01b0316146134ec576040516359dc379f60e01b815260040160405180910390fd5b6000818152600c602052604090205460ff1615158315151461356a57821561353e5760405181907feebbaa86c348cb664e392b180fd0ff2e1998af9fa833ef69a778cb0b42d3ca2790600090a261356a565b60405181907f11725367022c3ff288940f4b5473aa61c2da6a24af7363a1128ee2401e8983b290600090a25b6000908152600c60205260409020805460ff19168315151790558061358e81615a8f565b91505061342d565b506135a033611314565b336000818152600d6020526040908190208390555190917fb6bf628e496a24dda97f35748d8f57d01cd1a7c5558d35b07b6314c003c10161916135e591815260200190565b60405180910390a25050565b6135fc335b82613efa565b6136185760405162461bcd60e51b815260040161118290615e36565b61114e838383613f78565b6002601454036136755760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611182565b6002601455565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146136c9576040519150601f19603f3d011682016040523d82523d6000602084013e6136ce565b606091505b505090508061114e5760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b6044820152606401611182565b61107d8282604051806020016040528060008152506140f1565b6000306001600160a01b037f000000000000000000000000e87138a1ade9b6fe6dcf60b3a65c1f5e62a1f7081614801561378857507f000000000000000000000000000000000000000000000000000000000000000146145b156137b257507f5b4d5d10ae1eece071508f0091d3b95d8a4aabd91bcf26d7b5aeb155926bbd9590565b50604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527fa9950699814776c26ce78bdd814041868b6b4d36238fcfd19935cff0672f2f4d828401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b60004382106138a75760405162461bcd60e51b815260206004820181905260248201527f436865636b706f696e74733a20626c6f636b206e6f7420796574206d696e65646044820152606401611182565b60006138b283614124565b845490915060008160058111156139105760006138ce8461418d565b6138d89085615bce565b60008981526020902090915081015463ffffffff90811690861610156139005780915061390e565b61390b816001615b36565b92505b505b600061391e88868585614275565b9050801561395a5761394388613935600184615bce565b600091825260209091200190565b5464010000000090046001600160e01b031661395d565b60005b6001600160e01b031698975050505050505050565b600081831161398157816115c0565b5090919050565b61114e83838360405180602001604052806000815250612acb565b6139ac336135f6565b6139c85760405162461bcd60e51b815260040161118290615e36565b6112ad81613dd4565b6040516bffffffffffffffffffffffff19606084901b166020820152603481018290526000906054015b60405160208183030381529060405280519060200120905092915050565b60006115c082602354856142cb565b6001600160a01b0382811660008181526010602052604080822080548686166001600160a01b0319821681179092559151919094169392849290917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a461114e8183613a95866142e1565b6142ec565b601580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006115c082602054856142cb565b80546000908015611fba57613b1583613935600184615bce565b5464010000000090046001600160e01b03169392505050565b61107d338383614429565b600a5460ff1615613b5d5760405163690837d160e01b815260040160405180910390fd5b60005b815181101561114e576000613b758285615b36565b90506000838381518110613b8b57613b8b615aa8565b602091018101516000848152600b835260409081902054815160ff909116815260f89290921c92820183905291925083917f3df5b49ff0002b561a78cc6d2628cc6cca4781ad27ae87199b341d668b9a14f3910160405180910390a26000918252600b6020526040909120805460ff191660ff90921691909117905580613c1181615a8f565b915050613b60565b604051600181527f594169f67d23ab550f7dcb2303817abb33cbf95bc48ce5467c4d54661901d80c9060200160405180910390a1600a805460ff19166001179055565b613c663383613efa565b613c825760405162461bcd60e51b815260040161118290615e36565b611f22848484846144f7565b6000611065613c9b61372f565b8361452a565b6000806000613cb287878787614551565b91509150613cbf81614615565b5095945050505050565b6001600160a01b03811660009081526013602052604090208054600181018255905b50919050565b60606000613cfe8361475f565b60010190506000816001600160401b03811115613d1d57613d1d61555e565b6040519080825280601f01601f191660200182016040528015613d47576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084613d5157509392505050565b600082815260026020526040902054602c546001600160a01b039182169116613dad848385614837565b6001600160a01b03161461114e5760405163ea8e4eb560e01b815260040160405180910390fd5b6000613ddf826122a4565b9050613def81600084600161489c565b613df8826122a4565b600083815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526003845282852080546000190190558785526002909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a461107d8160008460016148a8565b6000611065826148b4565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190613ec1826122a4565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080613f06836122a4565b9050806001600160a01b0316846001600160a01b03161480613f4d57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80611a955750836001600160a01b0316613f6684611113565b6001600160a01b031614949350505050565b826001600160a01b0316613f8b826122a4565b6001600160a01b031614613fb15760405162461bcd60e51b815260040161118290615e83565b6001600160a01b0382166140135760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401611182565b614020838383600161489c565b826001600160a01b0316614033826122a4565b6001600160a01b0316146140595760405162461bcd60e51b815260040161118290615e83565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a461114e83838360016148a8565b6140fb83836148d9565b6141086000848484614a7c565b61114e5760405162461bcd60e51b815260040161118290615ec8565b600063ffffffff8211156141895760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b6064820152608401611182565b5090565b60008160000361419f57506000919050565b600060016141ac84614b7a565b901c6001901b905060018184816141c5576141c5615afe565b048201901c905060018184816141dd576141dd615afe565b048201901c905060018184816141f5576141f5615afe565b048201901c9050600181848161420d5761420d615afe565b048201901c9050600181848161422557614225615afe565b048201901c9050600181848161423d5761423d615afe565b048201901c9050600181848161425557614255615afe565b048201901c90506115c08182858161426f5761426f615afe565b04614c0e565b60005b8183101561268b57600061428c8484614c1d565b60008781526020902090915063ffffffff86169082015463ffffffff1611156142b7578092506142c5565b6142c2816001615b36565b93505b50614278565b6000826142d88584614c38565b14949350505050565b6000611065826124fd565b816001600160a01b0316836001600160a01b03161415801561430e5750600081115b1561114e576001600160a01b0383161561439c576001600160a01b0383166000908152601160205260408120819061434990614c7d85614c89565b91509150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051614391929190918252602082015260400190565b60405180910390a250505b6001600160a01b0382161561114e576001600160a01b038216600090815260116020526040812081906143d290614cc185614c89565b91509150836001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405161441a929190918252602082015260400190565b60405180910390a25050505050565b816001600160a01b0316836001600160a01b03160361448a5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401611182565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b614502848484613f78565b61450e84848484614a7c565b611f225760405162461bcd60e51b815260040161118290615ec8565b60405161190160f01b602082015260228101839052604281018290526000906062016139fb565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115614588575060009050600361460c565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156145dc573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166146055760006001925092505061460c565b9150600090505b94509492505050565b600081600481111561462957614629615f1a565b036146315750565b600181600481111561464557614645615f1a565b036146925760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401611182565b60028160048111156146a6576146a6615f1a565b036146f35760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401611182565b600381600481111561470757614707615f1a565b036112ad5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401611182565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b831061479e5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106147ca576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106147e857662386f26fc10000830492506010015b6305f5e1008310614800576305f5e100830492506008015b612710831061481457612710830492506004015b60648310614826576064830492506002015b600a83106110655760010192915050565b604080517f000000000000000000000000000000000000000000000000000000000000000160208201529081018490526001600160a01b0383166060820152600090611a95906080016040516020818303038152906040528051906020012083614ccd565b611f2284848484614ce9565b611f2284848484614cf5565b60006001600160e01b0319821663780e9d6360e01b1480611065575061106582614d05565b6001600160a01b03821661492f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401611182565b6000818152600260205260409020546001600160a01b0316156149945760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401611182565b6149a260008383600161489c565b6000818152600260205260409020546001600160a01b031615614a075760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401611182565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a461107d6000838360016148a8565b60006001600160a01b0384163b15614b7257604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614ac0903390899088908890600401615f30565b6020604051808303816000875af1925050508015614afb575060408051601f3d908101601f19168201909252614af891810190615f6d565b60015b614b58573d808015614b29576040519150601f19603f3d011682016040523d82523d6000602084013e614b2e565b606091505b508051600003614b505760405162461bcd60e51b815260040161118290615ec8565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611a95565b506001611a95565b600080608083901c15614b8f57608092831c92015b604083901c15614ba157604092831c92015b602083901c15614bb357602092831c92015b601083901c15614bc557601092831c92015b600883901c15614bd757600892831c92015b600483901c15614be957600492831c92015b600283901c15614bfb57600292831c92015b600183901c156110655760010192915050565b600081831061398157816115c0565b6000614c2c6002848418615b14565b6115c090848416615b36565b600081815b845181101561268b57614c6982868381518110614c5c57614c5c615aa8565b6020026020010151614d55565b915080614c7581615a8f565b915050614c3d565b60006115c08284615bce565b600080614cb485614caf614c9c88613afb565b6001600160e01b0316868863ffffffff16565b614d84565b915091505b935093915050565b60006115c08284615b36565b6000806000614cdc8585614db8565b9150915061268b81614615565b611f2284848484614dfa565b614d00848483614f33565b611f22565b60006001600160e01b031982166380ac58cd60e01b1480614d3657506001600160e01b03198216635b5e139f60e01b145b8061106557506301ffc9a760e01b6001600160e01b0319831614611065565b6000818310614d715760008281526020849052604090206115c0565b60008381526020839052604090206115c0565b600080614da284614d9443614124565b614d9d86614fa3565b61500c565b6001600160e01b03918216969116945092505050565b6000808251604103614dee5760208301516040840151606085015160001a614de287828585614551565b9450945050505061142e565b5060009050600261142e565b614e06848484846151af565b6001811115614e755760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401611182565b816001600160a01b038516614ed157614ecc81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b614ef4565b836001600160a01b0316856001600160a01b031614614ef457614ef48582615237565b6001600160a01b038416614f1057614f0b816152d4565b611380565b846001600160a01b0316846001600160a01b031614611380576113808482615383565b6001600160a01b038316614f5257614f4f6012614cc183614c89565b50505b6001600160a01b038216614f7157614f6e6012614c7d83614c89565b50505b6001600160a01b0383811660009081526010602052604080822054858416835291205461114e929182169116836142ec565b60006001600160e01b038211156141895760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b6064820152608401611182565b82546000908190801561515557600061502a87613935600185615bce565b60408051808201909152905463ffffffff8082168084526401000000009092046001600160e01b0316602084015291925090871610156150ac5760405162461bcd60e51b815260206004820152601760248201527f436865636b706f696e743a20696e76616c6964206b65790000000000000000006044820152606401611182565b805163ffffffff8088169116036150f557846150cd88613935600186615bce565b80546001600160e01b03929092166401000000000263ffffffff909216919091179055615145565b6040805180820190915263ffffffff80881682526001600160e01b0380881660208085019182528b54600181018d5560008d81529190912094519151909216640100000000029216919091179101555b602001519250839150614cb99050565b50506040805180820190915263ffffffff80851682526001600160e01b0380851660208085019182528854600181018a5560008a815291822095519251909316640100000000029190931617920191909155905081614cb9565b6001811115611f22576001600160a01b038416156151f5576001600160a01b038416600090815260036020526040812080548392906151ef908490615bce565b90915550505b6001600160a01b03831615611f22576001600160a01b0383166000908152600360205260408120805483929061522c908490615b36565b909155505050505050565b60006001615244846124fd565b61524e9190615bce565b6000838152600760205260409020549091508082146152a1576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906152e690600190615bce565b6000838152600960205260408120546008805493945090928490811061530e5761530e615aa8565b90600052602060002001549050806008838154811061532f5761532f615aa8565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061536757615367615f8a565b6001900381819060005260206000200160009055905550505050565b600061538e836124fd565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160e01b0319811681146112ad57600080fd5b6000602082840312156153ef57600080fd5b81356115c0816153c7565b80356001600160a01b038116811461541157600080fd5b919050565b6000806040838503121561542957600080fd5b615432836153fa565b915060208301356001600160601b038116811461544e57600080fd5b809150509250929050565b60005b8381101561547457818101518382015260200161545c565b50506000910152565b60008151808452615495816020860160208601615459565b601f01601f19169290920160200192915050565b6020815260006115c0602083018461547d565b6000602082840312156154ce57600080fd5b5035919050565b600080604083850312156154e857600080fd5b6154f1836153fa565b946020939093013593505050565b60006020828403121561551157600080fd5b6115c0826153fa565b6020808252825182820181905260009190848201906040850190845b8181101561555257835183529284019291840191600101615536565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561559c5761559c61555e565b604052919050565b600060208083850312156155b757600080fd5b82356001600160401b03808211156155ce57600080fd5b818501915085601f8301126155e257600080fd5b8135818111156155f4576155f461555e565b8060051b9150615605848301615574565b818152918301840191848101908884111561561f57600080fd5b938501935b8385101561563d57843582529385019390850190615624565b98975050505050505050565b60008060006060848603121561565e57600080fd5b615667846153fa565b9250615675602085016153fa565b9150604084013590509250925092565b6000806040838503121561569857600080fd5b50508035926020909101359150565b60008083601f8401126156b957600080fd5b5081356001600160401b038111156156d057600080fd5b6020830191508360208260051b850101111561142e57600080fd5b6000806000806060858703121561570157600080fd5b61570a856153fa565b93506020850135925060408501356001600160401b0381111561572c57600080fd5b615738878288016156a7565b95989497509550505050565b80151581146112ad57600080fd5b60006020828403121561576457600080fd5b81356115c081615744565b60006001600160401b038211156157885761578861555e565b50601f01601f191660200190565b60006157a96157a48461576f565b615574565b90508281528383830111156157bd57600080fd5b828260208301376000602084830101529392505050565b6000602082840312156157e657600080fd5b81356001600160401b038111156157fc57600080fd5b8201601f8101841361580d57600080fd5b611a9584823560208401615796565b60008060006040848603121561583157600080fd5b61583a846153fa565b925060208401356001600160401b0381111561585557600080fd5b615861868287016156a7565b9497909650939450505050565b6000806040838503121561588157600080fd5b61588a836153fa565b9150602083013561544e81615744565b600082601f8301126158ab57600080fd5b6115c083833560208501615796565b600080604083850312156158cd57600080fd5b8235915060208301356001600160401b038111156158ea57600080fd5b6158f68582860161589a565b9150509250929050565b6000806000806080858703121561591657600080fd5b61591f856153fa565b935061592d602086016153fa565b92506040850135915060608501356001600160401b0381111561594f57600080fd5b61595b8782880161589a565b91505092959194509250565b60008060008060008060c0878903121561598057600080fd5b615989876153fa565b95506020870135945060408701359350606087013560ff811681146159ad57600080fd5b9598949750929560808101359460a0909101359350915050565b600080604083850312156159da57600080fd5b6159e3836153fa565b91506159f1602084016153fa565b90509250929050565b600181811c90821680615a0e57607f821691505b602082108103613ceb57634e487b7160e01b600052602260045260246000fd5b6020808252602b908201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560408201526a74206f6620626f756e647360a81b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600060018201615aa157615aa1615a79565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6020808252600f908201526e151bdad95b881a5cc81cdd185ad959608a1b604082015260600190565b808202811582820484141761106557611065615a79565b634e487b7160e01b600052601260045260246000fd5b600082615b3157634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561106557611065615a79565b6020808252600a90820152694d41585f535550504c5960b01b604082015260600190565b60ff818116838216019081111561106557611065615a79565b60208082526028908201527f4d65726b6c654469737472696275746f723a20496e76616c696420206d65726b604082015267363290383937b7b360c11b606082015260800190565b8181038181111561106557611065615a79565b601f82111561114e57600081815260208120601f850160051c81016020861015615c085750805b601f850160051c820191505b81811015612b2a57828155600101615c14565b81516001600160401b03811115615c4057615c4061555e565b615c5481615c4e84546159fa565b84615be1565b602080601f831160018114615c895760008415615c715750858301515b600019600386901b1c1916600185901b178555612b2a565b600085815260208120601f198616915b82811015615cb857888601518255948401946001909101908401615c99565b5085821015615cd65787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600081615cf557615cf5615a79565b506000190190565b600060208284031215615d0f57600080fd5b81516001600160401b03811115615d2557600080fd5b8201601f81018413615d3657600080fd5b8051615d446157a48261576f565b818152856020838501011115615d5957600080fd5b615d6a826020830160208601615459565b95945050505050565b60008154615d80816159fa565b60018281168015615d985760018114615dad57615ddc565b60ff1984168752821515830287019450615ddc565b8560005260208060002060005b85811015615dd35781548a820152908401908201615dba565b50505082870194505b5050505092915050565b6000615df28286615d73565b8451615e02818360208901615459565b615e0e81830186615d73565b979650505050505050565b600060208284031215615e2b57600080fd5b81516115c081615744565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090615f639083018461547d565b9695505050505050565b600060208284031215615f7f57600080fd5b81516115c0816153c7565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220ca421b430dd0f8dd7ff1a35859e4ff18fd71b913e5554e89c783c10312ccfa7764736f6c63430008110033

Deployed Bytecode Sourcemap

185731:15567:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;196597:31;;196618:9;160:25:1;;196606:10:0;;196597:31;;148:2:1;133:18;196597:31:0;;;;;;;185731:15567;;;;;201038:257;;;;;;;;;;-1:-1:-1;201038:257:0;;;;;:::i;:::-;;:::i;:::-;;;747:14:1;;740:22;722:41;;710:2;695:18;201038:257:0;;;;;;;;198725:193;;;;;;;;;;-1:-1:-1;198725:193:0;;;;;:::i;:::-;;:::i;:::-;;37645:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;39157:171::-;;;;;;;;;;-1:-1:-1;39157:171:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2428:32:1;;;2410:51;;2398:2;2383:18;39157:171:0;2264:203:1;199807:199:0;;;;;;;;;;-1:-1:-1;199807:199:0;;;;;:::i;:::-;;:::i;177517:24::-;;;;;;;;;;-1:-1:-1;177517:24:0;;;;;;;;187102:27;;;;;;;;;;;;;;;;;;;160:25:1;;;148:2;133:18;187102:27:0;14:177:1;183128:819:0;;;;;;;;;;-1:-1:-1;183128:819:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;181988:92::-;;;;;;;;;;-1:-1:-1;181988:92:0;;;;;:::i;:::-;;:::i;55538:113::-;;;;;;;;;;-1:-1:-1;55626:10:0;:17;55538:113;;188734:142;;;;;;;;;;-1:-1:-1;188734:142:0;;;;;:::i;:::-;;:::i;186682:36::-;;;;;;;;;;-1:-1:-1;186682:36:0;;;;-1:-1:-1;;;186682:36:0;;;;;;182983:137;;;;;;;;;;-1:-1:-1;182983:137:0;;;;;:::i;:::-;;:::i;200130:278::-;;;;;;;;;;-1:-1:-1;200130:278:0;;;;;:::i;:::-;;:::i;186953:34::-;;;;;;;;;;;;;;;;64531:442;;;;;;;;;;-1:-1:-1;64531:442:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;5700:32:1;;;5682:51;;5764:2;5749:18;;5742:34;;;;5655:18;64531:442:0;5508:274:1;194977:568:0;;;;;;:::i;:::-;;:::i;55206:256::-;;;;;;;;;;-1:-1:-1;55206:256:0;;;;;:::i;:::-;;:::i;181710:44::-;;;;;;;;;;-1:-1:-1;181710:44:0;;;;;:::i;:::-;;;;;;;;;;;;;;169281:106;;;;;;;;;;;;;:::i;186758:42::-;;;;;;;;;;-1:-1:-1;186758:42:0;;;;;:::i;:::-;;;;;;;;;;;;;;164305:200;;;;;;;;;;-1:-1:-1;164305:200:0;;;;;:::i;:::-;;:::i;187245:21::-;;;;;;;;;;-1:-1:-1;187245:21:0;;;;-1:-1:-1;;;;;187245:21:0;;;178903:2245;;;;;;;;;;-1:-1:-1;178903:2245:0;;;;;:::i;:::-;;:::i;75016:143::-;;;;;;;;;;;;73593:42;75016:143;;200416:286;;;;;;;;;;-1:-1:-1;200416:286:0;;;;;:::i;:::-;;:::i;200014:108::-;;;;;;;;;;-1:-1:-1;200014:108:0;;;;;:::i;:::-;;:::i;186904:42::-;;;;;;;;;;-1:-1:-1;186904:42:0;;;;;:::i;:::-;;;;;;;;;;;;;;194065:904;;;;;;:::i;:::-;;:::i;178253:642::-;;;;;;;;;;-1:-1:-1;178253:642:0;;;;;:::i;:::-;;:::i;193344:107::-;;;;;;;;;;-1:-1:-1;193344:107:0;;;;;:::i;:::-;;:::i;191409:1129::-;;;;;;;;;;-1:-1:-1;191409:1129:0;;;;;:::i;:::-;;:::i;55728:233::-;;;;;;;;;;-1:-1:-1;55728:233:0;;;;;:::i;:::-;;:::i;196334:102::-;;;;;;;;;;-1:-1:-1;196334:102:0;;;;;:::i;:::-;;:::i;186628:29::-;;;;;;;;;;-1:-1:-1;186628:29:0;;;;-1:-1:-1;;;;;186628:29:0;;;198379:93;;;;;;;;;;-1:-1:-1;198379:93:0;;;;;:::i;:::-;;:::i;165522:129::-;;;;;;;;;;-1:-1:-1;165522:129:0;;;;;:::i;:::-;-1:-1:-1;;;;;165623:20:0;;;165596:7;165623:20;;;:11;:20;;;;;;;;165522:129;187014:38;;;;;;;;;;-1:-1:-1;187014:38:0;;;;;;;;165738:150;;;;;;;;;;-1:-1:-1;165738:150:0;;;;;:::i;:::-;;:::i;37355:223::-;;;;;;;;;;-1:-1:-1;37355:223:0;;;;;:::i;:::-;;:::i;188884:170::-;;;;;;;;;;-1:-1:-1;188884:170:0;;;;;:::i;:::-;;:::i;190457:944::-;;;;;;;;;;-1:-1:-1;190457:944:0;;;;;:::i;:::-;;:::i;198611:90::-;;;;;;;;;;-1:-1:-1;198611:90:0;;;;;:::i;:::-;;:::i;37086:207::-;;;;;;;;;;-1:-1:-1;37086:207:0;;;;;:::i;:::-;;:::i;173556:103::-;;;;;;;;;;;;;:::i;169019:119::-;;;;;;;;;;-1:-1:-1;169019:119:0;;;;;:::i;:::-;;:::i;196658:112::-;;;;;;;;;;-1:-1:-1;196658:112:0;;;;;:::i;:::-;;:::i;196778:443::-;;;;;;;;;;-1:-1:-1;196778:443:0;;;;;:::i;:::-;;:::i;193459:598::-;;;;;;;;;;-1:-1:-1;193459:598:0;;;;;:::i;:::-;;:::i;172908:87::-;;;;;;;;;;-1:-1:-1;172981:6:0;;-1:-1:-1;;;;;172981:6:0;172908:87;;164981:253;;;;;;;;;;-1:-1:-1;164981:253:0;;;;;:::i;:::-;;:::i;197854:101::-;;;;;;;;;;-1:-1:-1;197854:101:0;;;;;:::i;:::-;;:::i;189713:736::-;;;;;;;;;;-1:-1:-1;189713:736:0;;;;;:::i;:::-;;:::i;37814:104::-;;;;;;;;;;;;;:::i;187305:32::-;;;;;;;;;;;;;;;163938:146;;;;;;;;;;-1:-1:-1;163938:146:0;;;;;:::i;:::-;;:::i;192570:427::-;;;;;;;;;;-1:-1:-1;192570:427:0;;;;;:::i;:::-;;:::i;199581:218::-;;;;;;;;;;-1:-1:-1;199581:218:0;;;;;:::i;:::-;;:::i;187185:51::-;;;;;;;;;;-1:-1:-1;187185:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;197474:72;;;;;;;;;;;;;:::i;198926:93::-;;;;;;;;;;;;;:::i;197248:120::-;;;;;;;;;;-1:-1:-1;197248:120:0;;;;;:::i;:::-;;:::i;197376:73::-;;;;;;;;;;;;;:::i;200710:320::-;;;;;;;;;;-1:-1:-1;200710:320:0;;;;;:::i;:::-;;:::i;181663:40::-;;;;;;;;;;-1:-1:-1;181663:40:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;193112:103;;;;;;;;;;-1:-1:-1;193112:103:0;;;;;:::i;:::-;;:::i;165971:581::-;;;;;;;;;;-1:-1:-1;165971:581:0;;;;;:::i;:::-;;:::i;197963:408::-;;;;;;;;;;-1:-1:-1;197963:408:0;;;;;:::i;:::-;;:::i;186871:26::-;;;;;;;;;;;;;;;;187059:34;;;;;;;;;;;;;;;;198480:123;;;;;;;;;;-1:-1:-1;198480:123:0;;;;;:::i;:::-;;:::i;186124:30::-;;;;;;;;;;;;;;;;193005:99;;;;;;;;;;-1:-1:-1;193005:99:0;;;;;:::i;:::-;;:::i;196444:102::-;;;;;;;;;;-1:-1:-1;196444:102:0;;;;;:::i;:::-;;:::i;188385:341::-;;;;;;;;;;-1:-1:-1;188385:341:0;;;;;:::i;:::-;;:::i;182088:95::-;;;;;;;;;;-1:-1:-1;182088:95:0;;;;;:::i;:::-;;:::i;186725:26::-;;;;;;;;;;;;;;;;177548:42;;;;;;;;;;-1:-1:-1;177548:42:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;11726:4:1;11714:17;;;11696:36;;11684:2;11669:18;177548:42:0;11554:184:1;187273:25:0;;;;;;;;;;-1:-1:-1;187273:25:0;;;;-1:-1:-1;;;;;187273:25:0;;;197669:177;;;;;;;;;;;;;:::i;186261:21::-;;;;;;;;;;-1:-1:-1;186261:21:0;;;;-1:-1:-1;;;;;186261:21:0;;;39626:164;;;;;;;;;;-1:-1:-1;39626:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;39747:25:0;;;39723:4;39747:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;39626:164;193223:113;;;;;;;;;;-1:-1:-1;193223:113:0;;;;;:::i;:::-;;:::i;197554:107::-;;;;;;;;;;-1:-1:-1;197554:107:0;;;;;:::i;:::-;;:::i;173814:201::-;;;;;;;;;;-1:-1:-1;173814:201:0;;;;;:::i;:::-;;:::i;187136:42::-;;;;;;;;;;-1:-1:-1;187136:42:0;;;;;:::i;:::-;;;;;;;;;;;;;;186823:41;;;;;;;;;;-1:-1:-1;186823:41:0;;;;;;;;201038:257;201222:4;201251:36;201275:11;201251:23;:36::i;:::-;201244:43;201038:257;-1:-1:-1;;201038:257:0:o;198725:193::-;172794:13;:11;:13::i;:::-;198857:53:::1;198876:15;198893:16;198857:18;:53::i;:::-;198725:193:::0;;:::o;37645:100::-;37699:13;37732:5;37725:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37645:100;:::o;39157:171::-;39233:7;39253:23;39268:7;39253:14;:23::i;:::-;-1:-1:-1;39296:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;39296:24:0;;39157:171::o;199807:199::-;199945:8;76798:30;76819:8;76798:20;:30::i;:::-;199966:32:::1;199980:8;199990:7;199966:13;:32::i;:::-;199807:199:::0;;;:::o;183128:819::-;183209:16;183238:18;183259:16;183269:5;183259:9;:16::i;:::-;183238:37;;183298:10;183294:1;:14;183286:70;;;;-1:-1:-1;;;183286:70:0;;;;;;;:::i;:::-;;;;;;;;;183367:19;183406:9;183401:160;183425:10;183421:1;:14;183401:160;;;183461:8;:39;183470:29;183490:5;183497:1;183470:19;:29::i;:::-;183461:39;;;;;;;;;;;-1:-1:-1;183461:39:0;;;;183457:93;;;183521:13;;;;:::i;:::-;;;;183457:93;183437:3;;;;:::i;:::-;;;;183401:160;;;;183573:25;183615:11;-1:-1:-1;;;;;183601:26:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;183601:26:0;;183573:54;;183652:1;183638:15;;183669:9;183664:250;183688:10;183684:1;:14;183664:250;;;183720:15;183738:29;183758:5;183765:1;183738:19;:29::i;:::-;183786:17;;;;:8;:17;;;;;;183720:47;;-1:-1:-1;183786:17:0;;183782:121;;;183848:7;183824:8;183833:11;183824:21;;;;;;;;:::i;:::-;;;;;;;;;;:31;183874:13;;;;:::i;:::-;;;;183782:121;-1:-1:-1;183700:3:0;;;;:::i;:::-;;;;183664:250;;;-1:-1:-1;183931:8:0;183128:819;-1:-1:-1;;;;183128:819:0:o;181988:92::-;182050:22;182057:8;182067:4;182050:6;:22::i;:::-;181988:92;:::o;188734:142::-;172794:13;:11;:13::i;:::-;188821:6:::1;::::0;188807:32:::1;::::0;-1:-1:-1;;;;;188807:32:0;;::::1;::::0;188821:6:::1;::::0;188807:32:::1;::::0;188821:6:::1;::::0;188807:32:::1;188850:6;:18:::0;;-1:-1:-1;;;;;;188850:18:0::1;-1:-1:-1::0;;;;;188850:18:0;;;::::1;::::0;;;::::1;::::0;;188734:142::o;182983:137::-;183042:7;183069:43;183083:28;183103:7;183083:19;:28::i;200130:278::-;200303:7;184006:23;184021:7;184006:14;:23::i;:::-;184049:17;;;;:8;:17;;;;;;;;184048:18;184040:46;;;;-1:-1:-1;;;184040:46:0;;;;;;;:::i;:::-;200341:4;-1:-1:-1;;;;;76524:18:0;::::1;76532:10;76524:18;76520:83;;76559:32;76580:10;76559:20;:32::i;:::-;200363:37:::2;200382:4;200388:2;200392:7;200363:18;:37::i;:::-;184097:1:::1;200130:278:::0;;;;:::o;64531:442::-;64628:7;64686:27;;;:17;:27;;;;;;;;64657:56;;;;;;;;;-1:-1:-1;;;;;64657:56:0;;;;;-1:-1:-1;;;64657:56:0;;;-1:-1:-1;;;;;64657:56:0;;;;;;;;64628:7;;64726:92;;-1:-1:-1;64777:29:0;;;;;;;;;64787:19;64777:29;-1:-1:-1;;;;;64777:29:0;;;;-1:-1:-1;;;64777:29:0;;-1:-1:-1;;;;;64777:29:0;;;;;64726:92;64868:23;;;;64830:21;;65339:5;;64855:36;;-1:-1:-1;;;;;64855:36:0;:10;:36;:::i;:::-;64854:58;;;;:::i;:::-;64933:16;;;-1:-1:-1;64830:82:0;;-1:-1:-1;;64531:442:0;;;;;;:::o;194977:568::-;176732:21;:19;:21::i;:::-;195063:18:::1;::::0;::::1;;195058:47;;195090:15;;-1:-1:-1::0;;;195090:15:0::1;;;;;;;;;;;195058:47;186113:4;195141:10;195125:13;55626:10:::0;:17;;55538:113;195125:13:::1;:26;;;;:::i;:::-;195124:42;;195116:65;;;;-1:-1:-1::0;;;195116:65:0::1;;;;;;;:::i;:::-;195222:6;::::0;195209:19:::1;::::0;:10;:19:::1;:::i;:::-;195196:9;:32;195192:61;;195237:16;;-1:-1:-1::0;;;195237:16:0::1;;;;;;;;;;;195192:61;195273:6;::::0;195264:27:::1;::::0;-1:-1:-1;;;;;195273:6:0::1;195281:9;195264:8;:27::i;:::-;195317:10;195302:11;;:25;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;195343:9:0::1;::::0;-1:-1:-1;195338:200:0::1;195362:10;195358:1;:14;195338:200;;;195394:15;195412:25;:15;103004:14:::0;;102912:114;195412:25:::1;195394:43;;195452:27;:15;103123:19:::0;;103141:1;103123:19;;;103034:127;195452:27:::1;195494:32;18323:10:::0;195518:7:::1;195494:9;:32::i;:::-;-1:-1:-1::0;195374:3:0;::::1;::::0;::::1;:::i;:::-;;;;195338:200;;;;176776:20:::0;176170:1;177296:7;:22;177113:213;55206:256;55303:7;55339:23;55356:5;55339:16;:23::i;:::-;55331:5;:31;55323:87;;;;-1:-1:-1;;;55323:87:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;55428:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;55206:256::o;169281:106::-;169332:7;169359:20;:18;:20::i;:::-;169352:27;;169281:106;:::o;164305:200::-;-1:-1:-1;;;;;164430:29:0;;164403:7;164430:29;;;:20;:29;;;;;:67;;164485:11;164430:54;:67::i;:::-;164423:74;164305:200;-1:-1:-1;;;164305:200:0:o;178903:2245::-;178990:15;;;179094;177506:2;179108:1;179094:15;:::i;:::-;179083:27;;-1:-1:-1;;;;;179083:27:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;179083:27:0;;179063:47;;179126:9;179121:295;179145:8;:15;179141:1;:19;179121:295;;;179182:15;179200:8;179209:1;179200:11;;;;;;;;:::i;:::-;;;;;;;179182:29;;179226:13;179242:18;179252:7;179242:9;:18::i;:::-;179285:11;179299:18;;;:9;:18;;;;;;179332:10;;179226:34;;-1:-1:-1;179299:18:0;;;;;179332:3;;179299:18;;179332:10;;;;;;:::i;:::-;:17;;;:10;;;;;;;;;;;:17;179379:25;179384:5;179391:12;179379:4;:25::i;:::-;179364:40;;179167:249;;;179162:3;;;;;:::i;:::-;;;;179121:295;;;;179463:3;179467:1;179463:6;;;;;;;;:::i;:::-;;;;;;;:29;;;;;179486:3;179490:1;179486:6;;;;;;;;:::i;:::-;;;;;;;179463:29;:52;;;;;179509:3;179513:1;179509:6;;;;;;;;:::i;:::-;;;;;;;179463:52;:75;;;;;179532:3;179536:1;179532:6;;;;;;;;:::i;:::-;;;;;;;179463:75;:98;;;;;179555:3;179559:1;179555:6;;;;;;;;:::i;:::-;;;;;;;179463:98;:121;;;;;179578:3;179582:1;179578:6;;;;;;;;:::i;:::-;;;;;;;179463:121;:144;;;;;179601:3;179605:1;179601:6;;;;;;;;:::i;:::-;;;;;;;179463:144;:167;;;;;179624:3;179628:1;179624:6;;;;;;;;:::i;:::-;;;;;;;179463:167;:190;;;;;179647:3;179651:1;179647:6;;;;;;;;:::i;:::-;;;;;;;179463:190;:214;;;;;179670:3;179674:2;179670:7;;;;;;;;:::i;:::-;;;;;;;179463:214;:238;;;;;179694:3;179698:2;179694:7;;;;;;;;:::i;:::-;;;;;;;179463:238;:262;;;;;179718:3;179722:2;179718:7;;;;;;;;:::i;:::-;;;;;;;179463:262;:286;;;;;179742:3;179746:2;179742:7;;;;;;;;:::i;:::-;;;;;;;179463:286;:310;;;;;179766:3;179770:2;179766:7;;;;;;;;:::i;:::-;;;;;;;179463:310;179445:407;;;-1:-1:-1;179807:3:0;;178903:2245;-1:-1:-1;;;178903:2245:0:o;179445:407::-;179866:3;179870:1;179866:6;;;;;;;;:::i;:::-;;;;;;;:16;;;;;179876:3;179880:1;179876:6;;;;;;;;:::i;:::-;;;;;;;179866:16;179862:91;;;-1:-1:-1;179906:2:0;;178903:2245;-1:-1:-1;;;178903:2245:0:o;179862:91::-;179995:3;179999:1;179995:6;;;;;;;;:::i;:::-;;;;;;;:16;;;;;180005:3;180009:1;180005:6;;;;;;;;:::i;:::-;;;;;;;179995:16;179991:58;;;-1:-1:-1;180035:2:0;;178903:2245;-1:-1:-1;;;178903:2245:0:o;179991:58::-;180089:3;180093:1;180089:6;;;;;;;;:::i;:::-;;;;;;;:17;;;;;180099:3;180103:2;180099:7;;;;;;;;:::i;:::-;;;;;;;180089:17;180085:59;;;-1:-1:-1;180130:2:0;;178903:2245;-1:-1:-1;;;178903:2245:0:o;180085:59::-;180186:3;180190:1;180186:6;;;;;;;;:::i;:::-;;;;;;;:16;;;;;180196:3;180200:1;180196:6;;;;;;;;:::i;:::-;;;;;;;180186:16;180182:58;;;-1:-1:-1;180226:2:0;;178903:2245;-1:-1:-1;;;178903:2245:0:o;180182:58::-;180256:3;180260:1;180256:6;;;;;;;;:::i;:::-;;;;;;;:16;;;;;180266:3;180270:1;180266:6;;;;;;;;:::i;:::-;;;;;;;180256:16;:26;;;;;180276:3;180280:1;180276:6;;;;;;;;:::i;:::-;;;;;;;180256:26;180252:96;;;-1:-1:-1;180306:2:0;;178903:2245;-1:-1:-1;;;178903:2245:0:o;180252:96::-;180390:3;180394:1;180390:6;;;;;;;;:::i;:::-;;;;;;;:17;;;;;180400:3;180404:2;180400:7;;;;;;;;:::i;:::-;;;;;;;180390:17;180386:79;;;180431:22;180436:2;180440:12;180431:4;:22::i;:::-;180424:29;178903:2245;-1:-1:-1;;;;178903:2245:0:o;180386:79::-;180499:3;180503:1;180499:6;;;;;;;;:::i;:::-;;;;;;;180495:156;;;180557:3;180561:1;180557:6;;;;;;;;:::i;:::-;;;;;;;:17;;;;180567:3;180571:2;180567:7;;;;;;;;:::i;:::-;;;;;;;180557:17;180553:87;;;180602:22;180607:2;180611:12;180602:4;:22::i;180553:87::-;180681:3;180685:1;180681:6;;;;;;;;:::i;:::-;;;;;;;:29;;;;;180704:3;180708:1;180704:6;;;;;;;;:::i;:::-;;;;;;;180681:29;:52;;;;;180727:3;180731:1;180727:6;;;;;;;;:::i;:::-;;;;;;;180681:52;:75;;;;;180750:3;180754:1;180750:6;;;;;;;;:::i;:::-;;;;;;;180681:75;:99;;;;;180773:3;180777:2;180773:7;;;;;;;;:::i;:::-;;;;;;;180681:99;:123;;;;;180797:3;180801:2;180797:7;;;;;;;;:::i;:::-;;;;;;;180681:123;:147;;;;;180821:3;180825:2;180821:7;;;;;;;;:::i;:::-;;;;;;;180681:147;:171;;;;;180845:3;180849:2;180845:7;;;;;;;;:::i;:::-;;;;;;;180681:171;:195;;;;;180869:3;180873:2;180869:7;;;;;;;;:::i;:::-;;;;;;;180681:195;180663:311;;;180910:22;180915:2;180919:12;180910:4;:22::i;180663:311::-;181016:3;181020:1;181016:6;;;;;;;;:::i;:::-;;;;;;;:17;;;;;181026:3;181030:2;181026:7;;;;;;;;:::i;:::-;;;;;;;181016:17;181012:79;;;181057:22;181062:2;181066:12;181057:4;:22::i;181012:79::-;-1:-1:-1;181110:12:0;178903:2245;-1:-1:-1;;178903:2245:0:o;200416:286::-;200593:7;184006:23;184021:7;184006:14;:23::i;:::-;184049:17;;;;:8;:17;;;;;;;;184048:18;184040:46;;;;-1:-1:-1;;;184040:46:0;;;;;;;:::i;:::-;200631:4;-1:-1:-1;;;;;76524:18:0;::::1;76532:10;76524:18;76520:83;;76559:32;76580:10;76559:20;:32::i;:::-;200653:41:::2;200676:4;200682:2;200686:7;200653:22;:41::i;200014:108::-:0;200075:7;184006:23;184021:7;184006:14;:23::i;:::-;184049:17;;;;:8;:17;;;;;;;;184048:18;184040:46;;;;-1:-1:-1;;;184040:46:0;;;;;;;:::i;:::-;200095:19:::1;200106:7;200095:10;:19::i;194065:904::-:0;176732:21;:19;:21::i;:::-;194237::::1;::::0;::::1;;194232:50;;194267:15;;-1:-1:-1::0;;;194267:15:0::1;;;;;;;;;;;194232:50;-1:-1:-1::0;;;;;194298:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;;194331:1:::1;::::0;194298:29:::1;::::0;194317:10;;194298:29:::1;:::i;:::-;194297:35;194293:59;;;194341:11;;-1:-1:-1::0;;;194341:11:0::1;;;;;;;;;;;194293:59;194385:40;194394:17;194400:7;194409:1;194394:5;:17::i;:::-;194413:11;;194385:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;194385:8:0::1;::::0;-1:-1:-1;;;194385:40:0:i:1;:::-;194363:130;;;;-1:-1:-1::0;;;194363:130:0::1;;;;;;;:::i;:::-;186113:4;194529:10;194513:13;55626:10:::0;:17;;55538:113;194513:13:::1;:26;;;;:::i;:::-;194512:42;;194504:65;;;;-1:-1:-1::0;;;194504:65:0::1;;;;;;;:::i;:::-;194610:6;::::0;194597:19:::1;::::0;:10;:19:::1;:::i;:::-;194584:9;:32;194580:61;;194625:16;;-1:-1:-1::0;;;194625:16:0::1;;;;;;;;;;;194580:61;194661:6;::::0;194652:27:::1;::::0;-1:-1:-1;;;;;194661:6:0::1;194669:9;194652:8;:27::i;:::-;-1:-1:-1::0;;;;;194690:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;:30;;194710:10;;194690:16;:30:::1;::::0;194710:10;;194690:30:::1;:::i;:::-;;;;;;;;194746:10;194731:11;;:25;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;194772:9:0::1;::::0;-1:-1:-1;194767:195:0::1;194791:10;194787:1;:14;194767:195;;;194823:15;194841:25;:15;103004:14:::0;;102912:114;194841:25:::1;194823:43;;194881:27;:15;103123:19:::0;;103141:1;103123:19;;;103034:127;194881:27:::1;194923;194933:7;194942;194923:9;:27::i;:::-;-1:-1:-1::0;194803:3:0;::::1;::::0;::::1;:::i;:::-;;;;194767:195;;;;176776:20:::0;176170:1;177296:7;:22;177113:213;176776:20;194065:904;;;;:::o;178253:642::-;178310:7;178344:18;;;:9;:18;;;;;;;;;178410:84;;-1:-1:-1;178455:1:0;;178253:642;-1:-1:-1;;178253:642:0:o;178410:84::-;178523:1;178508:17;;;;;;;:38;;-1:-1:-1;178544:1:0;178529:17;;;;;178508:38;178504:106;;;-1:-1:-1;178570:2:0;;178253:642;-1:-1:-1;;178253:642:0:o;178504:106::-;178639:1;178624:17;;;;;;;:38;;-1:-1:-1;178660:1:0;178645:17;;;;;178624:38;178620:101;;;-1:-1:-1;178686:2:0;;178253:642;-1:-1:-1;;178253:642:0:o;178620:101::-;178750:1;178735:17;;;;;;;:48;;-1:-1:-1;177506:2:0;178756:27;;;;;178735:48;178731:112;;;-1:-1:-1;178807:1:0;;178253:642;-1:-1:-1;;178253:642:0:o;178731:112::-;-1:-1:-1;178860:1:0;;178253:642;-1:-1:-1;;178253:642:0:o;193344:107::-;172794:13;:11;:13::i;:::-;193416:18:::1;:27:::0;;-1:-1:-1;;193416:27:0::1;::::0;::::1;;::::0;;;::::1;::::0;;193344:107::o;191409:1129::-;176732:21;:19;:21::i;:::-;172794:13:::1;:11;:13::i;:::-;191517::::2;191574:11;;191549:21;191534:12;;:36;;;;:::i;:::-;191533:52;;;;:::i;:::-;191517:68:::0;-1:-1:-1;191596:13:0::2;::::0;191620:785:::2;191644:8;:15;191640:1;:19;191620:785;;;191681:15;191699:8;191708:1;191699:11;;;;;;;;:::i;:::-;;;;;;;191681:29;;191739:1;191729:7;:11;:36;;;;191754:11;;191744:7;:21;191729:36;191725:67;;;191774:18;;-1:-1:-1::0;;;191774:18:0::2;;;;;;;;;;;191725:67;191812:9;191824:5;:1:::0;191828::::2;191824:5;:::i;:::-;191812:17;;191807:138;191835:8;:15;191831:1;:19;191807:138;;;191891:8;191900:1;191891:11;;;;;;;;:::i;:::-;;;;;;;191880:7;:22:::0;191876:53:::2;;191911:18;;-1:-1:-1::0;;;191911:18:0::2;;;;;;;;;;;191876:53;191852:3:::0;::::2;::::0;::::2;:::i;:::-;;;;191807:138;;;-1:-1:-1::0;192027:15:0::2;192014:8;186062:6;192020:2;192014:8;:::i;:::-;191986:25;::::0;;;:16:::2;:25;::::0;;;;;:36:::2;::::0;;::::2;:::i;:::-;191985:57;;191959:130;;;::::0;-1:-1:-1;;;191959:130:0;;15313:2:1;191959:130:0::2;::::0;::::2;15295:21:1::0;15352:2;15332:18;;;15325:30;-1:-1:-1;;;15371:18:1;;;15364:41;15422:18;;191959:130:0::2;15111:335:1::0;191959:130:0::2;192104:20;192127:16:::0;;;:7:::2;:16;::::0;;;;;192162:20;;::::2;192158:236;;;192203:13;192219:20;192227:12:::0;192219:5;:20:::2;:::i;:::-;192203:36;;192278:5;192258:7;:16;192266:7;192258:16;;;;;;;;;;;;:25;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;192302:25:0::2;::::0;;;:16:::2;:25;::::0;;;;192330:15:::2;192302:43:::0;;192364:14:::2;192373:5:::0;192364:14;::::2;:::i;:::-;;;192184:210;192158:236;191666:739;;191661:3;;;;;:::i;:::-;;;;191620:785;;;-1:-1:-1::0;192419:9:0;;192415:116:::2;;192445:38;18323:10:::0;192477:5:::2;192445:8;:38::i;:::-;192514:5;192498:12;;:21;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;192415:116:0::2;191506:1032;;176776:20:::0;176170:1;177296:7;:22;177113:213;55728:233;55803:7;55839:30;55626:10;:17;;55538:113;55839:30;55831:5;:38;55823:95;;;;-1:-1:-1;;;55823:95:0;;15786:2:1;55823:95:0;;;15768:21:1;15825:2;15805:18;;;15798:30;15864:34;15844:18;;;15837:62;-1:-1:-1;;;15915:18:1;;;15908:42;15967:19;;55823:95:0;15584:408:1;55823:95:0;55936:10;55947:5;55936:17;;;;;;;;:::i;:::-;;;;;;;;;55929:24;;55728:233;;;:::o;196334:102::-;172794:13;:11;:13::i;:::-;196403:11:::1;:25:::0;196334:102::o;198379:93::-;172794:13;:11;:13::i;:::-;198449:8:::1;:15;198460:4:::0;198449:8;:15:::1;:::i;165738:150::-:0;18323:10;165851:29;18323:10;165870:9;165851;:29::i;37355:223::-;37427:7;42242:16;;;:7;:16;;;;;;-1:-1:-1;;;;;42242:16:0;;37491:56;;;;-1:-1:-1;;;37491:56:0;;18403:2:1;37491:56:0;;;18385:21:1;18442:2;18422:18;;;18415:30;-1:-1:-1;;;18461:18:1;;;18454:54;18525:18;;37491:56:0;18201:348:1;188884:170:0;172794:13;:11;:13::i;:::-;188983:10:::1;::::0;188965:44:::1;::::0;-1:-1:-1;;;;;188965:44:0;;::::1;::::0;188983:10:::1;::::0;188965:44:::1;::::0;188983:10:::1;::::0;188965:44:::1;189020:10;:26:::0;;-1:-1:-1;;;;;;189020:26:0::1;-1:-1:-1::0;;;;;189020:26:0;;;::::1;::::0;;;::::1;::::0;;188884:170::o;190457:944::-;176732:21;:19;:21::i;:::-;190532:13:::1;190589:11;;190564:21;190549:12;;:36;;;;:::i;:::-;190548:52;;;;:::i;:::-;190532:68:::0;-1:-1:-1;190611:13:0::1;::::0;190635:633:::1;190659:8;:15;190655:1;:19;190635:633;;;190696:15;190714:8;190723:1;190714:11;;;;;;;;:::i;:::-;;;;;;;190696:29;;190745:9;190757:1;190761;190757:5;;;;:::i;:::-;190745:17;;190740:138;190768:8;:15;190764:1;:19;190740:138;;;190824:8;190833:1;190824:11;;;;;;;;:::i;:::-;;;;;;;190813:7;:22:::0;190809:53:::1;;190844:18;;-1:-1:-1::0;;;190844:18:0::1;;;;;;;;;;;190809:53;190785:3:::0;::::1;::::0;::::1;:::i;:::-;;;;190740:138;;;-1:-1:-1::0;18323:10:0;190896:16:::1;190904:7:::0;190896::::1;:16::i;:::-;-1:-1:-1::0;;;;;190896:32:0::1;;190892:60;;190937:15;;-1:-1:-1::0;;;190937:15:0::1;;;;;;;;;;;190892:60;190967:20;190990:16:::0;;;:7:::1;:16;::::0;;;;;191025:20;;::::1;191021:236;;;191066:13;191082:20;191090:12:::0;191082:5;:20:::1;:::i;:::-;191066:36;;191141:5;191121:7;:16;191129:7;191121:16;;;;;;;;;;;;:25;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;191165:25:0::1;::::0;;;:16:::1;:25;::::0;;;;191193:15:::1;191165:43:::0;;191227:14:::1;191236:5:::0;191227:14;::::1;:::i;:::-;;;191047:210;191021:236;190681:587;;190676:3;;;;;:::i;:::-;;;;190635:633;;198611:90:::0;172794:13;:11;:13::i;:::-;198677:6:::1;:16:::0;;-1:-1:-1;;;;;;198677:16:0::1;-1:-1:-1::0;;;;;198677:16:0;;;::::1;::::0;;;::::1;::::0;;198611:90::o;37086:207::-;37158:7;-1:-1:-1;;;;;37186:19:0;;37178:73;;;;-1:-1:-1;;;37178:73:0;;18756:2:1;37178:73:0;;;18738:21:1;18795:2;18775:18;;;18768:30;18834:34;18814:18;;;18807:62;-1:-1:-1;;;18885:18:1;;;18878:39;18934:19;;37178:73:0;18554:405:1;37178:73:0;-1:-1:-1;;;;;;37269:16:0;;;;;:9;:16;;;;;;;37086:207::o;173556:103::-;172794:13;:11;:13::i;:::-;173621:30:::1;173648:1;173621:18;:30::i;:::-;173556:103::o:0;169019:119::-;-1:-1:-1;;;;;169106:14:0;;169079:7;169106:14;;;:7;:14;;;;;103004;169106:24;102912:114;196658:112;196718:7;42242:16;;;:7;:16;;;;;;-1:-1:-1;;;;;42242:16:0;196745:17;42149:117;196778:443;196855:16;196884:18;196905:16;196915:5;196905:9;:16::i;:::-;196884:37;;196944:10;196940:1;:14;196932:70;;;;-1:-1:-1;;;196932:70:0;;;;;;;:::i;:::-;197013:25;197055:10;-1:-1:-1;;;;;197041:25:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;197041:25:0;;197013:53;;197082:9;197077:111;197101:10;197097:1;:14;197077:111;;;197147:29;197167:5;197174:1;197147:19;:29::i;:::-;197133:8;197142:1;197133:11;;;;;;;;:::i;:::-;;;;;;;;;;:43;197113:3;;;;:::i;:::-;;;;197077:111;;;-1:-1:-1;197205:8:0;196778:443;-1:-1:-1;;;196778:443:0:o;193459:598::-;176732:21;:19;:21::i;:::-;193589:16:::1;::::0;-1:-1:-1;;;193589:16:0;::::1;;;193588:17;::::0;:35:::1;;-1:-1:-1::0;193609:9:0::1;::::0;:14;193588:35:::1;193584:63;;;193632:15;;-1:-1:-1::0;;;193632:15:0::1;;;;;;;;;;;193584:63;-1:-1:-1::0;;;;;193662:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;;193682:1:::1;-1:-1:-1::0;193658:45:0::1;;193692:11;;-1:-1:-1::0;;;193692:11:0::1;;;;;;;;;;;193658:45;193736:40;193745:17;193751:7;193760:1;193745:5;:17::i;:::-;193764:11;;193736:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;193736:8:0::1;::::0;-1:-1:-1;;;193736:40:0:i:1;:::-;193714:130;;;;-1:-1:-1::0;;;193714:130:0::1;;;;;;;:::i;:::-;193855:9;:11:::0;;;:9:::1;:11;::::0;::::1;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;193877:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;:18;;;::::1;::::0;::::1;:::i;:::-;::::0;;;-1:-1:-1;;193906:11:0::1;:13:::0;;;:11:::1;:13;::::0;::::1;:::i;:::-;;;;;;193930:15;193948:25;:15;103004:14:::0;;102912:114;193948:25:::1;193930:43;;193984:27;:15;103123:19:::0;;103141:1;103123:19;;;103034:127;193984:27:::1;194022;194032:7;194041;194022:9;:27::i;:::-;193573:484;176776:20:::0;176170:1;177296:7;:22;177113:213;164981:253;165068:7;165110:12;165096:11;:26;165088:65;;;;-1:-1:-1;;;165088:65:0;;19307:2:1;165088:65:0;;;19289:21:1;19346:2;19326:18;;;19319:30;19385:28;19365:18;;;19358:56;19431:18;;165088:65:0;19105:350:1;165088:65:0;165171:55;:17;165214:11;165171:42;:55::i;197854:101::-;172794:13;:11;:13::i;:::-;197928:12:::1;:19;197943:4:::0;197928:12;:19:::1;:::i;189713:736::-:0;189800:7;189820:13;189877:11;;189852:21;189837:12;;:36;;;;:::i;:::-;189836:52;;;;:::i;:::-;189820:68;-1:-1:-1;189899:13:0;;189923:496;189947:8;:15;189943:1;:19;189923:496;;;189984:15;190002:8;190011:1;190002:11;;;;;;;;:::i;:::-;;;;;;;189984:29;;190042:1;190032:7;:11;:36;;;;190057:11;;190047:7;:21;190032:36;190028:67;;;190077:18;;-1:-1:-1;;;190077:18:0;;;;;;;;;;;190028:67;190115:9;190127:5;:1;190131;190127:5;:::i;:::-;190115:17;;190110:138;190138:8;:15;190134:1;:19;190110:138;;;190194:8;190203:1;190194:11;;;;;;;;:::i;:::-;;;;;;;190183:7;:22;190179:53;;190214:18;;-1:-1:-1;;;190214:18:0;;;;;;;;;;;190179:53;190155:3;;;;:::i;:::-;;;;190110:138;;;-1:-1:-1;190262:20:0;190285:16;;;:7;:16;;;;;;190320:20;;;190316:92;;;190371:20;190379:12;190371:5;:20;:::i;:::-;190361:31;;;;:::i;:::-;;;190316:92;189969:450;;189964:3;;;;;:::i;:::-;;;;189923:496;;37814:104;37870:13;37903:7;37896:14;;;;;:::i;163938:146::-;-1:-1:-1;;;;;164038:29:0;;164011:7;164038:29;;;:20;:29;;;;;:38;;:36;:38::i;:::-;-1:-1:-1;;;;;164031:45:0;;163938:146;-1:-1:-1;;163938:146:0:o;192570:427::-;176732:21;:19;:21::i;:::-;172794:13:::1;:11;:13::i;:::-;186113:4:::2;192713:10;192697:13;55626:10:::0;:17;;55538:113;192697:13:::2;:26;;;;:::i;:::-;192696:42;;192688:65;;;;-1:-1:-1::0;;;192688:65:0::2;;;;;;;:::i;:::-;192779:10;192764:11;;:25;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;192805:9:0::2;::::0;-1:-1:-1;192800:190:0::2;192824:10;192820:1;:14;192800:190;;;192856:15;192874:25;:15;103004:14:::0;;102912:114;192874:25:::2;192856:43;;192914:27;:15;103123:19:::0;;103141:1;103123:19;;;103034:127;192914:27:::2;192956:22;192966:2;192970:7;192956:9;:22::i;:::-;-1:-1:-1::0;192836:3:0;::::2;::::0;::::2;:::i;:::-;;;;192800:190;;;;176776:20:::0;176170:1;177296:7;:22;177113:213;199581:218;199727:8;76798:30;76819:8;76798:20;:30::i;:::-;199748:43:::1;199772:8;199782;199748:23;:43::i;197474:72::-:0;172794:13;:11;:13::i;:::-;197522:9:::1;:16:::0;;-1:-1:-1;;197522:16:0::1;197534:4;197522:16;::::0;;197474:72::o;198926:93::-;172794:13;:11;:13::i;:::-;198988:23:::1;66099:19:::0;;66092:26;66031:95;197248:120;172794:13;:11;:13::i;:::-;197334:26:::1;197347:5;197354;197334:12;:26::i;197376:73::-:0;172794:13;:11;:13::i;:::-;197428::::1;:11;:13::i;200710:320::-:0;200915:7;184006:23;184021:7;184006:14;:23::i;:::-;184049:17;;;;:8;:17;;;;;;;;184048:18;184040:46;;;;-1:-1:-1;;;184040:46:0;;;;;;;:::i;:::-;200953:4;-1:-1:-1;;;;;76524:18:0;::::1;76532:10;76524:18;76520:83;;76559:32;76580:10;76559:20;:32::i;:::-;200975:47:::2;200998:4;201004:2;201008:7;201017:4;200975:22;:47::i;:::-;184097:1:::1;200710:320:::0;;;;;:::o;193112:103::-;172794:13;:11;:13::i;:::-;193182:16:::1;:25:::0;;;::::1;;-1:-1:-1::0;;;193182:25:0::1;-1:-1:-1::0;;;;193182:25:0;;::::1;::::0;;;::::1;::::0;;193112:103::o;165971:581::-;166198:6;166179:15;:25;;166171:62;;;;-1:-1:-1;;;166171:62:0;;19662:2:1;166171:62:0;;;19644:21:1;19701:2;19681:18;;;19674:30;19740:26;19720:18;;;19713:54;19784:18;;166171:62:0;19460:348:1;166171:62:0;166316:58;;;163527:71;166316:58;;;20044:25:1;-1:-1:-1;;;;;20105:32:1;;20085:18;;;20078:60;;;;20154:18;;;20147:34;;;20197:18;;;20190:34;;;166244:14:0;;166261:174;;166289:87;;20016:19:1;;166316:58:0;;;;;;;;;;;;166306:69;;;;;;166289:16;:87::i;:::-;166391:1;166407;166423;166261:13;:174::i;:::-;166244:191;;166463:17;166473:6;166463:9;:17::i;:::-;166454:5;:26;166446:59;;;;-1:-1:-1;;;166446:59:0;;20437:2:1;166446:59:0;;;20419:21:1;20476:2;20456:18;;;20449:30;-1:-1:-1;;;20495:18:1;;;20488:50;20555:18;;166446:59:0;20235:344:1;166446:59:0;166516:28;166526:6;166534:9;166516;:28::i;:::-;166160:392;165971:581;;;;;;:::o;197963:408::-;198044:13;198070:23;198085:7;198070:14;:23::i;:::-;198111:9;;;;198106:38;;198129:15;198122:22;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;197963:408;;;:::o;198106:38::-;198161:6;;-1:-1:-1;;;;;198161:6:0;:20;198157:71;;198203:6;;198190:38;;-1:-1:-1;;;198190:38:0;;;;;160:25:1;;;-1:-1:-1;;;;;198203:6:0;;;;198190:29;;133:18:1;;198190:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;198190:38:0;;;;;;;;;;;;:::i;198157:71::-;198303:8;198313:18;:7;:16;:18::i;:::-;198333:14;198286:62;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;198241:122;;197963:408;;;:::o;198480:123::-;172794:13;:11;:13::i;:::-;198565:14:::1;:30;198582:13:::0;198565:14;:30:::1;:::i;193005:99::-:0;172794:13;:11;:13::i;:::-;193071:6:::1;:25:::0;;-1:-1:-1;;;;;;193071:25:0::1;-1:-1:-1::0;;;;;193071:25:0;;;::::1;::::0;;;::::1;::::0;;193005:99::o;196444:102::-;172794:13;:11;:13::i;:::-;196513:11:::1;:25:::0;196444:102::o;188385:341::-;188488:7;184006:23;184021:7;184006:14;:23::i;:::-;184049:17;;;;:8;:17;;;;;;;;184048:18;184040:46;;;;-1:-1:-1;;;184040:46:0;;;;;;;:::i;:::-;188532:6:::1;::::0;-1:-1:-1;;;;;188532:6:0::1;18323:10:::0;-1:-1:-1;;;;;188516:22:0::1;;188508:48;;;::::0;-1:-1:-1;;;188508:48:0;;22641:2:1;188508:48:0::1;::::0;::::1;22623:21:1::0;22680:2;22660:18;;;22653:30;-1:-1:-1;;;22699:18:1;;;22692:43;22752:18;;188508:48:0::1;22439:337:1::0;188508:48:0::1;188573:10;::::0;-1:-1:-1;;;;;188573:10:0::1;:24:::0;188569:92:::1;;188614:35;188630:7;188639:9;188614:15;:35::i;:::-;188673:14;188679:7;188673:5;:14::i;:::-;188703:15;::::0;188710:7;;188703:15:::1;::::0;;;::::1;188385:341:::0;;;:::o;182088:95::-;182152:23;182159:8;182169:5;182152:6;:23::i;197669:177::-;197745:6;;197715:13;;-1:-1:-1;;;;;197745:6:0;:20;197741:67;;197787:6;;;;;;;;;-1:-1:-1;;;;;197787:6:0;-1:-1:-1;;;;;197774:32:0;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;197774:34:0;;;;;;;;;;;;:::i;197741:67::-;197826:12;197819:19;;;;;:::i;193223:113::-;172794:13;:11;:13::i;:::-;193298:21:::1;:30:::0;;-1:-1:-1;;193298:30:0::1;::::0;::::1;;::::0;;;::::1;::::0;;193223:113::o;197554:107::-;172794:13;:11;:13::i;:::-;197631:15:::1;:22;197649:4:::0;197631:15;:22:::1;:::i;173814:201::-:0;172794:13;:11;:13::i;:::-;-1:-1:-1;;;;;173903:22:0;::::1;173895:73;;;::::0;-1:-1:-1;;;173895:73:0;;22983:2:1;173895:73:0::1;::::0;::::1;22965:21:1::0;23022:2;23002:18;;;22995:30;23061:34;23041:18;;;23034:62;-1:-1:-1;;;23112:18:1;;;23105:36;23158:19;;173895:73:0::1;22781:402:1::0;173895:73:0::1;173979:28;173998:8;173979:18;:28::i;103034:127::-:0;103123:19;;103141:1;103123:19;;;103034:127::o;64261:215::-;64363:4;-1:-1:-1;;;;;;64387:41:0;;-1:-1:-1;;;64387:41:0;;:81;;;64432:36;64456:11;64432:23;:36::i;173073:132::-;172981:6;;-1:-1:-1;;;;;172981:6:0;18323:10;173137:23;173129:68;;;;-1:-1:-1;;;173129:68:0;;23390:2:1;173129:68:0;;;23372:21:1;;;23409:18;;;23402:30;23468:34;23448:18;;;23441:62;23520:18;;173129:68:0;23188:356:1;65623:332:0;65339:5;-1:-1:-1;;;;;65726:33:0;;;;65718:88;;;;-1:-1:-1;;;65718:88:0;;23751:2:1;65718:88:0;;;23733:21:1;23790:2;23770:18;;;23763:30;23829:34;23809:18;;;23802:62;-1:-1:-1;;;23880:18:1;;;23873:40;23930:19;;65718:88:0;23549:406:1;65718:88:0;-1:-1:-1;;;;;65825:22:0;;65817:60;;;;-1:-1:-1;;;65817:60:0;;24162:2:1;65817:60:0;;;24144:21:1;24201:2;24181:18;;;24174:30;24240:27;24220:18;;;24213:55;24285:18;;65817:60:0;23960:349:1;65817:60:0;65912:35;;;;;;;;;-1:-1:-1;;;;;65912:35:0;;;;;;-1:-1:-1;;;;;65912:35:0;;;;;;;;;;-1:-1:-1;;;65890:57:0;;;;:19;:57;65623:332::o;48976:135::-;42644:4;42242:16;;;:7;:16;;;;;;-1:-1:-1;;;;;42242:16:0;49050:53;;;;-1:-1:-1;;;49050:53:0;;18403:2:1;49050:53:0;;;18385:21:1;18442:2;18422:18;;;18415:30;-1:-1:-1;;;18461:18:1;;;18454:54;18525:18;;49050:53:0;18201:348:1;76941:647:0;73593:42;77132:45;:49;77128:453;;77431:67;;-1:-1:-1;;;77431:67:0;;77482:4;77431:67;;;24526:34:1;-1:-1:-1;;;;;24596:15:1;;24576:18;;;24569:43;73593:42:0;;77431;;24461:18:1;;77431:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77426:144;;77526:28;;-1:-1:-1;;;77526:28:0;;-1:-1:-1;;;;;2428:32:1;;77526:28:0;;;2410:51:1;2383:18;;77526:28:0;2264:203:1;38675:416:0;38756:13;38772:23;38787:7;38772:14;:23::i;:::-;38756:39;;38820:5;-1:-1:-1;;;;;38814:11:0;:2;-1:-1:-1;;;;;38814:11:0;;38806:57;;;;-1:-1:-1;;;38806:57:0;;25075:2:1;38806:57:0;;;25057:21:1;25114:2;25094:18;;;25087:30;25153:34;25133:18;;;25126:62;-1:-1:-1;;;25204:18:1;;;25197:31;25245:19;;38806:57:0;24873:397:1;38806:57:0;18323:10;-1:-1:-1;;;;;38898:21:0;;;;:62;;-1:-1:-1;38923:37:0;38940:5;18323:10;39626:164;:::i;38923:37::-;38876:173;;;;-1:-1:-1;;;38876:173:0;;25477:2:1;38876:173:0;;;25459:21:1;25516:2;25496:18;;;25489:30;25555:34;25535:18;;;25528:62;25626:31;25606:18;;;25599:59;25675:19;;38876:173:0;25275:425:1;38876:173:0;39062:21;39071:2;39075:7;39062:8;:21::i;182191:784::-;182270:12;;;;182265:41;;182291:15;;-1:-1:-1;;;182291:15:0;;;;;;;;;;;182265:41;182322:9;182317:525;182341:8;:15;182337:1;:19;182317:525;;;182378:15;182396:8;182405:1;182396:11;;;;;;;;:::i;:::-;;;;;;;182378:29;;182427:9;182439:1;182443;182439:5;;;;:::i;:::-;182427:17;;182422:138;182450:8;:15;182446:1;:19;182422:138;;;182506:8;182515:1;182506:11;;;;;;;;:::i;:::-;;;;;;;182495:7;:22;182491:53;;182526:18;;-1:-1:-1;;;182526:18:0;;;;;;;;;;;182491:53;182467:3;;;;:::i;:::-;;;;182422:138;;;-1:-1:-1;182598:10:0;182578:16;182586:7;182578;:16::i;:::-;-1:-1:-1;;;;;182578:30:0;;182574:58;;182617:15;;-1:-1:-1;;;182617:15:0;;;;;;;;;;;182574:58;182651:17;;;;:8;:17;;;;;;;;:26;;;;;;182647:144;;182702:5;182698:77;;;182714:15;;182721:7;;182714:15;;;;;182698:77;;;182758:17;;182767:7;;182758:17;;;;;182698:77;182805:17;;;;:8;:17;;;;;:25;;-1:-1:-1;;182805:25:0;;;;;;;182358:3;;;;:::i;:::-;;;;182317:525;;;;182878:23;182890:10;182878:11;:23::i;:::-;182864:10;182854:21;;;;:9;:21;;;;;;;:47;;;182917:50;182864:10;;182917:50;;;;160:25:1;;148:2;133:18;;14:177;182917:50:0;;;;;;;;182191:784;;:::o;39857:335::-;40052:41;18323:10;40071:12;40085:7;40052:18;:41::i;:::-;40044:99;;;;-1:-1:-1;;;40044:99:0;;;;;;;:::i;:::-;40156:28;40166:4;40172:2;40176:7;40156:9;:28::i;176812:293::-;176214:1;176946:7;;:19;176938:63;;;;-1:-1:-1;;;176938:63:0;;26321:2:1;176938:63:0;;;26303:21:1;26360:2;26340:18;;;26333:30;26399:33;26379:18;;;26372:61;26450:18;;176938:63:0;26119:355:1;176938:63:0;176214:1;177079:7;:18;176812:293::o;195553:190::-;195634:12;195652:9;-1:-1:-1;;;;;195652:14:0;195674:6;195652:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;195633:52;;;195704:7;195696:39;;;;-1:-1:-1;;;195696:39:0;;26891:2:1;195696:39:0;;;26873:21:1;26930:2;26910:18;;;26903:30;-1:-1:-1;;;26949:18:1;;;26942:49;27008:18;;195696:39:0;26689:343:1;43480:110:0;43556:26;43566:2;43570:7;43556:26;;;;;;;;;;;;:9;:26::i;90710:314::-;90763:7;90795:4;-1:-1:-1;;;;;90804:12:0;90787:29;;:66;;;;;90837:16;90820:13;:33;90787:66;90783:234;;;-1:-1:-1;90877:24:0;;90710:314::o;90783:234::-;-1:-1:-1;91213:73:0;;;90963:10;91213:73;;;;29453:25:1;;;;90975:12:0;29494:18:1;;;29487:34;90989:15:0;29537:18:1;;;29530:34;91257:13:0;29580:18:1;;;29573:34;91280:4:0;29623:19:1;;;;29616:61;;;;91213:73:0;;;;;;;;;;29425:19:1;;;;91213:73:0;;;91203:84;;;;;;169281:106::o;141976:785::-;142076:7;142118:12;142104:11;:26;142096:71;;;;-1:-1:-1;;;142096:71:0;;27239:2:1;142096:71:0;;;27221:21:1;;;27258:18;;;27251:30;27317:34;27297:18;;;27290:62;27369:18;;142096:71:0;27037:356:1;142096:71:0;142178:10;142191:30;142209:11;142191:17;:30::i;:::-;142248:24;;142178:43;;-1:-1:-1;142234:11:0;142248:24;142352:1;142346:7;;142342:249;;;142370:11;142390:14;142400:3;142390:9;:14::i;:::-;142384:20;;:3;:20;:::i;:::-;147734:25;147796:20;;;147862:4;147849:18;;142370:34;;-1:-1:-1;147845:28:0;;142429:50;;;;;142423:56;;;;142419:161;;;142507:3;142500:10;;142419:161;;;142557:7;:3;142563:1;142557:7;:::i;:::-;142551:13;;142419:161;142355:236;142342:249;142603:11;142617:53;142636:4;142655:3;142660;142665:4;142617:18;:53::i;:::-;142603:67;-1:-1:-1;142690:8:0;;:63;;142705:41;142719:4;142738:7;142744:1;142738:3;:7;:::i;:::-;147734:25;147796:20;;;147862:4;147849:18;;;147845:28;;147649:242;142705:41;:48;;;;-1:-1:-1;;;;;142705:48:0;142690:63;;;142701:1;142690:63;-1:-1:-1;;;;;142683:70:0;;141976:785;-1:-1:-1;;;;;;;;141976:785:0:o;181156:106::-;181214:7;181245:1;181241;:5;:13;;181253:1;181241:13;;;-1:-1:-1;181249:1:0;;181156:106;-1:-1:-1;181156:106:0:o;40263:185::-;40401:39;40418:4;40424:2;40428:7;40401:39;;;;;;;;;;;;:16;:39::i;61501:242::-;61619:41;18323:10;61638:12;18243:98;61619:41;61611:99;;;;-1:-1:-1;;;61611:99:0;;;;;;;:::i;:::-;61721:14;61727:7;61721:5;:14::i;195751:175::-;195884:33;;-1:-1:-1;;27575:2:1;27571:15;;;27567:53;195884:33:0;;;27555:66:1;27637:12;;;27630:28;;;195847:7:0;;27674:12:1;;195884:33:0;;;;;;;;;;;;;195874:44;;;;;;195867:51;;195751:175;;;;:::o;196134:192::-;196244:4;196268:50;196287:11;196300;;196313:4;196268:18;:50::i;166737:319::-;-1:-1:-1;;;;;165623:20:0;;;166820:19;165623:20;;;:11;:20;;;;;;;;166871:32;;;-1:-1:-1;;;;;;166871:32:0;;;;;;;166921:48;;165623:20;;;;;166871:32;165623:20;;;;166921:48;;166820:19;166921:48;166980:68;166999:11;167012:9;167023:24;167039:7;167023:15;:24::i;:::-;166980:18;:68::i;174175:191::-;174268:6;;;-1:-1:-1;;;;;174285:17:0;;;-1:-1:-1;;;;;;174285:17:0;;;;;;;174318:40;;174268:6;;;174285:17;174268:6;;174318:40;;174249:16;;174318:40;174238:128;174175:191;:::o;195934:192::-;196044:4;196068:50;196087:11;196100;;196113:4;196068:18;:50::i;143746:208::-;143841:24;;143807:7;;143883:8;;:63;;143898:41;143912:4;143931:7;143937:1;143931:3;:7;:::i;143898:41::-;:48;;;;-1:-1:-1;;;;;143898:48:0;143876:70;143746:208;-1:-1:-1;;;143746:208:0:o;39400:155::-;39495:52;18323:10;39528:8;39538;39495:18;:52::i;177751:384::-;177832:12;;;;177828:40;;;177853:15;;-1:-1:-1;;;177853:15:0;;;;;;;;;;;177828:40;177884:9;177879:249;177903:5;:12;177899:1;:16;177879:249;;;177937:15;177955:9;177963:1;177955:5;:9;:::i;:::-;177937:27;;177979:11;177999:5;178005:1;177999:8;;;;;;;;:::i;:::-;;;;;;;178049:18;;;;:9;:18;;;;;;;;178028:47;;177993:15;178049:18;;;27863:36:1;;177999:8:0;;;;;27915:18:1;;;27908:45;;;177999:8:0;;-1:-1:-1;178049:18:0;;178028:47;;27836:18:1;178028:47:0;;;;;;;178090:18;;;;:9;:18;;;;;;:26;;-1:-1:-1;;178090:26:0;;;;;;;;;;;177917:3;;;;:::i;:::-;;;;177879:249;;178143:102;178191:16;;178202:4;722:41:1;;178191:16:0;;710:2:1;695:18;178191:16:0;;;;;;;178218:12;:19;;-1:-1:-1;;178218:19:0;178233:4;178218:19;;;178143:102::o;40519:322::-;40693:41;18323:10;40726:7;40693:18;:41::i;:::-;40685:99;;;;-1:-1:-1;;;40685:99:0;;;;;;;:::i;:::-;40795:38;40809:4;40815:2;40819:7;40828:4;40795:13;:38::i;91937:167::-;92014:7;92041:55;92063:20;:18;:20::i;:::-;92085:10;92041:21;:55::i;85502:279::-;85630:7;85651:17;85670:18;85692:25;85703:4;85709:1;85712;85715;85692:10;:25::i;:::-;85650:67;;;;85728:18;85740:5;85728:11;:18::i;:::-;-1:-1:-1;85764:9:0;85502:279;-1:-1:-1;;;;;85502:279:0:o;168747:207::-;-1:-1:-1;;;;;168868:14:0;;168807:15;168868:14;;;:7;:14;;;;;103004;;103141:1;103123:19;;;;103004:14;168929:17;168824:130;168747:207;;;:::o;31848:716::-;31904:13;31955:14;31972:17;31983:5;31972:10;:17::i;:::-;31992:1;31972:21;31955:38;;32008:20;32042:6;-1:-1:-1;;;;;32031:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;32031:18:0;-1:-1:-1;32008:41:0;-1:-1:-1;32173:28:0;;;32189:2;32173:28;32230:288;-1:-1:-1;;32262:5:0;-1:-1:-1;;;32399:2:0;32388:14;;32383:30;32262:5;32370:44;32460:2;32451:11;;;-1:-1:-1;32481:21:0;32230:288;32481:21;-1:-1:-1;32539:6:0;31848:716;-1:-1:-1;;;31848:716:0:o;189062:276::-;189178:18;42242:16;;;:7;:16;;;;;;189283:10;;-1:-1:-1;;;;;42242:16:0;;;;189283:10;189231:48;42242:16;;189269:9;189231:16;:48::i;:::-;-1:-1:-1;;;;;189231:62:0;;189227:103;;189315:15;;-1:-1:-1;;;189315:15:0;;;;;;;;;;;45753:783;45813:13;45829:23;45844:7;45829:14;:23::i;:::-;45813:39;;45865:51;45886:5;45901:1;45905:7;45914:1;45865:20;:51::i;:::-;46029:23;46044:7;46029:14;:23::i;:::-;46100:24;;;;:15;:24;;;;;;;;46093:31;;-1:-1:-1;;;;;;46093:31:0;;;;;;-1:-1:-1;;;;;46345:16:0;;;;;:9;:16;;;;;:21;;-1:-1:-1;;46345:21:0;;;46395:16;;;:7;:16;;;;;;46388:23;;;;;;;46429:36;46021:31;;-1:-1:-1;46116:7:0;;46429:36;;46100:24;;46429:36;46478:50;46498:5;46513:1;46517:7;46526:1;46478:19;:50::i;184401:195::-;184528:4;184552:36;184576:11;184552:23;:36::i;48255:174::-;48330:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;48330:29:0;-1:-1:-1;;;;;48330:29:0;;;;;;;;:24;;48384:23;48330:24;48384:14;:23::i;:::-;-1:-1:-1;;;;;48375:46:0;;;;;;;;;;;48255:174;;:::o;42874:264::-;42967:4;42984:13;43000:23;43015:7;43000:14;:23::i;:::-;42984:39;;43053:5;-1:-1:-1;;;;;43042:16:0;:7;-1:-1:-1;;;;;43042:16:0;;:52;;;-1:-1:-1;;;;;;39747:25:0;;;39723:4;39747:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;43062:32;43042:87;;;;43122:7;-1:-1:-1;;;;;43098:31:0;:20;43110:7;43098:11;:20::i;:::-;-1:-1:-1;;;;;43098:31:0;;43034:96;42874:264;-1:-1:-1;;;;42874:264:0:o;46873:1263::-;47032:4;-1:-1:-1;;;;;47005:31:0;:23;47020:7;47005:14;:23::i;:::-;-1:-1:-1;;;;;47005:31:0;;46997:81;;;;-1:-1:-1;;;46997:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;47097:16:0;;47089:65;;;;-1:-1:-1;;;47089:65:0;;28572:2:1;47089:65:0;;;28554:21:1;28611:2;28591:18;;;28584:30;28650:34;28630:18;;;28623:62;-1:-1:-1;;;28701:18:1;;;28694:34;28745:19;;47089:65:0;28370:400:1;47089:65:0;47167:42;47188:4;47194:2;47198:7;47207:1;47167:20;:42::i;:::-;47339:4;-1:-1:-1;;;;;47312:31:0;:23;47327:7;47312:14;:23::i;:::-;-1:-1:-1;;;;;47312:31:0;;47304:81;;;;-1:-1:-1;;;47304:81:0;;;;;;;:::i;:::-;47457:24;;;;:15;:24;;;;;;;;47450:31;;-1:-1:-1;;;;;;47450:31:0;;;;;;-1:-1:-1;;;;;47933:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;47933:20:0;;;47968:13;;;;;;;;;:18;;47450:31;47968:18;;;48008:16;;;:7;:16;;;;;;:21;;;;;;;;;;48047:27;;47473:7;;48047:27;;;48087:41;48107:4;48113:2;48117:7;48126:1;48087:19;:41::i;43817:319::-;43946:18;43952:2;43956:7;43946:5;:18::i;:::-;43997:53;44028:1;44032:2;44036:7;44045:4;43997:22;:53::i;:::-;43975:153;;;;-1:-1:-1;;;43975:153:0;;;;;;;:::i;119305:190::-;119361:6;119397:16;119388:25;;;119380:76;;;;-1:-1:-1;;;119380:76:0;;29890:2:1;119380:76:0;;;29872:21:1;29929:2;29909:18;;;29902:30;29968:34;29948:18;;;29941:62;-1:-1:-1;;;30019:18:1;;;30012:36;30065:19;;119380:76:0;29688:402:1;119380:76:0;-1:-1:-1;119481:5:0;119305:190::o;24933:1673::-;24981:7;25005:1;25010;25005:6;25001:47;;-1:-1:-1;25035:1:0;;24933:1673;-1:-1:-1;24933:1673:0:o;25001:47::-;25739:14;25773:1;25762:7;25767:1;25762:4;:7::i;:::-;:12;;25756:1;:19;;25739:36;;26241:1;26230:6;26226:1;:10;;;;;:::i;:::-;;26217:6;:19;26216:26;;26207:35;;26291:1;26280:6;26276:1;:10;;;;;:::i;:::-;;26267:6;:19;26266:26;;26257:35;;26341:1;26330:6;26326:1;:10;;;;;:::i;:::-;;26317:6;:19;26316:26;;26307:35;;26391:1;26380:6;26376:1;:10;;;;;:::i;:::-;;26367:6;:19;26366:26;;26357:35;;26441:1;26430:6;26426:1;:10;;;;;:::i;:::-;;26417:6;:19;26416:26;;26407:35;;26491:1;26480:6;26476:1;:10;;;;;:::i;:::-;;26467:6;:19;26466:26;;26457:35;;26541:1;26530:6;26526:1;:10;;;;;:::i;:::-;;26517:6;:19;26516:26;;26507:35;;26564:23;26568:6;26580;26576:1;:10;;;;;:::i;:::-;;26564:3;:23::i;146247:453::-;146406:7;146426:245;146439:4;146433:3;:10;146426:245;;;146460:11;146474:23;146487:3;146492:4;146474:12;:23::i;:::-;147734:25;147796:20;;;147862:4;147849:18;;146460:37;;-1:-1:-1;146516:43:0;;;;147845:28;;146516:37;;;:43;146512:148;;;146587:3;146580:10;;146512:148;;;146637:7;:3;146643:1;146637:7;:::i;:::-;146631:13;;146512:148;146445:226;146426:245;;93687:190;93812:4;93865;93836:25;93849:5;93856:4;93836:12;:25::i;:::-;:33;;93687:190;-1:-1:-1;;;;93687:190:0:o;171024:135::-;171106:7;171133:18;171143:7;171133:9;:18::i;167784:625::-;167919:2;-1:-1:-1;;;;;167911:10:0;:4;-1:-1:-1;;;;;167911:10:0;;;:24;;;;;167934:1;167925:6;:10;167911:24;167907:495;;;-1:-1:-1;;;;;167956:18:0;;;167952:218;;-1:-1:-1;;;;;168034:26:0;;167996:16;168034:26;;;:20;:26;;;;;167996:16;;168034:50;;168066:9;168077:6;168034:31;:50::i;:::-;167995:89;;;;168129:4;-1:-1:-1;;;;;168108:46:0;;168135:8;168145;168108:46;;;;;;30269:25:1;;;30325:2;30310:18;;30303:34;30257:2;30242:18;;30095:248;168108:46:0;;;;;;;;167976:194;;167952:218;-1:-1:-1;;;;;168188:16:0;;;168184:207;;-1:-1:-1;;;;;168264:24:0;;168226:16;168264:24;;;:20;:24;;;;;168226:16;;168264:43;;168294:4;168300:6;168264:29;:43::i;:::-;168225:82;;;;168352:2;-1:-1:-1;;;;;168331:44:0;;168356:8;168366;168331:44;;;;;;30269:25:1;;;30325:2;30310:18;;30303:34;30257:2;30242:18;;30095:248;168331:44:0;;;;;;;;168206:185;;167784:625;;;:::o;48572:315::-;48727:8;-1:-1:-1;;;;;48718:17:0;:5;-1:-1:-1;;;;;48718:17:0;;48710:55;;;;-1:-1:-1;;;48710:55:0;;30550:2:1;48710:55:0;;;30532:21:1;30589:2;30569:18;;;30562:30;30628:27;30608:18;;;30601:55;30673:18;;48710:55:0;30348:349:1;48710:55:0;-1:-1:-1;;;;;48776:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;48776:46:0;;;;;;;;;;48838:41;;722::1;;;48838::0;;695:18:1;48838:41:0;;;;;;;48572:315;;;:::o;41722:313::-;41878:28;41888:4;41894:2;41898:7;41878:9;:28::i;:::-;41925:47;41948:4;41954:2;41958:7;41967:4;41925:22;:47::i;:::-;41917:110;;;;-1:-1:-1;;;41917:110:0;;;;;;;:::i;87193:196::-;87323:57;;-1:-1:-1;;;87323:57:0;;;30960:27:1;31003:11;;;30996:27;;;31039:12;;;31032:28;;;87286:7:0;;31076:12:1;;87323:57:0;30702:392:1;83843:1520:0;83974:7;;84908:66;84895:79;;84891:163;;;-1:-1:-1;85007:1:0;;-1:-1:-1;85011:30:0;84991:51;;84891:163;85168:24;;;85151:14;85168:24;;;;;;;;;31326:25:1;;;31399:4;31387:17;;31367:18;;;31360:45;;;;31421:18;;;31414:34;;;31464:18;;;31457:34;;;85168:24:0;;31298:19:1;;85168:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;85168:24:0;;-1:-1:-1;;85168:24:0;;;-1:-1:-1;;;;;;;85207:20:0;;85203:103;;85260:1;85264:29;85244:50;;;;;;;85203:103;85326:6;-1:-1:-1;85334:20:0;;-1:-1:-1;83843:1520:0;;;;;;;;:::o;79235:521::-;79313:20;79304:5;:29;;;;;;;;:::i;:::-;;79300:449;;79235:521;:::o;79300:449::-;79411:29;79402:5;:38;;;;;;;;:::i;:::-;;79398:351;;79457:34;;-1:-1:-1;;;79457:34:0;;31836:2:1;79457:34:0;;;31818:21:1;31875:2;31855:18;;;31848:30;31914:26;31894:18;;;31887:54;31958:18;;79457:34:0;31634:348:1;79398:351:0;79522:35;79513:5;:44;;;;;;;;:::i;:::-;;79509:240;;79574:41;;-1:-1:-1;;;79574:41:0;;32189:2:1;79574:41:0;;;32171:21:1;32228:2;32208:18;;;32201:30;32267:33;32247:18;;;32240:61;32318:18;;79574:41:0;31987:355:1;79509:240:0;79646:30;79637:5;:39;;;;;;;;:::i;:::-;;79633:116;;79693:44;;-1:-1:-1;;;79693:44:0;;32549:2:1;79693:44:0;;;32531:21:1;32588:2;32568:18;;;32561:30;32627:34;32607:18;;;32600:62;-1:-1:-1;;;32678:18:1;;;32671:32;32720:19;;79693:44:0;32347:398:1;28642:922:0;28695:7;;-1:-1:-1;;;28773:15:0;;28769:102;;-1:-1:-1;;;28809:15:0;;;-1:-1:-1;28853:2:0;28843:12;28769:102;28898:6;28889:5;:15;28885:102;;28934:6;28925:15;;;-1:-1:-1;28969:2:0;28959:12;28885:102;29014:6;29005:5;:15;29001:102;;29050:6;29041:15;;;-1:-1:-1;29085:2:0;29075:12;29001:102;29130:5;29121;:14;29117:99;;29165:5;29156:14;;;-1:-1:-1;29199:1:0;29189:11;29117:99;29243:5;29234;:14;29230:99;;29278:5;29269:14;;;-1:-1:-1;29312:1:0;29302:11;29230:99;29356:5;29347;:14;29343:99;;29391:5;29382:14;;;-1:-1:-1;29425:1:0;29415:11;29343:99;29469:5;29460;:14;29456:66;;29505:1;29495:11;29550:6;28642:922;-1:-1:-1;;28642:922:0:o;189346:317::-;189571:40;;;189582:7;189571:40;;;32952:25:1;32993:18;;;32986:34;;;-1:-1:-1;;;;;33056:32:1;;33036:18;;;33029:60;189489:7:0;;189529:126;;32925:18:1;;189571:40:0;;;;;;;;;;;;189561:51;;;;;;189631:9;189529:13;:126::i;199044:274::-;199254:56;199281:4;199287:2;199291:7;199300:9;199254:26;:56::i;199326:247::-;199510:55;199536:4;199542:2;199546:7;199555:9;199510:25;:55::i;54898:224::-;55000:4;-1:-1:-1;;;;;;55024:50:0;;-1:-1:-1;;;55024:50:0;;:90;;;55078:36;55102:11;55078:23;:36::i;44472:942::-;-1:-1:-1;;;;;44552:16:0;;44544:61;;;;-1:-1:-1;;;44544:61:0;;33302:2:1;44544:61:0;;;33284:21:1;;;33321:18;;;33314:30;33380:34;33360:18;;;33353:62;33432:18;;44544:61:0;33100:356:1;44544:61:0;42644:4;42242:16;;;:7;:16;;;;;;-1:-1:-1;;;;;42242:16:0;42668:31;44616:58;;;;-1:-1:-1;;;44616:58:0;;33663:2:1;44616:58:0;;;33645:21:1;33702:2;33682:18;;;33675:30;33741;33721:18;;;33714:58;33789:18;;44616:58:0;33461:352:1;44616:58:0;44687:48;44716:1;44720:2;44724:7;44733:1;44687:20;:48::i;:::-;42644:4;42242:16;;;:7;:16;;;;;;-1:-1:-1;;;;;42242:16:0;42668:31;44825:58;;;;-1:-1:-1;;;44825:58:0;;33663:2:1;44825:58:0;;;33645:21:1;33702:2;33682:18;;;33675:30;33741;33721:18;;;33714:58;33789:18;;44825:58:0;33461:352:1;44825:58:0;-1:-1:-1;;;;;45232:13:0;;;;;;:9;:13;;;;;;;;:18;;45249:1;45232:18;;;45274:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;45274:21:0;;;;;45313:33;45282:7;;45232:13;;45313:33;;45232:13;;45313:33;45359:47;45387:1;45391:2;45395:7;45404:1;45359:19;:47::i;49675:853::-;49829:4;-1:-1:-1;;;;;49850:13:0;;9650:19;:23;49846:675;;49886:71;;-1:-1:-1;;;49886:71:0;;-1:-1:-1;;;;;49886:36:0;;;;;:71;;18323:10;;49937:4;;49943:7;;49952:4;;49886:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;49886:71:0;;;;;;;;-1:-1:-1;;49886:71:0;;;;;;;;;;;;:::i;:::-;;;49882:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50127:6;:13;50144:1;50127:18;50123:328;;50170:60;;-1:-1:-1;;;50170:60:0;;;;;;;:::i;50123:328::-;50401:6;50395:13;50386:6;50382:2;50378:15;50371:38;49882:584;-1:-1:-1;;;;;;50008:51:0;-1:-1:-1;;;50008:51:0;;-1:-1:-1;50001:58:0;;49846:675;-1:-1:-1;50505:4:0;50498:11;;27083:1019;27135:7;;27222:3;27213:12;;;:16;27209:102;;27260:3;27250:13;;;;27282;27209:102;27338:2;27329:11;;;:15;27325:99;;27375:2;27365:12;;;;27396;27325:99;27451:2;27442:11;;;:15;27438:99;;27488:2;27478:12;;;;27509;27438:99;27564:2;27555:11;;;:15;27551:99;;27601:2;27591:12;;;;27622;27551:99;27677:1;27668:10;;;:14;27664:96;;27713:1;27703:11;;;;27733;27664:96;27787:1;27778:10;;;:14;27774:96;;27823:1;27813:11;;;;27843;27774:96;27897:1;27888:10;;;:14;27884:96;;27933:1;27923:11;;;;27953;27884:96;28007:1;27998:10;;;:14;27994:66;;28043:1;28033:11;28088:6;27083:1019;-1:-1:-1;;27083:1019:0:o;19109:106::-;19167:7;19198:1;19194;:5;:13;;19206:1;19194:13;;19334:156;19396:7;19471:11;19481:1;19472:5;;;19471:11;:::i;:::-;19461:21;;19462:5;;;19461:21;:::i;94554:296::-;94637:7;94680:4;94637:7;94695:118;94719:5;:12;94715:1;:16;94695:118;;;94768:33;94778:12;94792:5;94798:1;94792:8;;;;;;;;:::i;:::-;;;;;;;94768:9;:33::i;:::-;94753:48;-1:-1:-1;94733:3:0;;;;:::i;:::-;;;;94695:118;;168523:103;168586:7;168613:5;168617:1;168613;:5;:::i;143385:236::-;143542:7;143551;143578:35;143583:4;143589:23;143592:12;143599:4;143592:6;:12::i;:::-;-1:-1:-1;;;;;143589:23:0;143606:5;143589:2;:23;;:::i;:::-;143578:4;:35::i;:::-;143571:42;;;;143385:236;;;;;;;:::o;168417:98::-;168475:7;168502:5;168506:1;168502;:5;:::i;82391:231::-;82469:7;82490:17;82509:18;82531:27;82542:4;82548:9;82531:10;:27::i;:::-;82489:69;;;;82569:18;82581:5;82569:11;:18::i;184131:262::-;184329:56;184356:4;184362:2;184366:7;184375:9;184329:26;:56::i;170655:296::-;170831:41;170852:4;170858:2;170862:9;170831:20;:41::i;:::-;170883:60;194065:904;36717:305;36819:4;-1:-1:-1;;;;;;36856:40:0;;-1:-1:-1;;;36856:40:0;;:105;;-1:-1:-1;;;;;;;36913:48:0;;-1:-1:-1;;;36913:48:0;36856:105;:158;;;-1:-1:-1;;;;;;;;;;34800:40:0;;;36978:36;34691:157;101594:149;101657:7;101688:1;101684;:5;:51;;101819:13;101913:15;;;101949:4;101942:15;;;101996:4;101980:21;;101684:51;;;101819:13;101913:15;;;101949:4;101942:15;;;101996:4;101980:21;;101692:20;101751:268;142946:199;143015:7;;143051:86;143059:4;143078:31;143096:12;143078:17;:31::i;:::-;143111:25;143130:5;143111:18;:25::i;:::-;143051:7;:86::i;:::-;-1:-1:-1;;;;;143044:93:0;;;;;;;-1:-1:-1;142946:199:0;-1:-1:-1;;;142946:199:0:o;80842:747::-;80923:7;80932:12;80961:9;:16;80981:2;80961:22;80957:625;;81305:4;81290:20;;81284:27;81355:4;81340:20;;81334:27;81413:4;81398:20;;81392:27;81000:9;81384:36;81456:25;81467:4;81384:36;81284:27;81334;81456:10;:25::i;:::-;81449:32;;;;;;;;;80957:625;-1:-1:-1;81530:1:0;;-1:-1:-1;81534:35:0;81514:56;;56035:915;56212:61;56239:4;56245:2;56249:12;56263:9;56212:26;:61::i;:::-;56302:1;56290:9;:13;56286:222;;;56433:63;;-1:-1:-1;;;56433:63:0;;34768:2:1;56433:63:0;;;34750:21:1;34807:2;34787:18;;;34780:30;34846:34;34826:18;;;34819:62;-1:-1:-1;;;34897:18:1;;;34890:51;34958:19;;56433:63:0;34566:417:1;56286:222:0;56538:12;-1:-1:-1;;;;;56567:18:0;;56563:187;;56602:40;56634:7;57777:10;:17;;57750:24;;;;:15;:24;;;;;:44;;;57805:24;;;;;;;;;;;;57673:164;56602:40;56563:187;;;56672:2;-1:-1:-1;;;;;56664:10:0;:4;-1:-1:-1;;;;;56664:10:0;;56660:90;;56691:47;56724:4;56730:7;56691:32;:47::i;:::-;-1:-1:-1;;;;;56764:16:0;;56760:183;;56797:45;56834:7;56797:36;:45::i;:::-;56760:183;;;56870:4;-1:-1:-1;;;;;56864:10:0;:2;-1:-1:-1;;;;;56864:10:0;;56860:83;;56891:40;56919:2;56923:7;56891:27;:40::i;167296:397::-;-1:-1:-1;;;;;167434:18:0;;167430:87;;167469:36;:17;167492:4;167498:6;167469:22;:36::i;:::-;;;167430:87;-1:-1:-1;;;;;167531:16:0;;167527:90;;167564:41;:17;167587:9;167598:6;167564:22;:41::i;:::-;;;167527:90;-1:-1:-1;;;;;165623:20:0;;;165596:7;165623:20;;;:11;:20;;;;;;;;;;;;;;;167627:58;;165623:20;;;;;167678:6;167627:18;:58::i;106469:195::-;106526:7;-1:-1:-1;;;;;106554:26:0;;;106546:78;;;;-1:-1:-1;;;106546:78:0;;35190:2:1;106546:78:0;;;35172:21:1;35229:2;35209:18;;;35202:30;35268:34;35248:18;;;35241:62;-1:-1:-1;;;35319:18:1;;;35312:37;35366:19;;106546:78:0;34988:403:1;145004:904:0;145169:11;;145126:7;;;;145197;;145193:708;;145274:22;145299:28;145313:4;145319:7;145325:1;145319:3;:7;:::i;145299:28::-;145274:53;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;145274:53:0;;;;;;;-1:-1:-1;145405:24:0;;;-1:-1:-1;145405:24:0;145397:60;;;;-1:-1:-1;;;145397:60:0;;35598:2:1;145397:60:0;;;35580:21:1;35637:2;35617:18;;;35610:30;35676:25;35656:18;;;35649:53;35719:18;;145397:60:0;35396:347:1;145397:60:0;145524:17;;:24;;;;;;;145520:206;;145607:5;145569:28;145583:4;145589:7;145595:1;145589:3;:7;:::i;145569:28::-;:43;;-1:-1:-1;;;;;145569:43:0;;;;;;;;;;;;;;;;145520:206;;;145663:46;;;;;;;;;;;;;;;-1:-1:-1;;;;;145663:46:0;;;;;;;;;;145653:57;;;;;;;-1:-1:-1;145653:57:0;;;;;;;;;;;;;;;;;;;;;;;;;145520:206;145748:11;;;;-1:-1:-1;145761:5:0;;-1:-1:-1;145740:27:0;;-1:-1:-1;145740:27:0;145193:708;-1:-1:-1;;145810:46:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;145810:46:0;;;;;;;;;;145800:57;;;;;;;-1:-1:-1;145800:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;145849:5:0;145872:17;;51260:410;51450:1;51438:9;:13;51434:229;;;-1:-1:-1;;;;;51472:18:0;;;51468:87;;-1:-1:-1;;;;;51511:15:0;;;;;;:9;:15;;;;;:28;;51530:9;;51511:15;:28;;51530:9;;51511:28;:::i;:::-;;;;-1:-1:-1;;51468:87:0;-1:-1:-1;;;;;51573:16:0;;;51569:83;;-1:-1:-1;;;;;51610:13:0;;;;;;:9;:13;;;;;:26;;51627:9;;51610:13;:26;;51627:9;;51610:26;:::i;:::-;;;;-1:-1:-1;;51260:410:0;;;;:::o;58464:988::-;58730:22;58780:1;58755:22;58772:4;58755:16;:22::i;:::-;:26;;;;:::i;:::-;58792:18;58813:26;;;:17;:26;;;;;;58730:51;;-1:-1:-1;58946:28:0;;;58942:328;;-1:-1:-1;;;;;59013:18:0;;58991:19;59013:18;;;:12;:18;;;;;;;;:34;;;;;;;;;59064:30;;;;;;:44;;;59181:30;;:17;:30;;;;;:43;;;58942:328;-1:-1:-1;59366:26:0;;;;:17;:26;;;;;;;;59359:33;;;-1:-1:-1;;;;;59410:18:0;;;;;:12;:18;;;;;:34;;;;;;;59403:41;58464:988::o;59747:1079::-;60025:10;:17;60000:22;;60025:21;;60045:1;;60025:21;:::i;:::-;60057:18;60078:24;;;:15;:24;;;;;;60451:10;:26;;60000:46;;-1:-1:-1;60078:24:0;;60000:46;;60451:26;;;;;;:::i;:::-;;;;;;;;;60429:48;;60515:11;60490:10;60501;60490:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;60595:28;;;:15;:28;;;;;;;:41;;;60767:24;;;;;60760:31;60802:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;59818:1008;;;59747:1079;:::o;57251:221::-;57336:14;57353:20;57370:2;57353:16;:20::i;:::-;-1:-1:-1;;;;;57384:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;57429:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;57251:221:0:o;196:131:1:-;-1:-1:-1;;;;;;270:32:1;;260:43;;250:71;;317:1;314;307:12;332:245;390:6;443:2;431:9;422:7;418:23;414:32;411:52;;;459:1;456;449:12;411:52;498:9;485:23;517:30;541:5;517:30;:::i;774:173::-;842:20;;-1:-1:-1;;;;;891:31:1;;881:42;;871:70;;937:1;934;927:12;871:70;774:173;;;:::o;952:366::-;1019:6;1027;1080:2;1068:9;1059:7;1055:23;1051:32;1048:52;;;1096:1;1093;1086:12;1048:52;1119:29;1138:9;1119:29;:::i;:::-;1109:39;;1198:2;1187:9;1183:18;1170:32;-1:-1:-1;;;;;1235:5:1;1231:38;1224:5;1221:49;1211:77;;1284:1;1281;1274:12;1211:77;1307:5;1297:15;;;952:366;;;;;:::o;1323:250::-;1408:1;1418:113;1432:6;1429:1;1426:13;1418:113;;;1508:11;;;1502:18;1489:11;;;1482:39;1454:2;1447:10;1418:113;;;-1:-1:-1;;1565:1:1;1547:16;;1540:27;1323:250::o;1578:271::-;1620:3;1658:5;1652:12;1685:6;1680:3;1673:19;1701:76;1770:6;1763:4;1758:3;1754:14;1747:4;1740:5;1736:16;1701:76;:::i;:::-;1831:2;1810:15;-1:-1:-1;;1806:29:1;1797:39;;;;1838:4;1793:50;;1578:271;-1:-1:-1;;1578:271:1:o;1854:220::-;2003:2;1992:9;1985:21;1966:4;2023:45;2064:2;2053:9;2049:18;2041:6;2023:45;:::i;2079:180::-;2138:6;2191:2;2179:9;2170:7;2166:23;2162:32;2159:52;;;2207:1;2204;2197:12;2159:52;-1:-1:-1;2230:23:1;;2079:180;-1:-1:-1;2079:180:1:o;2472:254::-;2540:6;2548;2601:2;2589:9;2580:7;2576:23;2572:32;2569:52;;;2617:1;2614;2607:12;2569:52;2640:29;2659:9;2640:29;:::i;:::-;2630:39;2716:2;2701:18;;;;2688:32;;-1:-1:-1;;;2472:254:1:o;2731:186::-;2790:6;2843:2;2831:9;2822:7;2818:23;2814:32;2811:52;;;2859:1;2856;2849:12;2811:52;2882:29;2901:9;2882:29;:::i;2922:632::-;3093:2;3145:21;;;3215:13;;3118:18;;;3237:22;;;3064:4;;3093:2;3316:15;;;;3290:2;3275:18;;;3064:4;3359:169;3373:6;3370:1;3367:13;3359:169;;;3434:13;;3422:26;;3503:15;;;;3468:12;;;;3395:1;3388:9;3359:169;;;-1:-1:-1;3545:3:1;;2922:632;-1:-1:-1;;;;;;2922:632:1:o;3559:127::-;3620:10;3615:3;3611:20;3608:1;3601:31;3651:4;3648:1;3641:15;3675:4;3672:1;3665:15;3691:275;3762:2;3756:9;3827:2;3808:13;;-1:-1:-1;;3804:27:1;3792:40;;-1:-1:-1;;;;;3847:34:1;;3883:22;;;3844:62;3841:88;;;3909:18;;:::i;:::-;3945:2;3938:22;3691:275;;-1:-1:-1;3691:275:1:o;3971:946::-;4055:6;4086:2;4129;4117:9;4108:7;4104:23;4100:32;4097:52;;;4145:1;4142;4135:12;4097:52;4185:9;4172:23;-1:-1:-1;;;;;4255:2:1;4247:6;4244:14;4241:34;;;4271:1;4268;4261:12;4241:34;4309:6;4298:9;4294:22;4284:32;;4354:7;4347:4;4343:2;4339:13;4335:27;4325:55;;4376:1;4373;4366:12;4325:55;4412:2;4399:16;4434:2;4430;4427:10;4424:36;;;4440:18;;:::i;:::-;4486:2;4483:1;4479:10;4469:20;;4509:28;4533:2;4529;4525:11;4509:28;:::i;:::-;4571:15;;;4641:11;;;4637:20;;;4602:12;;;;4669:19;;;4666:39;;;4701:1;4698;4691:12;4666:39;4725:11;;;;4745:142;4761:6;4756:3;4753:15;4745:142;;;4827:17;;4815:30;;4778:12;;;;4865;;;;4745:142;;;4906:5;3971:946;-1:-1:-1;;;;;;;;3971:946:1:o;4922:328::-;4999:6;5007;5015;5068:2;5056:9;5047:7;5043:23;5039:32;5036:52;;;5084:1;5081;5074:12;5036:52;5107:29;5126:9;5107:29;:::i;:::-;5097:39;;5155:38;5189:2;5178:9;5174:18;5155:38;:::i;:::-;5145:48;;5240:2;5229:9;5225:18;5212:32;5202:42;;4922:328;;;;;:::o;5255:248::-;5323:6;5331;5384:2;5372:9;5363:7;5359:23;5355:32;5352:52;;;5400:1;5397;5390:12;5352:52;-1:-1:-1;;5423:23:1;;;5493:2;5478:18;;;5465:32;;-1:-1:-1;5255:248:1:o;6209:367::-;6272:8;6282:6;6336:3;6329:4;6321:6;6317:17;6313:27;6303:55;;6354:1;6351;6344:12;6303:55;-1:-1:-1;6377:20:1;;-1:-1:-1;;;;;6409:30:1;;6406:50;;;6452:1;6449;6442:12;6406:50;6489:4;6481:6;6477:17;6465:29;;6549:3;6542:4;6532:6;6529:1;6525:14;6517:6;6513:27;6509:38;6506:47;6503:67;;;6566:1;6563;6556:12;6581:579;6685:6;6693;6701;6709;6762:2;6750:9;6741:7;6737:23;6733:32;6730:52;;;6778:1;6775;6768:12;6730:52;6801:29;6820:9;6801:29;:::i;:::-;6791:39;;6877:2;6866:9;6862:18;6849:32;6839:42;;6932:2;6921:9;6917:18;6904:32;-1:-1:-1;;;;;6951:6:1;6948:30;6945:50;;;6991:1;6988;6981:12;6945:50;7030:70;7092:7;7083:6;7072:9;7068:22;7030:70;:::i;:::-;6581:579;;;;-1:-1:-1;7119:8:1;-1:-1:-1;;;;6581:579:1:o;7165:118::-;7251:5;7244:13;7237:21;7230:5;7227:32;7217:60;;7273:1;7270;7263:12;7288:241;7344:6;7397:2;7385:9;7376:7;7372:23;7368:32;7365:52;;;7413:1;7410;7403:12;7365:52;7452:9;7439:23;7471:28;7493:5;7471:28;:::i;7943:187::-;7992:4;-1:-1:-1;;;;;8017:6:1;8014:30;8011:56;;;8047:18;;:::i;:::-;-1:-1:-1;8113:2:1;8092:15;-1:-1:-1;;8088:29:1;8119:4;8084:40;;7943:187::o;8135:338::-;8200:5;8229:53;8245:36;8274:6;8245:36;:::i;:::-;8229:53;:::i;:::-;8220:62;;8305:6;8298:5;8291:21;8345:3;8336:6;8331:3;8327:16;8324:25;8321:45;;;8362:1;8359;8352:12;8321:45;8411:6;8406:3;8399:4;8392:5;8388:16;8375:43;8465:1;8458:4;8449:6;8442:5;8438:18;8434:29;8427:40;8135:338;;;;;:::o;8478:451::-;8547:6;8600:2;8588:9;8579:7;8575:23;8571:32;8568:52;;;8616:1;8613;8606:12;8568:52;8656:9;8643:23;-1:-1:-1;;;;;8681:6:1;8678:30;8675:50;;;8721:1;8718;8711:12;8675:50;8744:22;;8797:4;8789:13;;8785:27;-1:-1:-1;8775:55:1;;8826:1;8823;8816:12;8775:55;8849:74;8915:7;8910:2;8897:16;8892:2;8888;8884:11;8849:74;:::i;8934:511::-;9029:6;9037;9045;9098:2;9086:9;9077:7;9073:23;9069:32;9066:52;;;9114:1;9111;9104:12;9066:52;9137:29;9156:9;9137:29;:::i;:::-;9127:39;;9217:2;9206:9;9202:18;9189:32;-1:-1:-1;;;;;9236:6:1;9233:30;9230:50;;;9276:1;9273;9266:12;9230:50;9315:70;9377:7;9368:6;9357:9;9353:22;9315:70;:::i;:::-;8934:511;;9404:8;;-1:-1:-1;9289:96:1;;-1:-1:-1;;;;8934:511:1:o;9450:315::-;9515:6;9523;9576:2;9564:9;9555:7;9551:23;9547:32;9544:52;;;9592:1;9589;9582:12;9544:52;9615:29;9634:9;9615:29;:::i;:::-;9605:39;;9694:2;9683:9;9679:18;9666:32;9707:28;9729:5;9707:28;:::i;9770:221::-;9812:5;9865:3;9858:4;9850:6;9846:17;9842:27;9832:55;;9883:1;9880;9873:12;9832:55;9905:80;9981:3;9972:6;9959:20;9952:4;9944:6;9940:17;9905:80;:::i;9996:388::-;10073:6;10081;10134:2;10122:9;10113:7;10109:23;10105:32;10102:52;;;10150:1;10147;10140:12;10102:52;10186:9;10173:23;10163:33;;10247:2;10236:9;10232:18;10219:32;-1:-1:-1;;;;;10266:6:1;10263:30;10260:50;;;10306:1;10303;10296:12;10260:50;10329:49;10370:7;10361:6;10350:9;10346:22;10329:49;:::i;:::-;10319:59;;;9996:388;;;;;:::o;10389:537::-;10484:6;10492;10500;10508;10561:3;10549:9;10540:7;10536:23;10532:33;10529:53;;;10578:1;10575;10568:12;10529:53;10601:29;10620:9;10601:29;:::i;:::-;10591:39;;10649:38;10683:2;10672:9;10668:18;10649:38;:::i;:::-;10639:48;;10734:2;10723:9;10719:18;10706:32;10696:42;;10789:2;10778:9;10774:18;10761:32;-1:-1:-1;;;;;10808:6:1;10805:30;10802:50;;;10848:1;10845;10838:12;10802:50;10871:49;10912:7;10903:6;10892:9;10888:22;10871:49;:::i;:::-;10861:59;;;10389:537;;;;;;;:::o;10931:618::-;11033:6;11041;11049;11057;11065;11073;11126:3;11114:9;11105:7;11101:23;11097:33;11094:53;;;11143:1;11140;11133:12;11094:53;11166:29;11185:9;11166:29;:::i;:::-;11156:39;;11242:2;11231:9;11227:18;11214:32;11204:42;;11293:2;11282:9;11278:18;11265:32;11255:42;;11347:2;11336:9;11332:18;11319:32;11391:4;11384:5;11380:16;11373:5;11370:27;11360:55;;11411:1;11408;11401:12;11360:55;10931:618;;;;-1:-1:-1;10931:618:1;;11486:3;11471:19;;11458:33;;11538:3;11523:19;;;11510:33;;-1:-1:-1;10931:618:1;-1:-1:-1;;10931:618:1:o;11743:260::-;11811:6;11819;11872:2;11860:9;11851:7;11847:23;11843:32;11840:52;;;11888:1;11885;11878:12;11840:52;11911:29;11930:9;11911:29;:::i;:::-;11901:39;;11959:38;11993:2;11982:9;11978:18;11959:38;:::i;:::-;11949:48;;11743:260;;;;;:::o;12008:380::-;12087:1;12083:12;;;;12130;;;12151:61;;12205:4;12197:6;12193:17;12183:27;;12151:61;12258:2;12250:6;12247:14;12227:18;12224:38;12221:161;;12304:10;12299:3;12295:20;12292:1;12285:31;12339:4;12336:1;12329:15;12367:4;12364:1;12357:15;12393:407;12595:2;12577:21;;;12634:2;12614:18;;;12607:30;12673:34;12668:2;12653:18;;12646:62;-1:-1:-1;;;12739:2:1;12724:18;;12717:41;12790:3;12775:19;;12393:407::o;12805:127::-;12866:10;12861:3;12857:20;12854:1;12847:31;12897:4;12894:1;12887:15;12921:4;12918:1;12911:15;12937:135;12976:3;12997:17;;;12994:43;;13017:18;;:::i;:::-;-1:-1:-1;13064:1:1;13053:13;;12937:135::o;13077:127::-;13138:10;13133:3;13129:20;13126:1;13119:31;13169:4;13166:1;13159:15;13193:4;13190:1;13183:15;13209:339;13411:2;13393:21;;;13450:2;13430:18;;;13423:30;-1:-1:-1;;;13484:2:1;13469:18;;13462:45;13539:2;13524:18;;13209:339::o;13553:168::-;13626:9;;;13657;;13674:15;;;13668:22;;13654:37;13644:71;;13695:18;;:::i;13726:127::-;13787:10;13782:3;13778:20;13775:1;13768:31;13818:4;13815:1;13808:15;13842:4;13839:1;13832:15;13858:217;13898:1;13924;13914:132;;13968:10;13963:3;13959:20;13956:1;13949:31;14003:4;14000:1;13993:15;14031:4;14028:1;14021:15;13914:132;-1:-1:-1;14060:9:1;;13858:217::o;14080:125::-;14145:9;;;14166:10;;;14163:36;;;14179:18;;:::i;14210:334::-;14412:2;14394:21;;;14451:2;14431:18;;;14424:30;-1:-1:-1;;;14485:2:1;14470:18;;14463:40;14535:2;14520:18;;14210:334::o;14549:148::-;14637:4;14616:12;;;14630;;;14612:31;;14655:13;;14652:39;;;14671:18;;:::i;14702:404::-;14904:2;14886:21;;;14943:2;14923:18;;;14916:30;14982:34;14977:2;14962:18;;14955:62;-1:-1:-1;;;15048:2:1;15033:18;;15026:38;15096:3;15081:19;;14702:404::o;15451:128::-;15518:9;;;15539:11;;;15536:37;;;15553:18;;:::i;16123:545::-;16225:2;16220:3;16217:11;16214:448;;;16261:1;16286:5;16282:2;16275:17;16331:4;16327:2;16317:19;16401:2;16389:10;16385:19;16382:1;16378:27;16372:4;16368:38;16437:4;16425:10;16422:20;16419:47;;;-1:-1:-1;16460:4:1;16419:47;16515:2;16510:3;16506:12;16503:1;16499:20;16493:4;16489:31;16479:41;;16570:82;16588:2;16581:5;16578:13;16570:82;;;16633:17;;;16614:1;16603:13;16570:82;;16844:1352;16970:3;16964:10;-1:-1:-1;;;;;16989:6:1;16986:30;16983:56;;;17019:18;;:::i;:::-;17048:97;17138:6;17098:38;17130:4;17124:11;17098:38;:::i;:::-;17092:4;17048:97;:::i;:::-;17200:4;;17264:2;17253:14;;17281:1;17276:663;;;;17983:1;18000:6;17997:89;;;-1:-1:-1;18052:19:1;;;18046:26;17997:89;-1:-1:-1;;16801:1:1;16797:11;;;16793:24;16789:29;16779:40;16825:1;16821:11;;;16776:57;18099:81;;17246:944;;17276:663;16070:1;16063:14;;;16107:4;16094:18;;-1:-1:-1;;17312:20:1;;;17430:236;17444:7;17441:1;17438:14;17430:236;;;17533:19;;;17527:26;17512:42;;17625:27;;;;17593:1;17581:14;;;;17460:19;;17430:236;;;17434:3;17694:6;17685:7;17682:19;17679:201;;;17755:19;;;17749:26;-1:-1:-1;;17838:1:1;17834:14;;;17850:3;17830:24;17826:37;17822:42;17807:58;17792:74;;17679:201;-1:-1:-1;;;;;17926:1:1;17910:14;;;17906:22;17893:36;;-1:-1:-1;16844:1352:1:o;18964:136::-;19003:3;19031:5;19021:39;;19040:18;;:::i;:::-;-1:-1:-1;;;19076:18:1;;18964:136::o;20584:649::-;20664:6;20717:2;20705:9;20696:7;20692:23;20688:32;20685:52;;;20733:1;20730;20723:12;20685:52;20766:9;20760:16;-1:-1:-1;;;;;20791:6:1;20788:30;20785:50;;;20831:1;20828;20821:12;20785:50;20854:22;;20907:4;20899:13;;20895:27;-1:-1:-1;20885:55:1;;20936:1;20933;20926:12;20885:55;20965:2;20959:9;20990:49;21006:32;21035:2;21006:32;:::i;20990:49::-;21062:2;21055:5;21048:17;21102:7;21097:2;21092;21088;21084:11;21080:20;21077:33;21074:53;;;21123:1;21120;21113:12;21074:53;21136:67;21200:2;21195;21188:5;21184:14;21179:2;21175;21171:11;21136:67;:::i;:::-;21222:5;20584:649;-1:-1:-1;;;;;20584:649:1:o;21238:722::-;21288:3;21329:5;21323:12;21358:36;21384:9;21358:36;:::i;:::-;21413:1;21430:18;;;21457:133;;;;21604:1;21599:355;;;;21423:531;;21457:133;-1:-1:-1;;21490:24:1;;21478:37;;21563:14;;21556:22;21544:35;;21535:45;;;-1:-1:-1;21457:133:1;;21599:355;21630:5;21627:1;21620:16;21659:4;21704:2;21701:1;21691:16;21729:1;21743:165;21757:6;21754:1;21751:13;21743:165;;;21835:14;;21822:11;;;21815:35;21878:16;;;;21772:10;;21743:165;;;21747:3;;;21937:6;21932:3;21928:16;21921:23;;21423:531;;;;;21238:722;;;;:::o;21965:469::-;22186:3;22214:38;22248:3;22240:6;22214:38;:::i;:::-;22281:6;22275:13;22297:65;22355:6;22351:2;22344:4;22336:6;22332:17;22297:65;:::i;:::-;22378:50;22420:6;22416:2;22412:15;22404:6;22378:50;:::i;:::-;22371:57;21965:469;-1:-1:-1;;;;;;;21965:469:1:o;24623:245::-;24690:6;24743:2;24731:9;24722:7;24718:23;24714:32;24711:52;;;24759:1;24756;24749:12;24711:52;24791:9;24785:16;24810:28;24832:5;24810:28;:::i;25705:409::-;25907:2;25889:21;;;25946:2;25926:18;;;25919:30;25985:34;25980:2;25965:18;;25958:62;-1:-1:-1;;;26051:2:1;26036:18;;26029:43;26104:3;26089:19;;25705:409::o;27964:401::-;28166:2;28148:21;;;28205:2;28185:18;;;28178:30;28244:34;28239:2;28224:18;;28217:62;-1:-1:-1;;;28310:2:1;28295:18;;28288:35;28355:3;28340:19;;27964:401::o;28775:414::-;28977:2;28959:21;;;29016:2;28996:18;;;28989:30;29055:34;29050:2;29035:18;;29028:62;-1:-1:-1;;;29121:2:1;29106:18;;29099:48;29179:3;29164:19;;28775:414::o;31502:127::-;31563:10;31558:3;31554:20;31551:1;31544:31;31594:4;31591:1;31584:15;31618:4;31615:1;31608:15;33818:489;-1:-1:-1;;;;;34087:15:1;;;34069:34;;34139:15;;34134:2;34119:18;;34112:43;34186:2;34171:18;;34164:34;;;34234:3;34229:2;34214:18;;34207:31;;;34012:4;;34255:46;;34281:19;;34273:6;34255:46;:::i;:::-;34247:54;33818:489;-1:-1:-1;;;;;;33818:489:1:o;34312:249::-;34381:6;34434:2;34422:9;34413:7;34409:23;34405:32;34402:52;;;34450:1;34447;34440:12;34402:52;34482:9;34476:16;34501:30;34525:5;34501:30;:::i;35748:127::-;35809:10;35804:3;35800:20;35797:1;35790:31;35840:4;35837:1;35830:15;35864:4;35861:1;35854:15

Swarm Source

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