ETH Price: $3,487.62 (+5.35%)

Token

RFoxSquad (RFS)
 

Overview

Max Total Supply

3,000 RFS

Holders

1,333

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
4 RFS
0xc3b74447d51df2ceb9e330fe3a733fb8b470382b
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:
RandomFoxes

Compiler Version
v0.8.12+commit.f00d7308

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-10-22
*/

// SPDX-License-Identifier: MIT

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol

// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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

// File: contracts/witch.sol

// 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/witch.sol

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: https://github.com/chiru-labs/ERC721A/blob/main/contracts/ERC721A.sol

// ERC721A Contracts v3.3.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 (owner == address(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 (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // 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 (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // 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();

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

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

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        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));

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

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

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

        // Clear approvals from the previous owner.
        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: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol

// OpenZeppelin Contracts v4.4.1 (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: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/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: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol

// OpenZeppelin Contracts v4.4.1 (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 Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

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

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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol

// OpenZeppelin Contracts (last updated v4.5.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"
            );
    }

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

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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721Receiver.sol

// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/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: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/ERC165.sol
//hera
// 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: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol

// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * 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 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);
}

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/IERC721Metadata.sol

// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol

// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

        _afterTokenTransfer(address(0), to, tokenId);
    }

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

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

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

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

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

        _afterTokenTransfer(owner, address(0), tokenId);
    }

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

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

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

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

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

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

pragma solidity ^0.8.0;

contract RandomFoxes is ERC721A, Ownable, ReentrancyGuard {
    using Strings for uint256;

    string private baseURI;

    uint256 public maxPerWallet = 4;
    uint256 public price = 0.0066 ether;

    uint256 public maxFreePerWallet = 1;

    uint256 public maxSupply = 3400; // 67 reserved for team
    bool public mintEnabled = false;
    bool public publicEnabled = false;

    bytes32 vipRoot;
    bytes32 whitelistRoot;

    string public hiddenURI = "ipfs://bafybeibut3ro7tth33vn2hkdqdlcwsqzuukcml6x3q7yytgkaljpy25rou/hidden.json";

    bool public revealed = false;

    mapping(address => bool) private _mintedFree;

    constructor() ERC721A("RFoxSquad", "RFS") {}

    function vipMint(bytes32[] calldata _merkleProof, uint256 count)
        external
        payable
        nonReentrant
    {
        bool isFreeLeft = !(_mintedFree[msg.sender]);
        bool isEqual = count == maxFreePerWallet;

        uint256 cost = price;

        bytes32 leaf = keccak256(abi.encodePacked(msg.sender));

        if (isFreeLeft && isEqual) {
            cost = 0;
        }

        if (isFreeLeft && !isEqual) {
            require(
                msg.value >= (count - maxFreePerWallet) * cost,
                "Please send the exact amount."
            );
        } else {
            require(msg.value >= count * cost, "Please send the exact amount.");
        }
        require(
            MerkleProof.verify(_merkleProof, vipRoot, leaf),
            "Incorrect Whitelist Proof"
        );
        require(totalSupply() + count <= maxSupply, "No more");
        require(count > 0, "Please enter a number");
        require(mintEnabled, "Minting is not live yet");
        require(
            _numberMinted(msg.sender) + count <= maxPerWallet,
            "Can not mint more than 4"
        );

        _mintedFree[msg.sender] = true;

        _safeMint(msg.sender, count);
    }

    function whitelistMint(bytes32[] calldata _merkleProof, uint256 count)
        external
        payable
    {
        bytes32 leaf = keccak256(abi.encodePacked(msg.sender));

        require(
            MerkleProof.verify(_merkleProof, whitelistRoot, leaf),
            "Incorrect Whitelist Proof"
        );
        require(msg.value >= price * count, "Please send the exact amount.");
        require(
            _numberMinted(msg.sender) + count <= maxPerWallet,
            "You cant mint anymore"
        );
        require(totalSupply() + count <= maxSupply, "No more");
        require(mintEnabled, "Minting is not live yet");

        _safeMint(msg.sender, count);
    }

    function publicMint(uint256 count) external payable {
        require(msg.value >= count * price, "Please send the exact amount.");
        require(totalSupply() + count <= maxSupply, "No more NFT left");
        require(
            _numberMinted(msg.sender) + count <= maxPerWallet,
            "Can not mint more than 4"
        );
        require(count > 0, "Please enter a number");
        require(publicEnabled, "Minting is not live yet");

        _safeMint(msg.sender, count);
    }

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

    function _isMintedFree(address minter) external view returns (bool) {
        return _mintedFree[minter];
    }

    function _mintedAmount(address account) external view returns (uint256) {
        return _numberMinted(account);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "ERC721AMetadata: URI query for nonexistent token"
        );
        if (revealed == false) {
            return hiddenURI;
        }

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

    function setPreSaleRoot(bytes32 _presaleRoot_1, bytes32 _presaleRoot_2)
        external
        onlyOwner
    {
        vipRoot = _presaleRoot_1;
        whitelistRoot = _presaleRoot_2;
    }

    // Only Owner Functions-----------
    function setBaseURI(string memory uri) public onlyOwner {
        baseURI = uri;
    }

    function setMaxPerWallet(uint256 amount) external onlyOwner {
        maxPerWallet = amount;
    }

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

    function setMaxSupply(uint256 _newSupply) external onlyOwner {
        maxSupply = _newSupply;
    }

    function flipWhitelist(bool status) external onlyOwner {
        mintEnabled = status;
    }

    function flipPublic(bool status) external onlyOwner {
        publicEnabled = status;
    }

    function reveal() external onlyOwner {
        revealed = !revealed;
    }

    function batchMint(uint256 _mintAmount, address destination)
        public
        onlyOwner
    {
        require(_mintAmount > 0, "need to mint at least 1 NFT");
        uint256 supply = totalSupply();
        require(supply + _mintAmount <= maxSupply, "max NFT limit exceeded");

        _safeMint(destination, _mintAmount);
    }

    function withdraw() external onlyOwner {
        (bool success, ) = payable(msg.sender).call{
            value: address(this).balance
        }("");
        require(success, "Transfer failed.");
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"_isMintedFree","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"_mintedAmount","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":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"address","name":"destination","type":"address"}],"name":"batchMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"status","type":"bool"}],"name":"flipPublic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"status","type":"bool"}],"name":"flipWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hiddenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"maxFreePerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMaxPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_presaleRoot_1","type":"bytes32"},{"internalType":"bytes32","name":"_presaleRoot_2","type":"bytes32"}],"name":"setPreSaleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setPrice","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":"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":"bytes32[]","name":"_merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"vipMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526004600b55661772aa3f848000600c556001600d55610d48600e556000600f60006101000a81548160ff0219169083151502179055506000600f60016101000a81548160ff0219169083151502179055506040518060800160405280604e815260200162004840604e9139601290805190602001906200008692919062000267565b506000601360006101000a81548160ff021916908315150217905550348015620000af57600080fd5b506040518060400160405280600981526020017f52466f78537175616400000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f524653000000000000000000000000000000000000000000000000000000000081525081600290805190602001906200013492919062000267565b5080600390805190602001906200014d92919062000267565b506200015e6200019460201b60201c565b6000819055505050620001866200017a6200019960201b60201c565b620001a160201b60201c565b60016009819055506200037c565b600090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620002759062000346565b90600052602060002090601f016020900481019282620002995760008555620002e5565b82601f10620002b457805160ff1916838001178555620002e5565b82800160010185558215620002e5579182015b82811115620002e4578251825591602001919060010190620002c7565b5b509050620002f49190620002f8565b5090565b5b8082111562000313576000816000905550600101620002f9565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200035f57607f821691505b6020821081141562000376576200037562000317565b5b50919050565b6144b4806200038c6000396000f3fe60806040526004361061023b5760003560e01c80638cc54e7f1161012e578063bbb81279116100ab578063e268e4d31161006f578063e268e4d31461080e578063e985e9c514610837578063ed64892b14610874578063f2fde38b146108b1578063f55e7fc7146108da5761023b565b8063bbb8127914610729578063c2f637dc14610752578063c87b56dd1461077b578063d1239730146107b8578063d5abeb01146107e35761023b565b8063a035b1fe116100f2578063a035b1fe1461066a578063a22cb46514610695578063a475b5dd146106be578063a7027357146106d5578063b88d4fde146107005761023b565b80638cc54e7f146105955780638da5cb5b146105c057806391b7f5ed146105eb57806395d89b41146106145780639b001f451461063f5761023b565b80633ccfd60b116101bc5780636352211e116101805780636352211e146104b25780636f8b44b0146104ef57806370a0823114610518578063715018a61461055557806377aeead91461056c5761023b565b80633ccfd60b146103f357806342842e0e1461040a578063453c231014610433578063518302271461045e57806355f804b3146104895761023b565b80631b607944116102035780631b6079441461033957806323b872dd146103555780632810570f1461037e5780632904e6d9146103bb5780632db11544146103d75761023b565b806301ffc9a71461024057806306fdde031461027d578063081812fc146102a8578063095ea7b3146102e557806318160ddd1461030e575b600080fd5b34801561024c57600080fd5b506102676004803603810190610262919061313a565b610903565b6040516102749190613182565b60405180910390f35b34801561028957600080fd5b50610292610995565b60405161029f9190613236565b60405180910390f35b3480156102b457600080fd5b506102cf60048036038101906102ca919061328e565b610a27565b6040516102dc91906132fc565b60405180910390f35b3480156102f157600080fd5b5061030c60048036038101906103079190613343565b610aa3565b005b34801561031a57600080fd5b50610323610c4a565b6040516103309190613392565b60405180910390f35b610353600480360381019061034e9190613412565b610c61565b005b34801561036157600080fd5b5061037c60048036038101906103779190613472565b611050565b005b34801561038a57600080fd5b506103a560048036038101906103a091906134c5565b611060565b6040516103b29190613182565b60405180910390f35b6103d560048036038101906103d09190613412565b6110b6565b005b6103f160048036038101906103ec919061328e565b6112cc565b005b3480156103ff57600080fd5b5061040861146a565b005b34801561041657600080fd5b50610431600480360381019061042c9190613472565b611595565b005b34801561043f57600080fd5b506104486115b5565b6040516104559190613392565b60405180910390f35b34801561046a57600080fd5b506104736115bb565b6040516104809190613182565b60405180910390f35b34801561049557600080fd5b506104b060048036038101906104ab9190613622565b6115ce565b005b3480156104be57600080fd5b506104d960048036038101906104d4919061328e565b611664565b6040516104e691906132fc565b60405180910390f35b3480156104fb57600080fd5b506105166004803603810190610511919061328e565b611676565b005b34801561052457600080fd5b5061053f600480360381019061053a91906134c5565b6116fc565b60405161054c9190613392565b60405180910390f35b34801561056157600080fd5b5061056a6117b5565b005b34801561057857600080fd5b50610593600480360381019061058e91906136a1565b61183d565b005b3480156105a157600080fd5b506105aa6118cb565b6040516105b79190613236565b60405180910390f35b3480156105cc57600080fd5b506105d5611959565b6040516105e291906132fc565b60405180910390f35b3480156105f757600080fd5b50610612600480360381019061060d919061328e565b611983565b005b34801561062057600080fd5b50610629611a09565b6040516106369190613236565b60405180910390f35b34801561064b57600080fd5b50610654611a9b565b6040516106619190613182565b60405180910390f35b34801561067657600080fd5b5061067f611aae565b60405161068c9190613392565b60405180910390f35b3480156106a157600080fd5b506106bc60048036038101906106b7919061370d565b611ab4565b005b3480156106ca57600080fd5b506106d3611c2c565b005b3480156106e157600080fd5b506106ea611cd4565b6040516106f79190613392565b60405180910390f35b34801561070c57600080fd5b50610727600480360381019061072291906137ee565b611cda565b005b34801561073557600080fd5b50610750600480360381019061074b9190613871565b611d4d565b005b34801561075e57600080fd5b506107796004803603810190610774919061389e565b611de6565b005b34801561078757600080fd5b506107a2600480360381019061079d919061328e565b611f10565b6040516107af9190613236565b60405180910390f35b3480156107c457600080fd5b506107cd612066565b6040516107da9190613182565b60405180910390f35b3480156107ef57600080fd5b506107f8612079565b6040516108059190613392565b60405180910390f35b34801561081a57600080fd5b506108356004803603810190610830919061328e565b61207f565b005b34801561084357600080fd5b5061085e600480360381019061085991906138de565b612105565b60405161086b9190613182565b60405180910390f35b34801561088057600080fd5b5061089b600480360381019061089691906134c5565b612199565b6040516108a89190613392565b60405180910390f35b3480156108bd57600080fd5b506108d860048036038101906108d391906134c5565b6121ab565b005b3480156108e657600080fd5b5061090160048036038101906108fc9190613871565b6122a3565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061095e57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061098e5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6060600280546109a49061394d565b80601f01602080910402602001604051908101604052809291908181526020018280546109d09061394d565b8015610a1d5780601f106109f257610100808354040283529160200191610a1d565b820191906000526020600020905b815481529060010190602001808311610a0057829003601f168201915b5050505050905090565b6000610a328261233c565b610a68576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610aae8261239b565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610b16576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610b35612469565b73ffffffffffffffffffffffffffffffffffffffff1614610b9857610b6181610b5c612469565b612105565b610b97576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610c54612471565b6001546000540303905090565b60026009541415610ca7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9e906139cb565b60405180910390fd5b60026009819055506000601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161590506000600d54831490506000600c549050600033604051602001610d249190613a33565b604051602081830303815290604052805190602001209050838015610d465750825b15610d5057600091505b838015610d5b575082155b15610dc05781600d5486610d6f9190613a7d565b610d799190613ab1565b341015610dbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db290613b57565b60405180910390fd5b610e0f565b8185610dcc9190613ab1565b341015610e0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0590613b57565b60405180910390fd5b5b610e5d878780806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505060105483612476565b610e9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9390613bc3565b60405180910390fd5b600e5485610ea8610c4a565b610eb29190613be3565b1115610ef3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eea90613c85565b60405180910390fd5b60008511610f36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2d90613cf1565b60405180910390fd5b600f60009054906101000a900460ff16610f85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7c90613d5d565b60405180910390fd5b600b5485610f923361248d565b610f9c9190613be3565b1115610fdd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd490613dc9565b60405180910390fd5b6001601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061103f33866124e4565b505050506001600981905550505050565b61105b838383612502565b505050565b6000601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000336040516020016110c99190613a33565b60405160208183030381529060405280519060200120905061112f848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505060115483612476565b61116e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116590613bc3565b60405180910390fd5b81600c5461117c9190613ab1565b3410156111be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111b590613b57565b60405180910390fd5b600b54826111cb3361248d565b6111d59190613be3565b1115611216576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120d90613e35565b60405180910390fd5b600e5482611222610c4a565b61122c9190613be3565b111561126d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161126490613c85565b60405180910390fd5b600f60009054906101000a900460ff166112bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112b390613d5d565b60405180910390fd5b6112c633836124e4565b50505050565b600c54816112da9190613ab1565b34101561131c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131390613b57565b60405180910390fd5b600e5481611328610c4a565b6113329190613be3565b1115611373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136a90613ea1565b60405180910390fd5b600b54816113803361248d565b61138a9190613be3565b11156113cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c290613dc9565b60405180910390fd5b6000811161140e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140590613cf1565b60405180910390fd5b600f60019054906101000a900460ff1661145d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145490613d5d565b60405180910390fd5b61146733826124e4565b50565b6114726128ac565b73ffffffffffffffffffffffffffffffffffffffff16611490611959565b73ffffffffffffffffffffffffffffffffffffffff16146114e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114dd90613f0d565b60405180910390fd5b60003373ffffffffffffffffffffffffffffffffffffffff164760405161150c90613f5e565b60006040518083038185875af1925050503d8060008114611549576040519150601f19603f3d011682016040523d82523d6000602084013e61154e565b606091505b5050905080611592576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158990613fbf565b60405180910390fd5b50565b6115b083838360405180602001604052806000815250611cda565b505050565b600b5481565b601360009054906101000a900460ff1681565b6115d66128ac565b73ffffffffffffffffffffffffffffffffffffffff166115f4611959565b73ffffffffffffffffffffffffffffffffffffffff161461164a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164190613f0d565b60405180910390fd5b80600a908051906020019061166092919061302b565b5050565b600061166f8261239b565b9050919050565b61167e6128ac565b73ffffffffffffffffffffffffffffffffffffffff1661169c611959565b73ffffffffffffffffffffffffffffffffffffffff16146116f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e990613f0d565b60405180910390fd5b80600e8190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611764576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6117bd6128ac565b73ffffffffffffffffffffffffffffffffffffffff166117db611959565b73ffffffffffffffffffffffffffffffffffffffff1614611831576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182890613f0d565b60405180910390fd5b61183b60006128b4565b565b6118456128ac565b73ffffffffffffffffffffffffffffffffffffffff16611863611959565b73ffffffffffffffffffffffffffffffffffffffff16146118b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b090613f0d565b60405180910390fd5b81601081905550806011819055505050565b601280546118d89061394d565b80601f01602080910402602001604051908101604052809291908181526020018280546119049061394d565b80156119515780601f1061192657610100808354040283529160200191611951565b820191906000526020600020905b81548152906001019060200180831161193457829003601f168201915b505050505081565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61198b6128ac565b73ffffffffffffffffffffffffffffffffffffffff166119a9611959565b73ffffffffffffffffffffffffffffffffffffffff16146119ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f690613f0d565b60405180910390fd5b80600c8190555050565b606060038054611a189061394d565b80601f0160208091040260200160405190810160405280929190818152602001828054611a449061394d565b8015611a915780601f10611a6657610100808354040283529160200191611a91565b820191906000526020600020905b815481529060010190602001808311611a7457829003601f168201915b5050505050905090565b600f60019054906101000a900460ff1681565b600c5481565b611abc612469565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b21576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060076000611b2e612469565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611bdb612469565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611c209190613182565b60405180910390a35050565b611c346128ac565b73ffffffffffffffffffffffffffffffffffffffff16611c52611959565b73ffffffffffffffffffffffffffffffffffffffff1614611ca8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9f90613f0d565b60405180910390fd5b601360009054906101000a900460ff1615601360006101000a81548160ff021916908315150217905550565b600d5481565b611ce5848484612502565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611d4757611d108484848461297a565b611d46576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b611d556128ac565b73ffffffffffffffffffffffffffffffffffffffff16611d73611959565b73ffffffffffffffffffffffffffffffffffffffff1614611dc9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dc090613f0d565b60405180910390fd5b80600f60006101000a81548160ff02191690831515021790555050565b611dee6128ac565b73ffffffffffffffffffffffffffffffffffffffff16611e0c611959565b73ffffffffffffffffffffffffffffffffffffffff1614611e62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e5990613f0d565b60405180910390fd5b60008211611ea5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e9c9061402b565b60405180910390fd5b6000611eaf610c4a565b9050600e548382611ec09190613be3565b1115611f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef890614097565b60405180910390fd5b611f0b82846124e4565b505050565b6060611f1b8261233c565b611f5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5190614129565b60405180910390fd5b60001515601360009054906101000a900460ff16151514156120085760128054611f839061394d565b80601f0160208091040260200160405190810160405280929190818152602001828054611faf9061394d565b8015611ffc5780601f10611fd157610100808354040283529160200191611ffc565b820191906000526020600020905b815481529060010190602001808311611fdf57829003601f168201915b50505050509050612061565b6000612012612acb565b90506000815111612032576040518060200160405280600081525061205d565b8061203c84612b5d565b60405160200161204d9291906141d1565b6040516020818303038152906040525b9150505b919050565b600f60009054906101000a900460ff1681565b600e5481565b6120876128ac565b73ffffffffffffffffffffffffffffffffffffffff166120a5611959565b73ffffffffffffffffffffffffffffffffffffffff16146120fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120f290613f0d565b60405180910390fd5b80600b8190555050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60006121a48261248d565b9050919050565b6121b36128ac565b73ffffffffffffffffffffffffffffffffffffffff166121d1611959565b73ffffffffffffffffffffffffffffffffffffffff1614612227576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161221e90613f0d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612297576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228e90614272565b60405180910390fd5b6122a0816128b4565b50565b6122ab6128ac565b73ffffffffffffffffffffffffffffffffffffffff166122c9611959565b73ffffffffffffffffffffffffffffffffffffffff161461231f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231690613f0d565b60405180910390fd5b80600f60016101000a81548160ff02191690831515021790555050565b600081612347612471565b11158015612356575060005482105b8015612394575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600080829050806123aa612471565b11612432576000548110156124315760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216141561242f575b60008114156124255760046000836001900393508381526020019081526020016000205490506123fa565b8092505050612464565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b600090565b6000826124838584612cbe565b1490509392505050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b6124fe828260405180602001604052806000815250612d14565b5050565b600061250d8261239b565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612574576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff16612595612469565b73ffffffffffffffffffffffffffffffffffffffff1614806125c457506125c3856125be612469565b612105565b5b8061260957506125d2612469565b73ffffffffffffffffffffffffffffffffffffffff166125f184610a27565b73ffffffffffffffffffffffffffffffffffffffff16145b905080612642576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156126a9576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6126b68585856001612fc9565b6006600084815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b6127b386612fcf565b1717600460008581526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008316141561283d57600060018401905060006004600083815260200190815260200160002054141561283b57600054811461283a578260046000838152602001908152602001600020819055505b5b505b828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46128a58585856001612fd9565b5050505050565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026129a0612469565b8786866040518563ffffffff1660e01b81526004016129c294939291906142e7565b6020604051808303816000875af19250505080156129fe57506040513d601f19601f820116820180604052508101906129fb9190614348565b60015b612a78573d8060008114612a2e576040519150601f19603f3d011682016040523d82523d6000602084013e612a33565b606091505b50600081511415612a70576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600a8054612ada9061394d565b80601f0160208091040260200160405190810160405280929190818152602001828054612b069061394d565b8015612b535780601f10612b2857610100808354040283529160200191612b53565b820191906000526020600020905b815481529060010190602001808311612b3657829003601f168201915b5050505050905090565b60606000821415612ba5576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612cb9565b600082905060005b60008214612bd7578080612bc090614375565b915050600a82612bd091906143ed565b9150612bad565b60008167ffffffffffffffff811115612bf357612bf26134f7565b5b6040519080825280601f01601f191660200182016040528015612c255781602001600182028036833780820191505090505b5090505b60008514612cb257600182612c3e9190613a7d565b9150600a85612c4d919061441e565b6030612c599190613be3565b60f81b818381518110612c6f57612c6e61444f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612cab91906143ed565b9450612c29565b8093505050505b919050565b60008082905060005b8451811015612d0957612cf482868381518110612ce757612ce661444f565b5b6020026020010151612fdf565b91508080612d0190614375565b915050612cc7565b508091505092915050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415612d81576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000831415612dbc576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612dc96000858386612fc9565b600160406001901b178302600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e1612e2e6001851461300a565b901b60a042901b612e3e86612fcf565b1717600460008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b14612f42575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612ef2600087848060010195508761297a565b612f28576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808210612e83578260005414612f3d57600080fd5b612fad565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808210612f43575b816000819055505050612fc36000858386612fd9565b50505050565b50505050565b6000819050919050565b50505050565b6000818310612ff757612ff28284613014565b613002565b6130018383613014565b5b905092915050565b6000819050919050565b600082600052816020526040600020905092915050565b8280546130379061394d565b90600052602060002090601f01602090048101928261305957600085556130a0565b82601f1061307257805160ff19168380011785556130a0565b828001600101855582156130a0579182015b8281111561309f578251825591602001919060010190613084565b5b5090506130ad91906130b1565b5090565b5b808211156130ca5760008160009055506001016130b2565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613117816130e2565b811461312257600080fd5b50565b6000813590506131348161310e565b92915050565b6000602082840312156131505761314f6130d8565b5b600061315e84828501613125565b91505092915050565b60008115159050919050565b61317c81613167565b82525050565b60006020820190506131976000830184613173565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156131d75780820151818401526020810190506131bc565b838111156131e6576000848401525b50505050565b6000601f19601f8301169050919050565b60006132088261319d565b61321281856131a8565b93506132228185602086016131b9565b61322b816131ec565b840191505092915050565b6000602082019050818103600083015261325081846131fd565b905092915050565b6000819050919050565b61326b81613258565b811461327657600080fd5b50565b60008135905061328881613262565b92915050565b6000602082840312156132a4576132a36130d8565b5b60006132b284828501613279565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006132e6826132bb565b9050919050565b6132f6816132db565b82525050565b600060208201905061331160008301846132ed565b92915050565b613320816132db565b811461332b57600080fd5b50565b60008135905061333d81613317565b92915050565b6000806040838503121561335a576133596130d8565b5b60006133688582860161332e565b925050602061337985828601613279565b9150509250929050565b61338c81613258565b82525050565b60006020820190506133a76000830184613383565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126133d2576133d16133ad565b5b8235905067ffffffffffffffff8111156133ef576133ee6133b2565b5b60208301915083602082028301111561340b5761340a6133b7565b5b9250929050565b60008060006040848603121561342b5761342a6130d8565b5b600084013567ffffffffffffffff811115613449576134486130dd565b5b613455868287016133bc565b9350935050602061346886828701613279565b9150509250925092565b60008060006060848603121561348b5761348a6130d8565b5b60006134998682870161332e565b93505060206134aa8682870161332e565b92505060406134bb86828701613279565b9150509250925092565b6000602082840312156134db576134da6130d8565b5b60006134e98482850161332e565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61352f826131ec565b810181811067ffffffffffffffff8211171561354e5761354d6134f7565b5b80604052505050565b60006135616130ce565b905061356d8282613526565b919050565b600067ffffffffffffffff82111561358d5761358c6134f7565b5b613596826131ec565b9050602081019050919050565b82818337600083830152505050565b60006135c56135c084613572565b613557565b9050828152602081018484840111156135e1576135e06134f2565b5b6135ec8482856135a3565b509392505050565b600082601f830112613609576136086133ad565b5b81356136198482602086016135b2565b91505092915050565b600060208284031215613638576136376130d8565b5b600082013567ffffffffffffffff811115613656576136556130dd565b5b613662848285016135f4565b91505092915050565b6000819050919050565b61367e8161366b565b811461368957600080fd5b50565b60008135905061369b81613675565b92915050565b600080604083850312156136b8576136b76130d8565b5b60006136c68582860161368c565b92505060206136d78582860161368c565b9150509250929050565b6136ea81613167565b81146136f557600080fd5b50565b600081359050613707816136e1565b92915050565b60008060408385031215613724576137236130d8565b5b60006137328582860161332e565b9250506020613743858286016136f8565b9150509250929050565b600067ffffffffffffffff821115613768576137676134f7565b5b613771826131ec565b9050602081019050919050565b600061379161378c8461374d565b613557565b9050828152602081018484840111156137ad576137ac6134f2565b5b6137b88482856135a3565b509392505050565b600082601f8301126137d5576137d46133ad565b5b81356137e584826020860161377e565b91505092915050565b60008060008060808587031215613808576138076130d8565b5b60006138168782880161332e565b94505060206138278782880161332e565b935050604061383887828801613279565b925050606085013567ffffffffffffffff811115613859576138586130dd565b5b613865878288016137c0565b91505092959194509250565b600060208284031215613887576138866130d8565b5b6000613895848285016136f8565b91505092915050565b600080604083850312156138b5576138b46130d8565b5b60006138c385828601613279565b92505060206138d48582860161332e565b9150509250929050565b600080604083850312156138f5576138f46130d8565b5b60006139038582860161332e565b92505060206139148582860161332e565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061396557607f821691505b602082108114156139795761397861391e565b5b50919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006139b5601f836131a8565b91506139c08261397f565b602082019050919050565b600060208201905081810360008301526139e4816139a8565b9050919050565b60008160601b9050919050565b6000613a03826139eb565b9050919050565b6000613a15826139f8565b9050919050565b613a2d613a28826132db565b613a0a565b82525050565b6000613a3f8284613a1c565b60148201915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613a8882613258565b9150613a9383613258565b925082821015613aa657613aa5613a4e565b5b828203905092915050565b6000613abc82613258565b9150613ac783613258565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613b0057613aff613a4e565b5b828202905092915050565b7f506c656173652073656e642074686520657861637420616d6f756e742e000000600082015250565b6000613b41601d836131a8565b9150613b4c82613b0b565b602082019050919050565b60006020820190508181036000830152613b7081613b34565b9050919050565b7f496e636f72726563742057686974656c6973742050726f6f6600000000000000600082015250565b6000613bad6019836131a8565b9150613bb882613b77565b602082019050919050565b60006020820190508181036000830152613bdc81613ba0565b9050919050565b6000613bee82613258565b9150613bf983613258565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613c2e57613c2d613a4e565b5b828201905092915050565b7f4e6f206d6f726500000000000000000000000000000000000000000000000000600082015250565b6000613c6f6007836131a8565b9150613c7a82613c39565b602082019050919050565b60006020820190508181036000830152613c9e81613c62565b9050919050565b7f506c6561736520656e7465722061206e756d6265720000000000000000000000600082015250565b6000613cdb6015836131a8565b9150613ce682613ca5565b602082019050919050565b60006020820190508181036000830152613d0a81613cce565b9050919050565b7f4d696e74696e67206973206e6f74206c69766520796574000000000000000000600082015250565b6000613d476017836131a8565b9150613d5282613d11565b602082019050919050565b60006020820190508181036000830152613d7681613d3a565b9050919050565b7f43616e206e6f74206d696e74206d6f7265207468616e20340000000000000000600082015250565b6000613db36018836131a8565b9150613dbe82613d7d565b602082019050919050565b60006020820190508181036000830152613de281613da6565b9050919050565b7f596f752063616e74206d696e7420616e796d6f72650000000000000000000000600082015250565b6000613e1f6015836131a8565b9150613e2a82613de9565b602082019050919050565b60006020820190508181036000830152613e4e81613e12565b9050919050565b7f4e6f206d6f7265204e4654206c65667400000000000000000000000000000000600082015250565b6000613e8b6010836131a8565b9150613e9682613e55565b602082019050919050565b60006020820190508181036000830152613eba81613e7e565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613ef76020836131a8565b9150613f0282613ec1565b602082019050919050565b60006020820190508181036000830152613f2681613eea565b9050919050565b600081905092915050565b50565b6000613f48600083613f2d565b9150613f5382613f38565b600082019050919050565b6000613f6982613f3b565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b6000613fa96010836131a8565b9150613fb482613f73565b602082019050919050565b60006020820190508181036000830152613fd881613f9c565b9050919050565b7f6e65656420746f206d696e74206174206c656173742031204e46540000000000600082015250565b6000614015601b836131a8565b915061402082613fdf565b602082019050919050565b6000602082019050818103600083015261404481614008565b9050919050565b7f6d6178204e4654206c696d697420657863656564656400000000000000000000600082015250565b60006140816016836131a8565b915061408c8261404b565b602082019050919050565b600060208201905081810360008301526140b081614074565b9050919050565b7f455243373231414d657461646174613a2055524920717565727920666f72206e60008201527f6f6e6578697374656e7420746f6b656e00000000000000000000000000000000602082015250565b60006141136030836131a8565b915061411e826140b7565b604082019050919050565b6000602082019050818103600083015261414281614106565b9050919050565b600081905092915050565b600061415f8261319d565b6141698185614149565b93506141798185602086016131b9565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b60006141bb600583614149565b91506141c682614185565b600582019050919050565b60006141dd8285614154565b91506141e98284614154565b91506141f4826141ae565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061425c6026836131a8565b915061426782614200565b604082019050919050565b6000602082019050818103600083015261428b8161424f565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006142b982614292565b6142c3818561429d565b93506142d38185602086016131b9565b6142dc816131ec565b840191505092915050565b60006080820190506142fc60008301876132ed565b61430960208301866132ed565b6143166040830185613383565b818103606083015261432881846142ae565b905095945050505050565b6000815190506143428161310e565b92915050565b60006020828403121561435e5761435d6130d8565b5b600061436c84828501614333565b91505092915050565b600061438082613258565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156143b3576143b2613a4e565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006143f882613258565b915061440383613258565b925082614413576144126143be565b5b828204905092915050565b600061442982613258565b915061443483613258565b925082614444576144436143be565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212208dd415a79e7e27f8a61686aa7356a8dcad3ec41ce76aa55e3836e7740b2774e664736f6c634300080c0033697066733a2f2f6261667962656962757433726f377474683333766e32686b6471646c637773717a75756b636d6c3678337137797974676b616c6a70793235726f752f68696464656e2e6a736f6e

Deployed Bytecode

0x60806040526004361061023b5760003560e01c80638cc54e7f1161012e578063bbb81279116100ab578063e268e4d31161006f578063e268e4d31461080e578063e985e9c514610837578063ed64892b14610874578063f2fde38b146108b1578063f55e7fc7146108da5761023b565b8063bbb8127914610729578063c2f637dc14610752578063c87b56dd1461077b578063d1239730146107b8578063d5abeb01146107e35761023b565b8063a035b1fe116100f2578063a035b1fe1461066a578063a22cb46514610695578063a475b5dd146106be578063a7027357146106d5578063b88d4fde146107005761023b565b80638cc54e7f146105955780638da5cb5b146105c057806391b7f5ed146105eb57806395d89b41146106145780639b001f451461063f5761023b565b80633ccfd60b116101bc5780636352211e116101805780636352211e146104b25780636f8b44b0146104ef57806370a0823114610518578063715018a61461055557806377aeead91461056c5761023b565b80633ccfd60b146103f357806342842e0e1461040a578063453c231014610433578063518302271461045e57806355f804b3146104895761023b565b80631b607944116102035780631b6079441461033957806323b872dd146103555780632810570f1461037e5780632904e6d9146103bb5780632db11544146103d75761023b565b806301ffc9a71461024057806306fdde031461027d578063081812fc146102a8578063095ea7b3146102e557806318160ddd1461030e575b600080fd5b34801561024c57600080fd5b506102676004803603810190610262919061313a565b610903565b6040516102749190613182565b60405180910390f35b34801561028957600080fd5b50610292610995565b60405161029f9190613236565b60405180910390f35b3480156102b457600080fd5b506102cf60048036038101906102ca919061328e565b610a27565b6040516102dc91906132fc565b60405180910390f35b3480156102f157600080fd5b5061030c60048036038101906103079190613343565b610aa3565b005b34801561031a57600080fd5b50610323610c4a565b6040516103309190613392565b60405180910390f35b610353600480360381019061034e9190613412565b610c61565b005b34801561036157600080fd5b5061037c60048036038101906103779190613472565b611050565b005b34801561038a57600080fd5b506103a560048036038101906103a091906134c5565b611060565b6040516103b29190613182565b60405180910390f35b6103d560048036038101906103d09190613412565b6110b6565b005b6103f160048036038101906103ec919061328e565b6112cc565b005b3480156103ff57600080fd5b5061040861146a565b005b34801561041657600080fd5b50610431600480360381019061042c9190613472565b611595565b005b34801561043f57600080fd5b506104486115b5565b6040516104559190613392565b60405180910390f35b34801561046a57600080fd5b506104736115bb565b6040516104809190613182565b60405180910390f35b34801561049557600080fd5b506104b060048036038101906104ab9190613622565b6115ce565b005b3480156104be57600080fd5b506104d960048036038101906104d4919061328e565b611664565b6040516104e691906132fc565b60405180910390f35b3480156104fb57600080fd5b506105166004803603810190610511919061328e565b611676565b005b34801561052457600080fd5b5061053f600480360381019061053a91906134c5565b6116fc565b60405161054c9190613392565b60405180910390f35b34801561056157600080fd5b5061056a6117b5565b005b34801561057857600080fd5b50610593600480360381019061058e91906136a1565b61183d565b005b3480156105a157600080fd5b506105aa6118cb565b6040516105b79190613236565b60405180910390f35b3480156105cc57600080fd5b506105d5611959565b6040516105e291906132fc565b60405180910390f35b3480156105f757600080fd5b50610612600480360381019061060d919061328e565b611983565b005b34801561062057600080fd5b50610629611a09565b6040516106369190613236565b60405180910390f35b34801561064b57600080fd5b50610654611a9b565b6040516106619190613182565b60405180910390f35b34801561067657600080fd5b5061067f611aae565b60405161068c9190613392565b60405180910390f35b3480156106a157600080fd5b506106bc60048036038101906106b7919061370d565b611ab4565b005b3480156106ca57600080fd5b506106d3611c2c565b005b3480156106e157600080fd5b506106ea611cd4565b6040516106f79190613392565b60405180910390f35b34801561070c57600080fd5b50610727600480360381019061072291906137ee565b611cda565b005b34801561073557600080fd5b50610750600480360381019061074b9190613871565b611d4d565b005b34801561075e57600080fd5b506107796004803603810190610774919061389e565b611de6565b005b34801561078757600080fd5b506107a2600480360381019061079d919061328e565b611f10565b6040516107af9190613236565b60405180910390f35b3480156107c457600080fd5b506107cd612066565b6040516107da9190613182565b60405180910390f35b3480156107ef57600080fd5b506107f8612079565b6040516108059190613392565b60405180910390f35b34801561081a57600080fd5b506108356004803603810190610830919061328e565b61207f565b005b34801561084357600080fd5b5061085e600480360381019061085991906138de565b612105565b60405161086b9190613182565b60405180910390f35b34801561088057600080fd5b5061089b600480360381019061089691906134c5565b612199565b6040516108a89190613392565b60405180910390f35b3480156108bd57600080fd5b506108d860048036038101906108d391906134c5565b6121ab565b005b3480156108e657600080fd5b5061090160048036038101906108fc9190613871565b6122a3565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061095e57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061098e5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6060600280546109a49061394d565b80601f01602080910402602001604051908101604052809291908181526020018280546109d09061394d565b8015610a1d5780601f106109f257610100808354040283529160200191610a1d565b820191906000526020600020905b815481529060010190602001808311610a0057829003601f168201915b5050505050905090565b6000610a328261233c565b610a68576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610aae8261239b565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610b16576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610b35612469565b73ffffffffffffffffffffffffffffffffffffffff1614610b9857610b6181610b5c612469565b612105565b610b97576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610c54612471565b6001546000540303905090565b60026009541415610ca7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9e906139cb565b60405180910390fd5b60026009819055506000601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161590506000600d54831490506000600c549050600033604051602001610d249190613a33565b604051602081830303815290604052805190602001209050838015610d465750825b15610d5057600091505b838015610d5b575082155b15610dc05781600d5486610d6f9190613a7d565b610d799190613ab1565b341015610dbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db290613b57565b60405180910390fd5b610e0f565b8185610dcc9190613ab1565b341015610e0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0590613b57565b60405180910390fd5b5b610e5d878780806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505060105483612476565b610e9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9390613bc3565b60405180910390fd5b600e5485610ea8610c4a565b610eb29190613be3565b1115610ef3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eea90613c85565b60405180910390fd5b60008511610f36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2d90613cf1565b60405180910390fd5b600f60009054906101000a900460ff16610f85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7c90613d5d565b60405180910390fd5b600b5485610f923361248d565b610f9c9190613be3565b1115610fdd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd490613dc9565b60405180910390fd5b6001601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061103f33866124e4565b505050506001600981905550505050565b61105b838383612502565b505050565b6000601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000336040516020016110c99190613a33565b60405160208183030381529060405280519060200120905061112f848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505060115483612476565b61116e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116590613bc3565b60405180910390fd5b81600c5461117c9190613ab1565b3410156111be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111b590613b57565b60405180910390fd5b600b54826111cb3361248d565b6111d59190613be3565b1115611216576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120d90613e35565b60405180910390fd5b600e5482611222610c4a565b61122c9190613be3565b111561126d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161126490613c85565b60405180910390fd5b600f60009054906101000a900460ff166112bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112b390613d5d565b60405180910390fd5b6112c633836124e4565b50505050565b600c54816112da9190613ab1565b34101561131c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131390613b57565b60405180910390fd5b600e5481611328610c4a565b6113329190613be3565b1115611373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136a90613ea1565b60405180910390fd5b600b54816113803361248d565b61138a9190613be3565b11156113cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c290613dc9565b60405180910390fd5b6000811161140e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140590613cf1565b60405180910390fd5b600f60019054906101000a900460ff1661145d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145490613d5d565b60405180910390fd5b61146733826124e4565b50565b6114726128ac565b73ffffffffffffffffffffffffffffffffffffffff16611490611959565b73ffffffffffffffffffffffffffffffffffffffff16146114e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114dd90613f0d565b60405180910390fd5b60003373ffffffffffffffffffffffffffffffffffffffff164760405161150c90613f5e565b60006040518083038185875af1925050503d8060008114611549576040519150601f19603f3d011682016040523d82523d6000602084013e61154e565b606091505b5050905080611592576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158990613fbf565b60405180910390fd5b50565b6115b083838360405180602001604052806000815250611cda565b505050565b600b5481565b601360009054906101000a900460ff1681565b6115d66128ac565b73ffffffffffffffffffffffffffffffffffffffff166115f4611959565b73ffffffffffffffffffffffffffffffffffffffff161461164a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164190613f0d565b60405180910390fd5b80600a908051906020019061166092919061302b565b5050565b600061166f8261239b565b9050919050565b61167e6128ac565b73ffffffffffffffffffffffffffffffffffffffff1661169c611959565b73ffffffffffffffffffffffffffffffffffffffff16146116f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e990613f0d565b60405180910390fd5b80600e8190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611764576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6117bd6128ac565b73ffffffffffffffffffffffffffffffffffffffff166117db611959565b73ffffffffffffffffffffffffffffffffffffffff1614611831576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182890613f0d565b60405180910390fd5b61183b60006128b4565b565b6118456128ac565b73ffffffffffffffffffffffffffffffffffffffff16611863611959565b73ffffffffffffffffffffffffffffffffffffffff16146118b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b090613f0d565b60405180910390fd5b81601081905550806011819055505050565b601280546118d89061394d565b80601f01602080910402602001604051908101604052809291908181526020018280546119049061394d565b80156119515780601f1061192657610100808354040283529160200191611951565b820191906000526020600020905b81548152906001019060200180831161193457829003601f168201915b505050505081565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61198b6128ac565b73ffffffffffffffffffffffffffffffffffffffff166119a9611959565b73ffffffffffffffffffffffffffffffffffffffff16146119ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f690613f0d565b60405180910390fd5b80600c8190555050565b606060038054611a189061394d565b80601f0160208091040260200160405190810160405280929190818152602001828054611a449061394d565b8015611a915780601f10611a6657610100808354040283529160200191611a91565b820191906000526020600020905b815481529060010190602001808311611a7457829003601f168201915b5050505050905090565b600f60019054906101000a900460ff1681565b600c5481565b611abc612469565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b21576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060076000611b2e612469565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611bdb612469565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611c209190613182565b60405180910390a35050565b611c346128ac565b73ffffffffffffffffffffffffffffffffffffffff16611c52611959565b73ffffffffffffffffffffffffffffffffffffffff1614611ca8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9f90613f0d565b60405180910390fd5b601360009054906101000a900460ff1615601360006101000a81548160ff021916908315150217905550565b600d5481565b611ce5848484612502565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611d4757611d108484848461297a565b611d46576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b611d556128ac565b73ffffffffffffffffffffffffffffffffffffffff16611d73611959565b73ffffffffffffffffffffffffffffffffffffffff1614611dc9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dc090613f0d565b60405180910390fd5b80600f60006101000a81548160ff02191690831515021790555050565b611dee6128ac565b73ffffffffffffffffffffffffffffffffffffffff16611e0c611959565b73ffffffffffffffffffffffffffffffffffffffff1614611e62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e5990613f0d565b60405180910390fd5b60008211611ea5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e9c9061402b565b60405180910390fd5b6000611eaf610c4a565b9050600e548382611ec09190613be3565b1115611f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef890614097565b60405180910390fd5b611f0b82846124e4565b505050565b6060611f1b8261233c565b611f5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5190614129565b60405180910390fd5b60001515601360009054906101000a900460ff16151514156120085760128054611f839061394d565b80601f0160208091040260200160405190810160405280929190818152602001828054611faf9061394d565b8015611ffc5780601f10611fd157610100808354040283529160200191611ffc565b820191906000526020600020905b815481529060010190602001808311611fdf57829003601f168201915b50505050509050612061565b6000612012612acb565b90506000815111612032576040518060200160405280600081525061205d565b8061203c84612b5d565b60405160200161204d9291906141d1565b6040516020818303038152906040525b9150505b919050565b600f60009054906101000a900460ff1681565b600e5481565b6120876128ac565b73ffffffffffffffffffffffffffffffffffffffff166120a5611959565b73ffffffffffffffffffffffffffffffffffffffff16146120fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120f290613f0d565b60405180910390fd5b80600b8190555050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60006121a48261248d565b9050919050565b6121b36128ac565b73ffffffffffffffffffffffffffffffffffffffff166121d1611959565b73ffffffffffffffffffffffffffffffffffffffff1614612227576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161221e90613f0d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612297576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228e90614272565b60405180910390fd5b6122a0816128b4565b50565b6122ab6128ac565b73ffffffffffffffffffffffffffffffffffffffff166122c9611959565b73ffffffffffffffffffffffffffffffffffffffff161461231f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231690613f0d565b60405180910390fd5b80600f60016101000a81548160ff02191690831515021790555050565b600081612347612471565b11158015612356575060005482105b8015612394575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600080829050806123aa612471565b11612432576000548110156124315760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216141561242f575b60008114156124255760046000836001900393508381526020019081526020016000205490506123fa565b8092505050612464565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b600090565b6000826124838584612cbe565b1490509392505050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b6124fe828260405180602001604052806000815250612d14565b5050565b600061250d8261239b565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612574576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff16612595612469565b73ffffffffffffffffffffffffffffffffffffffff1614806125c457506125c3856125be612469565b612105565b5b8061260957506125d2612469565b73ffffffffffffffffffffffffffffffffffffffff166125f184610a27565b73ffffffffffffffffffffffffffffffffffffffff16145b905080612642576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156126a9576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6126b68585856001612fc9565b6006600084815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b6127b386612fcf565b1717600460008581526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008316141561283d57600060018401905060006004600083815260200190815260200160002054141561283b57600054811461283a578260046000838152602001908152602001600020819055505b5b505b828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46128a58585856001612fd9565b5050505050565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026129a0612469565b8786866040518563ffffffff1660e01b81526004016129c294939291906142e7565b6020604051808303816000875af19250505080156129fe57506040513d601f19601f820116820180604052508101906129fb9190614348565b60015b612a78573d8060008114612a2e576040519150601f19603f3d011682016040523d82523d6000602084013e612a33565b606091505b50600081511415612a70576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600a8054612ada9061394d565b80601f0160208091040260200160405190810160405280929190818152602001828054612b069061394d565b8015612b535780601f10612b2857610100808354040283529160200191612b53565b820191906000526020600020905b815481529060010190602001808311612b3657829003601f168201915b5050505050905090565b60606000821415612ba5576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612cb9565b600082905060005b60008214612bd7578080612bc090614375565b915050600a82612bd091906143ed565b9150612bad565b60008167ffffffffffffffff811115612bf357612bf26134f7565b5b6040519080825280601f01601f191660200182016040528015612c255781602001600182028036833780820191505090505b5090505b60008514612cb257600182612c3e9190613a7d565b9150600a85612c4d919061441e565b6030612c599190613be3565b60f81b818381518110612c6f57612c6e61444f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612cab91906143ed565b9450612c29565b8093505050505b919050565b60008082905060005b8451811015612d0957612cf482868381518110612ce757612ce661444f565b5b6020026020010151612fdf565b91508080612d0190614375565b915050612cc7565b508091505092915050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415612d81576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000831415612dbc576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612dc96000858386612fc9565b600160406001901b178302600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e1612e2e6001851461300a565b901b60a042901b612e3e86612fcf565b1717600460008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b14612f42575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612ef2600087848060010195508761297a565b612f28576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808210612e83578260005414612f3d57600080fd5b612fad565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808210612f43575b816000819055505050612fc36000858386612fd9565b50505050565b50505050565b6000819050919050565b50505050565b6000818310612ff757612ff28284613014565b613002565b6130018383613014565b5b905092915050565b6000819050919050565b600082600052816020526040600020905092915050565b8280546130379061394d565b90600052602060002090601f01602090048101928261305957600085556130a0565b82601f1061307257805160ff19168380011785556130a0565b828001600101855582156130a0579182015b8281111561309f578251825591602001919060010190613084565b5b5090506130ad91906130b1565b5090565b5b808211156130ca5760008160009055506001016130b2565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613117816130e2565b811461312257600080fd5b50565b6000813590506131348161310e565b92915050565b6000602082840312156131505761314f6130d8565b5b600061315e84828501613125565b91505092915050565b60008115159050919050565b61317c81613167565b82525050565b60006020820190506131976000830184613173565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156131d75780820151818401526020810190506131bc565b838111156131e6576000848401525b50505050565b6000601f19601f8301169050919050565b60006132088261319d565b61321281856131a8565b93506132228185602086016131b9565b61322b816131ec565b840191505092915050565b6000602082019050818103600083015261325081846131fd565b905092915050565b6000819050919050565b61326b81613258565b811461327657600080fd5b50565b60008135905061328881613262565b92915050565b6000602082840312156132a4576132a36130d8565b5b60006132b284828501613279565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006132e6826132bb565b9050919050565b6132f6816132db565b82525050565b600060208201905061331160008301846132ed565b92915050565b613320816132db565b811461332b57600080fd5b50565b60008135905061333d81613317565b92915050565b6000806040838503121561335a576133596130d8565b5b60006133688582860161332e565b925050602061337985828601613279565b9150509250929050565b61338c81613258565b82525050565b60006020820190506133a76000830184613383565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126133d2576133d16133ad565b5b8235905067ffffffffffffffff8111156133ef576133ee6133b2565b5b60208301915083602082028301111561340b5761340a6133b7565b5b9250929050565b60008060006040848603121561342b5761342a6130d8565b5b600084013567ffffffffffffffff811115613449576134486130dd565b5b613455868287016133bc565b9350935050602061346886828701613279565b9150509250925092565b60008060006060848603121561348b5761348a6130d8565b5b60006134998682870161332e565b93505060206134aa8682870161332e565b92505060406134bb86828701613279565b9150509250925092565b6000602082840312156134db576134da6130d8565b5b60006134e98482850161332e565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61352f826131ec565b810181811067ffffffffffffffff8211171561354e5761354d6134f7565b5b80604052505050565b60006135616130ce565b905061356d8282613526565b919050565b600067ffffffffffffffff82111561358d5761358c6134f7565b5b613596826131ec565b9050602081019050919050565b82818337600083830152505050565b60006135c56135c084613572565b613557565b9050828152602081018484840111156135e1576135e06134f2565b5b6135ec8482856135a3565b509392505050565b600082601f830112613609576136086133ad565b5b81356136198482602086016135b2565b91505092915050565b600060208284031215613638576136376130d8565b5b600082013567ffffffffffffffff811115613656576136556130dd565b5b613662848285016135f4565b91505092915050565b6000819050919050565b61367e8161366b565b811461368957600080fd5b50565b60008135905061369b81613675565b92915050565b600080604083850312156136b8576136b76130d8565b5b60006136c68582860161368c565b92505060206136d78582860161368c565b9150509250929050565b6136ea81613167565b81146136f557600080fd5b50565b600081359050613707816136e1565b92915050565b60008060408385031215613724576137236130d8565b5b60006137328582860161332e565b9250506020613743858286016136f8565b9150509250929050565b600067ffffffffffffffff821115613768576137676134f7565b5b613771826131ec565b9050602081019050919050565b600061379161378c8461374d565b613557565b9050828152602081018484840111156137ad576137ac6134f2565b5b6137b88482856135a3565b509392505050565b600082601f8301126137d5576137d46133ad565b5b81356137e584826020860161377e565b91505092915050565b60008060008060808587031215613808576138076130d8565b5b60006138168782880161332e565b94505060206138278782880161332e565b935050604061383887828801613279565b925050606085013567ffffffffffffffff811115613859576138586130dd565b5b613865878288016137c0565b91505092959194509250565b600060208284031215613887576138866130d8565b5b6000613895848285016136f8565b91505092915050565b600080604083850312156138b5576138b46130d8565b5b60006138c385828601613279565b92505060206138d48582860161332e565b9150509250929050565b600080604083850312156138f5576138f46130d8565b5b60006139038582860161332e565b92505060206139148582860161332e565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061396557607f821691505b602082108114156139795761397861391e565b5b50919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006139b5601f836131a8565b91506139c08261397f565b602082019050919050565b600060208201905081810360008301526139e4816139a8565b9050919050565b60008160601b9050919050565b6000613a03826139eb565b9050919050565b6000613a15826139f8565b9050919050565b613a2d613a28826132db565b613a0a565b82525050565b6000613a3f8284613a1c565b60148201915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613a8882613258565b9150613a9383613258565b925082821015613aa657613aa5613a4e565b5b828203905092915050565b6000613abc82613258565b9150613ac783613258565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613b0057613aff613a4e565b5b828202905092915050565b7f506c656173652073656e642074686520657861637420616d6f756e742e000000600082015250565b6000613b41601d836131a8565b9150613b4c82613b0b565b602082019050919050565b60006020820190508181036000830152613b7081613b34565b9050919050565b7f496e636f72726563742057686974656c6973742050726f6f6600000000000000600082015250565b6000613bad6019836131a8565b9150613bb882613b77565b602082019050919050565b60006020820190508181036000830152613bdc81613ba0565b9050919050565b6000613bee82613258565b9150613bf983613258565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613c2e57613c2d613a4e565b5b828201905092915050565b7f4e6f206d6f726500000000000000000000000000000000000000000000000000600082015250565b6000613c6f6007836131a8565b9150613c7a82613c39565b602082019050919050565b60006020820190508181036000830152613c9e81613c62565b9050919050565b7f506c6561736520656e7465722061206e756d6265720000000000000000000000600082015250565b6000613cdb6015836131a8565b9150613ce682613ca5565b602082019050919050565b60006020820190508181036000830152613d0a81613cce565b9050919050565b7f4d696e74696e67206973206e6f74206c69766520796574000000000000000000600082015250565b6000613d476017836131a8565b9150613d5282613d11565b602082019050919050565b60006020820190508181036000830152613d7681613d3a565b9050919050565b7f43616e206e6f74206d696e74206d6f7265207468616e20340000000000000000600082015250565b6000613db36018836131a8565b9150613dbe82613d7d565b602082019050919050565b60006020820190508181036000830152613de281613da6565b9050919050565b7f596f752063616e74206d696e7420616e796d6f72650000000000000000000000600082015250565b6000613e1f6015836131a8565b9150613e2a82613de9565b602082019050919050565b60006020820190508181036000830152613e4e81613e12565b9050919050565b7f4e6f206d6f7265204e4654206c65667400000000000000000000000000000000600082015250565b6000613e8b6010836131a8565b9150613e9682613e55565b602082019050919050565b60006020820190508181036000830152613eba81613e7e565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613ef76020836131a8565b9150613f0282613ec1565b602082019050919050565b60006020820190508181036000830152613f2681613eea565b9050919050565b600081905092915050565b50565b6000613f48600083613f2d565b9150613f5382613f38565b600082019050919050565b6000613f6982613f3b565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b6000613fa96010836131a8565b9150613fb482613f73565b602082019050919050565b60006020820190508181036000830152613fd881613f9c565b9050919050565b7f6e65656420746f206d696e74206174206c656173742031204e46540000000000600082015250565b6000614015601b836131a8565b915061402082613fdf565b602082019050919050565b6000602082019050818103600083015261404481614008565b9050919050565b7f6d6178204e4654206c696d697420657863656564656400000000000000000000600082015250565b60006140816016836131a8565b915061408c8261404b565b602082019050919050565b600060208201905081810360008301526140b081614074565b9050919050565b7f455243373231414d657461646174613a2055524920717565727920666f72206e60008201527f6f6e6578697374656e7420746f6b656e00000000000000000000000000000000602082015250565b60006141136030836131a8565b915061411e826140b7565b604082019050919050565b6000602082019050818103600083015261414281614106565b9050919050565b600081905092915050565b600061415f8261319d565b6141698185614149565b93506141798185602086016131b9565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b60006141bb600583614149565b91506141c682614185565b600582019050919050565b60006141dd8285614154565b91506141e98284614154565b91506141f4826141ae565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061425c6026836131a8565b915061426782614200565b604082019050919050565b6000602082019050818103600083015261428b8161424f565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006142b982614292565b6142c3818561429d565b93506142d38185602086016131b9565b6142dc816131ec565b840191505092915050565b60006080820190506142fc60008301876132ed565b61430960208301866132ed565b6143166040830185613383565b818103606083015261432881846142ae565b905095945050505050565b6000815190506143428161310e565b92915050565b60006020828403121561435e5761435d6130d8565b5b600061436c84828501614333565b91505092915050565b600061438082613258565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156143b3576143b2613a4e565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006143f882613258565b915061440383613258565b925082614413576144126143be565b5b828204905092915050565b600061442982613258565b915061443483613258565b925082614444576144436143be565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212208dd415a79e7e27f8a61686aa7356a8dcad3ec41ce76aa55e3836e7740b2774e664736f6c634300080c0033

Deployed Bytecode Sourcemap

91110:5772:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25044:665;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30300:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32497:245;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31957:474;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;24098:315;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91817:1247;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;33506:170;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94405:113;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93072:699;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93779:502;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96673:206;;;;;;;;;;;;;:::i;:::-;;33747:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;91240:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91675:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95621:88;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;30089:144;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95925:102;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;25773:224;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56528:103;;;;;;;;;;;;;:::i;:::-;;95375:198;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;91560:106;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55877:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95825:92;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;30469:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91466:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91278:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32814:340;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96238:76;;;;;;;;;;;;;:::i;:::-;;91322:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34003:396;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96035:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96322:343;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94654:713;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91428:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91366;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95717:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;33225:214;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94526:120;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56786:238;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96137:93;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;25044:665;25174:4;25494:10;25479:25;;:11;:25;;;;:102;;;;25571:10;25556:25;;:11;:25;;;;25479:102;:179;;;;25648:10;25633:25;;:11;:25;;;;25479:179;25459:199;;25044:665;;;:::o;30300:100::-;30354:13;30387:5;30380:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30300:100;:::o;32497:245::-;32601:7;32631:16;32639:7;32631;:16::i;:::-;32626:64;;32656:34;;;;;;;;;;;;;;32626:64;32710:15;:24;32726:7;32710:24;;;;;;;;;;;;;;;;;;;;;32703:31;;32497:245;;;:::o;31957:474::-;32030:13;32062:27;32081:7;32062:18;:27::i;:::-;32030:61;;32112:5;32106:11;;:2;:11;;;32102:48;;;32126:24;;;;;;;;;;;;;;32102:48;32190:5;32167:28;;:19;:17;:19::i;:::-;:28;;;32163:175;;32215:44;32232:5;32239:19;:17;:19::i;:::-;32215:16;:44::i;:::-;32210:128;;32287:35;;;;;;;;;;;;;;32210:128;32163:175;32377:2;32350:15;:24;32366:7;32350:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;32415:7;32411:2;32395:28;;32404:5;32395:28;;;;;;;;;;;;32019:412;31957:474;;:::o;24098:315::-;24151:7;24379:15;:13;:15::i;:::-;24364:12;;24348:13;;:28;:46;24341:53;;24098:315;:::o;91817:1247::-;1845:1;2443:7;;:19;;2435:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;1845:1;2576:7;:18;;;;91955:15:::1;91975:11;:23;91987:10;91975:23;;;;;;;;;;;;;;;;;;;;;;;;;91973:26;91955:44;;92010:12;92034:16;;92025:5;:25;92010:40;;92063:12;92078:5;;92063:20;;92096:12;92138:10;92121:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;92111:39;;;;;;92096:54;;92167:10;:21;;;;;92181:7;92167:21;92163:62;;;92212:1;92205:8;;92163:62;92241:10;:22;;;;;92256:7;92255:8;92241:22;92237:292;;;92348:4;92328:16;;92320:5;:24;;;;:::i;:::-;92319:33;;;;:::i;:::-;92306:9;:46;;92280:137;;;;;;;;;;;;:::i;:::-;;;;;;;;;92237:292;;;92479:4;92471:5;:12;;;;:::i;:::-;92458:9;:25;;92450:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;92237:292;92561:47;92580:12;;92561:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92594:7;;92603:4;92561:18;:47::i;:::-;92539:122;;;;;;;;;;;;:::i;:::-;;;;;;;;;92705:9;;92696:5;92680:13;:11;:13::i;:::-;:21;;;;:::i;:::-;:34;;92672:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;92753:1;92745:5;:9;92737:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;92799:11;;;;;;;;;;;92791:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;92908:12;;92899:5;92871:25;92885:10;92871:13;:25::i;:::-;:33;;;;:::i;:::-;:49;;92849:123;;;;;;;;;;;;:::i;:::-;;;;;;;;;93011:4;92985:11;:23;92997:10;92985:23;;;;;;;;;;;;;;;;:30;;;;;;;;;;;;;;;;;;93028:28;93038:10;93050:5;93028:9;:28::i;:::-;91944:1120;;;;1801:1:::0;2755:7;:22;;;;91817:1247;;;:::o;33506:170::-;33640:28;33650:4;33656:2;33660:7;33640:9;:28::i;:::-;33506:170;;;:::o;94405:113::-;94467:4;94491:11;:19;94503:6;94491:19;;;;;;;;;;;;;;;;;;;;;;;;;94484:26;;94405:113;;;:::o;93072:699::-;93194:12;93236:10;93219:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;93209:39;;;;;;93194:54;;93283:53;93302:12;;93283:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93316:13;;93331:4;93283:18;:53::i;:::-;93261:128;;;;;;;;;;;;:::i;:::-;;;;;;;;;93429:5;93421;;:13;;;;:::i;:::-;93408:9;:26;;93400:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;93538:12;;93529:5;93501:25;93515:10;93501:13;:25::i;:::-;:33;;;;:::i;:::-;:49;;93479:120;;;;;;;;;;;;:::i;:::-;;;;;;;;;93643:9;;93634:5;93618:13;:11;:13::i;:::-;:21;;;;:::i;:::-;:34;;93610:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;93683:11;;;;;;;;;;;93675:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;93735:28;93745:10;93757:5;93735:9;:28::i;:::-;93183:588;93072:699;;;:::o;93779:502::-;93871:5;;93863;:13;;;;:::i;:::-;93850:9;:26;;93842:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;93954:9;;93945:5;93929:13;:11;:13::i;:::-;:21;;;;:::i;:::-;:34;;93921:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;94054:12;;94045:5;94017:25;94031:10;94017:13;:25::i;:::-;:33;;;;:::i;:::-;:49;;93995:123;;;;;;;;;;;;:::i;:::-;;;;;;;;;94145:1;94137:5;:9;94129:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;94191:13;;;;;;;;;;;94183:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;94245:28;94255:10;94267:5;94245:9;:28::i;:::-;93779:502;:::o;96673:206::-;56108:12;:10;:12::i;:::-;56097:23;;:7;:5;:7::i;:::-;:23;;;56089:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;96724:12:::1;96750:10;96742:24;;96788:21;96742:82;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96723:101;;;96843:7;96835:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;96712:167;96673:206::o:0;33747:185::-;33885:39;33902:4;33908:2;33912:7;33885:39;;;;;;;;;;;;:16;:39::i;:::-;33747:185;;;:::o;91240:31::-;;;;:::o;91675:28::-;;;;;;;;;;;;;:::o;95621:88::-;56108:12;:10;:12::i;:::-;56097:23;;:7;:5;:7::i;:::-;:23;;;56089:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;95698:3:::1;95688:7;:13;;;;;;;;;;;;:::i;:::-;;95621:88:::0;:::o;30089:144::-;30153:7;30196:27;30215:7;30196:18;:27::i;:::-;30173:52;;30089:144;;;:::o;95925:102::-;56108:12;:10;:12::i;:::-;56097:23;;:7;:5;:7::i;:::-;:23;;;56089:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;96009:10:::1;95997:9;:22;;;;95925:102:::0;:::o;25773:224::-;25837:7;25878:1;25861:19;;:5;:19;;;25857:60;;;25889:28;;;;;;;;;;;;;;25857:60;21068:13;25935:18;:25;25954:5;25935:25;;;;;;;;;;;;;;;;:54;25928:61;;25773:224;;;:::o;56528:103::-;56108:12;:10;:12::i;:::-;56097:23;;:7;:5;:7::i;:::-;:23;;;56089:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;56593:30:::1;56620:1;56593:18;:30::i;:::-;56528:103::o:0;95375:198::-;56108:12;:10;:12::i;:::-;56097:23;;:7;:5;:7::i;:::-;:23;;;56089:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;95510:14:::1;95500:7;:24;;;;95551:14;95535:13;:30;;;;95375:198:::0;;:::o;91560:106::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;55877:87::-;55923:7;55950:6;;;;;;;;;;;55943:13;;55877:87;:::o;95825:92::-;56108:12;:10;:12::i;:::-;56097:23;;:7;:5;:7::i;:::-;:23;;;56089:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;95900:9:::1;95892:5;:17;;;;95825:92:::0;:::o;30469:104::-;30525:13;30558:7;30551:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30469:104;:::o;91466:33::-;;;;;;;;;;;;;:::o;91278:35::-;;;;:::o;32814:340::-;32957:19;:17;:19::i;:::-;32945:31;;:8;:31;;;32941:61;;;32985:17;;;;;;;;;;;;;;32941:61;33067:8;33015:18;:39;33034:19;:17;:19::i;:::-;33015:39;;;;;;;;;;;;;;;:49;33055:8;33015:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;33127:8;33091:55;;33106:19;:17;:19::i;:::-;33091:55;;;33137:8;33091:55;;;;;;:::i;:::-;;;;;;;;32814:340;;:::o;96238:76::-;56108:12;:10;:12::i;:::-;56097:23;;:7;:5;:7::i;:::-;:23;;;56089:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;96298:8:::1;;;;;;;;;;;96297:9;96286:8;;:20;;;;;;;;;;;;;;;;;;96238:76::o:0;91322:35::-;;;;:::o;34003:396::-;34170:28;34180:4;34186:2;34190:7;34170:9;:28::i;:::-;34231:1;34213:2;:14;;;:19;34209:183;;34252:56;34283:4;34289:2;34293:7;34302:5;34252:30;:56::i;:::-;34247:145;;34336:40;;;;;;;;;;;;;;34247:145;34209:183;34003:396;;;;:::o;96035:94::-;56108:12;:10;:12::i;:::-;56097:23;;:7;:5;:7::i;:::-;:23;;;56089:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;96115:6:::1;96101:11;;:20;;;;;;;;;;;;;;;;;;96035:94:::0;:::o;96322:343::-;56108:12;:10;:12::i;:::-;56097:23;;:7;:5;:7::i;:::-;:23;;;56089:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;96456:1:::1;96442:11;:15;96434:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;96500:14;96517:13;:11;:13::i;:::-;96500:30;;96573:9;;96558:11;96549:6;:20;;;;:::i;:::-;:33;;96541:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;96622:35;96632:11;96645;96622:9;:35::i;:::-;96423:242;96322:343:::0;;:::o;94654:713::-;94772:13;94825:16;94833:7;94825;:16::i;:::-;94803:114;;;;;;;;;;;;:::i;:::-;;;;;;;;;94944:5;94932:17;;:8;;;;;;;;;;;:17;;;94928:66;;;94973:9;94966:16;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94928:66;95006:28;95037:10;:8;:10::i;:::-;95006:41;;95109:1;95084:14;95078:28;:32;:281;;;;;;;;;;;;;;;;;95202:14;95243:18;:7;:16;:18::i;:::-;95159:159;;;;;;;;;:::i;:::-;;;;;;;;;;;;;95078:281;95058:301;;;94654:713;;;;:::o;91428:31::-;;;;;;;;;;;;;:::o;91366:::-;;;;:::o;95717:100::-;56108:12;:10;:12::i;:::-;56097:23;;:7;:5;:7::i;:::-;:23;;;56089:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;95803:6:::1;95788:12;:21;;;;95717:100:::0;:::o;33225:214::-;33367:4;33396:18;:25;33415:5;33396:25;;;;;;;;;;;;;;;:35;33422:8;33396:35;;;;;;;;;;;;;;;;;;;;;;;;;33389:42;;33225:214;;;;:::o;94526:120::-;94589:7;94616:22;94630:7;94616:13;:22::i;:::-;94609:29;;94526:120;;;:::o;56786:238::-;56108:12;:10;:12::i;:::-;56097:23;;:7;:5;:7::i;:::-;:23;;;56089:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;56909:1:::1;56889:22;;:8;:22;;;;56867:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;56988:28;57007:8;56988:18;:28::i;:::-;56786:238:::0;:::o;96137:93::-;56108:12;:10;:12::i;:::-;56097:23;;:7;:5;:7::i;:::-;:23;;;56089:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;96216:6:::1;96200:13;;:22;;;;;;;;;;;;;;;;;;96137:93:::0;:::o;34654:273::-;34711:4;34767:7;34748:15;:13;:15::i;:::-;:26;;:66;;;;;34801:13;;34791:7;:23;34748:66;:152;;;;;34899:1;21838:8;34852:17;:26;34870:7;34852:26;;;;;;;;;;;;:43;:48;34748:152;34728:172;;34654:273;;;:::o;27476:1161::-;27570:7;27595:12;27610:7;27595:22;;27678:4;27659:15;:13;:15::i;:::-;:23;27655:915;;27712:13;;27705:4;:20;27701:869;;;27750:14;27767:17;:23;27785:4;27767:23;;;;;;;;;;;;27750:40;;27883:1;21838:8;27856:6;:23;:28;27852:699;;;28375:113;28392:1;28382:6;:11;28375:113;;;28435:17;:25;28453:6;;;;;;;28435:25;;;;;;;;;;;;28426:34;;28375:113;;;28521:6;28514:13;;;;;;27852:699;27727:843;27701:869;27655:915;28598:31;;;;;;;;;;;;;;27476:1161;;;;:::o;49022:105::-;49082:7;49109:10;49102:17;;49022:105;:::o;23622:92::-;23678:7;23622:92;:::o;4041:190::-;4166:4;4219;4190:25;4203:5;4210:4;4190:12;:25::i;:::-;:33;4183:40;;4041:190;;;;;:::o;26079:202::-;26140:7;21068:13;21205:2;26181:18;:25;26200:5;26181:25;;;;;;;;;;;;;;;;:49;;26180:93;26160:113;;26079:202;;;:::o;35011:104::-;35080:27;35090:2;35094:8;35080:27;;;;;;;;;;;;:9;:27::i;:::-;35011:104;;:::o;40152:2528::-;40267:27;40297;40316:7;40297:18;:27::i;:::-;40267:57;;40382:4;40341:45;;40357:19;40341:45;;;40337:99;;40408:28;;;;;;;;;;;;;;40337:99;40449:22;40498:4;40475:27;;:19;:17;:19::i;:::-;:27;;;:87;;;;40519:43;40536:4;40542:19;:17;:19::i;:::-;40519:16;:43::i;:::-;40475:87;:147;;;;40603:19;:17;:19::i;:::-;40579:43;;:20;40591:7;40579:11;:20::i;:::-;:43;;;40475:147;40449:174;;40641:17;40636:66;;40667:35;;;;;;;;;;;;;;40636:66;40731:1;40717:16;;:2;:16;;;40713:52;;;40742:23;;;;;;;;;;;;;;40713:52;40778:43;40800:4;40806:2;40810:7;40819:1;40778:21;:43::i;:::-;40894:15;:24;40910:7;40894:24;;;;;;;;;;;;40887:31;;;;;;;;;;;41286:18;:24;41305:4;41286:24;;;;;;;;;;;;;;;;41284:26;;;;;;;;;;;;41355:18;:22;41374:2;41355:22;;;;;;;;;;;;;;;;41353:24;;;;;;;;;;;22116:8;21722:3;41736:15;:41;;41694:21;41712:2;41694:17;:21::i;:::-;:84;:128;41648:17;:26;41666:7;41648:26;;;;;;;;;;;:174;;;;41992:1;22116:8;41942:19;:46;:51;41938:626;;;42014:19;42046:1;42036:7;:11;42014:33;;42203:1;42169:17;:30;42187:11;42169:30;;;;;;;;;;;;:35;42165:384;;;42307:13;;42292:11;:28;42288:242;;42487:19;42454:17;:30;42472:11;42454:30;;;;;;;;;;;:52;;;;42288:242;42165:384;41995:569;41938:626;42611:7;42607:2;42592:27;;42601:4;42592:27;;;;;;;;;;;;42630:42;42651:4;42657:2;42661:7;42670:1;42630:20;:42::i;:::-;40256:2424;;40152:2528;;;:::o;54527:98::-;54580:7;54607:10;54600:17;;54527:98;:::o;57184:191::-;57258:16;57277:6;;;;;;;;;;;57258:25;;57303:8;57294:6;;:17;;;;;;;;;;;;;;;;;;57358:8;57327:40;;57348:8;57327:40;;;;;;;;;;;;57247:128;57184:191;:::o;46376:831::-;46539:4;46598:2;46573:45;;;46637:19;:17;:19::i;:::-;46675:4;46698:7;46724:5;46573:171;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;46556:644;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46975:1;46958:6;:13;:18;46954:235;;;47004:40;;;;;;;;;;;;;;46954:235;47147:6;47141:13;47132:6;47128:2;47124:15;47117:38;46556:644;46844:54;;;46817:81;;;:6;:81;;;;46793:105;;;46376:831;;;;;;:::o;94289:108::-;94349:13;94382:7;94375:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94289:108;:::o;51698:723::-;51754:13;51984:1;51975:5;:10;51971:53;;;52002:10;;;;;;;;;;;;;;;;;;;;;51971:53;52034:12;52049:5;52034:20;;52065:14;52090:78;52105:1;52097:4;:9;52090:78;;52123:8;;;;;:::i;:::-;;;;52154:2;52146:10;;;;;:::i;:::-;;;52090:78;;;52178:19;52210:6;52200:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52178:39;;52228:154;52244:1;52235:5;:10;52228:154;;52272:1;52262:11;;;;;:::i;:::-;;;52339:2;52331:5;:10;;;;:::i;:::-;52318:2;:24;;;;:::i;:::-;52305:39;;52288:6;52295;52288:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;52368:2;52359:11;;;;;:::i;:::-;;;52228:154;;;52406:6;52392:21;;;;;51698:723;;;;:::o;4908:328::-;5018:7;5043:20;5066:4;5043:27;;5086:9;5081:118;5105:5;:12;5101:1;:16;5081:118;;;5154:33;5164:12;5178:5;5184:1;5178:8;;;;;;;;:::i;:::-;;;;;;;;5154:9;:33::i;:::-;5139:48;;5119:3;;;;;:::i;:::-;;;;5081:118;;;;5216:12;5209:19;;;4908:328;;;;:::o;35488:2461::-;35611:20;35634:13;;35611:36;;35676:1;35662:16;;:2;:16;;;35658:48;;;35687:19;;;;;;;;;;;;;;35658:48;35733:1;35721:8;:13;35717:44;;;35743:18;;;;;;;;;;;;;;35717:44;35774:61;35804:1;35808:2;35812:12;35826:8;35774:21;:61::i;:::-;36412:1;21205:2;36383:1;:25;;36382:31;36353:8;:61;36310:18;:22;36329:2;36310:22;;;;;;;;;;;;;;;;:104;;;;;;;;;;;21981:3;36813:29;36840:1;36828:8;:13;36813:14;:29::i;:::-;:56;;21722:3;36750:15;:41;;36708:21;36726:2;36708:17;:21::i;:::-;:84;:162;36657:17;:31;36675:12;36657:31;;;;;;;;;;;:213;;;;36887:20;36910:12;36887:35;;36937:11;36966:8;36951:12;:23;36937:37;;37013:1;36995:2;:14;;;:19;36991:826;;37035:504;37091:12;37087:2;37066:38;;37083:1;37066:38;;;;;;;;;;;;37158:212;37227:1;37260:2;37293:14;;;;;;37338:5;37158:30;:212::i;:::-;37127:365;;37428:40;;;;;;;;;;;;;;37127:365;37534:3;37519:12;:18;37035:504;;37620:12;37603:13;;:29;37599:43;;37634:8;;;37599:43;36991:826;;;37683:119;37739:14;;;;;;37735:2;37714:40;;37731:1;37714:40;;;;;;;;;;;;37797:3;37782:12;:18;37683:119;;36991:826;37847:12;37831:13;:28;;;;36087:1784;;37881:60;37910:1;37914:2;37918:12;37932:8;37881:20;:60::i;:::-;35600:2349;35488:2461;;;:::o;47855:159::-;;;;;:::o;31486:180::-;31577:14;31643:5;31633:15;;31486:180;;;:::o;48673:158::-;;;;;:::o;11389:149::-;11452:7;11483:1;11479;:5;:51;;11510:20;11525:1;11528;11510:14;:20::i;:::-;11479:51;;;11487:20;11502:1;11505;11487:14;:20::i;:::-;11479:51;11472:58;;11389:149;;;;:::o;31753:142::-;31811:14;31872:5;31862:15;;31753:142;;;:::o;11546:300::-;11641:13;11753:1;11747:4;11740:15;11782:1;11776:4;11769:15;11823:4;11817;11807:21;11798:30;;11546:300;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:307::-;1866:1;1876:113;1890:6;1887:1;1884:13;1876:113;;;1975:1;1970:3;1966:11;1960:18;1956:1;1951:3;1947:11;1940:39;1912:2;1909:1;1905:10;1900:15;;1876:113;;;2007:6;2004:1;2001:13;1998:101;;;2087:1;2078:6;2073:3;2069:16;2062:27;1998:101;1847:258;1798:307;;;:::o;2111:102::-;2152:6;2203:2;2199:7;2194:2;2187:5;2183:14;2179:28;2169:38;;2111:102;;;:::o;2219:364::-;2307:3;2335:39;2368:5;2335:39;:::i;:::-;2390:71;2454:6;2449:3;2390:71;:::i;:::-;2383:78;;2470:52;2515:6;2510:3;2503:4;2496:5;2492:16;2470:52;:::i;:::-;2547:29;2569:6;2547:29;:::i;:::-;2542:3;2538:39;2531:46;;2311:272;2219:364;;;;:::o;2589:313::-;2702:4;2740:2;2729:9;2725:18;2717:26;;2789:9;2783:4;2779:20;2775:1;2764:9;2760:17;2753:47;2817:78;2890:4;2881:6;2817:78;:::i;:::-;2809:86;;2589:313;;;;:::o;2908:77::-;2945:7;2974:5;2963:16;;2908:77;;;:::o;2991:122::-;3064:24;3082:5;3064:24;:::i;:::-;3057:5;3054:35;3044:63;;3103:1;3100;3093:12;3044:63;2991:122;:::o;3119:139::-;3165:5;3203:6;3190:20;3181:29;;3219:33;3246:5;3219:33;:::i;:::-;3119:139;;;;:::o;3264:329::-;3323:6;3372:2;3360:9;3351:7;3347:23;3343:32;3340:119;;;3378:79;;:::i;:::-;3340:119;3498:1;3523:53;3568:7;3559:6;3548:9;3544:22;3523:53;:::i;:::-;3513:63;;3469:117;3264:329;;;;:::o;3599:126::-;3636:7;3676:42;3669:5;3665:54;3654:65;;3599:126;;;:::o;3731:96::-;3768:7;3797:24;3815:5;3797:24;:::i;:::-;3786:35;;3731:96;;;:::o;3833:118::-;3920:24;3938:5;3920:24;:::i;:::-;3915:3;3908:37;3833:118;;:::o;3957:222::-;4050:4;4088:2;4077:9;4073:18;4065:26;;4101:71;4169:1;4158:9;4154:17;4145:6;4101:71;:::i;:::-;3957:222;;;;:::o;4185:122::-;4258:24;4276:5;4258:24;:::i;:::-;4251:5;4248:35;4238:63;;4297:1;4294;4287:12;4238:63;4185:122;:::o;4313:139::-;4359:5;4397:6;4384:20;4375:29;;4413:33;4440:5;4413:33;:::i;:::-;4313:139;;;;:::o;4458:474::-;4526:6;4534;4583:2;4571:9;4562:7;4558:23;4554:32;4551:119;;;4589:79;;:::i;:::-;4551:119;4709:1;4734:53;4779:7;4770:6;4759:9;4755:22;4734:53;:::i;:::-;4724:63;;4680:117;4836:2;4862:53;4907:7;4898:6;4887:9;4883:22;4862:53;:::i;:::-;4852:63;;4807:118;4458:474;;;;;:::o;4938:118::-;5025:24;5043:5;5025:24;:::i;:::-;5020:3;5013:37;4938:118;;:::o;5062:222::-;5155:4;5193:2;5182:9;5178:18;5170:26;;5206:71;5274:1;5263:9;5259:17;5250:6;5206:71;:::i;:::-;5062:222;;;;:::o;5290:117::-;5399:1;5396;5389:12;5413:117;5522:1;5519;5512:12;5536:117;5645:1;5642;5635:12;5676:568;5749:8;5759:6;5809:3;5802:4;5794:6;5790:17;5786:27;5776:122;;5817:79;;:::i;:::-;5776:122;5930:6;5917:20;5907:30;;5960:18;5952:6;5949:30;5946:117;;;5982:79;;:::i;:::-;5946:117;6096:4;6088:6;6084:17;6072:29;;6150:3;6142:4;6134:6;6130:17;6120:8;6116:32;6113:41;6110:128;;;6157:79;;:::i;:::-;6110:128;5676:568;;;;;:::o;6250:704::-;6345:6;6353;6361;6410:2;6398:9;6389:7;6385:23;6381:32;6378:119;;;6416:79;;:::i;:::-;6378:119;6564:1;6553:9;6549:17;6536:31;6594:18;6586:6;6583:30;6580:117;;;6616:79;;:::i;:::-;6580:117;6729:80;6801:7;6792:6;6781:9;6777:22;6729:80;:::i;:::-;6711:98;;;;6507:312;6858:2;6884:53;6929:7;6920:6;6909:9;6905:22;6884:53;:::i;:::-;6874:63;;6829:118;6250:704;;;;;:::o;6960:619::-;7037:6;7045;7053;7102:2;7090:9;7081:7;7077:23;7073:32;7070:119;;;7108:79;;:::i;:::-;7070:119;7228:1;7253:53;7298:7;7289:6;7278:9;7274:22;7253:53;:::i;:::-;7243:63;;7199:117;7355:2;7381:53;7426:7;7417:6;7406:9;7402:22;7381:53;:::i;:::-;7371:63;;7326:118;7483:2;7509:53;7554:7;7545:6;7534:9;7530:22;7509:53;:::i;:::-;7499:63;;7454:118;6960:619;;;;;:::o;7585:329::-;7644:6;7693:2;7681:9;7672:7;7668:23;7664:32;7661:119;;;7699:79;;:::i;:::-;7661:119;7819:1;7844:53;7889:7;7880:6;7869:9;7865:22;7844:53;:::i;:::-;7834:63;;7790:117;7585:329;;;;:::o;7920:117::-;8029:1;8026;8019:12;8043:180;8091:77;8088:1;8081:88;8188:4;8185:1;8178:15;8212:4;8209:1;8202:15;8229:281;8312:27;8334:4;8312:27;:::i;:::-;8304:6;8300:40;8442:6;8430:10;8427:22;8406:18;8394:10;8391:34;8388:62;8385:88;;;8453:18;;:::i;:::-;8385:88;8493:10;8489:2;8482:22;8272:238;8229:281;;:::o;8516:129::-;8550:6;8577:20;;:::i;:::-;8567:30;;8606:33;8634:4;8626:6;8606:33;:::i;:::-;8516:129;;;:::o;8651:308::-;8713:4;8803:18;8795:6;8792:30;8789:56;;;8825:18;;:::i;:::-;8789:56;8863:29;8885:6;8863:29;:::i;:::-;8855:37;;8947:4;8941;8937:15;8929:23;;8651:308;;;:::o;8965:154::-;9049:6;9044:3;9039;9026:30;9111:1;9102:6;9097:3;9093:16;9086:27;8965:154;;;:::o;9125:412::-;9203:5;9228:66;9244:49;9286:6;9244:49;:::i;:::-;9228:66;:::i;:::-;9219:75;;9317:6;9310:5;9303:21;9355:4;9348:5;9344:16;9393:3;9384:6;9379:3;9375:16;9372:25;9369:112;;;9400:79;;:::i;:::-;9369:112;9490:41;9524:6;9519:3;9514;9490:41;:::i;:::-;9209:328;9125:412;;;;;:::o;9557:340::-;9613:5;9662:3;9655:4;9647:6;9643:17;9639:27;9629:122;;9670:79;;:::i;:::-;9629:122;9787:6;9774:20;9812:79;9887:3;9879:6;9872:4;9864:6;9860:17;9812:79;:::i;:::-;9803:88;;9619:278;9557:340;;;;:::o;9903:509::-;9972:6;10021:2;10009:9;10000:7;9996:23;9992:32;9989:119;;;10027:79;;:::i;:::-;9989:119;10175:1;10164:9;10160:17;10147:31;10205:18;10197:6;10194:30;10191:117;;;10227:79;;:::i;:::-;10191:117;10332:63;10387:7;10378:6;10367:9;10363:22;10332:63;:::i;:::-;10322:73;;10118:287;9903:509;;;;:::o;10418:77::-;10455:7;10484:5;10473:16;;10418:77;;;:::o;10501:122::-;10574:24;10592:5;10574:24;:::i;:::-;10567:5;10564:35;10554:63;;10613:1;10610;10603:12;10554:63;10501:122;:::o;10629:139::-;10675:5;10713:6;10700:20;10691:29;;10729:33;10756:5;10729:33;:::i;:::-;10629:139;;;;:::o;10774:474::-;10842:6;10850;10899:2;10887:9;10878:7;10874:23;10870:32;10867:119;;;10905:79;;:::i;:::-;10867:119;11025:1;11050:53;11095:7;11086:6;11075:9;11071:22;11050:53;:::i;:::-;11040:63;;10996:117;11152:2;11178:53;11223:7;11214:6;11203:9;11199:22;11178:53;:::i;:::-;11168:63;;11123:118;10774:474;;;;;:::o;11254:116::-;11324:21;11339:5;11324:21;:::i;:::-;11317:5;11314:32;11304:60;;11360:1;11357;11350:12;11304:60;11254:116;:::o;11376:133::-;11419:5;11457:6;11444:20;11435:29;;11473:30;11497:5;11473:30;:::i;:::-;11376:133;;;;:::o;11515:468::-;11580:6;11588;11637:2;11625:9;11616:7;11612:23;11608:32;11605:119;;;11643:79;;:::i;:::-;11605:119;11763:1;11788:53;11833:7;11824:6;11813:9;11809:22;11788:53;:::i;:::-;11778:63;;11734:117;11890:2;11916:50;11958:7;11949:6;11938:9;11934:22;11916:50;:::i;:::-;11906:60;;11861:115;11515:468;;;;;:::o;11989:307::-;12050:4;12140:18;12132:6;12129:30;12126:56;;;12162:18;;:::i;:::-;12126:56;12200:29;12222:6;12200:29;:::i;:::-;12192:37;;12284:4;12278;12274:15;12266:23;;11989:307;;;:::o;12302:410::-;12379:5;12404:65;12420:48;12461:6;12420:48;:::i;:::-;12404:65;:::i;:::-;12395:74;;12492:6;12485:5;12478:21;12530:4;12523:5;12519:16;12568:3;12559:6;12554:3;12550:16;12547:25;12544:112;;;12575:79;;:::i;:::-;12544:112;12665:41;12699:6;12694:3;12689;12665:41;:::i;:::-;12385:327;12302:410;;;;;:::o;12731:338::-;12786:5;12835:3;12828:4;12820:6;12816:17;12812:27;12802:122;;12843:79;;:::i;:::-;12802:122;12960:6;12947:20;12985:78;13059:3;13051:6;13044:4;13036:6;13032:17;12985:78;:::i;:::-;12976:87;;12792:277;12731:338;;;;:::o;13075:943::-;13170:6;13178;13186;13194;13243:3;13231:9;13222:7;13218:23;13214:33;13211:120;;;13250:79;;:::i;:::-;13211:120;13370:1;13395:53;13440:7;13431:6;13420:9;13416:22;13395:53;:::i;:::-;13385:63;;13341:117;13497:2;13523:53;13568:7;13559:6;13548:9;13544:22;13523:53;:::i;:::-;13513:63;;13468:118;13625:2;13651:53;13696:7;13687:6;13676:9;13672:22;13651:53;:::i;:::-;13641:63;;13596:118;13781:2;13770:9;13766:18;13753:32;13812:18;13804:6;13801:30;13798:117;;;13834:79;;:::i;:::-;13798:117;13939:62;13993:7;13984:6;13973:9;13969:22;13939:62;:::i;:::-;13929:72;;13724:287;13075:943;;;;;;;:::o;14024:323::-;14080:6;14129:2;14117:9;14108:7;14104:23;14100:32;14097:119;;;14135:79;;:::i;:::-;14097:119;14255:1;14280:50;14322:7;14313:6;14302:9;14298:22;14280:50;:::i;:::-;14270:60;;14226:114;14024:323;;;;:::o;14353:474::-;14421:6;14429;14478:2;14466:9;14457:7;14453:23;14449:32;14446:119;;;14484:79;;:::i;:::-;14446:119;14604:1;14629:53;14674:7;14665:6;14654:9;14650:22;14629:53;:::i;:::-;14619:63;;14575:117;14731:2;14757:53;14802:7;14793:6;14782:9;14778:22;14757:53;:::i;:::-;14747:63;;14702:118;14353:474;;;;;:::o;14833:::-;14901:6;14909;14958:2;14946:9;14937:7;14933:23;14929:32;14926:119;;;14964:79;;:::i;:::-;14926:119;15084:1;15109:53;15154:7;15145:6;15134:9;15130:22;15109:53;:::i;:::-;15099:63;;15055:117;15211:2;15237:53;15282:7;15273:6;15262:9;15258:22;15237:53;:::i;:::-;15227:63;;15182:118;14833:474;;;;;:::o;15313:180::-;15361:77;15358:1;15351:88;15458:4;15455:1;15448:15;15482:4;15479:1;15472:15;15499:320;15543:6;15580:1;15574:4;15570:12;15560:22;;15627:1;15621:4;15617:12;15648:18;15638:81;;15704:4;15696:6;15692:17;15682:27;;15638:81;15766:2;15758:6;15755:14;15735:18;15732:38;15729:84;;;15785:18;;:::i;:::-;15729:84;15550:269;15499:320;;;:::o;15825:181::-;15965:33;15961:1;15953:6;15949:14;15942:57;15825:181;:::o;16012:366::-;16154:3;16175:67;16239:2;16234:3;16175:67;:::i;:::-;16168:74;;16251:93;16340:3;16251:93;:::i;:::-;16369:2;16364:3;16360:12;16353:19;;16012:366;;;:::o;16384:419::-;16550:4;16588:2;16577:9;16573:18;16565:26;;16637:9;16631:4;16627:20;16623:1;16612:9;16608:17;16601:47;16665:131;16791:4;16665:131;:::i;:::-;16657:139;;16384:419;;;:::o;16809:94::-;16842:8;16890:5;16886:2;16882:14;16861:35;;16809:94;;;:::o;16909:::-;16948:7;16977:20;16991:5;16977:20;:::i;:::-;16966:31;;16909:94;;;:::o;17009:100::-;17048:7;17077:26;17097:5;17077:26;:::i;:::-;17066:37;;17009:100;;;:::o;17115:157::-;17220:45;17240:24;17258:5;17240:24;:::i;:::-;17220:45;:::i;:::-;17215:3;17208:58;17115:157;;:::o;17278:256::-;17390:3;17405:75;17476:3;17467:6;17405:75;:::i;:::-;17505:2;17500:3;17496:12;17489:19;;17525:3;17518:10;;17278:256;;;;:::o;17540:180::-;17588:77;17585:1;17578:88;17685:4;17682:1;17675:15;17709:4;17706:1;17699:15;17726:191;17766:4;17786:20;17804:1;17786:20;:::i;:::-;17781:25;;17820:20;17838:1;17820:20;:::i;:::-;17815:25;;17859:1;17856;17853:8;17850:34;;;17864:18;;:::i;:::-;17850:34;17909:1;17906;17902:9;17894:17;;17726:191;;;;:::o;17923:348::-;17963:7;17986:20;18004:1;17986:20;:::i;:::-;17981:25;;18020:20;18038:1;18020:20;:::i;:::-;18015:25;;18208:1;18140:66;18136:74;18133:1;18130:81;18125:1;18118:9;18111:17;18107:105;18104:131;;;18215:18;;:::i;:::-;18104:131;18263:1;18260;18256:9;18245:20;;17923:348;;;;:::o;18277:179::-;18417:31;18413:1;18405:6;18401:14;18394:55;18277:179;:::o;18462:366::-;18604:3;18625:67;18689:2;18684:3;18625:67;:::i;:::-;18618:74;;18701:93;18790:3;18701:93;:::i;:::-;18819:2;18814:3;18810:12;18803:19;;18462:366;;;:::o;18834:419::-;19000:4;19038:2;19027:9;19023:18;19015:26;;19087:9;19081:4;19077:20;19073:1;19062:9;19058:17;19051:47;19115:131;19241:4;19115:131;:::i;:::-;19107:139;;18834:419;;;:::o;19259:175::-;19399:27;19395:1;19387:6;19383:14;19376:51;19259:175;:::o;19440:366::-;19582:3;19603:67;19667:2;19662:3;19603:67;:::i;:::-;19596:74;;19679:93;19768:3;19679:93;:::i;:::-;19797:2;19792:3;19788:12;19781:19;;19440:366;;;:::o;19812:419::-;19978:4;20016:2;20005:9;20001:18;19993:26;;20065:9;20059:4;20055:20;20051:1;20040:9;20036:17;20029:47;20093:131;20219:4;20093:131;:::i;:::-;20085:139;;19812:419;;;:::o;20237:305::-;20277:3;20296:20;20314:1;20296:20;:::i;:::-;20291:25;;20330:20;20348:1;20330:20;:::i;:::-;20325:25;;20484:1;20416:66;20412:74;20409:1;20406:81;20403:107;;;20490:18;;:::i;:::-;20403:107;20534:1;20531;20527:9;20520:16;;20237:305;;;;:::o;20548:157::-;20688:9;20684:1;20676:6;20672:14;20665:33;20548:157;:::o;20711:365::-;20853:3;20874:66;20938:1;20933:3;20874:66;:::i;:::-;20867:73;;20949:93;21038:3;20949:93;:::i;:::-;21067:2;21062:3;21058:12;21051:19;;20711:365;;;:::o;21082:419::-;21248:4;21286:2;21275:9;21271:18;21263:26;;21335:9;21329:4;21325:20;21321:1;21310:9;21306:17;21299:47;21363:131;21489:4;21363:131;:::i;:::-;21355:139;;21082:419;;;:::o;21507:171::-;21647:23;21643:1;21635:6;21631:14;21624:47;21507:171;:::o;21684:366::-;21826:3;21847:67;21911:2;21906:3;21847:67;:::i;:::-;21840:74;;21923:93;22012:3;21923:93;:::i;:::-;22041:2;22036:3;22032:12;22025:19;;21684:366;;;:::o;22056:419::-;22222:4;22260:2;22249:9;22245:18;22237:26;;22309:9;22303:4;22299:20;22295:1;22284:9;22280:17;22273:47;22337:131;22463:4;22337:131;:::i;:::-;22329:139;;22056:419;;;:::o;22481:173::-;22621:25;22617:1;22609:6;22605:14;22598:49;22481:173;:::o;22660:366::-;22802:3;22823:67;22887:2;22882:3;22823:67;:::i;:::-;22816:74;;22899:93;22988:3;22899:93;:::i;:::-;23017:2;23012:3;23008:12;23001:19;;22660:366;;;:::o;23032:419::-;23198:4;23236:2;23225:9;23221:18;23213:26;;23285:9;23279:4;23275:20;23271:1;23260:9;23256:17;23249:47;23313:131;23439:4;23313:131;:::i;:::-;23305:139;;23032:419;;;:::o;23457:174::-;23597:26;23593:1;23585:6;23581:14;23574:50;23457:174;:::o;23637:366::-;23779:3;23800:67;23864:2;23859:3;23800:67;:::i;:::-;23793:74;;23876:93;23965:3;23876:93;:::i;:::-;23994:2;23989:3;23985:12;23978:19;;23637:366;;;:::o;24009:419::-;24175:4;24213:2;24202:9;24198:18;24190:26;;24262:9;24256:4;24252:20;24248:1;24237:9;24233:17;24226:47;24290:131;24416:4;24290:131;:::i;:::-;24282:139;;24009:419;;;:::o;24434:171::-;24574:23;24570:1;24562:6;24558:14;24551:47;24434:171;:::o;24611:366::-;24753:3;24774:67;24838:2;24833:3;24774:67;:::i;:::-;24767:74;;24850:93;24939:3;24850:93;:::i;:::-;24968:2;24963:3;24959:12;24952:19;;24611:366;;;:::o;24983:419::-;25149:4;25187:2;25176:9;25172:18;25164:26;;25236:9;25230:4;25226:20;25222:1;25211:9;25207:17;25200:47;25264:131;25390:4;25264:131;:::i;:::-;25256:139;;24983:419;;;:::o;25408:166::-;25548:18;25544:1;25536:6;25532:14;25525:42;25408:166;:::o;25580:366::-;25722:3;25743:67;25807:2;25802:3;25743:67;:::i;:::-;25736:74;;25819:93;25908:3;25819:93;:::i;:::-;25937:2;25932:3;25928:12;25921:19;;25580:366;;;:::o;25952:419::-;26118:4;26156:2;26145:9;26141:18;26133:26;;26205:9;26199:4;26195:20;26191:1;26180:9;26176:17;26169:47;26233:131;26359:4;26233:131;:::i;:::-;26225:139;;25952:419;;;:::o;26377:182::-;26517:34;26513:1;26505:6;26501:14;26494:58;26377:182;:::o;26565:366::-;26707:3;26728:67;26792:2;26787:3;26728:67;:::i;:::-;26721:74;;26804:93;26893:3;26804:93;:::i;:::-;26922:2;26917:3;26913:12;26906:19;;26565:366;;;:::o;26937:419::-;27103:4;27141:2;27130:9;27126:18;27118:26;;27190:9;27184:4;27180:20;27176:1;27165:9;27161:17;27154:47;27218:131;27344:4;27218:131;:::i;:::-;27210:139;;26937:419;;;:::o;27362:147::-;27463:11;27500:3;27485:18;;27362:147;;;;:::o;27515:114::-;;:::o;27635:398::-;27794:3;27815:83;27896:1;27891:3;27815:83;:::i;:::-;27808:90;;27907:93;27996:3;27907:93;:::i;:::-;28025:1;28020:3;28016:11;28009:18;;27635:398;;;:::o;28039:379::-;28223:3;28245:147;28388:3;28245:147;:::i;:::-;28238:154;;28409:3;28402:10;;28039:379;;;:::o;28424:166::-;28564:18;28560:1;28552:6;28548:14;28541:42;28424:166;:::o;28596:366::-;28738:3;28759:67;28823:2;28818:3;28759:67;:::i;:::-;28752:74;;28835:93;28924:3;28835:93;:::i;:::-;28953:2;28948:3;28944:12;28937:19;;28596:366;;;:::o;28968:419::-;29134:4;29172:2;29161:9;29157:18;29149:26;;29221:9;29215:4;29211:20;29207:1;29196:9;29192:17;29185:47;29249:131;29375:4;29249:131;:::i;:::-;29241:139;;28968:419;;;:::o;29393:177::-;29533:29;29529:1;29521:6;29517:14;29510:53;29393:177;:::o;29576:366::-;29718:3;29739:67;29803:2;29798:3;29739:67;:::i;:::-;29732:74;;29815:93;29904:3;29815:93;:::i;:::-;29933:2;29928:3;29924:12;29917:19;;29576:366;;;:::o;29948:419::-;30114:4;30152:2;30141:9;30137:18;30129:26;;30201:9;30195:4;30191:20;30187:1;30176:9;30172:17;30165:47;30229:131;30355:4;30229:131;:::i;:::-;30221:139;;29948:419;;;:::o;30373:172::-;30513:24;30509:1;30501:6;30497:14;30490:48;30373:172;:::o;30551:366::-;30693:3;30714:67;30778:2;30773:3;30714:67;:::i;:::-;30707:74;;30790:93;30879:3;30790:93;:::i;:::-;30908:2;30903:3;30899:12;30892:19;;30551:366;;;:::o;30923:419::-;31089:4;31127:2;31116:9;31112:18;31104:26;;31176:9;31170:4;31166:20;31162:1;31151:9;31147:17;31140:47;31204:131;31330:4;31204:131;:::i;:::-;31196:139;;30923:419;;;:::o;31348:235::-;31488:34;31484:1;31476:6;31472:14;31465:58;31557:18;31552:2;31544:6;31540:15;31533:43;31348:235;:::o;31589:366::-;31731:3;31752:67;31816:2;31811:3;31752:67;:::i;:::-;31745:74;;31828:93;31917:3;31828:93;:::i;:::-;31946:2;31941:3;31937:12;31930:19;;31589:366;;;:::o;31961:419::-;32127:4;32165:2;32154:9;32150:18;32142:26;;32214:9;32208:4;32204:20;32200:1;32189:9;32185:17;32178:47;32242:131;32368:4;32242:131;:::i;:::-;32234:139;;31961:419;;;:::o;32386:148::-;32488:11;32525:3;32510:18;;32386:148;;;;:::o;32540:377::-;32646:3;32674:39;32707:5;32674:39;:::i;:::-;32729:89;32811:6;32806:3;32729:89;:::i;:::-;32722:96;;32827:52;32872:6;32867:3;32860:4;32853:5;32849:16;32827:52;:::i;:::-;32904:6;32899:3;32895:16;32888:23;;32650:267;32540:377;;;;:::o;32923:155::-;33063:7;33059:1;33051:6;33047:14;33040:31;32923:155;:::o;33084:400::-;33244:3;33265:84;33347:1;33342:3;33265:84;:::i;:::-;33258:91;;33358:93;33447:3;33358:93;:::i;:::-;33476:1;33471:3;33467:11;33460:18;;33084:400;;;:::o;33490:701::-;33771:3;33793:95;33884:3;33875:6;33793:95;:::i;:::-;33786:102;;33905:95;33996:3;33987:6;33905:95;:::i;:::-;33898:102;;34017:148;34161:3;34017:148;:::i;:::-;34010:155;;34182:3;34175:10;;33490:701;;;;;:::o;34197:225::-;34337:34;34333:1;34325:6;34321:14;34314:58;34406:8;34401:2;34393:6;34389:15;34382:33;34197:225;:::o;34428:366::-;34570:3;34591:67;34655:2;34650:3;34591:67;:::i;:::-;34584:74;;34667:93;34756:3;34667:93;:::i;:::-;34785:2;34780:3;34776:12;34769:19;;34428:366;;;:::o;34800:419::-;34966:4;35004:2;34993:9;34989:18;34981:26;;35053:9;35047:4;35043:20;35039:1;35028:9;35024:17;35017:47;35081:131;35207:4;35081:131;:::i;:::-;35073:139;;34800:419;;;:::o;35225:98::-;35276:6;35310:5;35304:12;35294:22;;35225:98;;;:::o;35329:168::-;35412:11;35446:6;35441:3;35434:19;35486:4;35481:3;35477:14;35462:29;;35329:168;;;;:::o;35503:360::-;35589:3;35617:38;35649:5;35617:38;:::i;:::-;35671:70;35734:6;35729:3;35671:70;:::i;:::-;35664:77;;35750:52;35795:6;35790:3;35783:4;35776:5;35772:16;35750:52;:::i;:::-;35827:29;35849:6;35827:29;:::i;:::-;35822:3;35818:39;35811:46;;35593:270;35503:360;;;;:::o;35869:640::-;36064:4;36102:3;36091:9;36087:19;36079:27;;36116:71;36184:1;36173:9;36169:17;36160:6;36116:71;:::i;:::-;36197:72;36265:2;36254:9;36250:18;36241:6;36197:72;:::i;:::-;36279;36347:2;36336:9;36332:18;36323:6;36279:72;:::i;:::-;36398:9;36392:4;36388:20;36383:2;36372:9;36368:18;36361:48;36426:76;36497:4;36488:6;36426:76;:::i;:::-;36418:84;;35869:640;;;;;;;:::o;36515:141::-;36571:5;36602:6;36596:13;36587:22;;36618:32;36644:5;36618:32;:::i;:::-;36515:141;;;;:::o;36662:349::-;36731:6;36780:2;36768:9;36759:7;36755:23;36751:32;36748:119;;;36786:79;;:::i;:::-;36748:119;36906:1;36931:63;36986:7;36977:6;36966:9;36962:22;36931:63;:::i;:::-;36921:73;;36877:127;36662:349;;;;:::o;37017:233::-;37056:3;37079:24;37097:5;37079:24;:::i;:::-;37070:33;;37125:66;37118:5;37115:77;37112:103;;;37195:18;;:::i;:::-;37112:103;37242:1;37235:5;37231:13;37224:20;;37017:233;;;:::o;37256:180::-;37304:77;37301:1;37294:88;37401:4;37398:1;37391:15;37425:4;37422:1;37415:15;37442:185;37482:1;37499:20;37517:1;37499:20;:::i;:::-;37494:25;;37533:20;37551:1;37533:20;:::i;:::-;37528:25;;37572:1;37562:35;;37577:18;;:::i;:::-;37562:35;37619:1;37616;37612:9;37607:14;;37442:185;;;;:::o;37633:176::-;37665:1;37682:20;37700:1;37682:20;:::i;:::-;37677:25;;37716:20;37734:1;37716:20;:::i;:::-;37711:25;;37755:1;37745:35;;37760:18;;:::i;:::-;37745:35;37801:1;37798;37794:9;37789:14;;37633:176;;;;:::o;37815:180::-;37863:77;37860:1;37853:88;37960:4;37957:1;37950:15;37984:4;37981:1;37974:15

Swarm Source

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