APE Price: $0.71 (-2.74%)

Overview

TokenID

500

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
ApingStation

Compiler Version
v0.8.26+commit.8a97fa7a

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at apescan.io on 2025-02-20
*/

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


// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[ERC].
 *
 * 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[ERC section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

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


// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.20;


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

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

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

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

    /**
     * @dev Returns the value of tokens of token type `id` owned by `account`.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

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

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

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

    /**
     * @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`.
     *
     * WARNING: This function can potentially allow a reentrancy attack when transferring tokens
     * to an untrusted contract, when invoking {onERC1155Received} on the receiver.
     * Ensure to follow the checks-effects-interactions pattern and consider employing
     * reentrancy guards when interacting with untrusted contracts.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `value` amount.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * WARNING: This function can potentially allow a reentrancy attack when transferring tokens
     * to an untrusted contract, when invoking {onERC1155BatchReceived} on the receiver.
     * Ensure to follow the checks-effects-interactions pattern and consider employing
     * reentrancy guards when interacting with untrusted contracts.
     *
     * Emits either a {TransferSingle} or a {TransferBatch} event, depending on the length of the array arguments.
     *
     * Requirements:
     *
     * - `ids` and `values` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external;
}

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


// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC1155/extensions/IERC1155MetadataURI.sol)

pragma solidity ^0.8.20;


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

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


// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.20;


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

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

// File: @openzeppelin/contracts/interfaces/draft-IERC6093.sol


// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;

/**
 * @dev Standard ERC-20 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
 */
interface IERC20Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC20InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC20InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     * @param allowance Amount of tokens a `spender` is allowed to operate with.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC20InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC20InvalidSpender(address spender);
}

/**
 * @dev Standard ERC-721 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
 */
interface IERC721Errors {
    /**
     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
     * Used in balance queries.
     * @param owner Address of the current owner of a token.
     */
    error ERC721InvalidOwner(address owner);

    /**
     * @dev Indicates a `tokenId` whose `owner` is the zero address.
     * @param tokenId Identifier number of a token.
     */
    error ERC721NonexistentToken(uint256 tokenId);

    /**
     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param tokenId Identifier number of a token.
     * @param owner Address of the current owner of a token.
     */
    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC721InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC721InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param tokenId Identifier number of a token.
     */
    error ERC721InsufficientApproval(address operator, uint256 tokenId);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC721InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC721InvalidOperator(address operator);
}

/**
 * @dev Standard ERC-1155 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
 */
interface IERC1155Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     * @param tokenId Identifier number of a token.
     */
    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC1155InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC1155InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param owner Address of the current owner of a token.
     */
    error ERC1155MissingApprovalForAll(address operator, address owner);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC1155InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC1155InvalidOperator(address operator);

    /**
     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
     * Used in batch transfers.
     * @param idsLength Length of the array of token identifiers
     * @param valuesLength Length of the array of token amounts
     */
    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}

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


// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC1155/utils/ERC1155Utils.sol)

pragma solidity ^0.8.20;



/**
 * @dev Library that provide common ERC-1155 utility functions.
 *
 * See https://eips.ethereum.org/EIPS/eip-1155[ERC-1155].
 *
 * _Available since v5.1._
 */
library ERC1155Utils {
    /**
     * @dev Performs an acceptance check for the provided `operator` by calling {IERC1155-onERC1155Received}
     * on the `to` address. The `operator` is generally the address that initiated the token transfer (i.e. `msg.sender`).
     *
     * The acceptance call is not executed and treated as a no-op if the target address doesn't contain code (i.e. an EOA).
     * Otherwise, the recipient must implement {IERC1155Receiver-onERC1155Received} and return the acceptance magic value to accept
     * the transfer.
     */
    function checkOnERC1155Received(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 value,
        bytes memory data
    ) internal {
        if (to.code.length > 0) {
            try IERC1155Receiver(to).onERC1155Received(operator, from, id, value, data) returns (bytes4 response) {
                if (response != IERC1155Receiver.onERC1155Received.selector) {
                    // Tokens rejected
                    revert IERC1155Errors.ERC1155InvalidReceiver(to);
                }
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    // non-IERC1155Receiver implementer
                    revert IERC1155Errors.ERC1155InvalidReceiver(to);
                } else {
                    assembly ("memory-safe") {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        }
    }

    /**
     * @dev Performs a batch acceptance check for the provided `operator` by calling {IERC1155-onERC1155BatchReceived}
     * on the `to` address. The `operator` is generally the address that initiated the token transfer (i.e. `msg.sender`).
     *
     * The acceptance call is not executed and treated as a no-op if the target address doesn't contain code (i.e. an EOA).
     * Otherwise, the recipient must implement {IERC1155Receiver-onERC1155Received} and return the acceptance magic value to accept
     * the transfer.
     */
    function checkOnERC1155BatchReceived(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory values,
        bytes memory data
    ) internal {
        if (to.code.length > 0) {
            try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, values, data) returns (
                bytes4 response
            ) {
                if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
                    // Tokens rejected
                    revert IERC1155Errors.ERC1155InvalidReceiver(to);
                }
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    // non-IERC1155Receiver implementer
                    revert IERC1155Errors.ERC1155InvalidReceiver(to);
                } else {
                    assembly ("memory-safe") {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

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

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

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


// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol)

pragma solidity ^0.8.20;


/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC-165 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);
 * }
 * ```
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

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


// OpenZeppelin Contracts (last updated v5.1.0) (utils/Comparators.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides a set of functions to compare values.
 *
 * _Available since v5.1._
 */
library Comparators {
    function lt(uint256 a, uint256 b) internal pure returns (bool) {
        return a < b;
    }

    function gt(uint256 a, uint256 b) internal pure returns (bool) {
        return a > b;
    }
}

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


// OpenZeppelin Contracts (last updated v5.1.0) (utils/SlotDerivation.sol)
// This file was procedurally generated from scripts/generate/templates/SlotDerivation.js.

pragma solidity ^0.8.20;

/**
 * @dev Library for computing storage (and transient storage) locations from namespaces and deriving slots
 * corresponding to standard patterns. The derivation method for array and mapping matches the storage layout used by
 * the solidity language / compiler.
 *
 * See https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays[Solidity docs for mappings and dynamic arrays.].
 *
 * Example usage:
 * ```solidity
 * contract Example {
 *     // Add the library methods
 *     using StorageSlot for bytes32;
 *     using SlotDerivation for bytes32;
 *
 *     // Declare a namespace
 *     string private constant _NAMESPACE = "<namespace>" // eg. OpenZeppelin.Slot
 *
 *     function setValueInNamespace(uint256 key, address newValue) internal {
 *         _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value = newValue;
 *     }
 *
 *     function getValueInNamespace(uint256 key) internal view returns (address) {
 *         return _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value;
 *     }
 * }
 * ```
 *
 * TIP: Consider using this library along with {StorageSlot}.
 *
 * NOTE: This library provides a way to manipulate storage locations in a non-standard way. Tooling for checking
 * upgrade safety will ignore the slots accessed through this library.
 *
 * _Available since v5.1._
 */
library SlotDerivation {
    /**
     * @dev Derive an ERC-7201 slot from a string (namespace).
     */
    function erc7201Slot(string memory namespace) internal pure returns (bytes32 slot) {
        assembly ("memory-safe") {
            mstore(0x00, sub(keccak256(add(namespace, 0x20), mload(namespace)), 1))
            slot := and(keccak256(0x00, 0x20), not(0xff))
        }
    }

    /**
     * @dev Add an offset to a slot to get the n-th element of a structure or an array.
     */
    function offset(bytes32 slot, uint256 pos) internal pure returns (bytes32 result) {
        unchecked {
            return bytes32(uint256(slot) + pos);
        }
    }

    /**
     * @dev Derive the location of the first element in an array from the slot where the length is stored.
     */
    function deriveArray(bytes32 slot) internal pure returns (bytes32 result) {
        assembly ("memory-safe") {
            mstore(0x00, slot)
            result := keccak256(0x00, 0x20)
        }
    }

    /**
     * @dev Derive the location of a mapping element from the key.
     */
    function deriveMapping(bytes32 slot, address key) internal pure returns (bytes32 result) {
        assembly ("memory-safe") {
            mstore(0x00, and(key, shr(96, not(0))))
            mstore(0x20, slot)
            result := keccak256(0x00, 0x40)
        }
    }

    /**
     * @dev Derive the location of a mapping element from the key.
     */
    function deriveMapping(bytes32 slot, bool key) internal pure returns (bytes32 result) {
        assembly ("memory-safe") {
            mstore(0x00, iszero(iszero(key)))
            mstore(0x20, slot)
            result := keccak256(0x00, 0x40)
        }
    }

    /**
     * @dev Derive the location of a mapping element from the key.
     */
    function deriveMapping(bytes32 slot, bytes32 key) internal pure returns (bytes32 result) {
        assembly ("memory-safe") {
            mstore(0x00, key)
            mstore(0x20, slot)
            result := keccak256(0x00, 0x40)
        }
    }

    /**
     * @dev Derive the location of a mapping element from the key.
     */
    function deriveMapping(bytes32 slot, uint256 key) internal pure returns (bytes32 result) {
        assembly ("memory-safe") {
            mstore(0x00, key)
            mstore(0x20, slot)
            result := keccak256(0x00, 0x40)
        }
    }

    /**
     * @dev Derive the location of a mapping element from the key.
     */
    function deriveMapping(bytes32 slot, int256 key) internal pure returns (bytes32 result) {
        assembly ("memory-safe") {
            mstore(0x00, key)
            mstore(0x20, slot)
            result := keccak256(0x00, 0x40)
        }
    }

    /**
     * @dev Derive the location of a mapping element from the key.
     */
    function deriveMapping(bytes32 slot, string memory key) internal pure returns (bytes32 result) {
        assembly ("memory-safe") {
            let length := mload(key)
            let begin := add(key, 0x20)
            let end := add(begin, length)
            let cache := mload(end)
            mstore(end, slot)
            result := keccak256(begin, add(length, 0x20))
            mstore(end, cache)
        }
    }

    /**
     * @dev Derive the location of a mapping element from the key.
     */
    function deriveMapping(bytes32 slot, bytes memory key) internal pure returns (bytes32 result) {
        assembly ("memory-safe") {
            let length := mload(key)
            let begin := add(key, 0x20)
            let end := add(begin, length)
            let cache := mload(end)
            mstore(end, slot)
            result := keccak256(begin, add(length, 0x20))
            mstore(end, cache)
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.

pragma solidity ^0.8.20;

/**
 * @dev Library for reading and writing primitive types to specific storage slots.
 *
 * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
 * This library helps with reading and writing to such slots without the need for inline assembly.
 *
 * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
 *
 * Example usage to set ERC-1967 implementation slot:
 * ```solidity
 * contract ERC1967 {
 *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.
 *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
 *
 *     function _getImplementation() internal view returns (address) {
 *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
 *     }
 *
 *     function _setImplementation(address newImplementation) internal {
 *         require(newImplementation.code.length > 0);
 *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
 *     }
 * }
 * ```
 *
 * TIP: Consider using this library along with {SlotDerivation}.
 */
library StorageSlot {
    struct AddressSlot {
        address value;
    }

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 value;
    }

    struct Int256Slot {
        int256 value;
    }

    struct StringSlot {
        string value;
    }

    struct BytesSlot {
        bytes value;
    }

    /**
     * @dev Returns an `AddressSlot` with member `value` located at `slot`.
     */
    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
        assembly ("memory-safe") {
            r.slot := slot
        }
    }

    /**
     * @dev Returns a `BooleanSlot` with member `value` located at `slot`.
     */
    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
        assembly ("memory-safe") {
            r.slot := slot
        }
    }

    /**
     * @dev Returns a `Bytes32Slot` with member `value` located at `slot`.
     */
    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
        assembly ("memory-safe") {
            r.slot := slot
        }
    }

    /**
     * @dev Returns a `Uint256Slot` with member `value` located at `slot`.
     */
    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
        assembly ("memory-safe") {
            r.slot := slot
        }
    }

    /**
     * @dev Returns a `Int256Slot` with member `value` located at `slot`.
     */
    function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {
        assembly ("memory-safe") {
            r.slot := slot
        }
    }

    /**
     * @dev Returns a `StringSlot` with member `value` located at `slot`.
     */
    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
        assembly ("memory-safe") {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
     */
    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
        assembly ("memory-safe") {
            r.slot := store.slot
        }
    }

    /**
     * @dev Returns a `BytesSlot` with member `value` located at `slot`.
     */
    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
        assembly ("memory-safe") {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
     */
    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
        assembly ("memory-safe") {
            r.slot := store.slot
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)

pragma solidity ^0.8.20;

/**
 * @dev Helper library for emitting standardized panic codes.
 *
 * ```solidity
 * contract Example {
 *      using Panic for uint256;
 *
 *      // Use any of the declared internal constants
 *      function foo() { Panic.GENERIC.panic(); }
 *
 *      // Alternatively
 *      function foo() { Panic.panic(Panic.GENERIC); }
 * }
 * ```
 *
 * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].
 *
 * _Available since v5.1._
 */
// slither-disable-next-line unused-state
library Panic {
    /// @dev generic / unspecified error
    uint256 internal constant GENERIC = 0x00;
    /// @dev used by the assert() builtin
    uint256 internal constant ASSERT = 0x01;
    /// @dev arithmetic underflow or overflow
    uint256 internal constant UNDER_OVERFLOW = 0x11;
    /// @dev division or modulo by zero
    uint256 internal constant DIVISION_BY_ZERO = 0x12;
    /// @dev enum conversion error
    uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;
    /// @dev invalid encoding in storage
    uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;
    /// @dev empty array pop
    uint256 internal constant EMPTY_ARRAY_POP = 0x31;
    /// @dev array out of bounds access
    uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;
    /// @dev resource error (too large allocation or too large array)
    uint256 internal constant RESOURCE_ERROR = 0x41;
    /// @dev calling invalid internal function
    uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;

    /// @dev Reverts with a panic code. Recommended to use with
    /// the internal constants with predefined codes.
    function panic(uint256 code) internal pure {
        assembly ("memory-safe") {
            mstore(0x00, 0x4e487b71)
            mstore(0x20, code)
            revert(0x1c, 0x24)
        }
    }
}

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


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

pragma solidity ^0.8.20;

/**
 * @dev Wrappers over Solidity's uintXX/intXX/bool 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.
 */
library SafeCast {
    /**
     * @dev Value doesn't fit in an uint of `bits` size.
     */
    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);

    /**
     * @dev An int value doesn't fit in an uint of `bits` size.
     */
    error SafeCastOverflowedIntToUint(int256 value);

    /**
     * @dev Value doesn't fit in an int of `bits` size.
     */
    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);

    /**
     * @dev An uint value doesn't fit in an int of `bits` size.
     */
    error SafeCastOverflowedUintToInt(uint256 value);

    /**
     * @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
     */
    function toUint248(uint256 value) internal pure returns (uint248) {
        if (value > type(uint248).max) {
            revert SafeCastOverflowedUintDowncast(248, value);
        }
        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
     */
    function toUint240(uint256 value) internal pure returns (uint240) {
        if (value > type(uint240).max) {
            revert SafeCastOverflowedUintDowncast(240, value);
        }
        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
     */
    function toUint232(uint256 value) internal pure returns (uint232) {
        if (value > type(uint232).max) {
            revert SafeCastOverflowedUintDowncast(232, value);
        }
        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
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        if (value > type(uint224).max) {
            revert SafeCastOverflowedUintDowncast(224, value);
        }
        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
     */
    function toUint216(uint256 value) internal pure returns (uint216) {
        if (value > type(uint216).max) {
            revert SafeCastOverflowedUintDowncast(216, value);
        }
        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
     */
    function toUint208(uint256 value) internal pure returns (uint208) {
        if (value > type(uint208).max) {
            revert SafeCastOverflowedUintDowncast(208, value);
        }
        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
     */
    function toUint200(uint256 value) internal pure returns (uint200) {
        if (value > type(uint200).max) {
            revert SafeCastOverflowedUintDowncast(200, value);
        }
        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
     */
    function toUint192(uint256 value) internal pure returns (uint192) {
        if (value > type(uint192).max) {
            revert SafeCastOverflowedUintDowncast(192, value);
        }
        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
     */
    function toUint184(uint256 value) internal pure returns (uint184) {
        if (value > type(uint184).max) {
            revert SafeCastOverflowedUintDowncast(184, value);
        }
        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
     */
    function toUint176(uint256 value) internal pure returns (uint176) {
        if (value > type(uint176).max) {
            revert SafeCastOverflowedUintDowncast(176, value);
        }
        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
     */
    function toUint168(uint256 value) internal pure returns (uint168) {
        if (value > type(uint168).max) {
            revert SafeCastOverflowedUintDowncast(168, value);
        }
        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
     */
    function toUint160(uint256 value) internal pure returns (uint160) {
        if (value > type(uint160).max) {
            revert SafeCastOverflowedUintDowncast(160, value);
        }
        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
     */
    function toUint152(uint256 value) internal pure returns (uint152) {
        if (value > type(uint152).max) {
            revert SafeCastOverflowedUintDowncast(152, value);
        }
        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
     */
    function toUint144(uint256 value) internal pure returns (uint144) {
        if (value > type(uint144).max) {
            revert SafeCastOverflowedUintDowncast(144, value);
        }
        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
     */
    function toUint136(uint256 value) internal pure returns (uint136) {
        if (value > type(uint136).max) {
            revert SafeCastOverflowedUintDowncast(136, value);
        }
        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
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        if (value > type(uint128).max) {
            revert SafeCastOverflowedUintDowncast(128, value);
        }
        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
     */
    function toUint120(uint256 value) internal pure returns (uint120) {
        if (value > type(uint120).max) {
            revert SafeCastOverflowedUintDowncast(120, value);
        }
        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
     */
    function toUint112(uint256 value) internal pure returns (uint112) {
        if (value > type(uint112).max) {
            revert SafeCastOverflowedUintDowncast(112, value);
        }
        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
     */
    function toUint104(uint256 value) internal pure returns (uint104) {
        if (value > type(uint104).max) {
            revert SafeCastOverflowedUintDowncast(104, value);
        }
        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
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        if (value > type(uint96).max) {
            revert SafeCastOverflowedUintDowncast(96, value);
        }
        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
     */
    function toUint88(uint256 value) internal pure returns (uint88) {
        if (value > type(uint88).max) {
            revert SafeCastOverflowedUintDowncast(88, value);
        }
        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
     */
    function toUint80(uint256 value) internal pure returns (uint80) {
        if (value > type(uint80).max) {
            revert SafeCastOverflowedUintDowncast(80, value);
        }
        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
     */
    function toUint72(uint256 value) internal pure returns (uint72) {
        if (value > type(uint72).max) {
            revert SafeCastOverflowedUintDowncast(72, value);
        }
        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
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        if (value > type(uint64).max) {
            revert SafeCastOverflowedUintDowncast(64, value);
        }
        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
     */
    function toUint56(uint256 value) internal pure returns (uint56) {
        if (value > type(uint56).max) {
            revert SafeCastOverflowedUintDowncast(56, value);
        }
        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
     */
    function toUint48(uint256 value) internal pure returns (uint48) {
        if (value > type(uint48).max) {
            revert SafeCastOverflowedUintDowncast(48, value);
        }
        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
     */
    function toUint40(uint256 value) internal pure returns (uint40) {
        if (value > type(uint40).max) {
            revert SafeCastOverflowedUintDowncast(40, value);
        }
        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
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        if (value > type(uint32).max) {
            revert SafeCastOverflowedUintDowncast(32, value);
        }
        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
     */
    function toUint24(uint256 value) internal pure returns (uint24) {
        if (value > type(uint24).max) {
            revert SafeCastOverflowedUintDowncast(24, value);
        }
        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
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        if (value > type(uint16).max) {
            revert SafeCastOverflowedUintDowncast(16, value);
        }
        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
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        if (value > type(uint8).max) {
            revert SafeCastOverflowedUintDowncast(8, value);
        }
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        if (value < 0) {
            revert SafeCastOverflowedIntToUint(value);
        }
        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
     */
    function toInt248(int256 value) internal pure returns (int248 downcasted) {
        downcasted = int248(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(248, value);
        }
    }

    /**
     * @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
     */
    function toInt240(int256 value) internal pure returns (int240 downcasted) {
        downcasted = int240(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(240, value);
        }
    }

    /**
     * @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
     */
    function toInt232(int256 value) internal pure returns (int232 downcasted) {
        downcasted = int232(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(232, value);
        }
    }

    /**
     * @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
     */
    function toInt224(int256 value) internal pure returns (int224 downcasted) {
        downcasted = int224(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(224, value);
        }
    }

    /**
     * @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
     */
    function toInt216(int256 value) internal pure returns (int216 downcasted) {
        downcasted = int216(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(216, value);
        }
    }

    /**
     * @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
     */
    function toInt208(int256 value) internal pure returns (int208 downcasted) {
        downcasted = int208(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(208, value);
        }
    }

    /**
     * @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
     */
    function toInt200(int256 value) internal pure returns (int200 downcasted) {
        downcasted = int200(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(200, value);
        }
    }

    /**
     * @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
     */
    function toInt192(int256 value) internal pure returns (int192 downcasted) {
        downcasted = int192(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(192, value);
        }
    }

    /**
     * @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
     */
    function toInt184(int256 value) internal pure returns (int184 downcasted) {
        downcasted = int184(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(184, value);
        }
    }

    /**
     * @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
     */
    function toInt176(int256 value) internal pure returns (int176 downcasted) {
        downcasted = int176(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(176, value);
        }
    }

    /**
     * @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
     */
    function toInt168(int256 value) internal pure returns (int168 downcasted) {
        downcasted = int168(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(168, value);
        }
    }

    /**
     * @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
     */
    function toInt160(int256 value) internal pure returns (int160 downcasted) {
        downcasted = int160(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(160, value);
        }
    }

    /**
     * @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
     */
    function toInt152(int256 value) internal pure returns (int152 downcasted) {
        downcasted = int152(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(152, value);
        }
    }

    /**
     * @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
     */
    function toInt144(int256 value) internal pure returns (int144 downcasted) {
        downcasted = int144(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(144, value);
        }
    }

    /**
     * @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
     */
    function toInt136(int256 value) internal pure returns (int136 downcasted) {
        downcasted = int136(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(136, value);
        }
    }

    /**
     * @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
     */
    function toInt128(int256 value) internal pure returns (int128 downcasted) {
        downcasted = int128(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(128, value);
        }
    }

    /**
     * @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
     */
    function toInt120(int256 value) internal pure returns (int120 downcasted) {
        downcasted = int120(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(120, value);
        }
    }

    /**
     * @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
     */
    function toInt112(int256 value) internal pure returns (int112 downcasted) {
        downcasted = int112(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(112, value);
        }
    }

    /**
     * @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
     */
    function toInt104(int256 value) internal pure returns (int104 downcasted) {
        downcasted = int104(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(104, value);
        }
    }

    /**
     * @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
     */
    function toInt96(int256 value) internal pure returns (int96 downcasted) {
        downcasted = int96(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(96, value);
        }
    }

    /**
     * @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
     */
    function toInt88(int256 value) internal pure returns (int88 downcasted) {
        downcasted = int88(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(88, value);
        }
    }

    /**
     * @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
     */
    function toInt80(int256 value) internal pure returns (int80 downcasted) {
        downcasted = int80(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(80, value);
        }
    }

    /**
     * @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
     */
    function toInt72(int256 value) internal pure returns (int72 downcasted) {
        downcasted = int72(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(72, value);
        }
    }

    /**
     * @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
     */
    function toInt64(int256 value) internal pure returns (int64 downcasted) {
        downcasted = int64(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(64, value);
        }
    }

    /**
     * @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
     */
    function toInt56(int256 value) internal pure returns (int56 downcasted) {
        downcasted = int56(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(56, value);
        }
    }

    /**
     * @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
     */
    function toInt48(int256 value) internal pure returns (int48 downcasted) {
        downcasted = int48(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(48, value);
        }
    }

    /**
     * @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
     */
    function toInt40(int256 value) internal pure returns (int40 downcasted) {
        downcasted = int40(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(40, value);
        }
    }

    /**
     * @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
     */
    function toInt32(int256 value) internal pure returns (int32 downcasted) {
        downcasted = int32(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(32, value);
        }
    }

    /**
     * @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
     */
    function toInt24(int256 value) internal pure returns (int24 downcasted) {
        downcasted = int24(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(24, value);
        }
    }

    /**
     * @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
     */
    function toInt16(int256 value) internal pure returns (int16 downcasted) {
        downcasted = int16(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(16, value);
        }
    }

    /**
     * @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
     */
    function toInt8(int256 value) internal pure returns (int8 downcasted) {
        downcasted = int8(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(8, value);
        }
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
        if (value > uint256(type(int256).max)) {
            revert SafeCastOverflowedUintToInt(value);
        }
        return int256(value);
    }

    /**
     * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.
     */
    function toUint(bool b) internal pure returns (uint256 u) {
        assembly ("memory-safe") {
            u := iszero(iszero(b))
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/Math.sol)

pragma solidity ^0.8.20;



/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Floor, // Toward negative infinity
        Ceil, // Toward positive infinity
        Trunc, // Toward zero
        Expand // Away from zero
    }

    /**
     * @dev Returns the addition of two unsigned integers, with an success flag (no overflow).
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow).
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

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

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

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

    /**
     * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.
     *
     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.
     * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute
     * one branch when needed, making this function more expensive.
     */
    function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {
        unchecked {
            // branchless ternary works because:
            // b ^ (a ^ b) == a
            // b ^ 0 == b
            return b ^ ((a ^ b) * SafeCast.toUint(condition));
        }
    }

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

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return ternary(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 towards infinity instead
     * of rounding towards zero.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        if (b == 0) {
            // Guarantee the same behavior as in a regular Solidity division.
            Panic.panic(Panic.DIVISION_BY_ZERO);
        }

        // The following calculation ensures accurate ceiling division without overflow.
        // Since a is non-zero, (a - 1) / b will not overflow.
        // The largest possible result occurs when (a - 1) / b is type(uint256).max,
        // but the largest value we can obtain is type(uint256).max - 1, which happens
        // when a = type(uint256).max and b = 1.
        unchecked {
            return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);
        }
    }

    /**
     * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
     * denominator == 0.
     *
     * 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²⁵⁶ and mod 2²⁵⁶ - 1, then use
            // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2²⁵⁶ + prod0.
            uint256 prod0 = x * y; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.
            if (denominator <= prod1) {
                Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));
            }

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

            uint256 twos = denominator & (0 - denominator);
            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²⁵⁶ / 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²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such
            // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv ≡ 1 mod 2⁴.
            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⁸
            inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶
            inverse *= 2 - denominator * inverse; // inverse mod 2³²
            inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴
            inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸
            inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶

            // 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²⁵⁶. Since the preconditions guarantee that the outcome is
            // less than 2²⁵⁶, 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;
        }
    }

    /**
     * @dev 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) {
        return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);
    }

    /**
     * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.
     *
     * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.
     * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.
     *
     * If the input value is not inversible, 0 is returned.
     *
     * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the
     * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.
     */
    function invMod(uint256 a, uint256 n) internal pure returns (uint256) {
        unchecked {
            if (n == 0) return 0;

            // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)
            // Used to compute integers x and y such that: ax + ny = gcd(a, n).
            // When the gcd is 1, then the inverse of a modulo n exists and it's x.
            // ax + ny = 1
            // ax = 1 + (-y)n
            // ax ≡ 1 (mod n) # x is the inverse of a modulo n

            // If the remainder is 0 the gcd is n right away.
            uint256 remainder = a % n;
            uint256 gcd = n;

            // Therefore the initial coefficients are:
            // ax + ny = gcd(a, n) = n
            // 0a + 1n = n
            int256 x = 0;
            int256 y = 1;

            while (remainder != 0) {
                uint256 quotient = gcd / remainder;

                (gcd, remainder) = (
                    // The old remainder is the next gcd to try.
                    remainder,
                    // Compute the next remainder.
                    // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd
                    // where gcd is at most n (capped to type(uint256).max)
                    gcd - remainder * quotient
                );

                (x, y) = (
                    // Increment the coefficient of a.
                    y,
                    // Decrement the coefficient of n.
                    // Can overflow, but the result is casted to uint256 so that the
                    // next value of y is "wrapped around" to a value between 0 and n - 1.
                    x - y * int256(quotient)
                );
            }

            if (gcd != 1) return 0; // No inverse exists.
            return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.
        }
    }

    /**
     * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.
     *
     * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is
     * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that
     * `a**(p-2)` is the modular multiplicative inverse of a in Fp.
     *
     * NOTE: this function does NOT check that `p` is a prime greater than `2`.
     */
    function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {
        unchecked {
            return Math.modExp(a, p - 2, p);
        }
    }

    /**
     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)
     *
     * Requirements:
     * - modulus can't be zero
     * - underlying staticcall to precompile must succeed
     *
     * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make
     * sure the chain you're using it on supports the precompiled contract for modular exponentiation
     * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,
     * the underlying function will succeed given the lack of a revert, but the result may be incorrectly
     * interpreted as 0.
     */
    function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {
        (bool success, uint256 result) = tryModExp(b, e, m);
        if (!success) {
            Panic.panic(Panic.DIVISION_BY_ZERO);
        }
        return result;
    }

    /**
     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).
     * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying
     * to operate modulo 0 or if the underlying precompile reverted.
     *
     * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain
     * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in
     * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack
     * of a revert, but the result may be incorrectly interpreted as 0.
     */
    function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {
        if (m == 0) return (false, 0);
        assembly ("memory-safe") {
            let ptr := mload(0x40)
            // | Offset    | Content    | Content (Hex)                                                      |
            // |-----------|------------|--------------------------------------------------------------------|
            // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |
            // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |
            // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |
            // | 0x60:0x7f | value of b | 0x<.............................................................b> |
            // | 0x80:0x9f | value of e | 0x<.............................................................e> |
            // | 0xa0:0xbf | value of m | 0x<.............................................................m> |
            mstore(ptr, 0x20)
            mstore(add(ptr, 0x20), 0x20)
            mstore(add(ptr, 0x40), 0x20)
            mstore(add(ptr, 0x60), b)
            mstore(add(ptr, 0x80), e)
            mstore(add(ptr, 0xa0), m)

            // Given the result < m, it's guaranteed to fit in 32 bytes,
            // so we can use the memory scratch space located at offset 0.
            success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)
            result := mload(0x00)
        }
    }

    /**
     * @dev Variant of {modExp} that supports inputs of arbitrary length.
     */
    function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {
        (bool success, bytes memory result) = tryModExp(b, e, m);
        if (!success) {
            Panic.panic(Panic.DIVISION_BY_ZERO);
        }
        return result;
    }

    /**
     * @dev Variant of {tryModExp} that supports inputs of arbitrary length.
     */
    function tryModExp(
        bytes memory b,
        bytes memory e,
        bytes memory m
    ) internal view returns (bool success, bytes memory result) {
        if (_zeroBytes(m)) return (false, new bytes(0));

        uint256 mLen = m.length;

        // Encode call args in result and move the free memory pointer
        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);

        assembly ("memory-safe") {
            let dataPtr := add(result, 0x20)
            // Write result on top of args to avoid allocating extra memory.
            success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)
            // Overwrite the length.
            // result.length > returndatasize() is guaranteed because returndatasize() == m.length
            mstore(result, mLen)
            // Set the memory pointer after the returned data.
            mstore(0x40, add(dataPtr, mLen))
        }
    }

    /**
     * @dev Returns whether the provided byte array is zero.
     */
    function _zeroBytes(bytes memory byteArray) private pure returns (bool) {
        for (uint256 i = 0; i < byteArray.length; ++i) {
            if (byteArray[i] != 0) {
                return false;
            }
        }
        return true;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
     * towards zero.
     *
     * This method is based on Newton's method for computing square roots; the algorithm is restricted to only
     * using integer operations.
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        unchecked {
            // Take care of easy edge cases when a == 0 or a == 1
            if (a <= 1) {
                return a;
            }

            // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a
            // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between
            // the current value as `ε_n = | x_n - sqrt(a) |`.
            //
            // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root
            // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is
            // bigger than any uint256.
            //
            // By noticing that
            // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`
            // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar
            // to the msb function.
            uint256 aa = a;
            uint256 xn = 1;

            if (aa >= (1 << 128)) {
                aa >>= 128;
                xn <<= 64;
            }
            if (aa >= (1 << 64)) {
                aa >>= 64;
                xn <<= 32;
            }
            if (aa >= (1 << 32)) {
                aa >>= 32;
                xn <<= 16;
            }
            if (aa >= (1 << 16)) {
                aa >>= 16;
                xn <<= 8;
            }
            if (aa >= (1 << 8)) {
                aa >>= 8;
                xn <<= 4;
            }
            if (aa >= (1 << 4)) {
                aa >>= 4;
                xn <<= 2;
            }
            if (aa >= (1 << 2)) {
                xn <<= 1;
            }

            // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).
            //
            // We can refine our estimation by noticing that the middle of that interval minimizes the error.
            // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).
            // This is going to be our x_0 (and ε_0)
            xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)

            // From here, Newton's method give us:
            // x_{n+1} = (x_n + a / x_n) / 2
            //
            // One should note that:
            // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a
            //              = ((x_n² + a) / (2 * x_n))² - a
            //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a
            //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)
            //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)
            //              = (x_n² - a)² / (2 * x_n)²
            //              = ((x_n² - a) / (2 * x_n))²
            //              ≥ 0
            // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n
            //
            // This gives us the proof of quadratic convergence of the sequence:
            // ε_{n+1} = | x_{n+1} - sqrt(a) |
            //         = | (x_n + a / x_n) / 2 - sqrt(a) |
            //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |
            //         = | (x_n - sqrt(a))² / (2 * x_n) |
            //         = | ε_n² / (2 * x_n) |
            //         = ε_n² / | (2 * x_n) |
            //
            // For the first iteration, we have a special case where x_0 is known:
            // ε_1 = ε_0² / | (2 * x_0) |
            //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))
            //     ≤ 2**(2*e-4) / (3 * 2**(e-1))
            //     ≤ 2**(e-3) / 3
            //     ≤ 2**(e-3-log2(3))
            //     ≤ 2**(e-4.5)
            //
            // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:
            // ε_{n+1} = ε_n² / | (2 * x_n) |
            //         ≤ (2**(e-k))² / (2 * 2**(e-1))
            //         ≤ 2**(2*e-2*k) / 2**e
            //         ≤ 2**(e-2*k)
            xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above
            xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5
            xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9
            xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18
            xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36
            xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72

            // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision
            // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either
            // sqrt(a) or sqrt(a) + 1.
            return xn - SafeCast.toUint(xn > a / xn);
        }
    }

    /**
     * @dev 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);
        }
    }

    /**
     * @dev Return the log in base 2 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        uint256 exp;
        unchecked {
            exp = 128 * SafeCast.toUint(value > (1 << 128) - 1);
            value >>= exp;
            result += exp;

            exp = 64 * SafeCast.toUint(value > (1 << 64) - 1);
            value >>= exp;
            result += exp;

            exp = 32 * SafeCast.toUint(value > (1 << 32) - 1);
            value >>= exp;
            result += exp;

            exp = 16 * SafeCast.toUint(value > (1 << 16) - 1);
            value >>= exp;
            result += exp;

            exp = 8 * SafeCast.toUint(value > (1 << 8) - 1);
            value >>= exp;
            result += exp;

            exp = 4 * SafeCast.toUint(value > (1 << 4) - 1);
            value >>= exp;
            result += exp;

            exp = 2 * SafeCast.toUint(value > (1 << 2) - 1);
            value >>= exp;
            result += exp;

            result += SafeCast.toUint(value > 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);
        }
    }

    /**
     * @dev Return the log in base 10 of a positive value rounded towards zero.
     * 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);
        }
    }

    /**
     * @dev Return the log in base 256 of a positive value rounded towards zero.
     * 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;
        uint256 isGt;
        unchecked {
            isGt = SafeCast.toUint(value > (1 << 128) - 1);
            value >>= isGt * 128;
            result += isGt * 16;

            isGt = SafeCast.toUint(value > (1 << 64) - 1);
            value >>= isGt * 64;
            result += isGt * 8;

            isGt = SafeCast.toUint(value > (1 << 32) - 1);
            value >>= isGt * 32;
            result += isGt * 4;

            isGt = SafeCast.toUint(value > (1 << 16) - 1);
            value >>= isGt * 16;
            result += isGt * 2;

            result += SafeCast.toUint(value > (1 << 8) - 1);
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);
        }
    }

    /**
     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
     */
    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
        return uint8(rounding) % 2 == 1;
    }
}

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


// OpenZeppelin Contracts (last updated v5.1.0) (utils/Arrays.sol)
// This file was procedurally generated from scripts/generate/templates/Arrays.js.

pragma solidity ^0.8.20;





/**
 * @dev Collection of functions related to array types.
 */
library Arrays {
    using SlotDerivation for bytes32;
    using StorageSlot for bytes32;

    /**
     * @dev Sort an array of uint256 (in memory) following the provided comparator function.
     *
     * This function does the sorting "in place", meaning that it overrides the input. The object is returned for
     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
     *
     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
     * consume more gas than is available in a block, leading to potential DoS.
     *
     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
     */
    function sort(
        uint256[] memory array,
        function(uint256, uint256) pure returns (bool) comp
    ) internal pure returns (uint256[] memory) {
        _quickSort(_begin(array), _end(array), comp);
        return array;
    }

    /**
     * @dev Variant of {sort} that sorts an array of uint256 in increasing order.
     */
    function sort(uint256[] memory array) internal pure returns (uint256[] memory) {
        sort(array, Comparators.lt);
        return array;
    }

    /**
     * @dev Sort an array of address (in memory) following the provided comparator function.
     *
     * This function does the sorting "in place", meaning that it overrides the input. The object is returned for
     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
     *
     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
     * consume more gas than is available in a block, leading to potential DoS.
     *
     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
     */
    function sort(
        address[] memory array,
        function(address, address) pure returns (bool) comp
    ) internal pure returns (address[] memory) {
        sort(_castToUint256Array(array), _castToUint256Comp(comp));
        return array;
    }

    /**
     * @dev Variant of {sort} that sorts an array of address in increasing order.
     */
    function sort(address[] memory array) internal pure returns (address[] memory) {
        sort(_castToUint256Array(array), Comparators.lt);
        return array;
    }

    /**
     * @dev Sort an array of bytes32 (in memory) following the provided comparator function.
     *
     * This function does the sorting "in place", meaning that it overrides the input. The object is returned for
     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
     *
     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
     * consume more gas than is available in a block, leading to potential DoS.
     *
     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
     */
    function sort(
        bytes32[] memory array,
        function(bytes32, bytes32) pure returns (bool) comp
    ) internal pure returns (bytes32[] memory) {
        sort(_castToUint256Array(array), _castToUint256Comp(comp));
        return array;
    }

    /**
     * @dev Variant of {sort} that sorts an array of bytes32 in increasing order.
     */
    function sort(bytes32[] memory array) internal pure returns (bytes32[] memory) {
        sort(_castToUint256Array(array), Comparators.lt);
        return array;
    }

    /**
     * @dev Performs a quick sort of a segment of memory. The segment sorted starts at `begin` (inclusive), and stops
     * at end (exclusive). Sorting follows the `comp` comparator.
     *
     * Invariant: `begin <= end`. This is the case when initially called by {sort} and is preserved in subcalls.
     *
     * IMPORTANT: Memory locations between `begin` and `end` are not validated/zeroed. This function should
     * be used only if the limits are within a memory array.
     */
    function _quickSort(uint256 begin, uint256 end, function(uint256, uint256) pure returns (bool) comp) private pure {
        unchecked {
            if (end - begin < 0x40) return;

            // Use first element as pivot
            uint256 pivot = _mload(begin);
            // Position where the pivot should be at the end of the loop
            uint256 pos = begin;

            for (uint256 it = begin + 0x20; it < end; it += 0x20) {
                if (comp(_mload(it), pivot)) {
                    // If the value stored at the iterator's position comes before the pivot, we increment the
                    // position of the pivot and move the value there.
                    pos += 0x20;
                    _swap(pos, it);
                }
            }

            _swap(begin, pos); // Swap pivot into place
            _quickSort(begin, pos, comp); // Sort the left side of the pivot
            _quickSort(pos + 0x20, end, comp); // Sort the right side of the pivot
        }
    }

    /**
     * @dev Pointer to the memory location of the first element of `array`.
     */
    function _begin(uint256[] memory array) private pure returns (uint256 ptr) {
        assembly ("memory-safe") {
            ptr := add(array, 0x20)
        }
    }

    /**
     * @dev Pointer to the memory location of the first memory word (32bytes) after `array`. This is the memory word
     * that comes just after the last element of the array.
     */
    function _end(uint256[] memory array) private pure returns (uint256 ptr) {
        unchecked {
            return _begin(array) + array.length * 0x20;
        }
    }

    /**
     * @dev Load memory word (as a uint256) at location `ptr`.
     */
    function _mload(uint256 ptr) private pure returns (uint256 value) {
        assembly {
            value := mload(ptr)
        }
    }

    /**
     * @dev Swaps the elements memory location `ptr1` and `ptr2`.
     */
    function _swap(uint256 ptr1, uint256 ptr2) private pure {
        assembly {
            let value1 := mload(ptr1)
            let value2 := mload(ptr2)
            mstore(ptr1, value2)
            mstore(ptr2, value1)
        }
    }

    /// @dev Helper: low level cast address memory array to uint256 memory array
    function _castToUint256Array(address[] memory input) private pure returns (uint256[] memory output) {
        assembly {
            output := input
        }
    }

    /// @dev Helper: low level cast bytes32 memory array to uint256 memory array
    function _castToUint256Array(bytes32[] memory input) private pure returns (uint256[] memory output) {
        assembly {
            output := input
        }
    }

    /// @dev Helper: low level cast address comp function to uint256 comp function
    function _castToUint256Comp(
        function(address, address) pure returns (bool) input
    ) private pure returns (function(uint256, uint256) pure returns (bool) output) {
        assembly {
            output := input
        }
    }

    /// @dev Helper: low level cast bytes32 comp function to uint256 comp function
    function _castToUint256Comp(
        function(bytes32, bytes32) pure returns (bool) input
    ) private pure returns (function(uint256, uint256) pure returns (bool) output) {
        assembly {
            output := input
        }
    }

    /**
     * @dev Searches a sorted `array` and returns the first index that contains
     * a value greater or equal to `element`. If no such index exists (i.e. all
     * values in the array are strictly less than `element`), the array length is
     * returned. Time complexity O(log n).
     *
     * NOTE: The `array` is expected to be sorted in ascending order, and to
     * contain no repeated elements.
     *
     * IMPORTANT: Deprecated. This implementation behaves as {lowerBound} but lacks
     * support for repeated elements in the array. The {lowerBound} function should
     * be used instead.
     */
    function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
        uint256 low = 0;
        uint256 high = array.length;

        if (high == 0) {
            return 0;
        }

        while (low < high) {
            uint256 mid = Math.average(low, high);

            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
            // because Math.average rounds towards zero (it does integer division with truncation).
            if (unsafeAccess(array, mid).value > element) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
        if (low > 0 && unsafeAccess(array, low - 1).value == element) {
            return low - 1;
        } else {
            return low;
        }
    }

    /**
     * @dev Searches an `array` sorted in ascending order and returns the first
     * index that contains a value greater or equal than `element`. If no such index
     * exists (i.e. all values in the array are strictly less than `element`), the array
     * length is returned. Time complexity O(log n).
     *
     * See C++'s https://en.cppreference.com/w/cpp/algorithm/lower_bound[lower_bound].
     */
    function lowerBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
        uint256 low = 0;
        uint256 high = array.length;

        if (high == 0) {
            return 0;
        }

        while (low < high) {
            uint256 mid = Math.average(low, high);

            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
            // because Math.average rounds towards zero (it does integer division with truncation).
            if (unsafeAccess(array, mid).value < element) {
                // this cannot overflow because mid < high
                unchecked {
                    low = mid + 1;
                }
            } else {
                high = mid;
            }
        }

        return low;
    }

    /**
     * @dev Searches an `array` sorted in ascending order and returns the first
     * index that contains a value strictly greater than `element`. If no such index
     * exists (i.e. all values in the array are strictly less than `element`), the array
     * length is returned. Time complexity O(log n).
     *
     * See C++'s https://en.cppreference.com/w/cpp/algorithm/upper_bound[upper_bound].
     */
    function upperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
        uint256 low = 0;
        uint256 high = array.length;

        if (high == 0) {
            return 0;
        }

        while (low < high) {
            uint256 mid = Math.average(low, high);

            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
            // because Math.average rounds towards zero (it does integer division with truncation).
            if (unsafeAccess(array, mid).value > element) {
                high = mid;
            } else {
                // this cannot overflow because mid < high
                unchecked {
                    low = mid + 1;
                }
            }
        }

        return low;
    }

    /**
     * @dev Same as {lowerBound}, but with an array in memory.
     */
    function lowerBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {
        uint256 low = 0;
        uint256 high = array.length;

        if (high == 0) {
            return 0;
        }

        while (low < high) {
            uint256 mid = Math.average(low, high);

            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
            // because Math.average rounds towards zero (it does integer division with truncation).
            if (unsafeMemoryAccess(array, mid) < element) {
                // this cannot overflow because mid < high
                unchecked {
                    low = mid + 1;
                }
            } else {
                high = mid;
            }
        }

        return low;
    }

    /**
     * @dev Same as {upperBound}, but with an array in memory.
     */
    function upperBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {
        uint256 low = 0;
        uint256 high = array.length;

        if (high == 0) {
            return 0;
        }

        while (low < high) {
            uint256 mid = Math.average(low, high);

            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
            // because Math.average rounds towards zero (it does integer division with truncation).
            if (unsafeMemoryAccess(array, mid) > element) {
                high = mid;
            } else {
                // this cannot overflow because mid < high
                unchecked {
                    low = mid + 1;
                }
            }
        }

        return low;
    }

    /**
     * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
     *
     * WARNING: Only use if you are certain `pos` is lower than the array length.
     */
    function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlot.AddressSlot storage) {
        bytes32 slot;
        assembly ("memory-safe") {
            slot := arr.slot
        }
        return slot.deriveArray().offset(pos).getAddressSlot();
    }

    /**
     * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
     *
     * WARNING: Only use if you are certain `pos` is lower than the array length.
     */
    function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlot.Bytes32Slot storage) {
        bytes32 slot;
        assembly ("memory-safe") {
            slot := arr.slot
        }
        return slot.deriveArray().offset(pos).getBytes32Slot();
    }

    /**
     * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
     *
     * WARNING: Only use if you are certain `pos` is lower than the array length.
     */
    function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlot.Uint256Slot storage) {
        bytes32 slot;
        assembly ("memory-safe") {
            slot := arr.slot
        }
        return slot.deriveArray().offset(pos).getUint256Slot();
    }

    /**
     * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
     *
     * WARNING: Only use if you are certain `pos` is lower than the array length.
     */
    function unsafeMemoryAccess(address[] memory arr, uint256 pos) internal pure returns (address res) {
        assembly {
            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
        }
    }

    /**
     * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
     *
     * WARNING: Only use if you are certain `pos` is lower than the array length.
     */
    function unsafeMemoryAccess(bytes32[] memory arr, uint256 pos) internal pure returns (bytes32 res) {
        assembly {
            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
        }
    }

    /**
     * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
     *
     * WARNING: Only use if you are certain `pos` is lower than the array length.
     */
    function unsafeMemoryAccess(uint256[] memory arr, uint256 pos) internal pure returns (uint256 res) {
        assembly {
            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
        }
    }

    /**
     * @dev Helper to set the length of an dynamic array. Directly writing to `.length` is forbidden.
     *
     * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
     */
    function unsafeSetLength(address[] storage array, uint256 len) internal {
        assembly ("memory-safe") {
            sstore(array.slot, len)
        }
    }

    /**
     * @dev Helper to set the length of an dynamic array. Directly writing to `.length` is forbidden.
     *
     * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
     */
    function unsafeSetLength(bytes32[] storage array, uint256 len) internal {
        assembly ("memory-safe") {
            sstore(array.slot, len)
        }
    }

    /**
     * @dev Helper to set the length of an dynamic array. Directly writing to `.length` is forbidden.
     *
     * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
     */
    function unsafeSetLength(uint256[] storage array, uint256 len) internal {
        assembly ("memory-safe") {
            sstore(array.slot, len)
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC1155/ERC1155.sol)

pragma solidity ^0.8.20;








/**
 * @dev Implementation of the basic standard multi-token.
 * See https://eips.ethereum.org/EIPS/eip-1155
 * Originally based on code by Enjin: https://github.com/enjin/erc-1155
 */
abstract contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI, IERC1155Errors {
    using Arrays for uint256[];
    using Arrays for address[];

    mapping(uint256 id => mapping(address account => uint256)) private _balances;

    mapping(address account => mapping(address operator => bool)) private _operatorApprovals;

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

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

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

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

    /**
     * @dev See {IERC1155-balanceOf}.
     */
    function balanceOf(address account, uint256 id) public view virtual returns (uint256) {
        return _balances[id][account];
    }

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

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

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

        return batchBalances;
    }

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

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

    /**
     * @dev See {IERC1155-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes memory data) public virtual {
        address sender = _msgSender();
        if (from != sender && !isApprovedForAll(from, sender)) {
            revert ERC1155MissingApprovalForAll(sender, from);
        }
        _safeTransferFrom(from, to, id, value, data);
    }

    /**
     * @dev See {IERC1155-safeBatchTransferFrom}.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory values,
        bytes memory data
    ) public virtual {
        address sender = _msgSender();
        if (from != sender && !isApprovedForAll(from, sender)) {
            revert ERC1155MissingApprovalForAll(sender, from);
        }
        _safeBatchTransferFrom(from, to, ids, values, data);
    }

    /**
     * @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`. Will mint (or burn) if `from`
     * (or `to`) is the zero address.
     *
     * Emits a {TransferSingle} event if the arrays contain one element, and {TransferBatch} otherwise.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement either {IERC1155Receiver-onERC1155Received}
     *   or {IERC1155Receiver-onERC1155BatchReceived} and return the acceptance magic value.
     * - `ids` and `values` must have the same length.
     *
     * NOTE: The ERC-1155 acceptance check is not performed in this function. See {_updateWithAcceptanceCheck} instead.
     */
    function _update(address from, address to, uint256[] memory ids, uint256[] memory values) internal virtual {
        if (ids.length != values.length) {
            revert ERC1155InvalidArrayLength(ids.length, values.length);
        }

        address operator = _msgSender();

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids.unsafeMemoryAccess(i);
            uint256 value = values.unsafeMemoryAccess(i);

            if (from != address(0)) {
                uint256 fromBalance = _balances[id][from];
                if (fromBalance < value) {
                    revert ERC1155InsufficientBalance(from, fromBalance, value, id);
                }
                unchecked {
                    // Overflow not possible: value <= fromBalance
                    _balances[id][from] = fromBalance - value;
                }
            }

            if (to != address(0)) {
                _balances[id][to] += value;
            }
        }

        if (ids.length == 1) {
            uint256 id = ids.unsafeMemoryAccess(0);
            uint256 value = values.unsafeMemoryAccess(0);
            emit TransferSingle(operator, from, to, id, value);
        } else {
            emit TransferBatch(operator, from, to, ids, values);
        }
    }

    /**
     * @dev Version of {_update} that performs the token acceptance check by calling
     * {IERC1155Receiver-onERC1155Received} or {IERC1155Receiver-onERC1155BatchReceived} on the receiver address if it
     * contains code (eg. is a smart contract at the moment of execution).
     *
     * IMPORTANT: Overriding this function is discouraged because it poses a reentrancy risk from the receiver. So any
     * update to the contract state after this function would break the check-effect-interaction pattern. Consider
     * overriding {_update} instead.
     */
    function _updateWithAcceptanceCheck(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory values,
        bytes memory data
    ) internal virtual {
        _update(from, to, ids, values);
        if (to != address(0)) {
            address operator = _msgSender();
            if (ids.length == 1) {
                uint256 id = ids.unsafeMemoryAccess(0);
                uint256 value = values.unsafeMemoryAccess(0);
                ERC1155Utils.checkOnERC1155Received(operator, from, to, id, value, data);
            } else {
                ERC1155Utils.checkOnERC1155BatchReceived(operator, from, to, ids, values, data);
            }
        }
    }

    /**
     * @dev Transfers a `value` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `from` must have a balance of tokens of type `id` of at least `value` amount.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes memory data) internal {
        if (to == address(0)) {
            revert ERC1155InvalidReceiver(address(0));
        }
        if (from == address(0)) {
            revert ERC1155InvalidSender(address(0));
        }
        (uint256[] memory ids, uint256[] memory values) = _asSingletonArrays(id, value);
        _updateWithAcceptanceCheck(from, to, ids, values, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     * - `ids` and `values` must have the same length.
     */
    function _safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory values,
        bytes memory data
    ) internal {
        if (to == address(0)) {
            revert ERC1155InvalidReceiver(address(0));
        }
        if (from == address(0)) {
            revert ERC1155InvalidSender(address(0));
        }
        _updateWithAcceptanceCheck(from, to, ids, values, data);
    }

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

    /**
     * @dev Creates a `value` amount of tokens of type `id`, and assigns them to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _mint(address to, uint256 id, uint256 value, bytes memory data) internal {
        if (to == address(0)) {
            revert ERC1155InvalidReceiver(address(0));
        }
        (uint256[] memory ids, uint256[] memory values) = _asSingletonArrays(id, value);
        _updateWithAcceptanceCheck(address(0), to, ids, values, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `values` must have the same length.
     * - `to` cannot be the zero address.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _mintBatch(address to, uint256[] memory ids, uint256[] memory values, bytes memory data) internal {
        if (to == address(0)) {
            revert ERC1155InvalidReceiver(address(0));
        }
        _updateWithAcceptanceCheck(address(0), to, ids, values, data);
    }

    /**
     * @dev Destroys a `value` amount of tokens of type `id` from `from`
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `from` must have at least `value` amount of tokens of type `id`.
     */
    function _burn(address from, uint256 id, uint256 value) internal {
        if (from == address(0)) {
            revert ERC1155InvalidSender(address(0));
        }
        (uint256[] memory ids, uint256[] memory values) = _asSingletonArrays(id, value);
        _updateWithAcceptanceCheck(from, address(0), ids, values, "");
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `from` must have at least `value` amount of tokens of type `id`.
     * - `ids` and `values` must have the same length.
     */
    function _burnBatch(address from, uint256[] memory ids, uint256[] memory values) internal {
        if (from == address(0)) {
            revert ERC1155InvalidSender(address(0));
        }
        _updateWithAcceptanceCheck(from, address(0), ids, values, "");
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the zero address.
     */
    function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {
        if (operator == address(0)) {
            revert ERC1155InvalidOperator(address(0));
        }
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Creates an array in memory with only one value for each of the elements provided.
     */
    function _asSingletonArrays(
        uint256 element1,
        uint256 element2
    ) private pure returns (uint256[] memory array1, uint256[] memory array2) {
        assembly ("memory-safe") {
            // Load the free memory pointer
            array1 := mload(0x40)
            // Set array length to 1
            mstore(array1, 1)
            // Store the single element at the next word after the length (where content starts)
            mstore(add(array1, 0x20), element1)

            // Repeat for next array locating it right after the first array
            array2 := add(array1, 0x40)
            mstore(array2, 1)
            mstore(add(array2, 0x20), element2)

            // Update the free memory pointer by pointing after the second array
            mstore(0x40, add(array2, 0x40))
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;


/**
 * @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.
 *
 * The initial owner is set to the address provided by the deployer. 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;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @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 {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling 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 {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

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

// File: apingStation.sol



//     _  _ . _  _    
//    (_||_)|| |(_|   
//       |       _|   
//   __|_ _ _|_. _  _ 
//  _\ | (_| | |(_)| |
//   2025   @dakkyBear                 

pragma solidity ^0.8.0;



contract ApingStation is ERC1155, Ownable {
    uint256 public constant MAX_LEVEL1_SUPPLY = 20000;
    uint256 public level1Minted;
    uint256 public constant PRICE = 0.1 ether;
    event Message(address indexed user, string message);
    event Minted(address indexed user, string message);
    bool public mintingOpen = false; // Minting is closed by default

    // Mapping for token URIs. This will work for any token id.
    mapping(uint256 => string) private tokenURIs;

    constructor() ERC1155("") Ownable(msg.sender) {
        // Base URI is empty; we override uri() below.
    }

    // Override the uri function to return the token-specific URI.
    function uri(uint256 tokenId) public view override returns (string memory) {
        return tokenURIs[tokenId];
    }

    // Owner can update the URI for any token id.
    function setTokenURI(uint256 tokenId, string calldata newUri) external onlyOwner {
        tokenURIs[tokenId] = newUri;
    }

    // Minting function for level 1 tokens.
    // Allows minting multiple tokens as long as APE and max supply requirements are met.
    function mintLevel1(uint256 amount) external payable {
        require(mintingOpen, "Minting is not open");
        require(msg.value >= amount * PRICE, "Insufficient APE sent");
        require(level1Minted + amount <= MAX_LEVEL1_SUPPLY, "Max supply reached");
        level1Minted += amount;
        _mint(msg.sender, 1, amount, "");
    }

    function toggleMinting() external onlyOwner {
    mintingOpen = !mintingOpen;
    }

    // Upgrade functions:
    function upgrade1To2(uint256 amount) external {
        uint256 required = amount * 2;
        require(balanceOf(msg.sender, 1) >= required, "Not enough level 1 tokens");
        _burn(msg.sender, 1, required);

        for (uint256 i = 0; i < amount; i++) {
            // Using i in the hash to get a different random per iteration.
            uint256 random = uint256(keccak256(abi.encodePacked(block.prevrandao, msg.sender, i, block.timestamp))) % 100;

            if(random < 85) {
                _mint(msg.sender, 2, 1, "Minted Bottle of Potion.");
                emit Minted(msg.sender, "Minted Bottle of Potion.");
            } else {
                _mint(msg.sender, 200, 1, "Minted Cyan Potion.");
                emit Minted(msg.sender, "Minted Cyan Potion.");
            }
        }
    }

    function upgrade2To3(uint256 amount) external {
        uint256 required = amount * 2;
        require(balanceOf(msg.sender, 2) >= required, "Not enough level 2 tokens");
        _burn(msg.sender, 2, required);

        for (uint256 i = 0; i < amount; i++) {
            // Using i in the hash to get a different random per iteration.
            uint256 random = uint256(keccak256(abi.encodePacked(block.prevrandao, msg.sender, i, block.timestamp))) % 100;
            
            if(random < 50) {
                _mint(msg.sender, 3, 1, "Minted Cup of Potion.");
                emit Minted(msg.sender, "Minted Cup of Potion.");
            } else if(random < 70) {
                _mint(msg.sender, 300, 1, "Minted Trippy Potion.");
                emit Minted(msg.sender, "Minted Trippy Potion.");
            } else if(random < 95) {
                _mint(msg.sender, 301, 1, "Minted Rainbow Potion.");
                emit Minted(msg.sender, "Minted Rainbow Potion.");
            } else {
                emit Message(msg.sender, "You got nothing.");
            }
        }
    }

    function upgrade3To4(uint256 amount) external {
        uint256 required = amount * 2;
        require(balanceOf(msg.sender, 3) >= required, "Not enough level 3 tokens");
        _burn(msg.sender, 3, required);

        for (uint256 i = 0; i < amount; i++) {
            // Using i in the hash to get a different random per iteration.
            uint256 random = uint256(keccak256(abi.encodePacked(block.prevrandao, msg.sender, i, block.timestamp))) % 100;

            if(random < 30) {
                _mint(msg.sender, 4, 1, "Minted Keg of Potion.");
                emit Minted(msg.sender, "Minted Keg of Potion.");
            } else if(random < 80) {
                _mint(msg.sender, 400, 1, "Minted Pink Potion.");
                emit Minted(msg.sender, "Minted Pink Potion.");
            } else {
                _mint(msg.sender, 401, 1, "Minted Pink Explosion!");
                emit Minted(msg.sender, "Minted Pink Explosion!");
            }
        }
    }

    function upgrade4To5(uint256 amount) external {
        uint256 required = amount * 2;
        require(balanceOf(msg.sender, 4) >= required, "Not enough level 4 tokens");
        _burn(msg.sender, 4, required);

        for (uint256 i = 0; i < amount; i++) {
            // Using i in the hash to get a different random per iteration.
            uint256 random = uint256(keccak256(abi.encodePacked(block.prevrandao, msg.sender, i, block.timestamp))) % 100;

            if(random < 10) {
                _mint(msg.sender, 5, 1, "Minted Canister of Potion!");
                emit Minted(msg.sender, "Minted Canister of Potion!");
            } else if(random < 40) {
                _mint(msg.sender, 500, 1, "Minted Gold Explosion!");
                emit Minted(msg.sender, "Minted Gold Explosion!");
            } else {
                emit Message(msg.sender, "You got nothing.");
            }
        }
    }

    function upgrade5To6(uint256 amount) external {
    uint256 required = amount * 2;
    require(balanceOf(msg.sender, 5) >= required, "Not enough level 5 tokens");
    _burn(msg.sender, 5, required);

        for (uint256 i = 0; i < amount; i++) {
            // Using i in the hash to get a different random per iteration.
            uint256 random = uint256(keccak256(abi.encodePacked(block.prevrandao, msg.sender, i, block.timestamp))) % 100;

            if(random < 50) {
                _mint(msg.sender, 6, 1, "Minted Apechain Sculpture!!!");
                emit Minted(msg.sender, "Minted Apechain Sculpture!!!");
            } else {
                emit Message(msg.sender, "You got nothing.");
            }
        }
    }

    // Owner can withdraw the APE collected from minting.
    function withdraw() external onlyOwner {
        uint256 balance = address(this).balance;
        require(balance > 0, "No APE available");
        payable(owner()).transfer(balance);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC1155InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC1155InvalidApprover","type":"error"},{"inputs":[{"internalType":"uint256","name":"idsLength","type":"uint256"},{"internalType":"uint256","name":"valuesLength","type":"uint256"}],"name":"ERC1155InvalidArrayLength","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC1155InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC1155InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC1155InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC1155MissingApprovalForAll","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"string","name":"message","type":"string"}],"name":"Message","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"string","name":"message","type":"string"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[],"name":"MAX_LEVEL1_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"level1Minted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintLevel1","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintingOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"newUri","type":"string"}],"name":"setTokenURI","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":"toggleMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"upgrade1To2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"upgrade2To3","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"upgrade3To4","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"upgrade4To5","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"upgrade5To6","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040525f60055f6101000a81548160ff021916908315150217905550348015610028575f80fd5b503360405180602001604052805f815250610048816100ce60201b60201c565b505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100b9575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016100b091906101e3565b60405180910390fd5b6100c8816100e160201b60201c565b50610505565b80600290816100dd9190610436565b5050565b5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6101cd826101a4565b9050919050565b6101dd816101c3565b82525050565b5f6020820190506101f65f8301846101d4565b92915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061027757607f821691505b60208210810361028a57610289610233565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026102ec7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102b1565b6102f686836102b1565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61033a6103356103308461030e565b610317565b61030e565b9050919050565b5f819050919050565b61035383610320565b61036761035f82610341565b8484546102bd565b825550505050565b5f90565b61037b61036f565b61038681848461034a565b505050565b5b818110156103a95761039e5f82610373565b60018101905061038c565b5050565b601f8211156103ee576103bf81610290565b6103c8846102a2565b810160208510156103d7578190505b6103eb6103e3856102a2565b83018261038b565b50505b505050565b5f82821c905092915050565b5f61040e5f19846008026103f3565b1980831691505092915050565b5f61042683836103ff565b9150826002028217905092915050565b61043f826101fc565b67ffffffffffffffff81111561045857610457610206565b5b6104628254610260565b61046d8282856103ad565b5f60209050601f83116001811461049e575f841561048c578287015190505b610496858261041b565b8655506104fd565b601f1984166104ac86610290565b5f5b828110156104d3578489015182556001820191506020850194506020810190506104ae565b868310156104f057848901516104ec601f8916826103ff565b8355505b6001600288020188555050505b505050505050565b613fc4806105125f395ff3fe608060405260043610610149575f3560e01c80638d859f3e116100b5578063bfcee0b61161006e578063bfcee0b614610433578063e985e9c51461045d578063ea39e31a14610499578063f242432a146104c1578063f2fde38b146104e9578063f847d7231461051157610149565b80638d859f3e1461033d5780638da5cb5b146103675780638f4bb49714610391578063a22cb465146103bb578063a9bca560146103e3578063ae291e421461040b57610149565b80633ccfd60b116101075780633ccfd60b146102795780634e1273f41461028f578063601faccf146102cb57806361942327146102e7578063715018a6146103115780637d55094d1461032757610149565b8062fdd58e1461014d57806301ffc9a7146101895780630e89341c146101c5578063162094c4146102015780632eb2c2d6146102295780633563794c14610251575b5f80fd5b348015610158575f80fd5b50610173600480360381019061016e9190612765565b610539565b60405161018091906127b2565b60405180910390f35b348015610194575f80fd5b506101af60048036038101906101aa9190612820565b61058e565b6040516101bc9190612865565b60405180910390f35b3480156101d0575f80fd5b506101eb60048036038101906101e6919061287e565b61066f565b6040516101f89190612919565b60405180910390f35b34801561020c575f80fd5b506102276004803603810190610222919061299a565b610710565b005b348015610234575f80fd5b5061024f600480360381019061024a9190612bdf565b61073e565b005b34801561025c575f80fd5b506102776004803603810190610272919061287e565b6107e5565b005b348015610284575f80fd5b5061028d610a76565b005b34801561029a575f80fd5b506102b560048036038101906102b09190612d6a565b610b12565b6040516102c29190612e97565b60405180910390f35b6102e560048036038101906102e0919061287e565b610c19565b005b3480156102f2575f80fd5b506102fb610d45565b60405161030891906127b2565b60405180910390f35b34801561031c575f80fd5b50610325610d4b565b005b348015610332575f80fd5b5061033b610d5e565b005b348015610348575f80fd5b50610351610d90565b60405161035e91906127b2565b60405180910390f35b348015610372575f80fd5b5061037b610d9c565b6040516103889190612ec6565b60405180910390f35b34801561039c575f80fd5b506103a5610dc4565b6040516103b29190612865565b60405180910390f35b3480156103c6575f80fd5b506103e160048036038101906103dc9190612f09565b610dd6565b005b3480156103ee575f80fd5b506104096004803603810190610404919061287e565b610dec565b005b348015610416575f80fd5b50610431600480360381019061042c919061287e565b6110d8565b005b34801561043e575f80fd5b50610447611325565b60405161045491906127b2565b60405180910390f35b348015610468575f80fd5b50610483600480360381019061047e9190612f47565b61132b565b6040516104909190612865565b60405180910390f35b3480156104a4575f80fd5b506104bf60048036038101906104ba919061287e565b6113b9565b005b3480156104cc575f80fd5b506104e760048036038101906104e29190612f85565b611567565b005b3480156104f4575f80fd5b5061050f600480360381019061050a9190613018565b61160e565b005b34801561051c575f80fd5b506105376004803603810190610532919061287e565b611692565b005b5f805f8381526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f7fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061065857507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610668575061066782611883565b5b9050919050565b606060065f8381526020019081526020015f20805461068d90613070565b80601f01602080910402602001604051908101604052809291908181526020018280546106b990613070565b80156107045780601f106106db57610100808354040283529160200191610704565b820191905f5260205f20905b8154815290600101906020018083116106e757829003601f168201915b50505050509050919050565b6107186118ec565b818160065f8681526020019081526020015f209182610738929190613247565b50505050565b5f610747611973565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561078c575061078a868261132b565b155b156107d05780866040517fe237d9220000000000000000000000000000000000000000000000000000000081526004016107c7929190613314565b60405180910390fd5b6107dd868686868661197a565b505050505050565b5f6002826107f39190613368565b905080610801336003610539565b1015610842576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610839906133f3565b60405180910390fd5b61084e33600383611a6e565b5f5b82811015610a71575f6064443384426040516020016108729493929190613476565b604051602081830303815290604052805190602001205f1c61089491906134f0565b9050601e811015610933576108e233600460016040518060400160405280601581526020017f4d696e746564204b6567206f6620506f74696f6e2e0000000000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f926040516109269061356a565b60405180910390a2610a63565b60508110156109d1576109803361019060016040518060400160405280601381526020017f4d696e7465642050696e6b20506f74696f6e2e00000000000000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f926040516109c4906135d2565b60405180910390a2610a62565b610a153361019160016040518060400160405280601681526020017f4d696e7465642050696e6b204578706c6f73696f6e2100000000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f92604051610a599061363a565b60405180910390a25b5b508080600101915050610850565b505050565b610a7e6118ec565b5f4790505f8111610ac4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610abb906136a2565b60405180910390fd5b610acc610d9c565b73ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015610b0e573d5f803e3d5ffd5b5050565b60608151835114610b5e57815183516040517f5b059991000000000000000000000000000000000000000000000000000000008152600401610b559291906136c0565b60405180910390fd5b5f835167ffffffffffffffff811115610b7a57610b796129f7565b5b604051908082528060200260200182016040528015610ba85781602001602082028036833780820191505090505b5090505f5b8451811015610c0e57610be4610bcc8287611ba590919063ffffffff16565b610bdf8387611bb890919063ffffffff16565b610539565b828281518110610bf757610bf66136e7565b5b602002602001018181525050806001019050610bad565b508091505092915050565b60055f9054906101000a900460ff16610c67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c5e9061375e565b60405180910390fd5b67016345785d8a000081610c7b9190613368565b341015610cbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cb4906137c6565b60405180910390fd5b614e2081600454610cce91906137e4565b1115610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0690613861565b60405180910390fd5b8060045f828254610d2091906137e4565b92505081905550610d423360018360405180602001604052805f815250611b10565b50565b614e2081565b610d536118ec565b610d5c5f611bcb565b565b610d666118ec565b60055f9054906101000a900460ff161560055f6101000a81548160ff021916908315150217905550565b67016345785d8a000081565b5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60055f9054906101000a900460ff1681565b610de8610de1611973565b8383611c8e565b5050565b5f600282610dfa9190613368565b905080610e08336002610539565b1015610e49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e40906138c9565b60405180910390fd5b610e5533600283611a6e565b5f5b828110156110d3575f606444338442604051602001610e799493929190613476565b604051602081830303815290604052805190602001205f1c610e9b91906134f0565b90506032811015610f3a57610ee933600360016040518060400160405280601581526020017f4d696e74656420437570206f6620506f74696f6e2e0000000000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f92604051610f2d90613931565b60405180910390a26110c5565b6046811015610fd857610f873361012c60016040518060400160405280601581526020017f4d696e7465642054726970707920506f74696f6e2e0000000000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f92604051610fcb90613999565b60405180910390a26110c4565b605f811015611076576110253361012d60016040518060400160405280601681526020017f4d696e746564205261696e626f7720506f74696f6e2e00000000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f9260405161106990613a01565b60405180910390a26110c3565b3373ffffffffffffffffffffffffffffffffffffffff167f811f7cff0a3374ff67cccc3726035d34ba70410e0256818a891e4d6acc01d88e6040516110ba90613a69565b60405180910390a25b5b5b508080600101915050610e57565b505050565b5f6002826110e69190613368565b9050806110f4336004610539565b1015611135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112c90613ad1565b60405180910390fd5b61114133600483611a6e565b5f5b82811015611320575f6064443384426040516020016111659493929190613476565b604051602081830303815290604052805190602001205f1c61118791906134f0565b9050600a811015611226576111d533600560016040518060400160405280601a81526020017f4d696e7465642043616e6973746572206f6620506f74696f6e21000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f9260405161121990613b39565b60405180910390a2611312565b60288110156112c457611273336101f460016040518060400160405280601681526020017f4d696e74656420476f6c64204578706c6f73696f6e2100000000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f926040516112b790613ba1565b60405180910390a2611311565b3373ffffffffffffffffffffffffffffffffffffffff167f811f7cff0a3374ff67cccc3726035d34ba70410e0256818a891e4d6acc01d88e60405161130890613a69565b60405180910390a25b5b508080600101915050611143565b505050565b60045481565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f6002826113c79190613368565b9050806113d5336005610539565b1015611416576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140d90613c09565b60405180910390fd5b61142233600583611a6e565b5f5b82811015611562575f6064443384426040516020016114469493929190613476565b604051602081830303815290604052805190602001205f1c61146891906134f0565b90506032811015611507576114b633600660016040518060400160405280601c81526020017f4d696e74656420417065636861696e205363756c707475726521212100000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f926040516114fa90613c71565b60405180910390a2611554565b3373ffffffffffffffffffffffffffffffffffffffff167f811f7cff0a3374ff67cccc3726035d34ba70410e0256818a891e4d6acc01d88e60405161154b90613a69565b60405180910390a25b508080600101915050611424565b505050565b5f611570611973565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16141580156115b557506115b3868261132b565b155b156115f95780866040517fe237d9220000000000000000000000000000000000000000000000000000000081526004016115f0929190613314565b60405180910390fd5b6116068686868686611df7565b505050505050565b6116166118ec565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611686575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161167d9190612ec6565b60405180910390fd5b61168f81611bcb565b50565b5f6002826116a09190613368565b9050806116ae336001610539565b10156116ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e690613cd9565b60405180910390fd5b6116fb33600183611a6e565b5f5b8281101561187e575f60644433844260405160200161171f9493929190613476565b604051602081830303815290604052805190602001205f1c61174191906134f0565b905060558110156117e05761178f33600260016040518060400160405280601881526020017f4d696e74656420426f74746c65206f6620506f74696f6e2e0000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f926040516117d390613d41565b60405180910390a2611870565b6118233360c860016040518060400160405280601381526020017f4d696e746564204379616e20506f74696f6e2e00000000000000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f9260405161186790613da9565b60405180910390a25b5080806001019150506116fd565b505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6118f4611973565b73ffffffffffffffffffffffffffffffffffffffff16611912610d9c565b73ffffffffffffffffffffffffffffffffffffffff161461197157611935611973565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016119689190612ec6565b60405180910390fd5b565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036119ea575f6040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016119e19190612ec6565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611a5a575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401611a519190612ec6565b60405180910390fd5b611a678585858585611efd565b5050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611ade575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401611ad59190612ec6565b60405180910390fd5b5f80611aea8484611fa9565b91509150611b09855f848460405180602001604052805f815250611efd565b5050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611b80575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401611b779190612ec6565b60405180910390fd5b5f80611b8c8585611fa9565b91509150611b9d5f87848487611efd565b505050505050565b5f60208202602084010151905092915050565b5f60208202602084010151905092915050565b5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611cfe575f6040517fced3e100000000000000000000000000000000000000000000000000000000008152600401611cf59190612ec6565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611dea9190612865565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611e67575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401611e5e9190612ec6565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611ed7575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401611ece9190612ec6565b60405180910390fd5b5f80611ee38585611fa9565b91509150611ef48787848487611efd565b50505050505050565b611f0985858585611fd9565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614611fa2575f611f45611973565b90506001845103611f91575f611f645f86611bb890919063ffffffff16565b90505f611f7a5f86611bb890919063ffffffff16565b9050611f8a838989858589612369565b5050611fa0565b611f9f818787878787612518565b5b505b5050505050565b60608060405191506001825283602083015260408201905060018152826020820152604081016040529250929050565b805182511461202357815181516040517f5b05999100000000000000000000000000000000000000000000000000000000815260040161201a9291906136c0565b60405180910390fd5b5f61202c611973565b90505f5b8351811015612228575f61204d8286611bb890919063ffffffff16565b90505f6120638386611bb890919063ffffffff16565b90505f73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614612186575f805f8481526020019081526020015f205f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490508181101561213257888183856040517f03dee4c50000000000000000000000000000000000000000000000000000000081526004016121299493929190613dc7565b60405180910390fd5b8181035f808581526020019081526020015f205f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161461221b57805f808481526020019081526020015f205f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461221391906137e4565b925050819055505b5050806001019050612030565b5060018351036122e3575f6122465f85611bb890919063ffffffff16565b90505f61225c5f85611bb890919063ffffffff16565b90508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6285856040516122d49291906136c0565b60405180910390a45050612362565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051612359929190613e0a565b60405180910390a45b5050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115612510578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b81526004016123c9959493929190613e91565b6020604051808303815f875af192505050801561240457506040513d601f19601f820116820180604052508101906124019190613efd565b60015b612485573d805f8114612432576040519150601f19603f3d011682016040523d82523d5f602084013e612437565b606091505b505f81510361247d57846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016124749190612ec6565b60405180910390fd5b805181602001fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461250e57846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016125059190612ec6565b60405180910390fd5b505b505050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b11156126bf578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b8152600401612578959493929190613f28565b6020604051808303815f875af19250505080156125b357506040513d601f19601f820116820180604052508101906125b09190613efd565b60015b612634573d805f81146125e1576040519150601f19603f3d011682016040523d82523d5f602084013e6125e6565b606091505b505f81510361262c57846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016126239190612ec6565b60405180910390fd5b805181602001fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146126bd57846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016126b49190612ec6565b60405180910390fd5b505b505050505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612701826126d8565b9050919050565b612711816126f7565b811461271b575f80fd5b50565b5f8135905061272c81612708565b92915050565b5f819050919050565b61274481612732565b811461274e575f80fd5b50565b5f8135905061275f8161273b565b92915050565b5f806040838503121561277b5761277a6126d0565b5b5f6127888582860161271e565b925050602061279985828601612751565b9150509250929050565b6127ac81612732565b82525050565b5f6020820190506127c55f8301846127a3565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6127ff816127cb565b8114612809575f80fd5b50565b5f8135905061281a816127f6565b92915050565b5f60208284031215612835576128346126d0565b5b5f6128428482850161280c565b91505092915050565b5f8115159050919050565b61285f8161284b565b82525050565b5f6020820190506128785f830184612856565b92915050565b5f60208284031215612893576128926126d0565b5b5f6128a084828501612751565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6128eb826128a9565b6128f581856128b3565b93506129058185602086016128c3565b61290e816128d1565b840191505092915050565b5f6020820190508181035f83015261293181846128e1565b905092915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261295a57612959612939565b5b8235905067ffffffffffffffff8111156129775761297661293d565b5b60208301915083600182028301111561299357612992612941565b5b9250929050565b5f805f604084860312156129b1576129b06126d0565b5b5f6129be86828701612751565b935050602084013567ffffffffffffffff8111156129df576129de6126d4565b5b6129eb86828701612945565b92509250509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612a2d826128d1565b810181811067ffffffffffffffff82111715612a4c57612a4b6129f7565b5b80604052505050565b5f612a5e6126c7565b9050612a6a8282612a24565b919050565b5f67ffffffffffffffff821115612a8957612a886129f7565b5b602082029050602081019050919050565b5f612aac612aa784612a6f565b612a55565b90508083825260208201905060208402830185811115612acf57612ace612941565b5b835b81811015612af85780612ae48882612751565b845260208401935050602081019050612ad1565b5050509392505050565b5f82601f830112612b1657612b15612939565b5b8135612b26848260208601612a9a565b91505092915050565b5f80fd5b5f67ffffffffffffffff821115612b4d57612b4c6129f7565b5b612b56826128d1565b9050602081019050919050565b828183375f83830152505050565b5f612b83612b7e84612b33565b612a55565b905082815260208101848484011115612b9f57612b9e612b2f565b5b612baa848285612b63565b509392505050565b5f82601f830112612bc657612bc5612939565b5b8135612bd6848260208601612b71565b91505092915050565b5f805f805f60a08688031215612bf857612bf76126d0565b5b5f612c058882890161271e565b9550506020612c168882890161271e565b945050604086013567ffffffffffffffff811115612c3757612c366126d4565b5b612c4388828901612b02565b935050606086013567ffffffffffffffff811115612c6457612c636126d4565b5b612c7088828901612b02565b925050608086013567ffffffffffffffff811115612c9157612c906126d4565b5b612c9d88828901612bb2565b9150509295509295909350565b5f67ffffffffffffffff821115612cc457612cc36129f7565b5b602082029050602081019050919050565b5f612ce7612ce284612caa565b612a55565b90508083825260208201905060208402830185811115612d0a57612d09612941565b5b835b81811015612d335780612d1f888261271e565b845260208401935050602081019050612d0c565b5050509392505050565b5f82601f830112612d5157612d50612939565b5b8135612d61848260208601612cd5565b91505092915050565b5f8060408385031215612d8057612d7f6126d0565b5b5f83013567ffffffffffffffff811115612d9d57612d9c6126d4565b5b612da985828601612d3d565b925050602083013567ffffffffffffffff811115612dca57612dc96126d4565b5b612dd685828601612b02565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b612e1281612732565b82525050565b5f612e238383612e09565b60208301905092915050565b5f602082019050919050565b5f612e4582612de0565b612e4f8185612dea565b9350612e5a83612dfa565b805f5b83811015612e8a578151612e718882612e18565b9750612e7c83612e2f565b925050600181019050612e5d565b5085935050505092915050565b5f6020820190508181035f830152612eaf8184612e3b565b905092915050565b612ec0816126f7565b82525050565b5f602082019050612ed95f830184612eb7565b92915050565b612ee88161284b565b8114612ef2575f80fd5b50565b5f81359050612f0381612edf565b92915050565b5f8060408385031215612f1f57612f1e6126d0565b5b5f612f2c8582860161271e565b9250506020612f3d85828601612ef5565b9150509250929050565b5f8060408385031215612f5d57612f5c6126d0565b5b5f612f6a8582860161271e565b9250506020612f7b8582860161271e565b9150509250929050565b5f805f805f60a08688031215612f9e57612f9d6126d0565b5b5f612fab8882890161271e565b9550506020612fbc8882890161271e565b9450506040612fcd88828901612751565b9350506060612fde88828901612751565b925050608086013567ffffffffffffffff811115612fff57612ffe6126d4565b5b61300b88828901612bb2565b9150509295509295909350565b5f6020828403121561302d5761302c6126d0565b5b5f61303a8482850161271e565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061308757607f821691505b60208210810361309a57613099613043565b5b50919050565b5f82905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026131067fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826130cb565b61311086836130cb565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61314b61314661314184612732565b613128565b612732565b9050919050565b5f819050919050565b61316483613131565b61317861317082613152565b8484546130d7565b825550505050565b5f90565b61318c613180565b61319781848461315b565b505050565b5b818110156131ba576131af5f82613184565b60018101905061319d565b5050565b601f8211156131ff576131d0816130aa565b6131d9846130bc565b810160208510156131e8578190505b6131fc6131f4856130bc565b83018261319c565b50505b505050565b5f82821c905092915050565b5f61321f5f1984600802613204565b1980831691505092915050565b5f6132378383613210565b9150826002028217905092915050565b61325183836130a0565b67ffffffffffffffff81111561326a576132696129f7565b5b6132748254613070565b61327f8282856131be565b5f601f8311600181146132ac575f841561329a578287013590505b6132a4858261322c565b86555061330b565b601f1984166132ba866130aa565b5f5b828110156132e1578489013582556001820191506020850194506020810190506132bc565b868310156132fe57848901356132fa601f891682613210565b8355505b6001600288020188555050505b50505050505050565b5f6040820190506133275f830185612eb7565b6133346020830184612eb7565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61337282612732565b915061337d83612732565b925082820261338b81612732565b915082820484148315176133a2576133a161333b565b5b5092915050565b7f4e6f7420656e6f756768206c6576656c203320746f6b656e73000000000000005f82015250565b5f6133dd6019836128b3565b91506133e8826133a9565b602082019050919050565b5f6020820190508181035f83015261340a816133d1565b9050919050565b5f819050919050565b61342b61342682612732565b613411565b82525050565b5f8160601b9050919050565b5f61344782613431565b9050919050565b5f6134588261343d565b9050919050565b61347061346b826126f7565b61344e565b82525050565b5f613481828761341a565b602082019150613491828661345f565b6014820191506134a1828561341a565b6020820191506134b1828461341a565b60208201915081905095945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6134fa82612732565b915061350583612732565b925082613515576135146134c3565b5b828206905092915050565b7f4d696e746564204b6567206f6620506f74696f6e2e00000000000000000000005f82015250565b5f6135546015836128b3565b915061355f82613520565b602082019050919050565b5f6020820190508181035f83015261358181613548565b9050919050565b7f4d696e7465642050696e6b20506f74696f6e2e000000000000000000000000005f82015250565b5f6135bc6013836128b3565b91506135c782613588565b602082019050919050565b5f6020820190508181035f8301526135e9816135b0565b9050919050565b7f4d696e7465642050696e6b204578706c6f73696f6e21000000000000000000005f82015250565b5f6136246016836128b3565b915061362f826135f0565b602082019050919050565b5f6020820190508181035f83015261365181613618565b9050919050565b7f4e6f2041504520617661696c61626c65000000000000000000000000000000005f82015250565b5f61368c6010836128b3565b915061369782613658565b602082019050919050565b5f6020820190508181035f8301526136b981613680565b9050919050565b5f6040820190506136d35f8301856127a3565b6136e060208301846127a3565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4d696e74696e67206973206e6f74206f70656e000000000000000000000000005f82015250565b5f6137486013836128b3565b915061375382613714565b602082019050919050565b5f6020820190508181035f8301526137758161373c565b9050919050565b7f496e73756666696369656e74204150452073656e7400000000000000000000005f82015250565b5f6137b06015836128b3565b91506137bb8261377c565b602082019050919050565b5f6020820190508181035f8301526137dd816137a4565b9050919050565b5f6137ee82612732565b91506137f983612732565b92508282019050808211156138115761381061333b565b5b92915050565b7f4d617820737570706c79207265616368656400000000000000000000000000005f82015250565b5f61384b6012836128b3565b915061385682613817565b602082019050919050565b5f6020820190508181035f8301526138788161383f565b9050919050565b7f4e6f7420656e6f756768206c6576656c203220746f6b656e73000000000000005f82015250565b5f6138b36019836128b3565b91506138be8261387f565b602082019050919050565b5f6020820190508181035f8301526138e0816138a7565b9050919050565b7f4d696e74656420437570206f6620506f74696f6e2e00000000000000000000005f82015250565b5f61391b6015836128b3565b9150613926826138e7565b602082019050919050565b5f6020820190508181035f8301526139488161390f565b9050919050565b7f4d696e7465642054726970707920506f74696f6e2e00000000000000000000005f82015250565b5f6139836015836128b3565b915061398e8261394f565b602082019050919050565b5f6020820190508181035f8301526139b081613977565b9050919050565b7f4d696e746564205261696e626f7720506f74696f6e2e000000000000000000005f82015250565b5f6139eb6016836128b3565b91506139f6826139b7565b602082019050919050565b5f6020820190508181035f830152613a18816139df565b9050919050565b7f596f7520676f74206e6f7468696e672e000000000000000000000000000000005f82015250565b5f613a536010836128b3565b9150613a5e82613a1f565b602082019050919050565b5f6020820190508181035f830152613a8081613a47565b9050919050565b7f4e6f7420656e6f756768206c6576656c203420746f6b656e73000000000000005f82015250565b5f613abb6019836128b3565b9150613ac682613a87565b602082019050919050565b5f6020820190508181035f830152613ae881613aaf565b9050919050565b7f4d696e7465642043616e6973746572206f6620506f74696f6e210000000000005f82015250565b5f613b23601a836128b3565b9150613b2e82613aef565b602082019050919050565b5f6020820190508181035f830152613b5081613b17565b9050919050565b7f4d696e74656420476f6c64204578706c6f73696f6e21000000000000000000005f82015250565b5f613b8b6016836128b3565b9150613b9682613b57565b602082019050919050565b5f6020820190508181035f830152613bb881613b7f565b9050919050565b7f4e6f7420656e6f756768206c6576656c203520746f6b656e73000000000000005f82015250565b5f613bf36019836128b3565b9150613bfe82613bbf565b602082019050919050565b5f6020820190508181035f830152613c2081613be7565b9050919050565b7f4d696e74656420417065636861696e205363756c7074757265212121000000005f82015250565b5f613c5b601c836128b3565b9150613c6682613c27565b602082019050919050565b5f6020820190508181035f830152613c8881613c4f565b9050919050565b7f4e6f7420656e6f756768206c6576656c203120746f6b656e73000000000000005f82015250565b5f613cc36019836128b3565b9150613cce82613c8f565b602082019050919050565b5f6020820190508181035f830152613cf081613cb7565b9050919050565b7f4d696e74656420426f74746c65206f6620506f74696f6e2e00000000000000005f82015250565b5f613d2b6018836128b3565b9150613d3682613cf7565b602082019050919050565b5f6020820190508181035f830152613d5881613d1f565b9050919050565b7f4d696e746564204379616e20506f74696f6e2e000000000000000000000000005f82015250565b5f613d936013836128b3565b9150613d9e82613d5f565b602082019050919050565b5f6020820190508181035f830152613dc081613d87565b9050919050565b5f608082019050613dda5f830187612eb7565b613de760208301866127a3565b613df460408301856127a3565b613e0160608301846127a3565b95945050505050565b5f6040820190508181035f830152613e228185612e3b565b90508181036020830152613e368184612e3b565b90509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f613e6382613e3f565b613e6d8185613e49565b9350613e7d8185602086016128c3565b613e86816128d1565b840191505092915050565b5f60a082019050613ea45f830188612eb7565b613eb16020830187612eb7565b613ebe60408301866127a3565b613ecb60608301856127a3565b8181036080830152613edd8184613e59565b90509695505050505050565b5f81519050613ef7816127f6565b92915050565b5f60208284031215613f1257613f116126d0565b5b5f613f1f84828501613ee9565b91505092915050565b5f60a082019050613f3b5f830188612eb7565b613f486020830187612eb7565b8181036040830152613f5a8186612e3b565b90508181036060830152613f6e8185612e3b565b90508181036080830152613f828184613e59565b9050969550505050505056fea264697066735822122042765bae25b7949675932f02fc8e8772328cea390c695a7afbba53e20e9331eb64736f6c634300081a0033

Deployed Bytecode

0x608060405260043610610149575f3560e01c80638d859f3e116100b5578063bfcee0b61161006e578063bfcee0b614610433578063e985e9c51461045d578063ea39e31a14610499578063f242432a146104c1578063f2fde38b146104e9578063f847d7231461051157610149565b80638d859f3e1461033d5780638da5cb5b146103675780638f4bb49714610391578063a22cb465146103bb578063a9bca560146103e3578063ae291e421461040b57610149565b80633ccfd60b116101075780633ccfd60b146102795780634e1273f41461028f578063601faccf146102cb57806361942327146102e7578063715018a6146103115780637d55094d1461032757610149565b8062fdd58e1461014d57806301ffc9a7146101895780630e89341c146101c5578063162094c4146102015780632eb2c2d6146102295780633563794c14610251575b5f80fd5b348015610158575f80fd5b50610173600480360381019061016e9190612765565b610539565b60405161018091906127b2565b60405180910390f35b348015610194575f80fd5b506101af60048036038101906101aa9190612820565b61058e565b6040516101bc9190612865565b60405180910390f35b3480156101d0575f80fd5b506101eb60048036038101906101e6919061287e565b61066f565b6040516101f89190612919565b60405180910390f35b34801561020c575f80fd5b506102276004803603810190610222919061299a565b610710565b005b348015610234575f80fd5b5061024f600480360381019061024a9190612bdf565b61073e565b005b34801561025c575f80fd5b506102776004803603810190610272919061287e565b6107e5565b005b348015610284575f80fd5b5061028d610a76565b005b34801561029a575f80fd5b506102b560048036038101906102b09190612d6a565b610b12565b6040516102c29190612e97565b60405180910390f35b6102e560048036038101906102e0919061287e565b610c19565b005b3480156102f2575f80fd5b506102fb610d45565b60405161030891906127b2565b60405180910390f35b34801561031c575f80fd5b50610325610d4b565b005b348015610332575f80fd5b5061033b610d5e565b005b348015610348575f80fd5b50610351610d90565b60405161035e91906127b2565b60405180910390f35b348015610372575f80fd5b5061037b610d9c565b6040516103889190612ec6565b60405180910390f35b34801561039c575f80fd5b506103a5610dc4565b6040516103b29190612865565b60405180910390f35b3480156103c6575f80fd5b506103e160048036038101906103dc9190612f09565b610dd6565b005b3480156103ee575f80fd5b506104096004803603810190610404919061287e565b610dec565b005b348015610416575f80fd5b50610431600480360381019061042c919061287e565b6110d8565b005b34801561043e575f80fd5b50610447611325565b60405161045491906127b2565b60405180910390f35b348015610468575f80fd5b50610483600480360381019061047e9190612f47565b61132b565b6040516104909190612865565b60405180910390f35b3480156104a4575f80fd5b506104bf60048036038101906104ba919061287e565b6113b9565b005b3480156104cc575f80fd5b506104e760048036038101906104e29190612f85565b611567565b005b3480156104f4575f80fd5b5061050f600480360381019061050a9190613018565b61160e565b005b34801561051c575f80fd5b506105376004803603810190610532919061287e565b611692565b005b5f805f8381526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f7fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061065857507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610668575061066782611883565b5b9050919050565b606060065f8381526020019081526020015f20805461068d90613070565b80601f01602080910402602001604051908101604052809291908181526020018280546106b990613070565b80156107045780601f106106db57610100808354040283529160200191610704565b820191905f5260205f20905b8154815290600101906020018083116106e757829003601f168201915b50505050509050919050565b6107186118ec565b818160065f8681526020019081526020015f209182610738929190613247565b50505050565b5f610747611973565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561078c575061078a868261132b565b155b156107d05780866040517fe237d9220000000000000000000000000000000000000000000000000000000081526004016107c7929190613314565b60405180910390fd5b6107dd868686868661197a565b505050505050565b5f6002826107f39190613368565b905080610801336003610539565b1015610842576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610839906133f3565b60405180910390fd5b61084e33600383611a6e565b5f5b82811015610a71575f6064443384426040516020016108729493929190613476565b604051602081830303815290604052805190602001205f1c61089491906134f0565b9050601e811015610933576108e233600460016040518060400160405280601581526020017f4d696e746564204b6567206f6620506f74696f6e2e0000000000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f926040516109269061356a565b60405180910390a2610a63565b60508110156109d1576109803361019060016040518060400160405280601381526020017f4d696e7465642050696e6b20506f74696f6e2e00000000000000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f926040516109c4906135d2565b60405180910390a2610a62565b610a153361019160016040518060400160405280601681526020017f4d696e7465642050696e6b204578706c6f73696f6e2100000000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f92604051610a599061363a565b60405180910390a25b5b508080600101915050610850565b505050565b610a7e6118ec565b5f4790505f8111610ac4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610abb906136a2565b60405180910390fd5b610acc610d9c565b73ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015610b0e573d5f803e3d5ffd5b5050565b60608151835114610b5e57815183516040517f5b059991000000000000000000000000000000000000000000000000000000008152600401610b559291906136c0565b60405180910390fd5b5f835167ffffffffffffffff811115610b7a57610b796129f7565b5b604051908082528060200260200182016040528015610ba85781602001602082028036833780820191505090505b5090505f5b8451811015610c0e57610be4610bcc8287611ba590919063ffffffff16565b610bdf8387611bb890919063ffffffff16565b610539565b828281518110610bf757610bf66136e7565b5b602002602001018181525050806001019050610bad565b508091505092915050565b60055f9054906101000a900460ff16610c67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c5e9061375e565b60405180910390fd5b67016345785d8a000081610c7b9190613368565b341015610cbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cb4906137c6565b60405180910390fd5b614e2081600454610cce91906137e4565b1115610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0690613861565b60405180910390fd5b8060045f828254610d2091906137e4565b92505081905550610d423360018360405180602001604052805f815250611b10565b50565b614e2081565b610d536118ec565b610d5c5f611bcb565b565b610d666118ec565b60055f9054906101000a900460ff161560055f6101000a81548160ff021916908315150217905550565b67016345785d8a000081565b5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60055f9054906101000a900460ff1681565b610de8610de1611973565b8383611c8e565b5050565b5f600282610dfa9190613368565b905080610e08336002610539565b1015610e49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e40906138c9565b60405180910390fd5b610e5533600283611a6e565b5f5b828110156110d3575f606444338442604051602001610e799493929190613476565b604051602081830303815290604052805190602001205f1c610e9b91906134f0565b90506032811015610f3a57610ee933600360016040518060400160405280601581526020017f4d696e74656420437570206f6620506f74696f6e2e0000000000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f92604051610f2d90613931565b60405180910390a26110c5565b6046811015610fd857610f873361012c60016040518060400160405280601581526020017f4d696e7465642054726970707920506f74696f6e2e0000000000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f92604051610fcb90613999565b60405180910390a26110c4565b605f811015611076576110253361012d60016040518060400160405280601681526020017f4d696e746564205261696e626f7720506f74696f6e2e00000000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f9260405161106990613a01565b60405180910390a26110c3565b3373ffffffffffffffffffffffffffffffffffffffff167f811f7cff0a3374ff67cccc3726035d34ba70410e0256818a891e4d6acc01d88e6040516110ba90613a69565b60405180910390a25b5b5b508080600101915050610e57565b505050565b5f6002826110e69190613368565b9050806110f4336004610539565b1015611135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112c90613ad1565b60405180910390fd5b61114133600483611a6e565b5f5b82811015611320575f6064443384426040516020016111659493929190613476565b604051602081830303815290604052805190602001205f1c61118791906134f0565b9050600a811015611226576111d533600560016040518060400160405280601a81526020017f4d696e7465642043616e6973746572206f6620506f74696f6e21000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f9260405161121990613b39565b60405180910390a2611312565b60288110156112c457611273336101f460016040518060400160405280601681526020017f4d696e74656420476f6c64204578706c6f73696f6e2100000000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f926040516112b790613ba1565b60405180910390a2611311565b3373ffffffffffffffffffffffffffffffffffffffff167f811f7cff0a3374ff67cccc3726035d34ba70410e0256818a891e4d6acc01d88e60405161130890613a69565b60405180910390a25b5b508080600101915050611143565b505050565b60045481565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f6002826113c79190613368565b9050806113d5336005610539565b1015611416576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140d90613c09565b60405180910390fd5b61142233600583611a6e565b5f5b82811015611562575f6064443384426040516020016114469493929190613476565b604051602081830303815290604052805190602001205f1c61146891906134f0565b90506032811015611507576114b633600660016040518060400160405280601c81526020017f4d696e74656420417065636861696e205363756c707475726521212100000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f926040516114fa90613c71565b60405180910390a2611554565b3373ffffffffffffffffffffffffffffffffffffffff167f811f7cff0a3374ff67cccc3726035d34ba70410e0256818a891e4d6acc01d88e60405161154b90613a69565b60405180910390a25b508080600101915050611424565b505050565b5f611570611973565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16141580156115b557506115b3868261132b565b155b156115f95780866040517fe237d9220000000000000000000000000000000000000000000000000000000081526004016115f0929190613314565b60405180910390fd5b6116068686868686611df7565b505050505050565b6116166118ec565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611686575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161167d9190612ec6565b60405180910390fd5b61168f81611bcb565b50565b5f6002826116a09190613368565b9050806116ae336001610539565b10156116ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e690613cd9565b60405180910390fd5b6116fb33600183611a6e565b5f5b8281101561187e575f60644433844260405160200161171f9493929190613476565b604051602081830303815290604052805190602001205f1c61174191906134f0565b905060558110156117e05761178f33600260016040518060400160405280601881526020017f4d696e74656420426f74746c65206f6620506f74696f6e2e0000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f926040516117d390613d41565b60405180910390a2611870565b6118233360c860016040518060400160405280601381526020017f4d696e746564204379616e20506f74696f6e2e00000000000000000000000000815250611b10565b3373ffffffffffffffffffffffffffffffffffffffff167f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f9260405161186790613da9565b60405180910390a25b5080806001019150506116fd565b505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6118f4611973565b73ffffffffffffffffffffffffffffffffffffffff16611912610d9c565b73ffffffffffffffffffffffffffffffffffffffff161461197157611935611973565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016119689190612ec6565b60405180910390fd5b565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036119ea575f6040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016119e19190612ec6565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611a5a575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401611a519190612ec6565b60405180910390fd5b611a678585858585611efd565b5050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611ade575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401611ad59190612ec6565b60405180910390fd5b5f80611aea8484611fa9565b91509150611b09855f848460405180602001604052805f815250611efd565b5050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611b80575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401611b779190612ec6565b60405180910390fd5b5f80611b8c8585611fa9565b91509150611b9d5f87848487611efd565b505050505050565b5f60208202602084010151905092915050565b5f60208202602084010151905092915050565b5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611cfe575f6040517fced3e100000000000000000000000000000000000000000000000000000000008152600401611cf59190612ec6565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611dea9190612865565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611e67575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401611e5e9190612ec6565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611ed7575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401611ece9190612ec6565b60405180910390fd5b5f80611ee38585611fa9565b91509150611ef48787848487611efd565b50505050505050565b611f0985858585611fd9565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614611fa2575f611f45611973565b90506001845103611f91575f611f645f86611bb890919063ffffffff16565b90505f611f7a5f86611bb890919063ffffffff16565b9050611f8a838989858589612369565b5050611fa0565b611f9f818787878787612518565b5b505b5050505050565b60608060405191506001825283602083015260408201905060018152826020820152604081016040529250929050565b805182511461202357815181516040517f5b05999100000000000000000000000000000000000000000000000000000000815260040161201a9291906136c0565b60405180910390fd5b5f61202c611973565b90505f5b8351811015612228575f61204d8286611bb890919063ffffffff16565b90505f6120638386611bb890919063ffffffff16565b90505f73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614612186575f805f8481526020019081526020015f205f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490508181101561213257888183856040517f03dee4c50000000000000000000000000000000000000000000000000000000081526004016121299493929190613dc7565b60405180910390fd5b8181035f808581526020019081526020015f205f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161461221b57805f808481526020019081526020015f205f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461221391906137e4565b925050819055505b5050806001019050612030565b5060018351036122e3575f6122465f85611bb890919063ffffffff16565b90505f61225c5f85611bb890919063ffffffff16565b90508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6285856040516122d49291906136c0565b60405180910390a45050612362565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051612359929190613e0a565b60405180910390a45b5050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115612510578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b81526004016123c9959493929190613e91565b6020604051808303815f875af192505050801561240457506040513d601f19601f820116820180604052508101906124019190613efd565b60015b612485573d805f8114612432576040519150601f19603f3d011682016040523d82523d5f602084013e612437565b606091505b505f81510361247d57846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016124749190612ec6565b60405180910390fd5b805181602001fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461250e57846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016125059190612ec6565b60405180910390fd5b505b505050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b11156126bf578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b8152600401612578959493929190613f28565b6020604051808303815f875af19250505080156125b357506040513d601f19601f820116820180604052508101906125b09190613efd565b60015b612634573d805f81146125e1576040519150601f19603f3d011682016040523d82523d5f602084013e6125e6565b606091505b505f81510361262c57846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016126239190612ec6565b60405180910390fd5b805181602001fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146126bd57846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016126b49190612ec6565b60405180910390fd5b505b505050505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612701826126d8565b9050919050565b612711816126f7565b811461271b575f80fd5b50565b5f8135905061272c81612708565b92915050565b5f819050919050565b61274481612732565b811461274e575f80fd5b50565b5f8135905061275f8161273b565b92915050565b5f806040838503121561277b5761277a6126d0565b5b5f6127888582860161271e565b925050602061279985828601612751565b9150509250929050565b6127ac81612732565b82525050565b5f6020820190506127c55f8301846127a3565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6127ff816127cb565b8114612809575f80fd5b50565b5f8135905061281a816127f6565b92915050565b5f60208284031215612835576128346126d0565b5b5f6128428482850161280c565b91505092915050565b5f8115159050919050565b61285f8161284b565b82525050565b5f6020820190506128785f830184612856565b92915050565b5f60208284031215612893576128926126d0565b5b5f6128a084828501612751565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6128eb826128a9565b6128f581856128b3565b93506129058185602086016128c3565b61290e816128d1565b840191505092915050565b5f6020820190508181035f83015261293181846128e1565b905092915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261295a57612959612939565b5b8235905067ffffffffffffffff8111156129775761297661293d565b5b60208301915083600182028301111561299357612992612941565b5b9250929050565b5f805f604084860312156129b1576129b06126d0565b5b5f6129be86828701612751565b935050602084013567ffffffffffffffff8111156129df576129de6126d4565b5b6129eb86828701612945565b92509250509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612a2d826128d1565b810181811067ffffffffffffffff82111715612a4c57612a4b6129f7565b5b80604052505050565b5f612a5e6126c7565b9050612a6a8282612a24565b919050565b5f67ffffffffffffffff821115612a8957612a886129f7565b5b602082029050602081019050919050565b5f612aac612aa784612a6f565b612a55565b90508083825260208201905060208402830185811115612acf57612ace612941565b5b835b81811015612af85780612ae48882612751565b845260208401935050602081019050612ad1565b5050509392505050565b5f82601f830112612b1657612b15612939565b5b8135612b26848260208601612a9a565b91505092915050565b5f80fd5b5f67ffffffffffffffff821115612b4d57612b4c6129f7565b5b612b56826128d1565b9050602081019050919050565b828183375f83830152505050565b5f612b83612b7e84612b33565b612a55565b905082815260208101848484011115612b9f57612b9e612b2f565b5b612baa848285612b63565b509392505050565b5f82601f830112612bc657612bc5612939565b5b8135612bd6848260208601612b71565b91505092915050565b5f805f805f60a08688031215612bf857612bf76126d0565b5b5f612c058882890161271e565b9550506020612c168882890161271e565b945050604086013567ffffffffffffffff811115612c3757612c366126d4565b5b612c4388828901612b02565b935050606086013567ffffffffffffffff811115612c6457612c636126d4565b5b612c7088828901612b02565b925050608086013567ffffffffffffffff811115612c9157612c906126d4565b5b612c9d88828901612bb2565b9150509295509295909350565b5f67ffffffffffffffff821115612cc457612cc36129f7565b5b602082029050602081019050919050565b5f612ce7612ce284612caa565b612a55565b90508083825260208201905060208402830185811115612d0a57612d09612941565b5b835b81811015612d335780612d1f888261271e565b845260208401935050602081019050612d0c565b5050509392505050565b5f82601f830112612d5157612d50612939565b5b8135612d61848260208601612cd5565b91505092915050565b5f8060408385031215612d8057612d7f6126d0565b5b5f83013567ffffffffffffffff811115612d9d57612d9c6126d4565b5b612da985828601612d3d565b925050602083013567ffffffffffffffff811115612dca57612dc96126d4565b5b612dd685828601612b02565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b612e1281612732565b82525050565b5f612e238383612e09565b60208301905092915050565b5f602082019050919050565b5f612e4582612de0565b612e4f8185612dea565b9350612e5a83612dfa565b805f5b83811015612e8a578151612e718882612e18565b9750612e7c83612e2f565b925050600181019050612e5d565b5085935050505092915050565b5f6020820190508181035f830152612eaf8184612e3b565b905092915050565b612ec0816126f7565b82525050565b5f602082019050612ed95f830184612eb7565b92915050565b612ee88161284b565b8114612ef2575f80fd5b50565b5f81359050612f0381612edf565b92915050565b5f8060408385031215612f1f57612f1e6126d0565b5b5f612f2c8582860161271e565b9250506020612f3d85828601612ef5565b9150509250929050565b5f8060408385031215612f5d57612f5c6126d0565b5b5f612f6a8582860161271e565b9250506020612f7b8582860161271e565b9150509250929050565b5f805f805f60a08688031215612f9e57612f9d6126d0565b5b5f612fab8882890161271e565b9550506020612fbc8882890161271e565b9450506040612fcd88828901612751565b9350506060612fde88828901612751565b925050608086013567ffffffffffffffff811115612fff57612ffe6126d4565b5b61300b88828901612bb2565b9150509295509295909350565b5f6020828403121561302d5761302c6126d0565b5b5f61303a8482850161271e565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061308757607f821691505b60208210810361309a57613099613043565b5b50919050565b5f82905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026131067fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826130cb565b61311086836130cb565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61314b61314661314184612732565b613128565b612732565b9050919050565b5f819050919050565b61316483613131565b61317861317082613152565b8484546130d7565b825550505050565b5f90565b61318c613180565b61319781848461315b565b505050565b5b818110156131ba576131af5f82613184565b60018101905061319d565b5050565b601f8211156131ff576131d0816130aa565b6131d9846130bc565b810160208510156131e8578190505b6131fc6131f4856130bc565b83018261319c565b50505b505050565b5f82821c905092915050565b5f61321f5f1984600802613204565b1980831691505092915050565b5f6132378383613210565b9150826002028217905092915050565b61325183836130a0565b67ffffffffffffffff81111561326a576132696129f7565b5b6132748254613070565b61327f8282856131be565b5f601f8311600181146132ac575f841561329a578287013590505b6132a4858261322c565b86555061330b565b601f1984166132ba866130aa565b5f5b828110156132e1578489013582556001820191506020850194506020810190506132bc565b868310156132fe57848901356132fa601f891682613210565b8355505b6001600288020188555050505b50505050505050565b5f6040820190506133275f830185612eb7565b6133346020830184612eb7565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61337282612732565b915061337d83612732565b925082820261338b81612732565b915082820484148315176133a2576133a161333b565b5b5092915050565b7f4e6f7420656e6f756768206c6576656c203320746f6b656e73000000000000005f82015250565b5f6133dd6019836128b3565b91506133e8826133a9565b602082019050919050565b5f6020820190508181035f83015261340a816133d1565b9050919050565b5f819050919050565b61342b61342682612732565b613411565b82525050565b5f8160601b9050919050565b5f61344782613431565b9050919050565b5f6134588261343d565b9050919050565b61347061346b826126f7565b61344e565b82525050565b5f613481828761341a565b602082019150613491828661345f565b6014820191506134a1828561341a565b6020820191506134b1828461341a565b60208201915081905095945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6134fa82612732565b915061350583612732565b925082613515576135146134c3565b5b828206905092915050565b7f4d696e746564204b6567206f6620506f74696f6e2e00000000000000000000005f82015250565b5f6135546015836128b3565b915061355f82613520565b602082019050919050565b5f6020820190508181035f83015261358181613548565b9050919050565b7f4d696e7465642050696e6b20506f74696f6e2e000000000000000000000000005f82015250565b5f6135bc6013836128b3565b91506135c782613588565b602082019050919050565b5f6020820190508181035f8301526135e9816135b0565b9050919050565b7f4d696e7465642050696e6b204578706c6f73696f6e21000000000000000000005f82015250565b5f6136246016836128b3565b915061362f826135f0565b602082019050919050565b5f6020820190508181035f83015261365181613618565b9050919050565b7f4e6f2041504520617661696c61626c65000000000000000000000000000000005f82015250565b5f61368c6010836128b3565b915061369782613658565b602082019050919050565b5f6020820190508181035f8301526136b981613680565b9050919050565b5f6040820190506136d35f8301856127a3565b6136e060208301846127a3565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4d696e74696e67206973206e6f74206f70656e000000000000000000000000005f82015250565b5f6137486013836128b3565b915061375382613714565b602082019050919050565b5f6020820190508181035f8301526137758161373c565b9050919050565b7f496e73756666696369656e74204150452073656e7400000000000000000000005f82015250565b5f6137b06015836128b3565b91506137bb8261377c565b602082019050919050565b5f6020820190508181035f8301526137dd816137a4565b9050919050565b5f6137ee82612732565b91506137f983612732565b92508282019050808211156138115761381061333b565b5b92915050565b7f4d617820737570706c79207265616368656400000000000000000000000000005f82015250565b5f61384b6012836128b3565b915061385682613817565b602082019050919050565b5f6020820190508181035f8301526138788161383f565b9050919050565b7f4e6f7420656e6f756768206c6576656c203220746f6b656e73000000000000005f82015250565b5f6138b36019836128b3565b91506138be8261387f565b602082019050919050565b5f6020820190508181035f8301526138e0816138a7565b9050919050565b7f4d696e74656420437570206f6620506f74696f6e2e00000000000000000000005f82015250565b5f61391b6015836128b3565b9150613926826138e7565b602082019050919050565b5f6020820190508181035f8301526139488161390f565b9050919050565b7f4d696e7465642054726970707920506f74696f6e2e00000000000000000000005f82015250565b5f6139836015836128b3565b915061398e8261394f565b602082019050919050565b5f6020820190508181035f8301526139b081613977565b9050919050565b7f4d696e746564205261696e626f7720506f74696f6e2e000000000000000000005f82015250565b5f6139eb6016836128b3565b91506139f6826139b7565b602082019050919050565b5f6020820190508181035f830152613a18816139df565b9050919050565b7f596f7520676f74206e6f7468696e672e000000000000000000000000000000005f82015250565b5f613a536010836128b3565b9150613a5e82613a1f565b602082019050919050565b5f6020820190508181035f830152613a8081613a47565b9050919050565b7f4e6f7420656e6f756768206c6576656c203420746f6b656e73000000000000005f82015250565b5f613abb6019836128b3565b9150613ac682613a87565b602082019050919050565b5f6020820190508181035f830152613ae881613aaf565b9050919050565b7f4d696e7465642043616e6973746572206f6620506f74696f6e210000000000005f82015250565b5f613b23601a836128b3565b9150613b2e82613aef565b602082019050919050565b5f6020820190508181035f830152613b5081613b17565b9050919050565b7f4d696e74656420476f6c64204578706c6f73696f6e21000000000000000000005f82015250565b5f613b8b6016836128b3565b9150613b9682613b57565b602082019050919050565b5f6020820190508181035f830152613bb881613b7f565b9050919050565b7f4e6f7420656e6f756768206c6576656c203520746f6b656e73000000000000005f82015250565b5f613bf36019836128b3565b9150613bfe82613bbf565b602082019050919050565b5f6020820190508181035f830152613c2081613be7565b9050919050565b7f4d696e74656420417065636861696e205363756c7074757265212121000000005f82015250565b5f613c5b601c836128b3565b9150613c6682613c27565b602082019050919050565b5f6020820190508181035f830152613c8881613c4f565b9050919050565b7f4e6f7420656e6f756768206c6576656c203120746f6b656e73000000000000005f82015250565b5f613cc36019836128b3565b9150613cce82613c8f565b602082019050919050565b5f6020820190508181035f830152613cf081613cb7565b9050919050565b7f4d696e74656420426f74746c65206f6620506f74696f6e2e00000000000000005f82015250565b5f613d2b6018836128b3565b9150613d3682613cf7565b602082019050919050565b5f6020820190508181035f830152613d5881613d1f565b9050919050565b7f4d696e746564204379616e20506f74696f6e2e000000000000000000000000005f82015250565b5f613d936013836128b3565b9150613d9e82613d5f565b602082019050919050565b5f6020820190508181035f830152613dc081613d87565b9050919050565b5f608082019050613dda5f830187612eb7565b613de760208301866127a3565b613df460408301856127a3565b613e0160608301846127a3565b95945050505050565b5f6040820190508181035f830152613e228185612e3b565b90508181036020830152613e368184612e3b565b90509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f613e6382613e3f565b613e6d8185613e49565b9350613e7d8185602086016128c3565b613e86816128d1565b840191505092915050565b5f60a082019050613ea45f830188612eb7565b613eb16020830187612eb7565b613ebe60408301866127a3565b613ecb60608301856127a3565b8181036080830152613edd8184613e59565b90509695505050505050565b5f81519050613ef7816127f6565b92915050565b5f60208284031215613f1257613f116126d0565b5b5f613f1f84828501613ee9565b91505092915050565b5f60a082019050613f3b5f830188612eb7565b613f486020830187612eb7565b8181036040830152613f5a8186612e3b565b90508181036060830152613f6e8185612e3b565b90508181036080830152613f828184613e59565b9050969550505050505056fea264697066735822122042765bae25b7949675932f02fc8e8772328cea390c695a7afbba53e20e9331eb64736f6c634300081a0033

Deployed Bytecode Sourcemap

135440:6512:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;119405:134;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;118514:310;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;136118:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;136296:127;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;121228:441;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;138993:994;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;141756:193;;;;;;;;;;;;;:::i;:::-;;119705:567;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;136567:347;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;135489:49;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;134377:103;;;;;;;;;;;;;:::i;:::-;;136922:85;;;;;;;;;;;;;:::i;:::-;;135579:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;133702:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135742:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;120345:146;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137874:1111;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;139995:935;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;135545:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;120563:159;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;140938:751;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;120794:357;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;134635:220;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137042:824;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;119405:134;119482:7;119509:9;:13;119519:2;119509:13;;;;;;;;;;;:22;119523:7;119509:22;;;;;;;;;;;;;;;;119502:29;;119405:134;;;;:::o;118514:310::-;118616:4;118668:26;118653:41;;;:11;:41;;;;:110;;;;118726:37;118711:52;;;:11;:52;;;;118653:110;:163;;;;118780:36;118804:11;118780:23;:36::i;:::-;118653:163;118633:183;;118514:310;;;:::o;136118:119::-;136178:13;136211:9;:18;136221:7;136211:18;;;;;;;;;;;136204:25;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;136118:119;;;:::o;136296:127::-;133588:13;:11;:13::i;:::-;136409:6:::1;;136388:9;:18;136398:7;136388:18;;;;;;;;;;;:27;;;;;;;:::i;:::-;;136296:127:::0;;;:::o;121228:441::-;121429:14;121446:12;:10;:12::i;:::-;121429:29;;121481:6;121473:14;;:4;:14;;;;:49;;;;;121492:30;121509:4;121515:6;121492:16;:30::i;:::-;121491:31;121473:49;121469:131;;;121575:6;121583:4;121546:42;;;;;;;;;;;;:::i;:::-;;;;;;;;121469:131;121610:51;121633:4;121639:2;121643:3;121648:6;121656:4;121610:22;:51::i;:::-;121418:251;121228:441;;;;;:::o;138993:994::-;139050:16;139078:1;139069:6;:10;;;;:::i;:::-;139050:29;;139126:8;139098:24;139108:10;139120:1;139098:9;:24::i;:::-;:36;;139090:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;139175:30;139181:10;139193:1;139196:8;139175:5;:30::i;:::-;139223:9;139218:762;139242:6;139238:1;:10;139218:762;;;139347:14;139453:3;139399:16;139417:10;139429:1;139432:15;139382:66;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;139372:77;;;;;;139364:86;;:92;;;;:::i;:::-;139347:109;;139485:2;139476:6;:11;139473:496;;;139508:48;139514:10;139526:1;139529;139508:48;;;;;;;;;;;;;;;;;:5;:48::i;:::-;139587:10;139580:43;;;;;;;;:::i;:::-;;;;;;;;139473:496;;;139657:2;139648:6;:11;139645:324;;;139680:48;139686:10;139698:3;139703:1;139680:48;;;;;;;;;;;;;;;;;:5;:48::i;:::-;139759:10;139752:41;;;;;;;;:::i;:::-;;;;;;;;139645:324;;;139834:51;139840:10;139852:3;139857:1;139834:51;;;;;;;;;;;;;;;;;:5;:51::i;:::-;139916:10;139909:44;;;;;;;;:::i;:::-;;;;;;;;139645:324;139473:496;139255:725;139250:3;;;;;;;139218:762;;;;139039:948;138993:994;:::o;141756:193::-;133588:13;:11;:13::i;:::-;141806:15:::1;141824:21;141806:39;;141874:1;141864:7;:11;141856:40;;;;;;;;;;;;:::i;:::-;;;;;;;;;141915:7;:5;:7::i;:::-;141907:25;;:34;141933:7;141907:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;141795:154;141756:193::o:0;119705:567::-;119832:16;119884:3;:10;119865:8;:15;:29;119861:123;;119944:3;:10;119956:8;:15;119918:54;;;;;;;;;;;;:::i;:::-;;;;;;;;119861:123;119996:30;120043:8;:15;120029:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;119996:63;;120077:9;120072:160;120096:8;:15;120092:1;:19;120072:160;;;120152:68;120162:30;120190:1;120162:8;:27;;:30;;;;:::i;:::-;120194:25;120217:1;120194:3;:22;;:25;;;;:::i;:::-;120152:9;:68::i;:::-;120133:13;120147:1;120133:16;;;;;;;;:::i;:::-;;;;;;;:87;;;;;120113:3;;;;;120072:160;;;;120251:13;120244:20;;;119705:567;;;;:::o;136567:347::-;136639:11;;;;;;;;;;;136631:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;135611:9;136706:6;:14;;;;:::i;:::-;136693:9;:27;;136685:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;135533:5;136780:6;136765:12;;:21;;;;:::i;:::-;:42;;136757:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;136857:6;136841:12;;:22;;;;;;;:::i;:::-;;;;;;;;136874:32;136880:10;136892:1;136895:6;136874:32;;;;;;;;;;;;:5;:32::i;:::-;136567:347;:::o;135489:49::-;135533:5;135489:49;:::o;134377:103::-;133588:13;:11;:13::i;:::-;134442:30:::1;134469:1;134442:18;:30::i;:::-;134377:103::o:0;136922:85::-;133588:13;:11;:13::i;:::-;136988:11:::1;;;;;;;;;;;136987:12;136973:11;;:26;;;;;;;;;;;;;;;;;;136922:85::o:0;135579:41::-;135611:9;135579:41;:::o;133702:87::-;133748:7;133775:6;;;;;;;;;;;133768:13;;133702:87;:::o;135742:31::-;;;;;;;;;;;;;:::o;120345:146::-;120431:52;120450:12;:10;:12::i;:::-;120464:8;120474;120431:18;:52::i;:::-;120345:146;;:::o;137874:1111::-;137931:16;137959:1;137950:6;:10;;;;:::i;:::-;137931:29;;138007:8;137979:24;137989:10;138001:1;137979:9;:24::i;:::-;:36;;137971:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;138056:30;138062:10;138074:1;138077:8;138056:5;:30::i;:::-;138104:9;138099:879;138123:6;138119:1;:10;138099:879;;;138228:14;138334:3;138280:16;138298:10;138310:1;138313:15;138263:66;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;138253:77;;;;;;138245:86;;:92;;;;:::i;:::-;138228:109;;138378:2;138369:6;:11;138366:601;;;138401:48;138407:10;138419:1;138422;138401:48;;;;;;;;;;;;;;;;;:5;:48::i;:::-;138480:10;138473:43;;;;;;;;:::i;:::-;;;;;;;;138366:601;;;138550:2;138541:6;:11;138538:429;;;138573:50;138579:10;138591:3;138596:1;138573:50;;;;;;;;;;;;;;;;;:5;:50::i;:::-;138654:10;138647:43;;;;;;;;:::i;:::-;;;;;;;;138538:429;;;138724:2;138715:6;:11;138712:255;;;138747:51;138753:10;138765:3;138770:1;138747:51;;;;;;;;;;;;;;;;;:5;:51::i;:::-;138829:10;138822:44;;;;;;;;:::i;:::-;;;;;;;;138712:255;;;138920:10;138912:39;;;;;;;;:::i;:::-;;;;;;;;138712:255;138538:429;138366:601;138136:842;138131:3;;;;;;;138099:879;;;;137920:1065;137874:1111;:::o;139995:935::-;140052:16;140080:1;140071:6;:10;;;;:::i;:::-;140052:29;;140128:8;140100:24;140110:10;140122:1;140100:9;:24::i;:::-;:36;;140092:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;140177:30;140183:10;140195:1;140198:8;140177:5;:30::i;:::-;140225:9;140220:703;140244:6;140240:1;:10;140220:703;;;140349:14;140455:3;140401:16;140419:10;140431:1;140434:15;140384:66;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;140374:77;;;;;;140366:86;;:92;;;;:::i;:::-;140349:109;;140487:2;140478:6;:11;140475:437;;;140510:53;140516:10;140528:1;140531;140510:53;;;;;;;;;;;;;;;;;:5;:53::i;:::-;140594:10;140587:48;;;;;;;;:::i;:::-;;;;;;;;140475:437;;;140669:2;140660:6;:11;140657:255;;;140692:51;140698:10;140710:3;140715:1;140692:51;;;;;;;;;;;;;;;;;:5;:51::i;:::-;140774:10;140767:44;;;;;;;;:::i;:::-;;;;;;;;140657:255;;;140865:10;140857:39;;;;;;;;:::i;:::-;;;;;;;;140657:255;140475:437;140257:666;140252:3;;;;;;;140220:703;;;;140041:889;139995:935;:::o;135545:27::-;;;;:::o;120563:159::-;120653:4;120677:18;:27;120696:7;120677:27;;;;;;;;;;;;;;;:37;120705:8;120677:37;;;;;;;;;;;;;;;;;;;;;;;;;120670:44;;120563:159;;;;:::o;140938:751::-;140991:16;141019:1;141010:6;:10;;;;:::i;:::-;140991:29;;141063:8;141035:24;141045:10;141057:1;141035:9;:24::i;:::-;:36;;141027:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;141108:30;141114:10;141126:1;141129:8;141108:5;:30::i;:::-;141156:9;141151:531;141175:6;141171:1;:10;141151:531;;;141280:14;141386:3;141332:16;141350:10;141362:1;141365:15;141315:66;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;141305:77;;;;;;141297:86;;:92;;;;:::i;:::-;141280:109;;141418:2;141409:6;:11;141406:265;;;141441:55;141447:10;141459:1;141462;141441:55;;;;;;;;;;;;;;;;;:5;:55::i;:::-;141527:10;141520:50;;;;;;;;:::i;:::-;;;;;;;;141406:265;;;141624:10;141616:39;;;;;;;;:::i;:::-;;;;;;;;141406:265;141188:494;141183:3;;;;;;;141151:531;;;;140984:705;140938:751;:::o;120794:357::-;120918:14;120935:12;:10;:12::i;:::-;120918:29;;120970:6;120962:14;;:4;:14;;;;:49;;;;;120981:30;120998:4;121004:6;120981:16;:30::i;:::-;120980:31;120962:49;120958:131;;;121064:6;121072:4;121035:42;;;;;;;;;;;;:::i;:::-;;;;;;;;120958:131;121099:44;121117:4;121123:2;121127;121131:5;121138:4;121099:17;:44::i;:::-;120907:244;120794:357;;;;;:::o;134635:220::-;133588:13;:11;:13::i;:::-;134740:1:::1;134720:22;;:8;:22;;::::0;134716:93:::1;;134794:1;134766:31;;;;;;;;;;;:::i;:::-;;;;;;;;134716:93;134819:28;134838:8;134819:18;:28::i;:::-;134635:220:::0;:::o;137042:824::-;137099:16;137127:1;137118:6;:10;;;;:::i;:::-;137099:29;;137175:8;137147:24;137157:10;137169:1;137147:9;:24::i;:::-;:36;;137139:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;137224:30;137230:10;137242:1;137245:8;137224:5;:30::i;:::-;137272:9;137267:592;137291:6;137287:1;:10;137267:592;;;137396:14;137502:3;137448:16;137466:10;137478:1;137481:15;137431:66;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;137421:77;;;;;;137413:86;;:92;;;;:::i;:::-;137396:109;;137534:2;137525:6;:11;137522:326;;;137557:51;137563:10;137575:1;137578;137557:51;;;;;;;;;;;;;;;;;:5;:51::i;:::-;137639:10;137632:46;;;;;;;;:::i;:::-;;;;;;;;137522:326;;;137719:48;137725:10;137737:3;137742:1;137719:48;;;;;;;;;;;;;;;;;:5;:48::i;:::-;137798:10;137791:41;;;;;;;;:::i;:::-;;;;;;;;137522:326;137304:555;137299:3;;;;;;;137267:592;;;;137088:778;137042:824;:::o;21160:148::-;21236:4;21275:25;21260:40;;;:11;:40;;;;21253:47;;21160:148;;;:::o;133867:166::-;133938:12;:10;:12::i;:::-;133927:23;;:7;:5;:7::i;:::-;:23;;;133923:103;;134001:12;:10;:12::i;:::-;133974:40;;;;;;;;;;;:::i;:::-;;;;;;;;133923:103;133867:166::o;20057:98::-;20110:7;20137:10;20130:17;;20057:98;:::o;126366:459::-;126580:1;126566:16;;:2;:16;;;126562:90;;126637:1;126606:34;;;;;;;;;;;:::i;:::-;;;;;;;;126562:90;126682:1;126666:18;;:4;:18;;;126662:90;;126737:1;126708:32;;;;;;;;;;;:::i;:::-;;;;;;;;126662:90;126762:55;126789:4;126795:2;126799:3;126804:6;126812:4;126762:26;:55::i;:::-;126366:459;;;;;:::o;129537:335::-;129633:1;129617:18;;:4;:18;;;129613:90;;129688:1;129659:32;;;;;;;;;;;:::i;:::-;;;;;;;;129613:90;129714:20;129736:23;129763:29;129782:2;129786:5;129763:18;:29::i;:::-;129713:79;;;;129803:61;129830:4;129844:1;129848:3;129853:6;129803:61;;;;;;;;;;;;:26;:61::i;:::-;129602:270;;129537:335;;;:::o;128147:352::-;128258:1;128244:16;;:2;:16;;;128240:90;;128315:1;128284:34;;;;;;;;;;;:::i;:::-;;;;;;;;128240:90;128341:20;128363:23;128390:29;128409:2;128413:5;128390:18;:29::i;:::-;128340:79;;;;128430:61;128465:1;128469:2;128473:3;128478:6;128486:4;128430:26;:61::i;:::-;128229:270;;128147:352;;;;:::o;115189:201::-;115275:11;115365:4;115360:3;115356:14;115349:4;115344:3;115340:14;115336:35;115330:42;115323:49;;115189:201;;;;:::o;116009:::-;116095:11;116185:4;116180:3;116176:14;116169:4;116164:3;116160:14;116156:35;116150:42;116143:49;;116009:201;;;;:::o;135015:191::-;135089:16;135108:6;;;;;;;;;;;135089:25;;135134:8;135125:6;;:17;;;;;;;;;;;;;;;;;;135189:8;135158:40;;135179:8;135158:40;;;;;;;;;;;;135078:128;135015:191;:::o;130741:321::-;130869:1;130849:22;;:8;:22;;;130845:96;;130926:1;130895:34;;;;;;;;;;;:::i;:::-;;;;;;;;130845:96;130989:8;130951:18;:25;130970:5;130951:25;;;;;;;;;;;;;;;:35;130977:8;130951:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;131035:8;131013:41;;131028:5;131013:41;;;131045:8;131013:41;;;;;;:::i;:::-;;;;;;;;130741:321;;;:::o;125480:472::-;125617:1;125603:16;;:2;:16;;;125599:90;;125674:1;125643:34;;;;;;;;;;;:::i;:::-;;;;;;;;125599:90;125719:1;125703:18;;:4;:18;;;125699:90;;125774:1;125745:32;;;;;;;;;;;:::i;:::-;;;;;;;;125699:90;125800:20;125822:23;125849:29;125868:2;125872:5;125849:18;:29::i;:::-;125799:79;;;;125889:55;125916:4;125922:2;125926:3;125931:6;125939:4;125889:26;:55::i;:::-;125588:364;;125480:472;;;;;:::o;124291:718::-;124499:30;124507:4;124513:2;124517:3;124522:6;124499:7;:30::i;:::-;124558:1;124544:16;;:2;:16;;;124540:462;;124577:16;124596:12;:10;:12::i;:::-;124577:31;;124641:1;124627:3;:10;:15;124623:368;;124663:10;124676:25;124699:1;124676:3;:22;;:25;;;;:::i;:::-;124663:38;;124720:13;124736:28;124762:1;124736:6;:25;;:28;;;;:::i;:::-;124720:44;;124783:72;124819:8;124829:4;124835:2;124839;124843:5;124850:4;124783:35;:72::i;:::-;124644:227;;124623:368;;;124896:79;124937:8;124947:4;124953:2;124957:3;124962:6;124970:4;124896:40;:79::i;:::-;124623:368;124562:440;124540:462;124291:718;;;;;:::o;131183:842::-;131294:23;131319;131456:4;131450:11;131440:21;;131528:1;131520:6;131513:17;131668:8;131661:4;131653:6;131649:17;131642:35;131793:4;131785:6;131781:17;131771:27;;131827:1;131819:6;131812:17;131869:8;131862:4;131854:6;131850:17;131843:35;132001:4;131993:6;131989:17;131983:4;131976:31;131183:842;;;;;:::o;122386:1315::-;122522:6;:13;122508:3;:10;:27;122504:119;;122585:3;:10;122597:6;:13;122559:52;;;;;;;;;;;;:::i;:::-;;;;;;;;122504:119;122635:16;122654:12;:10;:12::i;:::-;122635:31;;122684:9;122679:709;122703:3;:10;122699:1;:14;122679:709;;;122735:10;122748:25;122771:1;122748:3;:22;;:25;;;;:::i;:::-;122735:38;;122788:13;122804:28;122830:1;122804:6;:25;;:28;;;;:::i;:::-;122788:44;;122869:1;122853:18;;:4;:18;;;122849:429;;122892:19;122914:9;:13;122924:2;122914:13;;;;;;;;;;;:19;122928:4;122914:19;;;;;;;;;;;;;;;;122892:41;;122970:5;122956:11;:19;122952:131;;;123034:4;123040:11;123053:5;123060:2;123007:56;;;;;;;;;;;;;;:::i;:::-;;;;;;;;122952:131;123238:5;123224:11;:19;123202:9;:13;123212:2;123202:13;;;;;;;;;;;:19;123216:4;123202:19;;;;;;;;;;;;;;;:41;;;;122873:405;122849:429;123312:1;123298:16;;:2;:16;;;123294:83;;123356:5;123335:9;:13;123345:2;123335:13;;;;;;;;;;;:17;123349:2;123335:17;;;;;;;;;;;;;;;;:26;;;;;;;:::i;:::-;;;;;;;;123294:83;122720:668;;122715:3;;;;;122679:709;;;;123418:1;123404:3;:10;:15;123400:294;;123436:10;123449:25;123472:1;123449:3;:22;;:25;;;;:::i;:::-;123436:38;;123489:13;123505:28;123531:1;123505:6;:25;;:28;;;;:::i;:::-;123489:44;;123584:2;123553:45;;123578:4;123553:45;;123568:8;123553:45;;;123588:2;123592:5;123553:45;;;;;;;:::i;:::-;;;;;;;;123421:189;;123400:294;;;123666:2;123636:46;;123660:4;123636:46;;123650:8;123636:46;;;123670:3;123675:6;123636:46;;;;;;;:::i;:::-;;;;;;;;123400:294;122493:1208;122386:1315;;;;:::o;16760:984::-;16984:1;16967:2;:14;;;:18;16963:774;;;17023:2;17006:38;;;17045:8;17055:4;17061:2;17065:5;17072:4;17006:71;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;17002:724;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17399:1;17382:6;:13;:18;17378:333;;17527:2;17489:41;;;;;;;;;;;:::i;:::-;;;;;;;;17378:333;17661:6;17655:13;17646:6;17642:2;17638:15;17631:38;17002:724;17139:43;;;17127:55;;;:8;:55;;;;17123:192;;17292:2;17254:41;;;;;;;;;;;:::i;:::-;;;;;;;;17123:192;17078:252;16963:774;16760:984;;;;;;:::o;18302:1053::-;18551:1;18534:2;:14;;;:18;18530:818;;;18590:2;18573:43;;;18617:8;18627:4;18633:3;18638:6;18646:4;18573:78;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;18569:768;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19010:1;18993:6;:13;:18;18989:333;;19138:2;19100:41;;;;;;;;;;;:::i;:::-;;;;;;;;18989:333;19272:6;19266:13;19257:6;19253:2;19249:15;19242:38;18569:768;18745:48;;;18733:60;;;:8;:60;;;;18729:197;;18903:2;18865:41;;;;;;;;;;;:::i;:::-;;;;;;;;18729:197;18652:289;18530:818;18302:1053;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:126;371:7;411:42;404:5;400:54;389:65;;334:126;;;:::o;466:96::-;503:7;532:24;550:5;532:24;:::i;:::-;521:35;;466:96;;;:::o;568:122::-;641:24;659:5;641:24;:::i;:::-;634:5;631:35;621:63;;680:1;677;670:12;621:63;568:122;:::o;696:139::-;742:5;780:6;767:20;758:29;;796:33;823:5;796:33;:::i;:::-;696:139;;;;:::o;841:77::-;878:7;907:5;896:16;;841:77;;;:::o;924:122::-;997:24;1015:5;997:24;:::i;:::-;990:5;987:35;977:63;;1036:1;1033;1026:12;977:63;924:122;:::o;1052:139::-;1098:5;1136:6;1123:20;1114:29;;1152:33;1179:5;1152:33;:::i;:::-;1052:139;;;;:::o;1197:474::-;1265:6;1273;1322:2;1310:9;1301:7;1297:23;1293:32;1290:119;;;1328:79;;:::i;:::-;1290:119;1448:1;1473:53;1518:7;1509:6;1498:9;1494:22;1473:53;:::i;:::-;1463:63;;1419:117;1575:2;1601:53;1646:7;1637:6;1626:9;1622:22;1601:53;:::i;:::-;1591:63;;1546:118;1197:474;;;;;:::o;1677:118::-;1764:24;1782:5;1764:24;:::i;:::-;1759:3;1752:37;1677:118;;:::o;1801:222::-;1894:4;1932:2;1921:9;1917:18;1909:26;;1945:71;2013:1;2002:9;1998:17;1989:6;1945:71;:::i;:::-;1801:222;;;;:::o;2029:149::-;2065:7;2105:66;2098:5;2094:78;2083:89;;2029:149;;;:::o;2184:120::-;2256:23;2273:5;2256:23;:::i;:::-;2249:5;2246:34;2236:62;;2294:1;2291;2284:12;2236:62;2184:120;:::o;2310:137::-;2355:5;2393:6;2380:20;2371:29;;2409:32;2435:5;2409:32;:::i;:::-;2310:137;;;;:::o;2453:327::-;2511:6;2560:2;2548:9;2539:7;2535:23;2531:32;2528:119;;;2566:79;;:::i;:::-;2528:119;2686:1;2711:52;2755:7;2746:6;2735:9;2731:22;2711:52;:::i;:::-;2701:62;;2657:116;2453:327;;;;:::o;2786:90::-;2820:7;2863:5;2856:13;2849:21;2838:32;;2786:90;;;:::o;2882:109::-;2963:21;2978:5;2963:21;:::i;:::-;2958:3;2951:34;2882:109;;:::o;2997:210::-;3084:4;3122:2;3111:9;3107:18;3099:26;;3135:65;3197:1;3186:9;3182:17;3173:6;3135:65;:::i;:::-;2997:210;;;;:::o;3213:329::-;3272:6;3321:2;3309:9;3300:7;3296:23;3292:32;3289:119;;;3327:79;;:::i;:::-;3289:119;3447:1;3472:53;3517:7;3508:6;3497:9;3493:22;3472:53;:::i;:::-;3462:63;;3418:117;3213:329;;;;:::o;3548:99::-;3600:6;3634:5;3628:12;3618:22;;3548:99;;;:::o;3653:169::-;3737:11;3771:6;3766:3;3759:19;3811:4;3806:3;3802:14;3787:29;;3653:169;;;;:::o;3828:139::-;3917:6;3912:3;3907;3901:23;3958:1;3949:6;3944:3;3940:16;3933:27;3828:139;;;:::o;3973:102::-;4014:6;4065:2;4061:7;4056:2;4049:5;4045:14;4041:28;4031:38;;3973:102;;;:::o;4081:377::-;4169:3;4197:39;4230:5;4197:39;:::i;:::-;4252:71;4316:6;4311:3;4252:71;:::i;:::-;4245:78;;4332:65;4390:6;4385:3;4378:4;4371:5;4367:16;4332:65;:::i;:::-;4422:29;4444:6;4422:29;:::i;:::-;4417:3;4413:39;4406:46;;4173:285;4081:377;;;;:::o;4464:313::-;4577:4;4615:2;4604:9;4600:18;4592:26;;4664:9;4658:4;4654:20;4650:1;4639:9;4635:17;4628:47;4692:78;4765:4;4756:6;4692:78;:::i;:::-;4684:86;;4464:313;;;;:::o;4783:117::-;4892:1;4889;4882:12;4906:117;5015:1;5012;5005:12;5029:117;5138:1;5135;5128:12;5166:553;5224:8;5234:6;5284:3;5277:4;5269:6;5265:17;5261:27;5251:122;;5292:79;;:::i;:::-;5251:122;5405:6;5392:20;5382:30;;5435:18;5427:6;5424:30;5421:117;;;5457:79;;:::i;:::-;5421:117;5571:4;5563:6;5559:17;5547:29;;5625:3;5617:4;5609:6;5605:17;5595:8;5591:32;5588:41;5585:128;;;5632:79;;:::i;:::-;5585:128;5166:553;;;;;:::o;5725:674::-;5805:6;5813;5821;5870:2;5858:9;5849:7;5845:23;5841:32;5838:119;;;5876:79;;:::i;:::-;5838:119;5996:1;6021:53;6066:7;6057:6;6046:9;6042:22;6021:53;:::i;:::-;6011:63;;5967:117;6151:2;6140:9;6136:18;6123:32;6182:18;6174:6;6171:30;6168:117;;;6204:79;;:::i;:::-;6168:117;6317:65;6374:7;6365:6;6354:9;6350:22;6317:65;:::i;:::-;6299:83;;;;6094:298;5725:674;;;;;:::o;6405:180::-;6453:77;6450:1;6443:88;6550:4;6547:1;6540:15;6574:4;6571:1;6564:15;6591:281;6674:27;6696:4;6674:27;:::i;:::-;6666:6;6662:40;6804:6;6792:10;6789:22;6768:18;6756:10;6753:34;6750:62;6747:88;;;6815:18;;:::i;:::-;6747:88;6855:10;6851:2;6844:22;6634:238;6591:281;;:::o;6878:129::-;6912:6;6939:20;;:::i;:::-;6929:30;;6968:33;6996:4;6988:6;6968:33;:::i;:::-;6878:129;;;:::o;7013:311::-;7090:4;7180:18;7172:6;7169:30;7166:56;;;7202:18;;:::i;:::-;7166:56;7252:4;7244:6;7240:17;7232:25;;7312:4;7306;7302:15;7294:23;;7013:311;;;:::o;7347:710::-;7443:5;7468:81;7484:64;7541:6;7484:64;:::i;:::-;7468:81;:::i;:::-;7459:90;;7569:5;7598:6;7591:5;7584:21;7632:4;7625:5;7621:16;7614:23;;7685:4;7677:6;7673:17;7665:6;7661:30;7714:3;7706:6;7703:15;7700:122;;;7733:79;;:::i;:::-;7700:122;7848:6;7831:220;7865:6;7860:3;7857:15;7831:220;;;7940:3;7969:37;8002:3;7990:10;7969:37;:::i;:::-;7964:3;7957:50;8036:4;8031:3;8027:14;8020:21;;7907:144;7891:4;7886:3;7882:14;7875:21;;7831:220;;;7835:21;7449:608;;7347:710;;;;;:::o;8080:370::-;8151:5;8200:3;8193:4;8185:6;8181:17;8177:27;8167:122;;8208:79;;:::i;:::-;8167:122;8325:6;8312:20;8350:94;8440:3;8432:6;8425:4;8417:6;8413:17;8350:94;:::i;:::-;8341:103;;8157:293;8080:370;;;;:::o;8456:117::-;8565:1;8562;8555:12;8579:307;8640:4;8730:18;8722:6;8719:30;8716:56;;;8752:18;;:::i;:::-;8716:56;8790:29;8812:6;8790:29;:::i;:::-;8782:37;;8874:4;8868;8864:15;8856:23;;8579:307;;;:::o;8892:148::-;8990:6;8985:3;8980;8967:30;9031:1;9022:6;9017:3;9013:16;9006:27;8892:148;;;:::o;9046:423::-;9123:5;9148:65;9164:48;9205:6;9164:48;:::i;:::-;9148:65;:::i;:::-;9139:74;;9236:6;9229:5;9222:21;9274:4;9267:5;9263:16;9312:3;9303:6;9298:3;9294:16;9291:25;9288:112;;;9319:79;;:::i;:::-;9288:112;9409:54;9456:6;9451:3;9446;9409:54;:::i;:::-;9129:340;9046:423;;;;;:::o;9488:338::-;9543:5;9592:3;9585:4;9577:6;9573:17;9569:27;9559:122;;9600:79;;:::i;:::-;9559:122;9717:6;9704:20;9742:78;9816:3;9808:6;9801:4;9793:6;9789:17;9742:78;:::i;:::-;9733:87;;9549:277;9488:338;;;;:::o;9832:1509::-;9986:6;9994;10002;10010;10018;10067:3;10055:9;10046:7;10042:23;10038:33;10035:120;;;10074:79;;:::i;:::-;10035:120;10194:1;10219:53;10264:7;10255:6;10244:9;10240:22;10219:53;:::i;:::-;10209:63;;10165:117;10321:2;10347:53;10392:7;10383:6;10372:9;10368:22;10347:53;:::i;:::-;10337:63;;10292:118;10477:2;10466:9;10462:18;10449:32;10508:18;10500:6;10497:30;10494:117;;;10530:79;;:::i;:::-;10494:117;10635:78;10705:7;10696:6;10685:9;10681:22;10635:78;:::i;:::-;10625:88;;10420:303;10790:2;10779:9;10775:18;10762:32;10821:18;10813:6;10810:30;10807:117;;;10843:79;;:::i;:::-;10807:117;10948:78;11018:7;11009:6;10998:9;10994:22;10948:78;:::i;:::-;10938:88;;10733:303;11103:3;11092:9;11088:19;11075:33;11135:18;11127:6;11124:30;11121:117;;;11157:79;;:::i;:::-;11121:117;11262:62;11316:7;11307:6;11296:9;11292:22;11262:62;:::i;:::-;11252:72;;11046:288;9832:1509;;;;;;;;:::o;11347:311::-;11424:4;11514:18;11506:6;11503:30;11500:56;;;11536:18;;:::i;:::-;11500:56;11586:4;11578:6;11574:17;11566:25;;11646:4;11640;11636:15;11628:23;;11347:311;;;:::o;11681:710::-;11777:5;11802:81;11818:64;11875:6;11818:64;:::i;:::-;11802:81;:::i;:::-;11793:90;;11903:5;11932:6;11925:5;11918:21;11966:4;11959:5;11955:16;11948:23;;12019:4;12011:6;12007:17;11999:6;11995:30;12048:3;12040:6;12037:15;12034:122;;;12067:79;;:::i;:::-;12034:122;12182:6;12165:220;12199:6;12194:3;12191:15;12165:220;;;12274:3;12303:37;12336:3;12324:10;12303:37;:::i;:::-;12298:3;12291:50;12370:4;12365:3;12361:14;12354:21;;12241:144;12225:4;12220:3;12216:14;12209:21;;12165:220;;;12169:21;11783:608;;11681:710;;;;;:::o;12414:370::-;12485:5;12534:3;12527:4;12519:6;12515:17;12511:27;12501:122;;12542:79;;:::i;:::-;12501:122;12659:6;12646:20;12684:94;12774:3;12766:6;12759:4;12751:6;12747:17;12684:94;:::i;:::-;12675:103;;12491:293;12414:370;;;;:::o;12790:894::-;12908:6;12916;12965:2;12953:9;12944:7;12940:23;12936:32;12933:119;;;12971:79;;:::i;:::-;12933:119;13119:1;13108:9;13104:17;13091:31;13149:18;13141:6;13138:30;13135:117;;;13171:79;;:::i;:::-;13135:117;13276:78;13346:7;13337:6;13326:9;13322:22;13276:78;:::i;:::-;13266:88;;13062:302;13431:2;13420:9;13416:18;13403:32;13462:18;13454:6;13451:30;13448:117;;;13484:79;;:::i;:::-;13448:117;13589:78;13659:7;13650:6;13639:9;13635:22;13589:78;:::i;:::-;13579:88;;13374:303;12790:894;;;;;:::o;13690:114::-;13757:6;13791:5;13785:12;13775:22;;13690:114;;;:::o;13810:184::-;13909:11;13943:6;13938:3;13931:19;13983:4;13978:3;13974:14;13959:29;;13810:184;;;;:::o;14000:132::-;14067:4;14090:3;14082:11;;14120:4;14115:3;14111:14;14103:22;;14000:132;;;:::o;14138:108::-;14215:24;14233:5;14215:24;:::i;:::-;14210:3;14203:37;14138:108;;:::o;14252:179::-;14321:10;14342:46;14384:3;14376:6;14342:46;:::i;:::-;14420:4;14415:3;14411:14;14397:28;;14252:179;;;;:::o;14437:113::-;14507:4;14539;14534:3;14530:14;14522:22;;14437:113;;;:::o;14586:732::-;14705:3;14734:54;14782:5;14734:54;:::i;:::-;14804:86;14883:6;14878:3;14804:86;:::i;:::-;14797:93;;14914:56;14964:5;14914:56;:::i;:::-;14993:7;15024:1;15009:284;15034:6;15031:1;15028:13;15009:284;;;15110:6;15104:13;15137:63;15196:3;15181:13;15137:63;:::i;:::-;15130:70;;15223:60;15276:6;15223:60;:::i;:::-;15213:70;;15069:224;15056:1;15053;15049:9;15044:14;;15009:284;;;15013:14;15309:3;15302:10;;14710:608;;;14586:732;;;;:::o;15324:373::-;15467:4;15505:2;15494:9;15490:18;15482:26;;15554:9;15548:4;15544:20;15540:1;15529:9;15525:17;15518:47;15582:108;15685:4;15676:6;15582:108;:::i;:::-;15574:116;;15324:373;;;;:::o;15703:118::-;15790:24;15808:5;15790:24;:::i;:::-;15785:3;15778:37;15703:118;;:::o;15827:222::-;15920:4;15958:2;15947:9;15943:18;15935:26;;15971:71;16039:1;16028:9;16024:17;16015:6;15971:71;:::i;:::-;15827:222;;;;:::o;16055:116::-;16125:21;16140:5;16125:21;:::i;:::-;16118:5;16115:32;16105:60;;16161:1;16158;16151:12;16105:60;16055:116;:::o;16177:133::-;16220:5;16258:6;16245:20;16236:29;;16274:30;16298:5;16274:30;:::i;:::-;16177:133;;;;:::o;16316:468::-;16381:6;16389;16438:2;16426:9;16417:7;16413:23;16409:32;16406:119;;;16444:79;;:::i;:::-;16406:119;16564:1;16589:53;16634:7;16625:6;16614:9;16610:22;16589:53;:::i;:::-;16579:63;;16535:117;16691:2;16717:50;16759:7;16750:6;16739:9;16735:22;16717:50;:::i;:::-;16707:60;;16662:115;16316:468;;;;;:::o;16790:474::-;16858:6;16866;16915:2;16903:9;16894:7;16890:23;16886:32;16883:119;;;16921:79;;:::i;:::-;16883:119;17041:1;17066:53;17111:7;17102:6;17091:9;17087:22;17066:53;:::i;:::-;17056:63;;17012:117;17168:2;17194:53;17239:7;17230:6;17219:9;17215:22;17194:53;:::i;:::-;17184:63;;17139:118;16790:474;;;;;:::o;17270:1089::-;17374:6;17382;17390;17398;17406;17455:3;17443:9;17434:7;17430:23;17426:33;17423:120;;;17462:79;;:::i;:::-;17423:120;17582:1;17607:53;17652:7;17643:6;17632:9;17628:22;17607:53;:::i;:::-;17597:63;;17553:117;17709:2;17735:53;17780:7;17771:6;17760:9;17756:22;17735:53;:::i;:::-;17725:63;;17680:118;17837:2;17863:53;17908:7;17899:6;17888:9;17884:22;17863:53;:::i;:::-;17853:63;;17808:118;17965:2;17991:53;18036:7;18027:6;18016:9;18012:22;17991:53;:::i;:::-;17981:63;;17936:118;18121:3;18110:9;18106:19;18093:33;18153:18;18145:6;18142:30;18139:117;;;18175:79;;:::i;:::-;18139:117;18280:62;18334:7;18325:6;18314:9;18310:22;18280:62;:::i;:::-;18270:72;;18064:288;17270:1089;;;;;;;;:::o;18365:329::-;18424:6;18473:2;18461:9;18452:7;18448:23;18444:32;18441:119;;;18479:79;;:::i;:::-;18441:119;18599:1;18624:53;18669:7;18660:6;18649:9;18645:22;18624:53;:::i;:::-;18614:63;;18570:117;18365:329;;;;:::o;18700:180::-;18748:77;18745:1;18738:88;18845:4;18842:1;18835:15;18869:4;18866:1;18859:15;18886:320;18930:6;18967:1;18961:4;18957:12;18947:22;;19014:1;19008:4;19004:12;19035:18;19025:81;;19091:4;19083:6;19079:17;19069:27;;19025:81;19153:2;19145:6;19142:14;19122:18;19119:38;19116:84;;19172:18;;:::i;:::-;19116:84;18937:269;18886:320;;;:::o;19212:97::-;19271:6;19299:3;19289:13;;19212:97;;;;:::o;19315:141::-;19364:4;19387:3;19379:11;;19410:3;19407:1;19400:14;19444:4;19441:1;19431:18;19423:26;;19315:141;;;:::o;19462:93::-;19499:6;19546:2;19541;19534:5;19530:14;19526:23;19516:33;;19462:93;;;:::o;19561:107::-;19605:8;19655:5;19649:4;19645:16;19624:37;;19561:107;;;;:::o;19674:393::-;19743:6;19793:1;19781:10;19777:18;19816:97;19846:66;19835:9;19816:97;:::i;:::-;19934:39;19964:8;19953:9;19934:39;:::i;:::-;19922:51;;20006:4;20002:9;19995:5;19991:21;19982:30;;20055:4;20045:8;20041:19;20034:5;20031:30;20021:40;;19750:317;;19674:393;;;;;:::o;20073:60::-;20101:3;20122:5;20115:12;;20073:60;;;:::o;20139:142::-;20189:9;20222:53;20240:34;20249:24;20267:5;20249:24;:::i;:::-;20240:34;:::i;:::-;20222:53;:::i;:::-;20209:66;;20139:142;;;:::o;20287:75::-;20330:3;20351:5;20344:12;;20287:75;;;:::o;20368:269::-;20478:39;20509:7;20478:39;:::i;:::-;20539:91;20588:41;20612:16;20588:41;:::i;:::-;20580:6;20573:4;20567:11;20539:91;:::i;:::-;20533:4;20526:105;20444:193;20368:269;;;:::o;20643:73::-;20688:3;20643:73;:::o;20722:189::-;20799:32;;:::i;:::-;20840:65;20898:6;20890;20884:4;20840:65;:::i;:::-;20775:136;20722:189;;:::o;20917:186::-;20977:120;20994:3;20987:5;20984:14;20977:120;;;21048:39;21085:1;21078:5;21048:39;:::i;:::-;21021:1;21014:5;21010:13;21001:22;;20977:120;;;20917:186;;:::o;21109:543::-;21210:2;21205:3;21202:11;21199:446;;;21244:38;21276:5;21244:38;:::i;:::-;21328:29;21346:10;21328:29;:::i;:::-;21318:8;21314:44;21511:2;21499:10;21496:18;21493:49;;;21532:8;21517:23;;21493:49;21555:80;21611:22;21629:3;21611:22;:::i;:::-;21601:8;21597:37;21584:11;21555:80;:::i;:::-;21214:431;;21199:446;21109:543;;;:::o;21658:117::-;21712:8;21762:5;21756:4;21752:16;21731:37;;21658:117;;;;:::o;21781:169::-;21825:6;21858:51;21906:1;21902:6;21894:5;21891:1;21887:13;21858:51;:::i;:::-;21854:56;21939:4;21933;21929:15;21919:25;;21832:118;21781:169;;;;:::o;21955:295::-;22031:4;22177:29;22202:3;22196:4;22177:29;:::i;:::-;22169:37;;22239:3;22236:1;22232:11;22226:4;22223:21;22215:29;;21955:295;;;;:::o;22255:1403::-;22379:44;22419:3;22414;22379:44;:::i;:::-;22488:18;22480:6;22477:30;22474:56;;;22510:18;;:::i;:::-;22474:56;22554:38;22586:4;22580:11;22554:38;:::i;:::-;22639:67;22699:6;22691;22685:4;22639:67;:::i;:::-;22733:1;22762:2;22754:6;22751:14;22779:1;22774:632;;;;23450:1;23467:6;23464:84;;;23523:9;23518:3;23514:19;23501:33;23492:42;;23464:84;23574:67;23634:6;23627:5;23574:67;:::i;:::-;23568:4;23561:81;23423:229;22744:908;;22774:632;22826:4;22822:9;22814:6;22810:22;22860:37;22892:4;22860:37;:::i;:::-;22919:1;22933:215;22947:7;22944:1;22941:14;22933:215;;;23033:9;23028:3;23024:19;23011:33;23003:6;22996:49;23084:1;23076:6;23072:14;23062:24;;23131:2;23120:9;23116:18;23103:31;;22970:4;22967:1;22963:12;22958:17;;22933:215;;;23176:6;23167:7;23164:19;23161:186;;;23241:9;23236:3;23232:19;23219:33;23284:48;23326:4;23318:6;23314:17;23303:9;23284:48;:::i;:::-;23276:6;23269:64;23184:163;23161:186;23393:1;23389;23381:6;23377:14;23373:22;23367:4;23360:36;22781:625;;;22744:908;;22354:1304;;;22255:1403;;;:::o;23664:332::-;23785:4;23823:2;23812:9;23808:18;23800:26;;23836:71;23904:1;23893:9;23889:17;23880:6;23836:71;:::i;:::-;23917:72;23985:2;23974:9;23970:18;23961:6;23917:72;:::i;:::-;23664:332;;;;;:::o;24002:180::-;24050:77;24047:1;24040:88;24147:4;24144:1;24137:15;24171:4;24168:1;24161:15;24188:410;24228:7;24251:20;24269:1;24251:20;:::i;:::-;24246:25;;24285:20;24303:1;24285:20;:::i;:::-;24280:25;;24340:1;24337;24333:9;24362:30;24380:11;24362:30;:::i;:::-;24351:41;;24541:1;24532:7;24528:15;24525:1;24522:22;24502:1;24495:9;24475:83;24452:139;;24571:18;;:::i;:::-;24452:139;24236:362;24188:410;;;;:::o;24604:175::-;24744:27;24740:1;24732:6;24728:14;24721:51;24604:175;:::o;24785:366::-;24927:3;24948:67;25012:2;25007:3;24948:67;:::i;:::-;24941:74;;25024:93;25113:3;25024:93;:::i;:::-;25142:2;25137:3;25133:12;25126:19;;24785:366;;;:::o;25157:419::-;25323:4;25361:2;25350:9;25346:18;25338:26;;25410:9;25404:4;25400:20;25396:1;25385:9;25381:17;25374:47;25438:131;25564:4;25438:131;:::i;:::-;25430:139;;25157:419;;;:::o;25582:79::-;25621:7;25650:5;25639:16;;25582:79;;;:::o;25667:157::-;25772:45;25792:24;25810:5;25792:24;:::i;:::-;25772:45;:::i;:::-;25767:3;25760:58;25667:157;;:::o;25830:94::-;25863:8;25911:5;25907:2;25903:14;25882:35;;25830:94;;;:::o;25930:::-;25969:7;25998:20;26012:5;25998:20;:::i;:::-;25987:31;;25930:94;;;:::o;26030:100::-;26069:7;26098:26;26118:5;26098:26;:::i;:::-;26087:37;;26030:100;;;:::o;26136:157::-;26241:45;26261:24;26279:5;26261:24;:::i;:::-;26241:45;:::i;:::-;26236:3;26229:58;26136:157;;:::o;26299:679::-;26495:3;26510:75;26581:3;26572:6;26510:75;:::i;:::-;26610:2;26605:3;26601:12;26594:19;;26623:75;26694:3;26685:6;26623:75;:::i;:::-;26723:2;26718:3;26714:12;26707:19;;26736:75;26807:3;26798:6;26736:75;:::i;:::-;26836:2;26831:3;26827:12;26820:19;;26849:75;26920:3;26911:6;26849:75;:::i;:::-;26949:2;26944:3;26940:12;26933:19;;26969:3;26962:10;;26299:679;;;;;;;:::o;26984:180::-;27032:77;27029:1;27022:88;27129:4;27126:1;27119:15;27153:4;27150:1;27143:15;27170:176;27202:1;27219:20;27237:1;27219:20;:::i;:::-;27214:25;;27253:20;27271:1;27253:20;:::i;:::-;27248:25;;27292:1;27282:35;;27297:18;;:::i;:::-;27282:35;27338:1;27335;27331:9;27326:14;;27170:176;;;;:::o;27352:171::-;27492:23;27488:1;27480:6;27476:14;27469:47;27352:171;:::o;27529:366::-;27671:3;27692:67;27756:2;27751:3;27692:67;:::i;:::-;27685:74;;27768:93;27857:3;27768:93;:::i;:::-;27886:2;27881:3;27877:12;27870:19;;27529:366;;;:::o;27901:419::-;28067:4;28105:2;28094:9;28090:18;28082:26;;28154:9;28148:4;28144:20;28140:1;28129:9;28125:17;28118:47;28182:131;28308:4;28182:131;:::i;:::-;28174:139;;27901:419;;;:::o;28326:169::-;28466:21;28462:1;28454:6;28450:14;28443:45;28326:169;:::o;28501:366::-;28643:3;28664:67;28728:2;28723:3;28664:67;:::i;:::-;28657:74;;28740:93;28829:3;28740:93;:::i;:::-;28858:2;28853:3;28849:12;28842:19;;28501:366;;;:::o;28873:419::-;29039:4;29077:2;29066:9;29062:18;29054:26;;29126:9;29120:4;29116:20;29112:1;29101:9;29097:17;29090:47;29154:131;29280:4;29154:131;:::i;:::-;29146:139;;28873:419;;;:::o;29298:172::-;29438:24;29434:1;29426:6;29422:14;29415:48;29298:172;:::o;29476:366::-;29618:3;29639:67;29703:2;29698:3;29639:67;:::i;:::-;29632:74;;29715:93;29804:3;29715:93;:::i;:::-;29833:2;29828:3;29824:12;29817:19;;29476:366;;;:::o;29848:419::-;30014:4;30052:2;30041:9;30037:18;30029:26;;30101:9;30095:4;30091:20;30087:1;30076:9;30072:17;30065:47;30129:131;30255:4;30129:131;:::i;:::-;30121:139;;29848:419;;;:::o;30273:166::-;30413:18;30409:1;30401:6;30397:14;30390:42;30273:166;:::o;30445:366::-;30587:3;30608:67;30672:2;30667:3;30608:67;:::i;:::-;30601:74;;30684:93;30773:3;30684:93;:::i;:::-;30802:2;30797:3;30793:12;30786:19;;30445:366;;;:::o;30817:419::-;30983:4;31021:2;31010:9;31006:18;30998:26;;31070:9;31064:4;31060:20;31056:1;31045:9;31041:17;31034:47;31098:131;31224:4;31098:131;:::i;:::-;31090:139;;30817:419;;;:::o;31242:332::-;31363:4;31401:2;31390:9;31386:18;31378:26;;31414:71;31482:1;31471:9;31467:17;31458:6;31414:71;:::i;:::-;31495:72;31563:2;31552:9;31548:18;31539:6;31495:72;:::i;:::-;31242:332;;;;;:::o;31580:180::-;31628:77;31625:1;31618:88;31725:4;31722:1;31715:15;31749:4;31746:1;31739:15;31766:169;31906:21;31902:1;31894:6;31890:14;31883:45;31766:169;:::o;31941:366::-;32083:3;32104:67;32168:2;32163:3;32104:67;:::i;:::-;32097:74;;32180:93;32269:3;32180:93;:::i;:::-;32298:2;32293:3;32289:12;32282:19;;31941:366;;;:::o;32313:419::-;32479:4;32517:2;32506:9;32502:18;32494:26;;32566:9;32560:4;32556:20;32552:1;32541:9;32537:17;32530:47;32594:131;32720:4;32594:131;:::i;:::-;32586:139;;32313:419;;;:::o;32738:171::-;32878:23;32874:1;32866:6;32862:14;32855:47;32738:171;:::o;32915:366::-;33057:3;33078:67;33142:2;33137:3;33078:67;:::i;:::-;33071:74;;33154:93;33243:3;33154:93;:::i;:::-;33272:2;33267:3;33263:12;33256:19;;32915:366;;;:::o;33287:419::-;33453:4;33491:2;33480:9;33476:18;33468:26;;33540:9;33534:4;33530:20;33526:1;33515:9;33511:17;33504:47;33568:131;33694:4;33568:131;:::i;:::-;33560:139;;33287:419;;;:::o;33712:191::-;33752:3;33771:20;33789:1;33771:20;:::i;:::-;33766:25;;33805:20;33823:1;33805:20;:::i;:::-;33800:25;;33848:1;33845;33841:9;33834:16;;33869:3;33866:1;33863:10;33860:36;;;33876:18;;:::i;:::-;33860:36;33712:191;;;;:::o;33909:168::-;34049:20;34045:1;34037:6;34033:14;34026:44;33909:168;:::o;34083:366::-;34225:3;34246:67;34310:2;34305:3;34246:67;:::i;:::-;34239:74;;34322:93;34411:3;34322:93;:::i;:::-;34440:2;34435:3;34431:12;34424:19;;34083:366;;;:::o;34455:419::-;34621:4;34659:2;34648:9;34644:18;34636:26;;34708:9;34702:4;34698:20;34694:1;34683:9;34679:17;34672:47;34736:131;34862:4;34736:131;:::i;:::-;34728:139;;34455:419;;;:::o;34880:175::-;35020:27;35016:1;35008:6;35004:14;34997:51;34880:175;:::o;35061:366::-;35203:3;35224:67;35288:2;35283:3;35224:67;:::i;:::-;35217:74;;35300:93;35389:3;35300:93;:::i;:::-;35418:2;35413:3;35409:12;35402:19;;35061:366;;;:::o;35433:419::-;35599:4;35637:2;35626:9;35622:18;35614:26;;35686:9;35680:4;35676:20;35672:1;35661:9;35657:17;35650:47;35714:131;35840:4;35714:131;:::i;:::-;35706:139;;35433:419;;;:::o;35858:171::-;35998:23;35994:1;35986:6;35982:14;35975:47;35858:171;:::o;36035:366::-;36177:3;36198:67;36262:2;36257:3;36198:67;:::i;:::-;36191:74;;36274:93;36363:3;36274:93;:::i;:::-;36392:2;36387:3;36383:12;36376:19;;36035:366;;;:::o;36407:419::-;36573:4;36611:2;36600:9;36596:18;36588:26;;36660:9;36654:4;36650:20;36646:1;36635:9;36631:17;36624:47;36688:131;36814:4;36688:131;:::i;:::-;36680:139;;36407:419;;;:::o;36832:171::-;36972:23;36968:1;36960:6;36956:14;36949:47;36832:171;:::o;37009:366::-;37151:3;37172:67;37236:2;37231:3;37172:67;:::i;:::-;37165:74;;37248:93;37337:3;37248:93;:::i;:::-;37366:2;37361:3;37357:12;37350:19;;37009:366;;;:::o;37381:419::-;37547:4;37585:2;37574:9;37570:18;37562:26;;37634:9;37628:4;37624:20;37620:1;37609:9;37605:17;37598:47;37662:131;37788:4;37662:131;:::i;:::-;37654:139;;37381:419;;;:::o;37806:172::-;37946:24;37942:1;37934:6;37930:14;37923:48;37806:172;:::o;37984:366::-;38126:3;38147:67;38211:2;38206:3;38147:67;:::i;:::-;38140:74;;38223:93;38312:3;38223:93;:::i;:::-;38341:2;38336:3;38332:12;38325:19;;37984:366;;;:::o;38356:419::-;38522:4;38560:2;38549:9;38545:18;38537:26;;38609:9;38603:4;38599:20;38595:1;38584:9;38580:17;38573:47;38637:131;38763:4;38637:131;:::i;:::-;38629:139;;38356:419;;;:::o;38781:166::-;38921:18;38917:1;38909:6;38905:14;38898:42;38781:166;:::o;38953:366::-;39095:3;39116:67;39180:2;39175:3;39116:67;:::i;:::-;39109:74;;39192:93;39281:3;39192:93;:::i;:::-;39310:2;39305:3;39301:12;39294:19;;38953:366;;;:::o;39325:419::-;39491:4;39529:2;39518:9;39514:18;39506:26;;39578:9;39572:4;39568:20;39564:1;39553:9;39549:17;39542:47;39606:131;39732:4;39606:131;:::i;:::-;39598:139;;39325:419;;;:::o;39750:175::-;39890:27;39886:1;39878:6;39874:14;39867:51;39750:175;:::o;39931:366::-;40073:3;40094:67;40158:2;40153:3;40094:67;:::i;:::-;40087:74;;40170:93;40259:3;40170:93;:::i;:::-;40288:2;40283:3;40279:12;40272:19;;39931:366;;;:::o;40303:419::-;40469:4;40507:2;40496:9;40492:18;40484:26;;40556:9;40550:4;40546:20;40542:1;40531:9;40527:17;40520:47;40584:131;40710:4;40584:131;:::i;:::-;40576:139;;40303:419;;;:::o;40728:176::-;40868:28;40864:1;40856:6;40852:14;40845:52;40728:176;:::o;40910:366::-;41052:3;41073:67;41137:2;41132:3;41073:67;:::i;:::-;41066:74;;41149:93;41238:3;41149:93;:::i;:::-;41267:2;41262:3;41258:12;41251:19;;40910:366;;;:::o;41282:419::-;41448:4;41486:2;41475:9;41471:18;41463:26;;41535:9;41529:4;41525:20;41521:1;41510:9;41506:17;41499:47;41563:131;41689:4;41563:131;:::i;:::-;41555:139;;41282:419;;;:::o;41707:172::-;41847:24;41843:1;41835:6;41831:14;41824:48;41707:172;:::o;41885:366::-;42027:3;42048:67;42112:2;42107:3;42048:67;:::i;:::-;42041:74;;42124:93;42213:3;42124:93;:::i;:::-;42242:2;42237:3;42233:12;42226:19;;41885:366;;;:::o;42257:419::-;42423:4;42461:2;42450:9;42446:18;42438:26;;42510:9;42504:4;42500:20;42496:1;42485:9;42481:17;42474:47;42538:131;42664:4;42538:131;:::i;:::-;42530:139;;42257:419;;;:::o;42682:175::-;42822:27;42818:1;42810:6;42806:14;42799:51;42682:175;:::o;42863:366::-;43005:3;43026:67;43090:2;43085:3;43026:67;:::i;:::-;43019:74;;43102:93;43191:3;43102:93;:::i;:::-;43220:2;43215:3;43211:12;43204:19;;42863:366;;;:::o;43235:419::-;43401:4;43439:2;43428:9;43424:18;43416:26;;43488:9;43482:4;43478:20;43474:1;43463:9;43459:17;43452:47;43516:131;43642:4;43516:131;:::i;:::-;43508:139;;43235:419;;;:::o;43660:178::-;43800:30;43796:1;43788:6;43784:14;43777:54;43660:178;:::o;43844:366::-;43986:3;44007:67;44071:2;44066:3;44007:67;:::i;:::-;44000:74;;44083:93;44172:3;44083:93;:::i;:::-;44201:2;44196:3;44192:12;44185:19;;43844:366;;;:::o;44216:419::-;44382:4;44420:2;44409:9;44405:18;44397:26;;44469:9;44463:4;44459:20;44455:1;44444:9;44440:17;44433:47;44497:131;44623:4;44497:131;:::i;:::-;44489:139;;44216:419;;;:::o;44641:175::-;44781:27;44777:1;44769:6;44765:14;44758:51;44641:175;:::o;44822:366::-;44964:3;44985:67;45049:2;45044:3;44985:67;:::i;:::-;44978:74;;45061:93;45150:3;45061:93;:::i;:::-;45179:2;45174:3;45170:12;45163:19;;44822:366;;;:::o;45194:419::-;45360:4;45398:2;45387:9;45383:18;45375:26;;45447:9;45441:4;45437:20;45433:1;45422:9;45418:17;45411:47;45475:131;45601:4;45475:131;:::i;:::-;45467:139;;45194:419;;;:::o;45619:174::-;45759:26;45755:1;45747:6;45743:14;45736:50;45619:174;:::o;45799:366::-;45941:3;45962:67;46026:2;46021:3;45962:67;:::i;:::-;45955:74;;46038:93;46127:3;46038:93;:::i;:::-;46156:2;46151:3;46147:12;46140:19;;45799:366;;;:::o;46171:419::-;46337:4;46375:2;46364:9;46360:18;46352:26;;46424:9;46418:4;46414:20;46410:1;46399:9;46395:17;46388:47;46452:131;46578:4;46452:131;:::i;:::-;46444:139;;46171:419;;;:::o;46596:169::-;46736:21;46732:1;46724:6;46720:14;46713:45;46596:169;:::o;46771:366::-;46913:3;46934:67;46998:2;46993:3;46934:67;:::i;:::-;46927:74;;47010:93;47099:3;47010:93;:::i;:::-;47128:2;47123:3;47119:12;47112:19;;46771:366;;;:::o;47143:419::-;47309:4;47347:2;47336:9;47332:18;47324:26;;47396:9;47390:4;47386:20;47382:1;47371:9;47367:17;47360:47;47424:131;47550:4;47424:131;:::i;:::-;47416:139;;47143:419;;;:::o;47568:553::-;47745:4;47783:3;47772:9;47768:19;47760:27;;47797:71;47865:1;47854:9;47850:17;47841:6;47797:71;:::i;:::-;47878:72;47946:2;47935:9;47931:18;47922:6;47878:72;:::i;:::-;47960;48028:2;48017:9;48013:18;48004:6;47960:72;:::i;:::-;48042;48110:2;48099:9;48095:18;48086:6;48042:72;:::i;:::-;47568:553;;;;;;;:::o;48127:634::-;48348:4;48386:2;48375:9;48371:18;48363:26;;48435:9;48429:4;48425:20;48421:1;48410:9;48406:17;48399:47;48463:108;48566:4;48557:6;48463:108;:::i;:::-;48455:116;;48618:9;48612:4;48608:20;48603:2;48592:9;48588:18;48581:48;48646:108;48749:4;48740:6;48646:108;:::i;:::-;48638:116;;48127:634;;;;;:::o;48767:98::-;48818:6;48852:5;48846:12;48836:22;;48767:98;;;:::o;48871:168::-;48954:11;48988:6;48983:3;48976:19;49028:4;49023:3;49019:14;49004:29;;48871:168;;;;:::o;49045:373::-;49131:3;49159:38;49191:5;49159:38;:::i;:::-;49213:70;49276:6;49271:3;49213:70;:::i;:::-;49206:77;;49292:65;49350:6;49345:3;49338:4;49331:5;49327:16;49292:65;:::i;:::-;49382:29;49404:6;49382:29;:::i;:::-;49377:3;49373:39;49366:46;;49135:283;49045:373;;;;:::o;49424:751::-;49647:4;49685:3;49674:9;49670:19;49662:27;;49699:71;49767:1;49756:9;49752:17;49743:6;49699:71;:::i;:::-;49780:72;49848:2;49837:9;49833:18;49824:6;49780:72;:::i;:::-;49862;49930:2;49919:9;49915:18;49906:6;49862:72;:::i;:::-;49944;50012:2;50001:9;49997:18;49988:6;49944:72;:::i;:::-;50064:9;50058:4;50054:20;50048:3;50037:9;50033:19;50026:49;50092:76;50163:4;50154:6;50092:76;:::i;:::-;50084:84;;49424:751;;;;;;;;:::o;50181:141::-;50237:5;50268:6;50262:13;50253:22;;50284:32;50310:5;50284:32;:::i;:::-;50181:141;;;;:::o;50328:349::-;50397:6;50446:2;50434:9;50425:7;50421:23;50417:32;50414:119;;;50452:79;;:::i;:::-;50414:119;50572:1;50597:63;50652:7;50643:6;50632:9;50628:22;50597:63;:::i;:::-;50587:73;;50543:127;50328:349;;;;:::o;50683:1053::-;51006:4;51044:3;51033:9;51029:19;51021:27;;51058:71;51126:1;51115:9;51111:17;51102:6;51058:71;:::i;:::-;51139:72;51207:2;51196:9;51192:18;51183:6;51139:72;:::i;:::-;51258:9;51252:4;51248:20;51243:2;51232:9;51228:18;51221:48;51286:108;51389:4;51380:6;51286:108;:::i;:::-;51278:116;;51441:9;51435:4;51431:20;51426:2;51415:9;51411:18;51404:48;51469:108;51572:4;51563:6;51469:108;:::i;:::-;51461:116;;51625:9;51619:4;51615:20;51609:3;51598:9;51594:19;51587:49;51653:76;51724:4;51715:6;51653:76;:::i;:::-;51645:84;;50683:1053;;;;;;;;:::o

Swarm Source

ipfs://42765bae25b7949675932f02fc8e8772328cea390c695a7afbba53e20e9331eb
[ 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.