ETH Price: $3,321.69 (+2.21%)
Gas: 4 Gwei

Token

Liquid Invaders (INVADER)
 

Overview

Max Total Supply

3,333 INVADER

Holders

376

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 INVADER
0xfebbB48C8f7A67Dc3DcEE19524A410E078e6A6a1
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Liquid Invaders are a collection of 3333 NFTs and alien companions to Liquid Legends. Invaders have utility, including the ability to "abduct" NFTs and deliver them to a wallet holding a random Liquid Invader.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
LiquidInvaders

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

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

/*

  .____    .__             .__    .___ .___                         .___
  |    |   |__| ________ __|__| __| _/ |   | _______  _______     __| _/___________  ______
  |    |   |  |/ ____/  |  \  |/ __ |  |   |/    \  \/ /\__  \   / __ |/ __ \_  __ \/  ___/
  |    |___|  < <_|  |  |  /  / /_/ |  |   |   |  \   /  / __ \_/ /_/ \  ___/|  | \/\___ \
  |_______ \__|\__   |____/|__\____ |  |___|___|  /\_/  (____  /\____ |\___  >__|  /____  >
          \/      |__|             \/           \/           \/      \/    \/           \/
     _____                .____    .__             .__    .___    _____  .__        __
    /  _  \ ______   ____ |    |   |__| ________ __|__| __| _/   /     \ |__| _____/  |_
   /  /_\  \\____ \_/ __ \|    |   |  |/ ____/  |  \  |/ __ |   /  \ /  \|  |/    \   __\
  /    |    \  |_> >  ___/|    |___|  < <_|  |  |  /  / /_/ |  /    Y    \  |   |  \  |
  \____|__  /   __/ \___  >_______ \__|\__   |____/|__\____ |  \____|__  /__|___|  /__|
          \/|__|        \/        \/      |__|             \/          \/        \/

    Contract created for ApeLiquid.io by Ryo & Aleph 0ne

*/

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


pragma solidity ^0.8.0;



/**
 * @title PaymentSplitter
 * @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware
 * that the Ether will be split in this way, since it is handled transparently by the contract.
 *
 * The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each
 * account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim
 * an amount proportional to the percentage of total shares they were assigned.
 *
 * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the
 * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release}
 * function.
 *
 * NOTE: This contract assumes that ERC20 tokens will behave similarly to native tokens (Ether). Rebasing tokens, and
 * tokens that apply fees during transfers, are likely to not be supported as expected. If in doubt, we encourage you
 * to run tests before sending real value to this contract.
 */
contract PaymentSplitter is Context {
    event PayeeAdded(address account, uint256 shares);
    event PaymentReleased(address to, uint256 amount);
    event ERC20PaymentReleased(IERC20 indexed token, address to, uint256 amount);
    event PaymentReceived(address from, uint256 amount);

    uint256 private _totalShares;
    uint256 private _totalReleased;

    mapping(address => uint256) private _shares;
    mapping(address => uint256) private _released;
    address[] private _payees;

    mapping(IERC20 => uint256) private _erc20TotalReleased;
    mapping(IERC20 => mapping(address => uint256)) private _erc20Released;

    /**
     * @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at
     * the matching position in the `shares` array.
     *
     * All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no
     * duplicates in `payees`.
     */
    constructor(address[] memory payees, uint256[] memory shares_) payable {
        require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch");
        require(payees.length > 0, "PaymentSplitter: no payees");

        for (uint256 i = 0; i < payees.length; i++) {
            _addPayee(payees[i], shares_[i]);
        }
    }

    /**
     * @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully
     * reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the
     * reliability of the events, and not the actual splitting of Ether.
     *
     * To learn more about this see the Solidity documentation for
     * https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback
     * functions].
     */
    receive() external payable virtual {
        emit PaymentReceived(_msgSender(), msg.value);
    }

    /**
     * @dev Getter for the total shares held by payees.
     */
    function totalShares() public view returns (uint256) {
        return _totalShares;
    }

    /**
     * @dev Getter for the total amount of Ether already released.
     */
    function totalReleased() public view returns (uint256) {
        return _totalReleased;
    }

    /**
     * @dev Getter for the total amount of `token` already released. `token` should be the address of an IERC20
     * contract.
     */
    function totalReleased(IERC20 token) public view returns (uint256) {
        return _erc20TotalReleased[token];
    }

    /**
     * @dev Getter for the amount of shares held by an account.
     */
    function shares(address account) public view returns (uint256) {
        return _shares[account];
    }

    /**
     * @dev Getter for the amount of Ether already released to a payee.
     */
    function released(address account) public view returns (uint256) {
        return _released[account];
    }

    /**
     * @dev Getter for the amount of `token` tokens already released to a payee. `token` should be the address of an
     * IERC20 contract.
     */
    function released(IERC20 token, address account) public view returns (uint256) {
        return _erc20Released[token][account];
    }

    /**
     * @dev Getter for the address of the payee number `index`.
     */
    function payee(uint256 index) public view returns (address) {
        return _payees[index];
    }

    /**
     * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the
     * total shares and their previous withdrawals.
     */
    function release(address payable account) public virtual {
        require(_shares[account] > 0, "PaymentSplitter: account has no shares");

        uint256 totalReceived = address(this).balance + totalReleased();
        uint256 payment = _pendingPayment(account, totalReceived, released(account));

        require(payment != 0, "PaymentSplitter: account is not due payment");

        _released[account] += payment;
        _totalReleased += payment;

        Address.sendValue(account, payment);
        emit PaymentReleased(account, payment);
    }

    /**
     * @dev Triggers a transfer to `account` of the amount of `token` tokens they are owed, according to their
     * percentage of the total shares and their previous withdrawals. `token` must be the address of an IERC20
     * contract.
     */
    function release(IERC20 token, address account) public virtual {
        require(_shares[account] > 0, "PaymentSplitter: account has no shares");

        uint256 totalReceived = token.balanceOf(address(this)) + totalReleased(token);
        uint256 payment = _pendingPayment(account, totalReceived, released(token, account));

        require(payment != 0, "PaymentSplitter: account is not due payment");

        _erc20Released[token][account] += payment;
        _erc20TotalReleased[token] += payment;

        SafeERC20.safeTransfer(token, account, payment);
        emit ERC20PaymentReleased(token, account, payment);
    }

    /**
     * @dev internal logic for computing the pending payment of an `account` given the token historical balances and
     * already released amounts.
     */
    function _pendingPayment(
        address account,
        uint256 totalReceived,
        uint256 alreadyReleased
    ) private view returns (uint256) {
        return (totalReceived * _shares[account]) / _totalShares - alreadyReleased;
    }

    /**
     * @dev Add a new payee to the contract.
     * @param account The address of the payee to add.
     * @param shares_ The number of shares owned by the payee.
     */
    function _addPayee(address account, uint256 shares_) private {
        require(account != address(0), "PaymentSplitter: account is the zero address");
        require(shares_ > 0, "PaymentSplitter: shares are 0");
        require(_shares[account] == 0, "PaymentSplitter: account already has shares");

        _payees.push(account);
        _shares[account] = shares_;
        _totalShares = _totalShares + shares_;
        emit PayeeAdded(account, shares_);
    }
}

contract LiquidInvaders is ERC721A, ReentrancyGuard, Ownable, PaymentSplitter {

    // Minting Variables
    uint256 public mintPrice = 0.069 ether;
    uint256 public maxPurchase = 11;
    uint256 public maxSupply = 3333;
    address public apeLiquidAddress; // = 0x61028F622CB6618cAC3DeB9ef0f0D5B9c6369C72;

    address[] public _payees = [
        0x4e4CC29ab82cf8aa4EcD3578A26409E57793de4b,  // dev
        0x1Fd81469948135d389DCD4C47102FE6d6b229B7e,  // contract
        0x7FDE663601A53A6953bbb98F1Ab87E86dEE81b35,  // liquid + abductions
        0x2A724010b221DdAc53Efe3daeCC08DEfb81bD160,  // metl
        0x89B4b7b597D9D091E55426B7Ce7Fc722577dE1eC   // artist
    ];
    uint256[] private _shares = [5, 25, 40, 25, 5];

    // Sale Status
    bool public saleIsActive = false;
    bool public holderSaleIsActive = false;
    mapping(uint256 => bool) public claimedApeLiquid;
    mapping(address => uint) public addressesThatMinted;

    // Metadata
    string _baseTokenURI = "http://ipfs.io/ipfs/QmU1MSagkzwvxKJ51QHvi8aoBwQa5Cbs7H879yKhW7kp2U/";
    bool public locked;

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

    constructor(address _apeLiquidAddress) ERC721A("Liquid Invaders", "INVADER") PaymentSplitter(_payees, _shares) {
    apeLiquidAddress = _apeLiquidAddress;
    }

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

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

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

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

        ERC721Enumerable apeLiquid = ERC721Enumerable(apeLiquidAddress);
        require(apeLiquid.balanceOf(msg.sender) > 0, "NO_AL_TOKENS");
        for (uint256 i = 0; i < _apeLiquidIds.length; i++) {
            require(isApeLiquidAvailable(_apeLiquidIds[i]), "AL_ALREADY_CLAIMED");
            require(apeLiquid.ownerOf(_apeLiquidIds[i]) == msg.sender, "NOT_AL_OWNER");
            claimedApeLiquid[_apeLiquidIds[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(
            totalSupply() + _count <= maxSupply,
            "PUBLIC_SOLD_OUT"
        );
        require(
            mintPrice * _count <= msg.value,
            "INCORRECT_ETHER_VALUE"
        );

            _safeMint(msg.sender, _count);
            addressesThatMinted[msg.sender] += _count;
        }

    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 setApeLiquidAddress(address _apeLiquidAddress) external onlyOwner {
        apeLiquidAddress = _apeLiquidAddress;
    }

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

    function lockMetadata() external onlyOwner {
        locked = true;
    }

    // Payment
    function claim() external {
        release(payable(msg.sender));
    }

    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 {
        require(!locked, "METADATA_LOCKED");
        _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 _startTokenId() internal view virtual override returns (uint256){
        return 1;
    }


}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_apeLiquidAddress","type":"address"}],"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":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20PaymentReleased","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":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"PayeeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","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":"","type":"uint256"}],"name":"_payees","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressesThatMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"apeLiquidAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"claimedApeLiquid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"_apeLiquidIds","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":"uint256","name":"_tokenId","type":"uint256"}],"name":"isApeLiquidAvailable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"locked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"address[]","name":"_to","type":"address[]"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"membershipAirdopMint","outputs":[],"stateMutability":"nonpayable","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":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"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":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"payee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"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":"_apeLiquidAddress","type":"address"}],"name":"setApeLiquidAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"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":"address","name":"account","type":"address"}],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleHolderSaleStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleSaleStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

608060405266f5232269808000601155600b601255610d056013556040518060a00160405280734e4cc29ab82cf8aa4ecd3578a26409e57793de4b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001731fd81469948135d389dcd4c47102fe6d6b229b7e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001737fde663601a53a6953bbb98f1ab87e86dee81b3573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001732a724010b221ddac53efe3daecc08defb81bd16073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020017389b4b7b597d9d091e55426b7ce7fc722577de1ec73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525060159060056200019392919062000890565b506040518060a00160405280600560ff168152602001601960ff168152602001602860ff168152602001601960ff168152602001600560ff168152506016906005620001e19291906200091f565b506000601760006101000a81548160ff0219169083151502179055506000601760016101000a81548160ff02191690831515021790555060405180608001604052806043815260200162006cff60439139601a90805190602001906200024992919062000976565b503480156200025757600080fd5b5060405162006d4238038062006d4283398181016040528101906200027d919062000a90565b60158054806020026020016040519081016040528092919081815260200182805480156200030157602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311620002b6575b505050505060168054806020026020016040519081016040528092919081815260200182805480156200035457602002820191906000526020600020905b8154815260200190600101908083116200033f575b50505050506040518060400160405280600f81526020017f4c697175696420496e76616465727300000000000000000000000000000000008152506040518060400160405280600781526020017f494e5641444552000000000000000000000000000000000000000000000000008152508160029080519060200190620003dd92919062000976565b508060039080519060200190620003f692919062000976565b50620004076200057f60201b60201c565b60008190555050506001600881905550620004376200042b6200058860201b60201c565b6200059060201b60201c565b80518251146200047e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004759062000b49565b60405180910390fd5b6000825111620004c5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004bc9062000bbb565b60405180910390fd5b60005b825181101562000534576200051e838281518110620004ec57620004eb62000bdd565b5b60200260200101518383815181106200050a576200050962000bdd565b5b60200260200101516200065660201b60201c565b80806200052b9062000c45565b915050620004c8565b50505080601460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505062000f46565b60006001905090565b600033905090565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415620006c9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620006c09062000d09565b60405180910390fd5b600081116200070f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620007069062000d7b565b60405180910390fd5b6000600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541462000794576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200078b9062000e13565b60405180910390fd5b600e829080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080600a546200084b919062000e35565b600a819055507f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac82826040516200088492919062000eb4565b60405180910390a15050565b8280548282559060005260206000209081019282156200090c579160200282015b828111156200090b5782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555091602001919060010190620008b1565b5b5090506200091b919062000a07565b5090565b82805482825590600052602060002090810192821562000963579160200282015b8281111562000962578251829060ff1690559160200191906001019062000940565b5b50905062000972919062000a07565b5090565b828054620009849062000f10565b90600052602060002090601f016020900481019282620009a85760008555620009f4565b82601f10620009c357805160ff1916838001178555620009f4565b82800160010185558215620009f4579182015b82811115620009f3578251825591602001919060010190620009d6565b5b50905062000a03919062000a07565b5090565b5b8082111562000a2257600081600090555060010162000a08565b5090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000a588262000a2b565b9050919050565b62000a6a8162000a4b565b811462000a7657600080fd5b50565b60008151905062000a8a8162000a5f565b92915050565b60006020828403121562000aa95762000aa862000a26565b5b600062000ab98482850162000a79565b91505092915050565b600082825260208201905092915050565b7f5061796d656e7453706c69747465723a2070617965657320616e64207368617260008201527f6573206c656e677468206d69736d617463680000000000000000000000000000602082015250565b600062000b3160328362000ac2565b915062000b3e8262000ad3565b604082019050919050565b6000602082019050818103600083015262000b648162000b22565b9050919050565b7f5061796d656e7453706c69747465723a206e6f20706179656573000000000000600082015250565b600062000ba3601a8362000ac2565b915062000bb08262000b6b565b602082019050919050565b6000602082019050818103600083015262000bd68162000b94565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b600062000c528262000c3b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141562000c885762000c8762000c0c565b5b600182019050919050565b7f5061796d656e7453706c69747465723a206163636f756e74206973207468652060008201527f7a65726f20616464726573730000000000000000000000000000000000000000602082015250565b600062000cf1602c8362000ac2565b915062000cfe8262000c93565b604082019050919050565b6000602082019050818103600083015262000d248162000ce2565b9050919050565b7f5061796d656e7453706c69747465723a20736861726573206172652030000000600082015250565b600062000d63601d8362000ac2565b915062000d708262000d2b565b602082019050919050565b6000602082019050818103600083015262000d968162000d54565b9050919050565b7f5061796d656e7453706c69747465723a206163636f756e7420616c726561647960008201527f2068617320736861726573000000000000000000000000000000000000000000602082015250565b600062000dfb602b8362000ac2565b915062000e088262000d9d565b604082019050919050565b6000602082019050818103600083015262000e2e8162000dec565b9050919050565b600062000e428262000c3b565b915062000e4f8362000c3b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111562000e875762000e8662000c0c565b5b828201905092915050565b62000e9d8162000a4b565b82525050565b62000eae8162000c3b565b82525050565b600060408201905062000ecb600083018562000e92565b62000eda602083018462000ea3565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168062000f2957607f821691505b6020821081141562000f405762000f3f62000ee1565b5b50919050565b615da98062000f566000396000f3fe6080604052600436106102e85760003560e01c8063715018a611610190578063c4e41b22116100dc578063d79779b211610095578063e985e9c51161006f578063e985e9c514610b9a578063eb8d244414610bd7578063f2fde38b14610c02578063f4a0a52814610c2b5761032f565b8063d79779b214610af5578063e33b7de314610b32578063e5063b4e14610b5d5761032f565b8063c4e41b22146109cf578063c87b56dd146109fa578063ce7c2ac214610a37578063cf30901214610a74578063d0d703d314610a9f578063d5abeb0114610aca5761032f565b80639852595c11610149578063a22cb46511610123578063a22cb46514610915578063ab2fdb0c1461093e578063ae3692d41461097b578063b88d4fde146109a65761032f565b80639852595c146108a5578063989bdbb6146108e2578063a0712d68146108f95761032f565b8063715018a6146107a75780638b83209b146107be5780638da5cb5b146107fb57806394a4d5a91461082657806395d89b411461084f578063977b055b1461087a5761032f565b8063406072a91161024f5780634e71d92d116102085780636352211e116101e25780636352211e146106d95780636817c76c1461071657806370a0823114610741578063711897421461077e5761032f565b80634e71d92d1461065c57806355f804b314610673578063627fdeab1461069c5761032f565b8063406072a914610550578063406911011461058d57806342842e0e146105ca578063484b973c146105f357806348b750441461061c5780634b6bcbed146106455761032f565b806319165587116102a157806319165587146104445780631e0ba3151461046d57806323b872dd14610496578063283248be146104bf578063290775de146104fc5780633a98ef39146105255761032f565b806301ffc9a714610334578063049c5c491461037157806306fdde0314610388578063081812fc146103b3578063095ea7b3146103f057806318160ddd146104195761032f565b3661032f577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be770610316610c54565b3460405161032592919061437a565b60405180910390a1005b600080fd5b34801561034057600080fd5b5061035b6004803603810190610356919061440f565b610c5c565b6040516103689190614457565b60405180910390f35b34801561037d57600080fd5b50610386610d3e565b005b34801561039457600080fd5b5061039d610e2c565b6040516103aa919061450b565b60405180910390f35b3480156103bf57600080fd5b506103da60048036038101906103d59190614559565b610ebe565b6040516103e79190614586565b60405180910390f35b3480156103fc57600080fd5b50610417600480360381019061041291906145cd565b610f3a565b005b34801561042557600080fd5b5061042e611045565b60405161043b919061460d565b60405180910390f35b34801561045057600080fd5b5061046b60048036038101906104669190614666565b61105c565b005b34801561047957600080fd5b50610494600480360381019061048f91906146f8565b611207565b005b3480156104a257600080fd5b506104bd60048036038101906104b89190614758565b611603565b005b3480156104cb57600080fd5b506104e660048036038101906104e19190614559565b611613565b6040516104f39190614586565b60405180910390f35b34801561050857600080fd5b50610523600480360381019061051e91906147ab565b611652565b005b34801561053157600080fd5b5061053a611712565b604051610547919061460d565b60405180910390f35b34801561055c57600080fd5b5061057760048036038101906105729190614816565b61171c565b604051610584919061460d565b60405180910390f35b34801561059957600080fd5b506105b460048036038101906105af9190614559565b6117a3565b6040516105c19190614457565b60405180910390f35b3480156105d657600080fd5b506105f160048036038101906105ec9190614758565b6117c3565b005b3480156105ff57600080fd5b5061061a600480360381019061061591906145cd565b6117e3565b005b34801561062857600080fd5b50610643600480360381019061063e9190614816565b6118c4565b005b34801561065157600080fd5b5061065a611b7d565b005b34801561066857600080fd5b50610671611c6b565b005b34801561067f57600080fd5b5061069a60048036038101906106959190614986565b611c76565b005b3480156106a857600080fd5b506106c360048036038101906106be91906147ab565b611d5c565b6040516106d09190614a8d565b60405180910390f35b3480156106e557600080fd5b5061070060048036038101906106fb9190614559565b611f53565b60405161070d9190614586565b60405180910390f35b34801561072257600080fd5b5061072b611f69565b604051610738919061460d565b60405180910390f35b34801561074d57600080fd5b50610768600480360381019061076391906147ab565b611f6f565b604051610775919061460d565b60405180910390f35b34801561078a57600080fd5b506107a560048036038101906107a09190614559565b61203f565b005b3480156107b357600080fd5b506107bc6120c5565b005b3480156107ca57600080fd5b506107e560048036038101906107e09190614559565b61214d565b6040516107f29190614586565b60405180910390f35b34801561080757600080fd5b50610810612195565b60405161081d9190614586565b60405180910390f35b34801561083257600080fd5b5061084d60048036038101906108489190614b05565b6121bf565b005b34801561085b57600080fd5b506108646122da565b604051610871919061450b565b60405180910390f35b34801561088657600080fd5b5061088f61236c565b60405161089c919061460d565b60405180910390f35b3480156108b157600080fd5b506108cc60048036038101906108c791906147ab565b612372565b6040516108d9919061460d565b60405180910390f35b3480156108ee57600080fd5b506108f76123bb565b005b610913600480360381019061090e9190614559565b612454565b005b34801561092157600080fd5b5061093c60048036038101906109379190614bb2565b6126e9565b005b34801561094a57600080fd5b50610965600480360381019061096091906147ab565b612861565b604051610972919061460d565b60405180910390f35b34801561098757600080fd5b50610990612879565b60405161099d9190614586565b60405180910390f35b3480156109b257600080fd5b506109cd60048036038101906109c89190614c93565b61289f565b005b3480156109db57600080fd5b506109e461291b565b6040516109f1919061460d565b60405180910390f35b348015610a0657600080fd5b50610a216004803603810190610a1c9190614559565b61292a565b604051610a2e919061450b565b60405180910390f35b348015610a4357600080fd5b50610a5e6004803603810190610a5991906147ab565b61295b565b604051610a6b919061460d565b60405180910390f35b348015610a8057600080fd5b50610a896129a4565b604051610a969190614457565b60405180910390f35b348015610aab57600080fd5b50610ab46129b7565b604051610ac19190614457565b60405180910390f35b348015610ad657600080fd5b50610adf6129ca565b604051610aec919061460d565b60405180910390f35b348015610b0157600080fd5b50610b1c6004803603810190610b179190614d16565b6129d0565b604051610b29919061460d565b60405180910390f35b348015610b3e57600080fd5b50610b47612a19565b604051610b54919061460d565b60405180910390f35b348015610b6957600080fd5b50610b846004803603810190610b7f9190614559565b612a23565b604051610b919190614457565b60405180910390f35b348015610ba657600080fd5b50610bc16004803603810190610bbc9190614d43565b612a55565b604051610bce9190614457565b60405180910390f35b348015610be357600080fd5b50610bec612ae9565b604051610bf99190614457565b60405180910390f35b348015610c0e57600080fd5b50610c296004803603810190610c2491906147ab565b612afc565b005b348015610c3757600080fd5b50610c526004803603810190610c4d9190614559565b612bf4565b005b600033905090565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610d2757507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610d375750610d3682612c7a565b5b9050919050565b610d46610c54565b73ffffffffffffffffffffffffffffffffffffffff16610d64612195565b73ffffffffffffffffffffffffffffffffffffffff1614610dba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db190614dcf565b60405180910390fd5b601760009054906101000a900460ff1615601760006101000a81548160ff0219169083151502179055507f58655b75d3df612fe99ead00dbf0812d415d35078fe06217a94c0818bb13967f601760009054906101000a900460ff16604051610e229190614457565b60405180910390a1565b606060028054610e3b90614e1e565b80601f0160208091040260200160405190810160405280929190818152602001828054610e6790614e1e565b8015610eb45780601f10610e8957610100808354040283529160200191610eb4565b820191906000526020600020905b815481529060010190602001808311610e9757829003601f168201915b5050505050905090565b6000610ec982612ce4565b610eff576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610f4582611f53565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610fad576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610fcc610c54565b73ffffffffffffffffffffffffffffffffffffffff1614158015610ffe5750610ffc81610ff7610c54565b612a55565b155b15611035576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611040838383612d32565b505050565b600061104f612de4565b6001546000540303905090565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054116110de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d590614ec2565b60405180910390fd5b60006110e8612a19565b476110f39190614f11565b9050600061110a838361110586612372565b612ded565b90506000811415611150576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114790614fd9565b60405180910390fd5b80600d60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461119f9190614f11565b9250508190555080600b60008282546111b89190614f11565b925050819055506111c98382612e5b565b7fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b05683826040516111fa929190615058565b60405180910390a1505050565b6002600854141561124d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611244906150cd565b60405180910390fd5b6002600881905550601760019054906101000a900460ff166112a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129b90615139565b60405180910390fd5b8282905081146112e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112e0906151a5565b60405180910390fd5b601354816112f5611045565b6112ff9190614f11565b1115611340576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133790615211565b60405180910390fd5b6000601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016113a29190614586565b602060405180830381865afa1580156113bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e39190615246565b11611423576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141a906152bf565b60405180910390fd5b60005b848490508110156115ea57611453858583818110611447576114466152df565b5b90506020020135612a23565b611492576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114899061535a565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16636352211e8787858181106114d8576114d76152df565b5b905060200201356040518263ffffffff1660e01b81526004016114fb919061460d565b602060405180830381865afa158015611518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061153c919061538f565b73ffffffffffffffffffffffffffffffffffffffff1614611592576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158990615408565b60405180910390fd5b6001601860008787858181106115ab576115aa6152df565b5b90506020020135815260200190815260200160002060006101000a81548160ff02191690831515021790555080806115e290615428565b915050611426565b506115f53383612f4f565b506001600881905550505050565b61160e838383612f6d565b505050565b6015818154811061162357600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61165a610c54565b73ffffffffffffffffffffffffffffffffffffffff16611678612195565b73ffffffffffffffffffffffffffffffffffffffff16146116ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c590614dcf565b60405180910390fd5b80601460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600a54905090565b6000601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60186020528060005260406000206000915054906101000a900460ff1681565b6117de8383836040518060200160405280600081525061289f565b505050565b6117eb610c54565b73ffffffffffffffffffffffffffffffffffffffff16611809612195565b73ffffffffffffffffffffffffffffffffffffffff161461185f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185690614dcf565b60405180910390fd5b6013548161186b611045565b6118759190614f11565b11156118b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118ad90615211565b60405180910390fd5b6118c08282612f4f565b5050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411611946576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193d90614ec2565b60405180910390fd5b6000611951836129d0565b8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161198a9190614586565b602060405180830381865afa1580156119a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119cb9190615246565b6119d59190614f11565b905060006119ed83836119e8878761171c565b612ded565b90506000811415611a33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2a90614fd9565b60405180910390fd5b80601060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611abf9190614f11565b9250508190555080600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611b159190614f11565b92505081905550611b27848483613423565b8373ffffffffffffffffffffffffffffffffffffffff167f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a8483604051611b6f92919061437a565b60405180910390a250505050565b611b85610c54565b73ffffffffffffffffffffffffffffffffffffffff16611ba3612195565b73ffffffffffffffffffffffffffffffffffffffff1614611bf9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf090614dcf565b60405180910390fd5b601760019054906101000a900460ff1615601760016101000a81548160ff0219169083151502179055507fbc5b3e222a18d52c6bd2bc19880c605e9a1b50b11689f0315d149d12a26230fa601760019054906101000a900460ff16604051611c619190614457565b60405180910390a1565b611c743361105c565b565b611c7e610c54565b73ffffffffffffffffffffffffffffffffffffffff16611c9c612195565b73ffffffffffffffffffffffffffffffffffffffff1614611cf2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce990614dcf565b60405180910390fd5b601b60009054906101000a900460ff1615611d42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d39906154bd565b60405180910390fd5b80601a9080519060200190611d5892919061423a565b5050565b60606000611d6983611f6f565b67ffffffffffffffff811115611d8257611d8161485b565b5b604051908082528060200260200182016040528015611db05781602001602082028036833780820191505090505b50905060008054905060008060005b83811015611f46576000600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050806040015115611e9c5750611f39565b600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614611edc57806000015192505b8773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611f375781868580600101965081518110611f2a57611f296152df565b5b6020026020010181815250505b505b8080600101915050611dbf565b5083945050505050919050565b6000611f5e826134a9565b600001519050919050565b60115481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611fd7576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b612047610c54565b73ffffffffffffffffffffffffffffffffffffffff16612065612195565b73ffffffffffffffffffffffffffffffffffffffff16146120bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120b290614dcf565b60405180910390fd5b8060128190555050565b6120cd610c54565b73ffffffffffffffffffffffffffffffffffffffff166120eb612195565b73ffffffffffffffffffffffffffffffffffffffff1614612141576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213890614dcf565b60405180910390fd5b61214b6000613738565b565b6000600e8281548110612163576121626152df565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6121c7610c54565b73ffffffffffffffffffffffffffffffffffffffff166121e5612195565b73ffffffffffffffffffffffffffffffffffffffff161461223b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223290614dcf565b60405180910390fd5b60005b828290508110156122d35761227b85858381811061225f5761225e6152df565b5b905060200201602081019061227491906147ab565b6001612f4f565b600160186000858585818110612294576122936152df565b5b90506020020135815260200190815260200160002060006101000a81548160ff02191690831515021790555080806122cb90615428565b91505061223e565b5050505050565b6060600380546122e990614e1e565b80601f016020809104026020016040519081016040528092919081815260200182805461231590614e1e565b80156123625780601f1061233757610100808354040283529160200191612362565b820191906000526020600020905b81548152906001019060200180831161234557829003601f168201915b5050505050905090565b60125481565b6000600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6123c3610c54565b73ffffffffffffffffffffffffffffffffffffffff166123e1612195565b73ffffffffffffffffffffffffffffffffffffffff1614612437576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161242e90614dcf565b60405180910390fd5b6001601b60006101000a81548160ff021916908315150217905550565b6002600854141561249a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612491906150cd565b60405180910390fd5b6002600881905550601760009054906101000a900460ff166124f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e890615529565b60405180910390fd5b60125481601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461253f9190614f11565b1115612580576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612577906155bb565b60405180910390fd5b6013548161258c611045565b6125969190614f11565b11156125d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ce90615211565b60405180910390fd5b601354816125e3611045565b6125ed9190614f11565b111561262e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161262590615627565b60405180910390fd5b348160115461263d9190615647565b111561267e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612675906156ed565b60405180910390fd5b6126883382612f4f565b80601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546126d79190614f11565b92505081905550600160088190555050565b6126f1610c54565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612756576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060076000612763610c54565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612810610c54565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516128559190614457565b60405180910390a35050565b60196020528060005260406000206000915090505481565b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6128aa848484612f6d565b6128c98373ffffffffffffffffffffffffffffffffffffffff166137fe565b80156128de57506128dc84848484613811565b155b15612915576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6000612925611045565b905090565b606061293582613962565b6040516020016129459190615795565b6040516020818303038152906040529050919050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b601b60009054906101000a900460ff1681565b601760019054906101000a900460ff1681565b60135481565b6000600f60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000600b54905090565b6000600115156018600084815260200190815260200160002060009054906101000a900460ff16151514159050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b601760009054906101000a900460ff1681565b612b04610c54565b73ffffffffffffffffffffffffffffffffffffffff16612b22612195565b73ffffffffffffffffffffffffffffffffffffffff1614612b78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b6f90614dcf565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612be8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bdf90615829565b60405180910390fd5b612bf181613738565b50565b612bfc610c54565b73ffffffffffffffffffffffffffffffffffffffff16612c1a612195565b73ffffffffffffffffffffffffffffffffffffffff1614612c70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c6790614dcf565b60405180910390fd5b8060118190555050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600081612cef612de4565b11158015612cfe575060005482105b8015612d2b575060046000838152602001908152602001600020600001601c9054906101000a900460ff16155b9050919050565b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006001905090565b600081600a54600c60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485612e3e9190615647565b612e489190615878565b612e5291906158a9565b90509392505050565b80471015612e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9590615929565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff1682604051612ec49061597a565b60006040518083038185875af1925050503d8060008114612f01576040519150601f19603f3d011682016040523d82523d6000602084013e612f06565b606091505b5050905080612f4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f4190615a01565b60405180910390fd5b505050565b612f69828260405180602001604052806000815250613a01565b5050565b6000612f78826134a9565b90508373ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614612fe3576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff16613004610c54565b73ffffffffffffffffffffffffffffffffffffffff16148061303357506130328561302d610c54565b612a55565b5b806130785750613041610c54565b73ffffffffffffffffffffffffffffffffffffffff1661306084610ebe565b73ffffffffffffffffffffffffffffffffffffffff16145b9050806130b1576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415613118576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131258585856001613a13565b61313160008487612d32565b6001600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160392506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600460008581526020019081526020016000209050848160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550428160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060006001850190506000600460008381526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156133b15760005482146133b057878160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084602001518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b505050828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461341c8585856001613a19565b5050505050565b6134a48363a9059cbb60e01b848460405160240161344292919061437a565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613a1f565b505050565b6134b16142c0565b6000829050806134bf612de4565b111580156134ce575060005481105b15613701576000600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff161515151581525050905080604001516136ff57600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16146135e3578092505050613733565b5b6001156136fe57818060019003925050600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16146136f9578092505050613733565b6135e4565b5b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080823b905060008111915050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613837610c54565b8786866040518563ffffffff1660e01b81526004016138599493929190615a76565b6020604051808303816000875af192505050801561389557506040513d601f19601f820116820180604052508101906138929190615ad7565b60015b61390f573d80600081146138c5576040519150601f19603f3d011682016040523d82523d6000602084013e6138ca565b606091505b50600081511415613907576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b606061396d82612ce4565b6139a3576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006139ad613ae6565b90506000815114156139ce57604051806020016040528060008152506139f9565b806139d884613b78565b6040516020016139e9929190615b04565b6040516020818303038152906040525b915050919050565b613a0e8383836001613cd9565b505050565b50505050565b50505050565b6000613a81826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166140a79092919063ffffffff16565b9050600081511115613ae15780806020019051810190613aa19190615b3d565b613ae0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613ad790615bdc565b60405180910390fd5b5b505050565b6060601a8054613af590614e1e565b80601f0160208091040260200160405190810160405280929190818152602001828054613b2190614e1e565b8015613b6e5780601f10613b4357610100808354040283529160200191613b6e565b820191906000526020600020905b815481529060010190602001808311613b5157829003601f168201915b5050505050905090565b60606000821415613bc0576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050613cd4565b600082905060005b60008214613bf2578080613bdb90615428565b915050600a82613beb9190615878565b9150613bc8565b60008167ffffffffffffffff811115613c0e57613c0d61485b565b5b6040519080825280601f01601f191660200182016040528015613c405781602001600182028036833780820191505090505b5090505b60008514613ccd57600182613c5991906158a9565b9150600a85613c689190615bfc565b6030613c749190614f11565b60f81b818381518110613c8a57613c896152df565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85613cc69190615878565b9450613c44565b8093505050505b919050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415613d46576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000841415613d81576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d8e6000868387613a13565b83600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555083600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550846004600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426004600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600081905060008582019050838015613f585750613f578773ffffffffffffffffffffffffffffffffffffffff166137fe565b5b1561401e575b818773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4613fcd6000888480600101955088613811565b614003576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80821415613f5e57826000541461401957600080fd5b61408a565b5b818060010192508773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48082141561401f575b8160008190555050506140a06000868387613a19565b5050505050565b60606140b684846000856140bf565b90509392505050565b606082471015614104576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016140fb90615c9f565b60405180910390fd5b61410d856137fe565b61414c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161414390615d0b565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516141759190615d5c565b60006040518083038185875af1925050503d80600081146141b2576040519150601f19603f3d011682016040523d82523d6000602084013e6141b7565b606091505b50915091506141c78282866141d3565b92505050949350505050565b606083156141e357829050614233565b6000835111156141f65782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161422a919061450b565b60405180910390fd5b9392505050565b82805461424690614e1e565b90600052602060002090601f01602090048101928261426857600085556142af565b82601f1061428157805160ff19168380011785556142af565b828001600101855582156142af579182015b828111156142ae578251825591602001919060010190614293565b5b5090506142bc9190614303565b5090565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681526020016000151581525090565b5b8082111561431c576000816000905550600101614304565b5090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061434b82614320565b9050919050565b61435b81614340565b82525050565b6000819050919050565b61437481614361565b82525050565b600060408201905061438f6000830185614352565b61439c602083018461436b565b9392505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6143ec816143b7565b81146143f757600080fd5b50565b600081359050614409816143e3565b92915050565b600060208284031215614425576144246143ad565b5b6000614433848285016143fa565b91505092915050565b60008115159050919050565b6144518161443c565b82525050565b600060208201905061446c6000830184614448565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156144ac578082015181840152602081019050614491565b838111156144bb576000848401525b50505050565b6000601f19601f8301169050919050565b60006144dd82614472565b6144e7818561447d565b93506144f781856020860161448e565b614500816144c1565b840191505092915050565b6000602082019050818103600083015261452581846144d2565b905092915050565b61453681614361565b811461454157600080fd5b50565b6000813590506145538161452d565b92915050565b60006020828403121561456f5761456e6143ad565b5b600061457d84828501614544565b91505092915050565b600060208201905061459b6000830184614352565b92915050565b6145aa81614340565b81146145b557600080fd5b50565b6000813590506145c7816145a1565b92915050565b600080604083850312156145e4576145e36143ad565b5b60006145f2858286016145b8565b925050602061460385828601614544565b9150509250929050565b6000602082019050614622600083018461436b565b92915050565b600061463382614320565b9050919050565b61464381614628565b811461464e57600080fd5b50565b6000813590506146608161463a565b92915050565b60006020828403121561467c5761467b6143ad565b5b600061468a84828501614651565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126146b8576146b7614693565b5b8235905067ffffffffffffffff8111156146d5576146d4614698565b5b6020830191508360208202830111156146f1576146f061469d565b5b9250929050565b600080600060408486031215614711576147106143ad565b5b600084013567ffffffffffffffff81111561472f5761472e6143b2565b5b61473b868287016146a2565b9350935050602061474e86828701614544565b9150509250925092565b600080600060608486031215614771576147706143ad565b5b600061477f868287016145b8565b9350506020614790868287016145b8565b92505060406147a186828701614544565b9150509250925092565b6000602082840312156147c1576147c06143ad565b5b60006147cf848285016145b8565b91505092915050565b60006147e382614340565b9050919050565b6147f3816147d8565b81146147fe57600080fd5b50565b600081359050614810816147ea565b92915050565b6000806040838503121561482d5761482c6143ad565b5b600061483b85828601614801565b925050602061484c858286016145b8565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b614893826144c1565b810181811067ffffffffffffffff821117156148b2576148b161485b565b5b80604052505050565b60006148c56143a3565b90506148d1828261488a565b919050565b600067ffffffffffffffff8211156148f1576148f061485b565b5b6148fa826144c1565b9050602081019050919050565b82818337600083830152505050565b6000614929614924846148d6565b6148bb565b90508281526020810184848401111561494557614944614856565b5b614950848285614907565b509392505050565b600082601f83011261496d5761496c614693565b5b813561497d848260208601614916565b91505092915050565b60006020828403121561499c5761499b6143ad565b5b600082013567ffffffffffffffff8111156149ba576149b96143b2565b5b6149c684828501614958565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614a0481614361565b82525050565b6000614a1683836149fb565b60208301905092915050565b6000602082019050919050565b6000614a3a826149cf565b614a4481856149da565b9350614a4f836149eb565b8060005b83811015614a80578151614a678882614a0a565b9750614a7283614a22565b925050600181019050614a53565b5085935050505092915050565b60006020820190508181036000830152614aa78184614a2f565b905092915050565b60008083601f840112614ac557614ac4614693565b5b8235905067ffffffffffffffff811115614ae257614ae1614698565b5b602083019150836020820283011115614afe57614afd61469d565b5b9250929050565b60008060008060408587031215614b1f57614b1e6143ad565b5b600085013567ffffffffffffffff811115614b3d57614b3c6143b2565b5b614b4987828801614aaf565b9450945050602085013567ffffffffffffffff811115614b6c57614b6b6143b2565b5b614b78878288016146a2565b925092505092959194509250565b614b8f8161443c565b8114614b9a57600080fd5b50565b600081359050614bac81614b86565b92915050565b60008060408385031215614bc957614bc86143ad565b5b6000614bd7858286016145b8565b9250506020614be885828601614b9d565b9150509250929050565b600067ffffffffffffffff821115614c0d57614c0c61485b565b5b614c16826144c1565b9050602081019050919050565b6000614c36614c3184614bf2565b6148bb565b905082815260208101848484011115614c5257614c51614856565b5b614c5d848285614907565b509392505050565b600082601f830112614c7a57614c79614693565b5b8135614c8a848260208601614c23565b91505092915050565b60008060008060808587031215614cad57614cac6143ad565b5b6000614cbb878288016145b8565b9450506020614ccc878288016145b8565b9350506040614cdd87828801614544565b925050606085013567ffffffffffffffff811115614cfe57614cfd6143b2565b5b614d0a87828801614c65565b91505092959194509250565b600060208284031215614d2c57614d2b6143ad565b5b6000614d3a84828501614801565b91505092915050565b60008060408385031215614d5a57614d596143ad565b5b6000614d68858286016145b8565b9250506020614d79858286016145b8565b9150509250929050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614db960208361447d565b9150614dc482614d83565b602082019050919050565b60006020820190508181036000830152614de881614dac565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680614e3657607f821691505b60208210811415614e4a57614e49614def565b5b50919050565b7f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060008201527f7368617265730000000000000000000000000000000000000000000000000000602082015250565b6000614eac60268361447d565b9150614eb782614e50565b604082019050919050565b60006020820190508181036000830152614edb81614e9f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614f1c82614361565b9150614f2783614361565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614f5c57614f5b614ee2565b5b828201905092915050565b7f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060008201527f647565207061796d656e74000000000000000000000000000000000000000000602082015250565b6000614fc3602b8361447d565b9150614fce82614f67565b604082019050919050565b60006020820190508181036000830152614ff281614fb6565b9050919050565b6000819050919050565b600061501e61501961501484614320565b614ff9565b614320565b9050919050565b600061503082615003565b9050919050565b600061504282615025565b9050919050565b61505281615037565b82525050565b600060408201905061506d6000830185615049565b61507a602083018461436b565b9392505050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006150b7601f8361447d565b91506150c282615081565b602082019050919050565b600060208201905081810360008301526150e6816150aa565b9050919050565b7f484f4c4445525f53414c455f494e414354495645000000000000000000000000600082015250565b600061512360148361447d565b915061512e826150ed565b602082019050919050565b6000602082019050818103600083015261515281615116565b9050919050565b7f494e53554646494349454e545f414c5f544f4b454e5300000000000000000000600082015250565b600061518f60168361447d565b915061519a82615159565b602082019050919050565b600060208201905081810360008301526151be81615182565b9050919050565b7f534f4c445f4f5554000000000000000000000000000000000000000000000000600082015250565b60006151fb60088361447d565b9150615206826151c5565b602082019050919050565b6000602082019050818103600083015261522a816151ee565b9050919050565b6000815190506152408161452d565b92915050565b60006020828403121561525c5761525b6143ad565b5b600061526a84828501615231565b91505092915050565b7f4e4f5f414c5f544f4b454e530000000000000000000000000000000000000000600082015250565b60006152a9600c8361447d565b91506152b482615273565b602082019050919050565b600060208201905081810360008301526152d88161529c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f414c5f414c52454144595f434c41494d45440000000000000000000000000000600082015250565b600061534460128361447d565b915061534f8261530e565b602082019050919050565b6000602082019050818103600083015261537381615337565b9050919050565b600081519050615389816145a1565b92915050565b6000602082840312156153a5576153a46143ad565b5b60006153b38482850161537a565b91505092915050565b7f4e4f545f414c5f4f574e45520000000000000000000000000000000000000000600082015250565b60006153f2600c8361447d565b91506153fd826153bc565b602082019050919050565b60006020820190508181036000830152615421816153e5565b9050919050565b600061543382614361565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561546657615465614ee2565b5b600182019050919050565b7f4d455441444154415f4c4f434b45440000000000000000000000000000000000600082015250565b60006154a7600f8361447d565b91506154b282615471565b602082019050919050565b600060208201905081810360008301526154d68161549a565b9050919050565b7f53414c455f494e41435449564500000000000000000000000000000000000000600082015250565b6000615513600d8361447d565b915061551e826154dd565b602082019050919050565b6000602082019050818103600083015261554281615506565b9050919050565b7f7468697320776f756c6420657863656564206d696e74206d617820616c6c6f7760008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b60006155a560248361447d565b91506155b082615549565b604082019050919050565b600060208201905081810360008301526155d481615598565b9050919050565b7f5055424c49435f534f4c445f4f55540000000000000000000000000000000000600082015250565b6000615611600f8361447d565b915061561c826155db565b602082019050919050565b6000602082019050818103600083015261564081615604565b9050919050565b600061565282614361565b915061565d83614361565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561569657615695614ee2565b5b828202905092915050565b7f494e434f52524543545f45544845525f56414c55450000000000000000000000600082015250565b60006156d760158361447d565b91506156e2826156a1565b602082019050919050565b60006020820190508181036000830152615706816156ca565b9050919050565b600081905092915050565b600061572382614472565b61572d818561570d565b935061573d81856020860161448e565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b600061577f60058361570d565b915061578a82615749565b600582019050919050565b60006157a18284615718565b91506157ac82615772565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061581360268361447d565b915061581e826157b7565b604082019050919050565b6000602082019050818103600083015261584281615806565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061588382614361565b915061588e83614361565b92508261589e5761589d615849565b5b828204905092915050565b60006158b482614361565b91506158bf83614361565b9250828210156158d2576158d1614ee2565b5b828203905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b6000615913601d8361447d565b915061591e826158dd565b602082019050919050565b6000602082019050818103600083015261594281615906565b9050919050565b600081905092915050565b50565b6000615964600083615949565b915061596f82615954565b600082019050919050565b600061598582615957565b9150819050919050565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b60006159eb603a8361447d565b91506159f68261598f565b604082019050919050565b60006020820190508181036000830152615a1a816159de565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000615a4882615a21565b615a528185615a2c565b9350615a6281856020860161448e565b615a6b816144c1565b840191505092915050565b6000608082019050615a8b6000830187614352565b615a986020830186614352565b615aa5604083018561436b565b8181036060830152615ab78184615a3d565b905095945050505050565b600081519050615ad1816143e3565b92915050565b600060208284031215615aed57615aec6143ad565b5b6000615afb84828501615ac2565b91505092915050565b6000615b108285615718565b9150615b1c8284615718565b91508190509392505050565b600081519050615b3781614b86565b92915050565b600060208284031215615b5357615b526143ad565b5b6000615b6184828501615b28565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000615bc6602a8361447d565b9150615bd182615b6a565b604082019050919050565b60006020820190508181036000830152615bf581615bb9565b9050919050565b6000615c0782614361565b9150615c1283614361565b925082615c2257615c21615849565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000615c8960268361447d565b9150615c9482615c2d565b604082019050919050565b60006020820190508181036000830152615cb881615c7c565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000615cf5601d8361447d565b9150615d0082615cbf565b602082019050919050565b60006020820190508181036000830152615d2481615ce8565b9050919050565b6000615d3682615a21565b615d408185615949565b9350615d5081856020860161448e565b80840191505092915050565b6000615d688284615d2b565b91508190509291505056fea26469706673582212208c770796ef3735677e101d06545383accc9b6a790036483d526c7bc7a49c01d064736f6c634300080a0033687474703a2f2f697066732e696f2f697066732f516d55314d5361676b7a7776784b4a35315148766938616f42775161354362733748383739794b6857376b7032552f00000000000000000000000061028f622cb6618cac3deb9ef0f0d5b9c6369c72

Deployed Bytecode

0x6080604052600436106102e85760003560e01c8063715018a611610190578063c4e41b22116100dc578063d79779b211610095578063e985e9c51161006f578063e985e9c514610b9a578063eb8d244414610bd7578063f2fde38b14610c02578063f4a0a52814610c2b5761032f565b8063d79779b214610af5578063e33b7de314610b32578063e5063b4e14610b5d5761032f565b8063c4e41b22146109cf578063c87b56dd146109fa578063ce7c2ac214610a37578063cf30901214610a74578063d0d703d314610a9f578063d5abeb0114610aca5761032f565b80639852595c11610149578063a22cb46511610123578063a22cb46514610915578063ab2fdb0c1461093e578063ae3692d41461097b578063b88d4fde146109a65761032f565b80639852595c146108a5578063989bdbb6146108e2578063a0712d68146108f95761032f565b8063715018a6146107a75780638b83209b146107be5780638da5cb5b146107fb57806394a4d5a91461082657806395d89b411461084f578063977b055b1461087a5761032f565b8063406072a91161024f5780634e71d92d116102085780636352211e116101e25780636352211e146106d95780636817c76c1461071657806370a0823114610741578063711897421461077e5761032f565b80634e71d92d1461065c57806355f804b314610673578063627fdeab1461069c5761032f565b8063406072a914610550578063406911011461058d57806342842e0e146105ca578063484b973c146105f357806348b750441461061c5780634b6bcbed146106455761032f565b806319165587116102a157806319165587146104445780631e0ba3151461046d57806323b872dd14610496578063283248be146104bf578063290775de146104fc5780633a98ef39146105255761032f565b806301ffc9a714610334578063049c5c491461037157806306fdde0314610388578063081812fc146103b3578063095ea7b3146103f057806318160ddd146104195761032f565b3661032f577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be770610316610c54565b3460405161032592919061437a565b60405180910390a1005b600080fd5b34801561034057600080fd5b5061035b6004803603810190610356919061440f565b610c5c565b6040516103689190614457565b60405180910390f35b34801561037d57600080fd5b50610386610d3e565b005b34801561039457600080fd5b5061039d610e2c565b6040516103aa919061450b565b60405180910390f35b3480156103bf57600080fd5b506103da60048036038101906103d59190614559565b610ebe565b6040516103e79190614586565b60405180910390f35b3480156103fc57600080fd5b50610417600480360381019061041291906145cd565b610f3a565b005b34801561042557600080fd5b5061042e611045565b60405161043b919061460d565b60405180910390f35b34801561045057600080fd5b5061046b60048036038101906104669190614666565b61105c565b005b34801561047957600080fd5b50610494600480360381019061048f91906146f8565b611207565b005b3480156104a257600080fd5b506104bd60048036038101906104b89190614758565b611603565b005b3480156104cb57600080fd5b506104e660048036038101906104e19190614559565b611613565b6040516104f39190614586565b60405180910390f35b34801561050857600080fd5b50610523600480360381019061051e91906147ab565b611652565b005b34801561053157600080fd5b5061053a611712565b604051610547919061460d565b60405180910390f35b34801561055c57600080fd5b5061057760048036038101906105729190614816565b61171c565b604051610584919061460d565b60405180910390f35b34801561059957600080fd5b506105b460048036038101906105af9190614559565b6117a3565b6040516105c19190614457565b60405180910390f35b3480156105d657600080fd5b506105f160048036038101906105ec9190614758565b6117c3565b005b3480156105ff57600080fd5b5061061a600480360381019061061591906145cd565b6117e3565b005b34801561062857600080fd5b50610643600480360381019061063e9190614816565b6118c4565b005b34801561065157600080fd5b5061065a611b7d565b005b34801561066857600080fd5b50610671611c6b565b005b34801561067f57600080fd5b5061069a60048036038101906106959190614986565b611c76565b005b3480156106a857600080fd5b506106c360048036038101906106be91906147ab565b611d5c565b6040516106d09190614a8d565b60405180910390f35b3480156106e557600080fd5b5061070060048036038101906106fb9190614559565b611f53565b60405161070d9190614586565b60405180910390f35b34801561072257600080fd5b5061072b611f69565b604051610738919061460d565b60405180910390f35b34801561074d57600080fd5b50610768600480360381019061076391906147ab565b611f6f565b604051610775919061460d565b60405180910390f35b34801561078a57600080fd5b506107a560048036038101906107a09190614559565b61203f565b005b3480156107b357600080fd5b506107bc6120c5565b005b3480156107ca57600080fd5b506107e560048036038101906107e09190614559565b61214d565b6040516107f29190614586565b60405180910390f35b34801561080757600080fd5b50610810612195565b60405161081d9190614586565b60405180910390f35b34801561083257600080fd5b5061084d60048036038101906108489190614b05565b6121bf565b005b34801561085b57600080fd5b506108646122da565b604051610871919061450b565b60405180910390f35b34801561088657600080fd5b5061088f61236c565b60405161089c919061460d565b60405180910390f35b3480156108b157600080fd5b506108cc60048036038101906108c791906147ab565b612372565b6040516108d9919061460d565b60405180910390f35b3480156108ee57600080fd5b506108f76123bb565b005b610913600480360381019061090e9190614559565b612454565b005b34801561092157600080fd5b5061093c60048036038101906109379190614bb2565b6126e9565b005b34801561094a57600080fd5b50610965600480360381019061096091906147ab565b612861565b604051610972919061460d565b60405180910390f35b34801561098757600080fd5b50610990612879565b60405161099d9190614586565b60405180910390f35b3480156109b257600080fd5b506109cd60048036038101906109c89190614c93565b61289f565b005b3480156109db57600080fd5b506109e461291b565b6040516109f1919061460d565b60405180910390f35b348015610a0657600080fd5b50610a216004803603810190610a1c9190614559565b61292a565b604051610a2e919061450b565b60405180910390f35b348015610a4357600080fd5b50610a5e6004803603810190610a5991906147ab565b61295b565b604051610a6b919061460d565b60405180910390f35b348015610a8057600080fd5b50610a896129a4565b604051610a969190614457565b60405180910390f35b348015610aab57600080fd5b50610ab46129b7565b604051610ac19190614457565b60405180910390f35b348015610ad657600080fd5b50610adf6129ca565b604051610aec919061460d565b60405180910390f35b348015610b0157600080fd5b50610b1c6004803603810190610b179190614d16565b6129d0565b604051610b29919061460d565b60405180910390f35b348015610b3e57600080fd5b50610b47612a19565b604051610b54919061460d565b60405180910390f35b348015610b6957600080fd5b50610b846004803603810190610b7f9190614559565b612a23565b604051610b919190614457565b60405180910390f35b348015610ba657600080fd5b50610bc16004803603810190610bbc9190614d43565b612a55565b604051610bce9190614457565b60405180910390f35b348015610be357600080fd5b50610bec612ae9565b604051610bf99190614457565b60405180910390f35b348015610c0e57600080fd5b50610c296004803603810190610c2491906147ab565b612afc565b005b348015610c3757600080fd5b50610c526004803603810190610c4d9190614559565b612bf4565b005b600033905090565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610d2757507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610d375750610d3682612c7a565b5b9050919050565b610d46610c54565b73ffffffffffffffffffffffffffffffffffffffff16610d64612195565b73ffffffffffffffffffffffffffffffffffffffff1614610dba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db190614dcf565b60405180910390fd5b601760009054906101000a900460ff1615601760006101000a81548160ff0219169083151502179055507f58655b75d3df612fe99ead00dbf0812d415d35078fe06217a94c0818bb13967f601760009054906101000a900460ff16604051610e229190614457565b60405180910390a1565b606060028054610e3b90614e1e565b80601f0160208091040260200160405190810160405280929190818152602001828054610e6790614e1e565b8015610eb45780601f10610e8957610100808354040283529160200191610eb4565b820191906000526020600020905b815481529060010190602001808311610e9757829003601f168201915b5050505050905090565b6000610ec982612ce4565b610eff576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610f4582611f53565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610fad576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610fcc610c54565b73ffffffffffffffffffffffffffffffffffffffff1614158015610ffe5750610ffc81610ff7610c54565b612a55565b155b15611035576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611040838383612d32565b505050565b600061104f612de4565b6001546000540303905090565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054116110de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d590614ec2565b60405180910390fd5b60006110e8612a19565b476110f39190614f11565b9050600061110a838361110586612372565b612ded565b90506000811415611150576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114790614fd9565b60405180910390fd5b80600d60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461119f9190614f11565b9250508190555080600b60008282546111b89190614f11565b925050819055506111c98382612e5b565b7fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b05683826040516111fa929190615058565b60405180910390a1505050565b6002600854141561124d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611244906150cd565b60405180910390fd5b6002600881905550601760019054906101000a900460ff166112a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129b90615139565b60405180910390fd5b8282905081146112e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112e0906151a5565b60405180910390fd5b601354816112f5611045565b6112ff9190614f11565b1115611340576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133790615211565b60405180910390fd5b6000601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016113a29190614586565b602060405180830381865afa1580156113bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e39190615246565b11611423576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141a906152bf565b60405180910390fd5b60005b848490508110156115ea57611453858583818110611447576114466152df565b5b90506020020135612a23565b611492576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114899061535a565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16636352211e8787858181106114d8576114d76152df565b5b905060200201356040518263ffffffff1660e01b81526004016114fb919061460d565b602060405180830381865afa158015611518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061153c919061538f565b73ffffffffffffffffffffffffffffffffffffffff1614611592576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158990615408565b60405180910390fd5b6001601860008787858181106115ab576115aa6152df565b5b90506020020135815260200190815260200160002060006101000a81548160ff02191690831515021790555080806115e290615428565b915050611426565b506115f53383612f4f565b506001600881905550505050565b61160e838383612f6d565b505050565b6015818154811061162357600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61165a610c54565b73ffffffffffffffffffffffffffffffffffffffff16611678612195565b73ffffffffffffffffffffffffffffffffffffffff16146116ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c590614dcf565b60405180910390fd5b80601460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600a54905090565b6000601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60186020528060005260406000206000915054906101000a900460ff1681565b6117de8383836040518060200160405280600081525061289f565b505050565b6117eb610c54565b73ffffffffffffffffffffffffffffffffffffffff16611809612195565b73ffffffffffffffffffffffffffffffffffffffff161461185f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185690614dcf565b60405180910390fd5b6013548161186b611045565b6118759190614f11565b11156118b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118ad90615211565b60405180910390fd5b6118c08282612f4f565b5050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411611946576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193d90614ec2565b60405180910390fd5b6000611951836129d0565b8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161198a9190614586565b602060405180830381865afa1580156119a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119cb9190615246565b6119d59190614f11565b905060006119ed83836119e8878761171c565b612ded565b90506000811415611a33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2a90614fd9565b60405180910390fd5b80601060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611abf9190614f11565b9250508190555080600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611b159190614f11565b92505081905550611b27848483613423565b8373ffffffffffffffffffffffffffffffffffffffff167f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a8483604051611b6f92919061437a565b60405180910390a250505050565b611b85610c54565b73ffffffffffffffffffffffffffffffffffffffff16611ba3612195565b73ffffffffffffffffffffffffffffffffffffffff1614611bf9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf090614dcf565b60405180910390fd5b601760019054906101000a900460ff1615601760016101000a81548160ff0219169083151502179055507fbc5b3e222a18d52c6bd2bc19880c605e9a1b50b11689f0315d149d12a26230fa601760019054906101000a900460ff16604051611c619190614457565b60405180910390a1565b611c743361105c565b565b611c7e610c54565b73ffffffffffffffffffffffffffffffffffffffff16611c9c612195565b73ffffffffffffffffffffffffffffffffffffffff1614611cf2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce990614dcf565b60405180910390fd5b601b60009054906101000a900460ff1615611d42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d39906154bd565b60405180910390fd5b80601a9080519060200190611d5892919061423a565b5050565b60606000611d6983611f6f565b67ffffffffffffffff811115611d8257611d8161485b565b5b604051908082528060200260200182016040528015611db05781602001602082028036833780820191505090505b50905060008054905060008060005b83811015611f46576000600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050806040015115611e9c5750611f39565b600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614611edc57806000015192505b8773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611f375781868580600101965081518110611f2a57611f296152df565b5b6020026020010181815250505b505b8080600101915050611dbf565b5083945050505050919050565b6000611f5e826134a9565b600001519050919050565b60115481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611fd7576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b612047610c54565b73ffffffffffffffffffffffffffffffffffffffff16612065612195565b73ffffffffffffffffffffffffffffffffffffffff16146120bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120b290614dcf565b60405180910390fd5b8060128190555050565b6120cd610c54565b73ffffffffffffffffffffffffffffffffffffffff166120eb612195565b73ffffffffffffffffffffffffffffffffffffffff1614612141576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213890614dcf565b60405180910390fd5b61214b6000613738565b565b6000600e8281548110612163576121626152df565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6121c7610c54565b73ffffffffffffffffffffffffffffffffffffffff166121e5612195565b73ffffffffffffffffffffffffffffffffffffffff161461223b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223290614dcf565b60405180910390fd5b60005b828290508110156122d35761227b85858381811061225f5761225e6152df565b5b905060200201602081019061227491906147ab565b6001612f4f565b600160186000858585818110612294576122936152df565b5b90506020020135815260200190815260200160002060006101000a81548160ff02191690831515021790555080806122cb90615428565b91505061223e565b5050505050565b6060600380546122e990614e1e565b80601f016020809104026020016040519081016040528092919081815260200182805461231590614e1e565b80156123625780601f1061233757610100808354040283529160200191612362565b820191906000526020600020905b81548152906001019060200180831161234557829003601f168201915b5050505050905090565b60125481565b6000600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6123c3610c54565b73ffffffffffffffffffffffffffffffffffffffff166123e1612195565b73ffffffffffffffffffffffffffffffffffffffff1614612437576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161242e90614dcf565b60405180910390fd5b6001601b60006101000a81548160ff021916908315150217905550565b6002600854141561249a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612491906150cd565b60405180910390fd5b6002600881905550601760009054906101000a900460ff166124f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e890615529565b60405180910390fd5b60125481601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461253f9190614f11565b1115612580576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612577906155bb565b60405180910390fd5b6013548161258c611045565b6125969190614f11565b11156125d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ce90615211565b60405180910390fd5b601354816125e3611045565b6125ed9190614f11565b111561262e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161262590615627565b60405180910390fd5b348160115461263d9190615647565b111561267e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612675906156ed565b60405180910390fd5b6126883382612f4f565b80601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546126d79190614f11565b92505081905550600160088190555050565b6126f1610c54565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612756576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060076000612763610c54565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612810610c54565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516128559190614457565b60405180910390a35050565b60196020528060005260406000206000915090505481565b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6128aa848484612f6d565b6128c98373ffffffffffffffffffffffffffffffffffffffff166137fe565b80156128de57506128dc84848484613811565b155b15612915576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6000612925611045565b905090565b606061293582613962565b6040516020016129459190615795565b6040516020818303038152906040529050919050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b601b60009054906101000a900460ff1681565b601760019054906101000a900460ff1681565b60135481565b6000600f60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000600b54905090565b6000600115156018600084815260200190815260200160002060009054906101000a900460ff16151514159050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b601760009054906101000a900460ff1681565b612b04610c54565b73ffffffffffffffffffffffffffffffffffffffff16612b22612195565b73ffffffffffffffffffffffffffffffffffffffff1614612b78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b6f90614dcf565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612be8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bdf90615829565b60405180910390fd5b612bf181613738565b50565b612bfc610c54565b73ffffffffffffffffffffffffffffffffffffffff16612c1a612195565b73ffffffffffffffffffffffffffffffffffffffff1614612c70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c6790614dcf565b60405180910390fd5b8060118190555050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600081612cef612de4565b11158015612cfe575060005482105b8015612d2b575060046000838152602001908152602001600020600001601c9054906101000a900460ff16155b9050919050565b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006001905090565b600081600a54600c60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485612e3e9190615647565b612e489190615878565b612e5291906158a9565b90509392505050565b80471015612e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9590615929565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff1682604051612ec49061597a565b60006040518083038185875af1925050503d8060008114612f01576040519150601f19603f3d011682016040523d82523d6000602084013e612f06565b606091505b5050905080612f4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f4190615a01565b60405180910390fd5b505050565b612f69828260405180602001604052806000815250613a01565b5050565b6000612f78826134a9565b90508373ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614612fe3576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff16613004610c54565b73ffffffffffffffffffffffffffffffffffffffff16148061303357506130328561302d610c54565b612a55565b5b806130785750613041610c54565b73ffffffffffffffffffffffffffffffffffffffff1661306084610ebe565b73ffffffffffffffffffffffffffffffffffffffff16145b9050806130b1576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415613118576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131258585856001613a13565b61313160008487612d32565b6001600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160392506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600460008581526020019081526020016000209050848160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550428160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060006001850190506000600460008381526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156133b15760005482146133b057878160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084602001518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b505050828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461341c8585856001613a19565b5050505050565b6134a48363a9059cbb60e01b848460405160240161344292919061437a565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613a1f565b505050565b6134b16142c0565b6000829050806134bf612de4565b111580156134ce575060005481105b15613701576000600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff161515151581525050905080604001516136ff57600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16146135e3578092505050613733565b5b6001156136fe57818060019003925050600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16146136f9578092505050613733565b6135e4565b5b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080823b905060008111915050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613837610c54565b8786866040518563ffffffff1660e01b81526004016138599493929190615a76565b6020604051808303816000875af192505050801561389557506040513d601f19601f820116820180604052508101906138929190615ad7565b60015b61390f573d80600081146138c5576040519150601f19603f3d011682016040523d82523d6000602084013e6138ca565b606091505b50600081511415613907576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b606061396d82612ce4565b6139a3576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006139ad613ae6565b90506000815114156139ce57604051806020016040528060008152506139f9565b806139d884613b78565b6040516020016139e9929190615b04565b6040516020818303038152906040525b915050919050565b613a0e8383836001613cd9565b505050565b50505050565b50505050565b6000613a81826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166140a79092919063ffffffff16565b9050600081511115613ae15780806020019051810190613aa19190615b3d565b613ae0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613ad790615bdc565b60405180910390fd5b5b505050565b6060601a8054613af590614e1e565b80601f0160208091040260200160405190810160405280929190818152602001828054613b2190614e1e565b8015613b6e5780601f10613b4357610100808354040283529160200191613b6e565b820191906000526020600020905b815481529060010190602001808311613b5157829003601f168201915b5050505050905090565b60606000821415613bc0576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050613cd4565b600082905060005b60008214613bf2578080613bdb90615428565b915050600a82613beb9190615878565b9150613bc8565b60008167ffffffffffffffff811115613c0e57613c0d61485b565b5b6040519080825280601f01601f191660200182016040528015613c405781602001600182028036833780820191505090505b5090505b60008514613ccd57600182613c5991906158a9565b9150600a85613c689190615bfc565b6030613c749190614f11565b60f81b818381518110613c8a57613c896152df565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85613cc69190615878565b9450613c44565b8093505050505b919050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415613d46576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000841415613d81576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d8e6000868387613a13565b83600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555083600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550846004600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426004600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600081905060008582019050838015613f585750613f578773ffffffffffffffffffffffffffffffffffffffff166137fe565b5b1561401e575b818773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4613fcd6000888480600101955088613811565b614003576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80821415613f5e57826000541461401957600080fd5b61408a565b5b818060010192508773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48082141561401f575b8160008190555050506140a06000868387613a19565b5050505050565b60606140b684846000856140bf565b90509392505050565b606082471015614104576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016140fb90615c9f565b60405180910390fd5b61410d856137fe565b61414c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161414390615d0b565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516141759190615d5c565b60006040518083038185875af1925050503d80600081146141b2576040519150601f19603f3d011682016040523d82523d6000602084013e6141b7565b606091505b50915091506141c78282866141d3565b92505050949350505050565b606083156141e357829050614233565b6000835111156141f65782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161422a919061450b565b60405180910390fd5b9392505050565b82805461424690614e1e565b90600052602060002090601f01602090048101928261426857600085556142af565b82601f1061428157805160ff19168380011785556142af565b828001600101855582156142af579182015b828111156142ae578251825591602001919060010190614293565b5b5090506142bc9190614303565b5090565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681526020016000151581525090565b5b8082111561431c576000816000905550600101614304565b5090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061434b82614320565b9050919050565b61435b81614340565b82525050565b6000819050919050565b61437481614361565b82525050565b600060408201905061438f6000830185614352565b61439c602083018461436b565b9392505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6143ec816143b7565b81146143f757600080fd5b50565b600081359050614409816143e3565b92915050565b600060208284031215614425576144246143ad565b5b6000614433848285016143fa565b91505092915050565b60008115159050919050565b6144518161443c565b82525050565b600060208201905061446c6000830184614448565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156144ac578082015181840152602081019050614491565b838111156144bb576000848401525b50505050565b6000601f19601f8301169050919050565b60006144dd82614472565b6144e7818561447d565b93506144f781856020860161448e565b614500816144c1565b840191505092915050565b6000602082019050818103600083015261452581846144d2565b905092915050565b61453681614361565b811461454157600080fd5b50565b6000813590506145538161452d565b92915050565b60006020828403121561456f5761456e6143ad565b5b600061457d84828501614544565b91505092915050565b600060208201905061459b6000830184614352565b92915050565b6145aa81614340565b81146145b557600080fd5b50565b6000813590506145c7816145a1565b92915050565b600080604083850312156145e4576145e36143ad565b5b60006145f2858286016145b8565b925050602061460385828601614544565b9150509250929050565b6000602082019050614622600083018461436b565b92915050565b600061463382614320565b9050919050565b61464381614628565b811461464e57600080fd5b50565b6000813590506146608161463a565b92915050565b60006020828403121561467c5761467b6143ad565b5b600061468a84828501614651565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126146b8576146b7614693565b5b8235905067ffffffffffffffff8111156146d5576146d4614698565b5b6020830191508360208202830111156146f1576146f061469d565b5b9250929050565b600080600060408486031215614711576147106143ad565b5b600084013567ffffffffffffffff81111561472f5761472e6143b2565b5b61473b868287016146a2565b9350935050602061474e86828701614544565b9150509250925092565b600080600060608486031215614771576147706143ad565b5b600061477f868287016145b8565b9350506020614790868287016145b8565b92505060406147a186828701614544565b9150509250925092565b6000602082840312156147c1576147c06143ad565b5b60006147cf848285016145b8565b91505092915050565b60006147e382614340565b9050919050565b6147f3816147d8565b81146147fe57600080fd5b50565b600081359050614810816147ea565b92915050565b6000806040838503121561482d5761482c6143ad565b5b600061483b85828601614801565b925050602061484c858286016145b8565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b614893826144c1565b810181811067ffffffffffffffff821117156148b2576148b161485b565b5b80604052505050565b60006148c56143a3565b90506148d1828261488a565b919050565b600067ffffffffffffffff8211156148f1576148f061485b565b5b6148fa826144c1565b9050602081019050919050565b82818337600083830152505050565b6000614929614924846148d6565b6148bb565b90508281526020810184848401111561494557614944614856565b5b614950848285614907565b509392505050565b600082601f83011261496d5761496c614693565b5b813561497d848260208601614916565b91505092915050565b60006020828403121561499c5761499b6143ad565b5b600082013567ffffffffffffffff8111156149ba576149b96143b2565b5b6149c684828501614958565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614a0481614361565b82525050565b6000614a1683836149fb565b60208301905092915050565b6000602082019050919050565b6000614a3a826149cf565b614a4481856149da565b9350614a4f836149eb565b8060005b83811015614a80578151614a678882614a0a565b9750614a7283614a22565b925050600181019050614a53565b5085935050505092915050565b60006020820190508181036000830152614aa78184614a2f565b905092915050565b60008083601f840112614ac557614ac4614693565b5b8235905067ffffffffffffffff811115614ae257614ae1614698565b5b602083019150836020820283011115614afe57614afd61469d565b5b9250929050565b60008060008060408587031215614b1f57614b1e6143ad565b5b600085013567ffffffffffffffff811115614b3d57614b3c6143b2565b5b614b4987828801614aaf565b9450945050602085013567ffffffffffffffff811115614b6c57614b6b6143b2565b5b614b78878288016146a2565b925092505092959194509250565b614b8f8161443c565b8114614b9a57600080fd5b50565b600081359050614bac81614b86565b92915050565b60008060408385031215614bc957614bc86143ad565b5b6000614bd7858286016145b8565b9250506020614be885828601614b9d565b9150509250929050565b600067ffffffffffffffff821115614c0d57614c0c61485b565b5b614c16826144c1565b9050602081019050919050565b6000614c36614c3184614bf2565b6148bb565b905082815260208101848484011115614c5257614c51614856565b5b614c5d848285614907565b509392505050565b600082601f830112614c7a57614c79614693565b5b8135614c8a848260208601614c23565b91505092915050565b60008060008060808587031215614cad57614cac6143ad565b5b6000614cbb878288016145b8565b9450506020614ccc878288016145b8565b9350506040614cdd87828801614544565b925050606085013567ffffffffffffffff811115614cfe57614cfd6143b2565b5b614d0a87828801614c65565b91505092959194509250565b600060208284031215614d2c57614d2b6143ad565b5b6000614d3a84828501614801565b91505092915050565b60008060408385031215614d5a57614d596143ad565b5b6000614d68858286016145b8565b9250506020614d79858286016145b8565b9150509250929050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614db960208361447d565b9150614dc482614d83565b602082019050919050565b60006020820190508181036000830152614de881614dac565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680614e3657607f821691505b60208210811415614e4a57614e49614def565b5b50919050565b7f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060008201527f7368617265730000000000000000000000000000000000000000000000000000602082015250565b6000614eac60268361447d565b9150614eb782614e50565b604082019050919050565b60006020820190508181036000830152614edb81614e9f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614f1c82614361565b9150614f2783614361565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614f5c57614f5b614ee2565b5b828201905092915050565b7f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060008201527f647565207061796d656e74000000000000000000000000000000000000000000602082015250565b6000614fc3602b8361447d565b9150614fce82614f67565b604082019050919050565b60006020820190508181036000830152614ff281614fb6565b9050919050565b6000819050919050565b600061501e61501961501484614320565b614ff9565b614320565b9050919050565b600061503082615003565b9050919050565b600061504282615025565b9050919050565b61505281615037565b82525050565b600060408201905061506d6000830185615049565b61507a602083018461436b565b9392505050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006150b7601f8361447d565b91506150c282615081565b602082019050919050565b600060208201905081810360008301526150e6816150aa565b9050919050565b7f484f4c4445525f53414c455f494e414354495645000000000000000000000000600082015250565b600061512360148361447d565b915061512e826150ed565b602082019050919050565b6000602082019050818103600083015261515281615116565b9050919050565b7f494e53554646494349454e545f414c5f544f4b454e5300000000000000000000600082015250565b600061518f60168361447d565b915061519a82615159565b602082019050919050565b600060208201905081810360008301526151be81615182565b9050919050565b7f534f4c445f4f5554000000000000000000000000000000000000000000000000600082015250565b60006151fb60088361447d565b9150615206826151c5565b602082019050919050565b6000602082019050818103600083015261522a816151ee565b9050919050565b6000815190506152408161452d565b92915050565b60006020828403121561525c5761525b6143ad565b5b600061526a84828501615231565b91505092915050565b7f4e4f5f414c5f544f4b454e530000000000000000000000000000000000000000600082015250565b60006152a9600c8361447d565b91506152b482615273565b602082019050919050565b600060208201905081810360008301526152d88161529c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f414c5f414c52454144595f434c41494d45440000000000000000000000000000600082015250565b600061534460128361447d565b915061534f8261530e565b602082019050919050565b6000602082019050818103600083015261537381615337565b9050919050565b600081519050615389816145a1565b92915050565b6000602082840312156153a5576153a46143ad565b5b60006153b38482850161537a565b91505092915050565b7f4e4f545f414c5f4f574e45520000000000000000000000000000000000000000600082015250565b60006153f2600c8361447d565b91506153fd826153bc565b602082019050919050565b60006020820190508181036000830152615421816153e5565b9050919050565b600061543382614361565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561546657615465614ee2565b5b600182019050919050565b7f4d455441444154415f4c4f434b45440000000000000000000000000000000000600082015250565b60006154a7600f8361447d565b91506154b282615471565b602082019050919050565b600060208201905081810360008301526154d68161549a565b9050919050565b7f53414c455f494e41435449564500000000000000000000000000000000000000600082015250565b6000615513600d8361447d565b915061551e826154dd565b602082019050919050565b6000602082019050818103600083015261554281615506565b9050919050565b7f7468697320776f756c6420657863656564206d696e74206d617820616c6c6f7760008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b60006155a560248361447d565b91506155b082615549565b604082019050919050565b600060208201905081810360008301526155d481615598565b9050919050565b7f5055424c49435f534f4c445f4f55540000000000000000000000000000000000600082015250565b6000615611600f8361447d565b915061561c826155db565b602082019050919050565b6000602082019050818103600083015261564081615604565b9050919050565b600061565282614361565b915061565d83614361565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561569657615695614ee2565b5b828202905092915050565b7f494e434f52524543545f45544845525f56414c55450000000000000000000000600082015250565b60006156d760158361447d565b91506156e2826156a1565b602082019050919050565b60006020820190508181036000830152615706816156ca565b9050919050565b600081905092915050565b600061572382614472565b61572d818561570d565b935061573d81856020860161448e565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b600061577f60058361570d565b915061578a82615749565b600582019050919050565b60006157a18284615718565b91506157ac82615772565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061581360268361447d565b915061581e826157b7565b604082019050919050565b6000602082019050818103600083015261584281615806565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061588382614361565b915061588e83614361565b92508261589e5761589d615849565b5b828204905092915050565b60006158b482614361565b91506158bf83614361565b9250828210156158d2576158d1614ee2565b5b828203905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b6000615913601d8361447d565b915061591e826158dd565b602082019050919050565b6000602082019050818103600083015261594281615906565b9050919050565b600081905092915050565b50565b6000615964600083615949565b915061596f82615954565b600082019050919050565b600061598582615957565b9150819050919050565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b60006159eb603a8361447d565b91506159f68261598f565b604082019050919050565b60006020820190508181036000830152615a1a816159de565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000615a4882615a21565b615a528185615a2c565b9350615a6281856020860161448e565b615a6b816144c1565b840191505092915050565b6000608082019050615a8b6000830187614352565b615a986020830186614352565b615aa5604083018561436b565b8181036060830152615ab78184615a3d565b905095945050505050565b600081519050615ad1816143e3565b92915050565b600060208284031215615aed57615aec6143ad565b5b6000615afb84828501615ac2565b91505092915050565b6000615b108285615718565b9150615b1c8284615718565b91508190509392505050565b600081519050615b3781614b86565b92915050565b600060208284031215615b5357615b526143ad565b5b6000615b6184828501615b28565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000615bc6602a8361447d565b9150615bd182615b6a565b604082019050919050565b60006020820190508181036000830152615bf581615bb9565b9050919050565b6000615c0782614361565b9150615c1283614361565b925082615c2257615c21615849565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000615c8960268361447d565b9150615c9482615c2d565b604082019050919050565b60006020820190508181036000830152615cb881615c7c565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000615cf5601d8361447d565b9150615d0082615cbf565b602082019050919050565b60006020820190508181036000830152615d2481615ce8565b9050919050565b6000615d3682615a21565b615d408185615949565b9350615d5081856020860161448e565b80840191505092915050565b6000615d688284615d2b565b91508190509291505056fea26469706673582212208c770796ef3735677e101d06545383accc9b6a790036483d526c7bc7a49c01d064736f6c634300080a0033

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

00000000000000000000000061028f622cb6618cac3deb9ef0f0d5b9c6369c72

-----Decoded View---------------
Arg [0] : _apeLiquidAddress (address): 0x61028F622CB6618cAC3DeB9ef0f0D5B9c6369C72

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000061028f622cb6618cac3deb9ef0f0d5b9c6369c72


Deployed Bytecode Sourcemap

108811:5881:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104452:40;104468:12;:10;:12::i;:::-;104482:9;104452:40;;;;;;;:::i;:::-;;;;;;;;108811:5881;;;;;76987:305;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;112617:138;;;;;;;;;;;;;:::i;:::-;;80100:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81603:204;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81166:371;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76236:303;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;106238:566;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;110877:874;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82468:170;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;109134:365;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;112873:130;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;104583:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105712:135;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;109665:48;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82709:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;110390:212;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;107072:641;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;112441:168;;;;;;;;;;;;;:::i;:::-;;113228:73;;;;;;;;;;;;;:::i;:::-;;114134:150;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113309:712;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;79908:125;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;108924:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77356:206;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113011:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67110:103;;;;;;;;;;;;;:::i;:::-;;105938:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66459:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;110610:259;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80269:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;108969:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105434:109;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113129:75;;;;;;;;;;;;;:::i;:::-;;111759:674;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81879:287;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;109720:51;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;109045:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82965:369;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;114029:97;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;114414:163;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105230:105;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;109896:18;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;109620:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;109007:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105020:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104768:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;110232:134;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82237:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;109581:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67368:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;112763:102;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;34268:98;34321:7;34348:10;34341:17;;34268:98;:::o;76987:305::-;77089:4;77141:25;77126:40;;;:11;:40;;;;:105;;;;77198:33;77183:48;;;:11;:48;;;;77126:105;:158;;;;77248:36;77272:11;77248:23;:36::i;:::-;77126:158;77106:178;;76987:305;;;:::o;112617:138::-;66690:12;:10;:12::i;:::-;66679:23;;:7;:5;:7::i;:::-;:23;;;66671:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;112691:12:::1;;;;;;;;;;;112690:13;112675:12;;:28;;;;;;;;;;;;;;;;;;112719;112734:12;;;;;;;;;;;112719:28;;;;;;:::i;:::-;;;;;;;;112617:138::o:0;80100:100::-;80154:13;80187:5;80180:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80100:100;:::o;81603:204::-;81671:7;81696:16;81704:7;81696;:16::i;:::-;81691:64;;81721:34;;;;;;;;;;;;;;81691:64;81775:15;:24;81791:7;81775:24;;;;;;;;;;;;;;;;;;;;;81768:31;;81603:204;;;:::o;81166:371::-;81239:13;81255:24;81271:7;81255:15;:24::i;:::-;81239:40;;81300:5;81294:11;;:2;:11;;;81290:48;;;81314:24;;;;;;;;;;;;;;81290:48;81371:5;81355:21;;:12;:10;:12::i;:::-;:21;;;;:63;;;;;81381:37;81398:5;81405:12;:10;:12::i;:::-;81381:16;:37::i;:::-;81380:38;81355:63;81351:138;;;81442:35;;;;;;;;;;;;;;81351:138;81501:28;81510:2;81514:7;81523:5;81501:8;:28::i;:::-;81228:309;81166:371;;:::o;76236:303::-;76280:7;76505:15;:13;:15::i;:::-;76490:12;;76474:13;;:28;:46;76467:53;;76236:303;:::o;106238:566::-;106333:1;106314:7;:16;106322:7;106314:16;;;;;;;;;;;;;;;;:20;106306:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;106390:21;106438:15;:13;:15::i;:::-;106414:21;:39;;;;:::i;:::-;106390:63;;106464:15;106482:58;106498:7;106507:13;106522:17;106531:7;106522:8;:17::i;:::-;106482:15;:58::i;:::-;106464:76;;106572:1;106561:7;:12;;106553:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;106656:7;106634:9;:18;106644:7;106634:18;;;;;;;;;;;;;;;;:29;;;;;;;:::i;:::-;;;;;;;;106692:7;106674:14;;:25;;;;;;;:::i;:::-;;;;;;;;106712:35;106730:7;106739;106712:17;:35::i;:::-;106763:33;106779:7;106788;106763:33;;;;;;;:::i;:::-;;;;;;;;106295:509;;106238:566;:::o;110877:874::-;71844:1;72442:7;;:19;;72434:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;71844:1;72575:7;:18;;;;110992::::1;;;;;;;;;;;110984:51;;;;;;;;;;;;:::i;:::-;;;;;;;;;111078:13;;:20;;111068:6;:30;111046:102;;;;;;;;;;;;:::i;:::-;;;;;;;;;111207:9;;111197:6;111181:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;111159:93;;;;;;;;;;;;:::i;:::-;;;;;;;;;111265:26;111311:16;;;;;;;;;;;111265:63;;111381:1;111347:9;:19;;;111367:10;111347:31;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:35;111339:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;111415:9;111410:292;111434:13;;:20;;111430:1;:24;111410:292;;;111484:38;111505:13;;111519:1;111505:16;;;;;;;:::i;:::-;;;;;;;;111484:20;:38::i;:::-;111476:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;111607:10;111568:49;;:9;:17;;;111586:13;;111600:1;111586:16;;;;;;;:::i;:::-;;;;;;;;111568:35;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:49;;;111560:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;111686:4;111649:16;:34;111666:13;;111680:1;111666:16;;;;;;;:::i;:::-;;;;;;;;111649:34;;;;;;;;;;;;:41;;;;;;;;;;;;;;;;;;111456:3;;;;;:::i;:::-;;;;111410:292;;;;111714:29;111724:10;111736:6;111714:9;:29::i;:::-;110973:778;71800:1:::0;72754:7;:22;;;;110877:874;;;:::o;82468:170::-;82602:28;82612:4;82618:2;82622:7;82602:9;:28::i;:::-;82468:170;;;:::o;109134:365::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;112873:130::-;66690:12;:10;:12::i;:::-;66679:23;;:7;:5;:7::i;:::-;:23;;;66671:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;112978:17:::1;112959:16;;:36;;;;;;;;;;;;;;;;;;112873:130:::0;:::o;104583:91::-;104627:7;104654:12;;104647:19;;104583:91;:::o;105712:135::-;105782:7;105809:14;:21;105824:5;105809:21;;;;;;;;;;;;;;;:30;105831:7;105809:30;;;;;;;;;;;;;;;;105802:37;;105712:135;;;;:::o;109665:48::-;;;;;;;;;;;;;;;;;;;;;;:::o;82709:185::-;82847:39;82864:4;82870:2;82874:7;82847:39;;;;;;;;;;;;:16;:39::i;:::-;82709:185;;;:::o;110390:212::-;66690:12;:10;:12::i;:::-;66679:23;;:7;:5;:7::i;:::-;:23;;;66671:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;110516:9:::1;;110506:6;110490:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;110468:93;;;;;;;;;;;;:::i;:::-;;;;;;;;;110572:22;110582:3;110587:6;110572:9;:22::i;:::-;110390:212:::0;;:::o;107072:641::-;107173:1;107154:7;:16;107162:7;107154:16;;;;;;;;;;;;;;;;:20;107146:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;107230:21;107287:20;107301:5;107287:13;:20::i;:::-;107254:5;:15;;;107278:4;107254:30;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;;;;:::i;:::-;107230:77;;107318:15;107336:65;107352:7;107361:13;107376:24;107385:5;107392:7;107376:8;:24::i;:::-;107336:15;:65::i;:::-;107318:83;;107433:1;107422:7;:12;;107414:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;107529:7;107495:14;:21;107510:5;107495:21;;;;;;;;;;;;;;;:30;107517:7;107495:30;;;;;;;;;;;;;;;;:41;;;;;;;:::i;:::-;;;;;;;;107577:7;107547:19;:26;107567:5;107547:26;;;;;;;;;;;;;;;;:37;;;;;;;:::i;:::-;;;;;;;;107597:47;107620:5;107627:7;107636;107597:22;:47::i;:::-;107681:5;107660:45;;;107688:7;107697;107660:45;;;;;;;:::i;:::-;;;;;;;;107135:578;;107072:641;;:::o;112441:168::-;66690:12;:10;:12::i;:::-;66679:23;;:7;:5;:7::i;:::-;:23;;;66671:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;112527:18:::1;;;;;;;;;;;112526:19;112505:18;;:40;;;;;;;;;;;;;;;;;;112561;112582:18;;;;;;;;;;;112561:40;;;;;;:::i;:::-;;;;;;;;112441:168::o:0;113228:73::-;113265:28;113281:10;113265:7;:28::i;:::-;113228:73::o;114134:150::-;66690:12;:10;:12::i;:::-;66679:23;;:7;:5;:7::i;:::-;:23;;;66671:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;114216:6:::1;;;;;;;;;;;114215:7;114207:35;;;;;;;;;;;;:::i;:::-;;;;;;;;;114269:7;114253:13;:23;;;;;;;;;;;;:::i;:::-;;114134:150:::0;:::o;113309:712::-;113373:16;113419:18;113454:16;113464:5;113454:9;:16::i;:::-;113440:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;113419:52;;113482:11;113496:13;;113482:27;;113520:19;113550:25;113591:9;113586:402;113606:3;113602:1;:7;113586:402;;;113631:31;113665:11;:14;113677:1;113665:14;;;;;;;;;;;113631:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;113698:9;:16;;;113694:65;;;113735:8;;;113694:65;113803:1;113777:28;;:9;:14;;;:28;;;113773:103;;113846:9;:14;;;113826:34;;113773:103;113915:5;113894:26;;:17;:26;;;113890:87;;;113960:1;113941;113943:13;;;;;;113941:16;;;;;;;;:::i;:::-;;;;;;;:20;;;;;113890:87;113616:372;113586:402;113611:3;;;;;;;113586:402;;;;114005:1;113998:8;;;;;;113309:712;;;:::o;79908:125::-;79972:7;79999:21;80012:7;79999:12;:21::i;:::-;:26;;;79992:33;;79908:125;;;:::o;108924:38::-;;;;:::o;77356:206::-;77420:7;77461:1;77444:19;;:5;:19;;;77440:60;;;77472:28;;;;;;;;;;;;;;77440:60;77526:12;:19;77539:5;77526:19;;;;;;;;;;;;;;;:27;;;;;;;;;;;;77518:36;;77511:43;;77356:206;;;:::o;113011:110::-;66690:12;:10;:12::i;:::-;66679:23;;:7;:5;:7::i;:::-;:23;;;66671:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;113101:12:::1;113087:11;:26;;;;113011:110:::0;:::o;67110:103::-;66690:12;:10;:12::i;:::-;66679:23;;:7;:5;:7::i;:::-;:23;;;66671:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;67175:30:::1;67202:1;67175:18;:30::i;:::-;67110:103::o:0;105938:100::-;105989:7;106016;106024:5;106016:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;106009:21;;105938:100;;;:::o;66459:87::-;66505:7;66532:6;;;;;;;;;;;66525:13;;66459:87;:::o;110610:259::-;66690:12;:10;:12::i;:::-;66679:23;;:7;:5;:7::i;:::-;:23;;;66671:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;110729:9:::1;110724:138;110748:9;;:16;;110744:1;:20;110724:138;;;110782:20;110792:3;;110796:1;110792:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;110800:1;110782:9;:20::i;:::-;110846:4;110813:16;:30;110830:9;;110840:1;110830:12;;;;;;;:::i;:::-;;;;;;;;110813:30;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;110766:3;;;;;:::i;:::-;;;;110724:138;;;;110610:259:::0;;;;:::o;80269:104::-;80325:13;80358:7;80351:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80269:104;:::o;108969:31::-;;;;:::o;105434:109::-;105490:7;105517:9;:18;105527:7;105517:18;;;;;;;;;;;;;;;;105510:25;;105434:109;;;:::o;113129:75::-;66690:12;:10;:12::i;:::-;66679:23;;:7;:5;:7::i;:::-;:23;;;66671:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;113192:4:::1;113183:6;;:13;;;;;;;;;;;;;;;;;;113129:75::o:0;111759:674::-;71844:1;72442:7;;:19;;72434:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;71844:1;72575:7;:18;;;;111838:12:::1;;;;;;;;;;;111830:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;111936:11;;111923:6;111889:19;:31;111909:10;111889:31;;;;;;;;;;;;;;;;:40;;;;:::i;:::-;111887:60;;111879:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;112050:9;;112040:6;112024:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;112002:93;;;;;;;;;;;;:::i;:::-;;;;;;;;;112154:9;;112144:6;112128:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;112106:100;;;;;;;;;;;;:::i;:::-;;;;;;;;;112261:9;112251:6;112239:9;;:18;;;;:::i;:::-;:31;;112217:102;;;;;;;;;;;;:::i;:::-;;;;;;;;;112336:29;112346:10;112358:6;112336:9;:29::i;:::-;112415:6;112380:19;:31;112400:10;112380:31;;;;;;;;;;;;;;;;:41;;;;;;;:::i;:::-;;;;;;;;71800:1:::0;72754:7;:22;;;;111759:674;:::o;81879:287::-;81990:12;:10;:12::i;:::-;81978:24;;:8;:24;;;81974:54;;;82011:17;;;;;;;;;;;;;;81974:54;82086:8;82041:18;:32;82060:12;:10;:12::i;:::-;82041:32;;;;;;;;;;;;;;;:42;82074:8;82041:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;82139:8;82110:48;;82125:12;:10;:12::i;:::-;82110:48;;;82149:8;82110:48;;;;;;:::i;:::-;;;;;;;;81879:287;;:::o;109720:51::-;;;;;;;;;;;;;;;;;:::o;109045:31::-;;;;;;;;;;;;;:::o;82965:369::-;83132:28;83142:4;83148:2;83152:7;83132:9;:28::i;:::-;83175:15;:2;:13;;;:15::i;:::-;:76;;;;;83195:56;83226:4;83232:2;83236:7;83245:5;83195:30;:56::i;:::-;83194:57;83175:76;83171:156;;;83275:40;;;;;;;;;;;;;;83171:156;82965:369;;;;:::o;114029:97::-;114078:7;114105:13;:11;:13::i;:::-;114098:20;;114029:97;:::o;114414:163::-;114479:13;114535:23;114550:7;114535:14;:23::i;:::-;114518:50;;;;;;;;:::i;:::-;;;;;;;;;;;;;114504:65;;114414:163;;;:::o;105230:105::-;105284:7;105311;:16;105319:7;105311:16;;;;;;;;;;;;;;;;105304:23;;105230:105;;;:::o;109896:18::-;;;;;;;;;;;;;:::o;109620:38::-;;;;;;;;;;;;;:::o;109007:31::-;;;;:::o;105020:119::-;105078:7;105105:19;:26;105125:5;105105:26;;;;;;;;;;;;;;;;105098:33;;105020:119;;;:::o;104768:95::-;104814:7;104841:14;;104834:21;;104768:95;:::o;110232:134::-;110300:4;110354;110324:34;;:16;:26;110341:8;110324:26;;;;;;;;;;;;;;;;;;;;;:34;;;;110317:41;;110232:134;;;:::o;82237:164::-;82334:4;82358:18;:25;82377:5;82358:25;;;;;;;;;;;;;;;:35;82384:8;82358:35;;;;;;;;;;;;;;;;;;;;;;;;;82351:42;;82237:164;;;;:::o;109581:32::-;;;;;;;;;;;;;:::o;67368:201::-;66690:12;:10;:12::i;:::-;66679:23;;:7;:5;:7::i;:::-;:23;;;66671:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;67477:1:::1;67457:22;;:8;:22;;;;67449:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;67533:28;67552:8;67533:18;:28::i;:::-;67368:201:::0;:::o;112763:102::-;66690:12;:10;:12::i;:::-;66679:23;;:7;:5;:7::i;:::-;:23;;;66671:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;112847:10:::1;112835:9;:22;;;;112763:102:::0;:::o;37219:157::-;37304:4;37343:25;37328:40;;;:11;:40;;;;37321:47;;37219:157;;;:::o;83589:187::-;83646:4;83689:7;83670:15;:13;:15::i;:::-;:26;;:53;;;;;83710:13;;83700:7;:23;83670:53;:98;;;;;83741:11;:20;83753:7;83741:20;;;;;;;;;;;:27;;;;;;;;;;;;83740:28;83670:98;83663:105;;83589:187;;;:::o;91759:196::-;91901:2;91874:15;:24;91890:7;91874:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;91939:7;91935:2;91919:28;;91928:5;91919:28;;;;;;;;;;;;91759:196;;;:::o;114585:100::-;114650:7;114676:1;114669:8;;114585:100;:::o;107891:248::-;108037:7;108116:15;108101:12;;108081:7;:16;108089:7;108081:16;;;;;;;;;;;;;;;;108065:13;:32;;;;:::i;:::-;108064:49;;;;:::i;:::-;:67;;;;:::i;:::-;108057:74;;107891:248;;;;;:::o;27692:317::-;27807:6;27782:21;:31;;27774:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;27861:12;27879:9;:14;;27901:6;27879:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27860:52;;;27931:7;27923:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;27763:246;27692:317;;:::o;83784:104::-;83853:27;83863:2;83867:8;83853:27;;;;;;;;;;;;:9;:27::i;:::-;83784:104;;:::o;86702:2130::-;86817:35;86855:21;86868:7;86855:12;:21::i;:::-;86817:59;;86915:4;86893:26;;:13;:18;;;:26;;;86889:67;;86928:28;;;;;;;;;;;;;;86889:67;86969:22;87011:4;86995:20;;:12;:10;:12::i;:::-;:20;;;:73;;;;87032:36;87049:4;87055:12;:10;:12::i;:::-;87032:16;:36::i;:::-;86995:73;:126;;;;87109:12;:10;:12::i;:::-;87085:36;;:20;87097:7;87085:11;:20::i;:::-;:36;;;86995:126;86969:153;;87140:17;87135:66;;87166:35;;;;;;;;;;;;;;87135:66;87230:1;87216:16;;:2;:16;;;87212:52;;;87241:23;;;;;;;;;;;;;;87212:52;87277:43;87299:4;87305:2;87309:7;87318:1;87277:21;:43::i;:::-;87385:35;87402:1;87406:7;87415:4;87385:8;:35::i;:::-;87746:1;87716:12;:18;87729:4;87716:18;;;;;;;;;;;;;;;:26;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87790:1;87762:12;:16;87775:2;87762:16;;;;;;;;;;;;;;;:24;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87808:31;87842:11;:20;87854:7;87842:20;;;;;;;;;;;87808:54;;87893:2;87877:8;:13;;;:18;;;;;;;;;;;;;;;;;;87943:15;87910:8;:23;;;:49;;;;;;;;;;;;;;;;;;88211:19;88243:1;88233:7;:11;88211:33;;88259:31;88293:11;:24;88305:11;88293:24;;;;;;;;;;;88259:58;;88361:1;88336:27;;:8;:13;;;;;;;;;;;;:27;;;88332:384;;;88546:13;;88531:11;:28;88527:174;;88600:4;88584:8;:13;;;:20;;;;;;;;;;;;;;;;;;88653:13;:28;;;88627:8;:23;;;:54;;;;;;;;;;;;;;;;;;88527:174;88332:384;87691:1036;;;88763:7;88759:2;88744:27;;88753:4;88744:27;;;;;;;;;;;;88782:42;88803:4;88809:2;88813:7;88822:1;88782:20;:42::i;:::-;86806:2026;;86702:2130;;;:::o;98044:211::-;98161:86;98181:5;98211:23;;;98236:2;98240:5;98188:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98161:19;:86::i;:::-;98044:211;;;:::o;78737:1109::-;78799:21;;:::i;:::-;78833:12;78848:7;78833:22;;78916:4;78897:15;:13;:15::i;:::-;:23;;:47;;;;;78931:13;;78924:4;:20;78897:47;78893:886;;;78965:31;78999:11;:17;79011:4;78999:17;;;;;;;;;;;78965:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79040:9;:16;;;79035:729;;79111:1;79085:28;;:9;:14;;;:28;;;79081:101;;79149:9;79142:16;;;;;;79081:101;79484:261;79491:4;79484:261;;;79524:6;;;;;;;;79569:11;:17;79581:4;79569:17;;;;;;;;;;;79557:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79643:1;79617:28;;:9;:14;;;:28;;;79613:109;;79685:9;79678:16;;;;;;79613:109;79484:261;;;79035:729;78946:833;78893:886;79807:31;;;;;;;;;;;;;;78737:1109;;;;:::o;67729:191::-;67803:16;67822:6;;;;;;;;;;;67803:25;;67848:8;67839:6;;:17;;;;;;;;;;;;;;;;;;67903:8;67872:40;;67893:8;67872:40;;;;;;;;;;;;67792:128;67729:191;:::o;26370:387::-;26430:4;26638:12;26705:7;26693:20;26685:28;;26748:1;26741:4;:8;26734:15;;;26370:387;;;:::o;92447:667::-;92610:4;92647:2;92631:36;;;92668:12;:10;:12::i;:::-;92682:4;92688:7;92697:5;92631:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;92627:480;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92882:1;92865:6;:13;:18;92861:235;;;92911:40;;;;;;;;;;;;;;92861:235;93054:6;93048:13;93039:6;93035:2;93031:15;93024:38;92627:480;92760:45;;;92750:55;;;:6;:55;;;;92743:62;;;92447:667;;;;;;:::o;80444:318::-;80517:13;80548:16;80556:7;80548;:16::i;:::-;80543:59;;80573:29;;;;;;;;;;;;;;80543:59;80615:21;80639:10;:8;:10::i;:::-;80615:34;;80692:1;80673:7;80667:21;:26;;:87;;;;;;;;;;;;;;;;;80720:7;80729:18;:7;:16;:18::i;:::-;80703:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;80667:87;80660:94;;;80444:318;;;:::o;84251:163::-;84374:32;84380:2;84384:8;84394:5;84401:4;84374:5;:32::i;:::-;84251:163;;;:::o;93762:159::-;;;;;:::o;94580:158::-;;;;;:::o;100617:716::-;101041:23;101067:69;101095:4;101067:69;;;;;;;;;;;;;;;;;101075:5;101067:27;;;;:69;;;;;:::i;:::-;101041:95;;101171:1;101151:10;:17;:21;101147:179;;;101248:10;101237:30;;;;;;;;;;;;:::i;:::-;101229:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;101147:179;100687:646;100617:716;;:::o;114292:114::-;114352:13;114385;114378:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;114292:114;:::o;34735:723::-;34791:13;35021:1;35012:5;:10;35008:53;;;35039:10;;;;;;;;;;;;;;;;;;;;;35008:53;35071:12;35086:5;35071:20;;35102:14;35127:78;35142:1;35134:4;:9;35127:78;;35160:8;;;;;:::i;:::-;;;;35191:2;35183:10;;;;;:::i;:::-;;;35127:78;;;35215:19;35247:6;35237:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35215:39;;35265:154;35281:1;35272:5;:10;35265:154;;35309:1;35299:11;;;;;:::i;:::-;;;35376:2;35368:5;:10;;;;:::i;:::-;35355:2;:24;;;;:::i;:::-;35342:39;;35325:6;35332;35325:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;35405:2;35396:11;;;;;:::i;:::-;;;35265:154;;;35443:6;35429:21;;;;;34735:723;;;;:::o;84673:1775::-;84812:20;84835:13;;84812:36;;84877:1;84863:16;;:2;:16;;;84859:48;;;84888:19;;;;;;;;;;;;;;84859:48;84934:1;84922:8;:13;84918:44;;;84944:18;;;;;;;;;;;;;;84918:44;84975:61;85005:1;85009:2;85013:12;85027:8;84975:21;:61::i;:::-;85348:8;85313:12;:16;85326:2;85313:16;;;;;;;;;;;;;;;:24;;;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85412:8;85372:12;:16;85385:2;85372:16;;;;;;;;;;;;;;;:29;;;:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85471:2;85438:11;:25;85450:12;85438:25;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;85538:15;85488:11;:25;85500:12;85488:25;;;;;;;;;;;:40;;;:66;;;;;;;;;;;;;;;;;;85571:20;85594:12;85571:35;;85621:11;85650:8;85635:12;:23;85621:37;;85679:4;:23;;;;;85687:15;:2;:13;;;:15::i;:::-;85679:23;85675:641;;;85723:314;85779:12;85775:2;85754:38;;85771:1;85754:38;;;;;;;;;;;;85820:69;85859:1;85863:2;85867:14;;;;;;85883:5;85820:30;:69::i;:::-;85815:174;;85925:40;;;;;;;;;;;;;;85815:174;86032:3;86016:12;:19;;85723:314;;86118:12;86101:13;;:29;86097:43;;86132:8;;;86097:43;85675:641;;;86181:120;86237:14;;;;;;86233:2;86212:40;;86229:1;86212:40;;;;;;;;;;;;86296:3;86280:12;:19;;86181:120;;85675:641;86346:12;86330:13;:28;;;;85288:1082;;86380:60;86409:1;86413:2;86417:12;86431:8;86380:20;:60::i;:::-;84801:1647;84673:1775;;;;:::o;29176:229::-;29313:12;29345:52;29367:6;29375:4;29381:1;29384:12;29345:21;:52::i;:::-;29338:59;;29176:229;;;;;:::o;30296:510::-;30466:12;30524:5;30499:21;:30;;30491:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;30591:18;30602:6;30591:10;:18::i;:::-;30583:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;30657:12;30671:23;30698:6;:11;;30717:5;30724:4;30698:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30656:73;;;;30747:51;30764:7;30773:10;30785:12;30747:16;:51::i;:::-;30740:58;;;;30296:510;;;;;;:::o;32982:712::-;33132:12;33161:7;33157:530;;;33192:10;33185:17;;;;33157:530;33326:1;33306:10;:17;:21;33302:374;;;33504:10;33498:17;33565:15;33552:10;33548:2;33544:19;33537:44;33302:374;33647:12;33640:20;;;;;;;;;;;:::i;:::-;;;;;;;;32982:712;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:126:1:-;44:7;84:42;77:5;73:54;62:65;;7:126;;;:::o;139:96::-;176:7;205:24;223:5;205:24;:::i;:::-;194:35;;139:96;;;:::o;241:118::-;328:24;346:5;328:24;:::i;:::-;323:3;316:37;241:118;;:::o;365:77::-;402:7;431:5;420:16;;365:77;;;:::o;448:118::-;535:24;553:5;535:24;:::i;:::-;530:3;523:37;448:118;;:::o;572:332::-;693:4;731:2;720:9;716:18;708:26;;744:71;812:1;801:9;797:17;788:6;744:71;:::i;:::-;825:72;893:2;882:9;878:18;869:6;825:72;:::i;:::-;572:332;;;;;:::o;910:75::-;943:6;976:2;970:9;960:19;;910:75;:::o;991:117::-;1100:1;1097;1090:12;1114:117;1223:1;1220;1213:12;1237:149;1273:7;1313:66;1306:5;1302:78;1291:89;;1237:149;;;:::o;1392:120::-;1464:23;1481:5;1464:23;:::i;:::-;1457:5;1454:34;1444:62;;1502:1;1499;1492:12;1444:62;1392:120;:::o;1518:137::-;1563:5;1601:6;1588:20;1579:29;;1617:32;1643:5;1617:32;:::i;:::-;1518:137;;;;:::o;1661:327::-;1719:6;1768:2;1756:9;1747:7;1743:23;1739:32;1736:119;;;1774:79;;:::i;:::-;1736:119;1894:1;1919:52;1963:7;1954:6;1943:9;1939:22;1919:52;:::i;:::-;1909:62;;1865:116;1661:327;;;;:::o;1994:90::-;2028:7;2071:5;2064:13;2057:21;2046:32;;1994:90;;;:::o;2090:109::-;2171:21;2186:5;2171:21;:::i;:::-;2166:3;2159:34;2090:109;;:::o;2205:210::-;2292:4;2330:2;2319:9;2315:18;2307:26;;2343:65;2405:1;2394:9;2390:17;2381:6;2343:65;:::i;:::-;2205:210;;;;:::o;2421:99::-;2473:6;2507:5;2501:12;2491:22;;2421:99;;;:::o;2526:169::-;2610:11;2644:6;2639:3;2632:19;2684:4;2679:3;2675:14;2660:29;;2526:169;;;;:::o;2701:307::-;2769:1;2779:113;2793:6;2790:1;2787:13;2779:113;;;2878:1;2873:3;2869:11;2863:18;2859:1;2854:3;2850:11;2843:39;2815:2;2812:1;2808:10;2803:15;;2779:113;;;2910:6;2907:1;2904:13;2901:101;;;2990:1;2981:6;2976:3;2972:16;2965:27;2901:101;2750:258;2701:307;;;:::o;3014:102::-;3055:6;3106:2;3102:7;3097:2;3090:5;3086:14;3082:28;3072:38;;3014:102;;;:::o;3122:364::-;3210:3;3238:39;3271:5;3238:39;:::i;:::-;3293:71;3357:6;3352:3;3293:71;:::i;:::-;3286:78;;3373:52;3418:6;3413:3;3406:4;3399:5;3395:16;3373:52;:::i;:::-;3450:29;3472:6;3450:29;:::i;:::-;3445:3;3441:39;3434:46;;3214:272;3122:364;;;;:::o;3492:313::-;3605:4;3643:2;3632:9;3628:18;3620:26;;3692:9;3686:4;3682:20;3678:1;3667:9;3663:17;3656:47;3720:78;3793:4;3784:6;3720:78;:::i;:::-;3712:86;;3492:313;;;;:::o;3811:122::-;3884:24;3902:5;3884:24;:::i;:::-;3877:5;3874:35;3864:63;;3923:1;3920;3913:12;3864:63;3811:122;:::o;3939:139::-;3985:5;4023:6;4010:20;4001:29;;4039:33;4066:5;4039:33;:::i;:::-;3939:139;;;;:::o;4084:329::-;4143:6;4192:2;4180:9;4171:7;4167:23;4163:32;4160:119;;;4198:79;;:::i;:::-;4160:119;4318:1;4343:53;4388:7;4379:6;4368:9;4364:22;4343:53;:::i;:::-;4333:63;;4289:117;4084:329;;;;:::o;4419:222::-;4512:4;4550:2;4539:9;4535:18;4527:26;;4563:71;4631:1;4620:9;4616:17;4607:6;4563:71;:::i;:::-;4419:222;;;;:::o;4647:122::-;4720:24;4738:5;4720:24;:::i;:::-;4713:5;4710:35;4700:63;;4759:1;4756;4749:12;4700:63;4647:122;:::o;4775:139::-;4821:5;4859:6;4846:20;4837:29;;4875:33;4902:5;4875:33;:::i;:::-;4775:139;;;;:::o;4920:474::-;4988:6;4996;5045:2;5033:9;5024:7;5020:23;5016:32;5013:119;;;5051:79;;:::i;:::-;5013:119;5171:1;5196:53;5241:7;5232:6;5221:9;5217:22;5196:53;:::i;:::-;5186:63;;5142:117;5298:2;5324:53;5369:7;5360:6;5349:9;5345:22;5324:53;:::i;:::-;5314:63;;5269:118;4920:474;;;;;:::o;5400:222::-;5493:4;5531:2;5520:9;5516:18;5508:26;;5544:71;5612:1;5601:9;5597:17;5588:6;5544:71;:::i;:::-;5400:222;;;;:::o;5628:104::-;5673:7;5702:24;5720:5;5702:24;:::i;:::-;5691:35;;5628:104;;;:::o;5738:138::-;5819:32;5845:5;5819:32;:::i;:::-;5812:5;5809:43;5799:71;;5866:1;5863;5856:12;5799:71;5738:138;:::o;5882:155::-;5936:5;5974:6;5961:20;5952:29;;5990:41;6025:5;5990:41;:::i;:::-;5882:155;;;;:::o;6043:345::-;6110:6;6159:2;6147:9;6138:7;6134:23;6130:32;6127:119;;;6165:79;;:::i;:::-;6127:119;6285:1;6310:61;6363:7;6354:6;6343:9;6339:22;6310:61;:::i;:::-;6300:71;;6256:125;6043:345;;;;:::o;6394:117::-;6503:1;6500;6493:12;6517:117;6626:1;6623;6616:12;6640:117;6749:1;6746;6739:12;6780:568;6853:8;6863:6;6913:3;6906:4;6898:6;6894:17;6890:27;6880:122;;6921:79;;:::i;:::-;6880:122;7034:6;7021:20;7011:30;;7064:18;7056:6;7053:30;7050:117;;;7086:79;;:::i;:::-;7050:117;7200:4;7192:6;7188:17;7176:29;;7254:3;7246:4;7238:6;7234:17;7224:8;7220:32;7217:41;7214:128;;;7261:79;;:::i;:::-;7214:128;6780:568;;;;;:::o;7354:704::-;7449:6;7457;7465;7514:2;7502:9;7493:7;7489:23;7485:32;7482:119;;;7520:79;;:::i;:::-;7482:119;7668:1;7657:9;7653:17;7640:31;7698:18;7690:6;7687:30;7684:117;;;7720:79;;:::i;:::-;7684:117;7833:80;7905:7;7896:6;7885:9;7881:22;7833:80;:::i;:::-;7815:98;;;;7611:312;7962:2;7988:53;8033:7;8024:6;8013:9;8009:22;7988:53;:::i;:::-;7978:63;;7933:118;7354:704;;;;;:::o;8064:619::-;8141:6;8149;8157;8206:2;8194:9;8185:7;8181:23;8177:32;8174:119;;;8212:79;;:::i;:::-;8174:119;8332:1;8357:53;8402:7;8393:6;8382:9;8378:22;8357:53;:::i;:::-;8347:63;;8303:117;8459:2;8485:53;8530:7;8521:6;8510:9;8506:22;8485:53;:::i;:::-;8475:63;;8430:118;8587:2;8613:53;8658:7;8649:6;8638:9;8634:22;8613:53;:::i;:::-;8603:63;;8558:118;8064:619;;;;;:::o;8689:329::-;8748:6;8797:2;8785:9;8776:7;8772:23;8768:32;8765:119;;;8803:79;;:::i;:::-;8765:119;8923:1;8948:53;8993:7;8984:6;8973:9;8969:22;8948:53;:::i;:::-;8938:63;;8894:117;8689:329;;;;:::o;9024:111::-;9076:7;9105:24;9123:5;9105:24;:::i;:::-;9094:35;;9024:111;;;:::o;9141:152::-;9229:39;9262:5;9229:39;:::i;:::-;9222:5;9219:50;9209:78;;9283:1;9280;9273:12;9209:78;9141:152;:::o;9299:169::-;9360:5;9398:6;9385:20;9376:29;;9414:48;9456:5;9414:48;:::i;:::-;9299:169;;;;:::o;9474:504::-;9557:6;9565;9614:2;9602:9;9593:7;9589:23;9585:32;9582:119;;;9620:79;;:::i;:::-;9582:119;9740:1;9765:68;9825:7;9816:6;9805:9;9801:22;9765:68;:::i;:::-;9755:78;;9711:132;9882:2;9908:53;9953:7;9944:6;9933:9;9929:22;9908:53;:::i;:::-;9898:63;;9853:118;9474:504;;;;;:::o;9984:117::-;10093:1;10090;10083:12;10107:180;10155:77;10152:1;10145:88;10252:4;10249:1;10242:15;10276:4;10273:1;10266:15;10293:281;10376:27;10398:4;10376:27;:::i;:::-;10368:6;10364:40;10506:6;10494:10;10491:22;10470:18;10458:10;10455:34;10452:62;10449:88;;;10517:18;;:::i;:::-;10449:88;10557:10;10553:2;10546:22;10336:238;10293:281;;:::o;10580:129::-;10614:6;10641:20;;:::i;:::-;10631:30;;10670:33;10698:4;10690:6;10670:33;:::i;:::-;10580:129;;;:::o;10715:308::-;10777:4;10867:18;10859:6;10856:30;10853:56;;;10889:18;;:::i;:::-;10853:56;10927:29;10949:6;10927:29;:::i;:::-;10919:37;;11011:4;11005;11001:15;10993:23;;10715:308;;;:::o;11029:154::-;11113:6;11108:3;11103;11090:30;11175:1;11166:6;11161:3;11157:16;11150:27;11029:154;;;:::o;11189:412::-;11267:5;11292:66;11308:49;11350:6;11308:49;:::i;:::-;11292:66;:::i;:::-;11283:75;;11381:6;11374:5;11367:21;11419:4;11412:5;11408:16;11457:3;11448:6;11443:3;11439:16;11436:25;11433:112;;;11464:79;;:::i;:::-;11433:112;11554:41;11588:6;11583:3;11578;11554:41;:::i;:::-;11273:328;11189:412;;;;;:::o;11621:340::-;11677:5;11726:3;11719:4;11711:6;11707:17;11703:27;11693:122;;11734:79;;:::i;:::-;11693:122;11851:6;11838:20;11876:79;11951:3;11943:6;11936:4;11928:6;11924:17;11876:79;:::i;:::-;11867:88;;11683:278;11621:340;;;;:::o;11967:509::-;12036:6;12085:2;12073:9;12064:7;12060:23;12056:32;12053:119;;;12091:79;;:::i;:::-;12053:119;12239:1;12228:9;12224:17;12211:31;12269:18;12261:6;12258:30;12255:117;;;12291:79;;:::i;:::-;12255:117;12396:63;12451:7;12442:6;12431:9;12427:22;12396:63;:::i;:::-;12386:73;;12182:287;11967:509;;;;:::o;12482:114::-;12549:6;12583:5;12577:12;12567:22;;12482:114;;;:::o;12602:184::-;12701:11;12735:6;12730:3;12723:19;12775:4;12770:3;12766:14;12751:29;;12602:184;;;;:::o;12792:132::-;12859:4;12882:3;12874:11;;12912:4;12907:3;12903:14;12895:22;;12792:132;;;:::o;12930:108::-;13007:24;13025:5;13007:24;:::i;:::-;13002:3;12995:37;12930:108;;:::o;13044:179::-;13113:10;13134:46;13176:3;13168:6;13134:46;:::i;:::-;13212:4;13207:3;13203:14;13189:28;;13044:179;;;;:::o;13229:113::-;13299:4;13331;13326:3;13322:14;13314:22;;13229:113;;;:::o;13378:732::-;13497:3;13526:54;13574:5;13526:54;:::i;:::-;13596:86;13675:6;13670:3;13596:86;:::i;:::-;13589:93;;13706:56;13756:5;13706:56;:::i;:::-;13785:7;13816:1;13801:284;13826:6;13823:1;13820:13;13801:284;;;13902:6;13896:13;13929:63;13988:3;13973:13;13929:63;:::i;:::-;13922:70;;14015:60;14068:6;14015:60;:::i;:::-;14005:70;;13861:224;13848:1;13845;13841:9;13836:14;;13801:284;;;13805:14;14101:3;14094:10;;13502:608;;;13378:732;;;;:::o;14116:373::-;14259:4;14297:2;14286:9;14282:18;14274:26;;14346:9;14340:4;14336:20;14332:1;14321:9;14317:17;14310:47;14374:108;14477:4;14468:6;14374:108;:::i;:::-;14366:116;;14116:373;;;;:::o;14512:568::-;14585:8;14595:6;14645:3;14638:4;14630:6;14626:17;14622:27;14612:122;;14653:79;;:::i;:::-;14612:122;14766:6;14753:20;14743:30;;14796:18;14788:6;14785:30;14782:117;;;14818:79;;:::i;:::-;14782:117;14932:4;14924:6;14920:17;14908:29;;14986:3;14978:4;14970:6;14966:17;14956:8;14952:32;14949:41;14946:128;;;14993:79;;:::i;:::-;14946:128;14512:568;;;;;:::o;15086:934::-;15208:6;15216;15224;15232;15281:2;15269:9;15260:7;15256:23;15252:32;15249:119;;;15287:79;;:::i;:::-;15249:119;15435:1;15424:9;15420:17;15407:31;15465:18;15457:6;15454:30;15451:117;;;15487:79;;:::i;:::-;15451:117;15600:80;15672:7;15663:6;15652:9;15648:22;15600:80;:::i;:::-;15582:98;;;;15378:312;15757:2;15746:9;15742:18;15729:32;15788:18;15780:6;15777:30;15774:117;;;15810:79;;:::i;:::-;15774:117;15923:80;15995:7;15986:6;15975:9;15971:22;15923:80;:::i;:::-;15905:98;;;;15700:313;15086:934;;;;;;;:::o;16026:116::-;16096:21;16111:5;16096:21;:::i;:::-;16089:5;16086:32;16076:60;;16132:1;16129;16122:12;16076:60;16026:116;:::o;16148:133::-;16191:5;16229:6;16216:20;16207:29;;16245:30;16269:5;16245:30;:::i;:::-;16148:133;;;;:::o;16287:468::-;16352:6;16360;16409:2;16397:9;16388:7;16384:23;16380:32;16377:119;;;16415:79;;:::i;:::-;16377:119;16535:1;16560:53;16605:7;16596:6;16585:9;16581:22;16560:53;:::i;:::-;16550:63;;16506:117;16662:2;16688:50;16730:7;16721:6;16710:9;16706:22;16688:50;:::i;:::-;16678:60;;16633:115;16287:468;;;;;:::o;16761:307::-;16822:4;16912:18;16904:6;16901:30;16898:56;;;16934:18;;:::i;:::-;16898:56;16972:29;16994:6;16972:29;:::i;:::-;16964:37;;17056:4;17050;17046:15;17038:23;;16761:307;;;:::o;17074:410::-;17151:5;17176:65;17192:48;17233:6;17192:48;:::i;:::-;17176:65;:::i;:::-;17167:74;;17264:6;17257:5;17250:21;17302:4;17295:5;17291:16;17340:3;17331:6;17326:3;17322:16;17319:25;17316:112;;;17347:79;;:::i;:::-;17316:112;17437:41;17471:6;17466:3;17461;17437:41;:::i;:::-;17157:327;17074:410;;;;;:::o;17503:338::-;17558:5;17607:3;17600:4;17592:6;17588:17;17584:27;17574:122;;17615:79;;:::i;:::-;17574:122;17732:6;17719:20;17757:78;17831:3;17823:6;17816:4;17808:6;17804:17;17757:78;:::i;:::-;17748:87;;17564:277;17503:338;;;;:::o;17847:943::-;17942:6;17950;17958;17966;18015:3;18003:9;17994:7;17990:23;17986:33;17983:120;;;18022:79;;:::i;:::-;17983:120;18142:1;18167:53;18212:7;18203:6;18192:9;18188:22;18167:53;:::i;:::-;18157:63;;18113:117;18269:2;18295:53;18340:7;18331:6;18320:9;18316:22;18295:53;:::i;:::-;18285:63;;18240:118;18397:2;18423:53;18468:7;18459:6;18448:9;18444:22;18423:53;:::i;:::-;18413:63;;18368:118;18553:2;18542:9;18538:18;18525:32;18584:18;18576:6;18573:30;18570:117;;;18606:79;;:::i;:::-;18570:117;18711:62;18765:7;18756:6;18745:9;18741:22;18711:62;:::i;:::-;18701:72;;18496:287;17847:943;;;;;;;:::o;18796:359::-;18870:6;18919:2;18907:9;18898:7;18894:23;18890:32;18887:119;;;18925:79;;:::i;:::-;18887:119;19045:1;19070:68;19130:7;19121:6;19110:9;19106:22;19070:68;:::i;:::-;19060:78;;19016:132;18796:359;;;;:::o;19161:474::-;19229:6;19237;19286:2;19274:9;19265:7;19261:23;19257:32;19254:119;;;19292:79;;:::i;:::-;19254:119;19412:1;19437:53;19482:7;19473:6;19462:9;19458:22;19437:53;:::i;:::-;19427:63;;19383:117;19539:2;19565:53;19610:7;19601:6;19590:9;19586:22;19565:53;:::i;:::-;19555:63;;19510:118;19161:474;;;;;:::o;19641:182::-;19781:34;19777:1;19769:6;19765:14;19758:58;19641:182;:::o;19829:366::-;19971:3;19992:67;20056:2;20051:3;19992:67;:::i;:::-;19985:74;;20068:93;20157:3;20068:93;:::i;:::-;20186:2;20181:3;20177:12;20170:19;;19829:366;;;:::o;20201:419::-;20367:4;20405:2;20394:9;20390:18;20382:26;;20454:9;20448:4;20444:20;20440:1;20429:9;20425:17;20418:47;20482:131;20608:4;20482:131;:::i;:::-;20474:139;;20201:419;;;:::o;20626:180::-;20674:77;20671:1;20664:88;20771:4;20768:1;20761:15;20795:4;20792:1;20785:15;20812:320;20856:6;20893:1;20887:4;20883:12;20873:22;;20940:1;20934:4;20930:12;20961:18;20951:81;;21017:4;21009:6;21005:17;20995:27;;20951:81;21079:2;21071:6;21068:14;21048:18;21045:38;21042:84;;;21098:18;;:::i;:::-;21042:84;20863:269;20812:320;;;:::o;21138:225::-;21278:34;21274:1;21266:6;21262:14;21255:58;21347:8;21342:2;21334:6;21330:15;21323:33;21138:225;:::o;21369:366::-;21511:3;21532:67;21596:2;21591:3;21532:67;:::i;:::-;21525:74;;21608:93;21697:3;21608:93;:::i;:::-;21726:2;21721:3;21717:12;21710:19;;21369:366;;;:::o;21741:419::-;21907:4;21945:2;21934:9;21930:18;21922:26;;21994:9;21988:4;21984:20;21980:1;21969:9;21965:17;21958:47;22022:131;22148:4;22022:131;:::i;:::-;22014:139;;21741:419;;;:::o;22166:180::-;22214:77;22211:1;22204:88;22311:4;22308:1;22301:15;22335:4;22332:1;22325:15;22352:305;22392:3;22411:20;22429:1;22411:20;:::i;:::-;22406:25;;22445:20;22463:1;22445:20;:::i;:::-;22440:25;;22599:1;22531:66;22527:74;22524:1;22521:81;22518:107;;;22605:18;;:::i;:::-;22518:107;22649:1;22646;22642:9;22635:16;;22352:305;;;;:::o;22663:230::-;22803:34;22799:1;22791:6;22787:14;22780:58;22872:13;22867:2;22859:6;22855:15;22848:38;22663:230;:::o;22899:366::-;23041:3;23062:67;23126:2;23121:3;23062:67;:::i;:::-;23055:74;;23138:93;23227:3;23138:93;:::i;:::-;23256:2;23251:3;23247:12;23240:19;;22899:366;;;:::o;23271:419::-;23437:4;23475:2;23464:9;23460:18;23452:26;;23524:9;23518:4;23514:20;23510:1;23499:9;23495:17;23488:47;23552:131;23678:4;23552:131;:::i;:::-;23544:139;;23271:419;;;:::o;23696:60::-;23724:3;23745:5;23738:12;;23696:60;;;:::o;23762:142::-;23812:9;23845:53;23863:34;23872:24;23890:5;23872:24;:::i;:::-;23863:34;:::i;:::-;23845:53;:::i;:::-;23832:66;;23762:142;;;:::o;23910:126::-;23960:9;23993:37;24024:5;23993:37;:::i;:::-;23980:50;;23910:126;;;:::o;24042:134::-;24100:9;24133:37;24164:5;24133:37;:::i;:::-;24120:50;;24042:134;;;:::o;24182:147::-;24277:45;24316:5;24277:45;:::i;:::-;24272:3;24265:58;24182:147;;:::o;24335:348::-;24464:4;24502:2;24491:9;24487:18;24479:26;;24515:79;24591:1;24580:9;24576:17;24567:6;24515:79;:::i;:::-;24604:72;24672:2;24661:9;24657:18;24648:6;24604:72;:::i;:::-;24335:348;;;;;:::o;24689:181::-;24829:33;24825:1;24817:6;24813:14;24806:57;24689:181;:::o;24876:366::-;25018:3;25039:67;25103:2;25098:3;25039:67;:::i;:::-;25032:74;;25115:93;25204:3;25115:93;:::i;:::-;25233:2;25228:3;25224:12;25217:19;;24876:366;;;:::o;25248:419::-;25414:4;25452:2;25441:9;25437:18;25429:26;;25501:9;25495:4;25491:20;25487:1;25476:9;25472:17;25465:47;25529:131;25655:4;25529:131;:::i;:::-;25521:139;;25248:419;;;:::o;25673:170::-;25813:22;25809:1;25801:6;25797:14;25790:46;25673:170;:::o;25849:366::-;25991:3;26012:67;26076:2;26071:3;26012:67;:::i;:::-;26005:74;;26088:93;26177:3;26088:93;:::i;:::-;26206:2;26201:3;26197:12;26190:19;;25849:366;;;:::o;26221:419::-;26387:4;26425:2;26414:9;26410:18;26402:26;;26474:9;26468:4;26464:20;26460:1;26449:9;26445:17;26438:47;26502:131;26628:4;26502:131;:::i;:::-;26494:139;;26221:419;;;:::o;26646:172::-;26786:24;26782:1;26774:6;26770:14;26763:48;26646:172;:::o;26824:366::-;26966:3;26987:67;27051:2;27046:3;26987:67;:::i;:::-;26980:74;;27063:93;27152:3;27063:93;:::i;:::-;27181:2;27176:3;27172:12;27165:19;;26824:366;;;:::o;27196:419::-;27362:4;27400:2;27389:9;27385:18;27377:26;;27449:9;27443:4;27439:20;27435:1;27424:9;27420:17;27413:47;27477:131;27603:4;27477:131;:::i;:::-;27469:139;;27196:419;;;:::o;27621:158::-;27761:10;27757:1;27749:6;27745:14;27738:34;27621:158;:::o;27785:365::-;27927:3;27948:66;28012:1;28007:3;27948:66;:::i;:::-;27941:73;;28023:93;28112:3;28023:93;:::i;:::-;28141:2;28136:3;28132:12;28125:19;;27785:365;;;:::o;28156:419::-;28322:4;28360:2;28349:9;28345:18;28337:26;;28409:9;28403:4;28399:20;28395:1;28384:9;28380:17;28373:47;28437:131;28563:4;28437:131;:::i;:::-;28429:139;;28156:419;;;:::o;28581:143::-;28638:5;28669:6;28663:13;28654:22;;28685:33;28712:5;28685:33;:::i;:::-;28581:143;;;;:::o;28730:351::-;28800:6;28849:2;28837:9;28828:7;28824:23;28820:32;28817:119;;;28855:79;;:::i;:::-;28817:119;28975:1;29000:64;29056:7;29047:6;29036:9;29032:22;29000:64;:::i;:::-;28990:74;;28946:128;28730:351;;;;:::o;29087:162::-;29227:14;29223:1;29215:6;29211:14;29204:38;29087:162;:::o;29255:366::-;29397:3;29418:67;29482:2;29477:3;29418:67;:::i;:::-;29411:74;;29494:93;29583:3;29494:93;:::i;:::-;29612:2;29607:3;29603:12;29596:19;;29255:366;;;:::o;29627:419::-;29793:4;29831:2;29820:9;29816:18;29808:26;;29880:9;29874:4;29870:20;29866:1;29855:9;29851:17;29844:47;29908:131;30034:4;29908:131;:::i;:::-;29900:139;;29627:419;;;:::o;30052:180::-;30100:77;30097:1;30090:88;30197:4;30194:1;30187:15;30221:4;30218:1;30211:15;30238:168;30378:20;30374:1;30366:6;30362:14;30355:44;30238:168;:::o;30412:366::-;30554:3;30575:67;30639:2;30634:3;30575:67;:::i;:::-;30568:74;;30651:93;30740:3;30651:93;:::i;:::-;30769:2;30764:3;30760:12;30753:19;;30412:366;;;:::o;30784:419::-;30950:4;30988:2;30977:9;30973:18;30965:26;;31037:9;31031:4;31027:20;31023:1;31012:9;31008:17;31001:47;31065:131;31191:4;31065:131;:::i;:::-;31057:139;;30784:419;;;:::o;31209:143::-;31266:5;31297:6;31291:13;31282:22;;31313:33;31340:5;31313:33;:::i;:::-;31209:143;;;;:::o;31358:351::-;31428:6;31477:2;31465:9;31456:7;31452:23;31448:32;31445:119;;;31483:79;;:::i;:::-;31445:119;31603:1;31628:64;31684:7;31675:6;31664:9;31660:22;31628:64;:::i;:::-;31618:74;;31574:128;31358:351;;;;:::o;31715:162::-;31855:14;31851:1;31843:6;31839:14;31832:38;31715:162;:::o;31883:366::-;32025:3;32046:67;32110:2;32105:3;32046:67;:::i;:::-;32039:74;;32122:93;32211:3;32122:93;:::i;:::-;32240:2;32235:3;32231:12;32224:19;;31883:366;;;:::o;32255:419::-;32421:4;32459:2;32448:9;32444:18;32436:26;;32508:9;32502:4;32498:20;32494:1;32483:9;32479:17;32472:47;32536:131;32662:4;32536:131;:::i;:::-;32528:139;;32255:419;;;:::o;32680:233::-;32719:3;32742:24;32760:5;32742:24;:::i;:::-;32733:33;;32788:66;32781:5;32778:77;32775:103;;;32858:18;;:::i;:::-;32775:103;32905:1;32898:5;32894:13;32887:20;;32680:233;;;:::o;32919:165::-;33059:17;33055:1;33047:6;33043:14;33036:41;32919:165;:::o;33090:366::-;33232:3;33253:67;33317:2;33312:3;33253:67;:::i;:::-;33246:74;;33329:93;33418:3;33329:93;:::i;:::-;33447:2;33442:3;33438:12;33431:19;;33090:366;;;:::o;33462:419::-;33628:4;33666:2;33655:9;33651:18;33643:26;;33715:9;33709:4;33705:20;33701:1;33690:9;33686:17;33679:47;33743:131;33869:4;33743:131;:::i;:::-;33735:139;;33462:419;;;:::o;33887:163::-;34027:15;34023:1;34015:6;34011:14;34004:39;33887:163;:::o;34056:366::-;34198:3;34219:67;34283:2;34278:3;34219:67;:::i;:::-;34212:74;;34295:93;34384:3;34295:93;:::i;:::-;34413:2;34408:3;34404:12;34397:19;;34056:366;;;:::o;34428:419::-;34594:4;34632:2;34621:9;34617:18;34609:26;;34681:9;34675:4;34671:20;34667:1;34656:9;34652:17;34645:47;34709:131;34835:4;34709:131;:::i;:::-;34701:139;;34428:419;;;:::o;34853:223::-;34993:34;34989:1;34981:6;34977:14;34970:58;35062:6;35057:2;35049:6;35045:15;35038:31;34853:223;:::o;35082:366::-;35224:3;35245:67;35309:2;35304:3;35245:67;:::i;:::-;35238:74;;35321:93;35410:3;35321:93;:::i;:::-;35439:2;35434:3;35430:12;35423:19;;35082:366;;;:::o;35454:419::-;35620:4;35658:2;35647:9;35643:18;35635:26;;35707:9;35701:4;35697:20;35693:1;35682:9;35678:17;35671:47;35735:131;35861:4;35735:131;:::i;:::-;35727:139;;35454:419;;;:::o;35879:165::-;36019:17;36015:1;36007:6;36003:14;35996:41;35879:165;:::o;36050:366::-;36192:3;36213:67;36277:2;36272:3;36213:67;:::i;:::-;36206:74;;36289:93;36378:3;36289:93;:::i;:::-;36407:2;36402:3;36398:12;36391:19;;36050:366;;;:::o;36422:419::-;36588:4;36626:2;36615:9;36611:18;36603:26;;36675:9;36669:4;36665:20;36661:1;36650:9;36646:17;36639:47;36703:131;36829:4;36703:131;:::i;:::-;36695:139;;36422:419;;;:::o;36847:348::-;36887:7;36910:20;36928:1;36910:20;:::i;:::-;36905:25;;36944:20;36962:1;36944:20;:::i;:::-;36939:25;;37132:1;37064:66;37060:74;37057:1;37054:81;37049:1;37042:9;37035:17;37031:105;37028:131;;;37139:18;;:::i;:::-;37028:131;37187:1;37184;37180:9;37169:20;;36847:348;;;;:::o;37201:171::-;37341:23;37337:1;37329:6;37325:14;37318:47;37201:171;:::o;37378:366::-;37520:3;37541:67;37605:2;37600:3;37541:67;:::i;:::-;37534:74;;37617:93;37706:3;37617:93;:::i;:::-;37735:2;37730:3;37726:12;37719:19;;37378:366;;;:::o;37750:419::-;37916:4;37954:2;37943:9;37939:18;37931:26;;38003:9;37997:4;37993:20;37989:1;37978:9;37974:17;37967:47;38031:131;38157:4;38031:131;:::i;:::-;38023:139;;37750:419;;;:::o;38175:148::-;38277:11;38314:3;38299:18;;38175:148;;;;:::o;38329:377::-;38435:3;38463:39;38496:5;38463:39;:::i;:::-;38518:89;38600:6;38595:3;38518:89;:::i;:::-;38511:96;;38616:52;38661:6;38656:3;38649:4;38642:5;38638:16;38616:52;:::i;:::-;38693:6;38688:3;38684:16;38677:23;;38439:267;38329:377;;;;:::o;38712:155::-;38852:7;38848:1;38840:6;38836:14;38829:31;38712:155;:::o;38873:400::-;39033:3;39054:84;39136:1;39131:3;39054:84;:::i;:::-;39047:91;;39147:93;39236:3;39147:93;:::i;:::-;39265:1;39260:3;39256:11;39249:18;;38873:400;;;:::o;39279:541::-;39512:3;39534:95;39625:3;39616:6;39534:95;:::i;:::-;39527:102;;39646:148;39790:3;39646:148;:::i;:::-;39639:155;;39811:3;39804:10;;39279:541;;;;:::o;39826:225::-;39966:34;39962:1;39954:6;39950:14;39943:58;40035:8;40030:2;40022:6;40018:15;40011:33;39826:225;:::o;40057:366::-;40199:3;40220:67;40284:2;40279:3;40220:67;:::i;:::-;40213:74;;40296:93;40385:3;40296:93;:::i;:::-;40414:2;40409:3;40405:12;40398:19;;40057:366;;;:::o;40429:419::-;40595:4;40633:2;40622:9;40618:18;40610:26;;40682:9;40676:4;40672:20;40668:1;40657:9;40653:17;40646:47;40710:131;40836:4;40710:131;:::i;:::-;40702:139;;40429:419;;;:::o;40854:180::-;40902:77;40899:1;40892:88;40999:4;40996:1;40989:15;41023:4;41020:1;41013:15;41040:185;41080:1;41097:20;41115:1;41097:20;:::i;:::-;41092:25;;41131:20;41149:1;41131:20;:::i;:::-;41126:25;;41170:1;41160:35;;41175:18;;:::i;:::-;41160:35;41217:1;41214;41210:9;41205:14;;41040:185;;;;:::o;41231:191::-;41271:4;41291:20;41309:1;41291:20;:::i;:::-;41286:25;;41325:20;41343:1;41325:20;:::i;:::-;41320:25;;41364:1;41361;41358:8;41355:34;;;41369:18;;:::i;:::-;41355:34;41414:1;41411;41407:9;41399:17;;41231:191;;;;:::o;41428:179::-;41568:31;41564:1;41556:6;41552:14;41545:55;41428:179;:::o;41613:366::-;41755:3;41776:67;41840:2;41835:3;41776:67;:::i;:::-;41769:74;;41852:93;41941:3;41852:93;:::i;:::-;41970:2;41965:3;41961:12;41954:19;;41613:366;;;:::o;41985:419::-;42151:4;42189:2;42178:9;42174:18;42166:26;;42238:9;42232:4;42228:20;42224:1;42213:9;42209:17;42202:47;42266:131;42392:4;42266:131;:::i;:::-;42258:139;;41985:419;;;:::o;42410:147::-;42511:11;42548:3;42533:18;;42410:147;;;;:::o;42563:114::-;;:::o;42683:398::-;42842:3;42863:83;42944:1;42939:3;42863:83;:::i;:::-;42856:90;;42955:93;43044:3;42955:93;:::i;:::-;43073:1;43068:3;43064:11;43057:18;;42683:398;;;:::o;43087:379::-;43271:3;43293:147;43436:3;43293:147;:::i;:::-;43286:154;;43457:3;43450:10;;43087:379;;;:::o;43472:245::-;43612:34;43608:1;43600:6;43596:14;43589:58;43681:28;43676:2;43668:6;43664:15;43657:53;43472:245;:::o;43723:366::-;43865:3;43886:67;43950:2;43945:3;43886:67;:::i;:::-;43879:74;;43962:93;44051:3;43962:93;:::i;:::-;44080:2;44075:3;44071:12;44064:19;;43723:366;;;:::o;44095:419::-;44261:4;44299:2;44288:9;44284:18;44276:26;;44348:9;44342:4;44338:20;44334:1;44323:9;44319:17;44312:47;44376:131;44502:4;44376:131;:::i;:::-;44368:139;;44095:419;;;:::o;44520:98::-;44571:6;44605:5;44599:12;44589:22;;44520:98;;;:::o;44624:168::-;44707:11;44741:6;44736:3;44729:19;44781:4;44776:3;44772:14;44757:29;;44624:168;;;;:::o;44798:360::-;44884:3;44912:38;44944:5;44912:38;:::i;:::-;44966:70;45029:6;45024:3;44966:70;:::i;:::-;44959:77;;45045:52;45090:6;45085:3;45078:4;45071:5;45067:16;45045:52;:::i;:::-;45122:29;45144:6;45122:29;:::i;:::-;45117:3;45113:39;45106:46;;44888:270;44798:360;;;;:::o;45164:640::-;45359:4;45397:3;45386:9;45382:19;45374:27;;45411:71;45479:1;45468:9;45464:17;45455:6;45411:71;:::i;:::-;45492:72;45560:2;45549:9;45545:18;45536:6;45492:72;:::i;:::-;45574;45642:2;45631:9;45627:18;45618:6;45574:72;:::i;:::-;45693:9;45687:4;45683:20;45678:2;45667:9;45663:18;45656:48;45721:76;45792:4;45783:6;45721:76;:::i;:::-;45713:84;;45164:640;;;;;;;:::o;45810:141::-;45866:5;45897:6;45891:13;45882:22;;45913:32;45939:5;45913:32;:::i;:::-;45810:141;;;;:::o;45957:349::-;46026:6;46075:2;46063:9;46054:7;46050:23;46046:32;46043:119;;;46081:79;;:::i;:::-;46043:119;46201:1;46226:63;46281:7;46272:6;46261:9;46257:22;46226:63;:::i;:::-;46216:73;;46172:127;45957:349;;;;:::o;46312:435::-;46492:3;46514:95;46605:3;46596:6;46514:95;:::i;:::-;46507:102;;46626:95;46717:3;46708:6;46626:95;:::i;:::-;46619:102;;46738:3;46731:10;;46312:435;;;;;:::o;46753:137::-;46807:5;46838:6;46832:13;46823:22;;46854:30;46878:5;46854:30;:::i;:::-;46753:137;;;;:::o;46896:345::-;46963:6;47012:2;47000:9;46991:7;46987:23;46983:32;46980:119;;;47018:79;;:::i;:::-;46980:119;47138:1;47163:61;47216:7;47207:6;47196:9;47192:22;47163:61;:::i;:::-;47153:71;;47109:125;46896:345;;;;:::o;47247:229::-;47387:34;47383:1;47375:6;47371:14;47364:58;47456:12;47451:2;47443:6;47439:15;47432:37;47247:229;:::o;47482:366::-;47624:3;47645:67;47709:2;47704:3;47645:67;:::i;:::-;47638:74;;47721:93;47810:3;47721:93;:::i;:::-;47839:2;47834:3;47830:12;47823:19;;47482:366;;;:::o;47854:419::-;48020:4;48058:2;48047:9;48043:18;48035:26;;48107:9;48101:4;48097:20;48093:1;48082:9;48078:17;48071:47;48135:131;48261:4;48135:131;:::i;:::-;48127:139;;47854:419;;;:::o;48279:176::-;48311:1;48328:20;48346:1;48328:20;:::i;:::-;48323:25;;48362:20;48380:1;48362:20;:::i;:::-;48357:25;;48401:1;48391:35;;48406:18;;:::i;:::-;48391:35;48447:1;48444;48440:9;48435:14;;48279:176;;;;:::o;48461:225::-;48601:34;48597:1;48589:6;48585:14;48578:58;48670:8;48665:2;48657:6;48653:15;48646:33;48461:225;:::o;48692:366::-;48834:3;48855:67;48919:2;48914:3;48855:67;:::i;:::-;48848:74;;48931:93;49020:3;48931:93;:::i;:::-;49049:2;49044:3;49040:12;49033:19;;48692:366;;;:::o;49064:419::-;49230:4;49268:2;49257:9;49253:18;49245:26;;49317:9;49311:4;49307:20;49303:1;49292:9;49288:17;49281:47;49345:131;49471:4;49345:131;:::i;:::-;49337:139;;49064:419;;;:::o;49489:179::-;49629:31;49625:1;49617:6;49613:14;49606:55;49489:179;:::o;49674:366::-;49816:3;49837:67;49901:2;49896:3;49837:67;:::i;:::-;49830:74;;49913:93;50002:3;49913:93;:::i;:::-;50031:2;50026:3;50022:12;50015:19;;49674:366;;;:::o;50046:419::-;50212:4;50250:2;50239:9;50235:18;50227:26;;50299:9;50293:4;50289:20;50285:1;50274:9;50270:17;50263:47;50327:131;50453:4;50327:131;:::i;:::-;50319:139;;50046:419;;;:::o;50471:373::-;50575:3;50603:38;50635:5;50603:38;:::i;:::-;50657:88;50738:6;50733:3;50657:88;:::i;:::-;50650:95;;50754:52;50799:6;50794:3;50787:4;50780:5;50776:16;50754:52;:::i;:::-;50831:6;50826:3;50822:16;50815:23;;50579:265;50471:373;;;;:::o;50850:271::-;50980:3;51002:93;51091:3;51082:6;51002:93;:::i;:::-;50995:100;;51112:3;51105:10;;50850:271;;;;:::o

Swarm Source

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