ETH Price: $3,342.19 (-1.65%)

Token

Appreciators (APR)
 

Overview

Max Total Supply

6,666 APR

Holders

1,615

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
6 APR
0x532f3ADc82E54d4D51B4E1C24056C48C82e379Ee
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:
Appreciators

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-08-20
*/

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


// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @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
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 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
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

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

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


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

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

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


// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

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


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

// File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol


// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

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

    /**
     * @dev Calldata version of {verify}
     *
     * _Available since v4.7._
     */
    function verifyCalldata(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

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

    /**
     * @dev Calldata version of {processProof}
     *
     * _Available since v4.7._
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * _Available since v4.7._
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * _Available since v4.7._
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,
     * consuming from one or the other at each step according to the instructions given by
     * `proofFlags`.
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

// File: contracts/lib/IERC721A.sol


// ERC721A Contracts v4.0.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

/**
 * @dev Interface of an ERC721A compliant contract.
 */
interface IERC721A {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

    /**
     * The token does not exist.
     */
    error ApprovalQueryForNonexistentToken();

    /**
     * The caller cannot approve to their own address.
     */
    error ApproveToCaller();

    /**
     * The caller cannot approve to the current owner.
     */
    error ApprovalToCurrentOwner();

    /**
     * Cannot query the balance for the zero address.
     */
    error BalanceQueryForZeroAddress();

    /**
     * Cannot mint to the zero address.
     */
    error MintToZeroAddress();

    /**
     * The quantity of tokens minted must be more than zero.
     */
    error MintZeroQuantity();

    /**
     * The token does not exist.
     */
    error OwnerQueryForNonexistentToken();

    /**
     * The caller must own the token or be an approved operator.
     */
    error TransferCallerNotOwnerNorApproved();

    /**
     * The token must be owned by `from`.
     */
    error TransferFromIncorrectOwner();

    /**
     * Cannot safely transfer to a contract that does not implement the ERC721Receiver interface.
     */
    error TransferToNonERC721ReceiverImplementer();

    /**
     * Cannot transfer to the zero address.
     */
    error TransferToZeroAddress();

    /**
     * The token does not exist.
     */
    error URIQueryForNonexistentToken();

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

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     *
     * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens.
     */
    function totalSupply() external view returns (uint256);

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

    // ==============================
    //            IERC721
    // ==============================

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

    /**
     * @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 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 the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

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

    // ==============================
    //        IERC721Metadata
    // ==============================

    /**
     * @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);
}
// File: contracts/lib/ERC721A.sol


// ERC721A Contracts v4.0.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;


/**
 * @dev ERC721 token receiver interface.
 */
interface ERC721A__IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

/**
 * @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 IERC721A {
    // Mask of an entry in packed address data.
    uint256 private constant BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

    // The bit position of `numberMinted` in packed address data.
    uint256 private constant BITPOS_NUMBER_MINTED = 64;

    // The bit position of `numberBurned` in packed address data.
    uint256 private constant BITPOS_NUMBER_BURNED = 128;

    // The bit position of `aux` in packed address data.
    uint256 private constant BITPOS_AUX = 192;

    // Mask of all 256 bits in packed address data except the 64 bits for `aux`.
    uint256 private constant BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;

    // The bit position of `startTimestamp` in packed ownership.
    uint256 private constant BITPOS_START_TIMESTAMP = 160;

    // The bit mask of the `burned` bit in packed ownership.
    uint256 private constant BITMASK_BURNED = 1 << 224;
    
    // The bit position of the `nextInitialized` bit in packed ownership.
    uint256 private constant BITPOS_NEXT_INITIALIZED = 225;

    // The bit mask of the `nextInitialized` bit in packed ownership.
    uint256 private constant BITMASK_NEXT_INITIALIZED = 1 << 225;

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

    // The number of tokens burned.
    uint256 private _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 `_packedOwnershipOf` implementation for details.
    //
    // Bits Layout:
    // - [0..159]   `addr`
    // - [160..223] `startTimestamp`
    // - [224]      `burned`
    // - [225]      `nextInitialized`
    mapping(uint256 => uint256) private _packedOwnerships;

    // Mapping owner address to address data.
    //
    // Bits Layout:
    // - [0..63]    `balance`
    // - [64..127]  `numberMinted`
    // - [128..191] `numberBurned`
    // - [192..255] `aux`
    mapping(address => uint256) private _packedAddressData;

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

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

    /**
     * @dev Returns the next token ID to be minted.
     */
    function _nextTokenId() internal view returns (uint256) {
        return _currentIndex;
    }

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count. 
     * To get the total number of tokens minted, please see `_totalMinted`.
     */
    function totalSupply() public view override returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than `_currentIndex - _startTokenId()` times.
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * @dev 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 Returns the total number of tokens burned.
     */
    function _totalBurned() internal view returns (uint256) {
        return _burnCounter;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        // The interface IDs are constants representing the first 4 bytes of the XOR of
        // all function selectors in the interface. See: https://eips.ethereum.org/EIPS/eip-165
        // e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

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

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> BITPOS_NUMBER_MINTED) & BITMASK_ADDRESS_DATA_ENTRY;
    }

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

    /**
     * Returns the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return uint64(_packedAddressData[owner] >> BITPOS_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 {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        assembly { // Cast aux without masking.
            auxCasted := aux
        }
        packed = (packed & BITMASK_AUX_COMPLEMENT) | (auxCasted << BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

    /**
     * Returns the packed ownership data of `tokenId`.
     */
    function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & BITMASK_BURNED == 0) {
                        // 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.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed is zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * Returns the unpacked `TokenOwnership` struct from `packed`.
     */
    function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
        ownership.addr = address(uint160(packed));
        ownership.startTimestamp = uint64(packed >> BITPOS_START_TIMESTAMP);
        ownership.burned = packed & BITMASK_BURNED != 0;
    }

    /**
     * Returns the unpacked `TokenOwnership` struct at `index`.
     */
    function _ownershipAt(uint256 index) internal view returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnerships[index]);
    }

    /**
     * @dev Initializes the ownership slot minted at `index` for efficiency purposes.
     */
    function _initializeOwnershipAt(uint256 index) internal {
        if (_packedOwnerships[index] == 0) {
            _packedOwnerships[index] = _packedOwnershipOf(index);
        }
    }

    /**
     * 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) {
        return _unpackedOwnership(_packedOwnershipOf(tokenId));
    }

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

    /**
     * @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, _toString(tokenId))) : '';
    }

    /**
     * @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 Casts the address to uint256 without masking.
     */
    function _addressToUint256(address value) private pure returns (uint256 result) {
        assembly {
            result := value
        }
    }

    /**
     * @dev Casts the boolean to uint256 without branching.
     */
    function _boolToUint256(bool value) private pure returns (uint256 result) {
        assembly {
            result := value
        }
    }

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

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

        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @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 == _msgSenderERC721A()) revert ApproveToCaller();

        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), 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.code.length != 0)
            if (!_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 && // If within bounds,
            _packedOwnerships[tokenId] & BITMASK_BURNED == 0; // and not burned.
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    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 {
        uint256 startTokenId = _currentIndex;
        if (_addressToUint256(to) == 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 {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);

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

            if (to.code.length != 0) {
                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 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) internal {
        uint256 startTokenId = _currentIndex;
        if (_addressToUint256(to) == 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 {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);

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

            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 {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();

        address approvedAddress = _tokenApprovals[tokenId];

        bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
            isApprovedForAll(from, _msgSenderERC721A()) ||
            approvedAddress == _msgSenderERC721A());

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

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        if (_addressToUint256(approvedAddress) != 0) {
            delete _tokenApprovals[tokenId];
        }

        // 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 {
            // We can directly increment and decrement the balances.
            --_packedAddressData[from]; // Updates: `balance -= 1`.
            ++_packedAddressData[to]; // Updates: `balance += 1`.

            // Updates:
            // - `address` to the next owner.
            // - `startTimestamp` to the timestamp of transfering.
            // - `burned` to `false`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                BITMASK_NEXT_INITIALIZED;

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

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

    /**
     * @dev 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 {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        address from = address(uint160(prevOwnershipPacked));
        address approvedAddress = _tokenApprovals[tokenId];

        if (approvalCheck) {
            bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
                isApprovedForAll(from, _msgSenderERC721A()) ||
                approvedAddress == _msgSenderERC721A());

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

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

        // Clear approvals from the previous owner.
        if (_addressToUint256(approvedAddress) != 0) {
            delete _tokenApprovals[tokenId];
        }

        // 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 {
            // Updates:
            // - `balance -= 1`.
            // - `numberBurned += 1`.
            //
            // We can directly decrement the balance, and increment the number burned.
            // This is equivalent to `packed -= 1; packed += 1 << BITPOS_NUMBER_BURNED;`.
            _packedAddressData[from] += (1 << BITPOS_NUMBER_BURNED) - 1;

            // Updates:
            // - `address` to the last owner.
            // - `startTimestamp` to the timestamp of burning.
            // - `burned` to `true`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] =
                _addressToUint256(from) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                BITMASK_BURNED | 
                BITMASK_NEXT_INITIALIZED;

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        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 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 ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
            bytes4 retval
        ) {
            return retval == ERC721A__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 {}

    /**
     * @dev Returns the message sender (defaults to `msg.sender`).
     *
     * If you are writing GSN compatible contracts, you need to override this function.
     */
    function _msgSenderERC721A() internal view virtual returns (address) {
        return msg.sender;
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function _toString(uint256 value) internal pure returns (string memory ptr) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit), 
            // but we allocate 128 bytes to keep the free memory pointer 32-byte word aliged.
            // We will need 1 32-byte word to store the length, 
            // and 3 32-byte words to store a maximum of 78 digits. Total: 32 + 3 * 32 = 128.
            ptr := add(mload(0x40), 128)
            // Update the free memory pointer to allocate.
            mstore(0x40, ptr)

            // Cache the end of the memory to calculate the length later.
            let end := ptr

            // We write the string from the rightmost digit to the leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // Costs a bit more than early returning for the zero case,
            // but cheaper in terms of deployment and overall runtime costs.
            for { 
                // Initialize and perform the first pass without check.
                let temp := value
                // Move the pointer 1 byte leftwards to point to an empty character slot.
                ptr := sub(ptr, 1)
                // Write the character to the pointer. 48 is the ASCII index of '0'.
                mstore8(ptr, add(48, mod(temp, 10)))
                temp := div(temp, 10)
            } temp { 
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
            } { // Body of the for loop.
                ptr := sub(ptr, 1)
                mstore8(ptr, add(48, mod(temp, 10)))
            }
            
            let length := sub(end, ptr)
            // Move the pointer 32 bytes leftwards to make room for the length.
            ptr := sub(ptr, 32)
            // Store the length.
            mstore(ptr, length)
        }
    }
}
// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

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


// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)

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

    /**
     * @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 `_msgSender()` is missing `role`.
     * Overriding this function changes the behavior of the {onlyRole} modifier.
     *
     * Format of the revert message is described in {_checkRole}.
     *
     * _Available since v4.6._
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @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.
     *
     * May emit a {RoleGranted} event.
     */
    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.
     *
     * May emit a {RoleRevoked} event.
     */
    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`.
     *
     * May emit a {RoleRevoked} event.
     */
    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.
     *
     * May emit a {RoleGranted} event.
     *
     * [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.
     *
     * May emit a {RoleGranted} event.
     */
    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.
     *
     * May emit a {RoleRevoked} event.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

// File: contracts/lib/PaymentSplitterConnector.sol


pragma solidity ^0.8.4;



contract PaymentSplitterConnector is AccessControl {
    address public PAYMENT_SPLITTER_ADDRESS;
    address public PAYMENT_DEFAULT_ADMIN;
    address public SPLITTER_ADMIN;
    bytes32 private constant SPLITTER_ADMIN_ROLE = keccak256("SPLITTER_ADMIN");

    constructor(address admin, address splitterAddress) {
        _setupRole(DEFAULT_ADMIN_ROLE, admin);
        _setupRole(SPLITTER_ADMIN_ROLE, admin);

        SPLITTER_ADMIN = admin;
        PAYMENT_DEFAULT_ADMIN = admin;
        PAYMENT_SPLITTER_ADDRESS = splitterAddress;
    }

    modifier onlySplitterAdmin() {
        require(
            hasRole(SPLITTER_ADMIN_ROLE, msg.sender),
            "Splitter: No Splitter Role"
        );
        _;
    }

    modifier onlyDefaultAdmin() {
        require(
            hasRole(DEFAULT_ADMIN_ROLE, msg.sender),
            "Splitter: No Admin Permission"
        );
        _;
    }

    function setSplitterAddress(address _splitterAddress)
        public
        onlySplitterAdmin
    {
        PAYMENT_SPLITTER_ADDRESS = _splitterAddress;
    }

    function withdraw() public {
        address payable recipient = payable(PAYMENT_SPLITTER_ADDRESS);
        uint256 balance = address(this).balance;

        Address.sendValue(recipient, balance);
    }

    function transferSplitterAdminRole(address admin) public onlyDefaultAdmin {
        require(SPLITTER_ADMIN != admin, "Splitter: Should be different");

        grantRole(SPLITTER_ADMIN_ROLE, admin);
        revokeRole(SPLITTER_ADMIN_ROLE, SPLITTER_ADMIN);
        SPLITTER_ADMIN = admin;
    }

    function transferDefaultAdminRole(address admin) public onlyDefaultAdmin {
        require(
            PAYMENT_DEFAULT_ADMIN != admin,
            "Splitter: Should be different"
        );

        grantRole(DEFAULT_ADMIN_ROLE, admin);
        revokeRole(DEFAULT_ADMIN_ROLE, PAYMENT_DEFAULT_ADMIN);
        PAYMENT_DEFAULT_ADMIN = admin;
    }
}

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


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

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 Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

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

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

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

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

// File: contracts/lib/MintStageWithReset.sol


pragma solidity ^0.8.4;



error InvalidMintAmount();
error InvalidDuration();
error NotOpenMint();
error ReachedMintStageLimit();
error ReachedMintWalletLimit();
error NotWhitelisted();
error NotEnoughPayment();

contract MintStageWithReset is Ownable {
    struct Stage {
        uint256 id;
        uint256 totalLimit;
        uint256 walletLimit;
        uint256 rate;
        uint256 walletLimitCounter;
        uint256 openingTime;
        uint256 closingTime;
        bytes32 whitelistRoot;
        bool isPublic;
    }

    Stage public currentStage;

    mapping(uint256 => mapping(address => uint256)) public walletMintCount;

    uint256 private constant BATCH_LIMIT = 10000;

    event MintStageUpdated(
        uint256 indexed _stage,
        uint256 _stageLimit,
        uint256 _stageLimitPerWallet,
        uint256 _rate,
        uint256 _openingTime,
        uint256 _closingTIme
    );

    function setMintStage(
        uint256 _stage,
        uint256 _stageLimit,
        uint256 _stageLimitPerWallet,
        uint256 _rate,
        uint256 _openingTime,
        uint256 _closingTime,
        bytes32 _whitelistMerkleRoot,
        bool _isPublic,
        bool _resetClaimCounter
    ) public onlyOwner {
        if (_openingTime > _closingTime) {
            revert InvalidDuration();
        }

        uint256 currentLimitWalletPerCounter = currentStage.walletLimitCounter;

        if (_resetClaimCounter) {
            currentLimitWalletPerCounter = currentLimitWalletPerCounter + 1;
        }

        currentStage = Stage(
            _stage,
            _stageLimit,
            _stageLimitPerWallet,
            _rate,
            currentLimitWalletPerCounter,
            _openingTime,
            _closingTime,
            _whitelistMerkleRoot,
            _isPublic
        );

        emit MintStageUpdated(
            _stage,
            _stageLimit,
            _stageLimitPerWallet,
            _rate,
            _openingTime,
            _closingTime
        );
    }

    function _verifyMint(
        bytes32[] calldata _merkleProof,
        uint256 _mintAmount,
        uint256 currentMintedCount,
        uint256 discount
    ) internal {
        address sender = msg.sender;
        uint256 sentAmount = msg.value;

        if (_mintAmount == 0 || _mintAmount > BATCH_LIMIT) {
            revert InvalidMintAmount();
        }

        if (!isStageOpen()) {
            revert NotOpenMint();
        }

        if (currentMintedCount + _mintAmount > currentStage.totalLimit) {
            revert ReachedMintStageLimit();
        }

        uint256 mintCount = walletMintCount[currentStage.walletLimitCounter][
            sender
        ];
        if (
            currentStage.walletLimit > 0 &&
            mintCount + _mintAmount > currentStage.walletLimit
        ) {
            revert ReachedMintWalletLimit();
        }

        if (!currentStage.isPublic) {
            bytes32 leaf = keccak256(abi.encodePacked(sender));

            if (
                !MerkleProof.verify(
                    _merkleProof,
                    currentStage.whitelistRoot,
                    leaf
                )
            ) {
                revert NotWhitelisted();
            }
        }

        uint256 requiredPayment = _mintAmount * (currentStage.rate - discount);
        if (sentAmount < requiredPayment) {
            revert NotEnoughPayment();
        }
    }

    function isStageOpen() public view returns (bool) {
        return
            block.timestamp >= currentStage.openingTime &&
            block.timestamp <= currentStage.closingTime;
    }

    function _updateWalletMintCount(address sender, uint256 _mintAmount)
        internal
    {
        uint256 mintCount = walletMintCount[currentStage.walletLimitCounter][
            sender
        ];
        walletMintCount[currentStage.walletLimitCounter][sender] =
            mintCount +
            _mintAmount;
    }
}

// File: contracts/Appreciators.sol


pragma solidity ^0.8.4;





error TokenSupplyExceeded();
error BatchLengthMismatch();

contract Appreciators is
    PaymentSplitterConnector,
    ERC721A,
    Ownable,
    MintStageWithReset
{
    uint256 public constant TOKEN_SUPPLY_LIMIT = 10000;
    string public baseExtension = ".json";
    string public baseURI = "";

    constructor(address splitterAdmin, address splitterAddress)
        ERC721A("Appreciators", "APR")
        PaymentSplitterConnector(splitterAdmin, splitterAddress)
    {}

    function batchAirdrop(
        address[] calldata recipients,
        uint256[] calldata quantity
    ) public onlyOwner {
        if (recipients.length != quantity.length) {
            revert BatchLengthMismatch();
        }

        for (uint256 i; i < recipients.length; ++i) {
            if ((_totalMinted() + quantity[i]) > TOKEN_SUPPLY_LIMIT) {
                revert TokenSupplyExceeded();
            }

            _safeMint(recipients[i], quantity[i]);
        }
    }

    function mint(bytes32[] calldata merkleProof, uint256 quantity)
        public
        payable
    {
        _verifyMint(merkleProof, quantity, _totalMinted(), 0);
        _updateWalletMintCount(msg.sender, quantity);
        _safeMint(msg.sender, quantity);
    }

    function burn(uint256 tokenId) public {
        _burn(tokenId, true);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721A, AccessControl)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721A)
        returns (string memory)
    {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        return
            bytes(baseURI).length > 0
                ? string(
                    abi.encodePacked(baseURI, _toString(tokenId), baseExtension)
                )
                : baseURI;
    }

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

    function setBaseExtension(string memory extension) public onlyOwner {
        baseExtension = extension;
    }

    function _startTokenId() internal view virtual override returns (uint256) {
        return 1;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"splitterAdmin","type":"address"},{"internalType":"address","name":"splitterAddress","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":"BatchLengthMismatch","type":"error"},{"inputs":[],"name":"InvalidDuration","type":"error"},{"inputs":[],"name":"InvalidMintAmount","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"NotEnoughPayment","type":"error"},{"inputs":[],"name":"NotOpenMint","type":"error"},{"inputs":[],"name":"NotWhitelisted","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ReachedMintStageLimit","type":"error"},{"inputs":[],"name":"ReachedMintWalletLimit","type":"error"},{"inputs":[],"name":"TokenSupplyExceeded","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_stage","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_stageLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_stageLimitPerWallet","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_rate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_openingTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_closingTIme","type":"uint256"}],"name":"MintStageUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","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":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAYMENT_DEFAULT_ADMIN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAYMENT_SPLITTER_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SPLITTER_ADMIN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOKEN_SUPPLY_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"quantity","type":"uint256[]"}],"name":"batchAirdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentStage","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"totalLimit","type":"uint256"},{"internalType":"uint256","name":"walletLimit","type":"uint256"},{"internalType":"uint256","name":"rate","type":"uint256"},{"internalType":"uint256","name":"walletLimitCounter","type":"uint256"},{"internalType":"uint256","name":"openingTime","type":"uint256"},{"internalType":"uint256","name":"closingTime","type":"uint256"},{"internalType":"bytes32","name":"whitelistRoot","type":"bytes32"},{"internalType":"bool","name":"isPublic","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":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","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":"isStageOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"extension","type":"string"}],"name":"setBaseExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stage","type":"uint256"},{"internalType":"uint256","name":"_stageLimit","type":"uint256"},{"internalType":"uint256","name":"_stageLimitPerWallet","type":"uint256"},{"internalType":"uint256","name":"_rate","type":"uint256"},{"internalType":"uint256","name":"_openingTime","type":"uint256"},{"internalType":"uint256","name":"_closingTime","type":"uint256"},{"internalType":"bytes32","name":"_whitelistMerkleRoot","type":"bytes32"},{"internalType":"bool","name":"_isPublic","type":"bool"},{"internalType":"bool","name":"_resetClaimCounter","type":"bool"}],"name":"setMintStage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_splitterAddress","type":"address"}],"name":"setSplitterAddress","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":[{"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":"admin","type":"address"}],"name":"transferDefaultAdminRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"transferSplitterAdminRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"walletMintCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526040518060400160405280600581526020017f2e6a736f6e0000000000000000000000000000000000000000000000000000008152506017908051906020019062000051929190620004e1565b50604051806020016040528060008152506018908051906020019062000079929190620004e1565b503480156200008757600080fd5b50604051620051b3380380620051b38339818101604052810190620000ad9190620005a8565b6040518060400160405280600c81526020017f4170707265636961746f727300000000000000000000000000000000000000008152506040518060400160405280600381526020017f41505200000000000000000000000000000000000000000000000000000000008152508383620001306000801b836200029960201b60201c565b620001627f10ec476f95b2ac17b26abe61aa04eca5036baf3b2845e79fbbb0fd495127a458836200029960201b60201c565b81600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505081600690805190602001906200023f929190620004e1565b50806007908051906020019062000258929190620004e1565b5062000269620002af60201b60201c565b60048190555050506200029162000285620002b860201b60201c565b620002c060201b60201c565b5050620006a7565b620002ab82826200038660201b60201c565b5050565b60006001905090565b600033905090565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6200039882826200047760201b60201c565b6200047357600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555062000418620002b860201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b828054620004ef9062000623565b90600052602060002090601f0160209004810192826200051357600085556200055f565b82601f106200052e57805160ff19168380011785556200055f565b828001600101855582156200055f579182015b828111156200055e57825182559160200191906001019062000541565b5b5090506200056e919062000572565b5090565b5b808211156200058d57600081600090555060010162000573565b5090565b600081519050620005a2816200068d565b92915050565b60008060408385031215620005c257620005c162000688565b5b6000620005d28582860162000591565b9250506020620005e58582860162000591565b9150509250929050565b6000620005fc8262000603565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600060028204905060018216806200063c57607f821691505b6020821081141562000653576200065262000659565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600080fd5b6200069881620005ef565b8114620006a457600080fd5b50565b614afc80620006b76000396000f3fe6080604052600436106102515760003560e01c8063715018a611610139578063b816d087116100b6578063d547741f1161007a578063d547741f146108a7578063da3ef23f146108d0578063e985e9c5146108f9578063f0fea4c814610936578063f234420814610961578063f2fde38b1461098c57610251565b8063b816d087146107c2578063b88d4fde146107eb578063c668286214610814578063c87b56dd1461083f578063d2d871e01461087c57610251565b8063a217fddf116100fd578063a217fddf146106f1578063a22cb4651461071c578063ae0cb91014610745578063b69f6df91461076e578063b7f70ac21461079957610251565b8063715018a61461060a5780638da5cb5b1461062157806391d148541461064c57806395d89b411461068957806397813980146106b457610251565b806336568abe116101d257806345de0d9b1161019657806345de0d9b146104ed57806355f804b3146105095780635bf5d54c146105325780636352211e146105655780636c0360eb146105a257806370a08231146105cd57610251565b806336568abe146104325780633ccfd60b1461045b57806340dbdd211461047257806342842e0e1461049b57806342966c68146104c457610251565b806318160ddd1161021957806318160ddd1461034d57806323b872dd14610378578063248a9ca3146103a1578063292005a2146103de5780632f2ff15d1461040957610251565b806301ffc9a71461025657806306fdde0314610293578063081812fc146102be578063095ea7b3146102fb5780631526e08714610324575b600080fd5b34801561026257600080fd5b5061027d60048036038101906102789190613b33565b6109b5565b60405161028a9190614128565b60405180910390f35b34801561029f57600080fd5b506102a86109c7565b6040516102b5919061415e565b60405180910390f35b3480156102ca57600080fd5b506102e560048036038101906102e09190613bd6565b610a59565b6040516102f291906140c1565b60405180910390f35b34801561030757600080fd5b50610322600480360381019061031d91906139a5565b610ad5565b005b34801561033057600080fd5b5061034b60048036038101906103469190613822565b610c7c565b005b34801561035957600080fd5b50610362610dd9565b60405161036f91906142a0565b60405180910390f35b34801561038457600080fd5b5061039f600480360381019061039a919061388f565b610df0565b005b3480156103ad57600080fd5b506103c860048036038101906103c39190613ac6565b610e00565b6040516103d59190614143565b60405180910390f35b3480156103ea57600080fd5b506103f3610e1f565b60405161040091906142a0565b60405180910390f35b34801561041557600080fd5b50610430600480360381019061042b9190613af3565b610e25565b005b34801561043e57600080fd5b5061045960048036038101906104549190613af3565b610e46565b005b34801561046757600080fd5b50610470610ec9565b005b34801561047e57600080fd5b5061049960048036038101906104949190613822565b610f03565b005b3480156104a757600080fd5b506104c260048036038101906104bd919061388f565b610fb0565b005b3480156104d057600080fd5b506104eb60048036038101906104e69190613bd6565b610fd0565b005b61050760048036038101906105029190613a66565b610fde565b005b34801561051557600080fd5b50610530600480360381019061052b9190613b8d565b61100c565b005b34801561053e57600080fd5b5061054761102e565b60405161055c9998979695949392919061430e565b60405180910390f35b34801561057157600080fd5b5061058c60048036038101906105879190613bd6565b611077565b60405161059991906140c1565b60405180910390f35b3480156105ae57600080fd5b506105b7611089565b6040516105c4919061415e565b60405180910390f35b3480156105d957600080fd5b506105f460048036038101906105ef9190613822565b611117565b60405161060191906142a0565b60405180910390f35b34801561061657600080fd5b5061061f6111ac565b005b34801561062d57600080fd5b506106366111c0565b60405161064391906140c1565b60405180910390f35b34801561065857600080fd5b50610673600480360381019061066e9190613af3565b6111ea565b6040516106809190614128565b60405180910390f35b34801561069557600080fd5b5061069e611254565b6040516106ab919061415e565b60405180910390f35b3480156106c057600080fd5b506106db60048036038101906106d69190613c03565b6112e6565b6040516106e891906142a0565b60405180910390f35b3480156106fd57600080fd5b5061070661130b565b6040516107139190614143565b60405180910390f35b34801561072857600080fd5b50610743600480360381019061073e9190613965565b611312565b005b34801561075157600080fd5b5061076c60048036038101906107679190613c43565b61148a565b005b34801561077a57600080fd5b506107836115f0565b60405161079091906140c1565b60405180910390f35b3480156107a557600080fd5b506107c060048036038101906107bb9190613822565b611616565b005b3480156107ce57600080fd5b506107e960048036038101906107e491906139e5565b6117ad565b005b3480156107f757600080fd5b50610812600480360381019061080d91906138e2565b6118cb565b005b34801561082057600080fd5b5061082961193e565b604051610836919061415e565b60405180910390f35b34801561084b57600080fd5b5061086660048036038101906108619190613bd6565b6119cc565b604051610873919061415e565b60405180910390f35b34801561088857600080fd5b50610891611ae9565b60405161089e91906140c1565b60405180910390f35b3480156108b357600080fd5b506108ce60048036038101906108c99190613af3565b611b0f565b005b3480156108dc57600080fd5b506108f760048036038101906108f29190613b8d565b611b30565b005b34801561090557600080fd5b50610920600480360381019061091b919061384f565b611b52565b60405161092d9190614128565b60405180910390f35b34801561094257600080fd5b5061094b611be6565b6040516109589190614128565b60405180910390f35b34801561096d57600080fd5b50610976611c07565b60405161098391906140c1565b60405180910390f35b34801561099857600080fd5b506109b360048036038101906109ae9190613822565b611c2d565b005b60006109c082611cb1565b9050919050565b6060600680546109d690614653565b80601f0160208091040260200160405190810160405280929190818152602001828054610a0290614653565b8015610a4f5780601f10610a2457610100808354040283529160200191610a4f565b820191906000526020600020905b815481529060010190602001808311610a3257829003601f168201915b5050505050905090565b6000610a6482611d43565b610a9a576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610ae082611da2565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610b48576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610b67611e70565b73ffffffffffffffffffffffffffffffffffffffff1614610bca57610b9381610b8e611e70565b611b52565b610bc9576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b82600a600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b610c896000801b336111ea565b610cc8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cbf906141c0565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610d59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5090614220565b60405180910390fd5b610d666000801b82610e25565b610d956000801b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16611b0f565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000610de3611e78565b6005546004540303905090565b610dfb838383611e81565b505050565b6000806000838152602001908152602001600020600101549050919050565b61271081565b610e2e82610e00565b610e3781612249565b610e41838361225d565b505050565b610e4e61233d565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ebb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb290614280565b60405180910390fd5b610ec58282612345565b5050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000479050610eff8282612426565b5050565b610f2d7f10ec476f95b2ac17b26abe61aa04eca5036baf3b2845e79fbbb0fd495127a458336111ea565b610f6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6390614260565b60405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610fcb838383604051806020016040528060008152506118cb565b505050565b610fdb81600161251a565b50565b610ff3838383610fec612834565b6000612847565b610ffd3382612b05565b6110073382612bc9565b505050565b611014612be7565b806018908051906020019061102a92919061351f565b5050565b600d8060000154908060010154908060020154908060030154908060040154908060050154908060060154908060070154908060080160009054906101000a900460ff16905089565b600061108282611da2565b9050919050565b6018805461109690614653565b80601f01602080910402602001604051908101604052809291908181526020018280546110c290614653565b801561110f5780601f106110e45761010080835404028352916020019161110f565b820191906000526020600020905b8154815290600101906020018083116110f257829003601f168201915b505050505081565b60008061112383612c65565b141561115b576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6111b4612be7565b6111be6000612c6f565b565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60606007805461126390614653565b80601f016020809104026020016040519081016040528092919081815260200182805461128f90614653565b80156112dc5780601f106112b1576101008083540402835291602001916112dc565b820191906000526020600020905b8154815290600101906020018083116112bf57829003601f168201915b5050505050905090565b6016602052816000526040600020602052806000526040600020600091509150505481565b6000801b81565b61131a611e70565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561137f576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600b600061138c611e70565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611439611e70565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161147e9190614128565b60405180910390a35050565b611492612be7565b838511156114cc576040517f7616640100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600d60040154905081156114ec576001816114e99190614485565b90505b6040518061012001604052808b81526020018a8152602001898152602001888152602001828152602001878152602001868152602001858152602001841515815250600d600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701556101008201518160080160006101000a81548160ff021916908315150217905550905050897f1eac6b5b91b97537498543fce5db2429ccdd3b13445b508d3142bfc51c8736c78a8a8a8a8a6040516115dc9594939291906142bb565b60405180910390a250505050505050505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6116236000801b336111ea565b611662576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611659906141c0565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156116f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ea90614220565b60405180910390fd5b61171d7f10ec476f95b2ac17b26abe61aa04eca5036baf3b2845e79fbbb0fd495127a45882610e25565b6117697f10ec476f95b2ac17b26abe61aa04eca5036baf3b2845e79fbbb0fd495127a458600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16611b0f565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6117b5612be7565b8181905084849050146117f4576040517f17e37b5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b848490508110156118c45761271083838381811061181857611817614781565b5b90506020020135611827612834565b6118319190614485565b1115611869576040517f1c07ee3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118b385858381811061187f5761187e614781565b5b90506020020160208101906118949190613822565b8484848181106118a7576118a6614781565b5b90506020020135612bc9565b806118bd906146b6565b90506117f7565b5050505050565b6118d6848484611e81565b60008373ffffffffffffffffffffffffffffffffffffffff163b146119385761190184848484612d35565b611937576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6017805461194b90614653565b80601f016020809104026020016040519081016040528092919081815260200182805461197790614653565b80156119c45780601f10611999576101008083540402835291602001916119c4565b820191906000526020600020905b8154815290600101906020018083116119a757829003601f168201915b505050505081565b60606119d782611d43565b611a0d576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060188054611a1c90614653565b905011611ab35760188054611a3090614653565b80601f0160208091040260200160405190810160405280929190818152602001828054611a5c90614653565b8015611aa95780601f10611a7e57610100808354040283529160200191611aa9565b820191906000526020600020905b815481529060010190602001808311611a8c57829003601f168201915b5050505050611ae2565b6018611abe83612e95565b6017604051602001611ad293929190614041565b6040516020818303038152906040525b9050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611b1882610e00565b611b2181612249565b611b2b8383612345565b505050565b611b38612be7565b8060179080519060200190611b4e92919061351f565b5050565b6000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000600d600501544210158015611c025750600d600601544211155b905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611c35612be7565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611ca5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9c906141a0565b60405180910390fd5b611cae81612c6f565b50565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611d0c57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611d3c5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600081611d4e611e78565b11158015611d5d575060045482105b8015611d9b575060007c0100000000000000000000000000000000000000000000000000000000600860008581526020019081526020016000205416145b9050919050565b60008082905080611db1611e78565b11611e3957600454811015611e385760006008600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082161415611e36575b6000811415611e2c576008600083600190039350838152602001908152602001600020549050611e01565b8092505050611e6b565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b60006001905090565b6000611e8c82611da2565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611ef3576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600a600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008573ffffffffffffffffffffffffffffffffffffffff16611f4c611e70565b73ffffffffffffffffffffffffffffffffffffffff161480611f7b5750611f7a86611f75611e70565b611b52565b5b80611fb85750611f89611e70565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b905080611ff1576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611ffc86612c65565b1415612034576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120418686866001612eef565b600061204c83612c65565b1461208857600a600085815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b61214f87612c65565b1717600860008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841614156121d95760006001850190506000600860008381526020019081526020016000205414156121d75760045481146121d6578360086000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46122418686866001612ef5565b505050505050565b61225a8161225561233d565b612efb565b50565b61226782826111ea565b61233957600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506122de61233d565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600033905090565b61234f82826111ea565b1561242257600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506123c761233d565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b80471015612469576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246090614200565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff168260405161248f90614072565b60006040518083038185875af1925050503d80600081146124cc576040519150601f19603f3d011682016040523d82523d6000602084013e6124d1565b606091505b5050905080612515576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161250c906141e0565b60405180910390fd5b505050565b600061252583611da2565b905060008190506000600a600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083156126325760008273ffffffffffffffffffffffffffffffffffffffff1661258b611e70565b73ffffffffffffffffffffffffffffffffffffffff1614806125ba57506125b9836125b4611e70565b611b52565b5b806125f757506125c8611e70565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b905080612630576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b612640826000876001612eef565b600061264b82612c65565b1461268757600a600086815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b600160806001901b03600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055507c02000000000000000000000000000000000000000000000000000000007c010000000000000000000000000000000000000000000000000000000060a042901b61272685612c65565b171717600860008781526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841614156127b15760006001860190506000600860008381526020019081526020016000205414156127af5760045481146127ae578360086000838152602001908152602001600020819055505b5b505b84600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461281b826000876001612ef5565b6005600081548092919060010191905055505050505050565b600061283e611e78565b60045403905090565b600033905060003490506000851480612861575061271085115b15612898576040517fccfad01800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128a0611be6565b6128d6576040517fa213ecf100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d6001015485856128e89190614485565b1115612920576040517fdfedbeec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060166000600d60040154815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000600d6002015411801561299e5750600d60020154868261299c9190614485565b115b156129d5576040517fbf7fbad100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d60080160009054906101000a900460ff16612aa0576000836040516020016129ff9190614026565b604051602081830303815290604052805190602001209050612a68898980806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600d6007015483612f98565b612a9e576040517f584a793800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b600084600d60030154612ab39190614535565b87612abe91906144db565b905080831015612afa576040517f6d35ff8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600060166000600d60040154815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181612b6b9190614485565b60166000600d60040154815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050565b612be3828260405180602001604052806000815250612faf565b5050565b612bef61233d565b73ffffffffffffffffffffffffffffffffffffffff16612c0d6111c0565b73ffffffffffffffffffffffffffffffffffffffff1614612c63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c5a90614240565b60405180910390fd5b565b6000819050919050565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612d5b611e70565b8786866040518563ffffffff1660e01b8152600401612d7d94939291906140dc565b602060405180830381600087803b158015612d9757600080fd5b505af1925050508015612dc857506040513d601f19601f82011682018060405250810190612dc59190613b60565b60015b612e42573d8060008114612df8576040519150601f19603f3d011682016040523d82523d6000602084013e612dfd565b606091505b50600081511415612e3a576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606080604051019050806040528082600183039250600a81066030018353600a810490505b8015612edb57600183039250600a81066030018353600a81049050612ebb565b508181036020830392508083525050919050565b50505050565b50505050565b612f0582826111ea565b612f9457612f2a8173ffffffffffffffffffffffffffffffffffffffff166014613241565b612f388360001c6020613241565b604051602001612f49929190614087565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f8b919061415e565b60405180910390fd5b5050565b600082612fa5858461347d565b1490509392505050565b600060045490506000612fc185612c65565b1415612ff9576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000831415613034576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6130416000858386612eef565b600160406001901b178302600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e16130a6600185146134d3565b901b60a042901b6130b686612c65565b1717600860008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b146131ba575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461316a6000878480600101955087612d35565b6131a0576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8082106130fb5782600454146131b557600080fd5b613225565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48082106131bb575b81600481905550505061323b6000858386612ef5565b50505050565b60606000600283600261325491906144db565b61325e9190614485565b67ffffffffffffffff811115613277576132766147b0565b5b6040519080825280601f01601f1916602001820160405280156132a95781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106132e1576132e0614781565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061334557613344614781565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261338591906144db565b61338f9190614485565b90505b600181111561342f577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106133d1576133d0614781565b5b1a60f81b8282815181106133e8576133e7614781565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c94508061342890614629565b9050613392565b5060008414613473576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161346a90614180565b60405180910390fd5b8091505092915050565b60008082905060005b84518110156134c8576134b3828683815181106134a6576134a5614781565b5b60200260200101516134dd565b915080806134c0906146b6565b915050613486565b508091505092915050565b6000819050919050565b60008183106134f5576134f08284613508565b613500565b6134ff8383613508565b5b905092915050565b600082600052816020526040600020905092915050565b82805461352b90614653565b90600052602060002090601f01602090048101928261354d5760008555613594565b82601f1061356657805160ff1916838001178555613594565b82800160010185558215613594579182015b82811115613593578251825591602001919060010190613578565b5b5090506135a191906135a5565b5090565b5b808211156135be5760008160009055506001016135a6565b5090565b60006135d56135d0846143c0565b61439b565b9050828152602081018484840111156135f1576135f06147ee565b5b6135fc8482856145e7565b509392505050565b6000613617613612846143f1565b61439b565b905082815260208101848484011115613633576136326147ee565b5b61363e8482856145e7565b509392505050565b60008135905061365581614a53565b92915050565b60008083601f840112613671576136706147e4565b5b8235905067ffffffffffffffff81111561368e5761368d6147df565b5b6020830191508360208202830111156136aa576136a96147e9565b5b9250929050565b60008083601f8401126136c7576136c66147e4565b5b8235905067ffffffffffffffff8111156136e4576136e36147df565b5b602083019150836020820283011115613700576136ff6147e9565b5b9250929050565b60008083601f84011261371d5761371c6147e4565b5b8235905067ffffffffffffffff81111561373a576137396147df565b5b602083019150836020820283011115613756576137556147e9565b5b9250929050565b60008135905061376c81614a6a565b92915050565b60008135905061378181614a81565b92915050565b60008135905061379681614a98565b92915050565b6000815190506137ab81614a98565b92915050565b600082601f8301126137c6576137c56147e4565b5b81356137d68482602086016135c2565b91505092915050565b600082601f8301126137f4576137f36147e4565b5b8135613804848260208601613604565b91505092915050565b60008135905061381c81614aaf565b92915050565b600060208284031215613838576138376147f8565b5b600061384684828501613646565b91505092915050565b60008060408385031215613866576138656147f8565b5b600061387485828601613646565b925050602061388585828601613646565b9150509250929050565b6000806000606084860312156138a8576138a76147f8565b5b60006138b686828701613646565b93505060206138c786828701613646565b92505060406138d88682870161380d565b9150509250925092565b600080600080608085870312156138fc576138fb6147f8565b5b600061390a87828801613646565b945050602061391b87828801613646565b935050604061392c8782880161380d565b925050606085013567ffffffffffffffff81111561394d5761394c6147f3565b5b613959878288016137b1565b91505092959194509250565b6000806040838503121561397c5761397b6147f8565b5b600061398a85828601613646565b925050602061399b8582860161375d565b9150509250929050565b600080604083850312156139bc576139bb6147f8565b5b60006139ca85828601613646565b92505060206139db8582860161380d565b9150509250929050565b600080600080604085870312156139ff576139fe6147f8565b5b600085013567ffffffffffffffff811115613a1d57613a1c6147f3565b5b613a298782880161365b565b9450945050602085013567ffffffffffffffff811115613a4c57613a4b6147f3565b5b613a5887828801613707565b925092505092959194509250565b600080600060408486031215613a7f57613a7e6147f8565b5b600084013567ffffffffffffffff811115613a9d57613a9c6147f3565b5b613aa9868287016136b1565b93509350506020613abc8682870161380d565b9150509250925092565b600060208284031215613adc57613adb6147f8565b5b6000613aea84828501613772565b91505092915050565b60008060408385031215613b0a57613b096147f8565b5b6000613b1885828601613772565b9250506020613b2985828601613646565b9150509250929050565b600060208284031215613b4957613b486147f8565b5b6000613b5784828501613787565b91505092915050565b600060208284031215613b7657613b756147f8565b5b6000613b848482850161379c565b91505092915050565b600060208284031215613ba357613ba26147f8565b5b600082013567ffffffffffffffff811115613bc157613bc06147f3565b5b613bcd848285016137df565b91505092915050565b600060208284031215613bec57613beb6147f8565b5b6000613bfa8482850161380d565b91505092915050565b60008060408385031215613c1a57613c196147f8565b5b6000613c288582860161380d565b9250506020613c3985828601613646565b9150509250929050565b60008060008060008060008060006101208a8c031215613c6657613c656147f8565b5b6000613c748c828d0161380d565b9950506020613c858c828d0161380d565b9850506040613c968c828d0161380d565b9750506060613ca78c828d0161380d565b9650506080613cb88c828d0161380d565b95505060a0613cc98c828d0161380d565b94505060c0613cda8c828d01613772565b93505060e0613ceb8c828d0161375d565b925050610100613cfd8c828d0161375d565b9150509295985092959850929598565b613d1681614569565b82525050565b613d2d613d2882614569565b6146ff565b82525050565b613d3c8161457b565b82525050565b613d4b81614587565b82525050565b6000613d5c82614437565b613d66818561444d565b9350613d768185602086016145f6565b613d7f816147fd565b840191505092915050565b6000613d9582614442565b613d9f8185614469565b9350613daf8185602086016145f6565b613db8816147fd565b840191505092915050565b6000613dce82614442565b613dd8818561447a565b9350613de88185602086016145f6565b80840191505092915050565b60008154613e0181614653565b613e0b818661447a565b94506001821660008114613e265760018114613e3757613e6a565b60ff19831686528186019350613e6a565b613e4085614422565b60005b83811015613e6257815481890152600182019150602081019050613e43565b838801955050505b50505092915050565b6000613e80602083614469565b9150613e8b8261481b565b602082019050919050565b6000613ea3602683614469565b9150613eae82614844565b604082019050919050565b6000613ec6601d83614469565b9150613ed182614893565b602082019050919050565b6000613ee9603a83614469565b9150613ef4826148bc565b604082019050919050565b6000613f0c601d83614469565b9150613f178261490b565b602082019050919050565b6000613f2f601d83614469565b9150613f3a82614934565b602082019050919050565b6000613f52602083614469565b9150613f5d8261495d565b602082019050919050565b6000613f75601a83614469565b9150613f8082614986565b602082019050919050565b6000613f9860008361445e565b9150613fa3826149af565b600082019050919050565b6000613fbb60178361447a565b9150613fc6826149b2565b601782019050919050565b6000613fde60118361447a565b9150613fe9826149db565b601182019050919050565b6000614001602f83614469565b915061400c82614a04565b604082019050919050565b614020816145dd565b82525050565b60006140328284613d1c565b60148201915081905092915050565b600061404d8286613df4565b91506140598285613dc3565b91506140658284613df4565b9150819050949350505050565b600061407d82613f8b565b9150819050919050565b600061409282613fae565b915061409e8285613dc3565b91506140a982613fd1565b91506140b58284613dc3565b91508190509392505050565b60006020820190506140d66000830184613d0d565b92915050565b60006080820190506140f16000830187613d0d565b6140fe6020830186613d0d565b61410b6040830185614017565b818103606083015261411d8184613d51565b905095945050505050565b600060208201905061413d6000830184613d33565b92915050565b60006020820190506141586000830184613d42565b92915050565b600060208201905081810360008301526141788184613d8a565b905092915050565b6000602082019050818103600083015261419981613e73565b9050919050565b600060208201905081810360008301526141b981613e96565b9050919050565b600060208201905081810360008301526141d981613eb9565b9050919050565b600060208201905081810360008301526141f981613edc565b9050919050565b6000602082019050818103600083015261421981613eff565b9050919050565b6000602082019050818103600083015261423981613f22565b9050919050565b6000602082019050818103600083015261425981613f45565b9050919050565b6000602082019050818103600083015261427981613f68565b9050919050565b6000602082019050818103600083015261429981613ff4565b9050919050565b60006020820190506142b56000830184614017565b92915050565b600060a0820190506142d06000830188614017565b6142dd6020830187614017565b6142ea6040830186614017565b6142f76060830185614017565b6143046080830184614017565b9695505050505050565b600061012082019050614324600083018c614017565b614331602083018b614017565b61433e604083018a614017565b61434b6060830189614017565b6143586080830188614017565b61436560a0830187614017565b61437260c0830186614017565b61437f60e0830185613d42565b61438d610100830184613d33565b9a9950505050505050505050565b60006143a56143b6565b90506143b18282614685565b919050565b6000604051905090565b600067ffffffffffffffff8211156143db576143da6147b0565b5b6143e4826147fd565b9050602081019050919050565b600067ffffffffffffffff82111561440c5761440b6147b0565b5b614415826147fd565b9050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000614490826145dd565b915061449b836145dd565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156144d0576144cf614723565b5b828201905092915050565b60006144e6826145dd565b91506144f1836145dd565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561452a57614529614723565b5b828202905092915050565b6000614540826145dd565b915061454b836145dd565b92508282101561455e5761455d614723565b5b828203905092915050565b6000614574826145bd565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156146145780820151818401526020810190506145f9565b83811115614623576000848401525b50505050565b6000614634826145dd565b9150600082141561464857614647614723565b5b600182039050919050565b6000600282049050600182168061466b57607f821691505b6020821081141561467f5761467e614752565b5b50919050565b61468e826147fd565b810181811067ffffffffffffffff821117156146ad576146ac6147b0565b5b80604052505050565b60006146c1826145dd565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156146f4576146f3614723565b5b600182019050919050565b600061470a82614711565b9050919050565b600061471c8261480e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f53706c69747465723a204e6f2041646d696e205065726d697373696f6e000000600082015250565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b7f53706c69747465723a2053686f756c6420626520646966666572656e74000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f53706c69747465723a204e6f2053706c697474657220526f6c65000000000000600082015250565b50565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b614a5c81614569565b8114614a6757600080fd5b50565b614a738161457b565b8114614a7e57600080fd5b50565b614a8a81614587565b8114614a9557600080fd5b50565b614aa181614591565b8114614aac57600080fd5b50565b614ab8816145dd565b8114614ac357600080fd5b5056fea2646970667358221220ac779afc29190c8bd853fb500a073e2684aa8cd8b1c4d8db8f0d3d486208725464736f6c634300080700330000000000000000000000002412c008ed3caabfbd2bf9ee73d9fdb6f2180a21000000000000000000000000e108a3b7ecb978b1e4fb4342e9296e134273d2d5

Deployed Bytecode

0x6080604052600436106102515760003560e01c8063715018a611610139578063b816d087116100b6578063d547741f1161007a578063d547741f146108a7578063da3ef23f146108d0578063e985e9c5146108f9578063f0fea4c814610936578063f234420814610961578063f2fde38b1461098c57610251565b8063b816d087146107c2578063b88d4fde146107eb578063c668286214610814578063c87b56dd1461083f578063d2d871e01461087c57610251565b8063a217fddf116100fd578063a217fddf146106f1578063a22cb4651461071c578063ae0cb91014610745578063b69f6df91461076e578063b7f70ac21461079957610251565b8063715018a61461060a5780638da5cb5b1461062157806391d148541461064c57806395d89b411461068957806397813980146106b457610251565b806336568abe116101d257806345de0d9b1161019657806345de0d9b146104ed57806355f804b3146105095780635bf5d54c146105325780636352211e146105655780636c0360eb146105a257806370a08231146105cd57610251565b806336568abe146104325780633ccfd60b1461045b57806340dbdd211461047257806342842e0e1461049b57806342966c68146104c457610251565b806318160ddd1161021957806318160ddd1461034d57806323b872dd14610378578063248a9ca3146103a1578063292005a2146103de5780632f2ff15d1461040957610251565b806301ffc9a71461025657806306fdde0314610293578063081812fc146102be578063095ea7b3146102fb5780631526e08714610324575b600080fd5b34801561026257600080fd5b5061027d60048036038101906102789190613b33565b6109b5565b60405161028a9190614128565b60405180910390f35b34801561029f57600080fd5b506102a86109c7565b6040516102b5919061415e565b60405180910390f35b3480156102ca57600080fd5b506102e560048036038101906102e09190613bd6565b610a59565b6040516102f291906140c1565b60405180910390f35b34801561030757600080fd5b50610322600480360381019061031d91906139a5565b610ad5565b005b34801561033057600080fd5b5061034b60048036038101906103469190613822565b610c7c565b005b34801561035957600080fd5b50610362610dd9565b60405161036f91906142a0565b60405180910390f35b34801561038457600080fd5b5061039f600480360381019061039a919061388f565b610df0565b005b3480156103ad57600080fd5b506103c860048036038101906103c39190613ac6565b610e00565b6040516103d59190614143565b60405180910390f35b3480156103ea57600080fd5b506103f3610e1f565b60405161040091906142a0565b60405180910390f35b34801561041557600080fd5b50610430600480360381019061042b9190613af3565b610e25565b005b34801561043e57600080fd5b5061045960048036038101906104549190613af3565b610e46565b005b34801561046757600080fd5b50610470610ec9565b005b34801561047e57600080fd5b5061049960048036038101906104949190613822565b610f03565b005b3480156104a757600080fd5b506104c260048036038101906104bd919061388f565b610fb0565b005b3480156104d057600080fd5b506104eb60048036038101906104e69190613bd6565b610fd0565b005b61050760048036038101906105029190613a66565b610fde565b005b34801561051557600080fd5b50610530600480360381019061052b9190613b8d565b61100c565b005b34801561053e57600080fd5b5061054761102e565b60405161055c9998979695949392919061430e565b60405180910390f35b34801561057157600080fd5b5061058c60048036038101906105879190613bd6565b611077565b60405161059991906140c1565b60405180910390f35b3480156105ae57600080fd5b506105b7611089565b6040516105c4919061415e565b60405180910390f35b3480156105d957600080fd5b506105f460048036038101906105ef9190613822565b611117565b60405161060191906142a0565b60405180910390f35b34801561061657600080fd5b5061061f6111ac565b005b34801561062d57600080fd5b506106366111c0565b60405161064391906140c1565b60405180910390f35b34801561065857600080fd5b50610673600480360381019061066e9190613af3565b6111ea565b6040516106809190614128565b60405180910390f35b34801561069557600080fd5b5061069e611254565b6040516106ab919061415e565b60405180910390f35b3480156106c057600080fd5b506106db60048036038101906106d69190613c03565b6112e6565b6040516106e891906142a0565b60405180910390f35b3480156106fd57600080fd5b5061070661130b565b6040516107139190614143565b60405180910390f35b34801561072857600080fd5b50610743600480360381019061073e9190613965565b611312565b005b34801561075157600080fd5b5061076c60048036038101906107679190613c43565b61148a565b005b34801561077a57600080fd5b506107836115f0565b60405161079091906140c1565b60405180910390f35b3480156107a557600080fd5b506107c060048036038101906107bb9190613822565b611616565b005b3480156107ce57600080fd5b506107e960048036038101906107e491906139e5565b6117ad565b005b3480156107f757600080fd5b50610812600480360381019061080d91906138e2565b6118cb565b005b34801561082057600080fd5b5061082961193e565b604051610836919061415e565b60405180910390f35b34801561084b57600080fd5b5061086660048036038101906108619190613bd6565b6119cc565b604051610873919061415e565b60405180910390f35b34801561088857600080fd5b50610891611ae9565b60405161089e91906140c1565b60405180910390f35b3480156108b357600080fd5b506108ce60048036038101906108c99190613af3565b611b0f565b005b3480156108dc57600080fd5b506108f760048036038101906108f29190613b8d565b611b30565b005b34801561090557600080fd5b50610920600480360381019061091b919061384f565b611b52565b60405161092d9190614128565b60405180910390f35b34801561094257600080fd5b5061094b611be6565b6040516109589190614128565b60405180910390f35b34801561096d57600080fd5b50610976611c07565b60405161098391906140c1565b60405180910390f35b34801561099857600080fd5b506109b360048036038101906109ae9190613822565b611c2d565b005b60006109c082611cb1565b9050919050565b6060600680546109d690614653565b80601f0160208091040260200160405190810160405280929190818152602001828054610a0290614653565b8015610a4f5780601f10610a2457610100808354040283529160200191610a4f565b820191906000526020600020905b815481529060010190602001808311610a3257829003601f168201915b5050505050905090565b6000610a6482611d43565b610a9a576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610ae082611da2565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610b48576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610b67611e70565b73ffffffffffffffffffffffffffffffffffffffff1614610bca57610b9381610b8e611e70565b611b52565b610bc9576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b82600a600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b610c896000801b336111ea565b610cc8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cbf906141c0565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610d59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5090614220565b60405180910390fd5b610d666000801b82610e25565b610d956000801b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16611b0f565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000610de3611e78565b6005546004540303905090565b610dfb838383611e81565b505050565b6000806000838152602001908152602001600020600101549050919050565b61271081565b610e2e82610e00565b610e3781612249565b610e41838361225d565b505050565b610e4e61233d565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ebb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb290614280565b60405180910390fd5b610ec58282612345565b5050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000479050610eff8282612426565b5050565b610f2d7f10ec476f95b2ac17b26abe61aa04eca5036baf3b2845e79fbbb0fd495127a458336111ea565b610f6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6390614260565b60405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610fcb838383604051806020016040528060008152506118cb565b505050565b610fdb81600161251a565b50565b610ff3838383610fec612834565b6000612847565b610ffd3382612b05565b6110073382612bc9565b505050565b611014612be7565b806018908051906020019061102a92919061351f565b5050565b600d8060000154908060010154908060020154908060030154908060040154908060050154908060060154908060070154908060080160009054906101000a900460ff16905089565b600061108282611da2565b9050919050565b6018805461109690614653565b80601f01602080910402602001604051908101604052809291908181526020018280546110c290614653565b801561110f5780601f106110e45761010080835404028352916020019161110f565b820191906000526020600020905b8154815290600101906020018083116110f257829003601f168201915b505050505081565b60008061112383612c65565b141561115b576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6111b4612be7565b6111be6000612c6f565b565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60606007805461126390614653565b80601f016020809104026020016040519081016040528092919081815260200182805461128f90614653565b80156112dc5780601f106112b1576101008083540402835291602001916112dc565b820191906000526020600020905b8154815290600101906020018083116112bf57829003601f168201915b5050505050905090565b6016602052816000526040600020602052806000526040600020600091509150505481565b6000801b81565b61131a611e70565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561137f576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600b600061138c611e70565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611439611e70565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161147e9190614128565b60405180910390a35050565b611492612be7565b838511156114cc576040517f7616640100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600d60040154905081156114ec576001816114e99190614485565b90505b6040518061012001604052808b81526020018a8152602001898152602001888152602001828152602001878152602001868152602001858152602001841515815250600d600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701556101008201518160080160006101000a81548160ff021916908315150217905550905050897f1eac6b5b91b97537498543fce5db2429ccdd3b13445b508d3142bfc51c8736c78a8a8a8a8a6040516115dc9594939291906142bb565b60405180910390a250505050505050505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6116236000801b336111ea565b611662576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611659906141c0565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156116f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ea90614220565b60405180910390fd5b61171d7f10ec476f95b2ac17b26abe61aa04eca5036baf3b2845e79fbbb0fd495127a45882610e25565b6117697f10ec476f95b2ac17b26abe61aa04eca5036baf3b2845e79fbbb0fd495127a458600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16611b0f565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6117b5612be7565b8181905084849050146117f4576040517f17e37b5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b848490508110156118c45761271083838381811061181857611817614781565b5b90506020020135611827612834565b6118319190614485565b1115611869576040517f1c07ee3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118b385858381811061187f5761187e614781565b5b90506020020160208101906118949190613822565b8484848181106118a7576118a6614781565b5b90506020020135612bc9565b806118bd906146b6565b90506117f7565b5050505050565b6118d6848484611e81565b60008373ffffffffffffffffffffffffffffffffffffffff163b146119385761190184848484612d35565b611937576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6017805461194b90614653565b80601f016020809104026020016040519081016040528092919081815260200182805461197790614653565b80156119c45780601f10611999576101008083540402835291602001916119c4565b820191906000526020600020905b8154815290600101906020018083116119a757829003601f168201915b505050505081565b60606119d782611d43565b611a0d576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060188054611a1c90614653565b905011611ab35760188054611a3090614653565b80601f0160208091040260200160405190810160405280929190818152602001828054611a5c90614653565b8015611aa95780601f10611a7e57610100808354040283529160200191611aa9565b820191906000526020600020905b815481529060010190602001808311611a8c57829003601f168201915b5050505050611ae2565b6018611abe83612e95565b6017604051602001611ad293929190614041565b6040516020818303038152906040525b9050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611b1882610e00565b611b2181612249565b611b2b8383612345565b505050565b611b38612be7565b8060179080519060200190611b4e92919061351f565b5050565b6000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000600d600501544210158015611c025750600d600601544211155b905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611c35612be7565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611ca5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9c906141a0565b60405180910390fd5b611cae81612c6f565b50565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611d0c57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611d3c5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600081611d4e611e78565b11158015611d5d575060045482105b8015611d9b575060007c0100000000000000000000000000000000000000000000000000000000600860008581526020019081526020016000205416145b9050919050565b60008082905080611db1611e78565b11611e3957600454811015611e385760006008600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082161415611e36575b6000811415611e2c576008600083600190039350838152602001908152602001600020549050611e01565b8092505050611e6b565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b60006001905090565b6000611e8c82611da2565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611ef3576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600a600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008573ffffffffffffffffffffffffffffffffffffffff16611f4c611e70565b73ffffffffffffffffffffffffffffffffffffffff161480611f7b5750611f7a86611f75611e70565b611b52565b5b80611fb85750611f89611e70565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b905080611ff1576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611ffc86612c65565b1415612034576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120418686866001612eef565b600061204c83612c65565b1461208857600a600085815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b61214f87612c65565b1717600860008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841614156121d95760006001850190506000600860008381526020019081526020016000205414156121d75760045481146121d6578360086000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46122418686866001612ef5565b505050505050565b61225a8161225561233d565b612efb565b50565b61226782826111ea565b61233957600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506122de61233d565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600033905090565b61234f82826111ea565b1561242257600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506123c761233d565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b80471015612469576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246090614200565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff168260405161248f90614072565b60006040518083038185875af1925050503d80600081146124cc576040519150601f19603f3d011682016040523d82523d6000602084013e6124d1565b606091505b5050905080612515576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161250c906141e0565b60405180910390fd5b505050565b600061252583611da2565b905060008190506000600a600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083156126325760008273ffffffffffffffffffffffffffffffffffffffff1661258b611e70565b73ffffffffffffffffffffffffffffffffffffffff1614806125ba57506125b9836125b4611e70565b611b52565b5b806125f757506125c8611e70565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b905080612630576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b612640826000876001612eef565b600061264b82612c65565b1461268757600a600086815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b600160806001901b03600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055507c02000000000000000000000000000000000000000000000000000000007c010000000000000000000000000000000000000000000000000000000060a042901b61272685612c65565b171717600860008781526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841614156127b15760006001860190506000600860008381526020019081526020016000205414156127af5760045481146127ae578360086000838152602001908152602001600020819055505b5b505b84600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461281b826000876001612ef5565b6005600081548092919060010191905055505050505050565b600061283e611e78565b60045403905090565b600033905060003490506000851480612861575061271085115b15612898576040517fccfad01800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128a0611be6565b6128d6576040517fa213ecf100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d6001015485856128e89190614485565b1115612920576040517fdfedbeec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060166000600d60040154815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000600d6002015411801561299e5750600d60020154868261299c9190614485565b115b156129d5576040517fbf7fbad100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d60080160009054906101000a900460ff16612aa0576000836040516020016129ff9190614026565b604051602081830303815290604052805190602001209050612a68898980806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600d6007015483612f98565b612a9e576040517f584a793800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b600084600d60030154612ab39190614535565b87612abe91906144db565b905080831015612afa576040517f6d35ff8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600060166000600d60040154815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181612b6b9190614485565b60166000600d60040154815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050565b612be3828260405180602001604052806000815250612faf565b5050565b612bef61233d565b73ffffffffffffffffffffffffffffffffffffffff16612c0d6111c0565b73ffffffffffffffffffffffffffffffffffffffff1614612c63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c5a90614240565b60405180910390fd5b565b6000819050919050565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612d5b611e70565b8786866040518563ffffffff1660e01b8152600401612d7d94939291906140dc565b602060405180830381600087803b158015612d9757600080fd5b505af1925050508015612dc857506040513d601f19601f82011682018060405250810190612dc59190613b60565b60015b612e42573d8060008114612df8576040519150601f19603f3d011682016040523d82523d6000602084013e612dfd565b606091505b50600081511415612e3a576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606080604051019050806040528082600183039250600a81066030018353600a810490505b8015612edb57600183039250600a81066030018353600a81049050612ebb565b508181036020830392508083525050919050565b50505050565b50505050565b612f0582826111ea565b612f9457612f2a8173ffffffffffffffffffffffffffffffffffffffff166014613241565b612f388360001c6020613241565b604051602001612f49929190614087565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f8b919061415e565b60405180910390fd5b5050565b600082612fa5858461347d565b1490509392505050565b600060045490506000612fc185612c65565b1415612ff9576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000831415613034576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6130416000858386612eef565b600160406001901b178302600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e16130a6600185146134d3565b901b60a042901b6130b686612c65565b1717600860008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b146131ba575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461316a6000878480600101955087612d35565b6131a0576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8082106130fb5782600454146131b557600080fd5b613225565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48082106131bb575b81600481905550505061323b6000858386612ef5565b50505050565b60606000600283600261325491906144db565b61325e9190614485565b67ffffffffffffffff811115613277576132766147b0565b5b6040519080825280601f01601f1916602001820160405280156132a95781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106132e1576132e0614781565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061334557613344614781565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261338591906144db565b61338f9190614485565b90505b600181111561342f577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106133d1576133d0614781565b5b1a60f81b8282815181106133e8576133e7614781565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c94508061342890614629565b9050613392565b5060008414613473576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161346a90614180565b60405180910390fd5b8091505092915050565b60008082905060005b84518110156134c8576134b3828683815181106134a6576134a5614781565b5b60200260200101516134dd565b915080806134c0906146b6565b915050613486565b508091505092915050565b6000819050919050565b60008183106134f5576134f08284613508565b613500565b6134ff8383613508565b5b905092915050565b600082600052816020526040600020905092915050565b82805461352b90614653565b90600052602060002090601f01602090048101928261354d5760008555613594565b82601f1061356657805160ff1916838001178555613594565b82800160010185558215613594579182015b82811115613593578251825591602001919060010190613578565b5b5090506135a191906135a5565b5090565b5b808211156135be5760008160009055506001016135a6565b5090565b60006135d56135d0846143c0565b61439b565b9050828152602081018484840111156135f1576135f06147ee565b5b6135fc8482856145e7565b509392505050565b6000613617613612846143f1565b61439b565b905082815260208101848484011115613633576136326147ee565b5b61363e8482856145e7565b509392505050565b60008135905061365581614a53565b92915050565b60008083601f840112613671576136706147e4565b5b8235905067ffffffffffffffff81111561368e5761368d6147df565b5b6020830191508360208202830111156136aa576136a96147e9565b5b9250929050565b60008083601f8401126136c7576136c66147e4565b5b8235905067ffffffffffffffff8111156136e4576136e36147df565b5b602083019150836020820283011115613700576136ff6147e9565b5b9250929050565b60008083601f84011261371d5761371c6147e4565b5b8235905067ffffffffffffffff81111561373a576137396147df565b5b602083019150836020820283011115613756576137556147e9565b5b9250929050565b60008135905061376c81614a6a565b92915050565b60008135905061378181614a81565b92915050565b60008135905061379681614a98565b92915050565b6000815190506137ab81614a98565b92915050565b600082601f8301126137c6576137c56147e4565b5b81356137d68482602086016135c2565b91505092915050565b600082601f8301126137f4576137f36147e4565b5b8135613804848260208601613604565b91505092915050565b60008135905061381c81614aaf565b92915050565b600060208284031215613838576138376147f8565b5b600061384684828501613646565b91505092915050565b60008060408385031215613866576138656147f8565b5b600061387485828601613646565b925050602061388585828601613646565b9150509250929050565b6000806000606084860312156138a8576138a76147f8565b5b60006138b686828701613646565b93505060206138c786828701613646565b92505060406138d88682870161380d565b9150509250925092565b600080600080608085870312156138fc576138fb6147f8565b5b600061390a87828801613646565b945050602061391b87828801613646565b935050604061392c8782880161380d565b925050606085013567ffffffffffffffff81111561394d5761394c6147f3565b5b613959878288016137b1565b91505092959194509250565b6000806040838503121561397c5761397b6147f8565b5b600061398a85828601613646565b925050602061399b8582860161375d565b9150509250929050565b600080604083850312156139bc576139bb6147f8565b5b60006139ca85828601613646565b92505060206139db8582860161380d565b9150509250929050565b600080600080604085870312156139ff576139fe6147f8565b5b600085013567ffffffffffffffff811115613a1d57613a1c6147f3565b5b613a298782880161365b565b9450945050602085013567ffffffffffffffff811115613a4c57613a4b6147f3565b5b613a5887828801613707565b925092505092959194509250565b600080600060408486031215613a7f57613a7e6147f8565b5b600084013567ffffffffffffffff811115613a9d57613a9c6147f3565b5b613aa9868287016136b1565b93509350506020613abc8682870161380d565b9150509250925092565b600060208284031215613adc57613adb6147f8565b5b6000613aea84828501613772565b91505092915050565b60008060408385031215613b0a57613b096147f8565b5b6000613b1885828601613772565b9250506020613b2985828601613646565b9150509250929050565b600060208284031215613b4957613b486147f8565b5b6000613b5784828501613787565b91505092915050565b600060208284031215613b7657613b756147f8565b5b6000613b848482850161379c565b91505092915050565b600060208284031215613ba357613ba26147f8565b5b600082013567ffffffffffffffff811115613bc157613bc06147f3565b5b613bcd848285016137df565b91505092915050565b600060208284031215613bec57613beb6147f8565b5b6000613bfa8482850161380d565b91505092915050565b60008060408385031215613c1a57613c196147f8565b5b6000613c288582860161380d565b9250506020613c3985828601613646565b9150509250929050565b60008060008060008060008060006101208a8c031215613c6657613c656147f8565b5b6000613c748c828d0161380d565b9950506020613c858c828d0161380d565b9850506040613c968c828d0161380d565b9750506060613ca78c828d0161380d565b9650506080613cb88c828d0161380d565b95505060a0613cc98c828d0161380d565b94505060c0613cda8c828d01613772565b93505060e0613ceb8c828d0161375d565b925050610100613cfd8c828d0161375d565b9150509295985092959850929598565b613d1681614569565b82525050565b613d2d613d2882614569565b6146ff565b82525050565b613d3c8161457b565b82525050565b613d4b81614587565b82525050565b6000613d5c82614437565b613d66818561444d565b9350613d768185602086016145f6565b613d7f816147fd565b840191505092915050565b6000613d9582614442565b613d9f8185614469565b9350613daf8185602086016145f6565b613db8816147fd565b840191505092915050565b6000613dce82614442565b613dd8818561447a565b9350613de88185602086016145f6565b80840191505092915050565b60008154613e0181614653565b613e0b818661447a565b94506001821660008114613e265760018114613e3757613e6a565b60ff19831686528186019350613e6a565b613e4085614422565b60005b83811015613e6257815481890152600182019150602081019050613e43565b838801955050505b50505092915050565b6000613e80602083614469565b9150613e8b8261481b565b602082019050919050565b6000613ea3602683614469565b9150613eae82614844565b604082019050919050565b6000613ec6601d83614469565b9150613ed182614893565b602082019050919050565b6000613ee9603a83614469565b9150613ef4826148bc565b604082019050919050565b6000613f0c601d83614469565b9150613f178261490b565b602082019050919050565b6000613f2f601d83614469565b9150613f3a82614934565b602082019050919050565b6000613f52602083614469565b9150613f5d8261495d565b602082019050919050565b6000613f75601a83614469565b9150613f8082614986565b602082019050919050565b6000613f9860008361445e565b9150613fa3826149af565b600082019050919050565b6000613fbb60178361447a565b9150613fc6826149b2565b601782019050919050565b6000613fde60118361447a565b9150613fe9826149db565b601182019050919050565b6000614001602f83614469565b915061400c82614a04565b604082019050919050565b614020816145dd565b82525050565b60006140328284613d1c565b60148201915081905092915050565b600061404d8286613df4565b91506140598285613dc3565b91506140658284613df4565b9150819050949350505050565b600061407d82613f8b565b9150819050919050565b600061409282613fae565b915061409e8285613dc3565b91506140a982613fd1565b91506140b58284613dc3565b91508190509392505050565b60006020820190506140d66000830184613d0d565b92915050565b60006080820190506140f16000830187613d0d565b6140fe6020830186613d0d565b61410b6040830185614017565b818103606083015261411d8184613d51565b905095945050505050565b600060208201905061413d6000830184613d33565b92915050565b60006020820190506141586000830184613d42565b92915050565b600060208201905081810360008301526141788184613d8a565b905092915050565b6000602082019050818103600083015261419981613e73565b9050919050565b600060208201905081810360008301526141b981613e96565b9050919050565b600060208201905081810360008301526141d981613eb9565b9050919050565b600060208201905081810360008301526141f981613edc565b9050919050565b6000602082019050818103600083015261421981613eff565b9050919050565b6000602082019050818103600083015261423981613f22565b9050919050565b6000602082019050818103600083015261425981613f45565b9050919050565b6000602082019050818103600083015261427981613f68565b9050919050565b6000602082019050818103600083015261429981613ff4565b9050919050565b60006020820190506142b56000830184614017565b92915050565b600060a0820190506142d06000830188614017565b6142dd6020830187614017565b6142ea6040830186614017565b6142f76060830185614017565b6143046080830184614017565b9695505050505050565b600061012082019050614324600083018c614017565b614331602083018b614017565b61433e604083018a614017565b61434b6060830189614017565b6143586080830188614017565b61436560a0830187614017565b61437260c0830186614017565b61437f60e0830185613d42565b61438d610100830184613d33565b9a9950505050505050505050565b60006143a56143b6565b90506143b18282614685565b919050565b6000604051905090565b600067ffffffffffffffff8211156143db576143da6147b0565b5b6143e4826147fd565b9050602081019050919050565b600067ffffffffffffffff82111561440c5761440b6147b0565b5b614415826147fd565b9050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000614490826145dd565b915061449b836145dd565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156144d0576144cf614723565b5b828201905092915050565b60006144e6826145dd565b91506144f1836145dd565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561452a57614529614723565b5b828202905092915050565b6000614540826145dd565b915061454b836145dd565b92508282101561455e5761455d614723565b5b828203905092915050565b6000614574826145bd565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156146145780820151818401526020810190506145f9565b83811115614623576000848401525b50505050565b6000614634826145dd565b9150600082141561464857614647614723565b5b600182039050919050565b6000600282049050600182168061466b57607f821691505b6020821081141561467f5761467e614752565b5b50919050565b61468e826147fd565b810181811067ffffffffffffffff821117156146ad576146ac6147b0565b5b80604052505050565b60006146c1826145dd565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156146f4576146f3614723565b5b600182019050919050565b600061470a82614711565b9050919050565b600061471c8261480e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f53706c69747465723a204e6f2041646d696e205065726d697373696f6e000000600082015250565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b7f53706c69747465723a2053686f756c6420626520646966666572656e74000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f53706c69747465723a204e6f2053706c697474657220526f6c65000000000000600082015250565b50565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b614a5c81614569565b8114614a6757600080fd5b50565b614a738161457b565b8114614a7e57600080fd5b50565b614a8a81614587565b8114614a9557600080fd5b50565b614aa181614591565b8114614aac57600080fd5b50565b614ab8816145dd565b8114614ac357600080fd5b5056fea2646970667358221220ac779afc29190c8bd853fb500a073e2684aa8cd8b1c4d8db8f0d3d486208725464736f6c63430008070033

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

0000000000000000000000002412c008ed3caabfbd2bf9ee73d9fdb6f2180a21000000000000000000000000e108a3b7ecb978b1e4fb4342e9296e134273d2d5

-----Decoded View---------------
Arg [0] : splitterAdmin (address): 0x2412C008ED3CAaBfBD2bF9Ee73D9fDB6F2180A21
Arg [1] : splitterAddress (address): 0xe108a3B7EcB978b1E4fB4342E9296e134273D2d5

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000002412c008ed3caabfbd2bf9ee73d9fdb6f2180a21
Arg [1] : 000000000000000000000000e108a3b7ecb978b1e4fb4342e9296e134273d2d5


Deployed Bytecode Sourcemap

81596:2277:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82896:210;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42848:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44916:204;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44376:474;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74255:354;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;36879:315;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45802:170;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68699:131;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81712:50;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69140:147;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70284:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73733:207;;;;;;;;;;;;;:::i;:::-;;73561:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;46043:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82811:77;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82532:271;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83543:98;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;77924:25;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;42637:144;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81813:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38504:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76499:103;;;;;;;;;;;;;:::i;:::-;;75851:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67159:147;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43017:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77958:70;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66264:49;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45192:308;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;78316:1138;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72780:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73948:299;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82029:495;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;46299:396;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81769:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83114:421;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72691:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69580:149;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83649:112;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;45571:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80921:192;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72737:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76757:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82896:210;83033:4;83062:36;83086:11;83062:23;:36::i;:::-;83055:43;;82896:210;;;:::o;42848:100::-;42902:13;42935:5;42928:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42848:100;:::o;44916:204::-;44984:7;45009:16;45017:7;45009;:16::i;:::-;45004:64;;45034:34;;;;;;;;;;;;;;45004:64;45088:15;:24;45104:7;45088:24;;;;;;;;;;;;;;;;;;;;;45081:31;;44916:204;;;:::o;44376:474::-;44449:13;44481:27;44500:7;44481:18;:27::i;:::-;44449:61;;44531:5;44525:11;;:2;:11;;;44521:48;;;44545:24;;;;;;;;;;;;;;44521:48;44609:5;44586:28;;:19;:17;:19::i;:::-;:28;;;44582:175;;44634:44;44651:5;44658:19;:17;:19::i;:::-;44634:16;:44::i;:::-;44629:128;;44706:35;;;;;;;;;;;;;;44629:128;44582:175;44796:2;44769:15;:24;44785:7;44769:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;44834:7;44830:2;44814:28;;44823:5;44814:28;;;;;;;;;;;;44438:412;44376:474;;:::o;74255:354::-;73437:39;66309:4;73445:18;;73465:10;73437:7;:39::i;:::-;73415:118;;;;;;;;;;;;:::i;:::-;;;;;;;;;74386:5:::1;74361:30;;:21;;;;;;;;;;;:30;;;;74339:109;;;;;;;;;;;;:::i;:::-;;;;;;;;;74461:36;66309:4;74471:18:::0;::::1;74491:5;74461:9;:36::i;:::-;74508:53;66309:4;74519:18:::0;::::1;74539:21;;;;;;;;;;;74508:10;:53::i;:::-;74596:5;74572:21;;:29;;;;;;;;;;;;;;;;;;74255:354:::0;:::o;36879:315::-;36932:7;37160:15;:13;:15::i;:::-;37145:12;;37129:13;;:28;:46;37122:53;;36879:315;:::o;45802:170::-;45936:28;45946:4;45952:2;45956:7;45936:9;:28::i;:::-;45802:170;;;:::o;68699:131::-;68773:7;68800:6;:12;68807:4;68800:12;;;;;;;;;;;:22;;;68793:29;;68699:131;;;:::o;81712:50::-;81757:5;81712:50;:::o;69140:147::-;69223:18;69236:4;69223:12;:18::i;:::-;66755:16;66766:4;66755:10;:16::i;:::-;69254:25:::1;69265:4;69271:7;69254:10;:25::i;:::-;69140:147:::0;;;:::o;70284:218::-;70391:12;:10;:12::i;:::-;70380:23;;:7;:23;;;70372:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;70468:26;70480:4;70486:7;70468:11;:26::i;:::-;70284:218;;:::o;73733:207::-;73771:25;73807:24;;;;;;;;;;;73771:61;;73843:15;73861:21;73843:39;;73895:37;73913:9;73924:7;73895:17;:37::i;:::-;73760:180;;73733:207::o;73561:164::-;73254:40;72863:27;73283:10;73254:7;:40::i;:::-;73232:116;;;;;;;;;;;;:::i;:::-;;;;;;;;;73701:16:::1;73674:24;;:43;;;;;;;;;;;;;;;;;;73561:164:::0;:::o;46043:185::-;46181:39;46198:4;46204:2;46208:7;46181:39;;;;;;;;;;;;:16;:39::i;:::-;46043:185;;;:::o;82811:77::-;82860:20;82866:7;82875:4;82860:5;:20::i;:::-;82811:77;:::o;82532:271::-;82645:53;82657:11;;82670:8;82680:14;:12;:14::i;:::-;82696:1;82645:11;:53::i;:::-;82709:44;82732:10;82744:8;82709:22;:44::i;:::-;82764:31;82774:10;82786:8;82764:9;:31::i;:::-;82532:271;;;:::o;83543:98::-;75737:13;:11;:13::i;:::-;83625:8:::1;83615:7;:18;;;;;;;;;;;;:::i;:::-;;83543:98:::0;:::o;77924:25::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;42637:144::-;42701:7;42744:27;42763:7;42744:18;:27::i;:::-;42721:52;;42637:144;;;:::o;81813:26::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;38504:234::-;38568:7;38620:1;38592:24;38610:5;38592:17;:24::i;:::-;:29;38588:70;;;38630:28;;;;;;;;;;;;;;38588:70;33843:13;38676:18;:25;38695:5;38676:25;;;;;;;;;;;;;;;;:54;38669:61;;38504:234;;;:::o;76499:103::-;75737:13;:11;:13::i;:::-;76564:30:::1;76591:1;76564:18;:30::i;:::-;76499:103::o:0;75851:87::-;75897:7;75924:6;;;;;;;;;;;75917:13;;75851:87;:::o;67159:147::-;67245:4;67269:6;:12;67276:4;67269:12;;;;;;;;;;;:20;;:29;67290:7;67269:29;;;;;;;;;;;;;;;;;;;;;;;;;67262:36;;67159:147;;;;:::o;43017:104::-;43073:13;43106:7;43099:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43017:104;:::o;77958:70::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;66264:49::-;66309:4;66264:49;;;:::o;45192:308::-;45303:19;:17;:19::i;:::-;45291:31;;:8;:31;;;45287:61;;;45331:17;;;;;;;;;;;;;;45287:61;45413:8;45361:18;:39;45380:19;:17;:19::i;:::-;45361:39;;;;;;;;;;;;;;;:49;45401:8;45361:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;45473:8;45437:55;;45452:19;:17;:19::i;:::-;45437:55;;;45483:8;45437:55;;;;;;:::i;:::-;;;;;;;;45192:308;;:::o;78316:1138::-;75737:13;:11;:13::i;:::-;78670:12:::1;78655;:27;78651:84;;;78706:17;;;;;;;;;;;;;;78651:84;78747:36;78786:12;:31;;;78747:70;;78834:18;78830:114;;;78931:1;78900:28;:32;;;;:::i;:::-;78869:63;;78830:114;78971:274;;;;;;;;78991:6;78971:274;;;;79012:11;78971:274;;;;79038:20;78971:274;;;;79073:5;78971:274;;;;79093:28;78971:274;;;;79136:12;78971:274;;;;79163:12;78971:274;;;;79190:20;78971:274;;;;79225:9;78971:274;;;;::::0;78956:12:::1;:289;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79294:6;79263:183;79315:11;79341:20;79376:5;79396:12;79423;79263:183;;;;;;;;;;:::i;:::-;;;;;;;;78640:814;78316:1138:::0;;;;;;;;;:::o;72780:29::-;;;;;;;;;;;;;:::o;73948:299::-;73437:39;66309:4;73445:18;;73465:10;73437:7;:39::i;:::-;73415:118;;;;;;;;;;;;:::i;:::-;;;;;;;;;74059:5:::1;74041:23;;:14;;;;;;;;;;;:23;;;;74033:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;74111:37;72863:27;74142:5;74111:9;:37::i;:::-;74159:47;72863:27;74191:14;;;;;;;;;;;74159:10;:47::i;:::-;74234:5;74217:14;;:22;;;;;;;;;;;;;;;;;;73948:299:::0;:::o;82029:495::-;75737:13;:11;:13::i;:::-;82189:8:::1;;:15;;82168:10;;:17;;:36;82164:97;;82228:21;;;;;;;;;;;;;;82164:97;82278:9;82273:244;82293:10;;:17;;82289:1;:21;82273:244;;;81757:5;82354:8;;82363:1;82354:11;;;;;;;:::i;:::-;;;;;;;;82337:14;:12;:14::i;:::-;:28;;;;:::i;:::-;82336:51;82332:120;;;82415:21;;;;;;;;;;;;;;82332:120;82468:37;82478:10;;82489:1;82478:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;82493:8;;82502:1;82493:11;;;;;;;:::i;:::-;;;;;;;;82468:9;:37::i;:::-;82312:3;;;;:::i;:::-;;;82273:244;;;;82029:495:::0;;;;:::o;46299:396::-;46466:28;46476:4;46482:2;46486:7;46466:9;:28::i;:::-;46527:1;46509:2;:14;;;:19;46505:183;;46548:56;46579:4;46585:2;46589:7;46598:5;46548:30;:56::i;:::-;46543:145;;46632:40;;;;;;;;;;;;;;46543:145;46505:183;46299:396;;;;:::o;81769:37::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;83114:421::-;83224:13;83260:16;83268:7;83260;:16::i;:::-;83255:59;;83285:29;;;;;;;;;;;;;;83255:59;83371:1;83353:7;83347:21;;;;;:::i;:::-;;;:25;:180;;83520:7;83347:180;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83438:7;83447:18;83457:7;83447:9;:18::i;:::-;83467:13;83421:60;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;83347:180;83327:200;;83114:421;;;:::o;72691:39::-;;;;;;;;;;;;;:::o;69580:149::-;69664:18;69677:4;69664:12;:18::i;:::-;66755:16;66766:4;66755:10;:16::i;:::-;69695:26:::1;69707:4;69713:7;69695:11;:26::i;:::-;69580:149:::0;;;:::o;83649:112::-;75737:13;:11;:13::i;:::-;83744:9:::1;83728:13;:25;;;;;;;;;;;;:::i;:::-;;83649:112:::0;:::o;45571:164::-;45668:4;45692:18;:25;45711:5;45692:25;;;;;;;;;;;;;;;:35;45718:8;45692:35;;;;;;;;;;;;;;;;;;;;;;;;;45685:42;;45571:164;;;;:::o;80921:192::-;80965:4;81021:12;:24;;;81002:15;:43;;:103;;;;;81081:12;:24;;;81062:15;:43;;81002:103;80982:123;;80921:192;:::o;72737:36::-;;;;;;;;;;;;;:::o;76757:201::-;75737:13;:11;:13::i;:::-;76866:1:::1;76846:22;;:8;:22;;;;76838:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;76922:28;76941:8;76922:18;:28::i;:::-;76757:201:::0;:::o;37825:615::-;37910:4;38225:10;38210:25;;:11;:25;;;;:102;;;;38302:10;38287:25;;:11;:25;;;;38210:102;:179;;;;38379:10;38364:25;;:11;:25;;;;38210:179;38190:199;;37825:615;;;:::o;46950:273::-;47007:4;47063:7;47044:15;:13;:15::i;:::-;:26;;:66;;;;;47097:13;;47087:7;:23;47044:66;:152;;;;;47195:1;34613:8;47148:17;:26;47166:7;47148:26;;;;;;;;;;;;:43;:48;47044:152;47024:172;;46950:273;;;:::o;40152:1129::-;40219:7;40239:12;40254:7;40239:22;;40322:4;40303:15;:13;:15::i;:::-;:23;40299:915;;40356:13;;40349:4;:20;40345:869;;;40394:14;40411:17;:23;40429:4;40411:23;;;;;;;;;;;;40394:40;;40527:1;34613:8;40500:6;:23;:28;40496:699;;;41019:113;41036:1;41026:6;:11;41019:113;;;41079:17;:25;41097:6;;;;;;;41079:25;;;;;;;;;;;;41070:34;;41019:113;;;41165:6;41158:13;;;;;;40496:699;40371:843;40345:869;40299:915;41242:31;;;;;;;;;;;;;;40152:1129;;;;:::o;61218:105::-;61278:7;61305:10;61298:17;;61218:105;:::o;83769:101::-;83834:7;83861:1;83854:8;;83769:101;:::o;52209:2654::-;52324:27;52354;52373:7;52354:18;:27::i;:::-;52324:57;;52439:4;52398:45;;52414:19;52398:45;;;52394:86;;52452:28;;;;;;;;;;;;;;52394:86;52493:23;52519:15;:24;52535:7;52519:24;;;;;;;;;;;;;;;;;;;;;52493:50;;52556:22;52605:4;52582:27;;:19;:17;:19::i;:::-;:27;;;:87;;;;52626:43;52643:4;52649:19;:17;:19::i;:::-;52626:16;:43::i;:::-;52582:87;:142;;;;52705:19;:17;:19::i;:::-;52686:38;;:15;:38;;;52582:142;52556:169;;52743:17;52738:66;;52769:35;;;;;;;;;;;;;;52738:66;52844:1;52819:21;52837:2;52819:17;:21::i;:::-;:26;52815:62;;;52854:23;;;;;;;;;;;;;;52815:62;52890:43;52912:4;52918:2;52922:7;52931:1;52890:21;:43::i;:::-;53041:1;53003:34;53021:15;53003:17;:34::i;:::-;:39;52999:103;;53066:15;:24;53082:7;53066:24;;;;;;;;;;;;53059:31;;;;;;;;;;;52999:103;53469:18;:24;53488:4;53469:24;;;;;;;;;;;;;;;;53467:26;;;;;;;;;;;;53538:18;:22;53557:2;53538:22;;;;;;;;;;;;;;;;53536:24;;;;;;;;;;;34895:8;34497:3;53919:15;:41;;53877:21;53895:2;53877:17;:21::i;:::-;:84;:128;53831:17;:26;53849:7;53831:26;;;;;;;;;;;:174;;;;54175:1;34895:8;54125:19;:46;:51;54121:626;;;54197:19;54229:1;54219:7;:11;54197:33;;54386:1;54352:17;:30;54370:11;54352:30;;;;;;;;;;;;:35;54348:384;;;54490:13;;54475:11;:28;54471:242;;54670:19;54637:17;:30;54655:11;54637:30;;;;;;;;;;;:52;;;;54471:242;54348:384;54178:569;54121:626;54794:7;54790:2;54775:27;;54784:4;54775:27;;;;;;;;;;;;54813:42;54834:4;54840:2;54844:7;54853:1;54813:20;:42::i;:::-;52313:2550;;;52209:2654;;;:::o;67610:105::-;67677:30;67688:4;67694:12;:10;:12::i;:::-;67677:10;:30::i;:::-;67610:105;:::o;71881:238::-;71965:22;71973:4;71979:7;71965;:22::i;:::-;71960:152;;72036:4;72004:6;:12;72011:4;72004:12;;;;;;;;;;;:20;;:29;72025:7;72004:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;72087:12;:10;:12::i;:::-;72060:40;;72078:7;72060:40;;72072:4;72060:40;;;;;;;;;;71960:152;71881:238;;:::o;64072:98::-;64125:7;64152:10;64145:17;;64072:98;:::o;72299:239::-;72383:22;72391:4;72397:7;72383;:22::i;:::-;72379:152;;;72454:5;72422:6;:12;72429:4;72422:12;;;;;;;;;;;:20;;:29;72443:7;72422:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;72506:12;:10;:12::i;:::-;72479:40;;72497:7;72479:40;;72491:4;72479:40;;;;;;;;;;72379:152;72299:239;;:::o;2494:317::-;2609:6;2584:21;:31;;2576:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;2663:12;2681:9;:14;;2703:6;2681:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2662:52;;;2733:7;2725:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;2565:246;2494:317;;:::o;55259:2936::-;55339:27;55369;55388:7;55369:18;:27::i;:::-;55339:57;;55409:12;55440:19;55409:52;;55472:23;55498:15;:24;55514:7;55498:24;;;;;;;;;;;;;;;;;;;;;55472:50;;55539:13;55535:306;;;55569:22;55618:4;55595:27;;:19;:17;:19::i;:::-;:27;;;:91;;;;55643:43;55660:4;55666:19;:17;:19::i;:::-;55643:16;:43::i;:::-;55595:91;:150;;;;55726:19;:17;:19::i;:::-;55707:38;;:15;:38;;;55595:150;55569:177;;55768:17;55763:66;;55794:35;;;;;;;;;;;;;;55763:66;55554:287;55535:306;55853:51;55875:4;55889:1;55893:7;55902:1;55853:21;:51::i;:::-;56012:1;55974:34;55992:15;55974:17;:34::i;:::-;:39;55970:103;;56037:15;:24;56053:7;56037:24;;;;;;;;;;;;56030:31;;;;;;;;;;;55970:103;56719:1;34106:3;56690:1;:25;;56689:31;56661:18;:24;56680:4;56661:24;;;;;;;;;;;;;;;;:59;;;;;;;;;;;34895:8;34613;34497:3;57048:15;:41;;57004:23;57022:4;57004:17;:23::i;:::-;:86;:120;:165;56958:17;:26;56976:7;56958:26;;;;;;;;;;;:211;;;;57339:1;34895:8;57289:19;:46;:51;57285:626;;;57361:19;57393:1;57383:7;:11;57361:33;;57550:1;57516:17;:30;57534:11;57516:30;;;;;;;;;;;;:35;57512:384;;;57654:13;;57639:11;:28;57635:242;;57834:19;57801:17;:30;57819:11;57801:30;;;;;;;;;;;:52;;;;57635:242;57512:384;57342:569;57285:626;57966:7;57962:1;57939:35;;57948:4;57939:35;;;;;;;;;;;;57985:50;58006:4;58020:1;58024:7;58033:1;57985:20;:50::i;:::-;58162:12;;:14;;;;;;;;;;;;;55328:2867;;;55259:2936;;:::o;37292:285::-;37339:7;37543:15;:13;:15::i;:::-;37527:13;;:31;37520:38;;37292:285;:::o;79462:1451::-;79646:14;79663:10;79646:27;;79684:18;79705:9;79684:30;;79746:1;79731:11;:16;:45;;;;78076:5;79751:11;:25;79731:45;79727:104;;;79800:19;;;;;;;;;;;;;;79727:104;79848:13;:11;:13::i;:::-;79843:67;;79885:13;;;;;;;;;;;;;;79843:67;79961:12;:23;;;79947:11;79926:18;:32;;;;:::i;:::-;:58;79922:121;;;80008:23;;;;;;;;;;;;;;79922:121;80055:17;80075:15;:48;80091:12;:31;;;80075:48;;;;;;;;;;;:80;80138:6;80075:80;;;;;;;;;;;;;;;;80055:100;;80211:1;80184:12;:24;;;:28;:95;;;;;80255:12;:24;;;80241:11;80229:9;:23;;;;:::i;:::-;:50;80184:95;80166:183;;;80313:24;;;;;;;;;;;;;;80166:183;80366:12;:21;;;;;;;;;;;;80361:366;;80404:12;80446:6;80429:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;80419:35;;;;;;80404:50;;80494:148;80535:12;;80494:148;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80570:12;:26;;;80619:4;80494:18;:148::i;:::-;80471:245;;80684:16;;;;;;;;;;;;;;80471:245;80389:338;80361:366;80739:23;80800:8;80780:12;:17;;;:28;;;;:::i;:::-;80765:11;:44;;;;:::i;:::-;80739:70;;80837:15;80824:10;:28;80820:86;;;80876:18;;;;;;;;;;;;;;80820:86;79635:1278;;;;79462:1451;;;;;:::o;81121:330::-;81224:17;81244:15;:48;81260:12;:31;;;81244:48;;;;;;;;;;;:80;81307:6;81244:80;;;;;;;;;;;;;;;;81224:100;;81432:11;81407:9;:36;;;;:::i;:::-;81335:15;:48;81351:12;:31;;;81335:48;;;;;;;;;;;:56;81384:6;81335:56;;;;;;;;;;;;;;;:108;;;;81213:238;81121:330;;:::o;47307:104::-;47376:27;47386:2;47390:8;47376:27;;;;;;;;;;;;:9;:27::i;:::-;47307:104;;:::o;76016:132::-;76091:12;:10;:12::i;:::-;76080:23;;:7;:5;:7::i;:::-;:23;;;76072:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;76016:132::o;43937:148::-;44001:14;44062:5;44052:15;;43937:148;;;:::o;77118:191::-;77192:16;77211:6;;;;;;;;;;;77192:25;;77237:8;77228:6;;:17;;;;;;;;;;;;;;;;;;77292:8;77261:40;;77282:8;77261:40;;;;;;;;;;;;77181:128;77118:191;:::o;58687:716::-;58850:4;58896:2;58871:45;;;58917:19;:17;:19::i;:::-;58938:4;58944:7;58953:5;58871:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;58867:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59171:1;59154:6;:13;:18;59150:235;;;59200:40;;;;;;;;;;;;;;59150:235;59343:6;59337:13;59328:6;59324:2;59320:15;59313:38;58867:529;59040:54;;;59030:64;;;:6;:64;;;;59023:71;;;58687:716;;;;;;:::o;61429:1959::-;61486:17;61907:3;61900:4;61894:11;61890:21;61883:28;;61998:3;61992:4;61985:17;62104:3;62561:5;62691:1;62686:3;62682:11;62675:18;;62828:2;62822:4;62818:13;62814:2;62810:22;62805:3;62797:36;62869:2;62863:4;62859:13;62851:21;;62452:682;62888:4;62452:682;;;63063:1;63058:3;63054:11;63047:18;;63114:2;63108:4;63104:13;63100:2;63096:22;63091:3;63083:36;62984:2;62978:4;62974:13;62966:21;;62452:682;;;62456:431;63185:3;63180;63176:13;63300:2;63295:3;63291:12;63284:19;;63363:6;63358:3;63351:19;61525:1856;;61429:1959;;;:::o;60051:159::-;;;;;:::o;60869:158::-;;;;;:::o;68005:505::-;68094:22;68102:4;68108:7;68094;:22::i;:::-;68089:414;;68282:41;68310:7;68282:41;;68320:2;68282:19;:41::i;:::-;68396:38;68424:4;68416:13;;68431:2;68396:19;:38::i;:::-;68187:270;;;;;;;;;:::i;:::-;;;;;;;;;;;;;68133:358;;;;;;;;;;;:::i;:::-;;;;;;;;68089:414;68005:505;;:::o;17256:190::-;17381:4;17434;17405:25;17418:5;17425:4;17405:12;:25::i;:::-;:33;17398:40;;17256:190;;;;;:::o;47784:2246::-;47907:20;47930:13;;47907:36;;47983:1;47958:21;47976:2;47958:17;:21::i;:::-;:26;47954:58;;;47993:19;;;;;;;;;;;;;;47954:58;48039:1;48027:8;:13;48023:44;;;48049:18;;;;;;;;;;;;;;48023:44;48080:61;48110:1;48114:2;48118:12;48132:8;48080:21;:61::i;:::-;48684:1;33980:2;48655:1;:25;;48654:31;48642:8;:44;48616:18;:22;48635:2;48616:22;;;;;;;;;;;;;;;;:70;;;;;;;;;;;34760:3;49085:29;49112:1;49100:8;:13;49085:14;:29::i;:::-;:56;;34497:3;49022:15;:41;;48980:21;48998:2;48980:17;:21::i;:::-;:84;:162;48929:17;:31;48947:12;48929:31;;;;;;;;;;;:213;;;;49159:20;49182:12;49159:35;;49209:11;49238:8;49223:12;:23;49209:37;;49285:1;49267:2;:14;;;:19;49263:635;;49307:313;49363:12;49359:2;49338:38;;49355:1;49338:38;;;;;;;;;;;;49404:69;49443:1;49447:2;49451:14;;;;;;49467:5;49404:30;:69::i;:::-;49399:174;;49509:40;;;;;;;;;;;;;;49399:174;49615:3;49600:12;:18;49307:313;;49701:12;49684:13;;:29;49680:43;;49715:8;;;49680:43;49263:635;;;49764:119;49820:14;;;;;;49816:2;49795:40;;49812:1;49795:40;;;;;;;;;;;;49878:3;49863:12;:18;49764:119;;49263:635;49928:12;49912:13;:28;;;;48393:1559;;49962:60;49991:1;49995:2;49999:12;50013:8;49962:20;:60::i;:::-;47896:2134;47784:2246;;;:::o;12230:451::-;12305:13;12331:19;12376:1;12367:6;12363:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;12353:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12331:47;;12389:15;:6;12396:1;12389:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;12415;:6;12422:1;12415:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;12446:9;12471:1;12462:6;12458:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;12446:26;;12441:135;12478:1;12474;:5;12441:135;;;12513:12;12534:3;12526:5;:11;12513:25;;;;;;;:::i;:::-;;;;;12501:6;12508:1;12501:9;;;;;;;;:::i;:::-;;;;;:37;;;;;;;;;;;12563:1;12553:11;;;;;12481:3;;;;:::i;:::-;;;12441:135;;;;12603:1;12594:5;:10;12586:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;12666:6;12652:21;;;12230:451;;;;:::o;18123:296::-;18206:7;18226:20;18249:4;18226:27;;18269:9;18264:118;18288:5;:12;18284:1;:16;18264:118;;;18337:33;18347:12;18361:5;18367:1;18361:8;;;;;;;;:::i;:::-;;;;;;;;18337:9;:33::i;:::-;18322:48;;18302:3;;;;;:::i;:::-;;;;18264:118;;;;18399:12;18392:19;;;18123:296;;;;:::o;44172:142::-;44230:14;44291:5;44281:15;;44172:142;;;:::o;24330:149::-;24393:7;24424:1;24420;:5;:51;;24451:20;24466:1;24469;24451:14;:20::i;:::-;24420:51;;;24428:20;24443:1;24446;24428:14;:20::i;:::-;24420:51;24413:58;;24330:149;;;;:::o;24487:268::-;24555:13;24662:1;24656:4;24649:15;24691:1;24685:4;24678:15;24732:4;24726;24716:21;24707:30;;24487:268;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::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;1003:568::-;1076:8;1086:6;1136:3;1129:4;1121:6;1117:17;1113:27;1103:122;;1144:79;;:::i;:::-;1103:122;1257:6;1244:20;1234:30;;1287:18;1279:6;1276:30;1273:117;;;1309:79;;:::i;:::-;1273:117;1423:4;1415:6;1411:17;1399:29;;1477:3;1469:4;1461:6;1457:17;1447:8;1443:32;1440:41;1437:128;;;1484:79;;:::i;:::-;1437:128;1003:568;;;;;:::o;1594:::-;1667:8;1677:6;1727:3;1720:4;1712:6;1708:17;1704:27;1694:122;;1735:79;;:::i;:::-;1694:122;1848:6;1835:20;1825:30;;1878:18;1870:6;1867:30;1864:117;;;1900:79;;:::i;:::-;1864:117;2014:4;2006:6;2002:17;1990:29;;2068:3;2060:4;2052:6;2048:17;2038:8;2034:32;2031:41;2028:128;;;2075:79;;:::i;:::-;2028:128;1594:568;;;;;:::o;2185:::-;2258:8;2268:6;2318:3;2311:4;2303:6;2299:17;2295:27;2285:122;;2326:79;;:::i;:::-;2285:122;2439:6;2426:20;2416:30;;2469:18;2461:6;2458:30;2455:117;;;2491:79;;:::i;:::-;2455:117;2605:4;2597:6;2593:17;2581:29;;2659:3;2651:4;2643:6;2639:17;2629:8;2625:32;2622:41;2619:128;;;2666:79;;:::i;:::-;2619:128;2185:568;;;;;:::o;2759:133::-;2802:5;2840:6;2827:20;2818:29;;2856:30;2880:5;2856:30;:::i;:::-;2759:133;;;;:::o;2898:139::-;2944:5;2982:6;2969:20;2960:29;;2998:33;3025:5;2998:33;:::i;:::-;2898:139;;;;:::o;3043:137::-;3088:5;3126:6;3113:20;3104:29;;3142:32;3168:5;3142:32;:::i;:::-;3043:137;;;;:::o;3186:141::-;3242:5;3273:6;3267:13;3258:22;;3289:32;3315:5;3289:32;:::i;:::-;3186:141;;;;:::o;3346:338::-;3401:5;3450:3;3443:4;3435:6;3431:17;3427:27;3417:122;;3458:79;;:::i;:::-;3417:122;3575:6;3562:20;3600:78;3674:3;3666:6;3659:4;3651:6;3647:17;3600:78;:::i;:::-;3591:87;;3407:277;3346:338;;;;:::o;3704:340::-;3760:5;3809:3;3802:4;3794:6;3790:17;3786:27;3776:122;;3817:79;;:::i;:::-;3776:122;3934:6;3921:20;3959:79;4034:3;4026:6;4019:4;4011:6;4007:17;3959:79;:::i;:::-;3950:88;;3766:278;3704:340;;;;:::o;4050:139::-;4096:5;4134:6;4121:20;4112:29;;4150:33;4177:5;4150:33;:::i;:::-;4050:139;;;;:::o;4195:329::-;4254:6;4303:2;4291:9;4282:7;4278:23;4274:32;4271:119;;;4309:79;;:::i;:::-;4271:119;4429:1;4454:53;4499:7;4490:6;4479:9;4475:22;4454:53;:::i;:::-;4444:63;;4400:117;4195:329;;;;:::o;4530:474::-;4598:6;4606;4655:2;4643:9;4634:7;4630:23;4626:32;4623:119;;;4661:79;;:::i;:::-;4623:119;4781:1;4806:53;4851:7;4842:6;4831:9;4827:22;4806:53;:::i;:::-;4796:63;;4752:117;4908:2;4934:53;4979:7;4970:6;4959:9;4955:22;4934:53;:::i;:::-;4924:63;;4879:118;4530:474;;;;;:::o;5010:619::-;5087:6;5095;5103;5152:2;5140:9;5131:7;5127:23;5123:32;5120:119;;;5158:79;;:::i;:::-;5120:119;5278:1;5303:53;5348:7;5339:6;5328:9;5324:22;5303:53;:::i;:::-;5293:63;;5249:117;5405:2;5431:53;5476:7;5467:6;5456:9;5452:22;5431:53;:::i;:::-;5421:63;;5376:118;5533:2;5559:53;5604:7;5595:6;5584:9;5580:22;5559:53;:::i;:::-;5549:63;;5504:118;5010:619;;;;;:::o;5635:943::-;5730:6;5738;5746;5754;5803:3;5791:9;5782:7;5778:23;5774:33;5771:120;;;5810:79;;:::i;:::-;5771:120;5930:1;5955:53;6000:7;5991:6;5980:9;5976:22;5955:53;:::i;:::-;5945:63;;5901:117;6057:2;6083:53;6128:7;6119:6;6108:9;6104:22;6083:53;:::i;:::-;6073:63;;6028:118;6185:2;6211:53;6256:7;6247:6;6236:9;6232:22;6211:53;:::i;:::-;6201:63;;6156:118;6341:2;6330:9;6326:18;6313:32;6372:18;6364:6;6361:30;6358:117;;;6394:79;;:::i;:::-;6358:117;6499:62;6553:7;6544:6;6533:9;6529:22;6499:62;:::i;:::-;6489:72;;6284:287;5635:943;;;;;;;:::o;6584:468::-;6649:6;6657;6706:2;6694:9;6685:7;6681:23;6677:32;6674:119;;;6712:79;;:::i;:::-;6674:119;6832:1;6857:53;6902:7;6893:6;6882:9;6878:22;6857:53;:::i;:::-;6847:63;;6803:117;6959:2;6985:50;7027:7;7018:6;7007:9;7003:22;6985:50;:::i;:::-;6975:60;;6930:115;6584:468;;;;;:::o;7058:474::-;7126:6;7134;7183:2;7171:9;7162:7;7158:23;7154:32;7151:119;;;7189:79;;:::i;:::-;7151:119;7309:1;7334:53;7379:7;7370:6;7359:9;7355:22;7334:53;:::i;:::-;7324:63;;7280:117;7436:2;7462:53;7507:7;7498:6;7487:9;7483:22;7462:53;:::i;:::-;7452:63;;7407:118;7058:474;;;;;:::o;7538:934::-;7660:6;7668;7676;7684;7733:2;7721:9;7712:7;7708:23;7704:32;7701:119;;;7739:79;;:::i;:::-;7701:119;7887:1;7876:9;7872:17;7859:31;7917:18;7909:6;7906:30;7903:117;;;7939:79;;:::i;:::-;7903:117;8052:80;8124:7;8115:6;8104:9;8100:22;8052:80;:::i;:::-;8034:98;;;;7830:312;8209:2;8198:9;8194:18;8181:32;8240:18;8232:6;8229:30;8226:117;;;8262:79;;:::i;:::-;8226:117;8375:80;8447:7;8438:6;8427:9;8423:22;8375:80;:::i;:::-;8357:98;;;;8152:313;7538:934;;;;;;;:::o;8478:704::-;8573:6;8581;8589;8638:2;8626:9;8617:7;8613:23;8609:32;8606:119;;;8644:79;;:::i;:::-;8606:119;8792:1;8781:9;8777:17;8764:31;8822:18;8814:6;8811:30;8808:117;;;8844:79;;:::i;:::-;8808:117;8957:80;9029:7;9020:6;9009:9;9005:22;8957:80;:::i;:::-;8939:98;;;;8735:312;9086:2;9112:53;9157:7;9148:6;9137:9;9133:22;9112:53;:::i;:::-;9102:63;;9057:118;8478:704;;;;;:::o;9188:329::-;9247:6;9296:2;9284:9;9275:7;9271:23;9267:32;9264:119;;;9302:79;;:::i;:::-;9264:119;9422:1;9447:53;9492:7;9483:6;9472:9;9468:22;9447:53;:::i;:::-;9437:63;;9393:117;9188:329;;;;:::o;9523:474::-;9591:6;9599;9648:2;9636:9;9627:7;9623:23;9619:32;9616:119;;;9654:79;;:::i;:::-;9616:119;9774:1;9799:53;9844:7;9835:6;9824:9;9820:22;9799:53;:::i;:::-;9789:63;;9745:117;9901:2;9927:53;9972:7;9963:6;9952:9;9948:22;9927:53;:::i;:::-;9917:63;;9872:118;9523:474;;;;;:::o;10003:327::-;10061:6;10110:2;10098:9;10089:7;10085:23;10081:32;10078:119;;;10116:79;;:::i;:::-;10078:119;10236:1;10261:52;10305:7;10296:6;10285:9;10281:22;10261:52;:::i;:::-;10251:62;;10207:116;10003:327;;;;:::o;10336:349::-;10405:6;10454:2;10442:9;10433:7;10429:23;10425:32;10422:119;;;10460:79;;:::i;:::-;10422:119;10580:1;10605:63;10660:7;10651:6;10640:9;10636:22;10605:63;:::i;:::-;10595:73;;10551:127;10336:349;;;;:::o;10691:509::-;10760:6;10809:2;10797:9;10788:7;10784:23;10780:32;10777:119;;;10815:79;;:::i;:::-;10777:119;10963:1;10952:9;10948:17;10935:31;10993:18;10985:6;10982:30;10979:117;;;11015:79;;:::i;:::-;10979:117;11120:63;11175:7;11166:6;11155:9;11151:22;11120:63;:::i;:::-;11110:73;;10906:287;10691:509;;;;:::o;11206:329::-;11265:6;11314:2;11302:9;11293:7;11289:23;11285:32;11282:119;;;11320:79;;:::i;:::-;11282:119;11440:1;11465:53;11510:7;11501:6;11490:9;11486:22;11465:53;:::i;:::-;11455:63;;11411:117;11206:329;;;;:::o;11541:474::-;11609:6;11617;11666:2;11654:9;11645:7;11641:23;11637:32;11634:119;;;11672:79;;:::i;:::-;11634:119;11792:1;11817:53;11862:7;11853:6;11842:9;11838:22;11817:53;:::i;:::-;11807:63;;11763:117;11919:2;11945:53;11990:7;11981:6;11970:9;11966:22;11945:53;:::i;:::-;11935:63;;11890:118;11541:474;;;;;:::o;12021:1483::-;12146:6;12154;12162;12170;12178;12186;12194;12202;12210;12259:3;12247:9;12238:7;12234:23;12230:33;12227:120;;;12266:79;;:::i;:::-;12227:120;12386:1;12411:53;12456:7;12447:6;12436:9;12432:22;12411:53;:::i;:::-;12401:63;;12357:117;12513:2;12539:53;12584:7;12575:6;12564:9;12560:22;12539:53;:::i;:::-;12529:63;;12484:118;12641:2;12667:53;12712:7;12703:6;12692:9;12688:22;12667:53;:::i;:::-;12657:63;;12612:118;12769:2;12795:53;12840:7;12831:6;12820:9;12816:22;12795:53;:::i;:::-;12785:63;;12740:118;12897:3;12924:53;12969:7;12960:6;12949:9;12945:22;12924:53;:::i;:::-;12914:63;;12868:119;13026:3;13053:53;13098:7;13089:6;13078:9;13074:22;13053:53;:::i;:::-;13043:63;;12997:119;13155:3;13182:53;13227:7;13218:6;13207:9;13203:22;13182:53;:::i;:::-;13172:63;;13126:119;13284:3;13311:50;13353:7;13344:6;13333:9;13329:22;13311:50;:::i;:::-;13301:60;;13255:116;13410:3;13437:50;13479:7;13470:6;13459:9;13455:22;13437:50;:::i;:::-;13427:60;;13381:116;12021:1483;;;;;;;;;;;:::o;13510:118::-;13597:24;13615:5;13597:24;:::i;:::-;13592:3;13585:37;13510:118;;:::o;13634:157::-;13739:45;13759:24;13777:5;13759:24;:::i;:::-;13739:45;:::i;:::-;13734:3;13727:58;13634:157;;:::o;13797:109::-;13878:21;13893:5;13878:21;:::i;:::-;13873:3;13866:34;13797:109;;:::o;13912:118::-;13999:24;14017:5;13999:24;:::i;:::-;13994:3;13987:37;13912:118;;:::o;14036:360::-;14122:3;14150:38;14182:5;14150:38;:::i;:::-;14204:70;14267:6;14262:3;14204:70;:::i;:::-;14197:77;;14283:52;14328:6;14323:3;14316:4;14309:5;14305:16;14283:52;:::i;:::-;14360:29;14382:6;14360:29;:::i;:::-;14355:3;14351:39;14344:46;;14126:270;14036:360;;;;:::o;14402:364::-;14490:3;14518:39;14551:5;14518:39;:::i;:::-;14573:71;14637:6;14632:3;14573:71;:::i;:::-;14566:78;;14653:52;14698:6;14693:3;14686:4;14679:5;14675:16;14653:52;:::i;:::-;14730:29;14752:6;14730:29;:::i;:::-;14725:3;14721:39;14714:46;;14494:272;14402:364;;;;:::o;14772:377::-;14878:3;14906:39;14939:5;14906:39;:::i;:::-;14961:89;15043:6;15038:3;14961:89;:::i;:::-;14954:96;;15059:52;15104:6;15099:3;15092:4;15085:5;15081:16;15059:52;:::i;:::-;15136:6;15131:3;15127:16;15120:23;;14882:267;14772:377;;;;:::o;15179:845::-;15282:3;15319:5;15313:12;15348:36;15374:9;15348:36;:::i;:::-;15400:89;15482:6;15477:3;15400:89;:::i;:::-;15393:96;;15520:1;15509:9;15505:17;15536:1;15531:137;;;;15682:1;15677:341;;;;15498:520;;15531:137;15615:4;15611:9;15600;15596:25;15591:3;15584:38;15651:6;15646:3;15642:16;15635:23;;15531:137;;15677:341;15744:38;15776:5;15744:38;:::i;:::-;15804:1;15818:154;15832:6;15829:1;15826:13;15818:154;;;15906:7;15900:14;15896:1;15891:3;15887:11;15880:35;15956:1;15947:7;15943:15;15932:26;;15854:4;15851:1;15847:12;15842:17;;15818:154;;;16001:6;15996:3;15992:16;15985:23;;15684:334;;15498:520;;15286:738;;15179:845;;;;:::o;16030:366::-;16172:3;16193:67;16257:2;16252:3;16193:67;:::i;:::-;16186:74;;16269:93;16358:3;16269:93;:::i;:::-;16387:2;16382:3;16378:12;16371:19;;16030:366;;;:::o;16402:::-;16544:3;16565:67;16629:2;16624:3;16565:67;:::i;:::-;16558:74;;16641:93;16730:3;16641:93;:::i;:::-;16759:2;16754:3;16750:12;16743:19;;16402:366;;;:::o;16774:::-;16916:3;16937:67;17001:2;16996:3;16937:67;:::i;:::-;16930:74;;17013:93;17102:3;17013:93;:::i;:::-;17131:2;17126:3;17122:12;17115:19;;16774:366;;;:::o;17146:::-;17288:3;17309:67;17373:2;17368:3;17309:67;:::i;:::-;17302:74;;17385:93;17474:3;17385:93;:::i;:::-;17503:2;17498:3;17494:12;17487:19;;17146:366;;;:::o;17518:::-;17660:3;17681:67;17745:2;17740:3;17681:67;:::i;:::-;17674:74;;17757:93;17846:3;17757:93;:::i;:::-;17875:2;17870:3;17866:12;17859:19;;17518:366;;;:::o;17890:::-;18032:3;18053:67;18117:2;18112:3;18053:67;:::i;:::-;18046:74;;18129:93;18218:3;18129:93;:::i;:::-;18247:2;18242:3;18238:12;18231:19;;17890:366;;;:::o;18262:::-;18404:3;18425:67;18489:2;18484:3;18425:67;:::i;:::-;18418:74;;18501:93;18590:3;18501:93;:::i;:::-;18619:2;18614:3;18610:12;18603:19;;18262:366;;;:::o;18634:::-;18776:3;18797:67;18861:2;18856:3;18797:67;:::i;:::-;18790:74;;18873:93;18962:3;18873:93;:::i;:::-;18991:2;18986:3;18982:12;18975:19;;18634:366;;;:::o;19006:398::-;19165:3;19186:83;19267:1;19262:3;19186:83;:::i;:::-;19179:90;;19278:93;19367:3;19278:93;:::i;:::-;19396:1;19391:3;19387:11;19380:18;;19006:398;;;:::o;19410:402::-;19570:3;19591:85;19673:2;19668:3;19591:85;:::i;:::-;19584:92;;19685:93;19774:3;19685:93;:::i;:::-;19803:2;19798:3;19794:12;19787:19;;19410:402;;;:::o;19818:::-;19978:3;19999:85;20081:2;20076:3;19999:85;:::i;:::-;19992:92;;20093:93;20182:3;20093:93;:::i;:::-;20211:2;20206:3;20202:12;20195:19;;19818:402;;;:::o;20226:366::-;20368:3;20389:67;20453:2;20448:3;20389:67;:::i;:::-;20382:74;;20465:93;20554:3;20465:93;:::i;:::-;20583:2;20578:3;20574:12;20567:19;;20226:366;;;:::o;20598:118::-;20685:24;20703:5;20685:24;:::i;:::-;20680:3;20673:37;20598:118;;:::o;20722:256::-;20834:3;20849:75;20920:3;20911:6;20849:75;:::i;:::-;20949:2;20944:3;20940:12;20933:19;;20969:3;20962:10;;20722:256;;;;:::o;20984:583::-;21206:3;21228:92;21316:3;21307:6;21228:92;:::i;:::-;21221:99;;21337:95;21428:3;21419:6;21337:95;:::i;:::-;21330:102;;21449:92;21537:3;21528:6;21449:92;:::i;:::-;21442:99;;21558:3;21551:10;;20984:583;;;;;;:::o;21573:379::-;21757:3;21779:147;21922:3;21779:147;:::i;:::-;21772:154;;21943:3;21936:10;;21573:379;;;:::o;21958:967::-;22340:3;22362:148;22506:3;22362:148;:::i;:::-;22355:155;;22527:95;22618:3;22609:6;22527:95;:::i;:::-;22520:102;;22639:148;22783:3;22639:148;:::i;:::-;22632:155;;22804:95;22895:3;22886:6;22804:95;:::i;:::-;22797:102;;22916:3;22909:10;;21958:967;;;;;:::o;22931:222::-;23024:4;23062:2;23051:9;23047:18;23039:26;;23075:71;23143:1;23132:9;23128:17;23119:6;23075:71;:::i;:::-;22931:222;;;;:::o;23159:640::-;23354:4;23392:3;23381:9;23377:19;23369:27;;23406:71;23474:1;23463:9;23459:17;23450:6;23406:71;:::i;:::-;23487:72;23555:2;23544:9;23540:18;23531:6;23487:72;:::i;:::-;23569;23637:2;23626:9;23622:18;23613:6;23569:72;:::i;:::-;23688:9;23682:4;23678:20;23673:2;23662:9;23658:18;23651:48;23716:76;23787:4;23778:6;23716:76;:::i;:::-;23708:84;;23159:640;;;;;;;:::o;23805:210::-;23892:4;23930:2;23919:9;23915:18;23907:26;;23943:65;24005:1;23994:9;23990:17;23981:6;23943:65;:::i;:::-;23805:210;;;;:::o;24021:222::-;24114:4;24152:2;24141:9;24137:18;24129:26;;24165:71;24233:1;24222:9;24218:17;24209:6;24165:71;:::i;:::-;24021:222;;;;:::o;24249:313::-;24362:4;24400:2;24389:9;24385:18;24377:26;;24449:9;24443:4;24439:20;24435:1;24424:9;24420:17;24413:47;24477:78;24550:4;24541:6;24477:78;:::i;:::-;24469:86;;24249:313;;;;:::o;24568:419::-;24734:4;24772:2;24761:9;24757:18;24749:26;;24821:9;24815:4;24811:20;24807:1;24796:9;24792:17;24785:47;24849:131;24975:4;24849:131;:::i;:::-;24841:139;;24568:419;;;:::o;24993:::-;25159:4;25197:2;25186:9;25182:18;25174:26;;25246:9;25240:4;25236:20;25232:1;25221:9;25217:17;25210:47;25274:131;25400:4;25274:131;:::i;:::-;25266:139;;24993:419;;;:::o;25418:::-;25584:4;25622:2;25611:9;25607:18;25599:26;;25671:9;25665:4;25661:20;25657:1;25646:9;25642:17;25635:47;25699:131;25825:4;25699:131;:::i;:::-;25691:139;;25418:419;;;:::o;25843:::-;26009:4;26047:2;26036:9;26032:18;26024:26;;26096:9;26090:4;26086:20;26082:1;26071:9;26067:17;26060:47;26124:131;26250:4;26124:131;:::i;:::-;26116:139;;25843:419;;;:::o;26268:::-;26434:4;26472:2;26461:9;26457:18;26449:26;;26521:9;26515:4;26511:20;26507:1;26496:9;26492:17;26485:47;26549:131;26675:4;26549:131;:::i;:::-;26541:139;;26268:419;;;:::o;26693:::-;26859:4;26897:2;26886:9;26882:18;26874:26;;26946:9;26940:4;26936:20;26932:1;26921:9;26917:17;26910:47;26974:131;27100:4;26974:131;:::i;:::-;26966:139;;26693:419;;;:::o;27118:::-;27284:4;27322:2;27311:9;27307:18;27299:26;;27371:9;27365:4;27361:20;27357:1;27346:9;27342:17;27335:47;27399:131;27525:4;27399:131;:::i;:::-;27391:139;;27118:419;;;:::o;27543:::-;27709:4;27747:2;27736:9;27732:18;27724:26;;27796:9;27790:4;27786:20;27782:1;27771:9;27767:17;27760:47;27824:131;27950:4;27824:131;:::i;:::-;27816:139;;27543:419;;;:::o;27968:::-;28134:4;28172:2;28161:9;28157:18;28149:26;;28221:9;28215:4;28211:20;28207:1;28196:9;28192:17;28185:47;28249:131;28375:4;28249:131;:::i;:::-;28241:139;;27968:419;;;:::o;28393:222::-;28486:4;28524:2;28513:9;28509:18;28501:26;;28537:71;28605:1;28594:9;28590:17;28581:6;28537:71;:::i;:::-;28393:222;;;;:::o;28621:664::-;28826:4;28864:3;28853:9;28849:19;28841:27;;28878:71;28946:1;28935:9;28931:17;28922:6;28878:71;:::i;:::-;28959:72;29027:2;29016:9;29012:18;29003:6;28959:72;:::i;:::-;29041;29109:2;29098:9;29094:18;29085:6;29041:72;:::i;:::-;29123;29191:2;29180:9;29176:18;29167:6;29123:72;:::i;:::-;29205:73;29273:3;29262:9;29258:19;29249:6;29205:73;:::i;:::-;28621:664;;;;;;;;:::o;29291:1096::-;29602:4;29640:3;29629:9;29625:19;29617:27;;29654:71;29722:1;29711:9;29707:17;29698:6;29654:71;:::i;:::-;29735:72;29803:2;29792:9;29788:18;29779:6;29735:72;:::i;:::-;29817;29885:2;29874:9;29870:18;29861:6;29817:72;:::i;:::-;29899;29967:2;29956:9;29952:18;29943:6;29899:72;:::i;:::-;29981:73;30049:3;30038:9;30034:19;30025:6;29981:73;:::i;:::-;30064;30132:3;30121:9;30117:19;30108:6;30064:73;:::i;:::-;30147;30215:3;30204:9;30200:19;30191:6;30147:73;:::i;:::-;30230;30298:3;30287:9;30283:19;30274:6;30230:73;:::i;:::-;30313:67;30375:3;30364:9;30360:19;30351:6;30313:67;:::i;:::-;29291:1096;;;;;;;;;;;;:::o;30393:129::-;30427:6;30454:20;;:::i;:::-;30444:30;;30483:33;30511:4;30503:6;30483:33;:::i;:::-;30393:129;;;:::o;30528:75::-;30561:6;30594:2;30588:9;30578:19;;30528:75;:::o;30609:307::-;30670:4;30760:18;30752:6;30749:30;30746:56;;;30782:18;;:::i;:::-;30746:56;30820:29;30842:6;30820:29;:::i;:::-;30812:37;;30904:4;30898;30894:15;30886:23;;30609:307;;;:::o;30922:308::-;30984:4;31074:18;31066:6;31063:30;31060:56;;;31096:18;;:::i;:::-;31060:56;31134:29;31156:6;31134:29;:::i;:::-;31126:37;;31218:4;31212;31208:15;31200:23;;30922:308;;;:::o;31236:141::-;31285:4;31308:3;31300:11;;31331:3;31328:1;31321:14;31365:4;31362:1;31352:18;31344:26;;31236:141;;;:::o;31383:98::-;31434:6;31468:5;31462:12;31452:22;;31383:98;;;:::o;31487:99::-;31539:6;31573:5;31567:12;31557:22;;31487:99;;;:::o;31592:168::-;31675:11;31709:6;31704:3;31697:19;31749:4;31744:3;31740:14;31725:29;;31592:168;;;;:::o;31766:147::-;31867:11;31904:3;31889:18;;31766:147;;;;:::o;31919:169::-;32003:11;32037:6;32032:3;32025:19;32077:4;32072:3;32068:14;32053:29;;31919:169;;;;:::o;32094:148::-;32196:11;32233:3;32218:18;;32094:148;;;;:::o;32248:305::-;32288:3;32307:20;32325:1;32307:20;:::i;:::-;32302:25;;32341:20;32359:1;32341:20;:::i;:::-;32336:25;;32495:1;32427:66;32423:74;32420:1;32417:81;32414:107;;;32501:18;;:::i;:::-;32414:107;32545:1;32542;32538:9;32531:16;;32248:305;;;;:::o;32559:348::-;32599:7;32622:20;32640:1;32622:20;:::i;:::-;32617:25;;32656:20;32674:1;32656:20;:::i;:::-;32651:25;;32844:1;32776:66;32772:74;32769:1;32766:81;32761:1;32754:9;32747:17;32743:105;32740:131;;;32851:18;;:::i;:::-;32740:131;32899:1;32896;32892:9;32881:20;;32559:348;;;;:::o;32913:191::-;32953:4;32973:20;32991:1;32973:20;:::i;:::-;32968:25;;33007:20;33025:1;33007:20;:::i;:::-;33002:25;;33046:1;33043;33040:8;33037:34;;;33051:18;;:::i;:::-;33037:34;33096:1;33093;33089:9;33081:17;;32913:191;;;;:::o;33110:96::-;33147:7;33176:24;33194:5;33176:24;:::i;:::-;33165:35;;33110:96;;;:::o;33212:90::-;33246:7;33289:5;33282:13;33275:21;33264:32;;33212:90;;;:::o;33308:77::-;33345:7;33374:5;33363:16;;33308:77;;;:::o;33391:149::-;33427:7;33467:66;33460:5;33456:78;33445:89;;33391:149;;;:::o;33546:126::-;33583:7;33623:42;33616:5;33612:54;33601:65;;33546:126;;;:::o;33678:77::-;33715:7;33744:5;33733:16;;33678:77;;;:::o;33761:154::-;33845:6;33840:3;33835;33822:30;33907:1;33898:6;33893:3;33889:16;33882:27;33761:154;;;:::o;33921:307::-;33989:1;33999:113;34013:6;34010:1;34007:13;33999:113;;;34098:1;34093:3;34089:11;34083:18;34079:1;34074:3;34070:11;34063:39;34035:2;34032:1;34028:10;34023:15;;33999:113;;;34130:6;34127:1;34124:13;34121:101;;;34210:1;34201:6;34196:3;34192:16;34185:27;34121:101;33970:258;33921:307;;;:::o;34234:171::-;34273:3;34296:24;34314:5;34296:24;:::i;:::-;34287:33;;34342:4;34335:5;34332:15;34329:41;;;34350:18;;:::i;:::-;34329:41;34397:1;34390:5;34386:13;34379:20;;34234:171;;;:::o;34411:320::-;34455:6;34492:1;34486:4;34482:12;34472:22;;34539:1;34533:4;34529:12;34560:18;34550:81;;34616:4;34608:6;34604:17;34594:27;;34550:81;34678:2;34670:6;34667:14;34647:18;34644:38;34641:84;;;34697:18;;:::i;:::-;34641:84;34462:269;34411:320;;;:::o;34737:281::-;34820:27;34842:4;34820:27;:::i;:::-;34812:6;34808:40;34950:6;34938:10;34935:22;34914:18;34902:10;34899:34;34896:62;34893:88;;;34961:18;;:::i;:::-;34893:88;35001:10;34997:2;34990:22;34780:238;34737:281;;:::o;35024:233::-;35063:3;35086:24;35104:5;35086:24;:::i;:::-;35077:33;;35132:66;35125:5;35122:77;35119:103;;;35202:18;;:::i;:::-;35119:103;35249:1;35242:5;35238:13;35231:20;;35024:233;;;:::o;35263:100::-;35302:7;35331:26;35351:5;35331:26;:::i;:::-;35320:37;;35263:100;;;:::o;35369:94::-;35408:7;35437:20;35451:5;35437:20;:::i;:::-;35426:31;;35369:94;;;:::o;35469:180::-;35517:77;35514:1;35507:88;35614:4;35611:1;35604:15;35638:4;35635:1;35628:15;35655:180;35703:77;35700:1;35693:88;35800:4;35797:1;35790:15;35824:4;35821:1;35814:15;35841:180;35889:77;35886:1;35879:88;35986:4;35983:1;35976:15;36010:4;36007:1;36000:15;36027:180;36075:77;36072:1;36065:88;36172:4;36169:1;36162:15;36196:4;36193:1;36186:15;36213:117;36322:1;36319;36312:12;36336:117;36445:1;36442;36435:12;36459:117;36568:1;36565;36558:12;36582:117;36691:1;36688;36681:12;36705:117;36814:1;36811;36804:12;36828:117;36937:1;36934;36927:12;36951:102;36992:6;37043:2;37039:7;37034:2;37027:5;37023:14;37019:28;37009:38;;36951:102;;;:::o;37059:94::-;37092:8;37140:5;37136:2;37132:14;37111:35;;37059:94;;;:::o;37159:182::-;37299:34;37295:1;37287:6;37283:14;37276:58;37159:182;:::o;37347:225::-;37487:34;37483:1;37475:6;37471:14;37464:58;37556:8;37551:2;37543:6;37539:15;37532:33;37347:225;:::o;37578:179::-;37718:31;37714:1;37706:6;37702:14;37695:55;37578:179;:::o;37763:245::-;37903:34;37899:1;37891:6;37887:14;37880:58;37972:28;37967:2;37959:6;37955:15;37948:53;37763:245;:::o;38014:179::-;38154:31;38150:1;38142:6;38138:14;38131:55;38014:179;:::o;38199:::-;38339:31;38335:1;38327:6;38323:14;38316:55;38199:179;:::o;38384:182::-;38524:34;38520:1;38512:6;38508:14;38501:58;38384:182;:::o;38572:176::-;38712:28;38708:1;38700:6;38696:14;38689:52;38572:176;:::o;38754:114::-;;:::o;38874:173::-;39014:25;39010:1;39002:6;38998:14;38991:49;38874:173;:::o;39053:167::-;39193:19;39189:1;39181:6;39177:14;39170:43;39053:167;:::o;39226:234::-;39366:34;39362:1;39354:6;39350:14;39343:58;39435:17;39430:2;39422:6;39418:15;39411:42;39226:234;:::o;39466:122::-;39539:24;39557:5;39539:24;:::i;:::-;39532:5;39529:35;39519:63;;39578:1;39575;39568:12;39519:63;39466:122;:::o;39594:116::-;39664:21;39679:5;39664:21;:::i;:::-;39657:5;39654:32;39644:60;;39700:1;39697;39690:12;39644:60;39594:116;:::o;39716:122::-;39789:24;39807:5;39789:24;:::i;:::-;39782:5;39779:35;39769:63;;39828:1;39825;39818:12;39769:63;39716:122;:::o;39844:120::-;39916:23;39933:5;39916:23;:::i;:::-;39909:5;39906:34;39896:62;;39954:1;39951;39944:12;39896:62;39844:120;:::o;39970:122::-;40043:24;40061:5;40043:24;:::i;:::-;40036:5;40033:35;40023:63;;40082:1;40079;40072:12;40023:63;39970:122;:::o

Swarm Source

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