ETH Price: $3,457.08 (-1.83%)
Gas: 3 Gwei

Token

Liquid Legends (LEGENDS)
 

Overview

Max Total Supply

3,333 LEGENDS

Holders

509

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 LEGENDS
0x532a408e6331e907f5a701312602301a9118a7bd
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
Legends

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-04-13
*/

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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


pragma solidity ^0.8.0;

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



pragma solidity ^0.8.0;



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

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



pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

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

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

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

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

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

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

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

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

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

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

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

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

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

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

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

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

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

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

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

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

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

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

        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

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

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

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

        assembly {
            result := store
        }

        return result;
    }
}





pragma solidity ^0.8.0;



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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;


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

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

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





pragma solidity ^0.8.0;

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




pragma solidity ^0.8.0;



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

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

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



pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


pragma solidity ^0.8.0;

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

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


pragma solidity ^0.8.0;

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

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

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

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

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


pragma solidity ^0.8.0;


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

pragma solidity ^0.8.0;



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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);
    }

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

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

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

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





pragma solidity ^0.8.0;



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

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

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

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

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

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

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

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

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

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

        _revokeRole(role, account);
    }

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

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

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

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


pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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


pragma solidity ^0.8.0;



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

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

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

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

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

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

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


pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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





pragma solidity ^0.8.4;


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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return uint256(_addressData[owner].balance);
    }

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public 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;





contract Legends is ERC721A, ReentrancyGuard, Ownable {

    // Minting Variables
    uint256 public mintPrice = 0.08 ether;
    uint256 public whitelistMintPrice = 0.025 ether;
    uint256 public maxPurchase = 3;
    uint256 public maxSupply = 3333;
    address public apeLiquidAddress;
    uint256 public liquidReserve = 1650;

    uint256 public reserveTokensMinted = 0;

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


    // Metadata
    string _baseTokenURI = "https://ipfs.io/ipfs/QmbYdwFxsh8GoZ6F9wY5ekQPwiXJjKiEiCs3neet8WDiF2/";
    bool public locked;

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


    constructor(address _apeLiquidAddress) ERC721A("Liquid Legends", "LEGENDS") {
    apeLiquidAddress = _apeLiquidAddress;
    }

 

    //Holder status validation

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

    function isOwnerOfValidLiquid(uint256[] calldata _apeLiquidIds, address _account) internal view {
        ERC721Enumerable apeLiquid = ERC721Enumerable(apeLiquidAddress);
        require(apeLiquid.balanceOf(_account) > 0, "NO_AL_TOKENS");
        for (uint256 i = 0; i < _apeLiquidIds.length; i++) {
            require(isApeLiquidAvailable(_apeLiquidIds[i]), "AL_ALREADY_CLAIMED");
            require(apeLiquid.ownerOf(_apeLiquidIds[i]) == _account, "NOT_AL_OWNER");
        }
    }

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

    function holderMint(uint256[] calldata _apeLiquidIds, uint256 _count) external payable nonReentrant {
        require(holderSaleIsActive, "HOLDER_SALE_INACTIVE");
          require(
            whitelistMintPrice  * _count <= msg.value,
            "INCORRECT_ETHER_VALUE"
        );
        require(
            _count == _apeLiquidIds.length,
            "INSUFFICIENT_AL_TOKENS"
        );
        require(
            totalSupply() + _count <= maxSupply,
            "SOLD_OUT"
        );
        isOwnerOfValidLiquid(_apeLiquidIds, msg.sender);
        for (uint256 i = 0; i < _apeLiquidIds.length; i++) {
            claimedApeLiquid[_apeLiquidIds[i]] = true;
        }
        _safeMint(msg.sender, _count);
        reserveTokensMinted++;
    }



    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"
        );
        isOwnerOfValidLiquid(_apeLiquidIds, msg.sender);
        for (uint256 i = 0; i < _apeLiquidIds.length; i++) {
            claimedApeLiquid[_apeLiquidIds[i]] = true;
        }
        for (uint256 i = 0; i < _apeLiquidIds.length; i++) {
            burnedApeLiquid[_apeLiquidIds[i]] = true;
        }
        _safeMint(msg.sender, _count);
        reserveTokensMinted++;
    }


    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 + liquidReserve - reserveTokensMinted <= 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 setWhitelistMintPrice(uint256 _mintPrice) external onlyOwner {
        whitelistMintPrice = _mintPrice;
    }

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

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

    function withdraw() external onlyOwner {
        payable(owner()).transfer(address(this).balance);
    }


    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":false,"internalType":"bool","name":"isActive","type":"bool"}],"name":"HolderSaleActivation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isActive","type":"bool"}],"name":"SaleActivation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"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":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"burnedApeLiquid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":[{"internalType":"uint256[]","name":"_apeLiquidIds","type":"uint256[]"},{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"holderMint","outputs":[],"stateMutability":"payable","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":"liquidReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"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":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserveTokensMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxPurchase","type":"uint256"}],"name":"setMaxPurchase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintPrice","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_liquidReserve","type":"uint256"}],"name":"setReserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintPrice","type":"uint256"}],"name":"setWhitelistMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleHolderSaleStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleSaleStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"whitelistMintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405267011c37937e080000600a556658d15e17628000600b556003600c55610d05600d55610672600f5560006010556000601160006101000a81548160ff0219169083151502179055506000601160016101000a81548160ff021916908315150217905550604051806080016040528060448152602001620051c8604491396015908051906020019062000098929190620002c9565b50348015620000a657600080fd5b506040516200520c3803806200520c8339818101604052810190620000cc919062000390565b6040518060400160405280600e81526020017f4c6971756964204c6567656e64730000000000000000000000000000000000008152506040518060400160405280600781526020017f4c4547454e445300000000000000000000000000000000000000000000000000815250816002908051906020019062000150929190620002c9565b50806003908051906020019062000169929190620002c9565b506200017a620001f260201b60201c565b60008190555050506001600881905550620001aa6200019e620001fb60201b60201c565b6200020360201b60201c565b80600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506200047a565b60006001905090565b600033905090565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620002d790620003f6565b90600052602060002090601f016020900481019282620002fb576000855562000347565b82601f106200031657805160ff191683800117855562000347565b8280016001018555821562000347579182015b828111156200034657825182559160200191906001019062000329565b5b5090506200035691906200035a565b5090565b5b80821115620003755760008160009055506001016200035b565b5090565b6000815190506200038a8162000460565b92915050565b600060208284031215620003a957620003a86200045b565b5b6000620003b98482850162000379565b91505092915050565b6000620003cf82620003d6565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600060028204905060018216806200040f57607f821691505b602082108114156200042657620004256200042c565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600080fd5b6200046b81620003c2565b81146200047757600080fd5b50565b614d3e806200048a6000396000f3fe60806040526004361061027d5760003560e01c8063715018a61161014f578063ae3692d4116100c1578063d5abeb011161007a578063d5abeb0114610944578063e5063b4e1461096f578063e985e9c5146109ac578063eb8d2444146109e9578063f2fde38b14610a14578063f4a0a52814610a3d5761027d565b8063ae3692d414610832578063b88d4fde1461085d578063c4e41b2214610886578063c87b56dd146108b1578063cf309012146108ee578063d0d703d3146109195761027d565b8063977b055b11610113578063977b055b14610745578063989bdbb614610770578063a0712d6814610787578063a22cb465146107a3578063a611708e146107cc578063ab2fdb0c146107f55761027d565b8063715018a61461067f578063782f31d7146106965780637d2dfbfe146106b25780638da5cb5b146106ef57806395d89b411461071a5761027d565b80634256dbe3116101f3578063627fdeab116101ac578063627fdeab146105495780636352211e146105865780636530fdc8146105c35780636817c76c146105ee57806370a082311461061957806371189742146106565761027d565b80634256dbe31461046357806342842e0e1461048c578063484b973c146104b55780634b6bcbed146104de57806351ab0c21146104f557806355f804b3146105205761027d565b806318160ddd1161024557806318160ddd146103675780631e0ba3151461039257806323b872dd146103bb57806335c6aaf8146103e45780633ccfd60b1461040f57806340691101146104265761027d565b806301ffc9a714610282578063049c5c49146102bf57806306fdde03146102d6578063081812fc14610301578063095ea7b31461033e575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613dee565b610a66565b6040516102b6919061431c565b60405180910390f35b3480156102cb57600080fd5b506102d4610b48565b005b3480156102e257600080fd5b506102eb610c36565b6040516102f89190614337565b60405180910390f35b34801561030d57600080fd5b5061032860048036038101906103239190613e91565b610cc8565b6040516103359190614293565b60405180910390f35b34801561034a57600080fd5b5061036560048036038101906103609190613d4e565b610d44565b005b34801561037357600080fd5b5061037c610e4f565b6040516103899190614519565b60405180910390f35b34801561039e57600080fd5b506103b960048036038101906103b49190613d8e565b610e66565b005b3480156103c757600080fd5b506103e260048036038101906103dd9190613c38565b6110a7565b005b3480156103f057600080fd5b506103f96110b7565b6040516104069190614519565b60405180910390f35b34801561041b57600080fd5b506104246110bd565b005b34801561043257600080fd5b5061044d60048036038101906104489190613e91565b611189565b60405161045a919061431c565b60405180910390f35b34801561046f57600080fd5b5061048a60048036038101906104859190613e91565b6111a9565b005b34801561049857600080fd5b506104b360048036038101906104ae9190613c38565b61122f565b005b3480156104c157600080fd5b506104dc60048036038101906104d79190613d4e565b61124f565b005b3480156104ea57600080fd5b506104f3611330565b005b34801561050157600080fd5b5061050a61141e565b6040516105179190614519565b60405180910390f35b34801561052c57600080fd5b5061054760048036038101906105429190613e48565b611424565b005b34801561055557600080fd5b50610570600480360381019061056b9190613b9e565b61150a565b60405161057d91906142fa565b60405180910390f35b34801561059257600080fd5b506105ad60048036038101906105a89190613e91565b611701565b6040516105ba9190614293565b60405180910390f35b3480156105cf57600080fd5b506105d8611717565b6040516105e59190614519565b60405180910390f35b3480156105fa57600080fd5b5061060361171d565b6040516106109190614519565b60405180910390f35b34801561062557600080fd5b50610640600480360381019061063b9190613b9e565b611723565b60405161064d9190614519565b60405180910390f35b34801561066257600080fd5b5061067d60048036038101906106789190613e91565b6117f3565b005b34801561068b57600080fd5b50610694611879565b005b6106b060048036038101906106ab9190613d8e565b611901565b005b3480156106be57600080fd5b506106d960048036038101906106d49190613e91565b611b2b565b6040516106e6919061431c565b60405180910390f35b3480156106fb57600080fd5b50610704611b4b565b6040516107119190614293565b60405180910390f35b34801561072657600080fd5b5061072f611b75565b60405161073c9190614337565b60405180910390f35b34801561075157600080fd5b5061075a611c07565b6040516107679190614519565b60405180910390f35b34801561077c57600080fd5b50610785611c0d565b005b6107a1600480360381019061079c9190613e91565b611ca6565b005b3480156107af57600080fd5b506107ca60048036038101906107c59190613d0e565b611f55565b005b3480156107d857600080fd5b506107f360048036038101906107ee9190613e91565b6120cd565b005b34801561080157600080fd5b5061081c60048036038101906108179190613b9e565b612153565b6040516108299190614519565b60405180910390f35b34801561083e57600080fd5b5061084761216b565b6040516108549190614293565b60405180910390f35b34801561086957600080fd5b50610884600480360381019061087f9190613c8b565b612191565b005b34801561089257600080fd5b5061089b61220d565b6040516108a89190614519565b60405180910390f35b3480156108bd57600080fd5b506108d860048036038101906108d39190613e91565b61221c565b6040516108e59190614337565b60405180910390f35b3480156108fa57600080fd5b5061090361224d565b604051610910919061431c565b60405180910390f35b34801561092557600080fd5b5061092e612260565b60405161093b919061431c565b60405180910390f35b34801561095057600080fd5b50610959612273565b6040516109669190614519565b60405180910390f35b34801561097b57600080fd5b5061099660048036038101906109919190613e91565b612279565b6040516109a3919061431c565b60405180910390f35b3480156109b857600080fd5b506109d360048036038101906109ce9190613bf8565b6122ab565b6040516109e0919061431c565b60405180910390f35b3480156109f557600080fd5b506109fe61233f565b604051610a0b919061431c565b60405180910390f35b348015610a2057600080fd5b50610a3b6004803603810190610a369190613b9e565b612352565b005b348015610a4957600080fd5b50610a646004803603810190610a5f9190613e91565b61244a565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610b3157507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b415750610b40826124d0565b5b9050919050565b610b5061253a565b73ffffffffffffffffffffffffffffffffffffffff16610b6e611b4b565b73ffffffffffffffffffffffffffffffffffffffff1614610bc4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbb90614459565b60405180910390fd5b601160009054906101000a900460ff1615601160006101000a81548160ff0219169083151502179055507f58655b75d3df612fe99ead00dbf0812d415d35078fe06217a94c0818bb13967f601160009054906101000a900460ff16604051610c2c919061431c565b60405180910390a1565b606060028054610c4590614802565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7190614802565b8015610cbe5780601f10610c9357610100808354040283529160200191610cbe565b820191906000526020600020905b815481529060010190602001808311610ca157829003601f168201915b5050505050905090565b6000610cd382612542565b610d09576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610d4f82611701565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610db7576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610dd661253a565b73ffffffffffffffffffffffffffffffffffffffff1614158015610e085750610e0681610e0161253a565b6122ab565b155b15610e3f576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e4a838383612590565b505050565b6000610e59612642565b6001546000540303905090565b60026008541415610eac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea3906144f9565b60405180910390fd5b6002600881905550601160019054906101000a900460ff16610f03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610efa90614359565b60405180910390fd5b828290508114610f48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3f90614399565b60405180910390fd5b600d5481610f54610e4f565b610f5e9190614637565b1115610f9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f96906143f9565b60405180910390fd5b610faa83833361264b565b60005b8383905081101561101057600160126000868685818110610fd157610fd061496c565b5b90506020020135815260200190815260200160002060006101000a81548160ff021916908315150217905550808061100890614865565b915050610fad565b5060005b83839050811015611077576001601360008686858181106110385761103761496c565b5b90506020020135815260200190815260200160002060006101000a81548160ff021916908315150217905550808061106f90614865565b915050611014565b5061108233826128d5565b6010600081548092919061109590614865565b91905055506001600881905550505050565b6110b28383836128f3565b505050565b600b5481565b6110c561253a565b73ffffffffffffffffffffffffffffffffffffffff166110e3611b4b565b73ffffffffffffffffffffffffffffffffffffffff1614611139576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113090614459565b60405180910390fd5b611141611b4b565b73ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015611186573d6000803e3d6000fd5b50565b60126020528060005260406000206000915054906101000a900460ff1681565b6111b161253a565b73ffffffffffffffffffffffffffffffffffffffff166111cf611b4b565b73ffffffffffffffffffffffffffffffffffffffff1614611225576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121c90614459565b60405180910390fd5b80600f8190555050565b61124a83838360405180602001604052806000815250612191565b505050565b61125761253a565b73ffffffffffffffffffffffffffffffffffffffff16611275611b4b565b73ffffffffffffffffffffffffffffffffffffffff16146112cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c290614459565b60405180910390fd5b600d54816112d7610e4f565b6112e19190614637565b1115611322576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611319906143f9565b60405180910390fd5b61132c82826128d5565b5050565b61133861253a565b73ffffffffffffffffffffffffffffffffffffffff16611356611b4b565b73ffffffffffffffffffffffffffffffffffffffff16146113ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a390614459565b60405180910390fd5b601160019054906101000a900460ff1615601160016101000a81548160ff0219169083151502179055507fbc5b3e222a18d52c6bd2bc19880c605e9a1b50b11689f0315d149d12a26230fa601160019054906101000a900460ff16604051611414919061431c565b60405180910390a1565b600f5481565b61142c61253a565b73ffffffffffffffffffffffffffffffffffffffff1661144a611b4b565b73ffffffffffffffffffffffffffffffffffffffff16146114a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149790614459565b60405180910390fd5b601660009054906101000a900460ff16156114f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e7906143d9565b60405180910390fd5b80601590805190602001906115069291906138ef565b5050565b6060600061151783611723565b67ffffffffffffffff8111156115305761152f61499b565b5b60405190808252806020026020018201604052801561155e5781602001602082028036833780820191505090505b50905060008054905060008060005b838110156116f4576000600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff161515151581525050905080604001511561164a57506116e7565b600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161461168a57806000015192505b8773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156116e557818685806001019650815181106116d8576116d761496c565b5b6020026020010181815250505b505b808060010191505061156d565b5083945050505050919050565b600061170c82612da9565b600001519050919050565b60105481565b600a5481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561178b576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b6117fb61253a565b73ffffffffffffffffffffffffffffffffffffffff16611819611b4b565b73ffffffffffffffffffffffffffffffffffffffff161461186f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186690614459565b60405180910390fd5b80600c8190555050565b61188161253a565b73ffffffffffffffffffffffffffffffffffffffff1661189f611b4b565b73ffffffffffffffffffffffffffffffffffffffff16146118f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118ec90614459565b60405180910390fd5b6118ff6000613038565b565b60026008541415611947576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193e906144f9565b60405180910390fd5b6002600881905550601160019054906101000a900460ff1661199e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161199590614359565b60405180910390fd5b3481600b546119ad91906146be565b11156119ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e5906143b9565b60405180910390fd5b828290508114611a33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2a90614399565b60405180910390fd5b600d5481611a3f610e4f565b611a499190614637565b1115611a8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a81906143f9565b60405180910390fd5b611a9583833361264b565b60005b83839050811015611afb57600160126000868685818110611abc57611abb61496c565b5b90506020020135815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611af390614865565b915050611a98565b50611b0633826128d5565b60106000815480929190611b1990614865565b91905055506001600881905550505050565b60136020528060005260406000206000915054906101000a900460ff1681565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054611b8490614802565b80601f0160208091040260200160405190810160405280929190818152602001828054611bb090614802565b8015611bfd5780601f10611bd257610100808354040283529160200191611bfd565b820191906000526020600020905b815481529060010190602001808311611be057829003601f168201915b5050505050905090565b600c5481565b611c1561253a565b73ffffffffffffffffffffffffffffffffffffffff16611c33611b4b565b73ffffffffffffffffffffffffffffffffffffffff1614611c89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8090614459565b60405180910390fd5b6001601660006101000a81548160ff021916908315150217905550565b60026008541415611cec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce3906144f9565b60405180910390fd5b6002600881905550601160009054906101000a900460ff16611d43576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3a90614439565b60405180910390fd5b600c5481601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611d919190614637565b1115611dd2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dc990614479565b60405180910390fd5b600d5481611dde610e4f565b611de89190614637565b1115611e29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e20906143f9565b60405180910390fd5b600d54601054600f5483611e3b610e4f565b611e459190614637565b611e4f9190614637565b611e599190614718565b1115611e9a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e91906144d9565b60405180910390fd5b3481600a54611ea991906146be565b1115611eea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ee1906143b9565b60405180910390fd5b611ef433826128d5565b80601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f439190614637565b92505081905550600160088190555050565b611f5d61253a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611fc2576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060076000611fcf61253a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661207c61253a565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516120c1919061431c565b60405180910390a35050565b6120d561253a565b73ffffffffffffffffffffffffffffffffffffffff166120f3611b4b565b73ffffffffffffffffffffffffffffffffffffffff1614612149576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214090614459565b60405180910390fd5b80600b8190555050565b60146020528060005260406000206000915090505481565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61219c8484846128f3565b6121bb8373ffffffffffffffffffffffffffffffffffffffff166130fe565b80156121d057506121ce84848484613111565b155b15612207576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6000612217610e4f565b905090565b606061222782613271565b6040516020016122379190614271565b6040516020818303038152906040529050919050565b601660009054906101000a900460ff1681565b601160019054906101000a900460ff1681565b600d5481565b6000600115156012600084815260200190815260200160002060009054906101000a900460ff16151514159050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b601160009054906101000a900460ff1681565b61235a61253a565b73ffffffffffffffffffffffffffffffffffffffff16612378611b4b565b73ffffffffffffffffffffffffffffffffffffffff16146123ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123c590614459565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561243e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161243590614379565b60405180910390fd5b61244781613038565b50565b61245261253a565b73ffffffffffffffffffffffffffffffffffffffff16612470611b4b565b73ffffffffffffffffffffffffffffffffffffffff16146124c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124bd90614459565b60405180910390fd5b80600a8190555050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b60008161254d612642565b1115801561255c575060005482105b8015612589575060046000838152602001908152602001600020600001601c9054906101000a900460ff16155b9050919050565b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006001905090565b6000600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231846040518263ffffffff1660e01b81526004016126ad9190614293565b60206040518083038186803b1580156126c557600080fd5b505afa1580156126d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126fd9190613ebe565b1161273d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612734906144b9565b60405180910390fd5b60005b848490508110156128ce5761276d8585838181106127615761276061496c565b5b90506020020135612279565b6127ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127a390614499565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16636352211e8787858181106127f2576127f161496c565b5b905060200201356040518263ffffffff1660e01b81526004016128159190614519565b60206040518083038186803b15801561282d57600080fd5b505afa158015612841573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128659190613bcb565b73ffffffffffffffffffffffffffffffffffffffff16146128bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b290614419565b60405180910390fd5b80806128c690614865565b915050612740565b5050505050565b6128ef828260405180602001604052806000815250613310565b5050565b60006128fe82612da9565b90508373ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614612969576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff1661298a61253a565b73ffffffffffffffffffffffffffffffffffffffff1614806129b957506129b8856129b361253a565b6122ab565b5b806129fe57506129c761253a565b73ffffffffffffffffffffffffffffffffffffffff166129e684610cc8565b73ffffffffffffffffffffffffffffffffffffffff16145b905080612a37576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415612a9e576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612aab8585856001613322565b612ab760008487612590565b6001600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160392506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600460008581526020019081526020016000209050848160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550428160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060006001850190506000600460008381526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415612d37576000548214612d3657878160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084602001518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b505050828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612da28585856001613328565b5050505050565b612db1613975565b600082905080612dbf612642565b11158015612dce575060005481105b15613001576000600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff16151515158152505090508060400151612fff57600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614612ee3578092505050613033565b5b600115612ffe57818060019003925050600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614612ff9578092505050613033565b612ee4565b5b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080823b905060008111915050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261313761253a565b8786866040518563ffffffff1660e01b815260040161315994939291906142ae565b602060405180830381600087803b15801561317357600080fd5b505af19250505080156131a457506040513d601f19601f820116820180604052508101906131a19190613e1b565b60015b61321e573d80600081146131d4576040519150601f19603f3d011682016040523d82523d6000602084013e6131d9565b606091505b50600081511415613216576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b606061327c82612542565b6132b2576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006132bc61332e565b90506000815114156132dd5760405180602001604052806000815250613308565b806132e7846133c0565b6040516020016132f892919061424d565b6040516020818303038152906040525b915050919050565b61331d8383836001613521565b505050565b50505050565b50505050565b60606015805461333d90614802565b80601f016020809104026020016040519081016040528092919081815260200182805461336990614802565b80156133b65780601f1061338b576101008083540402835291602001916133b6565b820191906000526020600020905b81548152906001019060200180831161339957829003601f168201915b5050505050905090565b60606000821415613408576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061351c565b600082905060005b6000821461343a57808061342390614865565b915050600a82613433919061468d565b9150613410565b60008167ffffffffffffffff8111156134565761345561499b565b5b6040519080825280601f01601f1916602001820160405280156134885781602001600182028036833780820191505090505b5090505b60008514613515576001826134a19190614718565b9150600a856134b091906148ae565b60306134bc9190614637565b60f81b8183815181106134d2576134d161496c565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561350e919061468d565b945061348c565b8093505050505b919050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141561358e576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008414156135c9576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6135d66000868387613322565b83600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555083600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550846004600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426004600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000819050600085820190508380156137a0575061379f8773ffffffffffffffffffffffffffffffffffffffff166130fe565b5b15613866575b818773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46138156000888480600101955088613111565b61384b576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808214156137a657826000541461386157600080fd5b6138d2565b5b818060010192508773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a480821415613867575b8160008190555050506138e86000868387613328565b5050505050565b8280546138fb90614802565b90600052602060002090601f01602090048101928261391d5760008555613964565b82601f1061393657805160ff1916838001178555613964565b82800160010185558215613964579182015b82811115613963578251825591602001919060010190613948565b5b50905061397191906139b8565b5090565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681526020016000151581525090565b5b808211156139d15760008160009055506001016139b9565b5090565b60006139e86139e384614559565b614534565b905082815260208101848484011115613a0457613a036149d9565b5b613a0f8482856147c0565b509392505050565b6000613a2a613a258461458a565b614534565b905082815260208101848484011115613a4657613a456149d9565b5b613a518482856147c0565b509392505050565b600081359050613a6881614cac565b92915050565b600081519050613a7d81614cac565b92915050565b60008083601f840112613a9957613a986149cf565b5b8235905067ffffffffffffffff811115613ab657613ab56149ca565b5b602083019150836020820283011115613ad257613ad16149d4565b5b9250929050565b600081359050613ae881614cc3565b92915050565b600081359050613afd81614cda565b92915050565b600081519050613b1281614cda565b92915050565b600082601f830112613b2d57613b2c6149cf565b5b8135613b3d8482602086016139d5565b91505092915050565b600082601f830112613b5b57613b5a6149cf565b5b8135613b6b848260208601613a17565b91505092915050565b600081359050613b8381614cf1565b92915050565b600081519050613b9881614cf1565b92915050565b600060208284031215613bb457613bb36149e3565b5b6000613bc284828501613a59565b91505092915050565b600060208284031215613be157613be06149e3565b5b6000613bef84828501613a6e565b91505092915050565b60008060408385031215613c0f57613c0e6149e3565b5b6000613c1d85828601613a59565b9250506020613c2e85828601613a59565b9150509250929050565b600080600060608486031215613c5157613c506149e3565b5b6000613c5f86828701613a59565b9350506020613c7086828701613a59565b9250506040613c8186828701613b74565b9150509250925092565b60008060008060808587031215613ca557613ca46149e3565b5b6000613cb387828801613a59565b9450506020613cc487828801613a59565b9350506040613cd587828801613b74565b925050606085013567ffffffffffffffff811115613cf657613cf56149de565b5b613d0287828801613b18565b91505092959194509250565b60008060408385031215613d2557613d246149e3565b5b6000613d3385828601613a59565b9250506020613d4485828601613ad9565b9150509250929050565b60008060408385031215613d6557613d646149e3565b5b6000613d7385828601613a59565b9250506020613d8485828601613b74565b9150509250929050565b600080600060408486031215613da757613da66149e3565b5b600084013567ffffffffffffffff811115613dc557613dc46149de565b5b613dd186828701613a83565b93509350506020613de486828701613b74565b9150509250925092565b600060208284031215613e0457613e036149e3565b5b6000613e1284828501613aee565b91505092915050565b600060208284031215613e3157613e306149e3565b5b6000613e3f84828501613b03565b91505092915050565b600060208284031215613e5e57613e5d6149e3565b5b600082013567ffffffffffffffff811115613e7c57613e7b6149de565b5b613e8884828501613b46565b91505092915050565b600060208284031215613ea757613ea66149e3565b5b6000613eb584828501613b74565b91505092915050565b600060208284031215613ed457613ed36149e3565b5b6000613ee284828501613b89565b91505092915050565b6000613ef7838361422f565b60208301905092915050565b613f0c8161474c565b82525050565b6000613f1d826145cb565b613f2781856145f9565b9350613f32836145bb565b8060005b83811015613f63578151613f4a8882613eeb565b9750613f55836145ec565b925050600181019050613f36565b5085935050505092915050565b613f798161475e565b82525050565b6000613f8a826145d6565b613f94818561460a565b9350613fa48185602086016147cf565b613fad816149e8565b840191505092915050565b6000613fc3826145e1565b613fcd818561461b565b9350613fdd8185602086016147cf565b613fe6816149e8565b840191505092915050565b6000613ffc826145e1565b614006818561462c565b93506140168185602086016147cf565b80840191505092915050565b600061402f60148361461b565b915061403a826149f9565b602082019050919050565b600061405260268361461b565b915061405d82614a22565b604082019050919050565b600061407560168361461b565b915061408082614a71565b602082019050919050565b600061409860158361461b565b91506140a382614a9a565b602082019050919050565b60006140bb600f8361461b565b91506140c682614ac3565b602082019050919050565b60006140de60088361461b565b91506140e982614aec565b602082019050919050565b6000614101600c8361461b565b915061410c82614b15565b602082019050919050565b600061412460058361462c565b915061412f82614b3e565b600582019050919050565b6000614147600d8361461b565b915061415282614b67565b602082019050919050565b600061416a60208361461b565b915061417582614b90565b602082019050919050565b600061418d60248361461b565b915061419882614bb9565b604082019050919050565b60006141b060128361461b565b91506141bb82614c08565b602082019050919050565b60006141d3600c8361461b565b91506141de82614c31565b602082019050919050565b60006141f6600f8361461b565b915061420182614c5a565b602082019050919050565b6000614219601f8361461b565b915061422482614c83565b602082019050919050565b614238816147b6565b82525050565b614247816147b6565b82525050565b60006142598285613ff1565b91506142658284613ff1565b91508190509392505050565b600061427d8284613ff1565b915061428882614117565b915081905092915050565b60006020820190506142a86000830184613f03565b92915050565b60006080820190506142c36000830187613f03565b6142d06020830186613f03565b6142dd604083018561423e565b81810360608301526142ef8184613f7f565b905095945050505050565b600060208201905081810360008301526143148184613f12565b905092915050565b60006020820190506143316000830184613f70565b92915050565b600060208201905081810360008301526143518184613fb8565b905092915050565b6000602082019050818103600083015261437281614022565b9050919050565b6000602082019050818103600083015261439281614045565b9050919050565b600060208201905081810360008301526143b281614068565b9050919050565b600060208201905081810360008301526143d28161408b565b9050919050565b600060208201905081810360008301526143f2816140ae565b9050919050565b60006020820190508181036000830152614412816140d1565b9050919050565b60006020820190508181036000830152614432816140f4565b9050919050565b600060208201905081810360008301526144528161413a565b9050919050565b600060208201905081810360008301526144728161415d565b9050919050565b6000602082019050818103600083015261449281614180565b9050919050565b600060208201905081810360008301526144b2816141a3565b9050919050565b600060208201905081810360008301526144d2816141c6565b9050919050565b600060208201905081810360008301526144f2816141e9565b9050919050565b600060208201905081810360008301526145128161420c565b9050919050565b600060208201905061452e600083018461423e565b92915050565b600061453e61454f565b905061454a8282614834565b919050565b6000604051905090565b600067ffffffffffffffff8211156145745761457361499b565b5b61457d826149e8565b9050602081019050919050565b600067ffffffffffffffff8211156145a5576145a461499b565b5b6145ae826149e8565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000614642826147b6565b915061464d836147b6565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614682576146816148df565b5b828201905092915050565b6000614698826147b6565b91506146a3836147b6565b9250826146b3576146b261490e565b5b828204905092915050565b60006146c9826147b6565b91506146d4836147b6565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561470d5761470c6148df565b5b828202905092915050565b6000614723826147b6565b915061472e836147b6565b925082821015614741576147406148df565b5b828203905092915050565b600061475782614796565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156147ed5780820151818401526020810190506147d2565b838111156147fc576000848401525b50505050565b6000600282049050600182168061481a57607f821691505b6020821081141561482e5761482d61493d565b5b50919050565b61483d826149e8565b810181811067ffffffffffffffff8211171561485c5761485b61499b565b5b80604052505050565b6000614870826147b6565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156148a3576148a26148df565b5b600182019050919050565b60006148b9826147b6565b91506148c4836147b6565b9250826148d4576148d361490e565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f484f4c4445525f53414c455f494e414354495645000000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f494e53554646494349454e545f414c5f544f4b454e5300000000000000000000600082015250565b7f494e434f52524543545f45544845525f56414c55450000000000000000000000600082015250565b7f4d455441444154415f4c4f434b45440000000000000000000000000000000000600082015250565b7f534f4c445f4f5554000000000000000000000000000000000000000000000000600082015250565b7f4e4f545f414c5f4f574e45520000000000000000000000000000000000000000600082015250565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b7f53414c455f494e41435449564500000000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f7468697320776f756c6420657863656564206d696e74206d617820616c6c6f7760008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b7f414c5f414c52454144595f434c41494d45440000000000000000000000000000600082015250565b7f4e4f5f414c5f544f4b454e530000000000000000000000000000000000000000600082015250565b7f5055424c49435f534f4c445f4f55540000000000000000000000000000000000600082015250565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b614cb58161474c565b8114614cc057600080fd5b50565b614ccc8161475e565b8114614cd757600080fd5b50565b614ce38161476a565b8114614cee57600080fd5b50565b614cfa816147b6565b8114614d0557600080fd5b5056fea264697066735822122017fd7e2b4533fbcb642277a3150446de225a767699a98c38ee66ff78549fa2ed64736f6c6343000807003368747470733a2f2f697066732e696f2f697066732f516d625964774678736838476f5a364639775935656b51507769584a6a4b6945694373336e6565743857446946322f00000000000000000000000061028f622cb6618cac3deb9ef0f0d5b9c6369c72

Deployed Bytecode

0x60806040526004361061027d5760003560e01c8063715018a61161014f578063ae3692d4116100c1578063d5abeb011161007a578063d5abeb0114610944578063e5063b4e1461096f578063e985e9c5146109ac578063eb8d2444146109e9578063f2fde38b14610a14578063f4a0a52814610a3d5761027d565b8063ae3692d414610832578063b88d4fde1461085d578063c4e41b2214610886578063c87b56dd146108b1578063cf309012146108ee578063d0d703d3146109195761027d565b8063977b055b11610113578063977b055b14610745578063989bdbb614610770578063a0712d6814610787578063a22cb465146107a3578063a611708e146107cc578063ab2fdb0c146107f55761027d565b8063715018a61461067f578063782f31d7146106965780637d2dfbfe146106b25780638da5cb5b146106ef57806395d89b411461071a5761027d565b80634256dbe3116101f3578063627fdeab116101ac578063627fdeab146105495780636352211e146105865780636530fdc8146105c35780636817c76c146105ee57806370a082311461061957806371189742146106565761027d565b80634256dbe31461046357806342842e0e1461048c578063484b973c146104b55780634b6bcbed146104de57806351ab0c21146104f557806355f804b3146105205761027d565b806318160ddd1161024557806318160ddd146103675780631e0ba3151461039257806323b872dd146103bb57806335c6aaf8146103e45780633ccfd60b1461040f57806340691101146104265761027d565b806301ffc9a714610282578063049c5c49146102bf57806306fdde03146102d6578063081812fc14610301578063095ea7b31461033e575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613dee565b610a66565b6040516102b6919061431c565b60405180910390f35b3480156102cb57600080fd5b506102d4610b48565b005b3480156102e257600080fd5b506102eb610c36565b6040516102f89190614337565b60405180910390f35b34801561030d57600080fd5b5061032860048036038101906103239190613e91565b610cc8565b6040516103359190614293565b60405180910390f35b34801561034a57600080fd5b5061036560048036038101906103609190613d4e565b610d44565b005b34801561037357600080fd5b5061037c610e4f565b6040516103899190614519565b60405180910390f35b34801561039e57600080fd5b506103b960048036038101906103b49190613d8e565b610e66565b005b3480156103c757600080fd5b506103e260048036038101906103dd9190613c38565b6110a7565b005b3480156103f057600080fd5b506103f96110b7565b6040516104069190614519565b60405180910390f35b34801561041b57600080fd5b506104246110bd565b005b34801561043257600080fd5b5061044d60048036038101906104489190613e91565b611189565b60405161045a919061431c565b60405180910390f35b34801561046f57600080fd5b5061048a60048036038101906104859190613e91565b6111a9565b005b34801561049857600080fd5b506104b360048036038101906104ae9190613c38565b61122f565b005b3480156104c157600080fd5b506104dc60048036038101906104d79190613d4e565b61124f565b005b3480156104ea57600080fd5b506104f3611330565b005b34801561050157600080fd5b5061050a61141e565b6040516105179190614519565b60405180910390f35b34801561052c57600080fd5b5061054760048036038101906105429190613e48565b611424565b005b34801561055557600080fd5b50610570600480360381019061056b9190613b9e565b61150a565b60405161057d91906142fa565b60405180910390f35b34801561059257600080fd5b506105ad60048036038101906105a89190613e91565b611701565b6040516105ba9190614293565b60405180910390f35b3480156105cf57600080fd5b506105d8611717565b6040516105e59190614519565b60405180910390f35b3480156105fa57600080fd5b5061060361171d565b6040516106109190614519565b60405180910390f35b34801561062557600080fd5b50610640600480360381019061063b9190613b9e565b611723565b60405161064d9190614519565b60405180910390f35b34801561066257600080fd5b5061067d60048036038101906106789190613e91565b6117f3565b005b34801561068b57600080fd5b50610694611879565b005b6106b060048036038101906106ab9190613d8e565b611901565b005b3480156106be57600080fd5b506106d960048036038101906106d49190613e91565b611b2b565b6040516106e6919061431c565b60405180910390f35b3480156106fb57600080fd5b50610704611b4b565b6040516107119190614293565b60405180910390f35b34801561072657600080fd5b5061072f611b75565b60405161073c9190614337565b60405180910390f35b34801561075157600080fd5b5061075a611c07565b6040516107679190614519565b60405180910390f35b34801561077c57600080fd5b50610785611c0d565b005b6107a1600480360381019061079c9190613e91565b611ca6565b005b3480156107af57600080fd5b506107ca60048036038101906107c59190613d0e565b611f55565b005b3480156107d857600080fd5b506107f360048036038101906107ee9190613e91565b6120cd565b005b34801561080157600080fd5b5061081c60048036038101906108179190613b9e565b612153565b6040516108299190614519565b60405180910390f35b34801561083e57600080fd5b5061084761216b565b6040516108549190614293565b60405180910390f35b34801561086957600080fd5b50610884600480360381019061087f9190613c8b565b612191565b005b34801561089257600080fd5b5061089b61220d565b6040516108a89190614519565b60405180910390f35b3480156108bd57600080fd5b506108d860048036038101906108d39190613e91565b61221c565b6040516108e59190614337565b60405180910390f35b3480156108fa57600080fd5b5061090361224d565b604051610910919061431c565b60405180910390f35b34801561092557600080fd5b5061092e612260565b60405161093b919061431c565b60405180910390f35b34801561095057600080fd5b50610959612273565b6040516109669190614519565b60405180910390f35b34801561097b57600080fd5b5061099660048036038101906109919190613e91565b612279565b6040516109a3919061431c565b60405180910390f35b3480156109b857600080fd5b506109d360048036038101906109ce9190613bf8565b6122ab565b6040516109e0919061431c565b60405180910390f35b3480156109f557600080fd5b506109fe61233f565b604051610a0b919061431c565b60405180910390f35b348015610a2057600080fd5b50610a3b6004803603810190610a369190613b9e565b612352565b005b348015610a4957600080fd5b50610a646004803603810190610a5f9190613e91565b61244a565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610b3157507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b415750610b40826124d0565b5b9050919050565b610b5061253a565b73ffffffffffffffffffffffffffffffffffffffff16610b6e611b4b565b73ffffffffffffffffffffffffffffffffffffffff1614610bc4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbb90614459565b60405180910390fd5b601160009054906101000a900460ff1615601160006101000a81548160ff0219169083151502179055507f58655b75d3df612fe99ead00dbf0812d415d35078fe06217a94c0818bb13967f601160009054906101000a900460ff16604051610c2c919061431c565b60405180910390a1565b606060028054610c4590614802565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7190614802565b8015610cbe5780601f10610c9357610100808354040283529160200191610cbe565b820191906000526020600020905b815481529060010190602001808311610ca157829003601f168201915b5050505050905090565b6000610cd382612542565b610d09576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610d4f82611701565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610db7576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610dd661253a565b73ffffffffffffffffffffffffffffffffffffffff1614158015610e085750610e0681610e0161253a565b6122ab565b155b15610e3f576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e4a838383612590565b505050565b6000610e59612642565b6001546000540303905090565b60026008541415610eac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea3906144f9565b60405180910390fd5b6002600881905550601160019054906101000a900460ff16610f03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610efa90614359565b60405180910390fd5b828290508114610f48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3f90614399565b60405180910390fd5b600d5481610f54610e4f565b610f5e9190614637565b1115610f9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f96906143f9565b60405180910390fd5b610faa83833361264b565b60005b8383905081101561101057600160126000868685818110610fd157610fd061496c565b5b90506020020135815260200190815260200160002060006101000a81548160ff021916908315150217905550808061100890614865565b915050610fad565b5060005b83839050811015611077576001601360008686858181106110385761103761496c565b5b90506020020135815260200190815260200160002060006101000a81548160ff021916908315150217905550808061106f90614865565b915050611014565b5061108233826128d5565b6010600081548092919061109590614865565b91905055506001600881905550505050565b6110b28383836128f3565b505050565b600b5481565b6110c561253a565b73ffffffffffffffffffffffffffffffffffffffff166110e3611b4b565b73ffffffffffffffffffffffffffffffffffffffff1614611139576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113090614459565b60405180910390fd5b611141611b4b565b73ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015611186573d6000803e3d6000fd5b50565b60126020528060005260406000206000915054906101000a900460ff1681565b6111b161253a565b73ffffffffffffffffffffffffffffffffffffffff166111cf611b4b565b73ffffffffffffffffffffffffffffffffffffffff1614611225576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121c90614459565b60405180910390fd5b80600f8190555050565b61124a83838360405180602001604052806000815250612191565b505050565b61125761253a565b73ffffffffffffffffffffffffffffffffffffffff16611275611b4b565b73ffffffffffffffffffffffffffffffffffffffff16146112cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c290614459565b60405180910390fd5b600d54816112d7610e4f565b6112e19190614637565b1115611322576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611319906143f9565b60405180910390fd5b61132c82826128d5565b5050565b61133861253a565b73ffffffffffffffffffffffffffffffffffffffff16611356611b4b565b73ffffffffffffffffffffffffffffffffffffffff16146113ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a390614459565b60405180910390fd5b601160019054906101000a900460ff1615601160016101000a81548160ff0219169083151502179055507fbc5b3e222a18d52c6bd2bc19880c605e9a1b50b11689f0315d149d12a26230fa601160019054906101000a900460ff16604051611414919061431c565b60405180910390a1565b600f5481565b61142c61253a565b73ffffffffffffffffffffffffffffffffffffffff1661144a611b4b565b73ffffffffffffffffffffffffffffffffffffffff16146114a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149790614459565b60405180910390fd5b601660009054906101000a900460ff16156114f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e7906143d9565b60405180910390fd5b80601590805190602001906115069291906138ef565b5050565b6060600061151783611723565b67ffffffffffffffff8111156115305761152f61499b565b5b60405190808252806020026020018201604052801561155e5781602001602082028036833780820191505090505b50905060008054905060008060005b838110156116f4576000600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff161515151581525050905080604001511561164a57506116e7565b600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161461168a57806000015192505b8773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156116e557818685806001019650815181106116d8576116d761496c565b5b6020026020010181815250505b505b808060010191505061156d565b5083945050505050919050565b600061170c82612da9565b600001519050919050565b60105481565b600a5481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561178b576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b6117fb61253a565b73ffffffffffffffffffffffffffffffffffffffff16611819611b4b565b73ffffffffffffffffffffffffffffffffffffffff161461186f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186690614459565b60405180910390fd5b80600c8190555050565b61188161253a565b73ffffffffffffffffffffffffffffffffffffffff1661189f611b4b565b73ffffffffffffffffffffffffffffffffffffffff16146118f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118ec90614459565b60405180910390fd5b6118ff6000613038565b565b60026008541415611947576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193e906144f9565b60405180910390fd5b6002600881905550601160019054906101000a900460ff1661199e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161199590614359565b60405180910390fd5b3481600b546119ad91906146be565b11156119ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e5906143b9565b60405180910390fd5b828290508114611a33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2a90614399565b60405180910390fd5b600d5481611a3f610e4f565b611a499190614637565b1115611a8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a81906143f9565b60405180910390fd5b611a9583833361264b565b60005b83839050811015611afb57600160126000868685818110611abc57611abb61496c565b5b90506020020135815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611af390614865565b915050611a98565b50611b0633826128d5565b60106000815480929190611b1990614865565b91905055506001600881905550505050565b60136020528060005260406000206000915054906101000a900460ff1681565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054611b8490614802565b80601f0160208091040260200160405190810160405280929190818152602001828054611bb090614802565b8015611bfd5780601f10611bd257610100808354040283529160200191611bfd565b820191906000526020600020905b815481529060010190602001808311611be057829003601f168201915b5050505050905090565b600c5481565b611c1561253a565b73ffffffffffffffffffffffffffffffffffffffff16611c33611b4b565b73ffffffffffffffffffffffffffffffffffffffff1614611c89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8090614459565b60405180910390fd5b6001601660006101000a81548160ff021916908315150217905550565b60026008541415611cec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce3906144f9565b60405180910390fd5b6002600881905550601160009054906101000a900460ff16611d43576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3a90614439565b60405180910390fd5b600c5481601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611d919190614637565b1115611dd2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dc990614479565b60405180910390fd5b600d5481611dde610e4f565b611de89190614637565b1115611e29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e20906143f9565b60405180910390fd5b600d54601054600f5483611e3b610e4f565b611e459190614637565b611e4f9190614637565b611e599190614718565b1115611e9a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e91906144d9565b60405180910390fd5b3481600a54611ea991906146be565b1115611eea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ee1906143b9565b60405180910390fd5b611ef433826128d5565b80601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f439190614637565b92505081905550600160088190555050565b611f5d61253a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611fc2576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060076000611fcf61253a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661207c61253a565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516120c1919061431c565b60405180910390a35050565b6120d561253a565b73ffffffffffffffffffffffffffffffffffffffff166120f3611b4b565b73ffffffffffffffffffffffffffffffffffffffff1614612149576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214090614459565b60405180910390fd5b80600b8190555050565b60146020528060005260406000206000915090505481565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61219c8484846128f3565b6121bb8373ffffffffffffffffffffffffffffffffffffffff166130fe565b80156121d057506121ce84848484613111565b155b15612207576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6000612217610e4f565b905090565b606061222782613271565b6040516020016122379190614271565b6040516020818303038152906040529050919050565b601660009054906101000a900460ff1681565b601160019054906101000a900460ff1681565b600d5481565b6000600115156012600084815260200190815260200160002060009054906101000a900460ff16151514159050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b601160009054906101000a900460ff1681565b61235a61253a565b73ffffffffffffffffffffffffffffffffffffffff16612378611b4b565b73ffffffffffffffffffffffffffffffffffffffff16146123ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123c590614459565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561243e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161243590614379565b60405180910390fd5b61244781613038565b50565b61245261253a565b73ffffffffffffffffffffffffffffffffffffffff16612470611b4b565b73ffffffffffffffffffffffffffffffffffffffff16146124c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124bd90614459565b60405180910390fd5b80600a8190555050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b60008161254d612642565b1115801561255c575060005482105b8015612589575060046000838152602001908152602001600020600001601c9054906101000a900460ff16155b9050919050565b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006001905090565b6000600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231846040518263ffffffff1660e01b81526004016126ad9190614293565b60206040518083038186803b1580156126c557600080fd5b505afa1580156126d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126fd9190613ebe565b1161273d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612734906144b9565b60405180910390fd5b60005b848490508110156128ce5761276d8585838181106127615761276061496c565b5b90506020020135612279565b6127ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127a390614499565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16636352211e8787858181106127f2576127f161496c565b5b905060200201356040518263ffffffff1660e01b81526004016128159190614519565b60206040518083038186803b15801561282d57600080fd5b505afa158015612841573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128659190613bcb565b73ffffffffffffffffffffffffffffffffffffffff16146128bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b290614419565b60405180910390fd5b80806128c690614865565b915050612740565b5050505050565b6128ef828260405180602001604052806000815250613310565b5050565b60006128fe82612da9565b90508373ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614612969576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff1661298a61253a565b73ffffffffffffffffffffffffffffffffffffffff1614806129b957506129b8856129b361253a565b6122ab565b5b806129fe57506129c761253a565b73ffffffffffffffffffffffffffffffffffffffff166129e684610cc8565b73ffffffffffffffffffffffffffffffffffffffff16145b905080612a37576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415612a9e576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612aab8585856001613322565b612ab760008487612590565b6001600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160392506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600460008581526020019081526020016000209050848160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550428160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060006001850190506000600460008381526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415612d37576000548214612d3657878160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084602001518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b505050828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612da28585856001613328565b5050505050565b612db1613975565b600082905080612dbf612642565b11158015612dce575060005481105b15613001576000600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff16151515158152505090508060400151612fff57600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614612ee3578092505050613033565b5b600115612ffe57818060019003925050600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614612ff9578092505050613033565b612ee4565b5b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080823b905060008111915050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261313761253a565b8786866040518563ffffffff1660e01b815260040161315994939291906142ae565b602060405180830381600087803b15801561317357600080fd5b505af19250505080156131a457506040513d601f19601f820116820180604052508101906131a19190613e1b565b60015b61321e573d80600081146131d4576040519150601f19603f3d011682016040523d82523d6000602084013e6131d9565b606091505b50600081511415613216576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b606061327c82612542565b6132b2576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006132bc61332e565b90506000815114156132dd5760405180602001604052806000815250613308565b806132e7846133c0565b6040516020016132f892919061424d565b6040516020818303038152906040525b915050919050565b61331d8383836001613521565b505050565b50505050565b50505050565b60606015805461333d90614802565b80601f016020809104026020016040519081016040528092919081815260200182805461336990614802565b80156133b65780601f1061338b576101008083540402835291602001916133b6565b820191906000526020600020905b81548152906001019060200180831161339957829003601f168201915b5050505050905090565b60606000821415613408576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061351c565b600082905060005b6000821461343a57808061342390614865565b915050600a82613433919061468d565b9150613410565b60008167ffffffffffffffff8111156134565761345561499b565b5b6040519080825280601f01601f1916602001820160405280156134885781602001600182028036833780820191505090505b5090505b60008514613515576001826134a19190614718565b9150600a856134b091906148ae565b60306134bc9190614637565b60f81b8183815181106134d2576134d161496c565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561350e919061468d565b945061348c565b8093505050505b919050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141561358e576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008414156135c9576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6135d66000868387613322565b83600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555083600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550846004600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426004600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000819050600085820190508380156137a0575061379f8773ffffffffffffffffffffffffffffffffffffffff166130fe565b5b15613866575b818773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46138156000888480600101955088613111565b61384b576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808214156137a657826000541461386157600080fd5b6138d2565b5b818060010192508773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a480821415613867575b8160008190555050506138e86000868387613328565b5050505050565b8280546138fb90614802565b90600052602060002090601f01602090048101928261391d5760008555613964565b82601f1061393657805160ff1916838001178555613964565b82800160010185558215613964579182015b82811115613963578251825591602001919060010190613948565b5b50905061397191906139b8565b5090565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681526020016000151581525090565b5b808211156139d15760008160009055506001016139b9565b5090565b60006139e86139e384614559565b614534565b905082815260208101848484011115613a0457613a036149d9565b5b613a0f8482856147c0565b509392505050565b6000613a2a613a258461458a565b614534565b905082815260208101848484011115613a4657613a456149d9565b5b613a518482856147c0565b509392505050565b600081359050613a6881614cac565b92915050565b600081519050613a7d81614cac565b92915050565b60008083601f840112613a9957613a986149cf565b5b8235905067ffffffffffffffff811115613ab657613ab56149ca565b5b602083019150836020820283011115613ad257613ad16149d4565b5b9250929050565b600081359050613ae881614cc3565b92915050565b600081359050613afd81614cda565b92915050565b600081519050613b1281614cda565b92915050565b600082601f830112613b2d57613b2c6149cf565b5b8135613b3d8482602086016139d5565b91505092915050565b600082601f830112613b5b57613b5a6149cf565b5b8135613b6b848260208601613a17565b91505092915050565b600081359050613b8381614cf1565b92915050565b600081519050613b9881614cf1565b92915050565b600060208284031215613bb457613bb36149e3565b5b6000613bc284828501613a59565b91505092915050565b600060208284031215613be157613be06149e3565b5b6000613bef84828501613a6e565b91505092915050565b60008060408385031215613c0f57613c0e6149e3565b5b6000613c1d85828601613a59565b9250506020613c2e85828601613a59565b9150509250929050565b600080600060608486031215613c5157613c506149e3565b5b6000613c5f86828701613a59565b9350506020613c7086828701613a59565b9250506040613c8186828701613b74565b9150509250925092565b60008060008060808587031215613ca557613ca46149e3565b5b6000613cb387828801613a59565b9450506020613cc487828801613a59565b9350506040613cd587828801613b74565b925050606085013567ffffffffffffffff811115613cf657613cf56149de565b5b613d0287828801613b18565b91505092959194509250565b60008060408385031215613d2557613d246149e3565b5b6000613d3385828601613a59565b9250506020613d4485828601613ad9565b9150509250929050565b60008060408385031215613d6557613d646149e3565b5b6000613d7385828601613a59565b9250506020613d8485828601613b74565b9150509250929050565b600080600060408486031215613da757613da66149e3565b5b600084013567ffffffffffffffff811115613dc557613dc46149de565b5b613dd186828701613a83565b93509350506020613de486828701613b74565b9150509250925092565b600060208284031215613e0457613e036149e3565b5b6000613e1284828501613aee565b91505092915050565b600060208284031215613e3157613e306149e3565b5b6000613e3f84828501613b03565b91505092915050565b600060208284031215613e5e57613e5d6149e3565b5b600082013567ffffffffffffffff811115613e7c57613e7b6149de565b5b613e8884828501613b46565b91505092915050565b600060208284031215613ea757613ea66149e3565b5b6000613eb584828501613b74565b91505092915050565b600060208284031215613ed457613ed36149e3565b5b6000613ee284828501613b89565b91505092915050565b6000613ef7838361422f565b60208301905092915050565b613f0c8161474c565b82525050565b6000613f1d826145cb565b613f2781856145f9565b9350613f32836145bb565b8060005b83811015613f63578151613f4a8882613eeb565b9750613f55836145ec565b925050600181019050613f36565b5085935050505092915050565b613f798161475e565b82525050565b6000613f8a826145d6565b613f94818561460a565b9350613fa48185602086016147cf565b613fad816149e8565b840191505092915050565b6000613fc3826145e1565b613fcd818561461b565b9350613fdd8185602086016147cf565b613fe6816149e8565b840191505092915050565b6000613ffc826145e1565b614006818561462c565b93506140168185602086016147cf565b80840191505092915050565b600061402f60148361461b565b915061403a826149f9565b602082019050919050565b600061405260268361461b565b915061405d82614a22565b604082019050919050565b600061407560168361461b565b915061408082614a71565b602082019050919050565b600061409860158361461b565b91506140a382614a9a565b602082019050919050565b60006140bb600f8361461b565b91506140c682614ac3565b602082019050919050565b60006140de60088361461b565b91506140e982614aec565b602082019050919050565b6000614101600c8361461b565b915061410c82614b15565b602082019050919050565b600061412460058361462c565b915061412f82614b3e565b600582019050919050565b6000614147600d8361461b565b915061415282614b67565b602082019050919050565b600061416a60208361461b565b915061417582614b90565b602082019050919050565b600061418d60248361461b565b915061419882614bb9565b604082019050919050565b60006141b060128361461b565b91506141bb82614c08565b602082019050919050565b60006141d3600c8361461b565b91506141de82614c31565b602082019050919050565b60006141f6600f8361461b565b915061420182614c5a565b602082019050919050565b6000614219601f8361461b565b915061422482614c83565b602082019050919050565b614238816147b6565b82525050565b614247816147b6565b82525050565b60006142598285613ff1565b91506142658284613ff1565b91508190509392505050565b600061427d8284613ff1565b915061428882614117565b915081905092915050565b60006020820190506142a86000830184613f03565b92915050565b60006080820190506142c36000830187613f03565b6142d06020830186613f03565b6142dd604083018561423e565b81810360608301526142ef8184613f7f565b905095945050505050565b600060208201905081810360008301526143148184613f12565b905092915050565b60006020820190506143316000830184613f70565b92915050565b600060208201905081810360008301526143518184613fb8565b905092915050565b6000602082019050818103600083015261437281614022565b9050919050565b6000602082019050818103600083015261439281614045565b9050919050565b600060208201905081810360008301526143b281614068565b9050919050565b600060208201905081810360008301526143d28161408b565b9050919050565b600060208201905081810360008301526143f2816140ae565b9050919050565b60006020820190508181036000830152614412816140d1565b9050919050565b60006020820190508181036000830152614432816140f4565b9050919050565b600060208201905081810360008301526144528161413a565b9050919050565b600060208201905081810360008301526144728161415d565b9050919050565b6000602082019050818103600083015261449281614180565b9050919050565b600060208201905081810360008301526144b2816141a3565b9050919050565b600060208201905081810360008301526144d2816141c6565b9050919050565b600060208201905081810360008301526144f2816141e9565b9050919050565b600060208201905081810360008301526145128161420c565b9050919050565b600060208201905061452e600083018461423e565b92915050565b600061453e61454f565b905061454a8282614834565b919050565b6000604051905090565b600067ffffffffffffffff8211156145745761457361499b565b5b61457d826149e8565b9050602081019050919050565b600067ffffffffffffffff8211156145a5576145a461499b565b5b6145ae826149e8565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000614642826147b6565b915061464d836147b6565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614682576146816148df565b5b828201905092915050565b6000614698826147b6565b91506146a3836147b6565b9250826146b3576146b261490e565b5b828204905092915050565b60006146c9826147b6565b91506146d4836147b6565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561470d5761470c6148df565b5b828202905092915050565b6000614723826147b6565b915061472e836147b6565b925082821015614741576147406148df565b5b828203905092915050565b600061475782614796565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156147ed5780820151818401526020810190506147d2565b838111156147fc576000848401525b50505050565b6000600282049050600182168061481a57607f821691505b6020821081141561482e5761482d61493d565b5b50919050565b61483d826149e8565b810181811067ffffffffffffffff8211171561485c5761485b61499b565b5b80604052505050565b6000614870826147b6565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156148a3576148a26148df565b5b600182019050919050565b60006148b9826147b6565b91506148c4836147b6565b9250826148d4576148d361490e565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f484f4c4445525f53414c455f494e414354495645000000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f494e53554646494349454e545f414c5f544f4b454e5300000000000000000000600082015250565b7f494e434f52524543545f45544845525f56414c55450000000000000000000000600082015250565b7f4d455441444154415f4c4f434b45440000000000000000000000000000000000600082015250565b7f534f4c445f4f5554000000000000000000000000000000000000000000000000600082015250565b7f4e4f545f414c5f4f574e45520000000000000000000000000000000000000000600082015250565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b7f53414c455f494e41435449564500000000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f7468697320776f756c6420657863656564206d696e74206d617820616c6c6f7760008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b7f414c5f414c52454144595f434c41494d45440000000000000000000000000000600082015250565b7f4e4f5f414c5f544f4b454e530000000000000000000000000000000000000000600082015250565b7f5055424c49435f534f4c445f4f55540000000000000000000000000000000000600082015250565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b614cb58161474c565b8114614cc057600080fd5b50565b614ccc8161475e565b8114614cd757600080fd5b50565b614ce38161476a565b8114614cee57600080fd5b50565b614cfa816147b6565b8114614d0557600080fd5b5056fea264697066735822122017fd7e2b4533fbcb642277a3150446de225a767699a98c38ee66ff78549fa2ed64736f6c63430008070033

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

93699:6653:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75904:305;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98150:138;;;;;;;;;;;;;:::i;:::-;;79017:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80520:204;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80083:371;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75153:303;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96462:770;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81385:170;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93832:47;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98853:106;;;;;;;;;;;;;:::i;:::-;;94194:48;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98650:112;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81626:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;95459:212;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;97972:168;;;;;;;;;;;;;:::i;:::-;;93999:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99794:150;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;98969:712;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;78825:125;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94043:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93788:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76273:206;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98534:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;66027:103;;;;;;;;;;;;;:::i;:::-;;95679:771;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94249:47;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65376:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;79186:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93886:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98770:75;;;;;;;;;;;;;:::i;:::-;;97242:720;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80796:287;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;98406:120;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94303:51;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93961:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81882:369;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;99689:97;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100074:163;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94488:18;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94149:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93923:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94802:134;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81154:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94110:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66285:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;98296:102;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75904:305;76006:4;76058:25;76043:40;;;:11;:40;;;;:105;;;;76115:33;76100:48;;;:11;:48;;;;76043:105;:158;;;;76165:36;76189:11;76165:23;:36::i;:::-;76043:158;76023:178;;75904:305;;;:::o;98150:138::-;65607:12;:10;:12::i;:::-;65596:23;;:7;:5;:7::i;:::-;:23;;;65588:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;98224:12:::1;;;;;;;;;;;98223:13;98208:12;;:28;;;;;;;;;;;;;;;;;;98252;98267:12;;;;;;;;;;;98252:28;;;;;;:::i;:::-;;;;;;;;98150:138::o:0;79017:100::-;79071:13;79104:5;79097:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79017:100;:::o;80520:204::-;80588:7;80613:16;80621:7;80613;:16::i;:::-;80608:64;;80638:34;;;;;;;;;;;;;;80608:64;80692:15;:24;80708:7;80692:24;;;;;;;;;;;;;;;;;;;;;80685:31;;80520:204;;;:::o;80083:371::-;80156:13;80172:24;80188:7;80172:15;:24::i;:::-;80156:40;;80217:5;80211:11;;:2;:11;;;80207:48;;;80231:24;;;;;;;;;;;;;;80207:48;80288:5;80272:21;;:12;:10;:12::i;:::-;:21;;;;:63;;;;;80298:37;80315:5;80322:12;:10;:12::i;:::-;80298:16;:37::i;:::-;80297:38;80272:63;80268:138;;;80359:35;;;;;;;;;;;;;;80268:138;80418:28;80427:2;80431:7;80440:5;80418:8;:28::i;:::-;80145:309;80083:371;;:::o;75153:303::-;75197:7;75422:15;:13;:15::i;:::-;75407:12;;75391:13;;:28;:46;75384:53;;75153:303;:::o;96462:770::-;70761:1;71359:7;;:19;;71351:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;70761:1;71492:7;:18;;;;96577::::1;;;;;;;;;;;96569:51;;;;;;;;;;;;:::i;:::-;;;;;;;;;96663:13;;:20;;96653:6;:30;96631:102;;;;;;;;;;;;:::i;:::-;;;;;;;;;96792:9;;96782:6;96766:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;96744:93;;;;;;;;;;;;:::i;:::-;;;;;;;;;96848:47;96869:13;;96884:10;96848:20;:47::i;:::-;96911:9;96906:119;96930:13;;:20;;96926:1;:24;96906:119;;;97009:4;96972:16;:34;96989:13;;97003:1;96989:16;;;;;;;:::i;:::-;;;;;;;;96972:34;;;;;;;;;;;;:41;;;;;;;;;;;;;;;;;;96952:3;;;;;:::i;:::-;;;;96906:119;;;;97040:9;97035:118;97059:13;;:20;;97055:1;:24;97035:118;;;97137:4;97101:15;:33;97117:13;;97131:1;97117:16;;;;;;;:::i;:::-;;;;;;;;97101:33;;;;;;;;;;;;:40;;;;;;;;;;;;;;;;;;97081:3;;;;;:::i;:::-;;;;97035:118;;;;97163:29;97173:10;97185:6;97163:9;:29::i;:::-;97203:19;;:21;;;;;;;;;:::i;:::-;;;;;;70717:1:::0;71671:7;:22;;;;96462:770;;;:::o;81385:170::-;81519:28;81529:4;81535:2;81539:7;81519:9;:28::i;:::-;81385:170;;;:::o;93832:47::-;;;;:::o;98853:106::-;65607:12;:10;:12::i;:::-;65596:23;;:7;:5;:7::i;:::-;:23;;;65588:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;98911:7:::1;:5;:7::i;:::-;98903:25;;:48;98929:21;98903:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;98853:106::o:0;94194:48::-;;;;;;;;;;;;;;;;;;;;;;:::o;98650:112::-;65607:12;:10;:12::i;:::-;65596:23;;:7;:5;:7::i;:::-;:23;;;65588:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;98740:14:::1;98724:13;:30;;;;98650:112:::0;:::o;81626:185::-;81764:39;81781:4;81787:2;81791:7;81764:39;;;;;;;;;;;;:16;:39::i;:::-;81626:185;;;:::o;95459:212::-;65607:12;:10;:12::i;:::-;65596:23;;:7;:5;:7::i;:::-;:23;;;65588:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;95585:9:::1;;95575:6;95559:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;95537:93;;;;;;;;;;;;:::i;:::-;;;;;;;;;95641:22;95651:3;95656:6;95641:9;:22::i;:::-;95459:212:::0;;:::o;97972:168::-;65607:12;:10;:12::i;:::-;65596:23;;:7;:5;:7::i;:::-;:23;;;65588:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;98058:18:::1;;;;;;;;;;;98057:19;98036:18;;:40;;;;;;;;;;;;;;;;;;98092;98113:18;;;;;;;;;;;98092:40;;;;;;:::i;:::-;;;;;;;;97972:168::o:0;93999:35::-;;;;:::o;99794:150::-;65607:12;:10;:12::i;:::-;65596:23;;:7;:5;:7::i;:::-;:23;;;65588:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;99876:6:::1;;;;;;;;;;;99875:7;99867:35;;;;;;;;;;;;:::i;:::-;;;;;;;;;99929:7;99913:13;:23;;;;;;;;;;;;:::i;:::-;;99794:150:::0;:::o;98969:712::-;99033:16;99079:18;99114:16;99124:5;99114:9;:16::i;:::-;99100:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99079:52;;99142:11;99156:13;;99142:27;;99180:19;99210:25;99251:9;99246:402;99266:3;99262:1;:7;99246:402;;;99291:31;99325:11;:14;99337:1;99325:14;;;;;;;;;;;99291:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99358:9;:16;;;99354:65;;;99395:8;;;99354:65;99463:1;99437:28;;:9;:14;;;:28;;;99433:103;;99506:9;:14;;;99486:34;;99433:103;99575:5;99554:26;;:17;:26;;;99550:87;;;99620:1;99601;99603:13;;;;;;99601:16;;;;;;;;:::i;:::-;;;;;;;:20;;;;;99550:87;99276:372;99246:402;99271:3;;;;;;;99246:402;;;;99665:1;99658:8;;;;;;98969:712;;;:::o;78825:125::-;78889:7;78916:21;78929:7;78916:12;:21::i;:::-;:26;;;78909:33;;78825:125;;;:::o;94043:38::-;;;;:::o;93788:37::-;;;;:::o;76273:206::-;76337:7;76378:1;76361:19;;:5;:19;;;76357:60;;;76389:28;;;;;;;;;;;;;;76357:60;76443:12;:19;76456:5;76443:19;;;;;;;;;;;;;;;:27;;;;;;;;;;;;76435:36;;76428:43;;76273:206;;;:::o;98534:110::-;65607:12;:10;:12::i;:::-;65596:23;;:7;:5;:7::i;:::-;:23;;;65588:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;98624:12:::1;98610:11;:26;;;;98534:110:::0;:::o;66027:103::-;65607:12;:10;:12::i;:::-;65596:23;;:7;:5;:7::i;:::-;:23;;;65588:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;66092:30:::1;66119:1;66092:18;:30::i;:::-;66027:103::o:0;95679:771::-;70761:1;71359:7;;:19;;71351:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;70761:1;71492:7;:18;;;;95798::::1;;;;;;;;;;;95790:51;;;;;;;;;;;;:::i;:::-;;;;;;;;;95908:9;95898:6;95876:18;;:28;;;;:::i;:::-;:41;;95854:112;;;;;;;;;;;;:::i;:::-;;;;;;;;;96009:13;;:20;;95999:6;:30;95977:102;;;;;;;;;;;;:::i;:::-;;;;;;;;;96138:9;;96128:6;96112:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;96090:93;;;;;;;;;;;;:::i;:::-;;;;;;;;;96194:47;96215:13;;96230:10;96194:20;:47::i;:::-;96257:9;96252:119;96276:13;;:20;;96272:1;:24;96252:119;;;96355:4;96318:16;:34;96335:13;;96349:1;96335:16;;;;;;;:::i;:::-;;;;;;;;96318:34;;;;;;;;;;;;:41;;;;;;;;;;;;;;;;;;96298:3;;;;;:::i;:::-;;;;96252:119;;;;96381:29;96391:10;96403:6;96381:9;:29::i;:::-;96421:19;;:21;;;;;;;;;:::i;:::-;;;;;;70717:1:::0;71671:7;:22;;;;95679:771;;;:::o;94249:47::-;;;;;;;;;;;;;;;;;;;;;;:::o;65376:87::-;65422:7;65449:6;;;;;;;;;;;65442:13;;65376:87;:::o;79186:104::-;79242:13;79275:7;79268:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79186:104;:::o;93886:30::-;;;;:::o;98770:75::-;65607:12;:10;:12::i;:::-;65596:23;;:7;:5;:7::i;:::-;:23;;;65588:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;98833:4:::1;98824:6;;:13;;;;;;;;;;;;;;;;;;98770:75::o:0;97242:720::-;70761:1;71359:7;;:19;;71351:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;70761:1;71492:7;:18;;;;97321:12:::1;;;;;;;;;;;97313:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;97419:11;;97406:6;97372:19;:31;97392:10;97372:31;;;;;;;;;;;;;;;;:40;;;;:::i;:::-;97370:60;;97362:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;97533:9;;97523:6;97507:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;97485:93;;;;;;;;;;;;:::i;:::-;;;;;;;;;97675:9;;97652:19;;97636:13;;97627:6;97611:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:38;;;;:::i;:::-;:60;;;;:::i;:::-;:73;;97589:138;;;;;;;;;;;;:::i;:::-;;;;;;;;;97782:9;97772:6;97760:9;;:18;;;;:::i;:::-;:31;;97738:102;;;;;;;;;;;;:::i;:::-;;;;;;;;;97861:29;97871:10;97883:6;97861:9;:29::i;:::-;97944:6;97909:19;:31;97929:10;97909:31;;;;;;;;;;;;;;;;:41;;;;;;;:::i;:::-;;;;;;;;70717:1:::0;71671:7;:22;;;;97242:720;:::o;80796:287::-;80907:12;:10;:12::i;:::-;80895:24;;:8;:24;;;80891:54;;;80928:17;;;;;;;;;;;;;;80891:54;81003:8;80958:18;:32;80977:12;:10;:12::i;:::-;80958:32;;;;;;;;;;;;;;;:42;80991:8;80958:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;81056:8;81027:48;;81042:12;:10;:12::i;:::-;81027:48;;;81066:8;81027:48;;;;;;:::i;:::-;;;;;;;;80796:287;;:::o;98406:120::-;65607:12;:10;:12::i;:::-;65596:23;;:7;:5;:7::i;:::-;:23;;;65588:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;98508:10:::1;98487:18;:31;;;;98406:120:::0;:::o;94303:51::-;;;;;;;;;;;;;;;;;:::o;93961:31::-;;;;;;;;;;;;;:::o;81882:369::-;82049:28;82059:4;82065:2;82069:7;82049:9;:28::i;:::-;82092:15;:2;:13;;;:15::i;:::-;:76;;;;;82112:56;82143:4;82149:2;82153:7;82162:5;82112:30;:56::i;:::-;82111:57;82092:76;82088:156;;;82192:40;;;;;;;;;;;;;;82088:156;81882:369;;;;:::o;99689:97::-;99738:7;99765:13;:11;:13::i;:::-;99758:20;;99689:97;:::o;100074:163::-;100139:13;100195:23;100210:7;100195:14;:23::i;:::-;100178:50;;;;;;;;:::i;:::-;;;;;;;;;;;;;100164:65;;100074:163;;;:::o;94488:18::-;;;;;;;;;;;;;:::o;94149:38::-;;;;;;;;;;;;;:::o;93923:31::-;;;;:::o;94802:134::-;94870:4;94924;94894:34;;:16;:26;94911:8;94894:26;;;;;;;;;;;;;;;;;;;;;:34;;;;94887:41;;94802:134;;;:::o;81154:164::-;81251:4;81275:18;:25;81294:5;81275:25;;;;;;;;;;;;;;;:35;81301:8;81275:35;;;;;;;;;;;;;;;;;;;;;;;;;81268:42;;81154:164;;;;:::o;94110:32::-;;;;;;;;;;;;;:::o;66285:201::-;65607:12;:10;:12::i;:::-;65596:23;;:7;:5;:7::i;:::-;:23;;;65588:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;66394:1:::1;66374:22;;:8;:22;;;;66366:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;66450:28;66469:8;66450:18;:28::i;:::-;66285:201:::0;:::o;98296:102::-;65607:12;:10;:12::i;:::-;65596:23;;:7;:5;:7::i;:::-;:23;;;65588:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;98380:10:::1;98368:9;:22;;;;98296:102:::0;:::o;36132:157::-;36217:4;36256:25;36241:40;;;:11;:40;;;;36234:47;;36132:157;;;:::o;33175:98::-;33228:7;33255:10;33248:17;;33175:98;:::o;82506:187::-;82563:4;82606:7;82587:15;:13;:15::i;:::-;:26;;:53;;;;;82627:13;;82617:7;:23;82587:53;:98;;;;;82658:11;:20;82670:7;82658:20;;;;;;;;;;;:27;;;;;;;;;;;;82657:28;82587:98;82580:105;;82506:187;;;:::o;90676:196::-;90818:2;90791:15;:24;90807:7;90791:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;90856:7;90852:2;90836:28;;90845:5;90836:28;;;;;;;;;;;;90676:196;;;:::o;100245:100::-;100310:7;100336:1;100329:8;;100245:100;:::o;94944:491::-;95051:26;95097:16;;;;;;;;;;;95051:63;;95165:1;95133:9;:19;;;95153:8;95133:29;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:33;95125:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;95199:9;95194:234;95218:13;;:20;;95214:1;:24;95194:234;;;95268:38;95289:13;;95303:1;95289:16;;;;;;;:::i;:::-;;;;;;;;95268:20;:38::i;:::-;95260:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;95391:8;95352:47;;:9;:17;;;95370:13;;95384:1;95370:16;;;;;;;:::i;:::-;;;;;;;;95352:35;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:47;;;95344:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;95240:3;;;;;:::i;:::-;;;;95194:234;;;;95040:395;94944:491;;;:::o;82701:104::-;82770:27;82780:2;82784:8;82770:27;;;;;;;;;;;;:9;:27::i;:::-;82701:104;;:::o;85619:2130::-;85734:35;85772:21;85785:7;85772:12;:21::i;:::-;85734:59;;85832:4;85810:26;;:13;:18;;;:26;;;85806:67;;85845:28;;;;;;;;;;;;;;85806:67;85886:22;85928:4;85912:20;;:12;:10;:12::i;:::-;:20;;;:73;;;;85949:36;85966:4;85972:12;:10;:12::i;:::-;85949:16;:36::i;:::-;85912:73;:126;;;;86026:12;:10;:12::i;:::-;86002:36;;:20;86014:7;86002:11;:20::i;:::-;:36;;;85912:126;85886:153;;86057:17;86052:66;;86083:35;;;;;;;;;;;;;;86052:66;86147:1;86133:16;;:2;:16;;;86129:52;;;86158:23;;;;;;;;;;;;;;86129:52;86194:43;86216:4;86222:2;86226:7;86235:1;86194:21;:43::i;:::-;86302:35;86319:1;86323:7;86332:4;86302:8;:35::i;:::-;86663:1;86633:12;:18;86646:4;86633:18;;;;;;;;;;;;;;;:26;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86707:1;86679:12;:16;86692:2;86679:16;;;;;;;;;;;;;;;:24;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86725:31;86759:11;:20;86771:7;86759:20;;;;;;;;;;;86725:54;;86810:2;86794:8;:13;;;:18;;;;;;;;;;;;;;;;;;86860:15;86827:8;:23;;;:49;;;;;;;;;;;;;;;;;;87128:19;87160:1;87150:7;:11;87128:33;;87176:31;87210:11;:24;87222:11;87210:24;;;;;;;;;;;87176:58;;87278:1;87253:27;;:8;:13;;;;;;;;;;;;:27;;;87249:384;;;87463:13;;87448:11;:28;87444:174;;87517:4;87501:8;:13;;;:20;;;;;;;;;;;;;;;;;;87570:13;:28;;;87544:8;:23;;;:54;;;;;;;;;;;;;;;;;;87444:174;87249:384;86608:1036;;;87680:7;87676:2;87661:27;;87670:4;87661:27;;;;;;;;;;;;87699:42;87720:4;87726:2;87730:7;87739:1;87699:20;:42::i;:::-;85723:2026;;85619:2130;;;:::o;77654:1109::-;77716:21;;:::i;:::-;77750:12;77765:7;77750:22;;77833:4;77814:15;:13;:15::i;:::-;:23;;:47;;;;;77848:13;;77841:4;:20;77814:47;77810:886;;;77882:31;77916:11;:17;77928:4;77916:17;;;;;;;;;;;77882:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77957:9;:16;;;77952:729;;78028:1;78002:28;;:9;:14;;;:28;;;77998:101;;78066:9;78059:16;;;;;;77998:101;78401:261;78408:4;78401:261;;;78441:6;;;;;;;;78486:11;:17;78498:4;78486:17;;;;;;;;;;;78474:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78560:1;78534:28;;:9;:14;;;:28;;;78530:109;;78602:9;78595:16;;;;;;78530:109;78401:261;;;77952:729;77863:833;77810:886;78724:31;;;;;;;;;;;;;;77654:1109;;;;:::o;66646:191::-;66720:16;66739:6;;;;;;;;;;;66720:25;;66765:8;66756:6;;:17;;;;;;;;;;;;;;;;;;66820:8;66789:40;;66810:8;66789:40;;;;;;;;;;;;66709:128;66646:191;:::o;25275:387::-;25335:4;25543:12;25610:7;25598:20;25590:28;;25653:1;25646:4;:8;25639:15;;;25275:387;;;:::o;91364:667::-;91527:4;91564:2;91548:36;;;91585:12;:10;:12::i;:::-;91599:4;91605:7;91614:5;91548:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;91544:480;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91799:1;91782:6;:13;:18;91778:235;;;91828:40;;;;;;;;;;;;;;91778:235;91971:6;91965:13;91956:6;91952:2;91948:15;91941:38;91544:480;91677:45;;;91667:55;;;:6;:55;;;;91660:62;;;91364:667;;;;;;:::o;79361:318::-;79434:13;79465:16;79473:7;79465;:16::i;:::-;79460:59;;79490:29;;;;;;;;;;;;;;79460:59;79532:21;79556:10;:8;:10::i;:::-;79532:34;;79609:1;79590:7;79584:21;:26;;:87;;;;;;;;;;;;;;;;;79637:7;79646:18;:7;:16;:18::i;:::-;79620:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;79584:87;79577:94;;;79361:318;;;:::o;83168:163::-;83291:32;83297:2;83301:8;83311:5;83318:4;83291:5;:32::i;:::-;83168:163;;;:::o;92679:159::-;;;;;:::o;93497:158::-;;;;;:::o;99952:114::-;100012:13;100045;100038:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99952:114;:::o;33644:723::-;33700:13;33930:1;33921:5;:10;33917:53;;;33948:10;;;;;;;;;;;;;;;;;;;;;33917:53;33980:12;33995:5;33980:20;;34011:14;34036:78;34051:1;34043:4;:9;34036:78;;34069:8;;;;;:::i;:::-;;;;34100:2;34092:10;;;;;:::i;:::-;;;34036:78;;;34124:19;34156:6;34146:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34124:39;;34174:154;34190:1;34181:5;:10;34174:154;;34218:1;34208:11;;;;;:::i;:::-;;;34285:2;34277:5;:10;;;;:::i;:::-;34264:2;:24;;;;:::i;:::-;34251:39;;34234:6;34241;34234:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;34314:2;34305:11;;;;;:::i;:::-;;;34174:154;;;34352:6;34338:21;;;;;33644:723;;;;:::o;83590:1775::-;83729:20;83752:13;;83729:36;;83794:1;83780:16;;:2;:16;;;83776:48;;;83805:19;;;;;;;;;;;;;;83776:48;83851:1;83839:8;:13;83835:44;;;83861:18;;;;;;;;;;;;;;83835:44;83892:61;83922:1;83926:2;83930:12;83944:8;83892:21;:61::i;:::-;84265:8;84230:12;:16;84243:2;84230:16;;;;;;;;;;;;;;;:24;;;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84329:8;84289:12;:16;84302:2;84289:16;;;;;;;;;;;;;;;:29;;;:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84388:2;84355:11;:25;84367:12;84355:25;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;84455:15;84405:11;:25;84417:12;84405:25;;;;;;;;;;;:40;;;:66;;;;;;;;;;;;;;;;;;84488:20;84511:12;84488:35;;84538:11;84567:8;84552:12;:23;84538:37;;84596:4;:23;;;;;84604:15;:2;:13;;;:15::i;:::-;84596:23;84592:641;;;84640:314;84696:12;84692:2;84671:38;;84688:1;84671:38;;;;;;;;;;;;84737:69;84776:1;84780:2;84784:14;;;;;;84800:5;84737:30;:69::i;:::-;84732:174;;84842:40;;;;;;;;;;;;;;84732:174;84949:3;84933:12;:19;;84640:314;;85035:12;85018:13;;:29;85014:43;;85049:8;;;85014:43;84592:641;;;85098:120;85154:14;;;;;;85150:2;85129:40;;85146:1;85129:40;;;;;;;;;;;;85213:3;85197:12;:19;;85098:120;;84592:641;85263:12;85247:13;:28;;;;84205:1082;;85297:60;85326:1;85330:2;85334:12;85348:8;85297:20;:60::i;:::-;83718:1647;83590:1775;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:410:1:-;84:5;109:65;125:48;166:6;125:48;:::i;:::-;109:65;:::i;:::-;100:74;;197:6;190:5;183:21;235:4;228:5;224:16;273:3;264:6;259:3;255:16;252:25;249:112;;;280:79;;:::i;:::-;249:112;370:41;404:6;399:3;394;370:41;:::i;:::-;90:327;7:410;;;;;:::o;423:412::-;501:5;526:66;542:49;584:6;542:49;:::i;:::-;526:66;:::i;:::-;517:75;;615:6;608:5;601:21;653:4;646:5;642:16;691:3;682:6;677:3;673:16;670:25;667:112;;;698:79;;:::i;:::-;667:112;788:41;822:6;817:3;812;788:41;:::i;:::-;507:328;423:412;;;;;:::o;841:139::-;887:5;925:6;912:20;903:29;;941:33;968:5;941:33;:::i;:::-;841:139;;;;:::o;986:143::-;1043:5;1074:6;1068:13;1059:22;;1090:33;1117:5;1090:33;:::i;:::-;986:143;;;;:::o;1152:568::-;1225:8;1235:6;1285:3;1278:4;1270:6;1266:17;1262:27;1252:122;;1293:79;;:::i;:::-;1252:122;1406:6;1393:20;1383:30;;1436:18;1428:6;1425:30;1422:117;;;1458:79;;:::i;:::-;1422:117;1572:4;1564:6;1560:17;1548:29;;1626:3;1618:4;1610:6;1606:17;1596:8;1592:32;1589:41;1586:128;;;1633:79;;:::i;:::-;1586:128;1152:568;;;;;:::o;1726:133::-;1769:5;1807:6;1794:20;1785:29;;1823:30;1847:5;1823:30;:::i;:::-;1726:133;;;;:::o;1865:137::-;1910:5;1948:6;1935:20;1926:29;;1964:32;1990:5;1964:32;:::i;:::-;1865:137;;;;:::o;2008:141::-;2064:5;2095:6;2089:13;2080:22;;2111:32;2137:5;2111:32;:::i;:::-;2008:141;;;;:::o;2168:338::-;2223:5;2272:3;2265:4;2257:6;2253:17;2249:27;2239:122;;2280:79;;:::i;:::-;2239:122;2397:6;2384:20;2422:78;2496:3;2488:6;2481:4;2473:6;2469:17;2422:78;:::i;:::-;2413:87;;2229:277;2168:338;;;;:::o;2526:340::-;2582:5;2631:3;2624:4;2616:6;2612:17;2608:27;2598:122;;2639:79;;:::i;:::-;2598:122;2756:6;2743:20;2781:79;2856:3;2848:6;2841:4;2833:6;2829:17;2781:79;:::i;:::-;2772:88;;2588:278;2526:340;;;;:::o;2872:139::-;2918:5;2956:6;2943:20;2934:29;;2972:33;2999:5;2972:33;:::i;:::-;2872:139;;;;:::o;3017:143::-;3074:5;3105:6;3099:13;3090:22;;3121:33;3148:5;3121:33;:::i;:::-;3017:143;;;;:::o;3166:329::-;3225:6;3274:2;3262:9;3253:7;3249:23;3245:32;3242:119;;;3280:79;;:::i;:::-;3242:119;3400:1;3425:53;3470:7;3461:6;3450:9;3446:22;3425:53;:::i;:::-;3415:63;;3371:117;3166:329;;;;:::o;3501:351::-;3571:6;3620:2;3608:9;3599:7;3595:23;3591:32;3588:119;;;3626:79;;:::i;:::-;3588:119;3746:1;3771:64;3827:7;3818:6;3807:9;3803:22;3771:64;:::i;:::-;3761:74;;3717:128;3501:351;;;;:::o;3858:474::-;3926:6;3934;3983:2;3971:9;3962:7;3958:23;3954:32;3951:119;;;3989:79;;:::i;:::-;3951:119;4109:1;4134:53;4179:7;4170:6;4159:9;4155:22;4134:53;:::i;:::-;4124:63;;4080:117;4236:2;4262:53;4307:7;4298:6;4287:9;4283:22;4262:53;:::i;:::-;4252:63;;4207:118;3858:474;;;;;:::o;4338:619::-;4415:6;4423;4431;4480:2;4468:9;4459:7;4455:23;4451:32;4448:119;;;4486:79;;:::i;:::-;4448:119;4606:1;4631:53;4676:7;4667:6;4656:9;4652:22;4631:53;:::i;:::-;4621:63;;4577:117;4733:2;4759:53;4804:7;4795:6;4784:9;4780:22;4759:53;:::i;:::-;4749:63;;4704:118;4861:2;4887:53;4932:7;4923:6;4912:9;4908:22;4887:53;:::i;:::-;4877:63;;4832:118;4338:619;;;;;:::o;4963:943::-;5058:6;5066;5074;5082;5131:3;5119:9;5110:7;5106:23;5102:33;5099:120;;;5138:79;;:::i;:::-;5099:120;5258:1;5283:53;5328:7;5319:6;5308:9;5304:22;5283:53;:::i;:::-;5273:63;;5229:117;5385:2;5411:53;5456:7;5447:6;5436:9;5432:22;5411:53;:::i;:::-;5401:63;;5356:118;5513:2;5539:53;5584:7;5575:6;5564:9;5560:22;5539:53;:::i;:::-;5529:63;;5484:118;5669:2;5658:9;5654:18;5641:32;5700:18;5692:6;5689:30;5686:117;;;5722:79;;:::i;:::-;5686:117;5827:62;5881:7;5872:6;5861:9;5857:22;5827:62;:::i;:::-;5817:72;;5612:287;4963:943;;;;;;;:::o;5912:468::-;5977:6;5985;6034:2;6022:9;6013:7;6009:23;6005:32;6002:119;;;6040:79;;:::i;:::-;6002:119;6160:1;6185:53;6230:7;6221:6;6210:9;6206:22;6185:53;:::i;:::-;6175:63;;6131:117;6287:2;6313:50;6355:7;6346:6;6335:9;6331:22;6313:50;:::i;:::-;6303:60;;6258:115;5912:468;;;;;:::o;6386:474::-;6454:6;6462;6511:2;6499:9;6490:7;6486:23;6482:32;6479:119;;;6517:79;;:::i;:::-;6479:119;6637:1;6662:53;6707:7;6698:6;6687:9;6683:22;6662:53;:::i;:::-;6652:63;;6608:117;6764:2;6790:53;6835:7;6826:6;6815:9;6811:22;6790:53;:::i;:::-;6780:63;;6735:118;6386:474;;;;;:::o;6866:704::-;6961:6;6969;6977;7026:2;7014:9;7005:7;7001:23;6997:32;6994:119;;;7032:79;;:::i;:::-;6994:119;7180:1;7169:9;7165:17;7152:31;7210:18;7202:6;7199:30;7196:117;;;7232:79;;:::i;:::-;7196:117;7345:80;7417:7;7408:6;7397:9;7393:22;7345:80;:::i;:::-;7327:98;;;;7123:312;7474:2;7500:53;7545:7;7536:6;7525:9;7521:22;7500:53;:::i;:::-;7490:63;;7445:118;6866:704;;;;;:::o;7576:327::-;7634:6;7683:2;7671:9;7662:7;7658:23;7654:32;7651:119;;;7689:79;;:::i;:::-;7651:119;7809:1;7834:52;7878:7;7869:6;7858:9;7854:22;7834:52;:::i;:::-;7824:62;;7780:116;7576:327;;;;:::o;7909:349::-;7978:6;8027:2;8015:9;8006:7;8002:23;7998:32;7995:119;;;8033:79;;:::i;:::-;7995:119;8153:1;8178:63;8233:7;8224:6;8213:9;8209:22;8178:63;:::i;:::-;8168:73;;8124:127;7909:349;;;;:::o;8264:509::-;8333:6;8382:2;8370:9;8361:7;8357:23;8353:32;8350:119;;;8388:79;;:::i;:::-;8350:119;8536:1;8525:9;8521:17;8508:31;8566:18;8558:6;8555:30;8552:117;;;8588:79;;:::i;:::-;8552:117;8693:63;8748:7;8739:6;8728:9;8724:22;8693:63;:::i;:::-;8683:73;;8479:287;8264:509;;;;:::o;8779:329::-;8838:6;8887:2;8875:9;8866:7;8862:23;8858:32;8855:119;;;8893:79;;:::i;:::-;8855:119;9013:1;9038:53;9083:7;9074:6;9063:9;9059:22;9038:53;:::i;:::-;9028:63;;8984:117;8779:329;;;;:::o;9114:351::-;9184:6;9233:2;9221:9;9212:7;9208:23;9204:32;9201:119;;;9239:79;;:::i;:::-;9201:119;9359:1;9384:64;9440:7;9431:6;9420:9;9416:22;9384:64;:::i;:::-;9374:74;;9330:128;9114:351;;;;:::o;9471:179::-;9540:10;9561:46;9603:3;9595:6;9561:46;:::i;:::-;9639:4;9634:3;9630:14;9616:28;;9471:179;;;;:::o;9656:118::-;9743:24;9761:5;9743:24;:::i;:::-;9738:3;9731:37;9656:118;;:::o;9810:732::-;9929:3;9958:54;10006:5;9958:54;:::i;:::-;10028:86;10107:6;10102:3;10028:86;:::i;:::-;10021:93;;10138:56;10188:5;10138:56;:::i;:::-;10217:7;10248:1;10233:284;10258:6;10255:1;10252:13;10233:284;;;10334:6;10328:13;10361:63;10420:3;10405:13;10361:63;:::i;:::-;10354:70;;10447:60;10500:6;10447:60;:::i;:::-;10437:70;;10293:224;10280:1;10277;10273:9;10268:14;;10233:284;;;10237:14;10533:3;10526:10;;9934:608;;;9810:732;;;;:::o;10548:109::-;10629:21;10644:5;10629:21;:::i;:::-;10624:3;10617:34;10548:109;;:::o;10663:360::-;10749:3;10777:38;10809:5;10777:38;:::i;:::-;10831:70;10894:6;10889:3;10831:70;:::i;:::-;10824:77;;10910:52;10955:6;10950:3;10943:4;10936:5;10932:16;10910:52;:::i;:::-;10987:29;11009:6;10987:29;:::i;:::-;10982:3;10978:39;10971:46;;10753:270;10663:360;;;;:::o;11029:364::-;11117:3;11145:39;11178:5;11145:39;:::i;:::-;11200:71;11264:6;11259:3;11200:71;:::i;:::-;11193:78;;11280:52;11325:6;11320:3;11313:4;11306:5;11302:16;11280:52;:::i;:::-;11357:29;11379:6;11357:29;:::i;:::-;11352:3;11348:39;11341:46;;11121:272;11029:364;;;;:::o;11399:377::-;11505:3;11533:39;11566:5;11533:39;:::i;:::-;11588:89;11670:6;11665:3;11588:89;:::i;:::-;11581:96;;11686:52;11731:6;11726:3;11719:4;11712:5;11708:16;11686:52;:::i;:::-;11763:6;11758:3;11754:16;11747:23;;11509:267;11399:377;;;;:::o;11782:366::-;11924:3;11945:67;12009:2;12004:3;11945:67;:::i;:::-;11938:74;;12021:93;12110:3;12021:93;:::i;:::-;12139:2;12134:3;12130:12;12123:19;;11782:366;;;:::o;12154:::-;12296:3;12317:67;12381:2;12376:3;12317:67;:::i;:::-;12310:74;;12393:93;12482:3;12393:93;:::i;:::-;12511:2;12506:3;12502:12;12495:19;;12154:366;;;:::o;12526:::-;12668:3;12689:67;12753:2;12748:3;12689:67;:::i;:::-;12682:74;;12765:93;12854:3;12765:93;:::i;:::-;12883:2;12878:3;12874:12;12867:19;;12526:366;;;:::o;12898:::-;13040:3;13061:67;13125:2;13120:3;13061:67;:::i;:::-;13054:74;;13137:93;13226:3;13137:93;:::i;:::-;13255:2;13250:3;13246:12;13239:19;;12898:366;;;:::o;13270:::-;13412:3;13433:67;13497:2;13492:3;13433:67;:::i;:::-;13426:74;;13509:93;13598:3;13509:93;:::i;:::-;13627:2;13622:3;13618:12;13611:19;;13270:366;;;:::o;13642:365::-;13784:3;13805:66;13869:1;13864:3;13805:66;:::i;:::-;13798:73;;13880:93;13969:3;13880:93;:::i;:::-;13998:2;13993:3;13989:12;13982:19;;13642:365;;;:::o;14013:366::-;14155:3;14176:67;14240:2;14235:3;14176:67;:::i;:::-;14169:74;;14252:93;14341:3;14252:93;:::i;:::-;14370:2;14365:3;14361:12;14354:19;;14013:366;;;:::o;14385:400::-;14545:3;14566:84;14648:1;14643:3;14566:84;:::i;:::-;14559:91;;14659:93;14748:3;14659:93;:::i;:::-;14777:1;14772:3;14768:11;14761:18;;14385:400;;;:::o;14791:366::-;14933:3;14954:67;15018:2;15013:3;14954:67;:::i;:::-;14947:74;;15030:93;15119:3;15030:93;:::i;:::-;15148:2;15143:3;15139:12;15132:19;;14791:366;;;:::o;15163:::-;15305:3;15326:67;15390:2;15385:3;15326:67;:::i;:::-;15319:74;;15402:93;15491:3;15402:93;:::i;:::-;15520:2;15515:3;15511:12;15504:19;;15163:366;;;:::o;15535:::-;15677:3;15698:67;15762:2;15757:3;15698:67;:::i;:::-;15691:74;;15774:93;15863:3;15774:93;:::i;:::-;15892:2;15887:3;15883:12;15876:19;;15535:366;;;:::o;15907:::-;16049:3;16070:67;16134:2;16129:3;16070:67;:::i;:::-;16063:74;;16146:93;16235:3;16146:93;:::i;:::-;16264:2;16259:3;16255:12;16248:19;;15907:366;;;:::o;16279:::-;16421:3;16442:67;16506:2;16501:3;16442:67;:::i;:::-;16435:74;;16518:93;16607:3;16518:93;:::i;:::-;16636:2;16631:3;16627:12;16620:19;;16279:366;;;:::o;16651:::-;16793:3;16814:67;16878:2;16873:3;16814:67;:::i;:::-;16807:74;;16890:93;16979:3;16890:93;:::i;:::-;17008:2;17003:3;16999:12;16992:19;;16651:366;;;:::o;17023:::-;17165:3;17186:67;17250:2;17245:3;17186:67;:::i;:::-;17179:74;;17262:93;17351:3;17262:93;:::i;:::-;17380:2;17375:3;17371:12;17364:19;;17023:366;;;:::o;17395:108::-;17472:24;17490:5;17472:24;:::i;:::-;17467:3;17460:37;17395:108;;:::o;17509:118::-;17596:24;17614:5;17596:24;:::i;:::-;17591:3;17584:37;17509:118;;:::o;17633:435::-;17813:3;17835:95;17926:3;17917:6;17835:95;:::i;:::-;17828:102;;17947:95;18038:3;18029:6;17947:95;:::i;:::-;17940:102;;18059:3;18052:10;;17633:435;;;;;:::o;18074:541::-;18307:3;18329:95;18420:3;18411:6;18329:95;:::i;:::-;18322:102;;18441:148;18585:3;18441:148;:::i;:::-;18434:155;;18606:3;18599:10;;18074:541;;;;:::o;18621:222::-;18714:4;18752:2;18741:9;18737:18;18729:26;;18765:71;18833:1;18822:9;18818:17;18809:6;18765:71;:::i;:::-;18621:222;;;;:::o;18849:640::-;19044:4;19082:3;19071:9;19067:19;19059:27;;19096:71;19164:1;19153:9;19149:17;19140:6;19096:71;:::i;:::-;19177:72;19245:2;19234:9;19230:18;19221:6;19177:72;:::i;:::-;19259;19327:2;19316:9;19312:18;19303:6;19259:72;:::i;:::-;19378:9;19372:4;19368:20;19363:2;19352:9;19348:18;19341:48;19406:76;19477:4;19468:6;19406:76;:::i;:::-;19398:84;;18849:640;;;;;;;:::o;19495:373::-;19638:4;19676:2;19665:9;19661:18;19653:26;;19725:9;19719:4;19715:20;19711:1;19700:9;19696:17;19689:47;19753:108;19856:4;19847:6;19753:108;:::i;:::-;19745:116;;19495:373;;;;:::o;19874:210::-;19961:4;19999:2;19988:9;19984:18;19976:26;;20012:65;20074:1;20063:9;20059:17;20050:6;20012:65;:::i;:::-;19874:210;;;;:::o;20090:313::-;20203:4;20241:2;20230:9;20226:18;20218:26;;20290:9;20284:4;20280:20;20276:1;20265:9;20261:17;20254:47;20318:78;20391:4;20382:6;20318:78;:::i;:::-;20310:86;;20090:313;;;;:::o;20409:419::-;20575:4;20613:2;20602:9;20598:18;20590:26;;20662:9;20656:4;20652:20;20648:1;20637:9;20633:17;20626:47;20690:131;20816:4;20690:131;:::i;:::-;20682:139;;20409:419;;;:::o;20834:::-;21000:4;21038:2;21027:9;21023:18;21015:26;;21087:9;21081:4;21077:20;21073:1;21062:9;21058:17;21051:47;21115:131;21241:4;21115:131;:::i;:::-;21107:139;;20834:419;;;:::o;21259:::-;21425:4;21463:2;21452:9;21448:18;21440:26;;21512:9;21506:4;21502:20;21498:1;21487:9;21483:17;21476:47;21540:131;21666:4;21540:131;:::i;:::-;21532:139;;21259:419;;;:::o;21684:::-;21850:4;21888:2;21877:9;21873:18;21865:26;;21937:9;21931:4;21927:20;21923:1;21912:9;21908:17;21901:47;21965:131;22091:4;21965:131;:::i;:::-;21957:139;;21684:419;;;:::o;22109:::-;22275:4;22313:2;22302:9;22298:18;22290:26;;22362:9;22356:4;22352:20;22348:1;22337:9;22333:17;22326:47;22390:131;22516:4;22390:131;:::i;:::-;22382:139;;22109:419;;;:::o;22534:::-;22700:4;22738:2;22727:9;22723:18;22715:26;;22787:9;22781:4;22777:20;22773:1;22762:9;22758:17;22751:47;22815:131;22941:4;22815:131;:::i;:::-;22807:139;;22534:419;;;:::o;22959:::-;23125:4;23163:2;23152:9;23148:18;23140:26;;23212:9;23206:4;23202:20;23198:1;23187:9;23183:17;23176:47;23240:131;23366:4;23240:131;:::i;:::-;23232:139;;22959:419;;;:::o;23384:::-;23550:4;23588:2;23577:9;23573:18;23565:26;;23637:9;23631:4;23627:20;23623:1;23612:9;23608:17;23601:47;23665:131;23791:4;23665:131;:::i;:::-;23657:139;;23384:419;;;:::o;23809:::-;23975:4;24013:2;24002:9;23998:18;23990:26;;24062:9;24056:4;24052:20;24048:1;24037:9;24033:17;24026:47;24090:131;24216:4;24090:131;:::i;:::-;24082:139;;23809:419;;;:::o;24234:::-;24400:4;24438:2;24427:9;24423:18;24415:26;;24487:9;24481:4;24477:20;24473:1;24462:9;24458:17;24451:47;24515:131;24641:4;24515:131;:::i;:::-;24507:139;;24234:419;;;:::o;24659:::-;24825:4;24863:2;24852:9;24848:18;24840:26;;24912:9;24906:4;24902:20;24898:1;24887:9;24883:17;24876:47;24940:131;25066:4;24940:131;:::i;:::-;24932:139;;24659:419;;;:::o;25084:::-;25250:4;25288:2;25277:9;25273:18;25265:26;;25337:9;25331:4;25327:20;25323:1;25312:9;25308:17;25301:47;25365:131;25491:4;25365:131;:::i;:::-;25357:139;;25084:419;;;:::o;25509:::-;25675:4;25713:2;25702:9;25698:18;25690:26;;25762:9;25756:4;25752:20;25748:1;25737:9;25733:17;25726:47;25790:131;25916:4;25790:131;:::i;:::-;25782:139;;25509:419;;;:::o;25934:::-;26100:4;26138:2;26127:9;26123:18;26115:26;;26187:9;26181:4;26177:20;26173:1;26162:9;26158:17;26151:47;26215:131;26341:4;26215:131;:::i;:::-;26207:139;;25934:419;;;:::o;26359:222::-;26452:4;26490:2;26479:9;26475:18;26467:26;;26503:71;26571:1;26560:9;26556:17;26547:6;26503:71;:::i;:::-;26359:222;;;;:::o;26587:129::-;26621:6;26648:20;;:::i;:::-;26638:30;;26677:33;26705:4;26697:6;26677:33;:::i;:::-;26587:129;;;:::o;26722:75::-;26755:6;26788:2;26782:9;26772:19;;26722:75;:::o;26803:307::-;26864:4;26954:18;26946:6;26943:30;26940:56;;;26976:18;;:::i;:::-;26940:56;27014:29;27036:6;27014:29;:::i;:::-;27006:37;;27098:4;27092;27088:15;27080:23;;26803:307;;;:::o;27116:308::-;27178:4;27268:18;27260:6;27257:30;27254:56;;;27290:18;;:::i;:::-;27254:56;27328:29;27350:6;27328:29;:::i;:::-;27320:37;;27412:4;27406;27402:15;27394:23;;27116:308;;;:::o;27430:132::-;27497:4;27520:3;27512:11;;27550:4;27545:3;27541:14;27533:22;;27430:132;;;:::o;27568:114::-;27635:6;27669:5;27663:12;27653:22;;27568:114;;;:::o;27688:98::-;27739:6;27773:5;27767:12;27757:22;;27688:98;;;:::o;27792:99::-;27844:6;27878:5;27872:12;27862:22;;27792:99;;;:::o;27897:113::-;27967:4;27999;27994:3;27990:14;27982:22;;27897:113;;;:::o;28016:184::-;28115:11;28149:6;28144:3;28137:19;28189:4;28184:3;28180:14;28165:29;;28016:184;;;;:::o;28206:168::-;28289:11;28323:6;28318:3;28311:19;28363:4;28358:3;28354:14;28339:29;;28206:168;;;;:::o;28380:169::-;28464:11;28498:6;28493:3;28486:19;28538:4;28533:3;28529:14;28514:29;;28380:169;;;;:::o;28555:148::-;28657:11;28694:3;28679:18;;28555:148;;;;:::o;28709:305::-;28749:3;28768:20;28786:1;28768:20;:::i;:::-;28763:25;;28802:20;28820:1;28802:20;:::i;:::-;28797:25;;28956:1;28888:66;28884:74;28881:1;28878:81;28875:107;;;28962:18;;:::i;:::-;28875:107;29006:1;29003;28999:9;28992:16;;28709:305;;;;:::o;29020:185::-;29060:1;29077:20;29095:1;29077:20;:::i;:::-;29072:25;;29111:20;29129:1;29111:20;:::i;:::-;29106:25;;29150:1;29140:35;;29155:18;;:::i;:::-;29140:35;29197:1;29194;29190:9;29185:14;;29020:185;;;;:::o;29211:348::-;29251:7;29274:20;29292:1;29274:20;:::i;:::-;29269:25;;29308:20;29326:1;29308:20;:::i;:::-;29303:25;;29496:1;29428:66;29424:74;29421:1;29418:81;29413:1;29406:9;29399:17;29395:105;29392:131;;;29503:18;;:::i;:::-;29392:131;29551:1;29548;29544:9;29533:20;;29211:348;;;;:::o;29565:191::-;29605:4;29625:20;29643:1;29625:20;:::i;:::-;29620:25;;29659:20;29677:1;29659:20;:::i;:::-;29654:25;;29698:1;29695;29692:8;29689:34;;;29703:18;;:::i;:::-;29689:34;29748:1;29745;29741:9;29733:17;;29565:191;;;;:::o;29762:96::-;29799:7;29828:24;29846:5;29828:24;:::i;:::-;29817:35;;29762:96;;;:::o;29864:90::-;29898:7;29941:5;29934:13;29927:21;29916:32;;29864:90;;;:::o;29960:149::-;29996:7;30036:66;30029:5;30025:78;30014:89;;29960:149;;;:::o;30115:126::-;30152:7;30192:42;30185:5;30181:54;30170:65;;30115:126;;;:::o;30247:77::-;30284:7;30313:5;30302:16;;30247:77;;;:::o;30330:154::-;30414:6;30409:3;30404;30391:30;30476:1;30467:6;30462:3;30458:16;30451:27;30330:154;;;:::o;30490:307::-;30558:1;30568:113;30582:6;30579:1;30576:13;30568:113;;;30667:1;30662:3;30658:11;30652:18;30648:1;30643:3;30639:11;30632:39;30604:2;30601:1;30597:10;30592:15;;30568:113;;;30699:6;30696:1;30693:13;30690:101;;;30779:1;30770:6;30765:3;30761:16;30754:27;30690:101;30539:258;30490:307;;;:::o;30803:320::-;30847:6;30884:1;30878:4;30874:12;30864:22;;30931:1;30925:4;30921:12;30952:18;30942:81;;31008:4;31000:6;30996:17;30986:27;;30942:81;31070:2;31062:6;31059:14;31039:18;31036:38;31033:84;;;31089:18;;:::i;:::-;31033:84;30854:269;30803:320;;;:::o;31129:281::-;31212:27;31234:4;31212:27;:::i;:::-;31204:6;31200:40;31342:6;31330:10;31327:22;31306:18;31294:10;31291:34;31288:62;31285:88;;;31353:18;;:::i;:::-;31285:88;31393:10;31389:2;31382:22;31172:238;31129:281;;:::o;31416:233::-;31455:3;31478:24;31496:5;31478:24;:::i;:::-;31469:33;;31524:66;31517:5;31514:77;31511:103;;;31594:18;;:::i;:::-;31511:103;31641:1;31634:5;31630:13;31623:20;;31416:233;;;:::o;31655:176::-;31687:1;31704:20;31722:1;31704:20;:::i;:::-;31699:25;;31738:20;31756:1;31738:20;:::i;:::-;31733:25;;31777:1;31767:35;;31782:18;;:::i;:::-;31767:35;31823:1;31820;31816:9;31811:14;;31655:176;;;;:::o;31837:180::-;31885:77;31882:1;31875:88;31982:4;31979:1;31972:15;32006:4;32003:1;31996:15;32023:180;32071:77;32068:1;32061:88;32168:4;32165:1;32158:15;32192:4;32189:1;32182:15;32209:180;32257:77;32254:1;32247:88;32354:4;32351:1;32344:15;32378:4;32375:1;32368:15;32395:180;32443:77;32440:1;32433:88;32540:4;32537:1;32530:15;32564:4;32561:1;32554:15;32581:180;32629:77;32626:1;32619:88;32726:4;32723:1;32716:15;32750:4;32747:1;32740:15;32767:117;32876:1;32873;32866:12;32890:117;32999:1;32996;32989:12;33013:117;33122:1;33119;33112:12;33136:117;33245:1;33242;33235:12;33259:117;33368:1;33365;33358:12;33382:117;33491:1;33488;33481:12;33505:102;33546:6;33597:2;33593:7;33588:2;33581:5;33577:14;33573:28;33563:38;;33505:102;;;:::o;33613:170::-;33753:22;33749:1;33741:6;33737:14;33730:46;33613:170;:::o;33789:225::-;33929:34;33925:1;33917:6;33913:14;33906:58;33998:8;33993:2;33985:6;33981:15;33974:33;33789:225;:::o;34020:172::-;34160:24;34156:1;34148:6;34144:14;34137:48;34020:172;:::o;34198:171::-;34338:23;34334:1;34326:6;34322:14;34315:47;34198:171;:::o;34375:165::-;34515:17;34511:1;34503:6;34499:14;34492:41;34375:165;:::o;34546:158::-;34686:10;34682:1;34674:6;34670:14;34663:34;34546:158;:::o;34710:162::-;34850:14;34846:1;34838:6;34834:14;34827:38;34710:162;:::o;34878:155::-;35018:7;35014:1;35006:6;35002:14;34995:31;34878:155;:::o;35039:163::-;35179:15;35175:1;35167:6;35163:14;35156:39;35039:163;:::o;35208:182::-;35348:34;35344:1;35336:6;35332:14;35325:58;35208:182;:::o;35396:223::-;35536:34;35532:1;35524:6;35520:14;35513:58;35605:6;35600:2;35592:6;35588:15;35581:31;35396:223;:::o;35625:168::-;35765:20;35761:1;35753:6;35749:14;35742:44;35625:168;:::o;35799:162::-;35939:14;35935:1;35927:6;35923:14;35916:38;35799:162;:::o;35967:165::-;36107:17;36103:1;36095:6;36091:14;36084:41;35967:165;:::o;36138:181::-;36278:33;36274:1;36266:6;36262:14;36255:57;36138:181;:::o;36325:122::-;36398:24;36416:5;36398:24;:::i;:::-;36391:5;36388:35;36378:63;;36437:1;36434;36427:12;36378:63;36325:122;:::o;36453:116::-;36523:21;36538:5;36523:21;:::i;:::-;36516:5;36513:32;36503:60;;36559:1;36556;36549:12;36503:60;36453:116;:::o;36575:120::-;36647:23;36664:5;36647:23;:::i;:::-;36640:5;36637:34;36627:62;;36685:1;36682;36675:12;36627:62;36575:120;:::o;36701:122::-;36774:24;36792:5;36774:24;:::i;:::-;36767:5;36764:35;36754:63;;36813:1;36810;36803:12;36754:63;36701:122;:::o

Swarm Source

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