ETH Price: $3,393.10 (+1.84%)

Token

Quantum Creatures (QCC)
 

Overview

Max Total Supply

662 QCC

Holders

143

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
1 QCC
0x4d1cb1c6cd01b93735619fc1340e413659da1c44
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:
QuantumCreatures

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-08-25
*/

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)



pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}


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 External interface of AccessControlEnumerable declared to support ERC165 detection.
 */
interface IAccessControlEnumerable is IAccessControl {
    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) external view returns (address);

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) external view returns (uint256);
}

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.
 */
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) {
        return _values(set._inner);
    }

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

        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 on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

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

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

        assembly {
            result := store
        }

        return result;
    }
}

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 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;

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: 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 baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

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

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

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not 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 {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: 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 Approve `operator` to operate on all of `owner` tokens
     *
     * Emits a {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

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



/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

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

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}


pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

    /**
     * @dev 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` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * 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 override {
        super._beforeTokenTransfer(from, to, tokenId);

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

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

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

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

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

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

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

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

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

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

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

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

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


pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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


pragma solidity ^0.8.0;



/**
 * @dev Extension of {AccessControl} that allows enumerating the members of each role.
 */
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
    using EnumerableSet for EnumerableSet.AddressSet;

    mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;

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

    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {
        return _roleMembers[role].at(index);
    }

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {
        return _roleMembers[role].length();
    }

    /**
     * @dev Overload {_grantRole} to track enumerable memberships
     */
    function _grantRole(bytes32 role, address account) internal virtual override {
        super._grantRole(role, account);
        _roleMembers[role].add(account);
    }

    /**
     * @dev Overload {_revokeRole} to track enumerable memberships
     */
    function _revokeRole(bytes32 role, address account) internal virtual override {
        super._revokeRole(role, account);
        _roleMembers[role].remove(account);
    }
}


pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

        _;

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





pragma solidity ^0.8.4;


error ApprovalCallerNotOwnerNorApproved();
error ApprovalQueryForNonexistentToken();
error ApproveToCaller();
error ApprovalToCurrentOwner();
error BalanceQueryForZeroAddress();
error MintToZeroAddress();
error MintZeroQuantity();
error OwnerQueryForNonexistentToken();
error TransferCallerNotOwnerNorApproved();
error TransferFromIncorrectOwner();
error TransferToNonERC721ReceiverImplementer();
error TransferToZeroAddress();
error URIQueryForNonexistentToken();

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Compiler will pack this into a single 256bit word.
    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
    }

    // Compiler will pack this into a single 256bit word.
    struct AddressData {
        // Realistically, 2**64-1 is more than enough.
        uint64 balance;
        // Keeps track of mint count with minimal overhead for tokenomics.
        uint64 numberMinted;
        // Keeps track of burn count with minimal overhead for tokenomics.
        uint64 numberBurned;
        // For miscellaneous variable(s) pertaining to the address
        // (e.g. number of whitelist mint slots used).
        // If there are multiple variables, please pack them into a uint64.
        uint64 aux;
    }

    // The tokenId of the next token to be minted.
    uint256 internal _currentIndex;

    // The number of tokens burned.
    uint256 internal _burnCounter;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned. See _ownershipOf implementation for details.
    mapping(uint256 => TokenOwnership) internal _ownerships;

    // Mapping owner address to address data
    mapping(address => AddressData) private _addressData;

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

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _currentIndex = _startTokenId();
    }

    /**
     * To change the starting tokenId, please override this function.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 0;
    }

    /**
     * @dev Burned tokens are calculated here, use _totalMinted() if you want to count just minted tokens.
     */
    function totalSupply() public view returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than _currentIndex - _startTokenId() times
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view returns (uint256) {
        // Counter underflow is impossible as _currentIndex does not decrement,
        // and it is initialized to _startTokenId()
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

    /**
     * @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 override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return uint256(_addressData[owner].balance);
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return uint256(_addressData[owner].numberMinted);
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        return uint256(_addressData[owner].numberBurned);
    }

    /**
     * Returns the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return _addressData[owner].aux;
    }

    /**
     * Sets the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal {
        _addressData[owner].aux = aux;
    }

    /**
     * Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around in the collection over time.
     */
    function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr && curr < _currentIndex) {
                TokenOwnership memory ownership = _ownerships[curr];
                if (!ownership.burned) {
                    if (ownership.addr != address(0)) {
                        return ownership;
                    }
                    // Invariant:
                    // There will always be an ownership that has an address and is not burned
                    // before an ownership that does not have an address and is not burned.
                    // Hence, curr will not underflow.
                    while (true) {
                        curr--;
                        ownership = _ownerships[curr];
                        if (ownership.addr != address(0)) {
                            return ownership;
                        }
                    }
                }
            }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view override returns (address) {
        return _ownershipOf(tokenId).addr;
    }

    /**
     * @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) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

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

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

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721A.ownerOf(tokenId);
        if (to == owner) revert ApprovalToCurrentOwner();

        if (_msgSender() != owner && !isApprovedForAll(owner, _msgSender())) {
            revert ApprovalCallerNotOwnerNorApproved();
        }

        _approve(to, tokenId, owner);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

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

        _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 {
        _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 {
        _transfer(from, to, tokenId);
        if (to.isContract() && !_checkContractOnERC721Received(from, to, tokenId, _data)) {
            revert TransferToNonERC721ReceiverImplementer();
        }
    }

    /**
     * @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`),
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return _startTokenId() <= tokenId && tokenId < _currentIndex &&
            !_ownerships[tokenId].burned;
    }

    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, '');
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        _mint(to, quantity, _data, true);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _mint(
        address to,
        uint256 quantity,
        bytes memory _data,
        bool safe
    ) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            if (safe && to.isContract()) {
                do {
                    emit Transfer(address(0), to, updatedIndex);
                    if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (updatedIndex != end);
                // Reentrancy protection
                if (_currentIndex != startTokenId) revert();
            } else {
                do {
                    emit Transfer(address(0), to, updatedIndex++);
                } while (updatedIndex != end);
            }
            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * 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
    ) private {
        TokenOwnership memory prevOwnership = _ownershipOf(tokenId);

        if (prevOwnership.addr != from) revert TransferFromIncorrectOwner();

        bool isApprovedOrOwner = (_msgSender() == from ||
            isApprovedForAll(from, _msgSender()) ||
            getApproved(tokenId) == _msgSender());

        if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

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

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            _addressData[from].balance -= 1;
            _addressData[to].balance += 1;

            TokenOwnership storage currSlot = _ownerships[tokenId];
            currSlot.addr = to;
            currSlot.startTimestamp = uint64(block.timestamp);

            // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            TokenOwnership storage nextSlot = _ownerships[nextTokenId];
            if (nextSlot.addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId != _currentIndex) {
                    nextSlot.addr = from;
                    nextSlot.startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

        emit Transfer(from, to, tokenId);
        _afterTokenTransfers(from, to, tokenId, 1);
    }

    /**
     * @dev This is equivalent to _burn(tokenId, false)
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
        TokenOwnership memory prevOwnership = _ownershipOf(tokenId);

        address from = prevOwnership.addr;

        if (approvalCheck) {
            bool isApprovedOrOwner = (_msgSender() == from ||
                isApprovedForAll(from, _msgSender()) ||
                getApproved(tokenId) == _msgSender());

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

        _beforeTokenTransfers(from, address(0), tokenId, 1);

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

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            AddressData storage addressData = _addressData[from];
            addressData.balance -= 1;
            addressData.numberBurned += 1;

            // Keep track of who burned the token, and the timestamp of burning.
            TokenOwnership storage currSlot = _ownerships[tokenId];
            currSlot.addr = from;
            currSlot.startTimestamp = uint64(block.timestamp);
            currSlot.burned = true;

            // If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            TokenOwnership storage nextSlot = _ownerships[nextTokenId];
            if (nextSlot.addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId != _currentIndex) {
                    nextSlot.addr = from;
                    nextSlot.startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

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

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target 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 _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        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 TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    /**
     * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
     * And also called before burning one token.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * 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, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes
     * minting.
     * And also called after one token has been burned.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}
}



pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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



contract QuantumCreatures is ERC721A, ReentrancyGuard, Ownable {



    // Minting Variables
    uint256 public mintPrice = 0.002 ether;
    uint256 public maxPurchase = 5;
    uint256 public maxSupply = 777;
    address public ogAddress = 0x514D7700782FBb17d9B0E478c9B14329E1e23937;
    uint256 public maxPublicMints = 400;
    uint256 public publicMints = 0;
    uint256 public mintProceeds = 0;
    uint256 public royaltiesPercentage = 2; // Royalties percentage (e.g., 2%)

    struct TokenListing {
        bool isListed;
        address seller;
        uint256 price;
    }

    mapping(uint256 => TokenListing) public tokenListings;
    

    struct Bid {
        uint256 amount;
        address bidder;
        bool isActive;
    }

    mapping(uint256 => Bid) public bids;
    uint256 public numBids;


    struct Offer {
        uint256 amount;
        address bidder;
        bool isActive;
    }

    // Mapping from token ID to offer
    mapping(uint256 => Offer) public tokenOffers;



    mapping(address => uint256[]) public bidderToBids;


    // Sale Status
    bool public saleIsActive = false;
    bool public holderSaleIsActive = false;

    // mappings
    mapping(uint256 => bool) public claimedSpys;
    mapping(address => uint) public addressesThatMinted;


    // Metadata
    string _baseTokenURI = "ipfs://bafybeickbczbls54haseef4rmzy2aq2yqjpznmkjakksdak3ptizw6pviq/";


    // Events
    event SaleActivation(bool isActive);
    event HolderSaleActivation(bool isActive);

    constructor() ERC721A("Quantum Creatures", "QCC")  {

    }

    //Holder status validation
    function isSpyAvailable(uint256 _tokenId) public view returns(bool) {
        return claimedSpys[_tokenId] != true;
    }

    // Minting
    function ownerMint(address _to, uint256 _count) external onlyOwner {
        require(
            totalSupply() + _count <= maxSupply,
            "SOLD_OUT"
        );
        _safeMint(_to, _count);
    }

    function airdopMint(address[] calldata _to) external onlyOwner {
        for (uint256 i = 0; i < _to.length; i++) {
        _safeMint(_to[i], 1);
        }
    }


    function holderFreeMint(uint256[] calldata _spyIds, uint256 _count) external nonReentrant {
        require(holderSaleIsActive);
        require(
            _count == _spyIds.length,
            "INSUFFICIENT_OG_TOKENS"
        );
        require(
            totalSupply() + _count <= maxSupply,
            "SOLD_OUT"
        );

        ERC721Enumerable ogSpys = ERC721Enumerable(ogAddress);
        require(ogSpys.balanceOf(msg.sender) > 0);
        for (uint256 i = 0; i < _spyIds.length; i++) {
            require(isSpyAvailable(_spyIds[i]), "OG_ALREADY_CLAIMED");
            require(ogSpys.ownerOf(_spyIds[i]) == msg.sender, "NOT_SPY_OWNER");
            claimedSpys[_spyIds[i]] = true;
        }

        _safeMint(msg.sender, _count);
    }

    function mint(uint256 _count) external payable nonReentrant {
        require(saleIsActive, "SALE_INACTIVE");
        require(((addressesThatMinted[msg.sender] + _count) ) <= maxPurchase , "this would exceed mint max allowance");

        require(
            totalSupply() + _count <= maxSupply,
            "SOLD_OUT"
        );
        require(
            publicMints + _count <= maxPublicMints,
            "PUBLIC_SOLD_OUT"
        );
        require(
            mintPrice * _count <= msg.value,
            "INCORRECT_ETHER_VALUE"
        );
            publicMints += _count;
            mintProceeds += msg.value;
            _safeMint(msg.sender, _count);
            addressesThatMinted[msg.sender] += _count;
        }

    function setMaxPublicMints(uint256 _maxPublicMints) external onlyOwner {
        maxPublicMints = _maxPublicMints;
    }

    function toggleHolderSaleStatus() external onlyOwner {
        holderSaleIsActive = !holderSaleIsActive;
        emit HolderSaleActivation(holderSaleIsActive);
    }

    function toggleSaleStatus() external onlyOwner {
        saleIsActive = !saleIsActive;
        emit SaleActivation(saleIsActive);
    }

    function setMintPrice(uint256 _mintPrice) external onlyOwner {
        mintPrice = _mintPrice;
    }


    function setMaxPurchase(uint256 _maxPurchase) external onlyOwner {
        maxPurchase = _maxPurchase;
    }


    function getWalletOfOwner(address owner) external view returns (uint256[] memory) {
    unchecked {
        uint256[] memory a = new uint256[](balanceOf(owner));
        uint256 end = _currentIndex;
        uint256 tokenIdsIdx;
        address currOwnershipAddr;
        for (uint256 i; i < end; i++) {
            TokenOwnership memory ownership = _ownerships[i];
            if (ownership.burned) {
                continue;
            }
            if (ownership.addr != address(0)) {
                currOwnershipAddr = ownership.addr;
            }
            if (currOwnershipAddr == owner) {
                a[tokenIdsIdx++] = i;
            }
        }
        return a;
    }
    }

    function getTotalSupply() external view returns (uint256) {
        return totalSupply();
    }

    function setBaseURI(string memory baseURI) external onlyOwner {
        _baseTokenURI = baseURI;
    }

    function _baseURI() internal view virtual override returns (string memory) {
        return _baseTokenURI;
    }


   function tokenURI(uint256 tokenId) public view override returns (string memory){
        return string(abi.encodePacked(super.tokenURI(tokenId), ".json"));
        
    }


    function setRoyaltiesPercentage(uint256 _newRoyaltiesPercentage) external onlyOwner {
        require(_newRoyaltiesPercentage <= 10, "Invalid royalties percentage");
        royaltiesPercentage = _newRoyaltiesPercentage;
    }


    function acceptBid(uint256 _tokenId, uint256 _bidIndex) external nonReentrant {
        require(_bidIndex <= numBids, "Invalid bid index");


        Bid storage acceptedBid = bids[_bidIndex];

        require(acceptedBid.isActive, "Bid not active");
        require(msg.sender == ownerOf(_tokenId), "Token not owned by accepter");

        uint256 royaltiesAmount = (acceptedBid.amount * royaltiesPercentage) / 100;
        uint256 sellerAmount = acceptedBid.amount - royaltiesAmount;

        acceptedBid.isActive = false; // Mark bid as inactive

                // Update listing status to inactive
        if (tokenListings[_tokenId].isListed) {
            tokenListings[_tokenId].isListed = false;
        }

        safeTransferFrom(msg.sender, acceptedBid.bidder, _tokenId); 
        payable(msg.sender).transfer(sellerAmount); // Send funds to the seller
        payable(owner()).transfer(royaltiesAmount); // Send royalties to the owner
    }


    function buyToken(uint256 _tokenId) external payable nonReentrant {
        TokenListing storage listing = tokenListings[_tokenId];

        require(listing.isListed, "Token not listed");
        require(msg.value >= listing.price, "Insufficient payment");
        require(ownerOf(_tokenId) == listing.seller, "Token not owned by seller");

        uint256 royaltiesAmount = (msg.value * royaltiesPercentage) / 100;
        uint256 sellerAmount = msg.value - royaltiesAmount;

        tokenListings[_tokenId].isListed = false; // Mark listing as inactive
        _approve(msg.sender, _tokenId, listing.seller);
        safeTransferFrom(listing.seller, msg.sender, _tokenId); 
       


        payable(listing.seller).transfer(sellerAmount); // Send funds to the seller
        payable(owner()).transfer(royaltiesAmount); // Send royalties to the owner
    }

    function removeTokenListings(uint256[] memory _tokenIds) external {
        for (uint256 i = 0; i < _tokenIds.length; i++) {
            require(msg.sender == tokenListings[_tokenIds[i]].seller, "Not the seller");
            tokenListings[_tokenIds[i]].isListed = false; // Mark listing as inactive
        }
    }


    function listTokens(uint256[] memory _tokenIds, uint256[] memory _prices) external {
        require(_tokenIds.length == _prices.length, "Array lengths must match");

        for (uint256 i = 0; i < _tokenIds.length; i++) {
            require(ownerOf(_tokenIds[i]) == msg.sender, "Not the token owner");
            tokenListings[_tokenIds[i]] = TokenListing(true, msg.sender, _prices[i]);
        }
    }

    function placeBid() external payable {
        require(msg.value > 0, "Bid amount must be greater than 0");

        numBids++;
        bids[numBids] = Bid(msg.value, msg.sender, true);
        bidderToBids[msg.sender].push(numBids);
    }

    function withdrawBid(uint256 _bidIndex) external nonReentrant {
        Bid storage bid = bids[_bidIndex];
        require(bid.bidder == msg.sender, "Not your bid");
        require(bid.isActive, "Bid not active");

        bid.isActive = false;
        payable(msg.sender).transfer(bid.amount);
    }

    function withdrawMintProceeds () external onlyOwner nonReentrant {
        payable(owner()).transfer(mintProceeds);
        mintProceeds -= mintProceeds;
    }

    // Place an offer on a specific token
    function placeOffer(uint256 _tokenId) external payable nonReentrant {
        require(_exists(_tokenId), "Token does not exist");
        require(msg.value > 0, "Offer amount must be greater than 0");

        Offer storage existingOffer = tokenOffers[_tokenId];

        if (existingOffer.isActive) {
            // Ensure the new offer is higher than the existing one
            require(msg.value > existingOffer.amount, "Offer must be higher than existing offer");
            
            // Return ETH to the previous offer's placer
            payable(existingOffer.bidder).transfer(existingOffer.amount);
        }

        tokenOffers[_tokenId] = Offer(msg.value, msg.sender, true);
    }


    // Accept an offer for a specific token
    function acceptOffer(uint256 _tokenId) external nonReentrant {
        require(_exists(_tokenId), "Token does not exist");

        Offer storage acceptedOffer = tokenOffers[_tokenId];

        require(acceptedOffer.isActive, "No active offer");
        require(ownerOf(_tokenId) == msg.sender, "Token not owned by accepter");

        

        acceptedOffer.isActive = false; // Mark offer as inactive


        uint256 royaltiesAmount = (acceptedOffer.amount * royaltiesPercentage) / 100;
        uint256 sellerAmount = acceptedOffer.amount- royaltiesAmount;

                // Update listing status to inactive
        if (tokenListings[_tokenId].isListed) {
            tokenListings[_tokenId].isListed = false;
        }


        safeTransferFrom(msg.sender, acceptedOffer.bidder, _tokenId);
        payable(msg.sender).transfer(sellerAmount); // Send funds to the seller
        payable(owner()).transfer(royaltiesAmount); // Send royalties to the owner
    }


    // Remove an offer for a specific token
    function withdrawOffer(uint256 _tokenId) external nonReentrant {
        require(_exists(_tokenId), "Token does not exist");

        Offer storage offer = tokenOffers[_tokenId];
        require(offer.bidder == msg.sender, "Not the offer creator");
        require(offer.isActive, "Offer not active");

        offer.isActive = false;
        payable(msg.sender).transfer(offer.amount);
    }


    function getActiveOffersForWallet(address wallet) external view returns (uint256[] memory) {
        uint256 numActiveOffers = 0;

        for (uint256 tokenId = 0; tokenId < totalSupply(); tokenId++) {
            Offer storage offer = tokenOffers[tokenId];
            if (offer.isActive && offer.bidder == wallet) {
                numActiveOffers++;
            }
        }

        uint256[] memory activeOffers = new uint256[](numActiveOffers);
        uint256 activeOfferIndex = 0;

        for (uint256 tokenId = 0; tokenId < totalSupply(); tokenId++) {
            Offer storage offer = tokenOffers[tokenId];
            if (offer.isActive && offer.bidder == wallet) {
                activeOffers[activeOfferIndex] = tokenId;
                activeOfferIndex++;
            }
        }

        return activeOffers;
    }

    function getActiveListingsForWallet(address wallet) external view returns (uint256[] memory) {
        uint256 numActiveListings = 0;

        for (uint256 tokenId = 0; tokenId < totalSupply(); tokenId++) {
            TokenListing storage listing = tokenListings[tokenId];
            if (listing.isListed && listing.seller == wallet) {
                numActiveListings++;
            }
        }

        uint256[] memory activeListings = new uint256[](numActiveListings);
        uint256 activeListingIndex = 0;

        for (uint256 tokenId = 0; tokenId < totalSupply(); tokenId++) {
            TokenListing storage listing = tokenListings[tokenId];
            if (listing.isListed && listing.seller == wallet) {
                activeListings[activeListingIndex] = tokenId;
                activeListingIndex++;
            }
        }

        return activeListings;
    }

    function getActiveBidsForWallet(address wallet) external view returns (uint256[] memory) {
        uint256 numActiveBids = 0;

        for (uint256 bidIndex = 1; bidIndex <= numBids; bidIndex++) {
            Bid storage bid = bids[bidIndex];
            if (bid.isActive && bid.bidder == wallet) {
                numActiveBids++;
            }
        }

        uint256[] memory activeBids = new uint256[](numActiveBids);
        uint256 activeBidIndex = 0;

        for (uint256 bidIndex = 1; bidIndex <= numBids; bidIndex++) {
            Bid storage bid = bids[bidIndex];
            if (bid.isActive && bid.bidder == wallet) {
                activeBids[activeBidIndex] = bidIndex;
                activeBidIndex++;
            }
        }

        return activeBids;
    }

    function getAllActiveListings() external view returns (uint256[] memory) {
        uint256 numActiveListings = 0;

        for (uint256 tokenId = 0; tokenId < totalSupply(); tokenId++) {
            if (tokenListings[tokenId].isListed) {
                numActiveListings++;
            }
        }

        uint256[] memory activeListings = new uint256[](numActiveListings);
        uint256 activeListingIndex = 0;

        for (uint256 tokenId = 0; tokenId < totalSupply(); tokenId++) {
            if (tokenListings[tokenId].isListed) {
                activeListings[activeListingIndex] = tokenId;
                activeListingIndex++;
            }
        }

        return activeListings;
    }


    function getAllActiveOffers() external view returns (uint256[] memory) {
        uint256 numActiveOffers = 0;

        for (uint256 tokenId = 0; tokenId < totalSupply(); tokenId++) {
            if (tokenOffers[tokenId].isActive) {
                numActiveOffers++;
            }
        }

        uint256[] memory activeOffers = new uint256[](numActiveOffers);
        uint256 activeOfferIndex = 0;

        for (uint256 tokenId = 0; tokenId < totalSupply(); tokenId++) {
            if (tokenOffers[tokenId].isActive) {
                activeOffers[activeOfferIndex] = tokenId;
                activeOfferIndex++;
            }
        }

        return activeOffers;
    }


    function getAllActiveBids() external view returns (uint256[] memory) {
        uint256 numActiveBids = 0;

        for (uint256 bidIndex = 1; bidIndex <= numBids; bidIndex++) {
            if (bids[bidIndex].isActive) {
                numActiveBids++;
            }
        }

        uint256[] memory activeBids = new uint256[](numActiveBids);
        uint256 activeBidIndex = 0;

        for (uint256 bidIndex = 1; bidIndex <= numBids; bidIndex++) {
            if (bids[bidIndex].isActive) {
                activeBids[activeBidIndex] = bidIndex;
                activeBidIndex++;
            }
        }

        return activeBids;
    }



}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isActive","type":"bool"}],"name":"HolderSaleActivation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isActive","type":"bool"}],"name":"SaleActivation","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":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_bidIndex","type":"uint256"}],"name":"acceptBid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"acceptOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressesThatMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_to","type":"address[]"}],"name":"airdopMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","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":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"bidderToBids","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"bids","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"bidder","type":"address"},{"internalType":"bool","name":"isActive","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"buyToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"claimedSpys","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"getActiveBidsForWallet","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"getActiveListingsForWallet","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"getActiveOffersForWallet","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllActiveBids","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllActiveListings","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllActiveOffers","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"getWalletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_spyIds","type":"uint256[]"},{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"holderFreeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"holderSaleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"isSpyAvailable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_prices","type":"uint256[]"}],"name":"listTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxPublicMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPurchase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintProceeds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numBids","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ogAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"placeBid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"placeOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"publicMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"removeTokenListings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"royaltiesPercentage","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":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"uint256","name":"_maxPublicMints","type":"uint256"}],"name":"setMaxPublicMints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxPurchase","type":"uint256"}],"name":"setMaxPurchase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintPrice","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newRoyaltiesPercentage","type":"uint256"}],"name":"setRoyaltiesPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleHolderSaleStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleSaleStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenListings","outputs":[{"internalType":"bool","name":"isListed","type":"bool"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenOffers","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"bidder","type":"address"},{"internalType":"bool","name":"isActive","type":"bool"}],"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":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_bidIndex","type":"uint256"}],"name":"withdrawBid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawMintProceeds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"withdrawOffer","outputs":[],"stateMutability":"nonpayable","type":"function"}]

66071afd498d0000600a556005600b55610309600c55600d80546001600160a01b03191673514d7700782fbb17d9b0e478c9b14329e1e23937179055610190600e556000600f81905560105560026011556017805461ffff191690556101006040526043608081815290620043c260a039601a906200007f908262000208565b503480156200008d57600080fd5b50604051806040016040528060118152602001705175616e74756d2043726561747572657360781b8152506040518060400160405280600381526020016251434360e81b8152508160029081620000e5919062000208565b506003620000f4828262000208565b5060008055505060016008556200010b3362000111565b620002d4565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200018e57607f821691505b602082108103620001af57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200020357600081815260208120601f850160051c81016020861015620001de5750805b601f850160051c820191505b81811015620001ff57828155600101620001ea565b5050505b505050565b81516001600160401b0381111562000224576200022462000163565b6200023c8162000235845462000179565b84620001b5565b602080601f8311600181146200027457600084156200025b5750858301515b600019600386901b1c1916600185901b178555620001ff565b600085815260208120601f198616915b82811015620002a55788860151825594840194600190910190840162000284565b5085821015620002c45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6140de80620002e46000396000f3fe6080604052600436106103c25760003560e01c806380feb139116101f2578063c815729d1161010d578063eb857fab116100a0578063ecfc7ecc1161006f578063ecfc7ecc14610ba0578063f2fde38b14610ba8578063f4a0a52814610bc8578063fb7cf4a414610be857600080fd5b8063eb857fab14610b26578063eb8d244414610b46578063ebc3388214610b60578063ecad059714610b8057600080fd5b8063ce9ec0a6116100dc578063ce9ec0a614610abb578063d0d703d314610ad1578063d5abeb0114610af0578063e985e9c514610b0657600080fd5b8063c815729d14610a1c578063c87b56dd14610a3c578063ca03452714610a5c578063cafa8dfe14610aa557600080fd5b8063a0712d6811610185578063b88d4fde11610154578063b88d4fde14610964578063bd64ace514610984578063c4e41b22146109f1578063c7b0dcbc14610a0657600080fd5b8063a0712d68146108e4578063a22cb465146108f7578063a93fef3b14610917578063ab2fdb0c1461093757600080fd5b80639466d206116101c15780639466d2061461087957806395d89b4114610899578063977b055b146108ae5780639923b86a146108c457600080fd5b806380feb139146107fb5780638610f0451461081b5780638da5cb5b1461083b5780638e25d8b31461085957600080fd5b80632e8e02d4116102e2578063627fdeab11610275578063701e508411610244578063701e50841461079157806370a08231146107a657806371189742146107c6578063715018a6146107e657600080fd5b8063627fdeab146107255780636352211e146107455780636817c76c146107655780636af42d861461077b57600080fd5b80634423c5f1116102b15780634423c5f114610662578063484b973c146106d05780634b6bcbed146106f057806355f804b31461070557600080fd5b80632e8e02d4146105dd57806338cc6a311461060d578063393d9eab1461062d57806342842e0e1461064257600080fd5b806318160ddd1161035a57806323b872dd1161032957806323b872dd146105825780632474659a146105a2578063294bc0e7146105b55780632d296bf1146105ca57600080fd5b806318160ddd146104f35780631e0ba315146105165780631e47ebe2146105365780632336296a1461056c57600080fd5b806306fdde031161039657806306fdde0314610459578063081812fc1461047b578063095ea7b3146104b35780630eaaf4c8146104d357600080fd5b80623beca0146103c757806301ffc9a7146103f257806302e9d5e414610422578063049c5c4914610444575b600080fd5b3480156103d357600080fd5b506103dc610c08565b6040516103e9919061378c565b60405180910390f35b3480156103fe57600080fd5b5061041261040d3660046137e6565b610d1e565b60405190151581526020016103e9565b34801561042e57600080fd5b5061044261043d366004613803565b610d70565b005b34801561045057600080fd5b50610442610fac565b34801561046557600080fd5b5061046e611024565b6040516103e99190613875565b34801561048757600080fd5b5061049b610496366004613888565b6110b6565b6040516001600160a01b0390911681526020016103e9565b3480156104bf57600080fd5b506104426104ce3660046138b6565b6110fa565b3480156104df57600080fd5b506104426104ee366004613888565b611187565b3480156104ff57600080fd5b50600154600054035b6040519081526020016103e9565b34801561052257600080fd5b5061044261053136600461392d565b611299565b34801561054257600080fd5b50610412610551366004613888565b60009081526018602052604090205460ff1615156001141590565b34801561057857600080fd5b50610508600f5481565b34801561058e57600080fd5b5061044261059d366004613978565b61158e565b6104426105b0366004613888565b611599565b3480156105c157600080fd5b506103dc61176c565b6104426105d8366004613888565b611871565b3480156105e957600080fd5b506104126105f8366004613888565b60186020526000908152604090205460ff1681565b34801561061957600080fd5b506103dc6106283660046139b9565b611aa3565b34801561063957600080fd5b50610442611be4565b34801561064e57600080fd5b5061044261065d366004613978565b611c8f565b34801561066e57600080fd5b506106ab61067d366004613888565b601360205260009081526040902080546001909101546001600160a01b03811690600160a01b900460ff1683565b604080519384526001600160a01b0390921660208401521515908201526060016103e9565b3480156106dc57600080fd5b506104426106eb3660046138b6565b611caa565b3480156106fc57600080fd5b50610442611d1b565b34801561071157600080fd5b50610442610720366004613a73565b611d9d565b34801561073157600080fd5b506103dc6107403660046139b9565b611dd3565b34801561075157600080fd5b5061049b610760366004613888565b611efb565b34801561077157600080fd5b50610508600a5481565b34801561078757600080fd5b5061050860105481565b34801561079d57600080fd5b506103dc611f0d565b3480156107b257600080fd5b506105086107c13660046139b9565b612006565b3480156107d257600080fd5b506104426107e1366004613888565b612054565b3480156107f257600080fd5b50610442612083565b34801561080757600080fd5b50600d5461049b906001600160a01b031681565b34801561082757600080fd5b50610442610836366004613888565b6120b9565b34801561084757600080fd5b506009546001600160a01b031661049b565b34801561086557600080fd5b506103dc6108743660046139b9565b6121b5565b34801561088557600080fd5b50610442610894366004613888565b6122fc565b3480156108a557600080fd5b5061046e61237c565b3480156108ba57600080fd5b50610508600b5481565b3480156108d057600080fd5b506104426108df366004613abb565b61238b565b6104426108f2366004613888565b612403565b34801561090357600080fd5b50610442610912366004613afc565b61262a565b34801561092357600080fd5b50610442610932366004613888565b6126bf565b34801561094357600080fd5b506105086109523660046139b9565b60196020526000908152604090205481565b34801561097057600080fd5b5061044261097f366004613b3a565b6126ee565b34801561099057600080fd5b506109cc61099f366004613888565b6012602052600090815260409020805460019091015460ff82169161010090046001600160a01b03169083565b6040805193151584526001600160a01b039092166020840152908201526060016103e9565b3480156109fd57600080fd5b5061050861273f565b348015610a1257600080fd5b50610508600e5481565b348015610a2857600080fd5b50610442610a37366004613888565b612753565b348015610a4857600080fd5b5061046e610a57366004613888565b612914565b348015610a6857600080fd5b506106ab610a77366004613888565b601560205260009081526040902080546001909101546001600160a01b03811690600160a01b900460ff1683565b348015610ab157600080fd5b5061050860115481565b348015610ac757600080fd5b5061050860145481565b348015610add57600080fd5b5060175461041290610100900460ff1681565b348015610afc57600080fd5b50610508600c5481565b348015610b1257600080fd5b50610412610b21366004613bb9565b612945565b348015610b3257600080fd5b50610508610b413660046138b6565b612973565b348015610b5257600080fd5b506017546104129060ff1681565b348015610b6c57600080fd5b506103dc610b7b3660046139b9565b6129a4565b348015610b8c57600080fd5b50610442610b9b366004613c66565b612ae3565b610442612bd6565b348015610bb457600080fd5b50610442610bc33660046139b9565b612cca565b348015610bd457600080fd5b50610442610be3366004613888565b612d65565b348015610bf457600080fd5b50610442610c03366004613c9a565b612d94565b60606000805b60015460005403811015610c5d57600081815260156020526040902060010154600160a01b900460ff1615610c4b5781610c4781613d13565b9250505b80610c5581613d13565b915050610c0e565b506000816001600160401b03811115610c7857610c786139d6565b604051908082528060200260200182016040528015610ca1578160200160208202803683370190505b5090506000805b60015460005403811015610d1557600081815260156020526040902060010154600160a01b900460ff1615610d035780838381518110610cea57610cea613d2c565b602090810291909101015281610cff81613d13565b9250505b80610d0d81613d13565b915050610ca8565b50909392505050565b60006001600160e01b031982166380ac58cd60e01b1480610d4f57506001600160e01b03198216635b5e139f60e01b145b80610d6a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b600260085403610d9b5760405162461bcd60e51b8152600401610d9290613d42565b60405180910390fd5b6002600855601454811115610de65760405162461bcd60e51b8152602060048201526011602482015270092dcecc2d8d2c840c4d2c840d2dcc8caf607b1b6044820152606401610d92565b60008181526013602052604090206001810154600160a01b900460ff16610e405760405162461bcd60e51b815260206004820152600e60248201526d426964206e6f742061637469766560901b6044820152606401610d92565b610e4983611efb565b6001600160a01b0316336001600160a01b031614610ea95760405162461bcd60e51b815260206004820152601b60248201527f546f6b656e206e6f74206f776e656420627920616363657074657200000000006044820152606401610d92565b600060646011548360000154610ebf9190613d79565b610ec99190613da6565b90506000818360000154610edd9190613dba565b60018401805460ff60a01b1916905560008681526012602052604090205490915060ff1615610f1d576000858152601260205260409020805460ff191690555b6001830154610f379033906001600160a01b031687611c8f565b604051339082156108fc029083906000818181858888f19350505050158015610f64573d6000803e3d6000fd5b506009546040516001600160a01b039091169083156108fc029084906000818181858888f19350505050158015610f9f573d6000803e3d6000fd5b5050600160085550505050565b6009546001600160a01b03163314610fd65760405162461bcd60e51b8152600401610d9290613dcd565b6017805460ff8082161560ff1990921682179092556040519116151581527f58655b75d3df612fe99ead00dbf0812d415d35078fe06217a94c0818bb13967f906020015b60405180910390a1565b60606002805461103390613e02565b80601f016020809104026020016040519081016040528092919081815260200182805461105f90613e02565b80156110ac5780601f10611081576101008083540402835291602001916110ac565b820191906000526020600020905b81548152906001019060200180831161108f57829003601f168201915b5050505050905090565b60006110c182612f34565b6110de576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600061110582611efb565b9050806001600160a01b0316836001600160a01b0316036111395760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b0382161480159061115957506111578133612945565b155b15611177576040516367d9dca160e11b815260040160405180910390fd5b611182838383612f5f565b505050565b6002600854036111a95760405162461bcd60e51b8152600401610d9290613d42565b6002600855600081815260136020526040902060018101546001600160a01b031633146112075760405162461bcd60e51b815260206004820152600c60248201526b139bdd081e5bdd5c88189a5960a21b6044820152606401610d92565b6001810154600160a01b900460ff166112535760405162461bcd60e51b815260206004820152600e60248201526d426964206e6f742061637469766560901b6044820152606401610d92565b60018101805460ff60a01b191690558054604051339180156108fc02916000818181858888f1935050505015801561128f573d6000803e3d6000fd5b5050600160085550565b6002600854036112bb5760405162461bcd60e51b8152600401610d9290613d42565b6002600855601754610100900460ff166112d457600080fd5b80821461131c5760405162461bcd60e51b8152602060048201526016602482015275494e53554646494349454e545f4f475f544f4b454e5360501b6044820152606401610d92565b600c548161132d6001546000540390565b6113379190613e3c565b11156113555760405162461bcd60e51b8152600401610d9290613e4f565b600d546040516370a0823160e01b81523360048201526001600160a01b039091169060009082906370a0823190602401602060405180830381865afa1580156113a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c69190613e71565b116113d057600080fd5b60005b83811015611578576114128585838181106113f0576113f0613d2c565b9050602002013560009081526018602052604090205460ff1615156001141590565b6114535760405162461bcd60e51b815260206004820152601260248201527113d1d7d053149150511657d0d3105253515160721b6044820152606401610d92565b336001600160a01b038316636352211e87878581811061147557611475613d2c565b905060200201356040518263ffffffff1660e01b815260040161149a91815260200190565b602060405180830381865afa1580156114b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114db9190613e8a565b6001600160a01b0316146115215760405162461bcd60e51b815260206004820152600d60248201526c2727aa2fa9a82cafa7aba722a960991b6044820152606401610d92565b60016018600087878581811061153957611539613d2c565b90506020020135815260200190815260200160002060006101000a81548160ff021916908315150217905550808061157090613d13565b9150506113d3565b506115833383612fbb565b505060016008555050565b611182838383612fd5565b6002600854036115bb5760405162461bcd60e51b8152600401610d9290613d42565b60026008556115c981612f34565b6115e55760405162461bcd60e51b8152600401610d9290613ea7565b600034116116415760405162461bcd60e51b815260206004820152602360248201527f4f6666657220616d6f756e74206d75737420626520677265617465722074686160448201526206e20360ec1b6064820152608401610d92565b60008181526015602052604090206001810154600160a01b900460ff161561170357805434116116c45760405162461bcd60e51b815260206004820152602860248201527f4f66666572206d75737420626520686967686572207468616e2065786973746960448201526737339037b33332b960c11b6064820152608401610d92565b600181015481546040516001600160a01b039092169181156108fc0291906000818181858888f19350505050158015611701573d6000803e3d6000fd5b505b5060408051606081018252348152336020808301918252600183850181815260009687526015909252939094209151825551908201805493511515600160a01b026001600160a81b03199094166001600160a01b03929092169190911792909217909155600855565b6060600060015b60145481116117bd57600081815260136020526040902060010154600160a01b900460ff16156117ab57816117a781613d13565b9250505b806117b581613d13565b915050611773565b506000816001600160401b038111156117d8576117d86139d6565b604051908082528060200260200182016040528015611801578160200160208202803683370190505b509050600060015b6014548111610d1557600081815260136020526040902060010154600160a01b900460ff161561185f578083838151811061184657611846613d2c565b60209081029190910101528161185b81613d13565b9250505b8061186981613d13565b915050611809565b6002600854036118935760405162461bcd60e51b8152600401610d9290613d42565b60026008556000818152601260205260409020805460ff166118ea5760405162461bcd60e51b815260206004820152601060248201526f151bdad95b881b9bdd081b1a5cdd195960821b6044820152606401610d92565b80600101543410156119355760405162461bcd60e51b8152602060048201526014602482015273125b9cdd59999a58da595b9d081c185e5b595b9d60621b6044820152606401610d92565b805461010090046001600160a01b031661194e83611efb565b6001600160a01b0316146119a45760405162461bcd60e51b815260206004820152601960248201527f546f6b656e206e6f74206f776e65642062792073656c6c6572000000000000006044820152606401610d92565b60006064601154346119b69190613d79565b6119c09190613da6565b905060006119ce8234613dba565b6000858152601260205260409020805460ff191690558354909150611a04903390869061010090046001600160a01b0316612f5f565b8254611a1f9061010090046001600160a01b03163386611c8f565b82546040516101009091046001600160a01b0316906108fc8315029083906000818181858888f19350505050158015611a5c573d6000803e3d6000fd5b506009546040516001600160a01b039091169083156108fc029084906000818181858888f19350505050158015611a97573d6000803e3d6000fd5b50506001600855505050565b60606000805b60015460005403811015611b0d576000818152601260205260409020805460ff168015611ae7575080546001600160a01b0386811661010090920416145b15611afa5782611af681613d13565b9350505b5080611b0581613d13565b915050611aa9565b506000816001600160401b03811115611b2857611b286139d6565b604051908082528060200260200182016040528015611b51578160200160208202803683370190505b5090506000805b60015460005403811015611bda576000818152601260205260409020805460ff168015611b96575080546001600160a01b0388811661010090920416145b15611bc75781848481518110611bae57611bae613d2c565b602090810291909101015282611bc381613d13565b9350505b5080611bd281613d13565b915050611b58565b5090949350505050565b6009546001600160a01b03163314611c0e5760405162461bcd60e51b8152600401610d9290613dcd565b600260085403611c305760405162461bcd60e51b8152600401610d9290613d42565b60026008556009546010546040516001600160a01b039092169181156108fc0291906000818181858888f19350505050158015611c71573d6000803e3d6000fd5b5060108054906000611c838380613dba565b90915550506001600855565b611182838383604051806020016040528060008152506126ee565b6009546001600160a01b03163314611cd45760405162461bcd60e51b8152600401610d9290613dcd565b600c5481611ce56001546000540390565b611cef9190613e3c565b1115611d0d5760405162461bcd60e51b8152600401610d9290613e4f565b611d178282612fbb565b5050565b6009546001600160a01b03163314611d455760405162461bcd60e51b8152600401610d9290613dcd565b6017805460ff610100808304821615810261ff001990931692909217928390556040517fbc5b3e222a18d52c6bd2bc19880c605e9a1b50b11689f0315d149d12a26230fa9361101a9390049091161515815260200190565b6009546001600160a01b03163314611dc75760405162461bcd60e51b8152600401610d9290613dcd565b601a611d178282613f23565b60606000611de083612006565b6001600160401b03811115611df757611df76139d6565b604051908082528060200260200182016040528015611e20578160200160208202803683370190505b506000805491925080805b83811015611ef057600081815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161580159282019290925290611e925750611ee8565b80516001600160a01b031615611ea757805192505b876001600160a01b0316836001600160a01b031603611ee65781868580600101965081518110611ed957611ed9613d2c565b6020026020010181815250505b505b600101611e2b565b509295945050505050565b6000611f06826131c3565b5192915050565b60606000805b60015460005403811015611f585760008181526012602052604090205460ff1615611f465781611f4281613d13565b9250505b80611f5081613d13565b915050611f13565b506000816001600160401b03811115611f7357611f736139d6565b604051908082528060200260200182016040528015611f9c578160200160208202803683370190505b5090506000805b60015460005403811015610d155760008181526012602052604090205460ff1615611ff45780838381518110611fdb57611fdb613d2c565b602090810291909101015281611ff081613d13565b9250505b80611ffe81613d13565b915050611fa3565b60006001600160a01b03821661202f576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6009546001600160a01b0316331461207e5760405162461bcd60e51b8152600401610d9290613dcd565b600b55565b6009546001600160a01b031633146120ad5760405162461bcd60e51b8152600401610d9290613dcd565b6120b760006132dd565b565b6002600854036120db5760405162461bcd60e51b8152600401610d9290613d42565b60026008556120e981612f34565b6121055760405162461bcd60e51b8152600401610d9290613ea7565b600081815260156020526040902060018101546001600160a01b031633146121675760405162461bcd60e51b81526020600482015260156024820152742737ba103a34329037b33332b91031b932b0ba37b960591b6044820152606401610d92565b6001810154600160a01b900460ff166112535760405162461bcd60e51b815260206004820152601060248201526f4f66666572206e6f742061637469766560801b6044820152606401610d92565b60606000805b600154600054038110156122275760008181526015602052604090206001810154600160a01b900460ff168015612201575060018101546001600160a01b038681169116145b15612214578261221081613d13565b9350505b508061221f81613d13565b9150506121bb565b506000816001600160401b03811115612242576122426139d6565b60405190808252806020026020018201604052801561226b578160200160208202803683370190505b5090506000805b60015460005403811015611bda5760008181526015602052604090206001810154600160a01b900460ff1680156122b8575060018101546001600160a01b038881169116145b156122e957818484815181106122d0576122d0613d2c565b6020908102919091010152826122e581613d13565b9350505b50806122f481613d13565b915050612272565b6009546001600160a01b031633146123265760405162461bcd60e51b8152600401610d9290613dcd565b600a8111156123775760405162461bcd60e51b815260206004820152601c60248201527f496e76616c696420726f79616c746965732070657263656e74616765000000006044820152606401610d92565b601155565b60606003805461103390613e02565b6009546001600160a01b031633146123b55760405162461bcd60e51b8152600401610d9290613dcd565b60005b81811015611182576123f18383838181106123d5576123d5613d2c565b90506020020160208101906123ea91906139b9565b6001612fbb565b806123fb81613d13565b9150506123b8565b6002600854036124255760405162461bcd60e51b8152600401610d9290613d42565b600260085560175460ff1661246c5760405162461bcd60e51b815260206004820152600d60248201526c53414c455f494e41435449564560981b6044820152606401610d92565b600b543360009081526019602052604090205461248a908390613e3c565b11156124e45760405162461bcd60e51b8152602060048201526024808201527f7468697320776f756c6420657863656564206d696e74206d617820616c6c6f77604482015263616e636560e01b6064820152608401610d92565b600c54816124f56001546000540390565b6124ff9190613e3c565b111561251d5760405162461bcd60e51b8152600401610d9290613e4f565b600e5481600f5461252e9190613e3c565b111561256e5760405162461bcd60e51b815260206004820152600f60248201526e141550931250d7d4d3d31117d3d555608a1b6044820152606401610d92565b3481600a5461257d9190613d79565b11156125c35760405162461bcd60e51b8152602060048201526015602482015274494e434f52524543545f45544845525f56414c554560581b6044820152606401610d92565b80600f60008282546125d59190613e3c565b9250508190555034601060008282546125ee9190613e3c565b909155506125fe90503382612fbb565b336000908152601960205260408120805483929061261d908490613e3c565b9091555050600160085550565b336001600160a01b038316036126535760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6009546001600160a01b031633146126e95760405162461bcd60e51b8152600401610d9290613dcd565b600e55565b6126f9848484612fd5565b6001600160a01b0383163b1515801561271b57506127198484848461332f565b155b15612739576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b600061274e6001546000540390565b905090565b6002600854036127755760405162461bcd60e51b8152600401610d9290613d42565b600260085561278381612f34565b61279f5760405162461bcd60e51b8152600401610d9290613ea7565b60008181526015602052604090206001810154600160a01b900460ff166127fa5760405162461bcd60e51b815260206004820152600f60248201526e27379030b1ba34bb329037b33332b960891b6044820152606401610d92565b3361280483611efb565b6001600160a01b03161461285a5760405162461bcd60e51b815260206004820152601b60248201527f546f6b656e206e6f74206f776e656420627920616363657074657200000000006044820152606401610d92565b60018101805460ff60a01b19169055601154815460009160649161287e9190613d79565b6128889190613da6565b9050600081836000015461289c9190613dba565b60008581526012602052604090205490915060ff16156128cd576000848152601260205260409020805460ff191690555b60018301546128e79033906001600160a01b031686611c8f565b604051339082156108fc029083906000818181858888f19350505050158015611a5c573d6000803e3d6000fd5b606061291f8261341b565b60405160200161292f9190613fe2565b6040516020818303038152906040529050919050565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b6016602052816000526040600020818154811061298f57600080fd5b90600052602060002001600091509150505481565b6060600060015b6014548111612a125760008181526013602052604090206001810154600160a01b900460ff1680156129ec575060018101546001600160a01b038681169116145b156129ff57826129fb81613d13565b9350505b5080612a0a81613d13565b9150506129ab565b506000816001600160401b03811115612a2d57612a2d6139d6565b604051908082528060200260200182016040528015612a56578160200160208202803683370190505b509050600060015b6014548111611bda5760008181526013602052604090206001810154600160a01b900460ff168015612a9f575060018101546001600160a01b038881169116145b15612ad05781848481518110612ab757612ab7613d2c565b602090810291909101015282612acc81613d13565b9350505b5080612adb81613d13565b915050612a5e565b60005b8151811015611d175760126000838381518110612b0557612b05613d2c565b6020026020010151815260200190815260200160002060000160019054906101000a90046001600160a01b03166001600160a01b0316336001600160a01b031614612b835760405162461bcd60e51b815260206004820152600e60248201526d2737ba103a34329039b2b63632b960911b6044820152606401610d92565b600060126000848481518110612b9b57612b9b613d2c565b6020908102919091018101518252810191909152604001600020805460ff191691151591909117905580612bce81613d13565b915050612ae6565b60003411612c305760405162461bcd60e51b815260206004820152602160248201527f42696420616d6f756e74206d7573742062652067726561746572207468616e206044820152600360fc1b6064820152608401610d92565b60148054906000612c4083613d13565b909155505060408051606081018252348152336020808301828152600184860181815260148054600090815260138652888120975188559351968301805492511515600160a01b026001600160a81b03199093166001600160a01b039890981697909717919091179095559281526016825293842092548354928301845592845290922090910155565b6009546001600160a01b03163314612cf45760405162461bcd60e51b8152600401610d9290613dcd565b6001600160a01b038116612d595760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d92565b612d62816132dd565b50565b6009546001600160a01b03163314612d8f5760405162461bcd60e51b8152600401610d9290613dcd565b600a55565b8051825114612de55760405162461bcd60e51b815260206004820152601860248201527f4172726179206c656e67746873206d757374206d6174636800000000000000006044820152606401610d92565b60005b825181101561118257336001600160a01b0316612e1d848381518110612e1057612e10613d2c565b6020026020010151611efb565b6001600160a01b031614612e695760405162461bcd60e51b81526020600482015260136024820152722737ba103a3432903a37b5b2b71037bbb732b960691b6044820152606401610d92565b6040518060600160405280600115158152602001336001600160a01b03168152602001838381518110612e9e57612e9e613d2c565b602002602001015181525060126000858481518110612ebf57612ebf613d2c565b602090810291909101810151825281810192909252604090810160002083518154938501516001600160a81b0319909416901515610100600160a81b031916176101006001600160a01b0390941693909302929092178255919091015160019091015580612f2c81613d13565b915050612de8565b6000805482108015610d6a575050600090815260046020526040902054600160e01b900460ff161590565b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b611d1782826040518060200160405280600081525061349f565b6000612fe0826131c3565b9050836001600160a01b031681600001516001600160a01b0316146130175760405162a1148160e81b815260040160405180910390fd5b6000336001600160a01b038616148061303557506130358533612945565b80613050575033613045846110b6565b6001600160a01b0316145b90508061307057604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b03841661309757604051633a954ecd60e21b815260040160405180910390fd5b6130a360008487612f5f565b6001600160a01b038581166000908152600560209081526040808320805467ffffffffffffffff198082166001600160401b0392831660001901831617909255898616808652838620805493841693831660019081018416949094179055898652600490945282852080546001600160e01b031916909417600160a01b4290921691909102178355870180845292208054919390911661317757600054821461317757805460208601516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038a16171781555b50505082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b5050505050565b6040805160608101825260008082526020820181905291810191909152816000548110156132c457600081815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161515918101829052906132c25780516001600160a01b031615613259579392505050565b5060001901600081815260046020908152604091829020825160608101845290546001600160a01b038116808352600160a01b82046001600160401b031693830193909352600160e01b900460ff16151592810192909252156132bd579392505050565b613259565b505b604051636f96cda160e11b815260040160405180910390fd5b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a029061336490339089908890889060040161400b565b6020604051808303816000875af192505050801561339f575060408051601f3d908101601f1916820190925261339c91810190614048565b60015b6133fd573d8080156133cd576040519150601f19603f3d011682016040523d82523d6000602084013e6133d2565b606091505b5080516000036133f5576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b606061342682612f34565b61344357604051630a14c4b560e41b815260040160405180910390fd5b600061344d6134ac565b9050805160000361346d5760405180602001604052806000815250613498565b80613477846134bb565b604051602001613488929190614065565b6040516020818303038152906040525b9392505050565b61118283838360016135bb565b6060601a805461103390613e02565b6060816000036134e25750506040805180820190915260018152600360fc1b602082015290565b8160005b811561350c57806134f681613d13565b91506135059050600a83613da6565b91506134e6565b6000816001600160401b03811115613526576135266139d6565b6040519080825280601f01601f191660200182016040528015613550576020820181803683370190505b5090505b841561341357613565600183613dba565b9150613572600a86614094565b61357d906030613e3c565b60f81b81838151811061359257613592613d2c565b60200101906001600160f81b031916908160001a9053506135b4600a86613da6565b9450613554565b6000546001600160a01b0385166135e457604051622e076360e81b815260040160405180910390fd5b836000036136055760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038516600081815260056020908152604080832080546fffffffffffffffffffffffffffffffff1981166001600160401b038083168c0181169182176801000000000000000067ffffffffffffffff1990941690921783900481168c01811690920217909155858452600490925290912080546001600160e01b031916909217600160a01b4290921691909102179055808085018380156136b657506001600160a01b0387163b15155b1561373e575b60405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4613707600088848060010195508861332f565b613724576040516368d2bf6b60e11b815260040160405180910390fd5b8082036136bc57826000541461373957600080fd5b613783565b5b6040516001830192906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a480820361373f575b506000556131bc565b6020808252825182820181905260009190848201906040850190845b818110156137c4578351835292840192918401916001016137a8565b50909695505050505050565b6001600160e01b031981168114612d6257600080fd5b6000602082840312156137f857600080fd5b8135613498816137d0565b6000806040838503121561381657600080fd5b50508035926020909101359150565b60005b83811015613840578181015183820152602001613828565b50506000910152565b60008151808452613861816020860160208601613825565b601f01601f19169290920160200192915050565b6020815260006134986020830184613849565b60006020828403121561389a57600080fd5b5035919050565b6001600160a01b0381168114612d6257600080fd5b600080604083850312156138c957600080fd5b82356138d4816138a1565b946020939093013593505050565b60008083601f8401126138f457600080fd5b5081356001600160401b0381111561390b57600080fd5b6020830191508360208260051b850101111561392657600080fd5b9250929050565b60008060006040848603121561394257600080fd5b83356001600160401b0381111561395857600080fd5b613964868287016138e2565b909790965060209590950135949350505050565b60008060006060848603121561398d57600080fd5b8335613998816138a1565b925060208401356139a8816138a1565b929592945050506040919091013590565b6000602082840312156139cb57600080fd5b8135613498816138a1565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613a1457613a146139d6565b604052919050565b60006001600160401b03831115613a3557613a356139d6565b613a48601f8401601f19166020016139ec565b9050828152838383011115613a5c57600080fd5b828260208301376000602084830101529392505050565b600060208284031215613a8557600080fd5b81356001600160401b03811115613a9b57600080fd5b8201601f81018413613aac57600080fd5b61341384823560208401613a1c565b60008060208385031215613ace57600080fd5b82356001600160401b03811115613ae457600080fd5b613af0858286016138e2565b90969095509350505050565b60008060408385031215613b0f57600080fd5b8235613b1a816138a1565b915060208301358015158114613b2f57600080fd5b809150509250929050565b60008060008060808587031215613b5057600080fd5b8435613b5b816138a1565b93506020850135613b6b816138a1565b92506040850135915060608501356001600160401b03811115613b8d57600080fd5b8501601f81018713613b9e57600080fd5b613bad87823560208401613a1c565b91505092959194509250565b60008060408385031215613bcc57600080fd5b8235613bd7816138a1565b91506020830135613b2f816138a1565b600082601f830112613bf857600080fd5b813560206001600160401b03821115613c1357613c136139d6565b8160051b613c228282016139ec565b9283528481018201928281019087851115613c3c57600080fd5b83870192505b84831015613c5b57823582529183019190830190613c42565b979650505050505050565b600060208284031215613c7857600080fd5b81356001600160401b03811115613c8e57600080fd5b61341384828501613be7565b60008060408385031215613cad57600080fd5b82356001600160401b0380821115613cc457600080fd5b613cd086838701613be7565b93506020850135915080821115613ce657600080fd5b50613cf385828601613be7565b9150509250929050565b634e487b7160e01b600052601160045260246000fd5b600060018201613d2557613d25613cfd565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b8082028115828204841417610d6a57610d6a613cfd565b634e487b7160e01b600052601260045260246000fd5b600082613db557613db5613d90565b500490565b81810381811115610d6a57610d6a613cfd565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600181811c90821680613e1657607f821691505b602082108103613e3657634e487b7160e01b600052602260045260246000fd5b50919050565b80820180821115610d6a57610d6a613cfd565b60208082526008908201526714d3d31117d3d55560c21b604082015260600190565b600060208284031215613e8357600080fd5b5051919050565b600060208284031215613e9c57600080fd5b8151613498816138a1565b602080825260149082015273151bdad95b88191bd95cc81b9bdd08195e1a5cdd60621b604082015260600190565b601f82111561118257600081815260208120601f850160051c81016020861015613efc5750805b601f850160051c820191505b81811015613f1b57828155600101613f08565b505050505050565b81516001600160401b03811115613f3c57613f3c6139d6565b613f5081613f4a8454613e02565b84613ed5565b602080601f831160018114613f855760008415613f6d5750858301515b600019600386901b1c1916600185901b178555613f1b565b600085815260208120601f198616915b82811015613fb457888601518255948401946001909101908401613f95565b5085821015613fd25787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008251613ff4818460208701613825565b64173539b7b760d91b920191825250600501919050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061403e90830184613849565b9695505050505050565b60006020828403121561405a57600080fd5b8151613498816137d0565b60008351614077818460208801613825565b83519083019061408b818360208801613825565b01949350505050565b6000826140a3576140a3613d90565b50069056fea2646970667358221220b3f299bebe369f5dbe40975b0cd50c25b722583c00144eee651f9d27b50addea64736f6c63430008110033697066733a2f2f62616679626569636b62637a626c73353468617365656634726d7a793261713279716a707a6e6d6b6a616b6b7364616b337074697a7736707669712f

Deployed Bytecode

0x6080604052600436106103c25760003560e01c806380feb139116101f2578063c815729d1161010d578063eb857fab116100a0578063ecfc7ecc1161006f578063ecfc7ecc14610ba0578063f2fde38b14610ba8578063f4a0a52814610bc8578063fb7cf4a414610be857600080fd5b8063eb857fab14610b26578063eb8d244414610b46578063ebc3388214610b60578063ecad059714610b8057600080fd5b8063ce9ec0a6116100dc578063ce9ec0a614610abb578063d0d703d314610ad1578063d5abeb0114610af0578063e985e9c514610b0657600080fd5b8063c815729d14610a1c578063c87b56dd14610a3c578063ca03452714610a5c578063cafa8dfe14610aa557600080fd5b8063a0712d6811610185578063b88d4fde11610154578063b88d4fde14610964578063bd64ace514610984578063c4e41b22146109f1578063c7b0dcbc14610a0657600080fd5b8063a0712d68146108e4578063a22cb465146108f7578063a93fef3b14610917578063ab2fdb0c1461093757600080fd5b80639466d206116101c15780639466d2061461087957806395d89b4114610899578063977b055b146108ae5780639923b86a146108c457600080fd5b806380feb139146107fb5780638610f0451461081b5780638da5cb5b1461083b5780638e25d8b31461085957600080fd5b80632e8e02d4116102e2578063627fdeab11610275578063701e508411610244578063701e50841461079157806370a08231146107a657806371189742146107c6578063715018a6146107e657600080fd5b8063627fdeab146107255780636352211e146107455780636817c76c146107655780636af42d861461077b57600080fd5b80634423c5f1116102b15780634423c5f114610662578063484b973c146106d05780634b6bcbed146106f057806355f804b31461070557600080fd5b80632e8e02d4146105dd57806338cc6a311461060d578063393d9eab1461062d57806342842e0e1461064257600080fd5b806318160ddd1161035a57806323b872dd1161032957806323b872dd146105825780632474659a146105a2578063294bc0e7146105b55780632d296bf1146105ca57600080fd5b806318160ddd146104f35780631e0ba315146105165780631e47ebe2146105365780632336296a1461056c57600080fd5b806306fdde031161039657806306fdde0314610459578063081812fc1461047b578063095ea7b3146104b35780630eaaf4c8146104d357600080fd5b80623beca0146103c757806301ffc9a7146103f257806302e9d5e414610422578063049c5c4914610444575b600080fd5b3480156103d357600080fd5b506103dc610c08565b6040516103e9919061378c565b60405180910390f35b3480156103fe57600080fd5b5061041261040d3660046137e6565b610d1e565b60405190151581526020016103e9565b34801561042e57600080fd5b5061044261043d366004613803565b610d70565b005b34801561045057600080fd5b50610442610fac565b34801561046557600080fd5b5061046e611024565b6040516103e99190613875565b34801561048757600080fd5b5061049b610496366004613888565b6110b6565b6040516001600160a01b0390911681526020016103e9565b3480156104bf57600080fd5b506104426104ce3660046138b6565b6110fa565b3480156104df57600080fd5b506104426104ee366004613888565b611187565b3480156104ff57600080fd5b50600154600054035b6040519081526020016103e9565b34801561052257600080fd5b5061044261053136600461392d565b611299565b34801561054257600080fd5b50610412610551366004613888565b60009081526018602052604090205460ff1615156001141590565b34801561057857600080fd5b50610508600f5481565b34801561058e57600080fd5b5061044261059d366004613978565b61158e565b6104426105b0366004613888565b611599565b3480156105c157600080fd5b506103dc61176c565b6104426105d8366004613888565b611871565b3480156105e957600080fd5b506104126105f8366004613888565b60186020526000908152604090205460ff1681565b34801561061957600080fd5b506103dc6106283660046139b9565b611aa3565b34801561063957600080fd5b50610442611be4565b34801561064e57600080fd5b5061044261065d366004613978565b611c8f565b34801561066e57600080fd5b506106ab61067d366004613888565b601360205260009081526040902080546001909101546001600160a01b03811690600160a01b900460ff1683565b604080519384526001600160a01b0390921660208401521515908201526060016103e9565b3480156106dc57600080fd5b506104426106eb3660046138b6565b611caa565b3480156106fc57600080fd5b50610442611d1b565b34801561071157600080fd5b50610442610720366004613a73565b611d9d565b34801561073157600080fd5b506103dc6107403660046139b9565b611dd3565b34801561075157600080fd5b5061049b610760366004613888565b611efb565b34801561077157600080fd5b50610508600a5481565b34801561078757600080fd5b5061050860105481565b34801561079d57600080fd5b506103dc611f0d565b3480156107b257600080fd5b506105086107c13660046139b9565b612006565b3480156107d257600080fd5b506104426107e1366004613888565b612054565b3480156107f257600080fd5b50610442612083565b34801561080757600080fd5b50600d5461049b906001600160a01b031681565b34801561082757600080fd5b50610442610836366004613888565b6120b9565b34801561084757600080fd5b506009546001600160a01b031661049b565b34801561086557600080fd5b506103dc6108743660046139b9565b6121b5565b34801561088557600080fd5b50610442610894366004613888565b6122fc565b3480156108a557600080fd5b5061046e61237c565b3480156108ba57600080fd5b50610508600b5481565b3480156108d057600080fd5b506104426108df366004613abb565b61238b565b6104426108f2366004613888565b612403565b34801561090357600080fd5b50610442610912366004613afc565b61262a565b34801561092357600080fd5b50610442610932366004613888565b6126bf565b34801561094357600080fd5b506105086109523660046139b9565b60196020526000908152604090205481565b34801561097057600080fd5b5061044261097f366004613b3a565b6126ee565b34801561099057600080fd5b506109cc61099f366004613888565b6012602052600090815260409020805460019091015460ff82169161010090046001600160a01b03169083565b6040805193151584526001600160a01b039092166020840152908201526060016103e9565b3480156109fd57600080fd5b5061050861273f565b348015610a1257600080fd5b50610508600e5481565b348015610a2857600080fd5b50610442610a37366004613888565b612753565b348015610a4857600080fd5b5061046e610a57366004613888565b612914565b348015610a6857600080fd5b506106ab610a77366004613888565b601560205260009081526040902080546001909101546001600160a01b03811690600160a01b900460ff1683565b348015610ab157600080fd5b5061050860115481565b348015610ac757600080fd5b5061050860145481565b348015610add57600080fd5b5060175461041290610100900460ff1681565b348015610afc57600080fd5b50610508600c5481565b348015610b1257600080fd5b50610412610b21366004613bb9565b612945565b348015610b3257600080fd5b50610508610b413660046138b6565b612973565b348015610b5257600080fd5b506017546104129060ff1681565b348015610b6c57600080fd5b506103dc610b7b3660046139b9565b6129a4565b348015610b8c57600080fd5b50610442610b9b366004613c66565b612ae3565b610442612bd6565b348015610bb457600080fd5b50610442610bc33660046139b9565b612cca565b348015610bd457600080fd5b50610442610be3366004613888565b612d65565b348015610bf457600080fd5b50610442610c03366004613c9a565b612d94565b60606000805b60015460005403811015610c5d57600081815260156020526040902060010154600160a01b900460ff1615610c4b5781610c4781613d13565b9250505b80610c5581613d13565b915050610c0e565b506000816001600160401b03811115610c7857610c786139d6565b604051908082528060200260200182016040528015610ca1578160200160208202803683370190505b5090506000805b60015460005403811015610d1557600081815260156020526040902060010154600160a01b900460ff1615610d035780838381518110610cea57610cea613d2c565b602090810291909101015281610cff81613d13565b9250505b80610d0d81613d13565b915050610ca8565b50909392505050565b60006001600160e01b031982166380ac58cd60e01b1480610d4f57506001600160e01b03198216635b5e139f60e01b145b80610d6a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b600260085403610d9b5760405162461bcd60e51b8152600401610d9290613d42565b60405180910390fd5b6002600855601454811115610de65760405162461bcd60e51b8152602060048201526011602482015270092dcecc2d8d2c840c4d2c840d2dcc8caf607b1b6044820152606401610d92565b60008181526013602052604090206001810154600160a01b900460ff16610e405760405162461bcd60e51b815260206004820152600e60248201526d426964206e6f742061637469766560901b6044820152606401610d92565b610e4983611efb565b6001600160a01b0316336001600160a01b031614610ea95760405162461bcd60e51b815260206004820152601b60248201527f546f6b656e206e6f74206f776e656420627920616363657074657200000000006044820152606401610d92565b600060646011548360000154610ebf9190613d79565b610ec99190613da6565b90506000818360000154610edd9190613dba565b60018401805460ff60a01b1916905560008681526012602052604090205490915060ff1615610f1d576000858152601260205260409020805460ff191690555b6001830154610f379033906001600160a01b031687611c8f565b604051339082156108fc029083906000818181858888f19350505050158015610f64573d6000803e3d6000fd5b506009546040516001600160a01b039091169083156108fc029084906000818181858888f19350505050158015610f9f573d6000803e3d6000fd5b5050600160085550505050565b6009546001600160a01b03163314610fd65760405162461bcd60e51b8152600401610d9290613dcd565b6017805460ff8082161560ff1990921682179092556040519116151581527f58655b75d3df612fe99ead00dbf0812d415d35078fe06217a94c0818bb13967f906020015b60405180910390a1565b60606002805461103390613e02565b80601f016020809104026020016040519081016040528092919081815260200182805461105f90613e02565b80156110ac5780601f10611081576101008083540402835291602001916110ac565b820191906000526020600020905b81548152906001019060200180831161108f57829003601f168201915b5050505050905090565b60006110c182612f34565b6110de576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600061110582611efb565b9050806001600160a01b0316836001600160a01b0316036111395760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b0382161480159061115957506111578133612945565b155b15611177576040516367d9dca160e11b815260040160405180910390fd5b611182838383612f5f565b505050565b6002600854036111a95760405162461bcd60e51b8152600401610d9290613d42565b6002600855600081815260136020526040902060018101546001600160a01b031633146112075760405162461bcd60e51b815260206004820152600c60248201526b139bdd081e5bdd5c88189a5960a21b6044820152606401610d92565b6001810154600160a01b900460ff166112535760405162461bcd60e51b815260206004820152600e60248201526d426964206e6f742061637469766560901b6044820152606401610d92565b60018101805460ff60a01b191690558054604051339180156108fc02916000818181858888f1935050505015801561128f573d6000803e3d6000fd5b5050600160085550565b6002600854036112bb5760405162461bcd60e51b8152600401610d9290613d42565b6002600855601754610100900460ff166112d457600080fd5b80821461131c5760405162461bcd60e51b8152602060048201526016602482015275494e53554646494349454e545f4f475f544f4b454e5360501b6044820152606401610d92565b600c548161132d6001546000540390565b6113379190613e3c565b11156113555760405162461bcd60e51b8152600401610d9290613e4f565b600d546040516370a0823160e01b81523360048201526001600160a01b039091169060009082906370a0823190602401602060405180830381865afa1580156113a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c69190613e71565b116113d057600080fd5b60005b83811015611578576114128585838181106113f0576113f0613d2c565b9050602002013560009081526018602052604090205460ff1615156001141590565b6114535760405162461bcd60e51b815260206004820152601260248201527113d1d7d053149150511657d0d3105253515160721b6044820152606401610d92565b336001600160a01b038316636352211e87878581811061147557611475613d2c565b905060200201356040518263ffffffff1660e01b815260040161149a91815260200190565b602060405180830381865afa1580156114b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114db9190613e8a565b6001600160a01b0316146115215760405162461bcd60e51b815260206004820152600d60248201526c2727aa2fa9a82cafa7aba722a960991b6044820152606401610d92565b60016018600087878581811061153957611539613d2c565b90506020020135815260200190815260200160002060006101000a81548160ff021916908315150217905550808061157090613d13565b9150506113d3565b506115833383612fbb565b505060016008555050565b611182838383612fd5565b6002600854036115bb5760405162461bcd60e51b8152600401610d9290613d42565b60026008556115c981612f34565b6115e55760405162461bcd60e51b8152600401610d9290613ea7565b600034116116415760405162461bcd60e51b815260206004820152602360248201527f4f6666657220616d6f756e74206d75737420626520677265617465722074686160448201526206e20360ec1b6064820152608401610d92565b60008181526015602052604090206001810154600160a01b900460ff161561170357805434116116c45760405162461bcd60e51b815260206004820152602860248201527f4f66666572206d75737420626520686967686572207468616e2065786973746960448201526737339037b33332b960c11b6064820152608401610d92565b600181015481546040516001600160a01b039092169181156108fc0291906000818181858888f19350505050158015611701573d6000803e3d6000fd5b505b5060408051606081018252348152336020808301918252600183850181815260009687526015909252939094209151825551908201805493511515600160a01b026001600160a81b03199094166001600160a01b03929092169190911792909217909155600855565b6060600060015b60145481116117bd57600081815260136020526040902060010154600160a01b900460ff16156117ab57816117a781613d13565b9250505b806117b581613d13565b915050611773565b506000816001600160401b038111156117d8576117d86139d6565b604051908082528060200260200182016040528015611801578160200160208202803683370190505b509050600060015b6014548111610d1557600081815260136020526040902060010154600160a01b900460ff161561185f578083838151811061184657611846613d2c565b60209081029190910101528161185b81613d13565b9250505b8061186981613d13565b915050611809565b6002600854036118935760405162461bcd60e51b8152600401610d9290613d42565b60026008556000818152601260205260409020805460ff166118ea5760405162461bcd60e51b815260206004820152601060248201526f151bdad95b881b9bdd081b1a5cdd195960821b6044820152606401610d92565b80600101543410156119355760405162461bcd60e51b8152602060048201526014602482015273125b9cdd59999a58da595b9d081c185e5b595b9d60621b6044820152606401610d92565b805461010090046001600160a01b031661194e83611efb565b6001600160a01b0316146119a45760405162461bcd60e51b815260206004820152601960248201527f546f6b656e206e6f74206f776e65642062792073656c6c6572000000000000006044820152606401610d92565b60006064601154346119b69190613d79565b6119c09190613da6565b905060006119ce8234613dba565b6000858152601260205260409020805460ff191690558354909150611a04903390869061010090046001600160a01b0316612f5f565b8254611a1f9061010090046001600160a01b03163386611c8f565b82546040516101009091046001600160a01b0316906108fc8315029083906000818181858888f19350505050158015611a5c573d6000803e3d6000fd5b506009546040516001600160a01b039091169083156108fc029084906000818181858888f19350505050158015611a97573d6000803e3d6000fd5b50506001600855505050565b60606000805b60015460005403811015611b0d576000818152601260205260409020805460ff168015611ae7575080546001600160a01b0386811661010090920416145b15611afa5782611af681613d13565b9350505b5080611b0581613d13565b915050611aa9565b506000816001600160401b03811115611b2857611b286139d6565b604051908082528060200260200182016040528015611b51578160200160208202803683370190505b5090506000805b60015460005403811015611bda576000818152601260205260409020805460ff168015611b96575080546001600160a01b0388811661010090920416145b15611bc75781848481518110611bae57611bae613d2c565b602090810291909101015282611bc381613d13565b9350505b5080611bd281613d13565b915050611b58565b5090949350505050565b6009546001600160a01b03163314611c0e5760405162461bcd60e51b8152600401610d9290613dcd565b600260085403611c305760405162461bcd60e51b8152600401610d9290613d42565b60026008556009546010546040516001600160a01b039092169181156108fc0291906000818181858888f19350505050158015611c71573d6000803e3d6000fd5b5060108054906000611c838380613dba565b90915550506001600855565b611182838383604051806020016040528060008152506126ee565b6009546001600160a01b03163314611cd45760405162461bcd60e51b8152600401610d9290613dcd565b600c5481611ce56001546000540390565b611cef9190613e3c565b1115611d0d5760405162461bcd60e51b8152600401610d9290613e4f565b611d178282612fbb565b5050565b6009546001600160a01b03163314611d455760405162461bcd60e51b8152600401610d9290613dcd565b6017805460ff610100808304821615810261ff001990931692909217928390556040517fbc5b3e222a18d52c6bd2bc19880c605e9a1b50b11689f0315d149d12a26230fa9361101a9390049091161515815260200190565b6009546001600160a01b03163314611dc75760405162461bcd60e51b8152600401610d9290613dcd565b601a611d178282613f23565b60606000611de083612006565b6001600160401b03811115611df757611df76139d6565b604051908082528060200260200182016040528015611e20578160200160208202803683370190505b506000805491925080805b83811015611ef057600081815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161580159282019290925290611e925750611ee8565b80516001600160a01b031615611ea757805192505b876001600160a01b0316836001600160a01b031603611ee65781868580600101965081518110611ed957611ed9613d2c565b6020026020010181815250505b505b600101611e2b565b509295945050505050565b6000611f06826131c3565b5192915050565b60606000805b60015460005403811015611f585760008181526012602052604090205460ff1615611f465781611f4281613d13565b9250505b80611f5081613d13565b915050611f13565b506000816001600160401b03811115611f7357611f736139d6565b604051908082528060200260200182016040528015611f9c578160200160208202803683370190505b5090506000805b60015460005403811015610d155760008181526012602052604090205460ff1615611ff45780838381518110611fdb57611fdb613d2c565b602090810291909101015281611ff081613d13565b9250505b80611ffe81613d13565b915050611fa3565b60006001600160a01b03821661202f576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6009546001600160a01b0316331461207e5760405162461bcd60e51b8152600401610d9290613dcd565b600b55565b6009546001600160a01b031633146120ad5760405162461bcd60e51b8152600401610d9290613dcd565b6120b760006132dd565b565b6002600854036120db5760405162461bcd60e51b8152600401610d9290613d42565b60026008556120e981612f34565b6121055760405162461bcd60e51b8152600401610d9290613ea7565b600081815260156020526040902060018101546001600160a01b031633146121675760405162461bcd60e51b81526020600482015260156024820152742737ba103a34329037b33332b91031b932b0ba37b960591b6044820152606401610d92565b6001810154600160a01b900460ff166112535760405162461bcd60e51b815260206004820152601060248201526f4f66666572206e6f742061637469766560801b6044820152606401610d92565b60606000805b600154600054038110156122275760008181526015602052604090206001810154600160a01b900460ff168015612201575060018101546001600160a01b038681169116145b15612214578261221081613d13565b9350505b508061221f81613d13565b9150506121bb565b506000816001600160401b03811115612242576122426139d6565b60405190808252806020026020018201604052801561226b578160200160208202803683370190505b5090506000805b60015460005403811015611bda5760008181526015602052604090206001810154600160a01b900460ff1680156122b8575060018101546001600160a01b038881169116145b156122e957818484815181106122d0576122d0613d2c565b6020908102919091010152826122e581613d13565b9350505b50806122f481613d13565b915050612272565b6009546001600160a01b031633146123265760405162461bcd60e51b8152600401610d9290613dcd565b600a8111156123775760405162461bcd60e51b815260206004820152601c60248201527f496e76616c696420726f79616c746965732070657263656e74616765000000006044820152606401610d92565b601155565b60606003805461103390613e02565b6009546001600160a01b031633146123b55760405162461bcd60e51b8152600401610d9290613dcd565b60005b81811015611182576123f18383838181106123d5576123d5613d2c565b90506020020160208101906123ea91906139b9565b6001612fbb565b806123fb81613d13565b9150506123b8565b6002600854036124255760405162461bcd60e51b8152600401610d9290613d42565b600260085560175460ff1661246c5760405162461bcd60e51b815260206004820152600d60248201526c53414c455f494e41435449564560981b6044820152606401610d92565b600b543360009081526019602052604090205461248a908390613e3c565b11156124e45760405162461bcd60e51b8152602060048201526024808201527f7468697320776f756c6420657863656564206d696e74206d617820616c6c6f77604482015263616e636560e01b6064820152608401610d92565b600c54816124f56001546000540390565b6124ff9190613e3c565b111561251d5760405162461bcd60e51b8152600401610d9290613e4f565b600e5481600f5461252e9190613e3c565b111561256e5760405162461bcd60e51b815260206004820152600f60248201526e141550931250d7d4d3d31117d3d555608a1b6044820152606401610d92565b3481600a5461257d9190613d79565b11156125c35760405162461bcd60e51b8152602060048201526015602482015274494e434f52524543545f45544845525f56414c554560581b6044820152606401610d92565b80600f60008282546125d59190613e3c565b9250508190555034601060008282546125ee9190613e3c565b909155506125fe90503382612fbb565b336000908152601960205260408120805483929061261d908490613e3c565b9091555050600160085550565b336001600160a01b038316036126535760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6009546001600160a01b031633146126e95760405162461bcd60e51b8152600401610d9290613dcd565b600e55565b6126f9848484612fd5565b6001600160a01b0383163b1515801561271b57506127198484848461332f565b155b15612739576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b600061274e6001546000540390565b905090565b6002600854036127755760405162461bcd60e51b8152600401610d9290613d42565b600260085561278381612f34565b61279f5760405162461bcd60e51b8152600401610d9290613ea7565b60008181526015602052604090206001810154600160a01b900460ff166127fa5760405162461bcd60e51b815260206004820152600f60248201526e27379030b1ba34bb329037b33332b960891b6044820152606401610d92565b3361280483611efb565b6001600160a01b03161461285a5760405162461bcd60e51b815260206004820152601b60248201527f546f6b656e206e6f74206f776e656420627920616363657074657200000000006044820152606401610d92565b60018101805460ff60a01b19169055601154815460009160649161287e9190613d79565b6128889190613da6565b9050600081836000015461289c9190613dba565b60008581526012602052604090205490915060ff16156128cd576000848152601260205260409020805460ff191690555b60018301546128e79033906001600160a01b031686611c8f565b604051339082156108fc029083906000818181858888f19350505050158015611a5c573d6000803e3d6000fd5b606061291f8261341b565b60405160200161292f9190613fe2565b6040516020818303038152906040529050919050565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b6016602052816000526040600020818154811061298f57600080fd5b90600052602060002001600091509150505481565b6060600060015b6014548111612a125760008181526013602052604090206001810154600160a01b900460ff1680156129ec575060018101546001600160a01b038681169116145b156129ff57826129fb81613d13565b9350505b5080612a0a81613d13565b9150506129ab565b506000816001600160401b03811115612a2d57612a2d6139d6565b604051908082528060200260200182016040528015612a56578160200160208202803683370190505b509050600060015b6014548111611bda5760008181526013602052604090206001810154600160a01b900460ff168015612a9f575060018101546001600160a01b038881169116145b15612ad05781848481518110612ab757612ab7613d2c565b602090810291909101015282612acc81613d13565b9350505b5080612adb81613d13565b915050612a5e565b60005b8151811015611d175760126000838381518110612b0557612b05613d2c565b6020026020010151815260200190815260200160002060000160019054906101000a90046001600160a01b03166001600160a01b0316336001600160a01b031614612b835760405162461bcd60e51b815260206004820152600e60248201526d2737ba103a34329039b2b63632b960911b6044820152606401610d92565b600060126000848481518110612b9b57612b9b613d2c565b6020908102919091018101518252810191909152604001600020805460ff191691151591909117905580612bce81613d13565b915050612ae6565b60003411612c305760405162461bcd60e51b815260206004820152602160248201527f42696420616d6f756e74206d7573742062652067726561746572207468616e206044820152600360fc1b6064820152608401610d92565b60148054906000612c4083613d13565b909155505060408051606081018252348152336020808301828152600184860181815260148054600090815260138652888120975188559351968301805492511515600160a01b026001600160a81b03199093166001600160a01b039890981697909717919091179095559281526016825293842092548354928301845592845290922090910155565b6009546001600160a01b03163314612cf45760405162461bcd60e51b8152600401610d9290613dcd565b6001600160a01b038116612d595760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d92565b612d62816132dd565b50565b6009546001600160a01b03163314612d8f5760405162461bcd60e51b8152600401610d9290613dcd565b600a55565b8051825114612de55760405162461bcd60e51b815260206004820152601860248201527f4172726179206c656e67746873206d757374206d6174636800000000000000006044820152606401610d92565b60005b825181101561118257336001600160a01b0316612e1d848381518110612e1057612e10613d2c565b6020026020010151611efb565b6001600160a01b031614612e695760405162461bcd60e51b81526020600482015260136024820152722737ba103a3432903a37b5b2b71037bbb732b960691b6044820152606401610d92565b6040518060600160405280600115158152602001336001600160a01b03168152602001838381518110612e9e57612e9e613d2c565b602002602001015181525060126000858481518110612ebf57612ebf613d2c565b602090810291909101810151825281810192909252604090810160002083518154938501516001600160a81b0319909416901515610100600160a81b031916176101006001600160a01b0390941693909302929092178255919091015160019091015580612f2c81613d13565b915050612de8565b6000805482108015610d6a575050600090815260046020526040902054600160e01b900460ff161590565b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b611d1782826040518060200160405280600081525061349f565b6000612fe0826131c3565b9050836001600160a01b031681600001516001600160a01b0316146130175760405162a1148160e81b815260040160405180910390fd5b6000336001600160a01b038616148061303557506130358533612945565b80613050575033613045846110b6565b6001600160a01b0316145b90508061307057604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b03841661309757604051633a954ecd60e21b815260040160405180910390fd5b6130a360008487612f5f565b6001600160a01b038581166000908152600560209081526040808320805467ffffffffffffffff198082166001600160401b0392831660001901831617909255898616808652838620805493841693831660019081018416949094179055898652600490945282852080546001600160e01b031916909417600160a01b4290921691909102178355870180845292208054919390911661317757600054821461317757805460208601516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038a16171781555b50505082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b5050505050565b6040805160608101825260008082526020820181905291810191909152816000548110156132c457600081815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161515918101829052906132c25780516001600160a01b031615613259579392505050565b5060001901600081815260046020908152604091829020825160608101845290546001600160a01b038116808352600160a01b82046001600160401b031693830193909352600160e01b900460ff16151592810192909252156132bd579392505050565b613259565b505b604051636f96cda160e11b815260040160405180910390fd5b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a029061336490339089908890889060040161400b565b6020604051808303816000875af192505050801561339f575060408051601f3d908101601f1916820190925261339c91810190614048565b60015b6133fd573d8080156133cd576040519150601f19603f3d011682016040523d82523d6000602084013e6133d2565b606091505b5080516000036133f5576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b606061342682612f34565b61344357604051630a14c4b560e41b815260040160405180910390fd5b600061344d6134ac565b9050805160000361346d5760405180602001604052806000815250613498565b80613477846134bb565b604051602001613488929190614065565b6040516020818303038152906040525b9392505050565b61118283838360016135bb565b6060601a805461103390613e02565b6060816000036134e25750506040805180820190915260018152600360fc1b602082015290565b8160005b811561350c57806134f681613d13565b91506135059050600a83613da6565b91506134e6565b6000816001600160401b03811115613526576135266139d6565b6040519080825280601f01601f191660200182016040528015613550576020820181803683370190505b5090505b841561341357613565600183613dba565b9150613572600a86614094565b61357d906030613e3c565b60f81b81838151811061359257613592613d2c565b60200101906001600160f81b031916908160001a9053506135b4600a86613da6565b9450613554565b6000546001600160a01b0385166135e457604051622e076360e81b815260040160405180910390fd5b836000036136055760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038516600081815260056020908152604080832080546fffffffffffffffffffffffffffffffff1981166001600160401b038083168c0181169182176801000000000000000067ffffffffffffffff1990941690921783900481168c01811690920217909155858452600490925290912080546001600160e01b031916909217600160a01b4290921691909102179055808085018380156136b657506001600160a01b0387163b15155b1561373e575b60405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4613707600088848060010195508861332f565b613724576040516368d2bf6b60e11b815260040160405180910390fd5b8082036136bc57826000541461373957600080fd5b613783565b5b6040516001830192906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a480820361373f575b506000556131bc565b6020808252825182820181905260009190848201906040850190845b818110156137c4578351835292840192918401916001016137a8565b50909695505050505050565b6001600160e01b031981168114612d6257600080fd5b6000602082840312156137f857600080fd5b8135613498816137d0565b6000806040838503121561381657600080fd5b50508035926020909101359150565b60005b83811015613840578181015183820152602001613828565b50506000910152565b60008151808452613861816020860160208601613825565b601f01601f19169290920160200192915050565b6020815260006134986020830184613849565b60006020828403121561389a57600080fd5b5035919050565b6001600160a01b0381168114612d6257600080fd5b600080604083850312156138c957600080fd5b82356138d4816138a1565b946020939093013593505050565b60008083601f8401126138f457600080fd5b5081356001600160401b0381111561390b57600080fd5b6020830191508360208260051b850101111561392657600080fd5b9250929050565b60008060006040848603121561394257600080fd5b83356001600160401b0381111561395857600080fd5b613964868287016138e2565b909790965060209590950135949350505050565b60008060006060848603121561398d57600080fd5b8335613998816138a1565b925060208401356139a8816138a1565b929592945050506040919091013590565b6000602082840312156139cb57600080fd5b8135613498816138a1565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613a1457613a146139d6565b604052919050565b60006001600160401b03831115613a3557613a356139d6565b613a48601f8401601f19166020016139ec565b9050828152838383011115613a5c57600080fd5b828260208301376000602084830101529392505050565b600060208284031215613a8557600080fd5b81356001600160401b03811115613a9b57600080fd5b8201601f81018413613aac57600080fd5b61341384823560208401613a1c565b60008060208385031215613ace57600080fd5b82356001600160401b03811115613ae457600080fd5b613af0858286016138e2565b90969095509350505050565b60008060408385031215613b0f57600080fd5b8235613b1a816138a1565b915060208301358015158114613b2f57600080fd5b809150509250929050565b60008060008060808587031215613b5057600080fd5b8435613b5b816138a1565b93506020850135613b6b816138a1565b92506040850135915060608501356001600160401b03811115613b8d57600080fd5b8501601f81018713613b9e57600080fd5b613bad87823560208401613a1c565b91505092959194509250565b60008060408385031215613bcc57600080fd5b8235613bd7816138a1565b91506020830135613b2f816138a1565b600082601f830112613bf857600080fd5b813560206001600160401b03821115613c1357613c136139d6565b8160051b613c228282016139ec565b9283528481018201928281019087851115613c3c57600080fd5b83870192505b84831015613c5b57823582529183019190830190613c42565b979650505050505050565b600060208284031215613c7857600080fd5b81356001600160401b03811115613c8e57600080fd5b61341384828501613be7565b60008060408385031215613cad57600080fd5b82356001600160401b0380821115613cc457600080fd5b613cd086838701613be7565b93506020850135915080821115613ce657600080fd5b50613cf385828601613be7565b9150509250929050565b634e487b7160e01b600052601160045260246000fd5b600060018201613d2557613d25613cfd565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b8082028115828204841417610d6a57610d6a613cfd565b634e487b7160e01b600052601260045260246000fd5b600082613db557613db5613d90565b500490565b81810381811115610d6a57610d6a613cfd565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600181811c90821680613e1657607f821691505b602082108103613e3657634e487b7160e01b600052602260045260246000fd5b50919050565b80820180821115610d6a57610d6a613cfd565b60208082526008908201526714d3d31117d3d55560c21b604082015260600190565b600060208284031215613e8357600080fd5b5051919050565b600060208284031215613e9c57600080fd5b8151613498816138a1565b602080825260149082015273151bdad95b88191bd95cc81b9bdd08195e1a5cdd60621b604082015260600190565b601f82111561118257600081815260208120601f850160051c81016020861015613efc5750805b601f850160051c820191505b81811015613f1b57828155600101613f08565b505050505050565b81516001600160401b03811115613f3c57613f3c6139d6565b613f5081613f4a8454613e02565b84613ed5565b602080601f831160018114613f855760008415613f6d5750858301515b600019600386901b1c1916600185901b178555613f1b565b600085815260208120601f198616915b82811015613fb457888601518255948401946001909101908401613f95565b5085821015613fd25787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008251613ff4818460208701613825565b64173539b7b760d91b920191825250600501919050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061403e90830184613849565b9695505050505050565b60006020828403121561405a57600080fd5b8151613498816137d0565b60008351614077818460208801613825565b83519083019061408b818360208801613825565b01949350505050565b6000826140a3576140a3613d90565b50069056fea2646970667358221220b3f299bebe369f5dbe40975b0cd50c25b722583c00144eee651f9d27b50addea64736f6c63430008110033

Deployed Bytecode Sourcemap

100214:16237:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;115073:697;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75848:305;;;;;;;;;;-1:-1:-1;75848:305:0;;;;;:::i;:::-;;:::i;:::-;;;1202:14:1;;1195:22;1177:41;;1165:2;1150:18;75848:305:0;1037:187:1;106132:975:0;;;;;;;;;;-1:-1:-1;106132:975:0;;;;;:::i;:::-;;:::i;:::-;;104272:138;;;;;;;;;;;;;:::i;78961:100::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;80472:204::-;;;;;;;;;;-1:-1:-1;80472:204:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2587:32:1;;;2569:51;;2557:2;2542:18;80472:204:0;2423:203:1;80027:379:0;;;;;;;;;;-1:-1:-1;80027:379:0;;;;;:::i;:::-;;:::i;109005:308::-;;;;;;;;;;-1:-1:-1;109005:308:0;;;;;:::i;:::-;;:::i;75097:303::-;;;;;;;;;;-1:-1:-1;75351:12:0;;75141:7;75335:13;:28;75097:303;;;3233:25:1;;;3221:2;3206:18;75097:303:0;3087:177:1;102427:772:0;;;;;;;;;;-1:-1:-1;102427:772:0;;;;;:::i;:::-;;:::i;101885:123::-;;;;;;;;;;-1:-1:-1;101885:123:0;;;;;:::i;:::-;101947:4;101971:21;;;:11;:21;;;;;;;;:29;;:21;:29;;;101885:123;100553:30;;;;;;;;;;;;;;;;81337:170;;;;;;;;;;-1:-1:-1;81337:170:0;;;;;:::i;:::-;;:::i;109534:712::-;;;;;;:::i;:::-;;:::i;115780:662::-;;;;;;;;;;;;;:::i;107117:876::-;;;;;;:::i;:::-;;:::i;101445:43::-;;;;;;;;;;-1:-1:-1;101445:43:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;112621:903;;;;;;;;;;-1:-1:-1;112621:903:0;;;;;:::i;:::-;;:::i;109321:162::-;;;;;;;;;;;;;:::i;81578:185::-;;;;;;;;;;-1:-1:-1;81578:185:0;;;;;:::i;:::-;;:::i;100988:35::-;;;;;;;;;;-1:-1:-1;100988:35:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;100988:35:0;;;-1:-1:-1;;;100988:35:0;;;;;;;;;;5060:25:1;;;-1:-1:-1;;;;;5121:32:1;;;5116:2;5101:18;;5094:60;5197:14;5190:22;5170:18;;;5163:50;5048:2;5033:18;100988:35:0;4864:355:1;102032:212:0;;;;;;;;;;-1:-1:-1;102032:212:0;;;;;:::i;:::-;;:::i;104096:168::-;;;;;;;;;;;;;:::i;105475:104::-;;;;;;;;;;-1:-1:-1;105475:104:0;;;;;:::i;:::-;;:::i;104650:712::-;;;;;;;;;;-1:-1:-1;104650:712:0;;;;;:::i;:::-;;:::i;78769:125::-;;;;;;;;;;-1:-1:-1;78769:125:0;;;;;:::i;:::-;;:::i;100316:38::-;;;;;;;;;;;;;;;;100590:31;;;;;;;;;;;;;;;;114342:721;;;;;;;;;;;;;:::i;76217:206::-;;;;;;;;;;-1:-1:-1;76217:206:0;;;;;:::i;:::-;;:::i;104530:110::-;;;;;;;;;;-1:-1:-1;104530:110:0;;;;;:::i;:::-;;:::i;65971:103::-;;;;;;;;;;;;;:::i;100435:69::-;;;;;;;;;;-1:-1:-1;100435:69:0;;;;-1:-1:-1;;;;;100435:69:0;;;111349:401;;;;;;;;;;-1:-1:-1;111349:401:0;;;;;:::i;:::-;;:::i;65320:87::-;;;;;;;;;;-1:-1:-1;65393:6:0;;-1:-1:-1;;;;;65393:6:0;65320:87;;111760:853;;;;;;;;;;-1:-1:-1;111760:853:0;;;;;:::i;:::-;;:::i;105893:229::-;;;;;;;;;;-1:-1:-1;105893:229:0;;;;;:::i;:::-;;:::i;79130:104::-;;;;;;;;;;;;;:::i;100361:30::-;;;;;;;;;;;;;;;;102252:165;;;;;;;;;;-1:-1:-1;102252:165:0;;;;;:::i;:::-;;:::i;103207:751::-;;;;;;:::i;:::-;;:::i;80748:287::-;;;;;;;;;;-1:-1:-1;80748:287:0;;;;;:::i;:::-;;:::i;103966:122::-;;;;;;;;;;-1:-1:-1;103966:122:0;;;;;:::i;:::-;;:::i;101495:51::-;;;;;;;;;;-1:-1:-1;101495:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;81834:369;;;;;;;;;;-1:-1:-1;81834:369:0;;;;;:::i;:::-;;:::i;100819:53::-;;;;;;;;;;-1:-1:-1;100819:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;100819:53:0;;;;;;;;8388:14:1;;8381:22;8363:41;;-1:-1:-1;;;;;8440:32:1;;;8435:2;8420:18;;8413:60;8489:18;;;8482:34;8351:2;8336:18;100819:53:0;8167:355:1;105370:97:0;;;;;;;;;;;;;:::i;100511:35::-;;;;;;;;;;;;;;;;110301:993;;;;;;;;;;-1:-1:-1;110301:993:0;;;;;:::i;:::-;;:::i;105710:173::-;;;;;;;;;;-1:-1:-1;105710:173:0;;;;;:::i;:::-;;:::i;101205:44::-;;;;;;;;;;-1:-1:-1;101205:44:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;101205:44:0;;;-1:-1:-1;;;101205:44:0;;;;;;100628:38;;;;;;;;;;;;;;;;101030:22;;;;;;;;;;;;;;;;101381:38;;;;;;;;;;-1:-1:-1;101381:38:0;;;;;;;;;;;100398:30;;;;;;;;;;;;;;;;81106:164;;;;;;;;;;-1:-1:-1;81106:164:0;;;;;:::i;:::-;;:::i;101262:49::-;;;;;;;;;;-1:-1:-1;101262:49:0;;;;;:::i;:::-;;:::i;101342:32::-;;;;;;;;;;-1:-1:-1;101342:32:0;;;;;;;;113532:802;;;;;;;;;;-1:-1:-1;113532:802:0;;;;;:::i;:::-;;:::i;108001:320::-;;;;;;;;;;-1:-1:-1;108001:320:0;;;;;:::i;:::-;;:::i;108752:245::-;;;:::i;66229:201::-;;;;;;;;;;-1:-1:-1;66229:201:0;;;;;:::i;:::-;;:::i;104418:102::-;;;;;;;;;;-1:-1:-1;104418:102:0;;;;;:::i;:::-;;:::i;108331:413::-;;;;;;;;;;-1:-1:-1;108331:413:0;;;;;:::i;:::-;;:::i;115073:697::-;115126:16;115155:23;115200:15;115195:175;75351:12;;75141:7;75335:13;:28;115221:7;:23;115195:175;;;115276:20;;;;:11;:20;;;;;:29;;;-1:-1:-1;;;115276:29:0;;;;115272:87;;;115326:17;;;;:::i;:::-;;;;115272:87;115246:9;;;;:::i;:::-;;;;115195:175;;;;115382:29;115428:15;-1:-1:-1;;;;;115414:30:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;115414:30:0;;115382:62;;115455:24;115501:15;115496:235;75351:12;;75141:7;75335:13;:28;115522:7;:23;115496:235;;;115577:20;;;;:11;:20;;;;;:29;;;-1:-1:-1;;;115577:29:0;;;;115573:147;;;115660:7;115627:12;115640:16;115627:30;;;;;;;;:::i;:::-;;;;;;;;;;:40;115686:18;;;;:::i;:::-;;;;115573:147;115547:9;;;;:::i;:::-;;;;115496:235;;;-1:-1:-1;115750:12:0;;115073:697;-1:-1:-1;;;115073:697:0:o;75848:305::-;75950:4;-1:-1:-1;;;;;;75987:40:0;;-1:-1:-1;;;75987:40:0;;:105;;-1:-1:-1;;;;;;;76044:48:0;;-1:-1:-1;;;76044:48:0;75987:105;:158;;;-1:-1:-1;;;;;;;;;;36189:40:0;;;76109:36;75967:178;75848:305;-1:-1:-1;;75848:305:0:o;106132:975::-;70705:1;71303:7;;:19;71295:63;;;;-1:-1:-1;;;71295:63:0;;;;;;;:::i;:::-;;;;;;;;;70705:1;71436:7;:18;106242:7:::1;::::0;106229:20;::::1;;106221:50;;;::::0;-1:-1:-1;;;106221:50:0;;11556:2:1;106221:50:0::1;::::0;::::1;11538:21:1::0;11595:2;11575:18;;;11568:30;-1:-1:-1;;;11614:18:1;;;11607:47;11671:18;;106221:50:0::1;11354:341:1::0;106221:50:0::1;106286:23;106312:15:::0;;;:4:::1;:15;::::0;;;;106348:20:::1;::::0;::::1;::::0;-1:-1:-1;;;106348:20:0;::::1;;;106340:47;;;::::0;-1:-1:-1;;;106340:47:0;;11902:2:1;106340:47:0::1;::::0;::::1;11884:21:1::0;11941:2;11921:18;;;11914:30;-1:-1:-1;;;11960:18:1;;;11953:44;12014:18;;106340:47:0::1;11700:338:1::0;106340:47:0::1;106420:17;106428:8;106420:7;:17::i;:::-;-1:-1:-1::0;;;;;106406:31:0::1;:10;-1:-1:-1::0;;;;;106406:31:0::1;;106398:71;;;::::0;-1:-1:-1;;;106398:71:0;;12245:2:1;106398:71:0::1;::::0;::::1;12227:21:1::0;12284:2;12264:18;;;12257:30;12323:29;12303:18;;;12296:57;12370:18;;106398:71:0::1;12043:351:1::0;106398:71:0::1;106482:23;106553:3;106530:19;;106509:11;:18;;;:40;;;;:::i;:::-;106508:48;;;;:::i;:::-;106482:74;;106567:20;106611:15;106590:11;:18;;;:36;;;;:::i;:::-;106639:20;::::0;::::1;:28:::0;;-1:-1:-1;;;;106639:28:0::1;::::0;;106662:5:::1;106762:23:::0;;;:13:::1;:23;::::0;;;;:32;106567:59;;-1:-1:-1;106639:28:0::1;106762:32;106758:105;;;106846:5;106811:23:::0;;;:13:::1;:23;::::0;;;;:40;;-1:-1:-1;;106811:40:0::1;::::0;;106758:105:::1;106904:18;::::0;::::1;::::0;106875:58:::1;::::0;106892:10:::1;::::0;-1:-1:-1;;;;;106904:18:0::1;106924:8:::0;106875:16:::1;:58::i;:::-;106945:42;::::0;106953:10:::1;::::0;106945:42;::::1;;;::::0;106974:12;;106945:42:::1;::::0;;;106974:12;106953:10;106945:42;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;65393:6:0;;107026:42:::1;::::0;-1:-1:-1;;;;;65393:6:0;;;;107026:42;::::1;;;::::0;107052:15;;107026:42:::1;::::0;;;107052:15;65393:6;107026:42;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;70661:1:0;71615:7;:22;-1:-1:-1;;;;106132:975:0:o;104272:138::-;65393:6;;-1:-1:-1;;;;;65393:6:0;33209:10;65540:23;65532:68;;;;-1:-1:-1;;;65532:68:0;;;;;;;:::i;:::-;104346:12:::1;::::0;;::::1;::::0;;::::1;104345:13;-1:-1:-1::0;;104330:28:0;;::::1;::::0;::::1;::::0;;;104374::::1;::::0;104389:12;;1202:14:1;1195:22;1177:41;;104374:28:0::1;::::0;1165:2:1;1150:18;104374:28:0::1;;;;;;;;104272:138::o:0;78961:100::-;79015:13;79048:5;79041:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78961:100;:::o;80472:204::-;80540:7;80565:16;80573:7;80565;:16::i;:::-;80560:64;;80590:34;;-1:-1:-1;;;80590:34:0;;;;;;;;;;;80560:64;-1:-1:-1;80644:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;80644:24:0;;80472:204::o;80027:379::-;80108:13;80124:24;80140:7;80124:15;:24::i;:::-;80108:40;;80169:5;-1:-1:-1;;;;;80163:11:0;:2;-1:-1:-1;;;;;80163:11:0;;80159:48;;80183:24;;-1:-1:-1;;;80183:24:0;;;;;;;;;;;80159:48;33209:10;-1:-1:-1;;;;;80224:21:0;;;;;;:63;;-1:-1:-1;80250:37:0;80267:5;33209:10;81106:164;:::i;80250:37::-;80249:38;80224:63;80220:138;;;80311:35;;-1:-1:-1;;;80311:35:0;;;;;;;;;;;80220:138;80370:28;80379:2;80383:7;80392:5;80370:8;:28::i;:::-;80097:309;80027:379;;:::o;109005:308::-;70705:1;71303:7;;:19;71295:63;;;;-1:-1:-1;;;71295:63:0;;;;;;;:::i;:::-;70705:1;71436:7;:18;109078:15:::1;109096::::0;;;:4:::1;:15;::::0;;;;109130:10:::1;::::0;::::1;::::0;-1:-1:-1;;;;;109130:10:0::1;109144;109130:24;109122:49;;;::::0;-1:-1:-1;;;109122:49:0;;13910:2:1;109122:49:0::1;::::0;::::1;13892:21:1::0;13949:2;13929:18;;;13922:30;-1:-1:-1;;;13968:18:1;;;13961:42;14020:18;;109122:49:0::1;13708:336:1::0;109122:49:0::1;109190:12;::::0;::::1;::::0;-1:-1:-1;;;109190:12:0;::::1;;;109182:39;;;::::0;-1:-1:-1;;;109182:39:0;;11902:2:1;109182:39:0::1;::::0;::::1;11884:21:1::0;11941:2;11921:18;;;11914:30;-1:-1:-1;;;11960:18:1;;;11953:44;12014:18;;109182:39:0::1;11700:338:1::0;109182:39:0::1;109234:12;::::0;::::1;:20:::0;;-1:-1:-1;;;;109234:20:0::1;::::0;;109294:10;;109265:40:::1;::::0;109273:10:::1;::::0;109265:40;::::1;;;::::0;109249:5:::1;109265:40:::0;109249:5;109265:40;109294:10;109273;109265:40;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;70661:1:0;71615:7;:22;-1:-1:-1;109005:308:0:o;102427:772::-;70705:1;71303:7;;:19;71295:63;;;;-1:-1:-1;;;71295:63:0;;;;;;;:::i;:::-;70705:1;71436:7;:18;102536::::1;::::0;::::1;::::0;::::1;;;102528:27;;;::::0;::::1;;102588:24:::0;;::::1;102566:96;;;::::0;-1:-1:-1;;;102566:96:0;;14251:2:1;102566:96:0::1;::::0;::::1;14233:21:1::0;14290:2;14270:18;;;14263:30;-1:-1:-1;;;14309:18:1;;;14302:52;14371:18;;102566:96:0::1;14049:346:1::0;102566:96:0::1;102721:9;;102711:6;102695:13;75351:12:::0;;75141:7;75335:13;:28;;75097:303;102695:13:::1;:22;;;;:::i;:::-;:35;;102673:93;;;;-1:-1:-1::0;;;102673:93:0::1;;;;;;;:::i;:::-;102822:9;::::0;102851:28:::1;::::0;-1:-1:-1;;;102851:28:0;;102868:10:::1;102851:28;::::0;::::1;2569:51:1::0;-1:-1:-1;;;;;102822:9:0;;::::1;::::0;102779:23:::1;::::0;102822:9;;102851:16:::1;::::0;2542:18:1;;102851:28:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:32;102843:41;;;::::0;::::1;;102900:9;102895:255;102915:18:::0;;::::1;102895:255;;;102963:26;102978:7;;102986:1;102978:10;;;;;;;:::i;:::-;;;;;;;101947:4:::0;101971:21;;;:11;:21;;;;;;;;:29;;:21;:29;;;101885:123;102963:26:::1;102955:57;;;::::0;-1:-1:-1;;;102955:57:0;;15257:2:1;102955:57:0::1;::::0;::::1;15239:21:1::0;15296:2;15276:18;;;15269:30;-1:-1:-1;;;15315:18:1;;;15308:48;15373:18;;102955:57:0::1;15055:342:1::0;102955:57:0::1;103065:10;-1:-1:-1::0;;;;;103035:14:0;::::1;;103050:7:::0;;103058:1;103050:10;;::::1;;;;;:::i;:::-;;;;;;;103035:26;;;;;;;;;;;;;3233:25:1::0;;3221:2;3206:18;;3087:177;103035:26:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;103035:40:0::1;;103027:66;;;::::0;-1:-1:-1;;;103027:66:0;;15860:2:1;103027:66:0::1;::::0;::::1;15842:21:1::0;15899:2;15879:18;;;15872:30;-1:-1:-1;;;15918:18:1;;;15911:43;15971:18;;103027:66:0::1;15658:337:1::0;103027:66:0::1;103134:4;103108:11;:23;103120:7;;103128:1;103120:10;;;;;;;:::i;:::-;;;;;;;103108:23;;;;;;;;;;;;:30;;;;;;;;;;;;;;;;;;102935:3;;;;;:::i;:::-;;;;102895:255;;;;103162:29;103172:10;103184:6;103162:9;:29::i;:::-;-1:-1:-1::0;;70661:1:0;71615:7;:22;-1:-1:-1;;102427:772:0:o;81337:170::-;81471:28;81481:4;81487:2;81491:7;81471:9;:28::i;109534:712::-;70705:1;71303:7;;:19;71295:63;;;;-1:-1:-1;;;71295:63:0;;;;;;;:::i;:::-;70705:1;71436:7;:18;109621:17:::1;109629:8:::0;109621:7:::1;:17::i;:::-;109613:50;;;;-1:-1:-1::0;;;109613:50:0::1;;;;;;;:::i;:::-;109694:1;109682:9;:13;109674:61;;;::::0;-1:-1:-1;;;109674:61:0;;16551:2:1;109674:61:0::1;::::0;::::1;16533:21:1::0;16590:2;16570:18;;;16563:30;16629:34;16609:18;;;16602:62;-1:-1:-1;;;16680:18:1;;;16673:33;16723:19;;109674:61:0::1;16349:399:1::0;109674:61:0::1;109748:27;109778:21:::0;;;:11:::1;:21;::::0;;;;109816:22:::1;::::0;::::1;::::0;-1:-1:-1;;;109816:22:0;::::1;;;109812:356;;;109944:20:::0;;109932:9:::1;:32;109924:85;;;::::0;-1:-1:-1;;;109924:85:0;;16955:2:1;109924:85:0::1;::::0;::::1;16937:21:1::0;16994:2;16974:18;;;16967:30;17033:34;17013:18;;;17006:62;-1:-1:-1;;;17084:18:1;;;17077:38;17132:19;;109924:85:0::1;16753:404:1::0;109924:85:0::1;110104:20;::::0;::::1;::::0;110135;;110096:60:::1;::::0;-1:-1:-1;;;;;110104:20:0;;::::1;::::0;110096:60;::::1;;;::::0;110135:20;110104::::1;110096:60:::0;110104:20;110096:60;110135:20;110104;110096:60;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;109812:356;-1:-1:-1::0;110204:34:0::1;::::0;;::::1;::::0;::::1;::::0;;110210:9:::1;110204:34:::0;;110221:10:::1;110204:34;::::0;;::::1;::::0;;;110233:4:::1;110204:34:::0;;;;;;-1:-1:-1;110180:21:0;;;:11:::1;:21:::0;;;;;;;:58;;;;;;;::::1;::::0;;;;::::1;;-1:-1:-1::0;;;110180:58:0::1;-1:-1:-1::0;;;;;;110180:58:0;;;-1:-1:-1;;;;;110180:58:0;;;::::1;::::0;;;;;;;::::1;::::0;;;71615:7;:22;109534:712::o;115780:662::-;115831:16;115860:21;115922:1;115898:165;115937:7;;115925:8;:19;115898:165;;115977:14;;;;:4;:14;;;;;:23;;;-1:-1:-1;;;115977:23:0;;;;115973:79;;;116021:15;;;;:::i;:::-;;;;115973:79;115946:10;;;;:::i;:::-;;;;115898:165;;;;116075:27;116119:13;-1:-1:-1;;;;;116105:28:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;116105:28:0;-1:-1:-1;116075:58:0;-1:-1:-1;116144:22:0;116207:1;116183:222;116222:7;;116210:8;:19;116183:222;;116262:14;;;;:4;:14;;;;;:23;;;-1:-1:-1;;;116262:23:0;;;;116258:136;;;116335:8;116306:10;116317:14;116306:26;;;;;;;;:::i;:::-;;;;;;;;;;:37;116362:16;;;;:::i;:::-;;;;116258:136;116231:10;;;;:::i;:::-;;;;116183:222;;107117:876;70705:1;71303:7;;:19;71295:63;;;;-1:-1:-1;;;71295:63:0;;;;;;;:::i;:::-;70705:1;71436:7;:18;107194:28:::1;107225:23:::0;;;:13:::1;:23;::::0;;;;107269:16;;::::1;;107261:45;;;::::0;-1:-1:-1;;;107261:45:0;;17364:2:1;107261:45:0::1;::::0;::::1;17346:21:1::0;17403:2;17383:18;;;17376:30;-1:-1:-1;;;17422:18:1;;;17415:46;17478:18;;107261:45:0::1;17162:340:1::0;107261:45:0::1;107338:7;:13;;;107325:9;:26;;107317:59;;;::::0;-1:-1:-1;;;107317:59:0;;17709:2:1;107317:59:0::1;::::0;::::1;17691:21:1::0;17748:2;17728:18;;;17721:30;-1:-1:-1;;;17767:18:1;;;17760:50;17827:18;;107317:59:0::1;17507:344:1::0;107317:59:0::1;107416:14:::0;;::::1;::::0;::::1;-1:-1:-1::0;;;;;107416:14:0::1;107395:17;107403:8:::0;107395:7:::1;:17::i;:::-;-1:-1:-1::0;;;;;107395:35:0::1;;107387:73;;;::::0;-1:-1:-1;;;107387:73:0;;18058:2:1;107387:73:0::1;::::0;::::1;18040:21:1::0;18097:2;18077:18;;;18070:30;18136:27;18116:18;;;18109:55;18181:18;;107387:73:0::1;17856:349:1::0;107387:73:0::1;107473:23;107535:3;107512:19;;107500:9;:31;;;;:::i;:::-;107499:39;;;;:::i;:::-;107473:65:::0;-1:-1:-1;107549:20:0::1;107572:27;107473:65:::0;107572:9:::1;:27;:::i;:::-;107647:5;107612:23:::0;;;:13:::1;:23;::::0;;;;:40;;-1:-1:-1;;107612:40:0::1;::::0;;107722:14;;107549:50;;-1:-1:-1;107691:46:0::1;::::0;107700:10:::1;::::0;107612:23;;:40:::1;107722:14:::0;::::1;-1:-1:-1::0;;;;;107722:14:0::1;107691:8;:46::i;:::-;107765:14:::0;;107748:54:::1;::::0;107765:14:::1;::::0;::::1;-1:-1:-1::0;;;;;107765:14:0::1;107781:10;107793:8:::0;107748:16:::1;:54::i;:::-;107835:14:::0;;107827:46:::1;::::0;107835:14:::1;::::0;;::::1;-1:-1:-1::0;;;;;107835:14:0::1;::::0;107827:46:::1;::::0;::::1;;::::0;;;107835:14:::1;107827:46:::0;107835:14;107827:46;;107835:14;107827:46;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;65393:6:0;;107912:42:::1;::::0;-1:-1:-1;;;;;65393:6:0;;;;107912:42;::::1;;;::::0;107938:15;;107912:42:::1;::::0;;;107938:15;65393:6;107912:42;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;70661:1:0;71615:7;:22;-1:-1:-1;;;107117:876:0:o;112621:903::-;112696:16;112725:25;112772:15;112767:260;75351:12;;75141:7;75335:13;:28;112793:7;:23;112767:260;;;112844:28;112875:22;;;:13;:22;;;;;112916:16;;;;:44;;;;-1:-1:-1;112936:14:0;;-1:-1:-1;;;;;112936:24:0;;;:14;;;;;:24;112916:44;112912:104;;;112981:19;;;;:::i;:::-;;;;112912:104;-1:-1:-1;112818:9:0;;;;:::i;:::-;;;;112767:260;;;;113039:31;113087:17;-1:-1:-1;;;;;113073:32:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;113073:32:0;;113039:66;;113116:26;113164:15;113159:324;75351:12;;75141:7;75335:13;:28;113185:7;:23;113159:324;;;113236:28;113267:22;;;:13;:22;;;;;113308:16;;;;:44;;;;-1:-1:-1;113328:14:0;;-1:-1:-1;;;;;113328:24:0;;;:14;;;;;:24;113308:44;113304:168;;;113410:7;113373:14;113388:18;113373:34;;;;;;;;:::i;:::-;;;;;;;;;;:44;113436:20;;;;:::i;:::-;;;;113304:168;-1:-1:-1;113210:9:0;;;;:::i;:::-;;;;113159:324;;;-1:-1:-1;113502:14:0;;112621:903;-1:-1:-1;;;;112621:903:0:o;109321:162::-;65393:6;;-1:-1:-1;;;;;65393:6:0;33209:10;65540:23;65532:68;;;;-1:-1:-1;;;65532:68:0;;;;;;;:::i;:::-;70705:1:::1;71303:7;;:19:::0;71295:63:::1;;;;-1:-1:-1::0;;;71295:63:0::1;;;;;;;:::i;:::-;70705:1;71436:7;:18:::0;65393:6;;109423:12:::2;::::0;109397:39:::2;::::0;-1:-1:-1;;;;;65393:6:0;;;;109397:39;::::2;;;::::0;109423:12;109397:39:::2;::::0;;;109423:12;65393:6;109397:39;::::2;;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;109463:12:0::2;::::0;;;109447::::2;:28;109463:12:::0;;109447:28:::2;:::i;:::-;::::0;;;-1:-1:-1;;70661:1:0::1;71615:7;:22:::0;109321:162::o;81578:185::-;81716:39;81733:4;81739:2;81743:7;81716:39;;;;;;;;;;;;:16;:39::i;102032:212::-;65393:6;;-1:-1:-1;;;;;65393:6:0;33209:10;65540:23;65532:68;;;;-1:-1:-1;;;65532:68:0;;;;;;;:::i;:::-;102158:9:::1;;102148:6;102132:13;75351:12:::0;;75141:7;75335:13;:28;;75097:303;102132:13:::1;:22;;;;:::i;:::-;:35;;102110:93;;;;-1:-1:-1::0;;;102110:93:0::1;;;;;;;:::i;:::-;102214:22;102224:3;102229:6;102214:9;:22::i;:::-;102032:212:::0;;:::o;104096:168::-;65393:6;;-1:-1:-1;;;;;65393:6:0;33209:10;65540:23;65532:68;;;;-1:-1:-1;;;65532:68:0;;;;;;;:::i;:::-;104182:18:::1;::::0;;::::1;;::::0;;::::1;::::0;::::1;104181:19;104160:40:::0;::::1;-1:-1:-1::0;;104160:40:0;;::::1;::::0;;;::::1;::::0;;;;104216::::1;::::0;::::1;::::0;::::1;::::0;104237:18;::::1;::::0;;::::1;1202:14:1::0;1195:22;1177:41;;1165:2;1150:18;;1037:187;105475:104:0;65393:6;;-1:-1:-1;;;;;65393:6:0;33209:10;65540:23;65532:68;;;;-1:-1:-1;;;65532:68:0;;;;;;;:::i;:::-;105548:13:::1;:23;105564:7:::0;105548:13;:23:::1;:::i;104650:712::-:0;104714:16;104760:18;104795:16;104805:5;104795:9;:16::i;:::-;-1:-1:-1;;;;;104781:31:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;104781:31:0;-1:-1:-1;104823:11:0;104837:13;;104760:52;;-1:-1:-1;104823:11:0;;104927:402;104947:3;104943:1;:7;104927:402;;;104972:31;105006:14;;;:11;:14;;;;;;;;;104972:48;;;;;;;;;-1:-1:-1;;;;;104972:48:0;;;;-1:-1:-1;;;104972:48:0;;-1:-1:-1;;;;;104972:48:0;;;;;;;;-1:-1:-1;;;104972:48:0;;;;;;;;;;;;;;;;105035:65;;105076:8;;;105035:65;105118:14;;-1:-1:-1;;;;;105118:28:0;;105114:103;;105187:14;;;-1:-1:-1;105114:103:0;105256:5;-1:-1:-1;;;;;105235:26:0;:17;-1:-1:-1;;;;;105235:26:0;;105231:87;;105301:1;105282;105284:13;;;;;;105282:16;;;;;;;;:::i;:::-;;;;;;:20;;;;;105231:87;104957:372;104927:402;104952:3;;104927:402;;;-1:-1:-1;105346:1:0;;104650:712;-1:-1:-1;;;;;104650:712:0:o;78769:125::-;78833:7;78860:21;78873:7;78860:12;:21::i;:::-;:26;;78769:125;-1:-1:-1;;78769:125:0:o;114342:721::-;114397:16;114426:25;114473:15;114468:179;75351:12;;75141:7;75335:13;:28;114494:7;:23;114468:179;;;114549:22;;;;:13;:22;;;;;:31;;;114545:91;;;114601:19;;;;:::i;:::-;;;;114545:91;114519:9;;;;:::i;:::-;;;;114468:179;;;;114659:31;114707:17;-1:-1:-1;;;;;114693:32:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;114693:32:0;;114659:66;;114736:26;114784:15;114779:243;75351:12;;75141:7;75335:13;:28;114805:7;:23;114779:243;;;114860:22;;;;:13;:22;;;;;:31;;;114856:155;;;114949:7;114912:14;114927:18;114912:34;;;;;;;;:::i;:::-;;;;;;;;;;:44;114975:20;;;;:::i;:::-;;;;114856:155;114830:9;;;;:::i;:::-;;;;114779:243;;76217:206;76281:7;-1:-1:-1;;;;;76305:19:0;;76301:60;;76333:28;;-1:-1:-1;;;76333:28:0;;;;;;;;;;;76301:60;-1:-1:-1;;;;;;76387:19:0;;;;;:12;:19;;;;;:27;-1:-1:-1;;;;;76387:27:0;;76217:206::o;104530:110::-;65393:6;;-1:-1:-1;;;;;65393:6:0;33209:10;65540:23;65532:68;;;;-1:-1:-1;;;65532:68:0;;;;;;;:::i;:::-;104606:11:::1;:26:::0;104530:110::o;65971:103::-;65393:6;;-1:-1:-1;;;;;65393:6:0;33209:10;65540:23;65532:68;;;;-1:-1:-1;;;65532:68:0;;;;;;;:::i;:::-;66036:30:::1;66063:1;66036:18;:30::i;:::-;65971:103::o:0;111349:401::-;70705:1;71303:7;;:19;71295:63;;;;-1:-1:-1;;;71295:63:0;;;;;;;:::i;:::-;70705:1;71436:7;:18;111431:17:::1;111439:8:::0;111431:7:::1;:17::i;:::-;111423:50;;;;-1:-1:-1::0;;;111423:50:0::1;;;;;;;:::i;:::-;111486:19;111508:21:::0;;;:11:::1;:21;::::0;;;;111548:12:::1;::::0;::::1;::::0;-1:-1:-1;;;;;111548:12:0::1;111564:10;111548:26;111540:60;;;::::0;-1:-1:-1;;;111540:60:0;;20616:2:1;111540:60:0::1;::::0;::::1;20598:21:1::0;20655:2;20635:18;;;20628:30;-1:-1:-1;;;20674:18:1;;;20667:51;20735:18;;111540:60:0::1;20414:345:1::0;111540:60:0::1;111619:14;::::0;::::1;::::0;-1:-1:-1;;;111619:14:0;::::1;;;111611:43;;;::::0;-1:-1:-1;;;111611:43:0;;20966:2:1;111611:43:0::1;::::0;::::1;20948:21:1::0;21005:2;20985:18;;;20978:30;-1:-1:-1;;;21024:18:1;;;21017:46;21080:18;;111611:43:0::1;20764:340:1::0;111760:853:0;111833:16;111862:23;111907:15;111902:243;75351:12;;75141:7;75335:13;:28;111928:7;:23;111902:243;;;111979:19;112001:20;;;:11;:20;;;;;112040:14;;;;-1:-1:-1;;;112040:14:0;;;;:40;;;;-1:-1:-1;112058:12:0;;;;-1:-1:-1;;;;;112058:22:0;;;:12;;:22;112040:40;112036:98;;;112101:17;;;;:::i;:::-;;;;112036:98;-1:-1:-1;111953:9:0;;;;:::i;:::-;;;;111902:243;;;;112157:29;112203:15;-1:-1:-1;;;;;112189:30:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;112189:30:0;;112157:62;;112230:24;112276:15;112271:303;75351:12;;75141:7;75335:13;:28;112297:7;:23;112271:303;;;112348:19;112370:20;;;:11;:20;;;;;112409:14;;;;-1:-1:-1;;;112409:14:0;;;;:40;;;;-1:-1:-1;112427:12:0;;;;-1:-1:-1;;;;;112427:22:0;;;:12;;:22;112409:40;112405:158;;;112503:7;112470:12;112483:16;112470:30;;;;;;;;:::i;:::-;;;;;;;;;;:40;112529:18;;;;:::i;:::-;;;;112405:158;-1:-1:-1;112322:9:0;;;;:::i;:::-;;;;112271:303;;105893:229;65393:6;;-1:-1:-1;;;;;65393:6:0;33209:10;65540:23;65532:68;;;;-1:-1:-1;;;65532:68:0;;;;;;;:::i;:::-;106023:2:::1;105996:23;:29;;105988:70;;;::::0;-1:-1:-1;;;105988:70:0;;21311:2:1;105988:70:0::1;::::0;::::1;21293:21:1::0;21350:2;21330:18;;;21323:30;21389;21369:18;;;21362:58;21437:18;;105988:70:0::1;21109:352:1::0;105988:70:0::1;106069:19;:45:::0;105893:229::o;79130:104::-;79186:13;79219:7;79212:14;;;;;:::i;102252:165::-;65393:6;;-1:-1:-1;;;;;65393:6:0;33209:10;65540:23;65532:68;;;;-1:-1:-1;;;65532:68:0;;;;;;;:::i;:::-;102331:9:::1;102326:84;102346:14:::0;;::::1;102326:84;;;102378:20;102388:3;;102392:1;102388:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;102396:1;102378:9;:20::i;:::-;102362:3:::0;::::1;::::0;::::1;:::i;:::-;;;;102326:84;;103207:751:::0;70705:1;71303:7;;:19;71295:63;;;;-1:-1:-1;;;71295:63:0;;;;;;;:::i;:::-;70705:1;71436:7;:18;103286:12:::1;::::0;::::1;;103278:38;;;::::0;-1:-1:-1;;;103278:38:0;;21668:2:1;103278:38:0::1;::::0;::::1;21650:21:1::0;21707:2;21687:18;;;21680:30;-1:-1:-1;;;21726:18:1;;;21719:43;21779:18;;103278:38:0::1;21466:337:1::0;103278:38:0::1;103384:11;::::0;103357:10:::1;103337:31;::::0;;;:19:::1;:31;::::0;;;;;:40:::1;::::0;103371:6;;103337:40:::1;:::i;:::-;103335:60;;103327:110;;;::::0;-1:-1:-1;;;103327:110:0;;22010:2:1;103327:110:0::1;::::0;::::1;21992:21:1::0;22049:2;22029:18;;;22022:30;22088:34;22068:18;;;22061:62;-1:-1:-1;;;22139:18:1;;;22132:34;22183:19;;103327:110:0::1;21808:400:1::0;103327:110:0::1;103498:9;;103488:6;103472:13;75351:12:::0;;75141:7;75335:13;:28;;75097:303;103472:13:::1;:22;;;;:::i;:::-;:35;;103450:93;;;;-1:-1:-1::0;;;103450:93:0::1;;;;;;;:::i;:::-;103600:14;;103590:6;103576:11;;:20;;;;:::i;:::-;:38;;103554:103;;;::::0;-1:-1:-1;;;103554:103:0;;22415:2:1;103554:103:0::1;::::0;::::1;22397:21:1::0;22454:2;22434:18;;;22427:30;-1:-1:-1;;;22473:18:1;;;22466:45;22528:18;;103554:103:0::1;22213:339:1::0;103554:103:0::1;103712:9;103702:6;103690:9;;:18;;;;:::i;:::-;:31;;103668:102;;;::::0;-1:-1:-1;;;103668:102:0;;22759:2:1;103668:102:0::1;::::0;::::1;22741:21:1::0;22798:2;22778:18;;;22771:30;-1:-1:-1;;;22817:18:1;;;22810:51;22878:18;;103668:102:0::1;22557:345:1::0;103668:102:0::1;103800:6;103785:11;;:21;;;;;;;:::i;:::-;;;;;;;;103837:9;103821:12;;:25;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;103861:29:0::1;::::0;-1:-1:-1;103871:10:0::1;103883:6:::0;103861:9:::1;:29::i;:::-;103925:10;103905:31;::::0;;;:19:::1;:31;::::0;;;;:41;;103940:6;;103905:31;:41:::1;::::0;103940:6;;103905:41:::1;:::i;:::-;::::0;;;-1:-1:-1;;70661:1:0;71615:7;:22;-1:-1:-1;103207:751:0:o;80748:287::-;33209:10;-1:-1:-1;;;;;80847:24:0;;;80843:54;;80880:17;;-1:-1:-1;;;80880:17:0;;;;;;;;;;;80843:54;33209:10;80910:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;80910:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;80910:53:0;;;;;;;;;;80979:48;;1177:41:1;;;80910:42:0;;33209:10;80979:48;;1150:18:1;80979:48:0;;;;;;;80748:287;;:::o;103966:122::-;65393:6;;-1:-1:-1;;;;;65393:6:0;33209:10;65540:23;65532:68;;;;-1:-1:-1;;;65532:68:0;;;;;;;:::i;:::-;104048:14:::1;:32:::0;103966:122::o;81834:369::-;82001:28;82011:4;82017:2;82021:7;82001:9;:28::i;:::-;-1:-1:-1;;;;;82044:13:0;;25554:20;25602:8;;82044:76;;;;;82064:56;82095:4;82101:2;82105:7;82114:5;82064:30;:56::i;:::-;82063:57;82044:76;82040:156;;;82144:40;;-1:-1:-1;;;82144:40:0;;;;;;;;;;;82040:156;81834:369;;;;:::o;105370:97::-;105419:7;105446:13;75351:12;;75141:7;75335:13;:28;;75097:303;105446:13;105439:20;;105370:97;:::o;110301:993::-;70705:1;71303:7;;:19;71295:63;;;;-1:-1:-1;;;71295:63:0;;;;;;;:::i;:::-;70705:1;71436:7;:18;110381:17:::1;110389:8:::0;110381:7:::1;:17::i;:::-;110373:50;;;;-1:-1:-1::0;;;110373:50:0::1;;;;;;;:::i;:::-;110436:27;110466:21:::0;;;:11:::1;:21;::::0;;;;110508:22:::1;::::0;::::1;::::0;-1:-1:-1;;;110508:22:0;::::1;;;110500:50;;;::::0;-1:-1:-1;;;110500:50:0;;23109:2:1;110500:50:0::1;::::0;::::1;23091:21:1::0;23148:2;23128:18;;;23121:30;-1:-1:-1;;;23167:18:1;;;23160:45;23222:18;;110500:50:0::1;22907:339:1::0;110500:50:0::1;110590:10;110569:17;110577:8:::0;110569:7:::1;:17::i;:::-;-1:-1:-1::0;;;;;110569:31:0::1;;110561:71;;;::::0;-1:-1:-1;;;110561:71:0;;12245:2:1;110561:71:0::1;::::0;::::1;12227:21:1::0;12284:2;12264:18;;;12257:30;12323:29;12303:18;;;12296:57;12370:18;;110561:71:0::1;12043:351:1::0;110561:71:0::1;110657:22;::::0;::::1;:30:::0;;-1:-1:-1;;;;110657:30:0::1;::::0;;110778:19:::1;::::0;110755:20;;110682:5:::1;::::0;110801:3:::1;::::0;110755:42:::1;::::0;110778:19;110755:42:::1;:::i;:::-;110754:50;;;;:::i;:::-;110728:76;;110815:20;110860:15;110838:13;:20;;;:37;;;;:::i;:::-;110946:23;::::0;;;:13:::1;:23;::::0;;;;:32;110815:60;;-1:-1:-1;110946:32:0::1;;110942:105;;;111030:5;110995:23:::0;;;:13:::1;:23;::::0;;;;:40;;-1:-1:-1;;110995:40:0::1;::::0;;110942:105:::1;111090:20;::::0;::::1;::::0;111061:60:::1;::::0;111078:10:::1;::::0;-1:-1:-1;;;;;111090:20:0::1;111112:8:::0;111061:16:::1;:60::i;:::-;111132:42;::::0;111140:10:::1;::::0;111132:42;::::1;;;::::0;111161:12;;111132:42:::1;::::0;;;111161:12;111140:10;111132:42;::::1;;;;;;;;;;;;;::::0;::::1;;;;105710:173:::0;105775:13;105831:23;105846:7;105831:14;:23::i;:::-;105814:50;;;;;;;;:::i;:::-;;;;;;;;;;;;;105800:65;;105710:173;;;:::o;81106:164::-;-1:-1:-1;;;;;81227:25:0;;;81203:4;81227:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;81106:164::o;101262:49::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;113532:802::-;113603:16;113632:21;113694:1;113670:225;113709:7;;113697:8;:19;113670:225;;113745:15;113763:14;;;:4;:14;;;;;113796:12;;;;-1:-1:-1;;;113796:12:0;;;;:36;;;;-1:-1:-1;113812:10:0;;;;-1:-1:-1;;;;;113812:20:0;;;:10;;:20;113796:36;113792:92;;;113853:15;;;;:::i;:::-;;;;113792:92;-1:-1:-1;113718:10:0;;;;:::i;:::-;;;;113670:225;;;;113907:27;113951:13;-1:-1:-1;;;;;113937:28:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;113937:28:0;-1:-1:-1;113907:58:0;-1:-1:-1;113976:22:0;114039:1;114015:282;114054:7;;114042:8;:19;114015:282;;114090:15;114108:14;;;:4;:14;;;;;114141:12;;;;-1:-1:-1;;;114141:12:0;;;;:36;;;;-1:-1:-1;114157:10:0;;;;-1:-1:-1;;;;;114157:20:0;;;:10;;:20;114141:36;114137:149;;;114227:8;114198:10;114209:14;114198:26;;;;;;;;:::i;:::-;;;;;;;;;;:37;114254:16;;;;:::i;:::-;;;;114137:149;-1:-1:-1;114063:10:0;;;;:::i;:::-;;;;114015:282;;108001:320;108083:9;108078:236;108102:9;:16;108098:1;:20;108078:236;;;108162:13;:27;108176:9;108186:1;108176:12;;;;;;;;:::i;:::-;;;;;;;108162:27;;;;;;;;;;;:34;;;;;;;;;;-1:-1:-1;;;;;108162:34:0;-1:-1:-1;;;;;108148:48:0;:10;-1:-1:-1;;;;;108148:48:0;;108140:75;;;;-1:-1:-1;;;108140:75:0;;23914:2:1;108140:75:0;;;23896:21:1;23953:2;23933:18;;;23926:30;-1:-1:-1;;;23972:18:1;;;23965:44;24026:18;;108140:75:0;23712:338:1;108140:75:0;108269:5;108230:13;:27;108244:9;108254:1;108244:12;;;;;;;;:::i;:::-;;;;;;;;;;;;108230:27;;;;;;;;;;-1:-1:-1;108230:27:0;:44;;-1:-1:-1;;108230:44:0;;;;;;;;;;108120:3;;;;:::i;:::-;;;;108078:236;;108752:245;108820:1;108808:9;:13;108800:59;;;;-1:-1:-1;;;108800:59:0;;24257:2:1;108800:59:0;;;24239:21:1;24296:2;24276:18;;;24269:30;24335:34;24315:18;;;24308:62;-1:-1:-1;;;24386:18:1;;;24379:31;24427:19;;108800:59:0;24055:397:1;108800:59:0;108872:7;:9;;;:7;:9;;;:::i;:::-;;;;-1:-1:-1;;108908:32:0;;;;;;;;108912:9;108908:32;;108923:10;108908:32;;;;;;;108935:4;108908:32;;;;;;108897:7;;;-1:-1:-1;108892:13:0;;;:4;:13;;;;;:48;;;;;;;;;;;;;;;-1:-1:-1;;;108892:48:0;-1:-1:-1;;;;;;108892:48:0;;;-1:-1:-1;;;;;108892:48:0;;;;;;;;;;;;;;;108951:24;;;:12;:24;;;;;108981:7;;108951:38;;;;;;;;;;;;;;;;;108752:245::o;66229:201::-;65393:6;;-1:-1:-1;;;;;65393:6:0;33209:10;65540:23;65532:68;;;;-1:-1:-1;;;65532:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;66318:22:0;::::1;66310:73;;;::::0;-1:-1:-1;;;66310:73:0;;24659:2:1;66310:73:0::1;::::0;::::1;24641:21:1::0;24698:2;24678:18;;;24671:30;24737:34;24717:18;;;24710:62;-1:-1:-1;;;24788:18:1;;;24781:36;24834:19;;66310:73:0::1;24457:402:1::0;66310:73:0::1;66394:28;66413:8;66394:18;:28::i;:::-;66229:201:::0;:::o;104418:102::-;65393:6;;-1:-1:-1;;;;;65393:6:0;33209:10;65540:23;65532:68;;;;-1:-1:-1;;;65532:68:0;;;;;;;:::i;:::-;104490:9:::1;:22:::0;104418:102::o;108331:413::-;108453:7;:14;108433:9;:16;:34;108425:71;;;;-1:-1:-1;;;108425:71:0;;25066:2:1;108425:71:0;;;25048:21:1;25105:2;25085:18;;;25078:30;25144:26;25124:18;;;25117:54;25188:18;;108425:71:0;24864:348:1;108425:71:0;108514:9;108509:228;108533:9;:16;108529:1;:20;108509:228;;;108604:10;-1:-1:-1;;;;;108579:35:0;:21;108587:9;108597:1;108587:12;;;;;;;;:::i;:::-;;;;;;;108579:7;:21::i;:::-;-1:-1:-1;;;;;108579:35:0;;108571:67;;;;-1:-1:-1;;;108571:67:0;;25419:2:1;108571:67:0;;;25401:21:1;25458:2;25438:18;;;25431:30;-1:-1:-1;;;25477:18:1;;;25470:49;25536:18;;108571:67:0;25217:343:1;108571:67:0;108683:42;;;;;;;;108696:4;108683:42;;;;;;108702:10;-1:-1:-1;;;;;108683:42:0;;;;;108714:7;108722:1;108714:10;;;;;;;;:::i;:::-;;;;;;;108683:42;;;108653:13;:27;108667:9;108677:1;108667:12;;;;;;;;:::i;:::-;;;;;;;;;;;;108653:27;;;;;;;;;;;;;-1:-1:-1;108653:27:0;:72;;;;;;;;-1:-1:-1;;;;;;108653:72:0;;;;;;-1:-1:-1;;;;;;108653:72:0;;;-1:-1:-1;;;;;108653:72:0;;;;;;;;;;;;;;;;;;-1:-1:-1;108653:72:0;;;;108551:3;;;;:::i;:::-;;;;108509:228;;82458:187;82515:4;82579:13;;82569:7;:23;82539:98;;;;-1:-1:-1;;82610:20:0;;;;:11;:20;;;;;:27;-1:-1:-1;;;82610:27:0;;;;82609:28;;82458:187::o;90628:197::-;90744:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;90744:29:0;-1:-1:-1;;;;;90744:29:0;;;;;;;;;90789:28;;90744:24;;90789:28;;;;;;;90628:197;;;:::o;82653:104::-;82722:27;82732:2;82736:8;82722:27;;;;;;;;;;;;:9;:27::i;85571:2130::-;85686:35;85724:21;85737:7;85724:12;:21::i;:::-;85686:59;;85784:4;-1:-1:-1;;;;;85762:26:0;:13;:18;;;-1:-1:-1;;;;;85762:26:0;;85758:67;;85797:28;;-1:-1:-1;;;85797:28:0;;;;;;;;;;;85758:67;85838:22;33209:10;-1:-1:-1;;;;;85864:20:0;;;;:73;;-1:-1:-1;85901:36:0;85918:4;33209:10;81106:164;:::i;85901:36::-;85864:126;;;-1:-1:-1;33209:10:0;85954:20;85966:7;85954:11;:20::i;:::-;-1:-1:-1;;;;;85954:36:0;;85864:126;85838:153;;86009:17;86004:66;;86035:35;;-1:-1:-1;;;86035:35:0;;;;;;;;;;;86004:66;-1:-1:-1;;;;;86085:16:0;;86081:52;;86110:23;;-1:-1:-1;;;86110:23:0;;;;;;;;;;;86081:52;86254:35;86271:1;86275:7;86284:4;86254:8;:35::i;:::-;-1:-1:-1;;;;;86585:18:0;;;;;;;:12;:18;;;;;;;;:31;;-1:-1:-1;;86585:31:0;;;-1:-1:-1;;;;;86585:31:0;;;-1:-1:-1;;86585:31:0;;;;;;;86631:16;;;;;;;;;:29;;;;;;;;-1:-1:-1;86631:29:0;;;;;;;;;;;86711:20;;;:11;:20;;;;;;86746:18;;-1:-1:-1;;;;;;86779:49:0;;;;-1:-1:-1;;;86812:15:0;86779:49;;;;;;;;;;87102:11;;87162:24;;;;;87205:13;;86711:20;;87162:24;;87205:13;87201:384;;87415:13;;87400:11;:28;87396:174;;87453:20;;87522:28;;;;-1:-1:-1;;;;;87496:54:0;-1:-1:-1;;;87496:54:0;-1:-1:-1;;;;;;87496:54:0;;;-1:-1:-1;;;;;87453:20:0;;87496:54;;;;87396:174;86560:1036;;;87632:7;87628:2;-1:-1:-1;;;;;87613:27:0;87622:4;-1:-1:-1;;;;;87613:27:0;;;;;;;;;;;87651:42;85675:2026;;85571:2130;;;:::o;77598:1109::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;77709:7:0;77792:13;;77785:4;:20;77754:886;;;77826:31;77860:17;;;:11;:17;;;;;;;;;77826:51;;;;;;;;;-1:-1:-1;;;;;77826:51:0;;;;-1:-1:-1;;;77826:51:0;;-1:-1:-1;;;;;77826:51:0;;;;;;;;-1:-1:-1;;;77826:51:0;;;;;;;;;;;;;;77896:729;;77946:14;;-1:-1:-1;;;;;77946:28:0;;77942:101;;78010:9;77598:1109;-1:-1:-1;;;77598:1109:0:o;77942:101::-;-1:-1:-1;;;78385:6:0;78430:17;;;;:11;:17;;;;;;;;;78418:29;;;;;;;;;-1:-1:-1;;;;;78418:29:0;;;;;-1:-1:-1;;;78418:29:0;;-1:-1:-1;;;;;78418:29:0;;;;;;;;-1:-1:-1;;;78418:29:0;;;;;;;;;;;;;78478:28;78474:109;;78546:9;77598:1109;-1:-1:-1;;;77598:1109:0:o;78474:109::-;78345:261;;;77807:833;77754:886;78668:31;;-1:-1:-1;;;78668:31:0;;;;;;;;;;;66590:191;66683:6;;;-1:-1:-1;;;;;66700:17:0;;;-1:-1:-1;;;;;;66700:17:0;;;;;;;66733:40;;66683:6;;;66700:17;66683:6;;66733:40;;66664:16;;66733:40;66653:128;66590:191;:::o;91317:667::-;91501:72;;-1:-1:-1;;;91501:72:0;;91480:4;;-1:-1:-1;;;;;91501:36:0;;;;;:72;;33209:10;;91552:4;;91558:7;;91567:5;;91501:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;91501:72:0;;;;;;;;-1:-1:-1;;91501:72:0;;;;;;;;;;;;:::i;:::-;;;91497:480;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91735:6;:13;91752:1;91735:18;91731:235;;91781:40;;-1:-1:-1;;;91781:40:0;;;;;;;;;;;91731:235;91924:6;91918:13;91909:6;91905:2;91901:15;91894:38;91497:480;-1:-1:-1;;;;;;91620:55:0;-1:-1:-1;;;91620:55:0;;-1:-1:-1;91497:480:0;91317:667;;;;;;:::o;79305:318::-;79378:13;79409:16;79417:7;79409;:16::i;:::-;79404:59;;79434:29;;-1:-1:-1;;;79434:29:0;;;;;;;;;;;79404:59;79476:21;79500:10;:8;:10::i;:::-;79476:34;;79534:7;79528:21;79553:1;79528:26;:87;;;;;;;;;;;;;;;;;79581:7;79590:18;:7;:16;:18::i;:::-;79564:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;79528:87;79521:94;79305:318;-1:-1:-1;;;79305:318:0:o;83120:163::-;83243:32;83249:2;83253:8;83263:5;83270:4;83243:5;:32::i;105587:114::-;105647:13;105680;105673:20;;;;;:::i;33596:723::-;33652:13;33873:5;33882:1;33873:10;33869:53;;-1:-1:-1;;33900:10:0;;;;;;;;;;;;-1:-1:-1;;;33900:10:0;;;;;33596:723::o;33869:53::-;33947:5;33932:12;33988:78;33995:9;;33988:78;;34021:8;;;;:::i;:::-;;-1:-1:-1;34044:10:0;;-1:-1:-1;34052:2:0;34044:10;;:::i;:::-;;;33988:78;;;34076:19;34108:6;-1:-1:-1;;;;;34098:17:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34098:17:0;;34076:39;;34126:154;34133:10;;34126:154;;34160:11;34170:1;34160:11;;:::i;:::-;;-1:-1:-1;34229:10:0;34237:2;34229:5;:10;:::i;:::-;34216:24;;:2;:24;:::i;:::-;34203:39;;34186:6;34193;34186:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;34186:56:0;;;;;;;;-1:-1:-1;34257:11:0;34266:2;34257:11;;:::i;:::-;;;34126:154;;83542:1775;83681:20;83704:13;-1:-1:-1;;;;;83732:16:0;;83728:48;;83757:19;;-1:-1:-1;;;83757:19:0;;;;;;;;;;;83728:48;83791:8;83803:1;83791:13;83787:44;;83813:18;;-1:-1:-1;;;83813:18:0;;;;;;;;;;;83787:44;-1:-1:-1;;;;;84182:16:0;;;;;;:12;:16;;;;;;;;:44;;-1:-1:-1;;84241:49:0;;-1:-1:-1;;;;;84182:44:0;;;;;;;84241:49;;;;-1:-1:-1;;84182:44:0;;;;;;84241:49;;;;;;;;;;;;;;;;84307:25;;;:11;:25;;;;;;:35;;-1:-1:-1;;;;;;84357:66:0;;;;-1:-1:-1;;;84407:15:0;84357:66;;;;;;;;;;84307:25;84504:23;;;84548:4;:23;;;;-1:-1:-1;;;;;;84556:13:0;;25554:20;25602:8;;84556:15;84544:641;;;84592:314;84623:38;;84648:12;;-1:-1:-1;;;;;84623:38:0;;;84640:1;;84623:38;;84640:1;;84623:38;84689:69;84728:1;84732:2;84736:14;;;;;;84752:5;84689:30;:69::i;:::-;84684:174;;84794:40;;-1:-1:-1;;;84794:40:0;;;;;;;;;;;84684:174;84901:3;84885:12;:19;84592:314;;84987:12;84970:13;;:29;84966:43;;85001:8;;;84966:43;84544:641;;;85050:120;85081:40;;85106:14;;;;;-1:-1:-1;;;;;85081:40:0;;;85098:1;;85081:40;;85098:1;;85081:40;85165:3;85149:12;:19;85050:120;;84544:641;-1:-1:-1;85199:13:0;:28;85249:60;81834:369;14:632:1;185:2;237:21;;;307:13;;210:18;;;329:22;;;156:4;;185:2;408:15;;;;382:2;367:18;;;156:4;451:169;465:6;462:1;459:13;451:169;;;526:13;;514:26;;595:15;;;;560:12;;;;487:1;480:9;451:169;;;-1:-1:-1;637:3:1;;14:632;-1:-1:-1;;;;;;14:632:1:o;651:131::-;-1:-1:-1;;;;;;725:32:1;;715:43;;705:71;;772:1;769;762:12;787:245;845:6;898:2;886:9;877:7;873:23;869:32;866:52;;;914:1;911;904:12;866:52;953:9;940:23;972:30;996:5;972:30;:::i;1229:248::-;1297:6;1305;1358:2;1346:9;1337:7;1333:23;1329:32;1326:52;;;1374:1;1371;1364:12;1326:52;-1:-1:-1;;1397:23:1;;;1467:2;1452:18;;;1439:32;;-1:-1:-1;1229:248:1:o;1482:250::-;1567:1;1577:113;1591:6;1588:1;1585:13;1577:113;;;1667:11;;;1661:18;1648:11;;;1641:39;1613:2;1606:10;1577:113;;;-1:-1:-1;;1724:1:1;1706:16;;1699:27;1482:250::o;1737:271::-;1779:3;1817:5;1811:12;1844:6;1839:3;1832:19;1860:76;1929:6;1922:4;1917:3;1913:14;1906:4;1899:5;1895:16;1860:76;:::i;:::-;1990:2;1969:15;-1:-1:-1;;1965:29:1;1956:39;;;;1997:4;1952:50;;1737:271;-1:-1:-1;;1737:271:1:o;2013:220::-;2162:2;2151:9;2144:21;2125:4;2182:45;2223:2;2212:9;2208:18;2200:6;2182:45;:::i;2238:180::-;2297:6;2350:2;2338:9;2329:7;2325:23;2321:32;2318:52;;;2366:1;2363;2356:12;2318:52;-1:-1:-1;2389:23:1;;2238:180;-1:-1:-1;2238:180:1:o;2631:131::-;-1:-1:-1;;;;;2706:31:1;;2696:42;;2686:70;;2752:1;2749;2742:12;2767:315;2835:6;2843;2896:2;2884:9;2875:7;2871:23;2867:32;2864:52;;;2912:1;2909;2902:12;2864:52;2951:9;2938:23;2970:31;2995:5;2970:31;:::i;:::-;3020:5;3072:2;3057:18;;;;3044:32;;-1:-1:-1;;;2767:315:1:o;3269:367::-;3332:8;3342:6;3396:3;3389:4;3381:6;3377:17;3373:27;3363:55;;3414:1;3411;3404:12;3363:55;-1:-1:-1;3437:20:1;;-1:-1:-1;;;;;3469:30:1;;3466:50;;;3512:1;3509;3502:12;3466:50;3549:4;3541:6;3537:17;3525:29;;3609:3;3602:4;3592:6;3589:1;3585:14;3577:6;3573:27;3569:38;3566:47;3563:67;;;3626:1;3623;3616:12;3563:67;3269:367;;;;;:::o;3641:505::-;3736:6;3744;3752;3805:2;3793:9;3784:7;3780:23;3776:32;3773:52;;;3821:1;3818;3811:12;3773:52;3861:9;3848:23;-1:-1:-1;;;;;3886:6:1;3883:30;3880:50;;;3926:1;3923;3916:12;3880:50;3965:70;4027:7;4018:6;4007:9;4003:22;3965:70;:::i;:::-;4054:8;;3939:96;;-1:-1:-1;4136:2:1;4121:18;;;;4108:32;;3641:505;-1:-1:-1;;;;3641:505:1:o;4151:456::-;4228:6;4236;4244;4297:2;4285:9;4276:7;4272:23;4268:32;4265:52;;;4313:1;4310;4303:12;4265:52;4352:9;4339:23;4371:31;4396:5;4371:31;:::i;:::-;4421:5;-1:-1:-1;4478:2:1;4463:18;;4450:32;4491:33;4450:32;4491:33;:::i;:::-;4151:456;;4543:7;;-1:-1:-1;;;4597:2:1;4582:18;;;;4569:32;;4151:456::o;4612:247::-;4671:6;4724:2;4712:9;4703:7;4699:23;4695:32;4692:52;;;4740:1;4737;4730:12;4692:52;4779:9;4766:23;4798:31;4823:5;4798:31;:::i;5224:127::-;5285:10;5280:3;5276:20;5273:1;5266:31;5316:4;5313:1;5306:15;5340:4;5337:1;5330:15;5356:275;5427:2;5421:9;5492:2;5473:13;;-1:-1:-1;;5469:27:1;5457:40;;-1:-1:-1;;;;;5512:34:1;;5548:22;;;5509:62;5506:88;;;5574:18;;:::i;:::-;5610:2;5603:22;5356:275;;-1:-1:-1;5356:275:1:o;5636:407::-;5701:5;-1:-1:-1;;;;;5727:6:1;5724:30;5721:56;;;5757:18;;:::i;:::-;5795:57;5840:2;5819:15;;-1:-1:-1;;5815:29:1;5846:4;5811:40;5795:57;:::i;:::-;5786:66;;5875:6;5868:5;5861:21;5915:3;5906:6;5901:3;5897:16;5894:25;5891:45;;;5932:1;5929;5922:12;5891:45;5981:6;5976:3;5969:4;5962:5;5958:16;5945:43;6035:1;6028:4;6019:6;6012:5;6008:18;6004:29;5997:40;5636:407;;;;;:::o;6048:451::-;6117:6;6170:2;6158:9;6149:7;6145:23;6141:32;6138:52;;;6186:1;6183;6176:12;6138:52;6226:9;6213:23;-1:-1:-1;;;;;6251:6:1;6248:30;6245:50;;;6291:1;6288;6281:12;6245:50;6314:22;;6367:4;6359:13;;6355:27;-1:-1:-1;6345:55:1;;6396:1;6393;6386:12;6345:55;6419:74;6485:7;6480:2;6467:16;6462:2;6458;6454:11;6419:74;:::i;6504:437::-;6590:6;6598;6651:2;6639:9;6630:7;6626:23;6622:32;6619:52;;;6667:1;6664;6657:12;6619:52;6707:9;6694:23;-1:-1:-1;;;;;6732:6:1;6729:30;6726:50;;;6772:1;6769;6762:12;6726:50;6811:70;6873:7;6864:6;6853:9;6849:22;6811:70;:::i;:::-;6900:8;;6785:96;;-1:-1:-1;6504:437:1;-1:-1:-1;;;;6504:437:1:o;6946:416::-;7011:6;7019;7072:2;7060:9;7051:7;7047:23;7043:32;7040:52;;;7088:1;7085;7078:12;7040:52;7127:9;7114:23;7146:31;7171:5;7146:31;:::i;:::-;7196:5;-1:-1:-1;7253:2:1;7238:18;;7225:32;7295:15;;7288:23;7276:36;;7266:64;;7326:1;7323;7316:12;7266:64;7349:7;7339:17;;;6946:416;;;;;:::o;7367:795::-;7462:6;7470;7478;7486;7539:3;7527:9;7518:7;7514:23;7510:33;7507:53;;;7556:1;7553;7546:12;7507:53;7595:9;7582:23;7614:31;7639:5;7614:31;:::i;:::-;7664:5;-1:-1:-1;7721:2:1;7706:18;;7693:32;7734:33;7693:32;7734:33;:::i;:::-;7786:7;-1:-1:-1;7840:2:1;7825:18;;7812:32;;-1:-1:-1;7895:2:1;7880:18;;7867:32;-1:-1:-1;;;;;7911:30:1;;7908:50;;;7954:1;7951;7944:12;7908:50;7977:22;;8030:4;8022:13;;8018:27;-1:-1:-1;8008:55:1;;8059:1;8056;8049:12;8008:55;8082:74;8148:7;8143:2;8130:16;8125:2;8121;8117:11;8082:74;:::i;:::-;8072:84;;;7367:795;;;;;;;:::o;8527:388::-;8595:6;8603;8656:2;8644:9;8635:7;8631:23;8627:32;8624:52;;;8672:1;8669;8662:12;8624:52;8711:9;8698:23;8730:31;8755:5;8730:31;:::i;:::-;8780:5;-1:-1:-1;8837:2:1;8822:18;;8809:32;8850:33;8809:32;8850:33;:::i;8920:712::-;8974:5;9027:3;9020:4;9012:6;9008:17;9004:27;8994:55;;9045:1;9042;9035:12;8994:55;9081:6;9068:20;9107:4;-1:-1:-1;;;;;9126:2:1;9123:26;9120:52;;;9152:18;;:::i;:::-;9198:2;9195:1;9191:10;9221:28;9245:2;9241;9237:11;9221:28;:::i;:::-;9283:15;;;9353;;;9349:24;;;9314:12;;;;9385:15;;;9382:35;;;9413:1;9410;9403:12;9382:35;9449:2;9441:6;9437:15;9426:26;;9461:142;9477:6;9472:3;9469:15;9461:142;;;9543:17;;9531:30;;9494:12;;;;9581;;;;9461:142;;;9621:5;8920:712;-1:-1:-1;;;;;;;8920:712:1:o;9637:348::-;9721:6;9774:2;9762:9;9753:7;9749:23;9745:32;9742:52;;;9790:1;9787;9780:12;9742:52;9830:9;9817:23;-1:-1:-1;;;;;9855:6:1;9852:30;9849:50;;;9895:1;9892;9885:12;9849:50;9918:61;9971:7;9962:6;9951:9;9947:22;9918:61;:::i;9990:595::-;10108:6;10116;10169:2;10157:9;10148:7;10144:23;10140:32;10137:52;;;10185:1;10182;10175:12;10137:52;10225:9;10212:23;-1:-1:-1;;;;;10295:2:1;10287:6;10284:14;10281:34;;;10311:1;10308;10301:12;10281:34;10334:61;10387:7;10378:6;10367:9;10363:22;10334:61;:::i;:::-;10324:71;;10448:2;10437:9;10433:18;10420:32;10404:48;;10477:2;10467:8;10464:16;10461:36;;;10493:1;10490;10483:12;10461:36;;10516:63;10571:7;10560:8;10549:9;10545:24;10516:63;:::i;:::-;10506:73;;;9990:595;;;;;:::o;10590:127::-;10651:10;10646:3;10642:20;10639:1;10632:31;10682:4;10679:1;10672:15;10706:4;10703:1;10696:15;10722:135;10761:3;10782:17;;;10779:43;;10802:18;;:::i;:::-;-1:-1:-1;10849:1:1;10838:13;;10722:135::o;10862:127::-;10923:10;10918:3;10914:20;10911:1;10904:31;10954:4;10951:1;10944:15;10978:4;10975:1;10968:15;10994:355;11196:2;11178:21;;;11235:2;11215:18;;;11208:30;11274:33;11269:2;11254:18;;11247:61;11340:2;11325:18;;10994:355::o;12399:168::-;12472:9;;;12503;;12520:15;;;12514:22;;12500:37;12490:71;;12541:18;;:::i;12572:127::-;12633:10;12628:3;12624:20;12621:1;12614:31;12664:4;12661:1;12654:15;12688:4;12685:1;12678:15;12704:120;12744:1;12770;12760:35;;12775:18;;:::i;:::-;-1:-1:-1;12809:9:1;;12704:120::o;12829:128::-;12896:9;;;12917:11;;;12914:37;;;12931:18;;:::i;12962:356::-;13164:2;13146:21;;;13183:18;;;13176:30;13242:34;13237:2;13222:18;;13215:62;13309:2;13294:18;;12962:356::o;13323:380::-;13402:1;13398:12;;;;13445;;;13466:61;;13520:4;13512:6;13508:17;13498:27;;13466:61;13573:2;13565:6;13562:14;13542:18;13539:38;13536:161;;13619:10;13614:3;13610:20;13607:1;13600:31;13654:4;13651:1;13644:15;13682:4;13679:1;13672:15;13536:161;;13323:380;;;:::o;14400:125::-;14465:9;;;14486:10;;;14483:36;;;14499:18;;:::i;14530:331::-;14732:2;14714:21;;;14771:1;14751:18;;;14744:29;-1:-1:-1;;;14804:2:1;14789:18;;14782:38;14852:2;14837:18;;14530:331::o;14866:184::-;14936:6;14989:2;14977:9;14968:7;14964:23;14960:32;14957:52;;;15005:1;15002;14995:12;14957:52;-1:-1:-1;15028:16:1;;14866:184;-1:-1:-1;14866:184:1:o;15402:251::-;15472:6;15525:2;15513:9;15504:7;15500:23;15496:32;15493:52;;;15541:1;15538;15531:12;15493:52;15573:9;15567:16;15592:31;15617:5;15592:31;:::i;16000:344::-;16202:2;16184:21;;;16241:2;16221:18;;;16214:30;-1:-1:-1;;;16275:2:1;16260:18;;16253:50;16335:2;16320:18;;16000:344::o;18336:545::-;18438:2;18433:3;18430:11;18427:448;;;18474:1;18499:5;18495:2;18488:17;18544:4;18540:2;18530:19;18614:2;18602:10;18598:19;18595:1;18591:27;18585:4;18581:38;18650:4;18638:10;18635:20;18632:47;;;-1:-1:-1;18673:4:1;18632:47;18728:2;18723:3;18719:12;18716:1;18712:20;18706:4;18702:31;18692:41;;18783:82;18801:2;18794:5;18791:13;18783:82;;;18846:17;;;18827:1;18816:13;18783:82;;;18787:3;;;18336:545;;;:::o;19057:1352::-;19183:3;19177:10;-1:-1:-1;;;;;19202:6:1;19199:30;19196:56;;;19232:18;;:::i;:::-;19261:97;19351:6;19311:38;19343:4;19337:11;19311:38;:::i;:::-;19305:4;19261:97;:::i;:::-;19413:4;;19477:2;19466:14;;19494:1;19489:663;;;;20196:1;20213:6;20210:89;;;-1:-1:-1;20265:19:1;;;20259:26;20210:89;-1:-1:-1;;19014:1:1;19010:11;;;19006:24;19002:29;18992:40;19038:1;19034:11;;;18989:57;20312:81;;19459:944;;19489:663;18283:1;18276:14;;;18320:4;18307:18;;-1:-1:-1;;19525:20:1;;;19643:236;19657:7;19654:1;19651:14;19643:236;;;19746:19;;;19740:26;19725:42;;19838:27;;;;19806:1;19794:14;;;;19673:19;;19643:236;;;19647:3;19907:6;19898:7;19895:19;19892:201;;;19968:19;;;19962:26;-1:-1:-1;;20051:1:1;20047:14;;;20063:3;20043:24;20039:37;20035:42;20020:58;20005:74;;19892:201;-1:-1:-1;;;;;20139:1:1;20123:14;;;20119:22;20106:36;;-1:-1:-1;19057:1352:1:o;23251:456::-;23483:3;23521:6;23515:13;23537:66;23596:6;23591:3;23584:4;23576:6;23572:17;23537:66;:::i;:::-;-1:-1:-1;;;23625:16:1;;23650:22;;;-1:-1:-1;23699:1:1;23688:13;;23251:456;-1:-1:-1;23251:456:1:o;25565:489::-;-1:-1:-1;;;;;25834:15:1;;;25816:34;;25886:15;;25881:2;25866:18;;25859:43;25933:2;25918:18;;25911:34;;;25981:3;25976:2;25961:18;;25954:31;;;25759:4;;26002:46;;26028:19;;26020:6;26002:46;:::i;:::-;25994:54;25565:489;-1:-1:-1;;;;;;25565:489:1:o;26059:249::-;26128:6;26181:2;26169:9;26160:7;26156:23;26152:32;26149:52;;;26197:1;26194;26187:12;26149:52;26229:9;26223:16;26248:30;26272:5;26248:30;:::i;26313:496::-;26492:3;26530:6;26524:13;26546:66;26605:6;26600:3;26593:4;26585:6;26581:17;26546:66;:::i;:::-;26675:13;;26634:16;;;;26697:70;26675:13;26634:16;26744:4;26732:17;;26697:70;:::i;:::-;26783:20;;26313:496;-1:-1:-1;;;;26313:496:1:o;26814:112::-;26846:1;26872;26862:35;;26877:18;;:::i;:::-;-1:-1:-1;26911:9:1;;26814:112::o

Swarm Source

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