ETH Price: $3,560.95 (-1.41%)

Token

Onisekai Crystal Collection (OCC)
 

Overview

Max Total Supply

489 OCC

Holders

193

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
9 OCC
0xb31045d707742e933a17e78eeeef7b9343256334
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
OnisekaiCrystalCollection

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 5 of 14: OnisekaiCrystalCollection.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import {DefaultOperatorFilterer} from "./DefaultOperatorFilterer.sol";

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

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

    function _efficientHash(bytes32 a, bytes32 b)
        private
        pure
        returns (bytes32 value)
    {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

    function _verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) private pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

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

pragma solidity ^0.8.0;

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

pragma solidity ^0.8.0;

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

pragma solidity ^0.8.0;

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

pragma solidity ^0.8.0;

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

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

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

pragma solidity ^0.8.0;

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */

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

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

pragma solidity ^0.8.0;

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

    string public _baseURI;

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

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

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

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId)
        public
        view
        virtual
        override
        returns (address)
    {
        address owner = _owners[tokenId];
        require(
            owner != address(0),
            "ERC721: owner query for nonexistent token"
        );
        return owner;
    }

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI query for nonexistent token"
        );

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

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

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

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

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId)
        public
        view
        virtual
        override
        returns (address)
    {
        require(
            _exists(tokenId),
            "ERC721: approved query for nonexistent token"
        );

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved)
        public
        virtual
        override
    {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

        _balances[to] += 1;
        _owners[tokenId] = to;

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

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

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

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

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

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

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

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

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

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}
pragma solidity ^0.8.0;

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

pragma solidity ^0.8.0;

contract OnisekaiCrystalCollection is ERC721, Ownable, DefaultOperatorFilterer {
    using SafeMath for uint256;
    using Strings for uint256;

    uint256 public constant _TOTALSUPPLY = 1000;

    uint256 public tokenIDRed = 1;
    uint256 public tokenIDBlue = 501;
    uint256 public _totalMinted = 0;
    uint public status = 0; //0-pause 1-IZANAGI 2-INANAMI

    // ---------- IZANAMI SALE ----------- //
    uint256 public IZM_TotalAvailable = 164;
    uint256 public MAX_PER_QUANTITY = 1; // maximum amount that user can mint/Transaction
    uint256 public MAX_PER_WALLET = 1; // maximum amount that user can mint/Wallet
    uint256 public price = 0 ether;

    bytes32 public IZM_ListMerkleRoot;
    mapping(address => uint256) public IZM_ClaimedBy;
    bool public isAllowBurn = false;

    constructor() ERC721("Onisekai Crystal Collection", "OCC") {}

    function setBaseURI(string memory baseURI) public onlyOwner {
        _baseURI = baseURI;
    }

    modifier isSaleOpen() {
        require(totalSupply() < _TOTALSUPPLY, "Sale end");
        _;
    }

    function setPrice(uint256 _newPrice) public onlyOwner {
        price = _newPrice;
    }

    function setMax_PER_QUANTITY(uint256 _quantity) public onlyOwner {
        MAX_PER_QUANTITY = _quantity;
    }

    function setTotalAvailable_IZM(uint256 _IZMCollection)
        external
        onlyOwner
    {
        IZM_TotalAvailable = _IZMCollection;
    }

    function setIZMListMerkleRoot(bytes32 _IZMListMerkleRoot) external onlyOwner {
        IZM_ListMerkleRoot = _IZMListMerkleRoot;
    }

    function changeMAX_PER_WALLET(uint256 q) external onlyOwner {
        MAX_PER_WALLET = q;
    }

    function setStatus(uint256 s)external onlyOwner{
      status = s;
  }

   function getStatus()public view returns(uint){
      return status;
  }

    function getPrice(uint256 _quantity) public view returns (uint256) {
        return _quantity * price;
    }

    function inIZMlist(bytes32[] memory _proof, address _owner) public view returns (bool) {
        return MerkleProof.verify(_proof, IZM_ListMerkleRoot, keccak256(abi.encodePacked(_owner)));
    }

    function mint(uint256 _quantity, bytes32[] calldata _proof, uint256 _colorCode) public payable isSaleOpen {
        require(status == 2 , "Sale is not active");
        require(totalSupply() + _quantity <= _TOTALSUPPLY,"Quantity must be lesser then MaxSupply");
        require(totalSupply() + _quantity <= IZM_TotalAvailable,"Quantity must be lesser then IZM Total Available");
        require(inIZMlist(_proof, msg.sender), "You are not in presale");
        require(_quantity <= MAX_PER_QUANTITY,"can not mint this many");
        require(msg.value >= _quantity * price, "Try to send more ETH");

        IZM_ClaimedBy[msg.sender] += _quantity;
        require(IZM_ClaimedBy[msg.sender] <= MAX_PER_WALLET,"Purchase exceeds max allowed");

        if(_colorCode == 1){        
        require((tokenIDRed + _quantity) - 1 <= 500,"Quantity must be lesser then MaxSupply for Red");
        for (uint256 i = 0; i < _quantity; i++) {
               _safeMint(msg.sender, tokenIDRed);
               tokenIDRed++;
               _totalMinted++;
            }
        } else {
        require((tokenIDBlue + _quantity) -1 <= 1000,"Quantity must be lesser then MaxSupply for Blue");
        for (uint256 i = 0; i < _quantity; i++) {
            _safeMint(msg.sender, tokenIDBlue);
            tokenIDBlue++;
            _totalMinted++;
            }
        }
    }

    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(_exists(tokenId),"ERC721Metadata: URI query for nonexistent token");

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

    }

    function withdraw() public onlyOwner {
        uint256 balance = address(this).balance;
        payable(msg.sender).transfer(balance);
    }

    function airdropRed(address sendTo, uint256 quantity) public onlyOwner {
        require((tokenIDRed + quantity) - 1 <= 500,"Quantity must be lesser then MaxSupply for Red");
        for (uint256 i = 0; i < quantity; i++) {
            _safeMint(sendTo, tokenIDRed);
            tokenIDRed++;
            _totalMinted++;
        }
    }

    function airdropBlue(address sendTo, uint256 quantity) public onlyOwner {
        require((tokenIDBlue + quantity) -1 <= 1000,"Quantity must be lesser then MaxSupply for Blue");
        for (uint256 i = 0; i < quantity; i++) {
            _safeMint(sendTo, tokenIDBlue);
            tokenIDBlue++;
            _totalMinted++;
        }
    }

    function totalSupply() public view returns (uint256) {
        return _totalMinted;
    }

     function totalRedMinted() public view returns (uint256) {
        return tokenIDRed;
    }

     function totalBlueMinted() public view returns (uint256) {
        return tokenIDBlue;
    }
        // ---------- IZANAGI Sale -------------- //

    uint256 public izgListMaxMint = 2;
    uint256 public izgListPerWallet = 2;
    bytes32 public izgListMerkleRoot;
    uint256 public izgItemPriceList = 0 ether;
    mapping(address => uint256) public izglistClaimedBy;
    uint256 public izgTotalListAvailable = 836; // total number of nfts


    function setIzgListMerkleRoot(bytes32 _izgListMerkleRoot) external onlyOwner {
        izgListMerkleRoot = _izgListMerkleRoot;
    }

    function getIzgListPrice(uint256 _quantity) public view returns (uint256) {
       
           return _quantity*izgItemPriceList;
    }

    function inIzglist(bytes32[] memory _proof, address _owner) public view returns (bool) {
        return MerkleProof.verify(_proof, izgListMerkleRoot, keccak256(abi.encodePacked(_owner)));
    }

    function mintIZG(uint256 _howMany, bytes32[] calldata _proof, uint256 _colorCode) external payable {
        require(status == 1 , "Sale is not active");
        require(totalSupply()+_howMany<=izgTotalListAvailable,"Quantity must be lesser then MaxSupply");
        require(inIzglist(_proof, msg.sender), "You are not in presale");
        require(_howMany <= izgListMaxMint,"can not mint this many");
        require(msg.value >= _howMany * izgItemPriceList, "Try to send more ETH");

        izglistClaimedBy[msg.sender] += _howMany;
        require(izglistClaimedBy[msg.sender] <= izgListPerWallet, "Purchase exceeds max allowed");

        if(_colorCode == 1){
            // 1 is RED
        require((tokenIDRed + _howMany) - 1 <= 500,"Quantity must be lesser then MaxSupply for Red");
        for (uint256 i = 0; i < _howMany; i++) {
            _safeMint(msg.sender, tokenIDRed);
            tokenIDRed++;
            _totalMinted++;
        }

        } else {
           // 2 is Blue
        require((tokenIDBlue + _howMany) -1 <= 1000,"Quantity must be lesser then MaxSupply for Blue");
        for (uint256 i = 0; i < _howMany; i++) {
            _safeMint(msg.sender, tokenIDBlue);
            tokenIDBlue++;
            _totalMinted++;
        }   
     }
    }

    function setIzgListMaxMint(uint256 _listMaxMint) external onlyOwner {
        izgListMaxMint = _listMaxMint;
    }

    function setIzgListPerWallet(uint256 _listPerWallet) external onlyOwner {
        izgListPerWallet = _listPerWallet;
    }

    function setIzgListAvailable(uint256 _listCollection) external onlyOwner {
        izgTotalListAvailable = _listCollection;
    }

    function setIzgItemPrice(uint256 _newPrice) public onlyOwner {
        izgItemPriceList = _newPrice;
    }

    function changeAllowBurning(bool _value) external onlyOwner {
        isAllowBurn = _value;
    }

    function burn(uint256 tokenId) public {
        require(isAllowBurn == true, "Burning Token is not allowed");
        require(_isApprovedOrOwner(_msgSender(), tokenId),"ERC721: caller is not token owner or approved");
        _burn(tokenId);
    }

    // ---------- CREATOR FEES CODE -------- //

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

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

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

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

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

File 1 of 14: Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

File 2 of 14: DefaultOperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {OperatorFilterer} from "./OperatorFilterer.sol";

/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 */
abstract contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}

File 3 of 14: EnumerableSet.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

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

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

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

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

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

            if (lastIndex != toDeleteIndex) {
                bytes32 lastValue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastValue;
                // Update the index for the moved value
                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
            }

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

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

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

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

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

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

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set)
        internal
        view
        returns (bytes32[] memory)
    {
        bytes32[] memory store = _values(set._inner);
        bytes32[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

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

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

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

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

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

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set)
        internal
        view
        returns (address[] memory)
    {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

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

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

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set)
        internal
        view
        returns (uint256[] memory)
    {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}

File 4 of 14: IOperatorFilterRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);
    function register(address registrant) external;
    function registerAndSubscribe(address registrant, address subscription) external;
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;
    function unregister(address addr) external;
    function updateOperator(address registrant, address operator, bool filtered) external;
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
    function subscribe(address registrant, address registrantToSubscribe) external;
    function unsubscribe(address registrant, bool copyExistingEntries) external;
    function subscriptionOf(address addr) external returns (address registrant);
    function subscribers(address registrant) external returns (address[] memory);
    function subscriberAt(address registrant, uint256 index) external returns (address);
    function copyEntriesOf(address registrant, address registrantToCopy) external;
    function isOperatorFiltered(address registrant, address operator) external returns (bool);
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
    function filteredOperators(address addr) external returns (address[] memory);
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
    function isRegistered(address addr) external returns (bool);
    function codeHashOf(address addr) external returns (bytes32);
}

File 6 of 14: OperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";

/**
 * @title  OperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 */
abstract contract OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

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

    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    function _checkFilterOperator(address operator) internal view virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}

File 7 of 14: OperatorFilterRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";
import {Ownable} from "./Ownable.sol";
import {EnumerableSet} from "./EnumerableSet.sol";
import {OperatorFilterRegistryErrorsAndEvents} from "./OperatorFilterRegistryErrorsAndEvents.sol";

/**
 * @title  OperatorFilterRegistry
 * @notice Borrows heavily from the QQL BlacklistOperatorFilter contract:
 *         https://github.com/qql-art/contracts/blob/main/contracts/BlacklistOperatorFilter.sol
 * @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be
 * *       restricted according to the isOperatorAllowed function.
 */
contract OperatorFilterRegistry is IOperatorFilterRegistry, OperatorFilterRegistryErrorsAndEvents {
    using EnumerableSet for EnumerableSet.AddressSet;
    using EnumerableSet for EnumerableSet.Bytes32Set;

    /// @dev initialized accounts have a nonzero codehash (see https://eips.ethereum.org/EIPS/eip-1052)
    /// Note that this will also be a smart contract's codehash when making calls from its constructor.
    bytes32 constant EOA_CODEHASH = keccak256("");

    mapping(address => EnumerableSet.AddressSet) private _filteredOperators;
    mapping(address => EnumerableSet.Bytes32Set) private _filteredCodeHashes;
    mapping(address => address) private _registrations;
    mapping(address => EnumerableSet.AddressSet) private _subscribers;

    /**
     * @notice restricts method caller to the address or EIP-173 "owner()"
     */
    modifier onlyAddressOrOwner(address addr) {
        if (msg.sender != addr) {
            try Ownable(addr).owner() returns (address owner) {
                if (msg.sender != owner) {
                    revert OnlyAddressOrOwner();
                }
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert NotOwnable();
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        }
        _;
    }

    /**
     * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns
     *         true if supplied registrant address is not registered.
     */
    function isOperatorAllowed(address registrant, address operator) external view returns (bool) {
        address registration = _registrations[registrant];
        if (registration != address(0)) {
            EnumerableSet.AddressSet storage filteredOperatorsRef;
            EnumerableSet.Bytes32Set storage filteredCodeHashesRef;

            filteredOperatorsRef = _filteredOperators[registration];
            filteredCodeHashesRef = _filteredCodeHashes[registration];

            if (filteredOperatorsRef.contains(operator)) {
                revert AddressFiltered(operator);
            }
            if (operator.code.length > 0) {
                bytes32 codeHash = operator.codehash;
                if (filteredCodeHashesRef.contains(codeHash)) {
                    revert CodeHashFiltered(operator, codeHash);
                }
            }
        }
        return true;
    }

    //////////////////
    // AUTH METHODS //
    //////////////////

    /**
     * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.
     */
    function register(address registrant) external onlyAddressOrOwner(registrant) {
        if (_registrations[registrant] != address(0)) {
            revert AlreadyRegistered();
        }
        _registrations[registrant] = registrant;
        emit RegistrationUpdated(registrant, true);
    }

    /**
     * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.
     *         Note that this does not remove any filtered addresses or codeHashes.
     *         Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.
     */
    function unregister(address registrant) external onlyAddressOrOwner(registrant) {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            _subscribers[registration].remove(registrant);
            emit SubscriptionUpdated(registrant, registration, false);
        }
        _registrations[registrant] = address(0);
        emit RegistrationUpdated(registrant, false);
    }

    /**
     * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes.
     */
    function registerAndSubscribe(address registrant, address subscription) external onlyAddressOrOwner(registrant) {
        address registration = _registrations[registrant];
        if (registration != address(0)) {
            revert AlreadyRegistered();
        }
        if (registrant == subscription) {
            revert CannotSubscribeToSelf();
        }
        address subscriptionRegistration = _registrations[subscription];
        if (subscriptionRegistration == address(0)) {
            revert NotRegistered(subscription);
        }
        if (subscriptionRegistration != subscription) {
            revert CannotSubscribeToRegistrantWithSubscription(subscription);
        }

        _registrations[registrant] = subscription;
        _subscribers[subscription].add(registrant);
        emit RegistrationUpdated(registrant, true);
        emit SubscriptionUpdated(registrant, subscription, true);
    }

    /**
     * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another
     *         address without subscribing.
     */
    function registerAndCopyEntries(address registrant, address registrantToCopy)
        external
        onlyAddressOrOwner(registrant)
    {
        if (registrantToCopy == registrant) {
            revert CannotCopyFromSelf();
        }
        address registration = _registrations[registrant];
        if (registration != address(0)) {
            revert AlreadyRegistered();
        }
        address registrantRegistration = _registrations[registrantToCopy];
        if (registrantRegistration == address(0)) {
            revert NotRegistered(registrantToCopy);
        }
        _registrations[registrant] = registrant;
        emit RegistrationUpdated(registrant, true);
        _copyEntries(registrant, registrantToCopy);
    }

    /**
     * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.
     */
    function updateOperator(address registrant, address operator, bool filtered)
        external
        onlyAddressOrOwner(registrant)
    {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];

        if (!filtered) {
            bool removed = filteredOperatorsRef.remove(operator);
            if (!removed) {
                revert AddressNotFiltered(operator);
            }
        } else {
            bool added = filteredOperatorsRef.add(operator);
            if (!added) {
                revert AddressAlreadyFiltered(operator);
            }
        }
        emit OperatorUpdated(registrant, operator, filtered);
    }

    /**
     * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.
     */
    function updateCodeHash(address registrant, bytes32 codeHash, bool filtered)
        external
        onlyAddressOrOwner(registrant)
    {
        if (codeHash == EOA_CODEHASH) {
            revert CannotFilterEOAs();
        }
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];

        if (!filtered) {
            bool removed = filteredCodeHashesRef.remove(codeHash);
            if (!removed) {
                revert CodeHashNotFiltered(codeHash);
            }
        } else {
            bool added = filteredCodeHashesRef.add(codeHash);
            if (!added) {
                revert CodeHashAlreadyFiltered(codeHash);
            }
        }
        emit CodeHashUpdated(registrant, codeHash, filtered);
    }

    /**
     * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.
     */
    function updateOperators(address registrant, address[] calldata operators, bool filtered)
        external
        onlyAddressOrOwner(registrant)
    {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];
        uint256 operatorsLength = operators.length;
        unchecked {
            if (!filtered) {
                for (uint256 i = 0; i < operatorsLength; ++i) {
                    address operator = operators[i];
                    bool removed = filteredOperatorsRef.remove(operator);
                    if (!removed) {
                        revert AddressNotFiltered(operator);
                    }
                }
            } else {
                for (uint256 i = 0; i < operatorsLength; ++i) {
                    address operator = operators[i];
                    bool added = filteredOperatorsRef.add(operator);
                    if (!added) {
                        revert AddressAlreadyFiltered(operator);
                    }
                }
            }
        }
        emit OperatorsUpdated(registrant, operators, filtered);
    }

    /**
     * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.
     */
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered)
        external
        onlyAddressOrOwner(registrant)
    {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];
        uint256 codeHashesLength = codeHashes.length;
        unchecked {
            if (!filtered) {
                for (uint256 i = 0; i < codeHashesLength; ++i) {
                    bytes32 codeHash = codeHashes[i];
                    bool removed = filteredCodeHashesRef.remove(codeHash);
                    if (!removed) {
                        revert CodeHashNotFiltered(codeHash);
                    }
                }
            } else {
                for (uint256 i = 0; i < codeHashesLength; ++i) {
                    bytes32 codeHash = codeHashes[i];
                    if (codeHash == EOA_CODEHASH) {
                        revert CannotFilterEOAs();
                    }
                    bool added = filteredCodeHashesRef.add(codeHash);
                    if (!added) {
                        revert CodeHashAlreadyFiltered(codeHash);
                    }
                }
            }
        }
        emit CodeHashesUpdated(registrant, codeHashes, filtered);
    }

    /**
     * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous
     *         subscription if present.
     *         Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,
     *         subscriptions will not be forwarded. Instead the former subscription's existing entries will still be
     *         used.
     */
    function subscribe(address registrant, address newSubscription) external onlyAddressOrOwner(registrant) {
        if (registrant == newSubscription) {
            revert CannotSubscribeToSelf();
        }
        if (newSubscription == address(0)) {
            revert CannotSubscribeToZeroAddress();
        }
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration == newSubscription) {
            revert AlreadySubscribed(newSubscription);
        }
        address newSubscriptionRegistration = _registrations[newSubscription];
        if (newSubscriptionRegistration == address(0)) {
            revert NotRegistered(newSubscription);
        }
        if (newSubscriptionRegistration != newSubscription) {
            revert CannotSubscribeToRegistrantWithSubscription(newSubscription);
        }

        if (registration != registrant) {
            _subscribers[registration].remove(registrant);
            emit SubscriptionUpdated(registrant, registration, false);
        }
        _registrations[registrant] = newSubscription;
        _subscribers[newSubscription].add(registrant);
        emit SubscriptionUpdated(registrant, newSubscription, true);
    }

    /**
     * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.
     */
    function unsubscribe(address registrant, bool copyExistingEntries) external onlyAddressOrOwner(registrant) {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration == registrant) {
            revert NotSubscribed();
        }
        _subscribers[registration].remove(registrant);
        _registrations[registrant] = registrant;
        emit SubscriptionUpdated(registrant, registration, false);
        if (copyExistingEntries) {
            _copyEntries(registrant, registration);
        }
    }

    /**
     * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.
     */
    function copyEntriesOf(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) {
        if (registrant == registrantToCopy) {
            revert CannotCopyFromSelf();
        }
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        address registrantRegistration = _registrations[registrantToCopy];
        if (registrantRegistration == address(0)) {
            revert NotRegistered(registrantToCopy);
        }
        _copyEntries(registrant, registrantToCopy);
    }

    /// @dev helper to copy entries from registrantToCopy to registrant and emit events
    function _copyEntries(address registrant, address registrantToCopy) private {
        EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrantToCopy];
        EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrantToCopy];
        uint256 filteredOperatorsLength = filteredOperatorsRef.length();
        uint256 filteredCodeHashesLength = filteredCodeHashesRef.length();
        unchecked {
            for (uint256 i = 0; i < filteredOperatorsLength; ++i) {
                address operator = filteredOperatorsRef.at(i);
                bool added = _filteredOperators[registrant].add(operator);
                if (added) {
                    emit OperatorUpdated(registrant, operator, true);
                }
            }
            for (uint256 i = 0; i < filteredCodeHashesLength; ++i) {
                bytes32 codehash = filteredCodeHashesRef.at(i);
                bool added = _filteredCodeHashes[registrant].add(codehash);
                if (added) {
                    emit CodeHashUpdated(registrant, codehash, true);
                }
            }
        }
    }

    //////////////////
    // VIEW METHODS //
    //////////////////

    /**
     * @notice Get the subscription address of a given registrant, if any.
     */
    function subscriptionOf(address registrant) external view returns (address subscription) {
        subscription = _registrations[registrant];
        if (subscription == address(0)) {
            revert NotRegistered(registrant);
        } else if (subscription == registrant) {
            subscription = address(0);
        }
    }

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

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

    /**
     * @notice Returns true if operator is filtered by a given address or its subscription.
     */
    function isOperatorFiltered(address registrant, address operator) external view returns (bool) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredOperators[registration].contains(operator);
        }
        return _filteredOperators[registrant].contains(operator);
    }

    /**
     * @notice Returns true if a codeHash is filtered by a given address or its subscription.
     */
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external view returns (bool) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredCodeHashes[registration].contains(codeHash);
        }
        return _filteredCodeHashes[registrant].contains(codeHash);
    }

    /**
     * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.
     */
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external view returns (bool) {
        bytes32 codeHash = operatorWithCode.codehash;
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredCodeHashes[registration].contains(codeHash);
        }
        return _filteredCodeHashes[registrant].contains(codeHash);
    }

    /**
     * @notice Returns true if an address has registered
     */
    function isRegistered(address registrant) external view returns (bool) {
        return _registrations[registrant] != address(0);
    }

    /**
     * @notice Returns a list of filtered operators for a given address or its subscription.
     */
    function filteredOperators(address registrant) external view returns (address[] memory) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredOperators[registration].values();
        }
        return _filteredOperators[registrant].values();
    }

    /**
     * @notice Returns the set of filtered codeHashes for a given address or its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashes(address registrant) external view returns (bytes32[] memory) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredCodeHashes[registration].values();
        }
        return _filteredCodeHashes[registrant].values();
    }

    /**
     * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredOperatorAt(address registrant, uint256 index) external view returns (address) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredOperators[registration].at(index);
        }
        return _filteredOperators[registrant].at(index);
    }

    /**
     * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashAt(address registrant, uint256 index) external view returns (bytes32) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredCodeHashes[registration].at(index);
        }
        return _filteredCodeHashes[registrant].at(index);
    }

    /// @dev Convenience method to compute the code hash of an arbitrary contract
    function codeHashOf(address a) external view returns (bytes32) {
        return a.codehash;
    }
}

File 8 of 14: OperatorFilterRegistryErrorsAndEvents.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

contract OperatorFilterRegistryErrorsAndEvents {
    error CannotFilterEOAs();
    error AddressAlreadyFiltered(address operator);
    error AddressNotFiltered(address operator);
    error CodeHashAlreadyFiltered(bytes32 codeHash);
    error CodeHashNotFiltered(bytes32 codeHash);
    error OnlyAddressOrOwner();
    error NotRegistered(address registrant);
    error AlreadyRegistered();
    error AlreadySubscribed(address subscription);
    error NotSubscribed();
    error CannotUpdateWhileSubscribed(address subscription);
    error CannotSubscribeToSelf();
    error CannotSubscribeToZeroAddress();
    error NotOwnable();
    error AddressFiltered(address filtered);
    error CodeHashFiltered(address account, bytes32 codeHash);
    error CannotSubscribeToRegistrantWithSubscription(address registrant);
    error CannotCopyFromSelf();

    event RegistrationUpdated(address indexed registrant, bool indexed registered);
    event OperatorUpdated(address indexed registrant, address indexed operator, bool indexed filtered);
    event OperatorsUpdated(address indexed registrant, address[] operators, bool indexed filtered);
    event CodeHashUpdated(address indexed registrant, bytes32 indexed codeHash, bool indexed filtered);
    event CodeHashesUpdated(address indexed registrant, bytes32[] codeHashes, bool indexed filtered);
    event SubscriptionUpdated(address indexed registrant, address indexed subscription, bool indexed subscribed);
}

File 9 of 14: Ownable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {Context} from "./Context.sol";

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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

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

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

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

File 10 of 14: Ownable2Step.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./Ownable.sol";

/**
 * @dev Contract module which provides access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership} and {acceptOwnership}.
 *
 * This module is used through inheritance. It will make available all functions
 * from parent (Ownable).
 */
abstract contract Ownable2Step is Ownable {
    address private _pendingOwner;

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

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

    /**
     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner)
        public
        virtual
        override
        onlyOwner
    {
        _pendingOwner = newOwner;
        emit OwnershipTransferStarted(owner(), newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual override {
        delete _pendingOwner;
        super._transferOwnership(newOwner);
    }

    /**
     * @dev The new owner accepts the ownership transfer.
     */
    function acceptOwnership() external {
        address sender = _msgSender();
        require(
            pendingOwner() == sender,
            "Ownable2Step: caller is not the new owner"
        );
        _transferOwnership(sender);
    }
}

File 11 of 14: OwnedRegistrant.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";
import {Ownable2Step} from "./Ownable2Step.sol";
/**
 * @title  OwnedRegistrant
 * @notice Ownable contract that registers itself with the OperatorFilterRegistry and administers its own entries,
 *         to facilitate a subscription whose ownership can be transferred.
 */
contract OwnedRegistrant is Ownable2Step {
    address constant registry = 0x000000000000AAeB6D7670E522A718067333cd4E;

    constructor(address _owner) {
        IOperatorFilterRegistry(registry).register(address(this));
        transferOwnership(_owner);
    }
}

File 12 of 14: RevokableDefaultOperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {RevokableOperatorFilterer} from "./RevokableOperatorFilterer.sol";

/**
 * @title  RevokableDefaultOperatorFilterer
 * @notice Inherits from RevokableOperatorFilterer and automatically subscribes to the default OpenSea subscription.
 *         Note that OpenSea will disable creator fee enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 */
abstract contract RevokableDefaultOperatorFilterer is RevokableOperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() RevokableOperatorFilterer(0x000000000000AAeB6D7670E522A718067333cd4E, DEFAULT_SUBSCRIPTION, true) {}
}

File 13 of 14: RevokableOperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {UpdatableOperatorFilterer} from "./UpdatableOperatorFilterer.sol";
import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";

/**
 * @title  RevokableOperatorFilterer
 * @notice This contract is meant to allow contracts to permanently skip OperatorFilterRegistry checks if desired. The
 *         Registry itself has an "unregister" function, but if the contract is ownable, the owner can re-register at
 *         any point. As implemented, this abstract contract allows the contract owner to permanently skip the
 *         OperatorFilterRegistry checks by calling revokeOperatorFilterRegistry. Once done, the registry
 *         address cannot be further updated.
 *         Note that OpenSea will still disable creator fee enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 */
abstract contract RevokableOperatorFilterer is UpdatableOperatorFilterer {
    error RegistryHasBeenRevoked();
    error InitialRegistryAddressCannotBeZeroAddress();

    bool public isOperatorFilterRegistryRevoked;

    constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe)
        UpdatableOperatorFilterer(_registry, subscriptionOrRegistrantToCopy, subscribe)
    {
        // don't allow creating a contract with a permanently revoked registry
        if (_registry == address(0)) {
            revert InitialRegistryAddressCannotBeZeroAddress();
        }
    }

    function _checkFilterOperator(address operator) internal view virtual override {
        if (address(operatorFilterRegistry) != address(0)) {
            super._checkFilterOperator(operator);
        }
    }

    /**
     * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero
     *         address, checks will be permanently bypassed, and the address cannot be updated again. OnlyOwner.
     */
    function updateOperatorFilterRegistryAddress(address newRegistry) public override {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        // if registry has been revoked, do not allow further updates
        if (isOperatorFilterRegistryRevoked) {
            revert RegistryHasBeenRevoked();
        }

        operatorFilterRegistry = IOperatorFilterRegistry(newRegistry);
    }

    /**
     * @notice Revoke the OperatorFilterRegistry address, permanently bypassing checks. OnlyOwner.
     */
    function revokeOperatorFilterRegistry() public {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        // if registry has been revoked, do not allow further updates
        if (isOperatorFilterRegistryRevoked) {
            revert RegistryHasBeenRevoked();
        }

        // set to zero address to bypass checks
        operatorFilterRegistry = IOperatorFilterRegistry(address(0));
        isOperatorFilterRegistryRevoked = true;
    }
}

File 14 of 14: UpdatableOperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";

/**
 * @title  UpdatableOperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry. This contract allows the Owner to update the
 *         OperatorFilterRegistry address via updateOperatorFilterRegistryAddress, including to the zero address,
 *         which will bypass registry checks.
 *         Note that OpenSea will still disable creator fee enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 */
abstract contract UpdatableOperatorFilterer {
    error OperatorNotAllowed(address operator);
    error OnlyOwner();

    IOperatorFilterRegistry public operatorFilterRegistry;

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

    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    /**
     * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero
     *         address, checks will be bypassed. OnlyOwner.
     */
    function updateOperatorFilterRegistryAddress(address newRegistry) public virtual {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        operatorFilterRegistry = IOperatorFilterRegistry(newRegistry);
    }

    /**
     * @dev assume the contract has an owner, but leave specific Ownable implementation up to inheriting contract
     */
    function owner() public view virtual returns (address);

    function _checkFilterOperator(address operator) internal view virtual {
        IOperatorFilterRegistry registry = operatorFilterRegistry;
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(registry) != address(0) && address(registry).code.length > 0) {
            if (!registry.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"IZM_ClaimedBy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IZM_ListMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IZM_TotalAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PER_QUANTITY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PER_WALLET","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_TOTALSUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sendTo","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"airdropBlue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sendTo","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"airdropRed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_value","type":"bool"}],"name":"changeAllowBurning","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"q","type":"uint256"}],"name":"changeMAX_PER_WALLET","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"getIzgListPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStatus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"address","name":"_owner","type":"address"}],"name":"inIZMlist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"address","name":"_owner","type":"address"}],"name":"inIzglist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isAllowBurn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"izgItemPriceList","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"izgListMaxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"izgListMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"izgListPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"izgTotalListAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"izglistClaimedBy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"uint256","name":"_colorCode","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_howMany","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"uint256","name":"_colorCode","type":"uint256"}],"name":"mintIZG","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_IZMListMerkleRoot","type":"bytes32"}],"name":"setIZMListMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setIzgItemPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_listCollection","type":"uint256"}],"name":"setIzgListAvailable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_listMaxMint","type":"uint256"}],"name":"setIzgListMaxMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_izgListMerkleRoot","type":"bytes32"}],"name":"setIzgListMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_listPerWallet","type":"uint256"}],"name":"setIzgListPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"setMax_PER_QUANTITY","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"s","type":"uint256"}],"name":"setStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_IZMCollection","type":"uint256"}],"name":"setTotalAvailable_IZM","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"status","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenIDBlue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenIDRed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBlueMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRedMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260016008556101f56009556000600a556000600b5560a4600c556001600d556001600e556000600f556000601260006101000a81548160ff0219169083151502179055506002601355600260145560006016556103446018553480156200006a57600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280601b81526020017f4f6e6973656b6169204372797374616c20436f6c6c656374696f6e00000000008152506040518060400160405280600381526020017f4f434300000000000000000000000000000000000000000000000000000000008152508160009081620000ff919062000644565b50806001908162000111919062000644565b505050600062000126620003c260201b60201c565b905080600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35060006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115620003ba57801562000280576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b81526004016200024692919062000770565b600060405180830381600087803b1580156200026157600080fd5b505af115801562000276573d6000803e3d6000fd5b50505050620003b9565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146200033a576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b81526004016200030092919062000770565b600060405180830381600087803b1580156200031b57600080fd5b505af115801562000330573d6000803e3d6000fd5b50505050620003b8565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b81526004016200038391906200079d565b600060405180830381600087803b1580156200039e57600080fd5b505af1158015620003b3573d6000803e3d6000fd5b505050505b5b5b5050620007ba565b600033905090565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200044c57607f821691505b60208210810362000462576200046162000404565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620004cc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200048d565b620004d886836200048d565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620005256200051f6200051984620004f0565b620004fa565b620004f0565b9050919050565b6000819050919050565b620005418362000504565b6200055962000550826200052c565b8484546200049a565b825550505050565b600090565b6200057062000561565b6200057d81848462000536565b505050565b5b81811015620005a5576200059960008262000566565b60018101905062000583565b5050565b601f821115620005f457620005be8162000468565b620005c9846200047d565b81016020851015620005d9578190505b620005f1620005e8856200047d565b83018262000582565b50505b505050565b600082821c905092915050565b60006200061960001984600802620005f9565b1980831691505092915050565b600062000634838362000606565b9150826002028217905092915050565b6200064f82620003ca565b67ffffffffffffffff8111156200066b576200066a620003d5565b5b62000677825462000433565b62000684828285620005a9565b600060209050601f831160018114620006bc5760008415620006a7578287015190505b620006b3858262000626565b86555062000723565b601f198416620006cc8662000468565b60005b82811015620006f657848901518255600182019150602085019450602081019050620006cf565b8683101562000716578489015162000712601f89168262000606565b8355505b6001600288020188555050505b505050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000758826200072b565b9050919050565b6200076a816200074b565b82525050565b60006040820190506200078760008301856200075f565b6200079660208301846200075f565b9392505050565b6000602082019050620007b460008301846200075f565b92915050565b615d8280620007ca6000396000f3fe6080604052600436106103ad5760003560e01c806369ba1a75116101e7578063a22cb4651161010d578063cd6efd09116100a0578063e361d15a1161006f578063e361d15a14610dca578063e757223014610df3578063e985e9c514610e30578063f2fde38b14610e6d576103ad565b8063cd6efd0914610d1e578063d9ef720414610d49578063db4568e214610d74578063e26b83d214610d9f576103ad565b8063c25214a9116100dc578063c25214a914610c62578063c87b56dd14610c8b578063ca96e41c14610cc8578063cd4ce50e14610cf3576103ad565b8063a22cb46514610bbe578063a95f3a5b14610be7578063b88d4fde14610c10578063bdc4f06314610c39576103ad565b80638f79edeb1161018557806395d89b411161015457806395d89b4114610b125780639a918bab14610b3d5780639d6bcba614610b68578063a035b1fe14610b93576103ad565b80638f79edeb14610a585780639072cb0814610a8357806390cdb17914610aac57806391b7f5ed14610ae9576103ad565b8063743976a0116101c1578063743976a01461099a5780637e1258c0146109c55780638b97645f146109f05780638da5cb5b14610a2d576103ad565b806369ba1a751461090957806370a0823114610932578063736bf5911461096f576103ad565b8063318dd32f116102d75780634e69d5601161026a5780635a8d7784116102395780635a8d77841461085c5780635ede2eae14610885578063624b024b146108a15780636352211e146108cc576103ad565b80634e69d560146107a25780634f4230dc146107cd57806354bf80b5146107f657806355f804b314610833576103ad565b806342842e0e116102a657806342842e0e146106ea57806342966c681461071357806346bb00ce1461073c5780634e56c96914610779576103ad565b8063318dd32f146106545780633ccfd60b1461067f5780633dee43be1461069657806341f43434146106bf576103ad565b8063173f60641161034f57806323b872dd1161031e57806323b872dd1461059c57806323bd6237146105c55780632ba2865b146106025780632ccc4f6c1461062b576103ad565b8063173f60641461050157806318160ddd1461052a5780631ff7712f14610555578063200d2ed214610571576103ad565b8063081812fc1161038b578063081812fc14610445578063095ea7b3146104825780630e7fd5df146104ab5780630f2cdd6c146104d6576103ad565b806301ffc9a7146103b257806302c3fb53146103ef57806306fdde031461041a575b600080fd5b3480156103be57600080fd5b506103d960048036038101906103d49190613e23565b610e96565b6040516103e69190613e6b565b60405180910390f35b3480156103fb57600080fd5b50610404610f78565b6040516104119190613e9f565b60405180910390f35b34801561042657600080fd5b5061042f610f7e565b60405161043c9190613f4a565b60405180910390f35b34801561045157600080fd5b5061046c60048036038101906104679190613f98565b611010565b6040516104799190614006565b60405180910390f35b34801561048e57600080fd5b506104a960048036038101906104a4919061404d565b611095565b005b3480156104b757600080fd5b506104c06110ae565b6040516104cd9190613e9f565b60405180910390f35b3480156104e257600080fd5b506104eb6110b4565b6040516104f89190613e9f565b60405180910390f35b34801561050d57600080fd5b50610528600480360381019061052391906140c3565b6110ba565b005b34801561053657600080fd5b5061053f611140565b60405161054c9190613e9f565b60405180910390f35b61056f600480360381019061056a9190614155565b61114a565b005b34801561057d57600080fd5b50610586611607565b6040516105939190613e9f565b60405180910390f35b3480156105a857600080fd5b506105c360048036038101906105be91906141c9565b61160d565b005b3480156105d157600080fd5b506105ec60048036038101906105e7919061421c565b61165c565b6040516105f99190613e9f565b60405180910390f35b34801561060e57600080fd5b5061062960048036038101906106249190613f98565b611674565b005b34801561063757600080fd5b50610652600480360381019061064d91906140c3565b6116fa565b005b34801561066057600080fd5b50610669611780565b6040516106769190613e9f565b60405180910390f35b34801561068b57600080fd5b50610694611786565b005b3480156106a257600080fd5b506106bd60048036038101906106b89190613f98565b611851565b005b3480156106cb57600080fd5b506106d46118d7565b6040516106e191906142a8565b60405180910390f35b3480156106f657600080fd5b50610711600480360381019061070c91906141c9565b6118e9565b005b34801561071f57600080fd5b5061073a60048036038101906107359190613f98565b611938565b005b34801561074857600080fd5b50610763600480360381019061075e9190614401565b6119ea565b6040516107709190613e6b565b60405180910390f35b34801561078557600080fd5b506107a0600480360381019061079b9190613f98565b611a27565b005b3480156107ae57600080fd5b506107b7611aad565b6040516107c49190613e9f565b60405180910390f35b3480156107d957600080fd5b506107f460048036038101906107ef9190613f98565b611ab7565b005b34801561080257600080fd5b5061081d6004803603810190610818919061421c565b611b3d565b60405161082a9190613e9f565b60405180910390f35b34801561083f57600080fd5b5061085a60048036038101906108559190614512565b611b55565b005b34801561086857600080fd5b50610883600480360381019061087e9190614587565b611be4565b005b61089f600480360381019061089a9190614155565b611c7d565b005b3480156108ad57600080fd5b506108b6612098565b6040516108c391906145c3565b60405180910390f35b3480156108d857600080fd5b506108f360048036038101906108ee9190613f98565b61209e565b6040516109009190614006565b60405180910390f35b34801561091557600080fd5b50610930600480360381019061092b9190613f98565b61214f565b005b34801561093e57600080fd5b506109596004803603810190610954919061421c565b6121d5565b6040516109669190613e9f565b60405180910390f35b34801561097b57600080fd5b5061098461228c565b6040516109919190613e9f565b60405180910390f35b3480156109a657600080fd5b506109af612292565b6040516109bc9190613f4a565b60405180910390f35b3480156109d157600080fd5b506109da612320565b6040516109e79190613e9f565b60405180910390f35b3480156109fc57600080fd5b50610a176004803603810190610a129190613f98565b612326565b604051610a249190613e9f565b60405180910390f35b348015610a3957600080fd5b50610a4261233d565b604051610a4f9190614006565b60405180910390f35b348015610a6457600080fd5b50610a6d612367565b604051610a7a9190613e9f565b60405180910390f35b348015610a8f57600080fd5b50610aaa6004803603810190610aa5919061404d565b612371565b005b348015610ab857600080fd5b50610ad36004803603810190610ace9190614401565b6124aa565b604051610ae09190613e6b565b60405180910390f35b348015610af557600080fd5b50610b106004803603810190610b0b9190613f98565b6124e7565b005b348015610b1e57600080fd5b50610b2761256d565b604051610b349190613f4a565b60405180910390f35b348015610b4957600080fd5b50610b526125ff565b604051610b5f9190613e9f565b60405180910390f35b348015610b7457600080fd5b50610b7d612605565b604051610b8a9190613e9f565b60405180910390f35b348015610b9f57600080fd5b50610ba861260b565b604051610bb59190613e9f565b60405180910390f35b348015610bca57600080fd5b50610be56004803603810190610be091906145de565b612611565b005b348015610bf357600080fd5b50610c0e6004803603810190610c099190613f98565b61262a565b005b348015610c1c57600080fd5b50610c376004803603810190610c3291906146bf565b6126b0565b005b348015610c4557600080fd5b50610c606004803603810190610c5b9190613f98565b612701565b005b348015610c6e57600080fd5b50610c896004803603810190610c849190613f98565b612787565b005b348015610c9757600080fd5b50610cb26004803603810190610cad9190613f98565b61280d565b604051610cbf9190613f4a565b60405180910390f35b348015610cd457600080fd5b50610cdd6128b4565b604051610cea91906145c3565b60405180910390f35b348015610cff57600080fd5b50610d086128ba565b604051610d159190613e9f565b60405180910390f35b348015610d2a57600080fd5b50610d336128c0565b604051610d409190613e9f565b60405180910390f35b348015610d5557600080fd5b50610d5e6128c6565b604051610d6b9190613e9f565b60405180910390f35b348015610d8057600080fd5b50610d896128d0565b604051610d969190613e9f565b60405180910390f35b348015610dab57600080fd5b50610db46128d6565b604051610dc19190613e6b565b60405180910390f35b348015610dd657600080fd5b50610df16004803603810190610dec919061404d565b6128e9565b005b348015610dff57600080fd5b50610e1a6004803603810190610e159190613f98565b612a22565b604051610e279190613e9f565b60405180910390f35b348015610e3c57600080fd5b50610e576004803603810190610e529190614742565b612a39565b604051610e649190613e6b565b60405180910390f35b348015610e7957600080fd5b50610e946004803603810190610e8f919061421c565b612acd565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610f6157507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610f715750610f7082612bc4565b5b9050919050565b60095481565b606060008054610f8d906147b1565b80601f0160208091040260200160405190810160405280929190818152602001828054610fb9906147b1565b80156110065780601f10610fdb57610100808354040283529160200191611006565b820191906000526020600020905b815481529060010190602001808311610fe957829003601f168201915b5050505050905090565b600061101b82612c2e565b61105a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105190614854565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8161109f81612c9a565b6110a98383612d97565b505050565b60145481565b600e5481565b6110c2612eae565b73ffffffffffffffffffffffffffffffffffffffff166110e061233d565b73ffffffffffffffffffffffffffffffffffffffff1614611136576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112d906148c0565b60405180910390fd5b8060158190555050565b6000600a54905090565b6103e8611155611140565b10611195576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118c9061492c565b60405180910390fd5b6002600b54146111da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d190614998565b60405180910390fd5b6103e8846111e6611140565b6111f091906149e7565b1115611231576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161122890614a8d565b60405180910390fd5b600c548461123d611140565b61124791906149e7565b1115611288576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127f90614b1f565b60405180910390fd5b6112d3838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050336124aa565b611312576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130990614b8b565b60405180910390fd5b600d54841115611357576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134e90614bf7565b60405180910390fd5b600f54846113659190614c17565b3410156113a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139e90614ca5565b60405180910390fd5b83601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546113f691906149e7565b92505081905550600e54601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611481576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147890614d11565b60405180910390fd5b60018103611547576101f460018560085461149c91906149e7565b6114a69190614d31565b11156114e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114de90614dd7565b60405180910390fd5b60005b84811015611541576114fe33600854612eb6565b6008600081548092919061151190614df7565b9190505550600a600081548092919061152990614df7565b9190505550808061153990614df7565b9150506114ea565b50611601565b6103e860018560095461155a91906149e7565b6115649190614d31565b11156115a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159c90614eb1565b60405180910390fd5b60005b848110156115ff576115bc33600954612eb6565b600960008154809291906115cf90614df7565b9190505550600a60008154809291906115e790614df7565b919050555080806115f790614df7565b9150506115a8565b505b50505050565b600b5481565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461164b5761164a33612c9a565b5b611656848484612ed4565b50505050565b60176020528060005260406000206000915090505481565b61167c612eae565b73ffffffffffffffffffffffffffffffffffffffff1661169a61233d565b73ffffffffffffffffffffffffffffffffffffffff16146116f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e7906148c0565b60405180910390fd5b80600e8190555050565b611702612eae565b73ffffffffffffffffffffffffffffffffffffffff1661172061233d565b73ffffffffffffffffffffffffffffffffffffffff1614611776576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161176d906148c0565b60405180910390fd5b8060108190555050565b60135481565b61178e612eae565b73ffffffffffffffffffffffffffffffffffffffff166117ac61233d565b73ffffffffffffffffffffffffffffffffffffffff1614611802576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f9906148c0565b60405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561184d573d6000803e3d6000fd5b5050565b611859612eae565b73ffffffffffffffffffffffffffffffffffffffff1661187761233d565b73ffffffffffffffffffffffffffffffffffffffff16146118cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c4906148c0565b60405180910390fd5b8060148190555050565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146119275761192633612c9a565b5b611932848484612f34565b50505050565b60011515601260009054906101000a900460ff1615151461198e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161198590614f1d565b60405180910390fd5b61199f611999612eae565b82612f54565b6119de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d590614faf565b60405180910390fd5b6119e781613032565b50565b6000611a1f8360155484604051602001611a049190615017565b60405160208183030381529060405280519060200120613143565b905092915050565b611a2f612eae565b73ffffffffffffffffffffffffffffffffffffffff16611a4d61233d565b73ffffffffffffffffffffffffffffffffffffffff1614611aa3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9a906148c0565b60405180910390fd5b80600c8190555050565b6000600b54905090565b611abf612eae565b73ffffffffffffffffffffffffffffffffffffffff16611add61233d565b73ffffffffffffffffffffffffffffffffffffffff1614611b33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b2a906148c0565b60405180910390fd5b8060168190555050565b60116020528060005260406000206000915090505481565b611b5d612eae565b73ffffffffffffffffffffffffffffffffffffffff16611b7b61233d565b73ffffffffffffffffffffffffffffffffffffffff1614611bd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bc8906148c0565b60405180910390fd5b8060069081611be091906151d4565b5050565b611bec612eae565b73ffffffffffffffffffffffffffffffffffffffff16611c0a61233d565b73ffffffffffffffffffffffffffffffffffffffff1614611c60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c57906148c0565b60405180910390fd5b80601260006101000a81548160ff02191690831515021790555050565b6001600b5414611cc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cb990614998565b60405180910390fd5b60185484611cce611140565b611cd891906149e7565b1115611d19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1090614a8d565b60405180910390fd5b611d64838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050336119ea565b611da3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9a90614b8b565b60405180910390fd5b601354841115611de8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ddf90614bf7565b60405180910390fd5b60165484611df69190614c17565b341015611e38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e2f90614ca5565b60405180910390fd5b83601760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611e8791906149e7565b92505081905550601454601760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611f12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0990614d11565b60405180910390fd5b60018103611fd8576101f4600185600854611f2d91906149e7565b611f379190614d31565b1115611f78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6f90614dd7565b60405180910390fd5b60005b84811015611fd257611f8f33600854612eb6565b60086000815480929190611fa290614df7565b9190505550600a6000815480929190611fba90614df7565b91905055508080611fca90614df7565b915050611f7b565b50612092565b6103e8600185600954611feb91906149e7565b611ff59190614d31565b1115612036576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202d90614eb1565b60405180910390fd5b60005b848110156120905761204d33600954612eb6565b6009600081548092919061206090614df7565b9190505550600a600081548092919061207890614df7565b9190505550808061208890614df7565b915050612039565b505b50505050565b60105481565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612146576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213d90615318565b60405180910390fd5b80915050919050565b612157612eae565b73ffffffffffffffffffffffffffffffffffffffff1661217561233d565b73ffffffffffffffffffffffffffffffffffffffff16146121cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121c2906148c0565b60405180910390fd5b80600b8190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612245576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223c906153aa565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600a5481565b6006805461229f906147b1565b80601f01602080910402602001604051908101604052809291908181526020018280546122cb906147b1565b80156123185780601f106122ed57610100808354040283529160200191612318565b820191906000526020600020905b8154815290600101906020018083116122fb57829003601f168201915b505050505081565b600c5481565b6000601654826123369190614c17565b9050919050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600954905090565b612379612eae565b73ffffffffffffffffffffffffffffffffffffffff1661239761233d565b73ffffffffffffffffffffffffffffffffffffffff16146123ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123e4906148c0565b60405180910390fd5b6101f460018260085461240091906149e7565b61240a9190614d31565b111561244b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244290614dd7565b60405180910390fd5b60005b818110156124a55761246283600854612eb6565b6008600081548092919061247590614df7565b9190505550600a600081548092919061248d90614df7565b9190505550808061249d90614df7565b91505061244e565b505050565b60006124df83601054846040516020016124c49190615017565b60405160208183030381529060405280519060200120613143565b905092915050565b6124ef612eae565b73ffffffffffffffffffffffffffffffffffffffff1661250d61233d565b73ffffffffffffffffffffffffffffffffffffffff1614612563576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161255a906148c0565b60405180910390fd5b80600f8190555050565b60606001805461257c906147b1565b80601f01602080910402602001604051908101604052809291908181526020018280546125a8906147b1565b80156125f55780601f106125ca576101008083540402835291602001916125f5565b820191906000526020600020905b8154815290600101906020018083116125d857829003601f168201915b5050505050905090565b600d5481565b60085481565b600f5481565b8161261b81612c9a565b612625838361315a565b505050565b612632612eae565b73ffffffffffffffffffffffffffffffffffffffff1661265061233d565b73ffffffffffffffffffffffffffffffffffffffff16146126a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161269d906148c0565b60405180910390fd5b8060138190555050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146126ee576126ed33612c9a565b5b6126fa858585856132da565b5050505050565b612709612eae565b73ffffffffffffffffffffffffffffffffffffffff1661272761233d565b73ffffffffffffffffffffffffffffffffffffffff161461277d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612774906148c0565b60405180910390fd5b8060188190555050565b61278f612eae565b73ffffffffffffffffffffffffffffffffffffffff166127ad61233d565b73ffffffffffffffffffffffffffffffffffffffff1614612803576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127fa906148c0565b60405180910390fd5b80600d8190555050565b606061281882612c2e565b612857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161284e9061543c565b60405180910390fd5b600061286161333c565b9050600081511161288157604051806020016040528060008152506128ac565b8061288b846133ce565b60405160200161289c929190615530565b6040516020818303038152906040525b915050919050565b60155481565b60185481565b60165481565b6000600854905090565b6103e881565b601260009054906101000a900460ff1681565b6128f1612eae565b73ffffffffffffffffffffffffffffffffffffffff1661290f61233d565b73ffffffffffffffffffffffffffffffffffffffff1614612965576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161295c906148c0565b60405180910390fd5b6103e860018260095461297891906149e7565b6129829190614d31565b11156129c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129ba90614eb1565b60405180910390fd5b60005b81811015612a1d576129da83600954612eb6565b600960008154809291906129ed90614df7565b9190505550600a6000815480929190612a0590614df7565b91905055508080612a1590614df7565b9150506129c6565b505050565b6000600f5482612a329190614c17565b9050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b612ad5612eae565b73ffffffffffffffffffffffffffffffffffffffff16612af361233d565b73ffffffffffffffffffffffffffffffffffffffff1614612b49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b40906148c0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612bb8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612baf906155dc565b60405180910390fd5b612bc18161352e565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115612d94576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401612d119291906155fc565b602060405180830381865afa158015612d2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d52919061563a565b612d9357806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401612d8a9190614006565b60405180910390fd5b5b50565b6000612da28261209e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612e12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e09906156d9565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16612e31612eae565b73ffffffffffffffffffffffffffffffffffffffff161480612e605750612e5f81612e5a612eae565b612a39565b5b612e9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e969061576b565b60405180910390fd5b612ea983836135f4565b505050565b600033905090565b612ed08282604051806020016040528060008152506136ad565b5050565b612ee5612edf612eae565b82612f54565b612f24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f1b906157fd565b60405180910390fd5b612f2f838383613708565b505050565b612f4f838383604051806020016040528060008152506126b0565b505050565b6000612f5f82612c2e565b612f9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f959061588f565b60405180910390fd5b6000612fa98361209e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061301857508373ffffffffffffffffffffffffffffffffffffffff1661300084611010565b73ffffffffffffffffffffffffffffffffffffffff16145b8061302957506130288185612a39565b5b91505092915050565b600061303d8261209e565b905061304b81600084613963565b6130566000836135f4565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546130a69190614d31565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b6000826131508584613968565b1490509392505050565b613162612eae565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036131cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131c6906158fb565b60405180910390fd5b80600560006131dc612eae565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16613289612eae565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516132ce9190613e6b565b60405180910390a35050565b6132eb6132e5612eae565b83612f54565b61332a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613321906157fd565b60405180910390fd5b613336848484846139dd565b50505050565b60606006805461334b906147b1565b80601f0160208091040260200160405190810160405280929190818152602001828054613377906147b1565b80156133c45780601f10613399576101008083540402835291602001916133c4565b820191906000526020600020905b8154815290600101906020018083116133a757829003601f168201915b5050505050905090565b606060008203613415576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050613529565b600082905060005b6000821461344757808061343090614df7565b915050600a82613440919061594a565b915061341d565b60008167ffffffffffffffff811115613463576134626142c3565b5b6040519080825280601f01601f1916602001820160405280156134955781602001600182028036833780820191505090505b5090505b60008514613522576001826134ae9190614d31565b9150600a856134bd919061597b565b60306134c991906149e7565b60f81b8183815181106134df576134de6159ac565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561351b919061594a565b9450613499565b8093505050505b919050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166136678361209e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6136b78383613a39565b6136c46000848484613c06565b613703576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136fa90615a4d565b60405180910390fd5b505050565b8273ffffffffffffffffffffffffffffffffffffffff166137288261209e565b73ffffffffffffffffffffffffffffffffffffffff161461377e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161377590615adf565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036137ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137e490615b71565b60405180910390fd5b6137f8838383613963565b6138036000826135f4565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546138539190614d31565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546138aa91906149e7565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b505050565b60008082905060005b84518110156139d257600085828151811061398f5761398e6159ac565b5b602002602001015190508083116139b1576139aa8382613d8d565b92506139be565b6139bb8184613d8d565b92505b5080806139ca90614df7565b915050613971565b508091505092915050565b6139e8848484613708565b6139f484848484613c06565b613a33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a2a90615a4d565b60405180910390fd5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613aa8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a9f90615bdd565b60405180910390fd5b613ab181612c2e565b15613af1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613ae890615c49565b60405180910390fd5b613afd60008383613963565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254613b4d91906149e7565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b6000613c278473ffffffffffffffffffffffffffffffffffffffff16613da4565b15613d80578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613c50612eae565b8786866040518563ffffffff1660e01b8152600401613c729493929190615cbe565b6020604051808303816000875af1925050508015613cae57506040513d601f19601f82011682018060405250810190613cab9190615d1f565b60015b613d30573d8060008114613cde576040519150601f19603f3d011682016040523d82523d6000602084013e613ce3565b606091505b506000815103613d28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d1f90615a4d565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050613d85565b600190505b949350505050565b600082600052816020526040600020905092915050565b600080823b905060008111915050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613e0081613dcb565b8114613e0b57600080fd5b50565b600081359050613e1d81613df7565b92915050565b600060208284031215613e3957613e38613dc1565b5b6000613e4784828501613e0e565b91505092915050565b60008115159050919050565b613e6581613e50565b82525050565b6000602082019050613e806000830184613e5c565b92915050565b6000819050919050565b613e9981613e86565b82525050565b6000602082019050613eb46000830184613e90565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613ef4578082015181840152602081019050613ed9565b60008484015250505050565b6000601f19601f8301169050919050565b6000613f1c82613eba565b613f268185613ec5565b9350613f36818560208601613ed6565b613f3f81613f00565b840191505092915050565b60006020820190508181036000830152613f648184613f11565b905092915050565b613f7581613e86565b8114613f8057600080fd5b50565b600081359050613f9281613f6c565b92915050565b600060208284031215613fae57613fad613dc1565b5b6000613fbc84828501613f83565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613ff082613fc5565b9050919050565b61400081613fe5565b82525050565b600060208201905061401b6000830184613ff7565b92915050565b61402a81613fe5565b811461403557600080fd5b50565b60008135905061404781614021565b92915050565b6000806040838503121561406457614063613dc1565b5b600061407285828601614038565b925050602061408385828601613f83565b9150509250929050565b6000819050919050565b6140a08161408d565b81146140ab57600080fd5b50565b6000813590506140bd81614097565b92915050565b6000602082840312156140d9576140d8613dc1565b5b60006140e7848285016140ae565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112614115576141146140f0565b5b8235905067ffffffffffffffff811115614132576141316140f5565b5b60208301915083602082028301111561414e5761414d6140fa565b5b9250929050565b6000806000806060858703121561416f5761416e613dc1565b5b600061417d87828801613f83565b945050602085013567ffffffffffffffff81111561419e5761419d613dc6565b5b6141aa878288016140ff565b935093505060406141bd87828801613f83565b91505092959194509250565b6000806000606084860312156141e2576141e1613dc1565b5b60006141f086828701614038565b935050602061420186828701614038565b925050604061421286828701613f83565b9150509250925092565b60006020828403121561423257614231613dc1565b5b600061424084828501614038565b91505092915050565b6000819050919050565b600061426e61426961426484613fc5565b614249565b613fc5565b9050919050565b600061428082614253565b9050919050565b600061429282614275565b9050919050565b6142a281614287565b82525050565b60006020820190506142bd6000830184614299565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6142fb82613f00565b810181811067ffffffffffffffff8211171561431a576143196142c3565b5b80604052505050565b600061432d613db7565b905061433982826142f2565b919050565b600067ffffffffffffffff821115614359576143586142c3565b5b602082029050602081019050919050565b600061437d6143788461433e565b614323565b905080838252602082019050602084028301858111156143a05761439f6140fa565b5b835b818110156143c957806143b588826140ae565b8452602084019350506020810190506143a2565b5050509392505050565b600082601f8301126143e8576143e76140f0565b5b81356143f884826020860161436a565b91505092915050565b6000806040838503121561441857614417613dc1565b5b600083013567ffffffffffffffff81111561443657614435613dc6565b5b614442858286016143d3565b925050602061445385828601614038565b9150509250929050565b600080fd5b600067ffffffffffffffff82111561447d5761447c6142c3565b5b61448682613f00565b9050602081019050919050565b82818337600083830152505050565b60006144b56144b084614462565b614323565b9050828152602081018484840111156144d1576144d061445d565b5b6144dc848285614493565b509392505050565b600082601f8301126144f9576144f86140f0565b5b81356145098482602086016144a2565b91505092915050565b60006020828403121561452857614527613dc1565b5b600082013567ffffffffffffffff81111561454657614545613dc6565b5b614552848285016144e4565b91505092915050565b61456481613e50565b811461456f57600080fd5b50565b6000813590506145818161455b565b92915050565b60006020828403121561459d5761459c613dc1565b5b60006145ab84828501614572565b91505092915050565b6145bd8161408d565b82525050565b60006020820190506145d860008301846145b4565b92915050565b600080604083850312156145f5576145f4613dc1565b5b600061460385828601614038565b925050602061461485828601614572565b9150509250929050565b600067ffffffffffffffff821115614639576146386142c3565b5b61464282613f00565b9050602081019050919050565b600061466261465d8461461e565b614323565b90508281526020810184848401111561467e5761467d61445d565b5b614689848285614493565b509392505050565b600082601f8301126146a6576146a56140f0565b5b81356146b684826020860161464f565b91505092915050565b600080600080608085870312156146d9576146d8613dc1565b5b60006146e787828801614038565b94505060206146f887828801614038565b935050604061470987828801613f83565b925050606085013567ffffffffffffffff81111561472a57614729613dc6565b5b61473687828801614691565b91505092959194509250565b6000806040838503121561475957614758613dc1565b5b600061476785828601614038565b925050602061477885828601614038565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806147c957607f821691505b6020821081036147dc576147db614782565b5b50919050565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b600061483e602c83613ec5565b9150614849826147e2565b604082019050919050565b6000602082019050818103600083015261486d81614831565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006148aa602083613ec5565b91506148b582614874565b602082019050919050565b600060208201905081810360008301526148d98161489d565b9050919050565b7f53616c6520656e64000000000000000000000000000000000000000000000000600082015250565b6000614916600883613ec5565b9150614921826148e0565b602082019050919050565b6000602082019050818103600083015261494581614909565b9050919050565b7f53616c65206973206e6f74206163746976650000000000000000000000000000600082015250565b6000614982601283613ec5565b915061498d8261494c565b602082019050919050565b600060208201905081810360008301526149b181614975565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006149f282613e86565b91506149fd83613e86565b9250828201905080821115614a1557614a146149b8565b5b92915050565b7f5175616e74697479206d757374206265206c6573736572207468656e204d617860008201527f537570706c790000000000000000000000000000000000000000000000000000602082015250565b6000614a77602683613ec5565b9150614a8282614a1b565b604082019050919050565b60006020820190508181036000830152614aa681614a6a565b9050919050565b7f5175616e74697479206d757374206265206c6573736572207468656e20495a4d60008201527f20546f74616c20417661696c61626c6500000000000000000000000000000000602082015250565b6000614b09603083613ec5565b9150614b1482614aad565b604082019050919050565b60006020820190508181036000830152614b3881614afc565b9050919050565b7f596f7520617265206e6f7420696e2070726573616c6500000000000000000000600082015250565b6000614b75601683613ec5565b9150614b8082614b3f565b602082019050919050565b60006020820190508181036000830152614ba481614b68565b9050919050565b7f63616e206e6f74206d696e742074686973206d616e7900000000000000000000600082015250565b6000614be1601683613ec5565b9150614bec82614bab565b602082019050919050565b60006020820190508181036000830152614c1081614bd4565b9050919050565b6000614c2282613e86565b9150614c2d83613e86565b9250828202614c3b81613e86565b91508282048414831517614c5257614c516149b8565b5b5092915050565b7f54727920746f2073656e64206d6f726520455448000000000000000000000000600082015250565b6000614c8f601483613ec5565b9150614c9a82614c59565b602082019050919050565b60006020820190508181036000830152614cbe81614c82565b9050919050565b7f50757263686173652065786365656473206d617820616c6c6f77656400000000600082015250565b6000614cfb601c83613ec5565b9150614d0682614cc5565b602082019050919050565b60006020820190508181036000830152614d2a81614cee565b9050919050565b6000614d3c82613e86565b9150614d4783613e86565b9250828203905081811115614d5f57614d5e6149b8565b5b92915050565b7f5175616e74697479206d757374206265206c6573736572207468656e204d617860008201527f537570706c7920666f7220526564000000000000000000000000000000000000602082015250565b6000614dc1602e83613ec5565b9150614dcc82614d65565b604082019050919050565b60006020820190508181036000830152614df081614db4565b9050919050565b6000614e0282613e86565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614e3457614e336149b8565b5b600182019050919050565b7f5175616e74697479206d757374206265206c6573736572207468656e204d617860008201527f537570706c7920666f7220426c75650000000000000000000000000000000000602082015250565b6000614e9b602f83613ec5565b9150614ea682614e3f565b604082019050919050565b60006020820190508181036000830152614eca81614e8e565b9050919050565b7f4275726e696e6720546f6b656e206973206e6f7420616c6c6f77656400000000600082015250565b6000614f07601c83613ec5565b9150614f1282614ed1565b602082019050919050565b60006020820190508181036000830152614f3681614efa565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000614f99602d83613ec5565b9150614fa482614f3d565b604082019050919050565b60006020820190508181036000830152614fc881614f8c565b9050919050565b60008160601b9050919050565b6000614fe782614fcf565b9050919050565b6000614ff982614fdc565b9050919050565b61501161500c82613fe5565b614fee565b82525050565b60006150238284615000565b60148201915081905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026150947fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82615057565b61509e8683615057565b95508019841693508086168417925050509392505050565b60006150d16150cc6150c784613e86565b614249565b613e86565b9050919050565b6000819050919050565b6150eb836150b6565b6150ff6150f7826150d8565b848454615064565b825550505050565b600090565b615114615107565b61511f8184846150e2565b505050565b5b818110156151435761513860008261510c565b600181019050615125565b5050565b601f8211156151885761515981615032565b61516284615047565b81016020851015615171578190505b61518561517d85615047565b830182615124565b50505b505050565b600082821c905092915050565b60006151ab6000198460080261518d565b1980831691505092915050565b60006151c4838361519a565b9150826002028217905092915050565b6151dd82613eba565b67ffffffffffffffff8111156151f6576151f56142c3565b5b61520082546147b1565b61520b828285615147565b600060209050601f83116001811461523e576000841561522c578287015190505b61523685826151b8565b86555061529e565b601f19841661524c86615032565b60005b828110156152745784890151825560018201915060208501945060208101905061524f565b86831015615291578489015161528d601f89168261519a565b8355505b6001600288020188555050505b505050505050565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b6000615302602983613ec5565b915061530d826152a6565b604082019050919050565b60006020820190508181036000830152615331816152f5565b9050919050565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b6000615394602a83613ec5565b915061539f82615338565b604082019050919050565b600060208201905081810360008301526153c381615387565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000615426602f83613ec5565b9150615431826153ca565b604082019050919050565b6000602082019050818103600083015261545581615419565b9050919050565b600081905092915050565b600061547282613eba565b61547c818561545c565b935061548c818560208601613ed6565b80840191505092915050565b7f2f00000000000000000000000000000000000000000000000000000000000000600082015250565b60006154ce60018361545c565b91506154d982615498565b600182019050919050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b600061551a60058361545c565b9150615525826154e4565b600582019050919050565b600061553c8285615467565b9150615547826154c1565b91506155538284615467565b915061555e8261550d565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006155c6602683613ec5565b91506155d18261556a565b604082019050919050565b600060208201905081810360008301526155f5816155b9565b9050919050565b60006040820190506156116000830185613ff7565b61561e6020830184613ff7565b9392505050565b6000815190506156348161455b565b92915050565b6000602082840312156156505761564f613dc1565b5b600061565e84828501615625565b91505092915050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006156c3602183613ec5565b91506156ce82615667565b604082019050919050565b600060208201905081810360008301526156f2816156b6565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b6000615755603883613ec5565b9150615760826156f9565b604082019050919050565b6000602082019050818103600083015261578481615748565b9050919050565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b60006157e7603183613ec5565b91506157f28261578b565b604082019050919050565b60006020820190508181036000830152615816816157da565b9050919050565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b6000615879602c83613ec5565b91506158848261581d565b604082019050919050565b600060208201905081810360008301526158a88161586c565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b60006158e5601983613ec5565b91506158f0826158af565b602082019050919050565b60006020820190508181036000830152615914816158d8565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061595582613e86565b915061596083613e86565b9250826159705761596f61591b565b5b828204905092915050565b600061598682613e86565b915061599183613e86565b9250826159a1576159a061591b565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000615a37603283613ec5565b9150615a42826159db565b604082019050919050565b60006020820190508181036000830152615a6681615a2a565b9050919050565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b6000615ac9602983613ec5565b9150615ad482615a6d565b604082019050919050565b60006020820190508181036000830152615af881615abc565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000615b5b602483613ec5565b9150615b6682615aff565b604082019050919050565b60006020820190508181036000830152615b8a81615b4e565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000615bc7602083613ec5565b9150615bd282615b91565b602082019050919050565b60006020820190508181036000830152615bf681615bba565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615c33601c83613ec5565b9150615c3e82615bfd565b602082019050919050565b60006020820190508181036000830152615c6281615c26565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000615c9082615c69565b615c9a8185615c74565b9350615caa818560208601613ed6565b615cb381613f00565b840191505092915050565b6000608082019050615cd36000830187613ff7565b615ce06020830186613ff7565b615ced6040830185613e90565b8181036060830152615cff8184615c85565b905095945050505050565b600081519050615d1981613df7565b92915050565b600060208284031215615d3557615d34613dc1565b5b6000615d4384828501615d0a565b9150509291505056fea2646970667358221220db4c91e32421bdfeb7828945922244fa9c16bb1dbe3d6cb12794aba95db571fd64736f6c63430008110033

Deployed Bytecode

0x6080604052600436106103ad5760003560e01c806369ba1a75116101e7578063a22cb4651161010d578063cd6efd09116100a0578063e361d15a1161006f578063e361d15a14610dca578063e757223014610df3578063e985e9c514610e30578063f2fde38b14610e6d576103ad565b8063cd6efd0914610d1e578063d9ef720414610d49578063db4568e214610d74578063e26b83d214610d9f576103ad565b8063c25214a9116100dc578063c25214a914610c62578063c87b56dd14610c8b578063ca96e41c14610cc8578063cd4ce50e14610cf3576103ad565b8063a22cb46514610bbe578063a95f3a5b14610be7578063b88d4fde14610c10578063bdc4f06314610c39576103ad565b80638f79edeb1161018557806395d89b411161015457806395d89b4114610b125780639a918bab14610b3d5780639d6bcba614610b68578063a035b1fe14610b93576103ad565b80638f79edeb14610a585780639072cb0814610a8357806390cdb17914610aac57806391b7f5ed14610ae9576103ad565b8063743976a0116101c1578063743976a01461099a5780637e1258c0146109c55780638b97645f146109f05780638da5cb5b14610a2d576103ad565b806369ba1a751461090957806370a0823114610932578063736bf5911461096f576103ad565b8063318dd32f116102d75780634e69d5601161026a5780635a8d7784116102395780635a8d77841461085c5780635ede2eae14610885578063624b024b146108a15780636352211e146108cc576103ad565b80634e69d560146107a25780634f4230dc146107cd57806354bf80b5146107f657806355f804b314610833576103ad565b806342842e0e116102a657806342842e0e146106ea57806342966c681461071357806346bb00ce1461073c5780634e56c96914610779576103ad565b8063318dd32f146106545780633ccfd60b1461067f5780633dee43be1461069657806341f43434146106bf576103ad565b8063173f60641161034f57806323b872dd1161031e57806323b872dd1461059c57806323bd6237146105c55780632ba2865b146106025780632ccc4f6c1461062b576103ad565b8063173f60641461050157806318160ddd1461052a5780631ff7712f14610555578063200d2ed214610571576103ad565b8063081812fc1161038b578063081812fc14610445578063095ea7b3146104825780630e7fd5df146104ab5780630f2cdd6c146104d6576103ad565b806301ffc9a7146103b257806302c3fb53146103ef57806306fdde031461041a575b600080fd5b3480156103be57600080fd5b506103d960048036038101906103d49190613e23565b610e96565b6040516103e69190613e6b565b60405180910390f35b3480156103fb57600080fd5b50610404610f78565b6040516104119190613e9f565b60405180910390f35b34801561042657600080fd5b5061042f610f7e565b60405161043c9190613f4a565b60405180910390f35b34801561045157600080fd5b5061046c60048036038101906104679190613f98565b611010565b6040516104799190614006565b60405180910390f35b34801561048e57600080fd5b506104a960048036038101906104a4919061404d565b611095565b005b3480156104b757600080fd5b506104c06110ae565b6040516104cd9190613e9f565b60405180910390f35b3480156104e257600080fd5b506104eb6110b4565b6040516104f89190613e9f565b60405180910390f35b34801561050d57600080fd5b50610528600480360381019061052391906140c3565b6110ba565b005b34801561053657600080fd5b5061053f611140565b60405161054c9190613e9f565b60405180910390f35b61056f600480360381019061056a9190614155565b61114a565b005b34801561057d57600080fd5b50610586611607565b6040516105939190613e9f565b60405180910390f35b3480156105a857600080fd5b506105c360048036038101906105be91906141c9565b61160d565b005b3480156105d157600080fd5b506105ec60048036038101906105e7919061421c565b61165c565b6040516105f99190613e9f565b60405180910390f35b34801561060e57600080fd5b5061062960048036038101906106249190613f98565b611674565b005b34801561063757600080fd5b50610652600480360381019061064d91906140c3565b6116fa565b005b34801561066057600080fd5b50610669611780565b6040516106769190613e9f565b60405180910390f35b34801561068b57600080fd5b50610694611786565b005b3480156106a257600080fd5b506106bd60048036038101906106b89190613f98565b611851565b005b3480156106cb57600080fd5b506106d46118d7565b6040516106e191906142a8565b60405180910390f35b3480156106f657600080fd5b50610711600480360381019061070c91906141c9565b6118e9565b005b34801561071f57600080fd5b5061073a60048036038101906107359190613f98565b611938565b005b34801561074857600080fd5b50610763600480360381019061075e9190614401565b6119ea565b6040516107709190613e6b565b60405180910390f35b34801561078557600080fd5b506107a0600480360381019061079b9190613f98565b611a27565b005b3480156107ae57600080fd5b506107b7611aad565b6040516107c49190613e9f565b60405180910390f35b3480156107d957600080fd5b506107f460048036038101906107ef9190613f98565b611ab7565b005b34801561080257600080fd5b5061081d6004803603810190610818919061421c565b611b3d565b60405161082a9190613e9f565b60405180910390f35b34801561083f57600080fd5b5061085a60048036038101906108559190614512565b611b55565b005b34801561086857600080fd5b50610883600480360381019061087e9190614587565b611be4565b005b61089f600480360381019061089a9190614155565b611c7d565b005b3480156108ad57600080fd5b506108b6612098565b6040516108c391906145c3565b60405180910390f35b3480156108d857600080fd5b506108f360048036038101906108ee9190613f98565b61209e565b6040516109009190614006565b60405180910390f35b34801561091557600080fd5b50610930600480360381019061092b9190613f98565b61214f565b005b34801561093e57600080fd5b506109596004803603810190610954919061421c565b6121d5565b6040516109669190613e9f565b60405180910390f35b34801561097b57600080fd5b5061098461228c565b6040516109919190613e9f565b60405180910390f35b3480156109a657600080fd5b506109af612292565b6040516109bc9190613f4a565b60405180910390f35b3480156109d157600080fd5b506109da612320565b6040516109e79190613e9f565b60405180910390f35b3480156109fc57600080fd5b50610a176004803603810190610a129190613f98565b612326565b604051610a249190613e9f565b60405180910390f35b348015610a3957600080fd5b50610a4261233d565b604051610a4f9190614006565b60405180910390f35b348015610a6457600080fd5b50610a6d612367565b604051610a7a9190613e9f565b60405180910390f35b348015610a8f57600080fd5b50610aaa6004803603810190610aa5919061404d565b612371565b005b348015610ab857600080fd5b50610ad36004803603810190610ace9190614401565b6124aa565b604051610ae09190613e6b565b60405180910390f35b348015610af557600080fd5b50610b106004803603810190610b0b9190613f98565b6124e7565b005b348015610b1e57600080fd5b50610b2761256d565b604051610b349190613f4a565b60405180910390f35b348015610b4957600080fd5b50610b526125ff565b604051610b5f9190613e9f565b60405180910390f35b348015610b7457600080fd5b50610b7d612605565b604051610b8a9190613e9f565b60405180910390f35b348015610b9f57600080fd5b50610ba861260b565b604051610bb59190613e9f565b60405180910390f35b348015610bca57600080fd5b50610be56004803603810190610be091906145de565b612611565b005b348015610bf357600080fd5b50610c0e6004803603810190610c099190613f98565b61262a565b005b348015610c1c57600080fd5b50610c376004803603810190610c3291906146bf565b6126b0565b005b348015610c4557600080fd5b50610c606004803603810190610c5b9190613f98565b612701565b005b348015610c6e57600080fd5b50610c896004803603810190610c849190613f98565b612787565b005b348015610c9757600080fd5b50610cb26004803603810190610cad9190613f98565b61280d565b604051610cbf9190613f4a565b60405180910390f35b348015610cd457600080fd5b50610cdd6128b4565b604051610cea91906145c3565b60405180910390f35b348015610cff57600080fd5b50610d086128ba565b604051610d159190613e9f565b60405180910390f35b348015610d2a57600080fd5b50610d336128c0565b604051610d409190613e9f565b60405180910390f35b348015610d5557600080fd5b50610d5e6128c6565b604051610d6b9190613e9f565b60405180910390f35b348015610d8057600080fd5b50610d896128d0565b604051610d969190613e9f565b60405180910390f35b348015610dab57600080fd5b50610db46128d6565b604051610dc19190613e6b565b60405180910390f35b348015610dd657600080fd5b50610df16004803603810190610dec919061404d565b6128e9565b005b348015610dff57600080fd5b50610e1a6004803603810190610e159190613f98565b612a22565b604051610e279190613e9f565b60405180910390f35b348015610e3c57600080fd5b50610e576004803603810190610e529190614742565b612a39565b604051610e649190613e6b565b60405180910390f35b348015610e7957600080fd5b50610e946004803603810190610e8f919061421c565b612acd565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610f6157507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610f715750610f7082612bc4565b5b9050919050565b60095481565b606060008054610f8d906147b1565b80601f0160208091040260200160405190810160405280929190818152602001828054610fb9906147b1565b80156110065780601f10610fdb57610100808354040283529160200191611006565b820191906000526020600020905b815481529060010190602001808311610fe957829003601f168201915b5050505050905090565b600061101b82612c2e565b61105a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105190614854565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8161109f81612c9a565b6110a98383612d97565b505050565b60145481565b600e5481565b6110c2612eae565b73ffffffffffffffffffffffffffffffffffffffff166110e061233d565b73ffffffffffffffffffffffffffffffffffffffff1614611136576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112d906148c0565b60405180910390fd5b8060158190555050565b6000600a54905090565b6103e8611155611140565b10611195576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118c9061492c565b60405180910390fd5b6002600b54146111da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d190614998565b60405180910390fd5b6103e8846111e6611140565b6111f091906149e7565b1115611231576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161122890614a8d565b60405180910390fd5b600c548461123d611140565b61124791906149e7565b1115611288576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127f90614b1f565b60405180910390fd5b6112d3838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050336124aa565b611312576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130990614b8b565b60405180910390fd5b600d54841115611357576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134e90614bf7565b60405180910390fd5b600f54846113659190614c17565b3410156113a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139e90614ca5565b60405180910390fd5b83601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546113f691906149e7565b92505081905550600e54601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611481576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147890614d11565b60405180910390fd5b60018103611547576101f460018560085461149c91906149e7565b6114a69190614d31565b11156114e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114de90614dd7565b60405180910390fd5b60005b84811015611541576114fe33600854612eb6565b6008600081548092919061151190614df7565b9190505550600a600081548092919061152990614df7565b9190505550808061153990614df7565b9150506114ea565b50611601565b6103e860018560095461155a91906149e7565b6115649190614d31565b11156115a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159c90614eb1565b60405180910390fd5b60005b848110156115ff576115bc33600954612eb6565b600960008154809291906115cf90614df7565b9190505550600a60008154809291906115e790614df7565b919050555080806115f790614df7565b9150506115a8565b505b50505050565b600b5481565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461164b5761164a33612c9a565b5b611656848484612ed4565b50505050565b60176020528060005260406000206000915090505481565b61167c612eae565b73ffffffffffffffffffffffffffffffffffffffff1661169a61233d565b73ffffffffffffffffffffffffffffffffffffffff16146116f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e7906148c0565b60405180910390fd5b80600e8190555050565b611702612eae565b73ffffffffffffffffffffffffffffffffffffffff1661172061233d565b73ffffffffffffffffffffffffffffffffffffffff1614611776576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161176d906148c0565b60405180910390fd5b8060108190555050565b60135481565b61178e612eae565b73ffffffffffffffffffffffffffffffffffffffff166117ac61233d565b73ffffffffffffffffffffffffffffffffffffffff1614611802576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f9906148c0565b60405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561184d573d6000803e3d6000fd5b5050565b611859612eae565b73ffffffffffffffffffffffffffffffffffffffff1661187761233d565b73ffffffffffffffffffffffffffffffffffffffff16146118cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c4906148c0565b60405180910390fd5b8060148190555050565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146119275761192633612c9a565b5b611932848484612f34565b50505050565b60011515601260009054906101000a900460ff1615151461198e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161198590614f1d565b60405180910390fd5b61199f611999612eae565b82612f54565b6119de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d590614faf565b60405180910390fd5b6119e781613032565b50565b6000611a1f8360155484604051602001611a049190615017565b60405160208183030381529060405280519060200120613143565b905092915050565b611a2f612eae565b73ffffffffffffffffffffffffffffffffffffffff16611a4d61233d565b73ffffffffffffffffffffffffffffffffffffffff1614611aa3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9a906148c0565b60405180910390fd5b80600c8190555050565b6000600b54905090565b611abf612eae565b73ffffffffffffffffffffffffffffffffffffffff16611add61233d565b73ffffffffffffffffffffffffffffffffffffffff1614611b33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b2a906148c0565b60405180910390fd5b8060168190555050565b60116020528060005260406000206000915090505481565b611b5d612eae565b73ffffffffffffffffffffffffffffffffffffffff16611b7b61233d565b73ffffffffffffffffffffffffffffffffffffffff1614611bd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bc8906148c0565b60405180910390fd5b8060069081611be091906151d4565b5050565b611bec612eae565b73ffffffffffffffffffffffffffffffffffffffff16611c0a61233d565b73ffffffffffffffffffffffffffffffffffffffff1614611c60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c57906148c0565b60405180910390fd5b80601260006101000a81548160ff02191690831515021790555050565b6001600b5414611cc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cb990614998565b60405180910390fd5b60185484611cce611140565b611cd891906149e7565b1115611d19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1090614a8d565b60405180910390fd5b611d64838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050336119ea565b611da3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9a90614b8b565b60405180910390fd5b601354841115611de8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ddf90614bf7565b60405180910390fd5b60165484611df69190614c17565b341015611e38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e2f90614ca5565b60405180910390fd5b83601760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611e8791906149e7565b92505081905550601454601760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611f12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0990614d11565b60405180910390fd5b60018103611fd8576101f4600185600854611f2d91906149e7565b611f379190614d31565b1115611f78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6f90614dd7565b60405180910390fd5b60005b84811015611fd257611f8f33600854612eb6565b60086000815480929190611fa290614df7565b9190505550600a6000815480929190611fba90614df7565b91905055508080611fca90614df7565b915050611f7b565b50612092565b6103e8600185600954611feb91906149e7565b611ff59190614d31565b1115612036576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202d90614eb1565b60405180910390fd5b60005b848110156120905761204d33600954612eb6565b6009600081548092919061206090614df7565b9190505550600a600081548092919061207890614df7565b9190505550808061208890614df7565b915050612039565b505b50505050565b60105481565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612146576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213d90615318565b60405180910390fd5b80915050919050565b612157612eae565b73ffffffffffffffffffffffffffffffffffffffff1661217561233d565b73ffffffffffffffffffffffffffffffffffffffff16146121cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121c2906148c0565b60405180910390fd5b80600b8190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612245576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223c906153aa565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600a5481565b6006805461229f906147b1565b80601f01602080910402602001604051908101604052809291908181526020018280546122cb906147b1565b80156123185780601f106122ed57610100808354040283529160200191612318565b820191906000526020600020905b8154815290600101906020018083116122fb57829003601f168201915b505050505081565b600c5481565b6000601654826123369190614c17565b9050919050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600954905090565b612379612eae565b73ffffffffffffffffffffffffffffffffffffffff1661239761233d565b73ffffffffffffffffffffffffffffffffffffffff16146123ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123e4906148c0565b60405180910390fd5b6101f460018260085461240091906149e7565b61240a9190614d31565b111561244b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244290614dd7565b60405180910390fd5b60005b818110156124a55761246283600854612eb6565b6008600081548092919061247590614df7565b9190505550600a600081548092919061248d90614df7565b9190505550808061249d90614df7565b91505061244e565b505050565b60006124df83601054846040516020016124c49190615017565b60405160208183030381529060405280519060200120613143565b905092915050565b6124ef612eae565b73ffffffffffffffffffffffffffffffffffffffff1661250d61233d565b73ffffffffffffffffffffffffffffffffffffffff1614612563576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161255a906148c0565b60405180910390fd5b80600f8190555050565b60606001805461257c906147b1565b80601f01602080910402602001604051908101604052809291908181526020018280546125a8906147b1565b80156125f55780601f106125ca576101008083540402835291602001916125f5565b820191906000526020600020905b8154815290600101906020018083116125d857829003601f168201915b5050505050905090565b600d5481565b60085481565b600f5481565b8161261b81612c9a565b612625838361315a565b505050565b612632612eae565b73ffffffffffffffffffffffffffffffffffffffff1661265061233d565b73ffffffffffffffffffffffffffffffffffffffff16146126a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161269d906148c0565b60405180910390fd5b8060138190555050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146126ee576126ed33612c9a565b5b6126fa858585856132da565b5050505050565b612709612eae565b73ffffffffffffffffffffffffffffffffffffffff1661272761233d565b73ffffffffffffffffffffffffffffffffffffffff161461277d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612774906148c0565b60405180910390fd5b8060188190555050565b61278f612eae565b73ffffffffffffffffffffffffffffffffffffffff166127ad61233d565b73ffffffffffffffffffffffffffffffffffffffff1614612803576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127fa906148c0565b60405180910390fd5b80600d8190555050565b606061281882612c2e565b612857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161284e9061543c565b60405180910390fd5b600061286161333c565b9050600081511161288157604051806020016040528060008152506128ac565b8061288b846133ce565b60405160200161289c929190615530565b6040516020818303038152906040525b915050919050565b60155481565b60185481565b60165481565b6000600854905090565b6103e881565b601260009054906101000a900460ff1681565b6128f1612eae565b73ffffffffffffffffffffffffffffffffffffffff1661290f61233d565b73ffffffffffffffffffffffffffffffffffffffff1614612965576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161295c906148c0565b60405180910390fd5b6103e860018260095461297891906149e7565b6129829190614d31565b11156129c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129ba90614eb1565b60405180910390fd5b60005b81811015612a1d576129da83600954612eb6565b600960008154809291906129ed90614df7565b9190505550600a6000815480929190612a0590614df7565b91905055508080612a1590614df7565b9150506129c6565b505050565b6000600f5482612a329190614c17565b9050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b612ad5612eae565b73ffffffffffffffffffffffffffffffffffffffff16612af361233d565b73ffffffffffffffffffffffffffffffffffffffff1614612b49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b40906148c0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612bb8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612baf906155dc565b60405180910390fd5b612bc18161352e565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115612d94576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401612d119291906155fc565b602060405180830381865afa158015612d2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d52919061563a565b612d9357806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401612d8a9190614006565b60405180910390fd5b5b50565b6000612da28261209e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612e12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e09906156d9565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16612e31612eae565b73ffffffffffffffffffffffffffffffffffffffff161480612e605750612e5f81612e5a612eae565b612a39565b5b612e9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e969061576b565b60405180910390fd5b612ea983836135f4565b505050565b600033905090565b612ed08282604051806020016040528060008152506136ad565b5050565b612ee5612edf612eae565b82612f54565b612f24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f1b906157fd565b60405180910390fd5b612f2f838383613708565b505050565b612f4f838383604051806020016040528060008152506126b0565b505050565b6000612f5f82612c2e565b612f9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f959061588f565b60405180910390fd5b6000612fa98361209e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061301857508373ffffffffffffffffffffffffffffffffffffffff1661300084611010565b73ffffffffffffffffffffffffffffffffffffffff16145b8061302957506130288185612a39565b5b91505092915050565b600061303d8261209e565b905061304b81600084613963565b6130566000836135f4565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546130a69190614d31565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b6000826131508584613968565b1490509392505050565b613162612eae565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036131cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131c6906158fb565b60405180910390fd5b80600560006131dc612eae565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16613289612eae565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516132ce9190613e6b565b60405180910390a35050565b6132eb6132e5612eae565b83612f54565b61332a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613321906157fd565b60405180910390fd5b613336848484846139dd565b50505050565b60606006805461334b906147b1565b80601f0160208091040260200160405190810160405280929190818152602001828054613377906147b1565b80156133c45780601f10613399576101008083540402835291602001916133c4565b820191906000526020600020905b8154815290600101906020018083116133a757829003601f168201915b5050505050905090565b606060008203613415576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050613529565b600082905060005b6000821461344757808061343090614df7565b915050600a82613440919061594a565b915061341d565b60008167ffffffffffffffff811115613463576134626142c3565b5b6040519080825280601f01601f1916602001820160405280156134955781602001600182028036833780820191505090505b5090505b60008514613522576001826134ae9190614d31565b9150600a856134bd919061597b565b60306134c991906149e7565b60f81b8183815181106134df576134de6159ac565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561351b919061594a565b9450613499565b8093505050505b919050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166136678361209e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6136b78383613a39565b6136c46000848484613c06565b613703576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136fa90615a4d565b60405180910390fd5b505050565b8273ffffffffffffffffffffffffffffffffffffffff166137288261209e565b73ffffffffffffffffffffffffffffffffffffffff161461377e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161377590615adf565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036137ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137e490615b71565b60405180910390fd5b6137f8838383613963565b6138036000826135f4565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546138539190614d31565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546138aa91906149e7565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b505050565b60008082905060005b84518110156139d257600085828151811061398f5761398e6159ac565b5b602002602001015190508083116139b1576139aa8382613d8d565b92506139be565b6139bb8184613d8d565b92505b5080806139ca90614df7565b915050613971565b508091505092915050565b6139e8848484613708565b6139f484848484613c06565b613a33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a2a90615a4d565b60405180910390fd5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613aa8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a9f90615bdd565b60405180910390fd5b613ab181612c2e565b15613af1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613ae890615c49565b60405180910390fd5b613afd60008383613963565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254613b4d91906149e7565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b6000613c278473ffffffffffffffffffffffffffffffffffffffff16613da4565b15613d80578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613c50612eae565b8786866040518563ffffffff1660e01b8152600401613c729493929190615cbe565b6020604051808303816000875af1925050508015613cae57506040513d601f19601f82011682018060405250810190613cab9190615d1f565b60015b613d30573d8060008114613cde576040519150601f19603f3d011682016040523d82523d6000602084013e613ce3565b606091505b506000815103613d28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d1f90615a4d565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050613d85565b600190505b949350505050565b600082600052816020526040600020905092915050565b600080823b905060008111915050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613e0081613dcb565b8114613e0b57600080fd5b50565b600081359050613e1d81613df7565b92915050565b600060208284031215613e3957613e38613dc1565b5b6000613e4784828501613e0e565b91505092915050565b60008115159050919050565b613e6581613e50565b82525050565b6000602082019050613e806000830184613e5c565b92915050565b6000819050919050565b613e9981613e86565b82525050565b6000602082019050613eb46000830184613e90565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613ef4578082015181840152602081019050613ed9565b60008484015250505050565b6000601f19601f8301169050919050565b6000613f1c82613eba565b613f268185613ec5565b9350613f36818560208601613ed6565b613f3f81613f00565b840191505092915050565b60006020820190508181036000830152613f648184613f11565b905092915050565b613f7581613e86565b8114613f8057600080fd5b50565b600081359050613f9281613f6c565b92915050565b600060208284031215613fae57613fad613dc1565b5b6000613fbc84828501613f83565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613ff082613fc5565b9050919050565b61400081613fe5565b82525050565b600060208201905061401b6000830184613ff7565b92915050565b61402a81613fe5565b811461403557600080fd5b50565b60008135905061404781614021565b92915050565b6000806040838503121561406457614063613dc1565b5b600061407285828601614038565b925050602061408385828601613f83565b9150509250929050565b6000819050919050565b6140a08161408d565b81146140ab57600080fd5b50565b6000813590506140bd81614097565b92915050565b6000602082840312156140d9576140d8613dc1565b5b60006140e7848285016140ae565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112614115576141146140f0565b5b8235905067ffffffffffffffff811115614132576141316140f5565b5b60208301915083602082028301111561414e5761414d6140fa565b5b9250929050565b6000806000806060858703121561416f5761416e613dc1565b5b600061417d87828801613f83565b945050602085013567ffffffffffffffff81111561419e5761419d613dc6565b5b6141aa878288016140ff565b935093505060406141bd87828801613f83565b91505092959194509250565b6000806000606084860312156141e2576141e1613dc1565b5b60006141f086828701614038565b935050602061420186828701614038565b925050604061421286828701613f83565b9150509250925092565b60006020828403121561423257614231613dc1565b5b600061424084828501614038565b91505092915050565b6000819050919050565b600061426e61426961426484613fc5565b614249565b613fc5565b9050919050565b600061428082614253565b9050919050565b600061429282614275565b9050919050565b6142a281614287565b82525050565b60006020820190506142bd6000830184614299565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6142fb82613f00565b810181811067ffffffffffffffff8211171561431a576143196142c3565b5b80604052505050565b600061432d613db7565b905061433982826142f2565b919050565b600067ffffffffffffffff821115614359576143586142c3565b5b602082029050602081019050919050565b600061437d6143788461433e565b614323565b905080838252602082019050602084028301858111156143a05761439f6140fa565b5b835b818110156143c957806143b588826140ae565b8452602084019350506020810190506143a2565b5050509392505050565b600082601f8301126143e8576143e76140f0565b5b81356143f884826020860161436a565b91505092915050565b6000806040838503121561441857614417613dc1565b5b600083013567ffffffffffffffff81111561443657614435613dc6565b5b614442858286016143d3565b925050602061445385828601614038565b9150509250929050565b600080fd5b600067ffffffffffffffff82111561447d5761447c6142c3565b5b61448682613f00565b9050602081019050919050565b82818337600083830152505050565b60006144b56144b084614462565b614323565b9050828152602081018484840111156144d1576144d061445d565b5b6144dc848285614493565b509392505050565b600082601f8301126144f9576144f86140f0565b5b81356145098482602086016144a2565b91505092915050565b60006020828403121561452857614527613dc1565b5b600082013567ffffffffffffffff81111561454657614545613dc6565b5b614552848285016144e4565b91505092915050565b61456481613e50565b811461456f57600080fd5b50565b6000813590506145818161455b565b92915050565b60006020828403121561459d5761459c613dc1565b5b60006145ab84828501614572565b91505092915050565b6145bd8161408d565b82525050565b60006020820190506145d860008301846145b4565b92915050565b600080604083850312156145f5576145f4613dc1565b5b600061460385828601614038565b925050602061461485828601614572565b9150509250929050565b600067ffffffffffffffff821115614639576146386142c3565b5b61464282613f00565b9050602081019050919050565b600061466261465d8461461e565b614323565b90508281526020810184848401111561467e5761467d61445d565b5b614689848285614493565b509392505050565b600082601f8301126146a6576146a56140f0565b5b81356146b684826020860161464f565b91505092915050565b600080600080608085870312156146d9576146d8613dc1565b5b60006146e787828801614038565b94505060206146f887828801614038565b935050604061470987828801613f83565b925050606085013567ffffffffffffffff81111561472a57614729613dc6565b5b61473687828801614691565b91505092959194509250565b6000806040838503121561475957614758613dc1565b5b600061476785828601614038565b925050602061477885828601614038565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806147c957607f821691505b6020821081036147dc576147db614782565b5b50919050565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b600061483e602c83613ec5565b9150614849826147e2565b604082019050919050565b6000602082019050818103600083015261486d81614831565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006148aa602083613ec5565b91506148b582614874565b602082019050919050565b600060208201905081810360008301526148d98161489d565b9050919050565b7f53616c6520656e64000000000000000000000000000000000000000000000000600082015250565b6000614916600883613ec5565b9150614921826148e0565b602082019050919050565b6000602082019050818103600083015261494581614909565b9050919050565b7f53616c65206973206e6f74206163746976650000000000000000000000000000600082015250565b6000614982601283613ec5565b915061498d8261494c565b602082019050919050565b600060208201905081810360008301526149b181614975565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006149f282613e86565b91506149fd83613e86565b9250828201905080821115614a1557614a146149b8565b5b92915050565b7f5175616e74697479206d757374206265206c6573736572207468656e204d617860008201527f537570706c790000000000000000000000000000000000000000000000000000602082015250565b6000614a77602683613ec5565b9150614a8282614a1b565b604082019050919050565b60006020820190508181036000830152614aa681614a6a565b9050919050565b7f5175616e74697479206d757374206265206c6573736572207468656e20495a4d60008201527f20546f74616c20417661696c61626c6500000000000000000000000000000000602082015250565b6000614b09603083613ec5565b9150614b1482614aad565b604082019050919050565b60006020820190508181036000830152614b3881614afc565b9050919050565b7f596f7520617265206e6f7420696e2070726573616c6500000000000000000000600082015250565b6000614b75601683613ec5565b9150614b8082614b3f565b602082019050919050565b60006020820190508181036000830152614ba481614b68565b9050919050565b7f63616e206e6f74206d696e742074686973206d616e7900000000000000000000600082015250565b6000614be1601683613ec5565b9150614bec82614bab565b602082019050919050565b60006020820190508181036000830152614c1081614bd4565b9050919050565b6000614c2282613e86565b9150614c2d83613e86565b9250828202614c3b81613e86565b91508282048414831517614c5257614c516149b8565b5b5092915050565b7f54727920746f2073656e64206d6f726520455448000000000000000000000000600082015250565b6000614c8f601483613ec5565b9150614c9a82614c59565b602082019050919050565b60006020820190508181036000830152614cbe81614c82565b9050919050565b7f50757263686173652065786365656473206d617820616c6c6f77656400000000600082015250565b6000614cfb601c83613ec5565b9150614d0682614cc5565b602082019050919050565b60006020820190508181036000830152614d2a81614cee565b9050919050565b6000614d3c82613e86565b9150614d4783613e86565b9250828203905081811115614d5f57614d5e6149b8565b5b92915050565b7f5175616e74697479206d757374206265206c6573736572207468656e204d617860008201527f537570706c7920666f7220526564000000000000000000000000000000000000602082015250565b6000614dc1602e83613ec5565b9150614dcc82614d65565b604082019050919050565b60006020820190508181036000830152614df081614db4565b9050919050565b6000614e0282613e86565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614e3457614e336149b8565b5b600182019050919050565b7f5175616e74697479206d757374206265206c6573736572207468656e204d617860008201527f537570706c7920666f7220426c75650000000000000000000000000000000000602082015250565b6000614e9b602f83613ec5565b9150614ea682614e3f565b604082019050919050565b60006020820190508181036000830152614eca81614e8e565b9050919050565b7f4275726e696e6720546f6b656e206973206e6f7420616c6c6f77656400000000600082015250565b6000614f07601c83613ec5565b9150614f1282614ed1565b602082019050919050565b60006020820190508181036000830152614f3681614efa565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000614f99602d83613ec5565b9150614fa482614f3d565b604082019050919050565b60006020820190508181036000830152614fc881614f8c565b9050919050565b60008160601b9050919050565b6000614fe782614fcf565b9050919050565b6000614ff982614fdc565b9050919050565b61501161500c82613fe5565b614fee565b82525050565b60006150238284615000565b60148201915081905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026150947fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82615057565b61509e8683615057565b95508019841693508086168417925050509392505050565b60006150d16150cc6150c784613e86565b614249565b613e86565b9050919050565b6000819050919050565b6150eb836150b6565b6150ff6150f7826150d8565b848454615064565b825550505050565b600090565b615114615107565b61511f8184846150e2565b505050565b5b818110156151435761513860008261510c565b600181019050615125565b5050565b601f8211156151885761515981615032565b61516284615047565b81016020851015615171578190505b61518561517d85615047565b830182615124565b50505b505050565b600082821c905092915050565b60006151ab6000198460080261518d565b1980831691505092915050565b60006151c4838361519a565b9150826002028217905092915050565b6151dd82613eba565b67ffffffffffffffff8111156151f6576151f56142c3565b5b61520082546147b1565b61520b828285615147565b600060209050601f83116001811461523e576000841561522c578287015190505b61523685826151b8565b86555061529e565b601f19841661524c86615032565b60005b828110156152745784890151825560018201915060208501945060208101905061524f565b86831015615291578489015161528d601f89168261519a565b8355505b6001600288020188555050505b505050505050565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b6000615302602983613ec5565b915061530d826152a6565b604082019050919050565b60006020820190508181036000830152615331816152f5565b9050919050565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b6000615394602a83613ec5565b915061539f82615338565b604082019050919050565b600060208201905081810360008301526153c381615387565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000615426602f83613ec5565b9150615431826153ca565b604082019050919050565b6000602082019050818103600083015261545581615419565b9050919050565b600081905092915050565b600061547282613eba565b61547c818561545c565b935061548c818560208601613ed6565b80840191505092915050565b7f2f00000000000000000000000000000000000000000000000000000000000000600082015250565b60006154ce60018361545c565b91506154d982615498565b600182019050919050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b600061551a60058361545c565b9150615525826154e4565b600582019050919050565b600061553c8285615467565b9150615547826154c1565b91506155538284615467565b915061555e8261550d565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006155c6602683613ec5565b91506155d18261556a565b604082019050919050565b600060208201905081810360008301526155f5816155b9565b9050919050565b60006040820190506156116000830185613ff7565b61561e6020830184613ff7565b9392505050565b6000815190506156348161455b565b92915050565b6000602082840312156156505761564f613dc1565b5b600061565e84828501615625565b91505092915050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006156c3602183613ec5565b91506156ce82615667565b604082019050919050565b600060208201905081810360008301526156f2816156b6565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b6000615755603883613ec5565b9150615760826156f9565b604082019050919050565b6000602082019050818103600083015261578481615748565b9050919050565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b60006157e7603183613ec5565b91506157f28261578b565b604082019050919050565b60006020820190508181036000830152615816816157da565b9050919050565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b6000615879602c83613ec5565b91506158848261581d565b604082019050919050565b600060208201905081810360008301526158a88161586c565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b60006158e5601983613ec5565b91506158f0826158af565b602082019050919050565b60006020820190508181036000830152615914816158d8565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061595582613e86565b915061596083613e86565b9250826159705761596f61591b565b5b828204905092915050565b600061598682613e86565b915061599183613e86565b9250826159a1576159a061591b565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000615a37603283613ec5565b9150615a42826159db565b604082019050919050565b60006020820190508181036000830152615a6681615a2a565b9050919050565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b6000615ac9602983613ec5565b9150615ad482615a6d565b604082019050919050565b60006020820190508181036000830152615af881615abc565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000615b5b602483613ec5565b9150615b6682615aff565b604082019050919050565b60006020820190508181036000830152615b8a81615b4e565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000615bc7602083613ec5565b9150615bd282615b91565b602082019050919050565b60006020820190508181036000830152615bf681615bba565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615c33601c83613ec5565b9150615c3e82615bfd565b602082019050919050565b60006020820190508181036000830152615c6281615c26565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000615c9082615c69565b615c9a8185615c74565b9350615caa818560208601613ed6565b615cb381613f00565b840191505092915050565b6000608082019050615cd36000830187613ff7565b615ce06020830186613ff7565b615ced6040830185613e90565b8181036060830152615cff8184615c85565b905095945050505050565b600081519050615d1981613df7565b92915050565b600060208284031215615d3557615d34613dc1565b5b6000615d4384828501615d0a565b9150509291505056fea2646970667358221220db4c91e32421bdfeb7828945922244fa9c16bb1dbe3d6cb12794aba95db571fd64736f6c63430008110033

Deployed Bytecode Sourcemap

45866:8951:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32437:344;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46100:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33555:98;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35335:295;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54090:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;50993:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46415:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51250:132;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;50610:89;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48007:1360;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;46175:22;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54251:161;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51119:51;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47440:95;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47301:133;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;50954:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49775:140;;;;;;;;;;;;;:::i;:::-;;53129:122;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;737:142:7;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54418:169:4;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53607:247;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51529:193;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47149:146;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47616:71;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53392:106;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;46574:48;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46733:95;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53504:97;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51728:1275;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;46535:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33180:313;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47541:70;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;32840:283;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46138:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32115:22;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46280:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51388:135;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30016:85;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50803:92;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49921:336;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47807:194;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46939:88;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;33717:102;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46325:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46065:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46498:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53910:174;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53009:114;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;54593:222;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53257:129;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47033:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;49373:396;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51034:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51176:42;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51072:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50706:90;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46015:43;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46628:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50263:341;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47693:108;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36081:206;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30792:223;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;32437:344;32579:4;32633:25;32618:40;;;:11;:40;;;;:104;;;;32689:33;32674:48;;;:11;:48;;;;32618:104;:156;;;;32738:36;32762:11;32738:23;:36::i;:::-;32618:156;32599:175;;32437:344;;;:::o;46100:32::-;;;;:::o;33555:98::-;33609:13;33641:5;33634:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33555:98;:::o;35335:295::-;35451:7;35495:16;35503:7;35495;:16::i;:::-;35474:107;;;;;;;;;;;;:::i;:::-;;;;;;;;;35599:15;:24;35615:7;35599:24;;;;;;;;;;;;;;;;;;;;;35592:31;;35335:295;;;:::o;54090:155::-;54186:8;2227:30:7;2248:8;2227:20;:30::i;:::-;54206:32:4::1;54220:8;54230:7;54206:13;:32::i;:::-;54090:155:::0;;;:::o;50993:35::-;;;;:::o;46415:33::-;;;;:::o;51250:132::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;51357:18:::1;51337:17;:38;;;;51250:132:::0;:::o;50610:89::-;50654:7;50680:12;;50673:19;;50610:89;:::o;48007:1360::-;46054:4;46874:13;:11;:13::i;:::-;:28;46866:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;48141:1:::1;48131:6;;:11;48123:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;46054:4;48200:9;48184:13;:11;:13::i;:::-;:25;;;;:::i;:::-;:41;;48176:91;;;;;;;;;;;;:::i;:::-;;;;;;;;;48314:18;;48301:9;48285:13;:11;:13::i;:::-;:25;;;;:::i;:::-;:47;;48277:107;;;;;;;;;;;;:::i;:::-;;;;;;;;;48402:29;48412:6;;48402:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48420:10;48402:9;:29::i;:::-;48394:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;48489:16;;48476:9;:29;;48468:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;48574:5;;48562:9;:17;;;;:::i;:::-;48549:9;:30;;48541:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;48644:9;48615:13;:25;48629:10;48615:25;;;;;;;;;;;;;;;;:38;;;;;;;:::i;:::-;;;;;;;;48700:14;;48671:13;:25;48685:10;48671:25;;;;;;;;;;;;;;;;:43;;48663:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;48774:1;48760:10;:15:::0;48757:604:::1;;48834:3;48829:1;48816:9;48803:10;;:22;;;;:::i;:::-;48802:28;;;;:::i;:::-;:35;;48794:93;;;;;;;;;;;;:::i;:::-;;;;;;;;;48902:9;48897:165;48921:9;48917:1;:13;48897:165;;;48954:33;48964:10;48976;;48954:9;:33::i;:::-;49004:10;;:12;;;;;;;;;:::i;:::-;;;;;;49033;;:14;;;;;;;;;:::i;:::-;;;;;;48932:3;;;;;:::i;:::-;;;;48897:165;;;;48757:604;;;49128:4;49123:1;49111:9;49097:11;;:23;;;;:::i;:::-;49096:28;;;;:::i;:::-;:36;;49088:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;49198:9;49193:158;49217:9;49213:1;:13;49193:158;;;49247:34;49257:10;49269:11;;49247:9;:34::i;:::-;49295:11;;:13;;;;;;;;;:::i;:::-;;;;;;49322:12;;:14;;;;;;;;;:::i;:::-;;;;;;49228:3;;;;;:::i;:::-;;;;49193:158;;;;48757:604;48007:1360:::0;;;;:::o;46175:22::-;;;;:::o;54251:161::-;54352:4;2062:10:7;2054:18;;:4;:18;;;2050:81;;2088:32;2109:10;2088:20;:32::i;:::-;2050:81;54368:37:4::1;54387:4;54393:2;54397:7;54368:18;:37::i;:::-;54251:161:::0;;;;:::o;51119:51::-;;;;;;;;;;;;;;;;;:::o;47440:95::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;47527:1:::1;47510:14;:18;;;;47440:95:::0;:::o;47301:133::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;47409:18:::1;47388;:39;;;;47301:133:::0;:::o;50954:33::-;;;;:::o;49775:140::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;49822:15:::1;49840:21;49822:39;;49879:10;49871:28;;:37;49900:7;49871:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;49812:103;49775:140::o:0;53129:122::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;53230:14:::1;53211:16;:33;;;;53129:122:::0;:::o;737:142:7:-;836:42;737:142;:::o;54418:169:4:-;54523:4;2062:10:7;2054:18;;:4;:18;;;2050:81;;2088:32;2109:10;2088:20;:32::i;:::-;2050:81;54539:41:4::1;54562:4;54568:2;54572:7;54539:22;:41::i;:::-;54418:169:::0;;;;:::o;53607:247::-;53678:4;53663:19;;:11;;;;;;;;;;;:19;;;53655:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;53733:41;53752:12;:10;:12::i;:::-;53766:7;53733:18;:41::i;:::-;53725:98;;;;;;;;;;;;:::i;:::-;;;;;;;;;53833:14;53839:7;53833:5;:14::i;:::-;53607:247;:::o;51529:193::-;51610:4;51633:82;51652:6;51660:17;;51706:6;51689:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;51679:35;;;;;;51633:18;:82::i;:::-;51626:89;;51529:193;;;;:::o;47149:146::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;47274:14:::1;47253:18;:35;;;;47149:146:::0;:::o;47616:71::-;47656:4;47676:6;;47669:13;;47616:71;:::o;53392:106::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;53482:9:::1;53463:16;:28;;;;53392:106:::0;:::o;46574:48::-;;;;;;;;;;;;;;;;;:::o;46733:95::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;46814:7:::1;46803:8;:18;;;;;;:::i;:::-;;46733:95:::0;:::o;53504:97::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;53588:6:::1;53574:11;;:20;;;;;;;;;;;;;;;;;;53504:97:::0;:::o;51728:1275::-;51855:1;51845:6;;:11;51837:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;51922:21;;51912:8;51898:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:45;;51890:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;52003:29;52013:6;;52003:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52021:10;52003:9;:29::i;:::-;51995:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;52089:14;;52077:8;:26;;52069:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;52171:16;;52160:8;:27;;;;:::i;:::-;52147:9;:40;;52139:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;52255:8;52223:16;:28;52240:10;52223:28;;;;;;;;;;;;;;;;:40;;;;;;;:::i;:::-;;;;;;;;52313:16;;52281;:28;52298:10;52281:28;;;;;;;;;;;;;;;;:48;;52273:89;;;;;;;;;;;;:::i;:::-;;;;;;;;;52390:1;52376:10;:15;52373:624;;52465:3;52460:1;52448:8;52435:10;;:21;;;;:::i;:::-;52434:27;;;;:::i;:::-;:34;;52426:92;;;;;;;;;;;;:::i;:::-;;;;;;;;;52533:9;52528:151;52552:8;52548:1;:12;52528:151;;;52581:33;52591:10;52603;;52581:9;:33::i;:::-;52628:10;;:12;;;;;;;;;:::i;:::-;;;;;;52654;;:14;;;;;;;;;:::i;:::-;;;;;;52562:3;;;;;:::i;:::-;;;;52528:151;;;;52373:624;;;52769:4;52764:1;52753:8;52739:11;;:22;;;;:::i;:::-;52738:27;;;;:::i;:::-;:35;;52730:94;;;;;;;;;;;;:::i;:::-;;;;;;;;;52839:9;52834:153;52858:8;52854:1;:12;52834:153;;;52887:34;52897:10;52909:11;;52887:9;:34::i;:::-;52935:11;;:13;;;;;;;;;:::i;:::-;;;;;;52962:12;;:14;;;;;;;;;:::i;:::-;;;;;;52868:3;;;;;:::i;:::-;;;;52834:153;;;;52373:624;51728:1275;;;;:::o;46535:33::-;;;;:::o;33180:313::-;33292:7;33315:13;33331:7;:16;33339:7;33331:16;;;;;;;;;;;;;;;;;;;;;33315:32;;33395:1;33378:19;;:5;:19;;;33357:107;;;;;;;;;;;;:::i;:::-;;;;;;;;;33481:5;33474:12;;;33180:313;;;:::o;47541:70::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;47605:1:::1;47596:6;:10;;;;47541:70:::0;:::o;32840:283::-;32952:7;33013:1;32996:19;;:5;:19;;;32975:108;;;;;;;;;;;;:::i;:::-;;;;;;;;;33100:9;:16;33110:5;33100:16;;;;;;;;;;;;;;;;33093:23;;32840:283;;;:::o;46138:31::-;;;;:::o;32115:22::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;46280:39::-;;;;:::o;51388:135::-;51453:7;51500:16;;51490:9;:26;;;;:::i;:::-;51483:33;;51388:135;;;:::o;30016:85::-;30062:7;30088:6;;;;;;;;;;;30081:13;;30016:85;:::o;50803:92::-;50851:7;50877:11;;50870:18;;50803:92;:::o;49921:336::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;50041:3:::1;50036:1;50024:8;50011:10;;:21;;;;:::i;:::-;50010:27;;;;:::i;:::-;:34;;50002:92;;;;;;;;;;;;:::i;:::-;;;;;;;;;50109:9;50104:147;50128:8;50124:1;:12;50104:147;;;50157:29;50167:6;50175:10;;50157:9;:29::i;:::-;50200:10;;:12;;;;;;;;;:::i;:::-;;;;;;50226;;:14;;;;;;;;;:::i;:::-;;;;;;50138:3;;;;;:::i;:::-;;;;50104:147;;;;49921:336:::0;;:::o;47807:194::-;47888:4;47911:83;47930:6;47938:18;;47985:6;47968:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;47958:35;;;;;;47911:18;:83::i;:::-;47904:90;;47807:194;;;;:::o;46939:88::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;47011:9:::1;47003:5;:17;;;;46939:88:::0;:::o;33717:102::-;33773:13;33805:7;33798:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33717:102;:::o;46325:35::-;;;;:::o;46065:29::-;;;;:::o;46498:30::-;;;;:::o;53910:174::-;54014:8;2227:30:7;2248:8;2227:20;:30::i;:::-;54034:43:4::1;54058:8;54068;54034:23;:43::i;:::-;53910:174:::0;;;:::o;53009:114::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;53104:12:::1;53087:14;:29;;;;53009:114:::0;:::o;54593:222::-;54741:4;2062:10:7;2054:18;;:4;:18;;;2050:81;;2088:32;2109:10;2088:20;:32::i;:::-;2050:81;54761:47:4::1;54784:4;54790:2;54794:7;54803:4;54761:22;:47::i;:::-;54593:222:::0;;;;;:::o;53257:129::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;53364:15:::1;53340:21;:39;;;;53257:129:::0;:::o;47033:110::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;47127:9:::1;47108:16;:28;;;;47033:110:::0;:::o;49373:396::-;49486:13;49523:16;49531:7;49523;:16::i;:::-;49515:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;49601:18;49622:9;:7;:9::i;:::-;49601:30;;49689:1;49674:4;49668:18;:22;:93;;;;;;;;;;;;;;;;;49717:4;49728:18;:7;:16;:18::i;:::-;49700:56;;;;;;;;;:::i;:::-;;;;;;;;;;;;;49668:93;49645:116;;;49373:396;;;:::o;51034:32::-;;;;:::o;51176:42::-;;;;:::o;51072:41::-;;;;:::o;50706:90::-;50753:7;50779:10;;50772:17;;50706:90;:::o;46015:43::-;46054:4;46015:43;:::o;46628:31::-;;;;;;;;;;;;;:::o;50263:341::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;50384:4:::1;50379:1;50368:8;50354:11;;:22;;;;:::i;:::-;50353:27;;;;:::i;:::-;:35;;50345:94;;;;;;;;;;;;:::i;:::-;;;;;;;;;50454:9;50449:149;50473:8;50469:1;:12;50449:149;;;50502:30;50512:6;50520:11;;50502:9;:30::i;:::-;50546:11;;:13;;;;;;;;;:::i;:::-;;;;;;50573:12;;:14;;;;;;;;;:::i;:::-;;;;;;50483:3;;;;;:::i;:::-;;;;50449:149;;;;50263:341:::0;;:::o;47693:108::-;47751:7;47789:5;;47777:9;:17;;;;:::i;:::-;47770:24;;47693:108;;;:::o;36081:206::-;36218:4;36245:18;:25;36264:5;36245:25;;;;;;;;;;;;;;;:35;36271:8;36245:35;;;;;;;;;;;;;;;;;;;;;;;;;36238:42;;36081:206;;;;:::o;30792:223::-;30239:12;:10;:12::i;:::-;30228:23;;:7;:5;:7::i;:::-;:23;;;30220:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;30913:1:::1;30893:22;;:8;:22;;::::0;30872:107:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;30989:19;30999:8;30989:9;:19::i;:::-;30792:223:::0;:::o;21771:199::-;21896:4;21938:25;21923:40;;;:11;:40;;;;21916:47;;21771:199;;;:::o;38884:125::-;38949:4;39000:1;38972:30;;:7;:16;38980:7;38972:16;;;;;;;;;;;;;;;;;;;;;:30;;;;38965:37;;38884:125;;;:::o;2281:412:7:-;2518:1;836:42;2470:45;;;:49;2466:221;;;836:42;2540;;;2591:4;2598:8;2540:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2535:142;;2653:8;2634:28;;;;;;;;;;;:::i;:::-;;;;;;;;2535:142;2466:221;2281:412;:::o;34873:401:4:-;34953:13;34969:23;34984:7;34969:14;:23::i;:::-;34953:39;;35016:5;35010:11;;:2;:11;;;35002:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;35107:5;35091:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;35116:37;35133:5;35140:12;:10;:12::i;:::-;35116:16;:37::i;:::-;35091:62;35070:165;;;;;;;;;;;;:::i;:::-;;;;;;;;;35246:21;35255:2;35259:7;35246:8;:21::i;:::-;34943:331;34873:401;;:::o;28786:96::-;28839:7;28865:10;28858:17;;28786:96;:::o;39935:108::-;40010:26;40020:2;40024:7;40010:26;;;;;;;;;;;;:9;:26::i;:::-;39935:108;;:::o;36349:364::-;36551:41;36570:12;:10;:12::i;:::-;36584:7;36551:18;:41::i;:::-;36530:137;;;;;;;;;;;;:::i;:::-;;;;;;;;;36678:28;36688:4;36694:2;36698:7;36678:9;:28::i;:::-;36349:364;;;:::o;36779:179::-;36912:39;36929:4;36935:2;36939:7;36912:39;;;;;;;;;;;;:16;:39::i;:::-;36779:179;;;:::o;39167:438::-;39292:4;39333:16;39341:7;39333;:16::i;:::-;39312:107;;;;;;;;;;;;:::i;:::-;;;;;;;;;39429:13;39445:23;39460:7;39445:14;:23::i;:::-;39429:39;;39497:5;39486:16;;:7;:16;;;:63;;;;39542:7;39518:31;;:20;39530:7;39518:11;:20::i;:::-;:31;;;39486:63;:111;;;;39565:32;39582:5;39589:7;39565:16;:32::i;:::-;39486:111;39478:120;;;39167:438;;;;:::o;41486:348::-;41545:13;41561:23;41576:7;41561:14;:23::i;:::-;41545:39;;41595:48;41616:5;41631:1;41635:7;41595:20;:48::i;:::-;41681:29;41698:1;41702:7;41681:8;:29::i;:::-;41741:1;41721:9;:16;41731:5;41721:16;;;;;;;;;;;;;;;;:21;;;;;;;:::i;:::-;;;;;;;;41759:7;:16;41767:7;41759:16;;;;;;;;;;;;41752:23;;;;;;;;;;;41819:7;41815:1;41791:36;;41800:5;41791:36;;;;;;;;;;;;41535:299;41486:348;:::o;1141:184::-;1262:4;1314;1285:25;1298:5;1305:4;1285:12;:25::i;:::-;:33;1278:40;;1141:184;;;;;:::o;35697:318::-;35839:12;:10;:12::i;:::-;35827:24;;:8;:24;;;35819:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;35937:8;35892:18;:32;35911:12;:10;:12::i;:::-;35892:32;;;;;;;;;;;;;;;:42;35925:8;35892:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;35989:8;35960:48;;35975:12;:10;:12::i;:::-;35960:48;;;35999:8;35960:48;;;;;;:::i;:::-;;;;;;;;35697:318;;:::o;37024:354::-;37206:41;37225:12;:10;:12::i;:::-;37239:7;37206:18;:41::i;:::-;37185:137;;;;;;;;;;;;:::i;:::-;;;;;;;;;37332:39;37346:4;37352:2;37356:7;37365:5;37332:13;:39::i;:::-;37024:354;;;;:::o;34719:97::-;34769:13;34801:8;34794:15;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34719:97;:::o;9672:703::-;9728:13;9954:1;9945:5;:10;9941:51;;9971:10;;;;;;;;;;;;;;;;;;;;;9941:51;10001:12;10016:5;10001:20;;10031:14;10055:75;10070:1;10062:4;:9;10055:75;;10087:8;;;;;:::i;:::-;;;;10117:2;10109:10;;;;;:::i;:::-;;;10055:75;;;10139:19;10171:6;10161:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10139:39;;10188:150;10204:1;10195:5;:10;10188:150;;10231:1;10221:11;;;;;:::i;:::-;;;10297:2;10289:5;:10;;;;:::i;:::-;10276:2;:24;;;;:::i;:::-;10263:39;;10246:6;10253;10246:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;10325:2;10316:11;;;;;:::i;:::-;;;10188:150;;;10361:6;10347:21;;;;;9672:703;;;;:::o;31021:169::-;31076:16;31095:6;;;;;;;;;;;31076:25;;31120:8;31111:6;;:17;;;;;;;;;;;;;;;;;;31174:8;31143:40;;31164:8;31143:40;;;;;;;;;;;;31066:124;31021:169;:::o;42863:171::-;42964:2;42937:15;:24;42953:7;42937:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;43019:7;43015:2;42981:46;;42990:23;43005:7;42990:14;:23::i;:::-;42981:46;;;;;;;;;;;;42863:171;;:::o;40264:311::-;40389:18;40395:2;40399:7;40389:5;:18::i;:::-;40438:54;40469:1;40473:2;40477:7;40486:5;40438:22;:54::i;:::-;40417:151;;;;;;;;;;;;:::i;:::-;;;;;;;;;40264:311;;;:::o;42158:594::-;42325:4;42298:31;;:23;42313:7;42298:14;:23::i;:::-;:31;;;42277:119;;;;;;;;;;;;:::i;:::-;;;;;;;;;42428:1;42414:16;;:2;:16;;;42406:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;42482:39;42503:4;42509:2;42513:7;42482:20;:39::i;:::-;42583:29;42600:1;42604:7;42583:8;:29::i;:::-;42642:1;42623:9;:15;42633:4;42623:15;;;;;;;;;;;;;;;;:20;;;;;;;:::i;:::-;;;;;;;;42670:1;42653:9;:13;42663:2;42653:13;;;;;;;;;;;;;;;;:18;;;;;;;:::i;:::-;;;;;;;;42700:2;42681:7;:16;42689:7;42681:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;42737:7;42733:2;42718:27;;42727:4;42718:27;;;;;;;;;;;;42158:594;;;:::o;45097:122::-;;;;:::o;1676:690::-;1783:7;1806:20;1829:4;1806:27;;1848:9;1843:488;1867:5;:12;1863:1;:16;1843:488;;;1900:20;1923:5;1929:1;1923:8;;;;;;;;:::i;:::-;;;;;;;;1900:31;;1965:12;1949;:28;1945:376;;2090:42;2105:12;2119;2090:14;:42::i;:::-;2075:57;;1945:376;;;2264:42;2279:12;2293;2264:14;:42::i;:::-;2249:57;;1945:376;1886:445;1881:3;;;;;:::i;:::-;;;;1843:488;;;;2347:12;2340:19;;;1676:690;;;;:::o;38240:341::-;38391:28;38401:4;38407:2;38411:7;38391:9;:28::i;:::-;38450:48;38473:4;38479:2;38483:7;38492:5;38450:22;:48::i;:::-;38429:145;;;;;;;;;;;;:::i;:::-;;;;;;;;;38240:341;;;;:::o;40897:372::-;40990:1;40976:16;;:2;:16;;;40968:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;41048:16;41056:7;41048;:16::i;:::-;41047:17;41039:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;41108:45;41137:1;41141:2;41145:7;41108:20;:45::i;:::-;41181:1;41164:9;:13;41174:2;41164:13;;;;;;;;;;;;;;;;:18;;;;;;;:::i;:::-;;;;;;;;41211:2;41192:7;:16;41200:7;41192:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;41254:7;41250:2;41229:33;;41246:1;41229:33;;;;;;;;;;;;40897:372;;:::o;43587:954::-;43737:4;43757:15;:2;:13;;;:15::i;:::-;43753:782;;;43824:2;43808:36;;;43866:12;:10;:12::i;:::-;43900:4;43926:7;43955:5;43808:170;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;43788:695;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44178:1;44161:6;:13;:18;44157:312;;44203:106;;;;;;;;;;:::i;:::-;;;;;;;;44157:312;44421:6;44415:13;44406:6;44402:2;44398:15;44391:38;43788:695;44050:45;;;44040:55;;;:6;:55;;;;44033:62;;;;;43753:782;44520:4;44513:11;;43587:954;;;;;;;:::o;2372:246::-;2464:13;2529:1;2523:4;2516:15;2557:1;2551:4;2544:15;2597:4;2591;2581:21;2572:30;;2372:246;;;;:::o;12090:377::-;12150:4;12353:12;12418:7;12406:20;12398:28;;12459:1;12452:4;:8;12445:15;;;12090:377;;;:::o;7:75:14:-;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:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:77::-;1555:7;1584:5;1573:16;;1518:77;;;:::o;1601:118::-;1688:24;1706:5;1688:24;:::i;:::-;1683:3;1676:37;1601:118;;:::o;1725:222::-;1818:4;1856:2;1845:9;1841:18;1833:26;;1869:71;1937:1;1926:9;1922:17;1913:6;1869:71;:::i;:::-;1725:222;;;;:::o;1953:99::-;2005:6;2039:5;2033:12;2023:22;;1953:99;;;:::o;2058:169::-;2142:11;2176:6;2171:3;2164:19;2216:4;2211:3;2207:14;2192:29;;2058:169;;;;:::o;2233:246::-;2314:1;2324:113;2338:6;2335:1;2332:13;2324:113;;;2423:1;2418:3;2414:11;2408:18;2404:1;2399:3;2395:11;2388:39;2360:2;2357:1;2353:10;2348:15;;2324:113;;;2471:1;2462:6;2457:3;2453:16;2446:27;2295:184;2233:246;;;:::o;2485:102::-;2526:6;2577:2;2573:7;2568:2;2561:5;2557:14;2553:28;2543:38;;2485:102;;;:::o;2593:377::-;2681:3;2709:39;2742:5;2709:39;:::i;:::-;2764:71;2828:6;2823:3;2764:71;:::i;:::-;2757:78;;2844:65;2902:6;2897:3;2890:4;2883:5;2879:16;2844:65;:::i;:::-;2934:29;2956:6;2934:29;:::i;:::-;2929:3;2925:39;2918:46;;2685:285;2593:377;;;;:::o;2976:313::-;3089:4;3127:2;3116:9;3112:18;3104:26;;3176:9;3170:4;3166:20;3162:1;3151:9;3147:17;3140:47;3204:78;3277:4;3268:6;3204:78;:::i;:::-;3196:86;;2976:313;;;;:::o;3295:122::-;3368:24;3386:5;3368:24;:::i;:::-;3361:5;3358:35;3348:63;;3407:1;3404;3397:12;3348:63;3295:122;:::o;3423:139::-;3469:5;3507:6;3494:20;3485:29;;3523:33;3550:5;3523:33;:::i;:::-;3423:139;;;;:::o;3568:329::-;3627:6;3676:2;3664:9;3655:7;3651:23;3647:32;3644:119;;;3682:79;;:::i;:::-;3644:119;3802:1;3827:53;3872:7;3863:6;3852:9;3848:22;3827:53;:::i;:::-;3817:63;;3773:117;3568:329;;;;:::o;3903:126::-;3940:7;3980:42;3973:5;3969:54;3958:65;;3903:126;;;:::o;4035:96::-;4072:7;4101:24;4119:5;4101:24;:::i;:::-;4090:35;;4035:96;;;:::o;4137:118::-;4224:24;4242:5;4224:24;:::i;:::-;4219:3;4212:37;4137:118;;:::o;4261:222::-;4354:4;4392:2;4381:9;4377:18;4369:26;;4405:71;4473:1;4462:9;4458:17;4449:6;4405:71;:::i;:::-;4261:222;;;;:::o;4489:122::-;4562:24;4580:5;4562:24;:::i;:::-;4555:5;4552:35;4542:63;;4601:1;4598;4591:12;4542:63;4489:122;:::o;4617:139::-;4663:5;4701:6;4688:20;4679:29;;4717:33;4744:5;4717:33;:::i;:::-;4617:139;;;;:::o;4762:474::-;4830:6;4838;4887:2;4875:9;4866:7;4862:23;4858:32;4855:119;;;4893:79;;:::i;:::-;4855:119;5013:1;5038:53;5083:7;5074:6;5063:9;5059:22;5038:53;:::i;:::-;5028:63;;4984:117;5140:2;5166:53;5211:7;5202:6;5191:9;5187:22;5166:53;:::i;:::-;5156:63;;5111:118;4762:474;;;;;:::o;5242:77::-;5279:7;5308:5;5297:16;;5242:77;;;:::o;5325:122::-;5398:24;5416:5;5398:24;:::i;:::-;5391:5;5388:35;5378:63;;5437:1;5434;5427:12;5378:63;5325:122;:::o;5453:139::-;5499:5;5537:6;5524:20;5515:29;;5553:33;5580:5;5553:33;:::i;:::-;5453:139;;;;:::o;5598:329::-;5657:6;5706:2;5694:9;5685:7;5681:23;5677:32;5674:119;;;5712:79;;:::i;:::-;5674:119;5832:1;5857:53;5902:7;5893:6;5882:9;5878:22;5857:53;:::i;:::-;5847:63;;5803:117;5598:329;;;;:::o;5933:117::-;6042:1;6039;6032:12;6056:117;6165:1;6162;6155:12;6179:117;6288:1;6285;6278:12;6319:568;6392:8;6402:6;6452:3;6445:4;6437:6;6433:17;6429:27;6419:122;;6460:79;;:::i;:::-;6419:122;6573:6;6560:20;6550:30;;6603:18;6595:6;6592:30;6589:117;;;6625:79;;:::i;:::-;6589:117;6739:4;6731:6;6727:17;6715:29;;6793:3;6785:4;6777:6;6773:17;6763:8;6759:32;6756:41;6753:128;;;6800:79;;:::i;:::-;6753:128;6319:568;;;;;:::o;6893:849::-;6997:6;7005;7013;7021;7070:2;7058:9;7049:7;7045:23;7041:32;7038:119;;;7076:79;;:::i;:::-;7038:119;7196:1;7221:53;7266:7;7257:6;7246:9;7242:22;7221:53;:::i;:::-;7211:63;;7167:117;7351:2;7340:9;7336:18;7323:32;7382:18;7374:6;7371:30;7368:117;;;7404:79;;:::i;:::-;7368:117;7517:80;7589:7;7580:6;7569:9;7565:22;7517:80;:::i;:::-;7499:98;;;;7294:313;7646:2;7672:53;7717:7;7708:6;7697:9;7693:22;7672:53;:::i;:::-;7662:63;;7617:118;6893:849;;;;;;;:::o;7748:619::-;7825:6;7833;7841;7890:2;7878:9;7869:7;7865:23;7861:32;7858:119;;;7896:79;;:::i;:::-;7858:119;8016:1;8041:53;8086:7;8077:6;8066:9;8062:22;8041:53;:::i;:::-;8031:63;;7987:117;8143:2;8169:53;8214:7;8205:6;8194:9;8190:22;8169:53;:::i;:::-;8159:63;;8114:118;8271:2;8297:53;8342:7;8333:6;8322:9;8318:22;8297:53;:::i;:::-;8287:63;;8242:118;7748:619;;;;;:::o;8373:329::-;8432:6;8481:2;8469:9;8460:7;8456:23;8452:32;8449:119;;;8487:79;;:::i;:::-;8449:119;8607:1;8632:53;8677:7;8668:6;8657:9;8653:22;8632:53;:::i;:::-;8622:63;;8578:117;8373:329;;;;:::o;8708:60::-;8736:3;8757:5;8750:12;;8708:60;;;:::o;8774:142::-;8824:9;8857:53;8875:34;8884:24;8902:5;8884:24;:::i;:::-;8875:34;:::i;:::-;8857:53;:::i;:::-;8844:66;;8774:142;;;:::o;8922:126::-;8972:9;9005:37;9036:5;9005:37;:::i;:::-;8992:50;;8922:126;;;:::o;9054:157::-;9135:9;9168:37;9199:5;9168:37;:::i;:::-;9155:50;;9054:157;;;:::o;9217:193::-;9335:68;9397:5;9335:68;:::i;:::-;9330:3;9323:81;9217:193;;:::o;9416:284::-;9540:4;9578:2;9567:9;9563:18;9555:26;;9591:102;9690:1;9679:9;9675:17;9666:6;9591:102;:::i;:::-;9416:284;;;;:::o;9706:180::-;9754:77;9751:1;9744:88;9851:4;9848:1;9841:15;9875:4;9872:1;9865:15;9892:281;9975:27;9997:4;9975:27;:::i;:::-;9967:6;9963:40;10105:6;10093:10;10090:22;10069:18;10057:10;10054:34;10051:62;10048:88;;;10116:18;;:::i;:::-;10048:88;10156:10;10152:2;10145:22;9935:238;9892:281;;:::o;10179:129::-;10213:6;10240:20;;:::i;:::-;10230:30;;10269:33;10297:4;10289:6;10269:33;:::i;:::-;10179:129;;;:::o;10314:311::-;10391:4;10481:18;10473:6;10470:30;10467:56;;;10503:18;;:::i;:::-;10467:56;10553:4;10545:6;10541:17;10533:25;;10613:4;10607;10603:15;10595:23;;10314:311;;;:::o;10648:710::-;10744:5;10769:81;10785:64;10842:6;10785:64;:::i;:::-;10769:81;:::i;:::-;10760:90;;10870:5;10899:6;10892:5;10885:21;10933:4;10926:5;10922:16;10915:23;;10986:4;10978:6;10974:17;10966:6;10962:30;11015:3;11007:6;11004:15;11001:122;;;11034:79;;:::i;:::-;11001:122;11149:6;11132:220;11166:6;11161:3;11158:15;11132:220;;;11241:3;11270:37;11303:3;11291:10;11270:37;:::i;:::-;11265:3;11258:50;11337:4;11332:3;11328:14;11321:21;;11208:144;11192:4;11187:3;11183:14;11176:21;;11132:220;;;11136:21;10750:608;;10648:710;;;;;:::o;11381:370::-;11452:5;11501:3;11494:4;11486:6;11482:17;11478:27;11468:122;;11509:79;;:::i;:::-;11468:122;11626:6;11613:20;11651:94;11741:3;11733:6;11726:4;11718:6;11714:17;11651:94;:::i;:::-;11642:103;;11458:293;11381:370;;;;:::o;11757:684::-;11850:6;11858;11907:2;11895:9;11886:7;11882:23;11878:32;11875:119;;;11913:79;;:::i;:::-;11875:119;12061:1;12050:9;12046:17;12033:31;12091:18;12083:6;12080:30;12077:117;;;12113:79;;:::i;:::-;12077:117;12218:78;12288:7;12279:6;12268:9;12264:22;12218:78;:::i;:::-;12208:88;;12004:302;12345:2;12371:53;12416:7;12407:6;12396:9;12392:22;12371:53;:::i;:::-;12361:63;;12316:118;11757:684;;;;;:::o;12447:117::-;12556:1;12553;12546:12;12570:308;12632:4;12722:18;12714:6;12711:30;12708:56;;;12744:18;;:::i;:::-;12708:56;12782:29;12804:6;12782:29;:::i;:::-;12774:37;;12866:4;12860;12856:15;12848:23;;12570:308;;;:::o;12884:146::-;12981:6;12976:3;12971;12958:30;13022:1;13013:6;13008:3;13004:16;12997:27;12884:146;;;:::o;13036:425::-;13114:5;13139:66;13155:49;13197:6;13155:49;:::i;:::-;13139:66;:::i;:::-;13130:75;;13228:6;13221:5;13214:21;13266:4;13259:5;13255:16;13304:3;13295:6;13290:3;13286:16;13283:25;13280:112;;;13311:79;;:::i;:::-;13280:112;13401:54;13448:6;13443:3;13438;13401:54;:::i;:::-;13120:341;13036:425;;;;;:::o;13481:340::-;13537:5;13586:3;13579:4;13571:6;13567:17;13563:27;13553:122;;13594:79;;:::i;:::-;13553:122;13711:6;13698:20;13736:79;13811:3;13803:6;13796:4;13788:6;13784:17;13736:79;:::i;:::-;13727:88;;13543:278;13481:340;;;;:::o;13827:509::-;13896:6;13945:2;13933:9;13924:7;13920:23;13916:32;13913:119;;;13951:79;;:::i;:::-;13913:119;14099:1;14088:9;14084:17;14071:31;14129:18;14121:6;14118:30;14115:117;;;14151:79;;:::i;:::-;14115:117;14256:63;14311:7;14302:6;14291:9;14287:22;14256:63;:::i;:::-;14246:73;;14042:287;13827:509;;;;:::o;14342:116::-;14412:21;14427:5;14412:21;:::i;:::-;14405:5;14402:32;14392:60;;14448:1;14445;14438:12;14392:60;14342:116;:::o;14464:133::-;14507:5;14545:6;14532:20;14523:29;;14561:30;14585:5;14561:30;:::i;:::-;14464:133;;;;:::o;14603:323::-;14659:6;14708:2;14696:9;14687:7;14683:23;14679:32;14676:119;;;14714:79;;:::i;:::-;14676:119;14834:1;14859:50;14901:7;14892:6;14881:9;14877:22;14859:50;:::i;:::-;14849:60;;14805:114;14603:323;;;;:::o;14932:118::-;15019:24;15037:5;15019:24;:::i;:::-;15014:3;15007:37;14932:118;;:::o;15056:222::-;15149:4;15187:2;15176:9;15172:18;15164:26;;15200:71;15268:1;15257:9;15253:17;15244:6;15200:71;:::i;:::-;15056:222;;;;:::o;15284:468::-;15349:6;15357;15406:2;15394:9;15385:7;15381:23;15377:32;15374:119;;;15412:79;;:::i;:::-;15374:119;15532:1;15557:53;15602:7;15593:6;15582:9;15578:22;15557:53;:::i;:::-;15547:63;;15503:117;15659:2;15685:50;15727:7;15718:6;15707:9;15703:22;15685:50;:::i;:::-;15675:60;;15630:115;15284:468;;;;;:::o;15758:307::-;15819:4;15909:18;15901:6;15898:30;15895:56;;;15931:18;;:::i;:::-;15895:56;15969:29;15991:6;15969:29;:::i;:::-;15961:37;;16053:4;16047;16043:15;16035:23;;15758:307;;;:::o;16071:423::-;16148:5;16173:65;16189:48;16230:6;16189:48;:::i;:::-;16173:65;:::i;:::-;16164:74;;16261:6;16254:5;16247:21;16299:4;16292:5;16288:16;16337:3;16328:6;16323:3;16319:16;16316:25;16313:112;;;16344:79;;:::i;:::-;16313:112;16434:54;16481:6;16476:3;16471;16434:54;:::i;:::-;16154:340;16071:423;;;;;:::o;16513:338::-;16568:5;16617:3;16610:4;16602:6;16598:17;16594:27;16584:122;;16625:79;;:::i;:::-;16584:122;16742:6;16729:20;16767:78;16841:3;16833:6;16826:4;16818:6;16814:17;16767:78;:::i;:::-;16758:87;;16574:277;16513:338;;;;:::o;16857:943::-;16952:6;16960;16968;16976;17025:3;17013:9;17004:7;17000:23;16996:33;16993:120;;;17032:79;;:::i;:::-;16993:120;17152:1;17177:53;17222:7;17213:6;17202:9;17198:22;17177:53;:::i;:::-;17167:63;;17123:117;17279:2;17305:53;17350:7;17341:6;17330:9;17326:22;17305:53;:::i;:::-;17295:63;;17250:118;17407:2;17433:53;17478:7;17469:6;17458:9;17454:22;17433:53;:::i;:::-;17423:63;;17378:118;17563:2;17552:9;17548:18;17535:32;17594:18;17586:6;17583:30;17580:117;;;17616:79;;:::i;:::-;17580:117;17721:62;17775:7;17766:6;17755:9;17751:22;17721:62;:::i;:::-;17711:72;;17506:287;16857:943;;;;;;;:::o;17806:474::-;17874:6;17882;17931:2;17919:9;17910:7;17906:23;17902:32;17899:119;;;17937:79;;:::i;:::-;17899:119;18057:1;18082:53;18127:7;18118:6;18107:9;18103:22;18082:53;:::i;:::-;18072:63;;18028:117;18184:2;18210:53;18255:7;18246:6;18235:9;18231:22;18210:53;:::i;:::-;18200:63;;18155:118;17806:474;;;;;:::o;18286:180::-;18334:77;18331:1;18324:88;18431:4;18428:1;18421:15;18455:4;18452:1;18445:15;18472:320;18516:6;18553:1;18547:4;18543:12;18533:22;;18600:1;18594:4;18590:12;18621:18;18611:81;;18677:4;18669:6;18665:17;18655:27;;18611:81;18739:2;18731:6;18728:14;18708:18;18705:38;18702:84;;18758:18;;:::i;:::-;18702:84;18523:269;18472:320;;;:::o;18798:231::-;18938:34;18934:1;18926:6;18922:14;18915:58;19007:14;19002:2;18994:6;18990:15;18983:39;18798:231;:::o;19035:366::-;19177:3;19198:67;19262:2;19257:3;19198:67;:::i;:::-;19191:74;;19274:93;19363:3;19274:93;:::i;:::-;19392:2;19387:3;19383:12;19376:19;;19035:366;;;:::o;19407:419::-;19573:4;19611:2;19600:9;19596:18;19588:26;;19660:9;19654:4;19650:20;19646:1;19635:9;19631:17;19624:47;19688:131;19814:4;19688:131;:::i;:::-;19680:139;;19407:419;;;:::o;19832:182::-;19972:34;19968:1;19960:6;19956:14;19949:58;19832:182;:::o;20020:366::-;20162:3;20183:67;20247:2;20242:3;20183:67;:::i;:::-;20176:74;;20259:93;20348:3;20259:93;:::i;:::-;20377:2;20372:3;20368:12;20361:19;;20020:366;;;:::o;20392:419::-;20558:4;20596:2;20585:9;20581:18;20573:26;;20645:9;20639:4;20635:20;20631:1;20620:9;20616:17;20609:47;20673:131;20799:4;20673:131;:::i;:::-;20665:139;;20392:419;;;:::o;20817:158::-;20957:10;20953:1;20945:6;20941:14;20934:34;20817:158;:::o;20981:365::-;21123:3;21144:66;21208:1;21203:3;21144:66;:::i;:::-;21137:73;;21219:93;21308:3;21219:93;:::i;:::-;21337:2;21332:3;21328:12;21321:19;;20981:365;;;:::o;21352:419::-;21518:4;21556:2;21545:9;21541:18;21533:26;;21605:9;21599:4;21595:20;21591:1;21580:9;21576:17;21569:47;21633:131;21759:4;21633:131;:::i;:::-;21625:139;;21352:419;;;:::o;21777:168::-;21917:20;21913:1;21905:6;21901:14;21894:44;21777:168;:::o;21951:366::-;22093:3;22114:67;22178:2;22173:3;22114:67;:::i;:::-;22107:74;;22190:93;22279:3;22190:93;:::i;:::-;22308:2;22303:3;22299:12;22292:19;;21951:366;;;:::o;22323:419::-;22489:4;22527:2;22516:9;22512:18;22504:26;;22576:9;22570:4;22566:20;22562:1;22551:9;22547:17;22540:47;22604:131;22730:4;22604:131;:::i;:::-;22596:139;;22323:419;;;:::o;22748:180::-;22796:77;22793:1;22786:88;22893:4;22890:1;22883:15;22917:4;22914:1;22907:15;22934:191;22974:3;22993:20;23011:1;22993:20;:::i;:::-;22988:25;;23027:20;23045:1;23027:20;:::i;:::-;23022:25;;23070:1;23067;23063:9;23056:16;;23091:3;23088:1;23085:10;23082:36;;;23098:18;;:::i;:::-;23082:36;22934:191;;;;:::o;23131:225::-;23271:34;23267:1;23259:6;23255:14;23248:58;23340:8;23335:2;23327:6;23323:15;23316:33;23131:225;:::o;23362:366::-;23504:3;23525:67;23589:2;23584:3;23525:67;:::i;:::-;23518:74;;23601:93;23690:3;23601:93;:::i;:::-;23719:2;23714:3;23710:12;23703:19;;23362:366;;;:::o;23734:419::-;23900:4;23938:2;23927:9;23923:18;23915:26;;23987:9;23981:4;23977:20;23973:1;23962:9;23958:17;23951:47;24015:131;24141:4;24015:131;:::i;:::-;24007:139;;23734:419;;;:::o;24159:235::-;24299:34;24295:1;24287:6;24283:14;24276:58;24368:18;24363:2;24355:6;24351:15;24344:43;24159:235;:::o;24400:366::-;24542:3;24563:67;24627:2;24622:3;24563:67;:::i;:::-;24556:74;;24639:93;24728:3;24639:93;:::i;:::-;24757:2;24752:3;24748:12;24741:19;;24400:366;;;:::o;24772:419::-;24938:4;24976:2;24965:9;24961:18;24953:26;;25025:9;25019:4;25015:20;25011:1;25000:9;24996:17;24989:47;25053:131;25179:4;25053:131;:::i;:::-;25045:139;;24772:419;;;:::o;25197:172::-;25337:24;25333:1;25325:6;25321:14;25314:48;25197:172;:::o;25375:366::-;25517:3;25538:67;25602:2;25597:3;25538:67;:::i;:::-;25531:74;;25614:93;25703:3;25614:93;:::i;:::-;25732:2;25727:3;25723:12;25716:19;;25375:366;;;:::o;25747:419::-;25913:4;25951:2;25940:9;25936:18;25928:26;;26000:9;25994:4;25990:20;25986:1;25975:9;25971:17;25964:47;26028:131;26154:4;26028:131;:::i;:::-;26020:139;;25747:419;;;:::o;26172:172::-;26312:24;26308:1;26300:6;26296:14;26289:48;26172:172;:::o;26350:366::-;26492:3;26513:67;26577:2;26572:3;26513:67;:::i;:::-;26506:74;;26589:93;26678:3;26589:93;:::i;:::-;26707:2;26702:3;26698:12;26691:19;;26350:366;;;:::o;26722:419::-;26888:4;26926:2;26915:9;26911:18;26903:26;;26975:9;26969:4;26965:20;26961:1;26950:9;26946:17;26939:47;27003:131;27129:4;27003:131;:::i;:::-;26995:139;;26722:419;;;:::o;27147:410::-;27187:7;27210:20;27228:1;27210:20;:::i;:::-;27205:25;;27244:20;27262:1;27244:20;:::i;:::-;27239:25;;27299:1;27296;27292:9;27321:30;27339:11;27321:30;:::i;:::-;27310:41;;27500:1;27491:7;27487:15;27484:1;27481:22;27461:1;27454:9;27434:83;27411:139;;27530:18;;:::i;:::-;27411:139;27195:362;27147:410;;;;:::o;27563:170::-;27703:22;27699:1;27691:6;27687:14;27680:46;27563:170;:::o;27739:366::-;27881:3;27902:67;27966:2;27961:3;27902:67;:::i;:::-;27895:74;;27978:93;28067:3;27978:93;:::i;:::-;28096:2;28091:3;28087:12;28080:19;;27739:366;;;:::o;28111:419::-;28277:4;28315:2;28304:9;28300:18;28292:26;;28364:9;28358:4;28354:20;28350:1;28339:9;28335:17;28328:47;28392:131;28518:4;28392:131;:::i;:::-;28384:139;;28111:419;;;:::o;28536:178::-;28676:30;28672:1;28664:6;28660:14;28653:54;28536:178;:::o;28720:366::-;28862:3;28883:67;28947:2;28942:3;28883:67;:::i;:::-;28876:74;;28959:93;29048:3;28959:93;:::i;:::-;29077:2;29072:3;29068:12;29061:19;;28720:366;;;:::o;29092:419::-;29258:4;29296:2;29285:9;29281:18;29273:26;;29345:9;29339:4;29335:20;29331:1;29320:9;29316:17;29309:47;29373:131;29499:4;29373:131;:::i;:::-;29365:139;;29092:419;;;:::o;29517:194::-;29557:4;29577:20;29595:1;29577:20;:::i;:::-;29572:25;;29611:20;29629:1;29611:20;:::i;:::-;29606:25;;29655:1;29652;29648:9;29640:17;;29679:1;29673:4;29670:11;29667:37;;;29684:18;;:::i;:::-;29667:37;29517:194;;;;:::o;29717:233::-;29857:34;29853:1;29845:6;29841:14;29834:58;29926:16;29921:2;29913:6;29909:15;29902:41;29717:233;:::o;29956:366::-;30098:3;30119:67;30183:2;30178:3;30119:67;:::i;:::-;30112:74;;30195:93;30284:3;30195:93;:::i;:::-;30313:2;30308:3;30304:12;30297:19;;29956:366;;;:::o;30328:419::-;30494:4;30532:2;30521:9;30517:18;30509:26;;30581:9;30575:4;30571:20;30567:1;30556:9;30552:17;30545:47;30609:131;30735:4;30609:131;:::i;:::-;30601:139;;30328:419;;;:::o;30753:233::-;30792:3;30815:24;30833:5;30815:24;:::i;:::-;30806:33;;30861:66;30854:5;30851:77;30848:103;;30931:18;;:::i;:::-;30848:103;30978:1;30971:5;30967:13;30960:20;;30753:233;;;:::o;30992:234::-;31132:34;31128:1;31120:6;31116:14;31109:58;31201:17;31196:2;31188:6;31184:15;31177:42;30992:234;:::o;31232:366::-;31374:3;31395:67;31459:2;31454:3;31395:67;:::i;:::-;31388:74;;31471:93;31560:3;31471:93;:::i;:::-;31589:2;31584:3;31580:12;31573:19;;31232:366;;;:::o;31604:419::-;31770:4;31808:2;31797:9;31793:18;31785:26;;31857:9;31851:4;31847:20;31843:1;31832:9;31828:17;31821:47;31885:131;32011:4;31885:131;:::i;:::-;31877:139;;31604:419;;;:::o;32029:178::-;32169:30;32165:1;32157:6;32153:14;32146:54;32029:178;:::o;32213:366::-;32355:3;32376:67;32440:2;32435:3;32376:67;:::i;:::-;32369:74;;32452:93;32541:3;32452:93;:::i;:::-;32570:2;32565:3;32561:12;32554:19;;32213:366;;;:::o;32585:419::-;32751:4;32789:2;32778:9;32774:18;32766:26;;32838:9;32832:4;32828:20;32824:1;32813:9;32809:17;32802:47;32866:131;32992:4;32866:131;:::i;:::-;32858:139;;32585:419;;;:::o;33010:232::-;33150:34;33146:1;33138:6;33134:14;33127:58;33219:15;33214:2;33206:6;33202:15;33195:40;33010:232;:::o;33248:366::-;33390:3;33411:67;33475:2;33470:3;33411:67;:::i;:::-;33404:74;;33487:93;33576:3;33487:93;:::i;:::-;33605:2;33600:3;33596:12;33589:19;;33248:366;;;:::o;33620:419::-;33786:4;33824:2;33813:9;33809:18;33801:26;;33873:9;33867:4;33863:20;33859:1;33848:9;33844:17;33837:47;33901:131;34027:4;33901:131;:::i;:::-;33893:139;;33620:419;;;:::o;34045:94::-;34078:8;34126:5;34122:2;34118:14;34097:35;;34045:94;;;:::o;34145:::-;34184:7;34213:20;34227:5;34213:20;:::i;:::-;34202:31;;34145:94;;;:::o;34245:100::-;34284:7;34313:26;34333:5;34313:26;:::i;:::-;34302:37;;34245:100;;;:::o;34351:157::-;34456:45;34476:24;34494:5;34476:24;:::i;:::-;34456:45;:::i;:::-;34451:3;34444:58;34351:157;;:::o;34514:256::-;34626:3;34641:75;34712:3;34703:6;34641:75;:::i;:::-;34741:2;34736:3;34732:12;34725:19;;34761:3;34754:10;;34514:256;;;;:::o;34776:141::-;34825:4;34848:3;34840:11;;34871:3;34868:1;34861:14;34905:4;34902:1;34892:18;34884:26;;34776:141;;;:::o;34923:93::-;34960:6;35007:2;35002;34995:5;34991:14;34987:23;34977:33;;34923:93;;;:::o;35022:107::-;35066:8;35116:5;35110:4;35106:16;35085:37;;35022:107;;;;:::o;35135:393::-;35204:6;35254:1;35242:10;35238:18;35277:97;35307:66;35296:9;35277:97;:::i;:::-;35395:39;35425:8;35414:9;35395:39;:::i;:::-;35383:51;;35467:4;35463:9;35456:5;35452:21;35443:30;;35516:4;35506:8;35502:19;35495:5;35492:30;35482:40;;35211:317;;35135:393;;;;;:::o;35534:142::-;35584:9;35617:53;35635:34;35644:24;35662:5;35644:24;:::i;:::-;35635:34;:::i;:::-;35617:53;:::i;:::-;35604:66;;35534:142;;;:::o;35682:75::-;35725:3;35746:5;35739:12;;35682:75;;;:::o;35763:269::-;35873:39;35904:7;35873:39;:::i;:::-;35934:91;35983:41;36007:16;35983:41;:::i;:::-;35975:6;35968:4;35962:11;35934:91;:::i;:::-;35928:4;35921:105;35839:193;35763:269;;;:::o;36038:73::-;36083:3;36038:73;:::o;36117:189::-;36194:32;;:::i;:::-;36235:65;36293:6;36285;36279:4;36235:65;:::i;:::-;36170:136;36117:189;;:::o;36312:186::-;36372:120;36389:3;36382:5;36379:14;36372:120;;;36443:39;36480:1;36473:5;36443:39;:::i;:::-;36416:1;36409:5;36405:13;36396:22;;36372:120;;;36312:186;;:::o;36504:543::-;36605:2;36600:3;36597:11;36594:446;;;36639:38;36671:5;36639:38;:::i;:::-;36723:29;36741:10;36723:29;:::i;:::-;36713:8;36709:44;36906:2;36894:10;36891:18;36888:49;;;36927:8;36912:23;;36888:49;36950:80;37006:22;37024:3;37006:22;:::i;:::-;36996:8;36992:37;36979:11;36950:80;:::i;:::-;36609:431;;36594:446;36504:543;;;:::o;37053:117::-;37107:8;37157:5;37151:4;37147:16;37126:37;;37053:117;;;;:::o;37176:169::-;37220:6;37253:51;37301:1;37297:6;37289:5;37286:1;37282:13;37253:51;:::i;:::-;37249:56;37334:4;37328;37324:15;37314:25;;37227:118;37176:169;;;;:::o;37350:295::-;37426:4;37572:29;37597:3;37591:4;37572:29;:::i;:::-;37564:37;;37634:3;37631:1;37627:11;37621:4;37618:21;37610:29;;37350:295;;;;:::o;37650:1395::-;37767:37;37800:3;37767:37;:::i;:::-;37869:18;37861:6;37858:30;37855:56;;;37891:18;;:::i;:::-;37855:56;37935:38;37967:4;37961:11;37935:38;:::i;:::-;38020:67;38080:6;38072;38066:4;38020:67;:::i;:::-;38114:1;38138:4;38125:17;;38170:2;38162:6;38159:14;38187:1;38182:618;;;;38844:1;38861:6;38858:77;;;38910:9;38905:3;38901:19;38895:26;38886:35;;38858:77;38961:67;39021:6;39014:5;38961:67;:::i;:::-;38955:4;38948:81;38817:222;38152:887;;38182:618;38234:4;38230:9;38222:6;38218:22;38268:37;38300:4;38268:37;:::i;:::-;38327:1;38341:208;38355:7;38352:1;38349:14;38341:208;;;38434:9;38429:3;38425:19;38419:26;38411:6;38404:42;38485:1;38477:6;38473:14;38463:24;;38532:2;38521:9;38517:18;38504:31;;38378:4;38375:1;38371:12;38366:17;;38341:208;;;38577:6;38568:7;38565:19;38562:179;;;38635:9;38630:3;38626:19;38620:26;38678:48;38720:4;38712:6;38708:17;38697:9;38678:48;:::i;:::-;38670:6;38663:64;38585:156;38562:179;38787:1;38783;38775:6;38771:14;38767:22;38761:4;38754:36;38189:611;;;38152:887;;37742:1303;;;37650:1395;;:::o;39051:228::-;39191:34;39187:1;39179:6;39175:14;39168:58;39260:11;39255:2;39247:6;39243:15;39236:36;39051:228;:::o;39285:366::-;39427:3;39448:67;39512:2;39507:3;39448:67;:::i;:::-;39441:74;;39524:93;39613:3;39524:93;:::i;:::-;39642:2;39637:3;39633:12;39626:19;;39285:366;;;:::o;39657:419::-;39823:4;39861:2;39850:9;39846:18;39838:26;;39910:9;39904:4;39900:20;39896:1;39885:9;39881:17;39874:47;39938:131;40064:4;39938:131;:::i;:::-;39930:139;;39657:419;;;:::o;40082:229::-;40222:34;40218:1;40210:6;40206:14;40199:58;40291:12;40286:2;40278:6;40274:15;40267:37;40082:229;:::o;40317:366::-;40459:3;40480:67;40544:2;40539:3;40480:67;:::i;:::-;40473:74;;40556:93;40645:3;40556:93;:::i;:::-;40674:2;40669:3;40665:12;40658:19;;40317:366;;;:::o;40689:419::-;40855:4;40893:2;40882:9;40878:18;40870:26;;40942:9;40936:4;40932:20;40928:1;40917:9;40913:17;40906:47;40970:131;41096:4;40970:131;:::i;:::-;40962:139;;40689:419;;;:::o;41114:234::-;41254:34;41250:1;41242:6;41238:14;41231:58;41323:17;41318:2;41310:6;41306:15;41299:42;41114:234;:::o;41354:366::-;41496:3;41517:67;41581:2;41576:3;41517:67;:::i;:::-;41510:74;;41593:93;41682:3;41593:93;:::i;:::-;41711:2;41706:3;41702:12;41695:19;;41354:366;;;:::o;41726:419::-;41892:4;41930:2;41919:9;41915:18;41907:26;;41979:9;41973:4;41969:20;41965:1;41954:9;41950:17;41943:47;42007:131;42133:4;42007:131;:::i;:::-;41999:139;;41726:419;;;:::o;42151:148::-;42253:11;42290:3;42275:18;;42151:148;;;;:::o;42305:390::-;42411:3;42439:39;42472:5;42439:39;:::i;:::-;42494:89;42576:6;42571:3;42494:89;:::i;:::-;42487:96;;42592:65;42650:6;42645:3;42638:4;42631:5;42627:16;42592:65;:::i;:::-;42682:6;42677:3;42673:16;42666:23;;42415:280;42305:390;;;;:::o;42701:151::-;42841:3;42837:1;42829:6;42825:14;42818:27;42701:151;:::o;42858:400::-;43018:3;43039:84;43121:1;43116:3;43039:84;:::i;:::-;43032:91;;43132:93;43221:3;43132:93;:::i;:::-;43250:1;43245:3;43241:11;43234:18;;42858:400;;;:::o;43264:155::-;43404:7;43400:1;43392:6;43388:14;43381:31;43264:155;:::o;43425:400::-;43585:3;43606:84;43688:1;43683:3;43606:84;:::i;:::-;43599:91;;43699:93;43788:3;43699:93;:::i;:::-;43817:1;43812:3;43808:11;43801:18;;43425:400;;;:::o;43831:967::-;44213:3;44235:95;44326:3;44317:6;44235:95;:::i;:::-;44228:102;;44347:148;44491:3;44347:148;:::i;:::-;44340:155;;44512:95;44603:3;44594:6;44512:95;:::i;:::-;44505:102;;44624:148;44768:3;44624:148;:::i;:::-;44617:155;;44789:3;44782:10;;43831:967;;;;;:::o;44804:225::-;44944:34;44940:1;44932:6;44928:14;44921:58;45013:8;45008:2;45000:6;44996:15;44989:33;44804:225;:::o;45035:366::-;45177:3;45198:67;45262:2;45257:3;45198:67;:::i;:::-;45191:74;;45274:93;45363:3;45274:93;:::i;:::-;45392:2;45387:3;45383:12;45376:19;;45035:366;;;:::o;45407:419::-;45573:4;45611:2;45600:9;45596:18;45588:26;;45660:9;45654:4;45650:20;45646:1;45635:9;45631:17;45624:47;45688:131;45814:4;45688:131;:::i;:::-;45680:139;;45407:419;;;:::o;45832:332::-;45953:4;45991:2;45980:9;45976:18;45968:26;;46004:71;46072:1;46061:9;46057:17;46048:6;46004:71;:::i;:::-;46085:72;46153:2;46142:9;46138:18;46129:6;46085:72;:::i;:::-;45832:332;;;;;:::o;46170:137::-;46224:5;46255:6;46249:13;46240:22;;46271:30;46295:5;46271:30;:::i;:::-;46170:137;;;;:::o;46313:345::-;46380:6;46429:2;46417:9;46408:7;46404:23;46400:32;46397:119;;;46435:79;;:::i;:::-;46397:119;46555:1;46580:61;46633:7;46624:6;46613:9;46609:22;46580:61;:::i;:::-;46570:71;;46526:125;46313:345;;;;:::o;46664:220::-;46804:34;46800:1;46792:6;46788:14;46781:58;46873:3;46868:2;46860:6;46856:15;46849:28;46664:220;:::o;46890:366::-;47032:3;47053:67;47117:2;47112:3;47053:67;:::i;:::-;47046:74;;47129:93;47218:3;47129:93;:::i;:::-;47247:2;47242:3;47238:12;47231:19;;46890:366;;;:::o;47262:419::-;47428:4;47466:2;47455:9;47451:18;47443:26;;47515:9;47509:4;47505:20;47501:1;47490:9;47486:17;47479:47;47543:131;47669:4;47543:131;:::i;:::-;47535:139;;47262:419;;;:::o;47687:243::-;47827:34;47823:1;47815:6;47811:14;47804:58;47896:26;47891:2;47883:6;47879:15;47872:51;47687:243;:::o;47936:366::-;48078:3;48099:67;48163:2;48158:3;48099:67;:::i;:::-;48092:74;;48175:93;48264:3;48175:93;:::i;:::-;48293:2;48288:3;48284:12;48277:19;;47936:366;;;:::o;48308:419::-;48474:4;48512:2;48501:9;48497:18;48489:26;;48561:9;48555:4;48551:20;48547:1;48536:9;48532:17;48525:47;48589:131;48715:4;48589:131;:::i;:::-;48581:139;;48308:419;;;:::o;48733:236::-;48873:34;48869:1;48861:6;48857:14;48850:58;48942:19;48937:2;48929:6;48925:15;48918:44;48733:236;:::o;48975:366::-;49117:3;49138:67;49202:2;49197:3;49138:67;:::i;:::-;49131:74;;49214:93;49303:3;49214:93;:::i;:::-;49332:2;49327:3;49323:12;49316:19;;48975:366;;;:::o;49347:419::-;49513:4;49551:2;49540:9;49536:18;49528:26;;49600:9;49594:4;49590:20;49586:1;49575:9;49571:17;49564:47;49628:131;49754:4;49628:131;:::i;:::-;49620:139;;49347:419;;;:::o;49772:231::-;49912:34;49908:1;49900:6;49896:14;49889:58;49981:14;49976:2;49968:6;49964:15;49957:39;49772:231;:::o;50009:366::-;50151:3;50172:67;50236:2;50231:3;50172:67;:::i;:::-;50165:74;;50248:93;50337:3;50248:93;:::i;:::-;50366:2;50361:3;50357:12;50350:19;;50009:366;;;:::o;50381:419::-;50547:4;50585:2;50574:9;50570:18;50562:26;;50634:9;50628:4;50624:20;50620:1;50609:9;50605:17;50598:47;50662:131;50788:4;50662:131;:::i;:::-;50654:139;;50381:419;;;:::o;50806:175::-;50946:27;50942:1;50934:6;50930:14;50923:51;50806:175;:::o;50987:366::-;51129:3;51150:67;51214:2;51209:3;51150:67;:::i;:::-;51143:74;;51226:93;51315:3;51226:93;:::i;:::-;51344:2;51339:3;51335:12;51328:19;;50987:366;;;:::o;51359:419::-;51525:4;51563:2;51552:9;51548:18;51540:26;;51612:9;51606:4;51602:20;51598:1;51587:9;51583:17;51576:47;51640:131;51766:4;51640:131;:::i;:::-;51632:139;;51359:419;;;:::o;51784:180::-;51832:77;51829:1;51822:88;51929:4;51926:1;51919:15;51953:4;51950:1;51943:15;51970:185;52010:1;52027:20;52045:1;52027:20;:::i;:::-;52022:25;;52061:20;52079:1;52061:20;:::i;:::-;52056:25;;52100:1;52090:35;;52105:18;;:::i;:::-;52090:35;52147:1;52144;52140:9;52135:14;;51970:185;;;;:::o;52161:176::-;52193:1;52210:20;52228:1;52210:20;:::i;:::-;52205:25;;52244:20;52262:1;52244:20;:::i;:::-;52239:25;;52283:1;52273:35;;52288:18;;:::i;:::-;52273:35;52329:1;52326;52322:9;52317:14;;52161:176;;;;:::o;52343:180::-;52391:77;52388:1;52381:88;52488:4;52485:1;52478:15;52512:4;52509:1;52502:15;52529:237;52669:34;52665:1;52657:6;52653:14;52646:58;52738:20;52733:2;52725:6;52721:15;52714:45;52529:237;:::o;52772:366::-;52914:3;52935:67;52999:2;52994:3;52935:67;:::i;:::-;52928:74;;53011:93;53100:3;53011:93;:::i;:::-;53129:2;53124:3;53120:12;53113:19;;52772:366;;;:::o;53144:419::-;53310:4;53348:2;53337:9;53333:18;53325:26;;53397:9;53391:4;53387:20;53383:1;53372:9;53368:17;53361:47;53425:131;53551:4;53425:131;:::i;:::-;53417:139;;53144:419;;;:::o;53569:228::-;53709:34;53705:1;53697:6;53693:14;53686:58;53778:11;53773:2;53765:6;53761:15;53754:36;53569:228;:::o;53803:366::-;53945:3;53966:67;54030:2;54025:3;53966:67;:::i;:::-;53959:74;;54042:93;54131:3;54042:93;:::i;:::-;54160:2;54155:3;54151:12;54144:19;;53803:366;;;:::o;54175:419::-;54341:4;54379:2;54368:9;54364:18;54356:26;;54428:9;54422:4;54418:20;54414:1;54403:9;54399:17;54392:47;54456:131;54582:4;54456:131;:::i;:::-;54448:139;;54175:419;;;:::o;54600:223::-;54740:34;54736:1;54728:6;54724:14;54717:58;54809:6;54804:2;54796:6;54792:15;54785:31;54600:223;:::o;54829:366::-;54971:3;54992:67;55056:2;55051:3;54992:67;:::i;:::-;54985:74;;55068:93;55157:3;55068:93;:::i;:::-;55186:2;55181:3;55177:12;55170:19;;54829:366;;;:::o;55201:419::-;55367:4;55405:2;55394:9;55390:18;55382:26;;55454:9;55448:4;55444:20;55440:1;55429:9;55425:17;55418:47;55482:131;55608:4;55482:131;:::i;:::-;55474:139;;55201:419;;;:::o;55626:182::-;55766:34;55762:1;55754:6;55750:14;55743:58;55626:182;:::o;55814:366::-;55956:3;55977:67;56041:2;56036:3;55977:67;:::i;:::-;55970:74;;56053:93;56142:3;56053:93;:::i;:::-;56171:2;56166:3;56162:12;56155:19;;55814:366;;;:::o;56186:419::-;56352:4;56390:2;56379:9;56375:18;56367:26;;56439:9;56433:4;56429:20;56425:1;56414:9;56410:17;56403:47;56467:131;56593:4;56467:131;:::i;:::-;56459:139;;56186:419;;;:::o;56611:178::-;56751:30;56747:1;56739:6;56735:14;56728:54;56611:178;:::o;56795:366::-;56937:3;56958:67;57022:2;57017:3;56958:67;:::i;:::-;56951:74;;57034:93;57123:3;57034:93;:::i;:::-;57152:2;57147:3;57143:12;57136:19;;56795:366;;;:::o;57167:419::-;57333:4;57371:2;57360:9;57356:18;57348:26;;57420:9;57414:4;57410:20;57406:1;57395:9;57391:17;57384:47;57448:131;57574:4;57448:131;:::i;:::-;57440:139;;57167:419;;;:::o;57592:98::-;57643:6;57677:5;57671:12;57661:22;;57592:98;;;:::o;57696:168::-;57779:11;57813:6;57808:3;57801:19;57853:4;57848:3;57844:14;57829:29;;57696:168;;;;:::o;57870:373::-;57956:3;57984:38;58016:5;57984:38;:::i;:::-;58038:70;58101:6;58096:3;58038:70;:::i;:::-;58031:77;;58117:65;58175:6;58170:3;58163:4;58156:5;58152:16;58117:65;:::i;:::-;58207:29;58229:6;58207:29;:::i;:::-;58202:3;58198:39;58191:46;;57960:283;57870:373;;;;:::o;58249:640::-;58444:4;58482:3;58471:9;58467:19;58459:27;;58496:71;58564:1;58553:9;58549:17;58540:6;58496:71;:::i;:::-;58577:72;58645:2;58634:9;58630:18;58621:6;58577:72;:::i;:::-;58659;58727:2;58716:9;58712:18;58703:6;58659:72;:::i;:::-;58778:9;58772:4;58768:20;58763:2;58752:9;58748:18;58741:48;58806:76;58877:4;58868:6;58806:76;:::i;:::-;58798:84;;58249:640;;;;;;;:::o;58895:141::-;58951:5;58982:6;58976:13;58967:22;;58998:32;59024:5;58998:32;:::i;:::-;58895:141;;;;:::o;59042:349::-;59111:6;59160:2;59148:9;59139:7;59135:23;59131:32;59128:119;;;59166:79;;:::i;:::-;59128:119;59286:1;59311:63;59366:7;59357:6;59346:9;59342:22;59311:63;:::i;:::-;59301:73;;59257:127;59042:349;;;;:::o

Swarm Source

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

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