ETH Price: $3,917.84 (+5.63%)

Token

PonziBucks (PonziBucks)
 

Overview

Max Total Supply

810 PonziBucks

Holders

185

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
1 PonziBucks
0x70978daba5ed3ac4c3c5e7c32cdc55f55ccecc52
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:
PonziBucks

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-06-04
*/

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


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

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * 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.
 * OpenZeppelin's JavaScript library generates merkle trees that are safe
 * against this attack out of the box.
 */
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 simultaneously proven to be a part of a merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _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}
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _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 sibling nodes in `proof`. The reconstruction
     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
     * respectively.
     *
     * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuilds 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 from 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) {
            unchecked {
                return hashes[totalHashes - 1];
            }
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuilds 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 from 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) {
            unchecked {
                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/IERC721A.sol


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

pragma solidity ^0.8.4;

/**
 * @dev Interface of an ERC721A compliant contract.
 */


interface IERC721A {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

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

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

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

    /**
     * The `quantity` minted with ERC2309 exceeds the safety limit.
     */
    error MintERC2309QuantityExceedsLimit();

    /**
     * The `extraData` cannot be set on an unintialized ownership slot.
     */
    error OwnershipNotInitializedForExtraData();

    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;
        // Arbitrary data similar to `startTimestamp` that can be set through `_extraData`.
        uint24 extraData;
    }

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

    // ==============================
    //            IERC2309
    // ==============================

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId` (inclusive) is transferred from `from` to `to`,
     * as defined in the ERC2309 standard. See `_mintERC2309` for more details.
     */
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}
// File: contracts/ERC721A_royalty.sol


// ERC721A Contracts v4.1.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 bit position of `extraData` in packed ownership.
    uint256 private constant BITPOS_EXTRA_DATA = 232;

    // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`.
    uint256 private constant BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;

    // The mask of the lower 160 bits for addresses.
    uint256 private constant BITMASK_ADDRESS = (1 << 160) - 1;

    // The maximum `quantity` that can be minted with `_mintERC2309`.
    // This limit is to prevent overflows on the address data entries.
    // For a limit of 5000, a total of 3.689e15 calls to `_mintERC2309`
    // is required to cause an overflow, which is unrealistic.
    uint256 private constant MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;

    // 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`
    // - [232..255] `extraData`
    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 1;
    }

    /**
     * @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 == 0x2a55205a || // ERC 2981 rotyalty
            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 auxiliary 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 auxiliary 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;
        // Cast `aux` with assembly to avoid redundant masking.
        assembly {
            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;
        ownership.extraData = uint24(packed >> BITPOS_EXTRA_DATA);
    }

    /**
     * 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 Packs ownership data into a single uint256.
     */
    function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, BITMASK_ADDRESS)
            // `owner | (block.timestamp << BITPOS_START_TIMESTAMP) | flags`.
            result := or(owner, or(shl(BITPOS_START_TIMESTAMP, timestamp()), flags))
        }
    }

    /**
     * @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, it can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return '';
    }

    /**
     * @dev Returns the `nextInitialized` flag set if `quantity` equals 1.
     */
    function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
        // For branchless setting of the `nextInitialized` flag.
        assembly {
            // `(quantity == 1) << BITPOS_NEXT_INITIALIZED`.
            result := shl(BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
        }
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ownerOf(tokenId);
        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-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 {
        transferFrom(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.
     *
     * See {_mint}.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        _mint(to, quantity);

        unchecked {
            if (to.code.length != 0) {
                uint256 end = _currentIndex;
                uint256 index = end - quantity;
                do {
                    if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (index < end);
                // Reentrancy protection.
                if (_currentIndex != end) revert();
            }
        }
    }

    /**
     * @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 for each mint.
     */
    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` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _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] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            uint256 tokenId = startTokenId;
            uint256 end = startTokenId + quantity;
            do {
                emit Transfer(address(0), to, tokenId++);
            } while (tokenId < end);

            _currentIndex = end;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * This function is intended for efficient minting only during contract creation.
     *
     * It emits only one {ConsecutiveTransfer} as defined in
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
     * instead of a sequence of {Transfer} event(s).
     *
     * Calling this function outside of contract creation WILL make your contract
     * non-compliant with the ERC721 standard.
     * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
     * {ConsecutiveTransfer} event is only permissible during contract creation.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {ConsecutiveTransfer} event.
     */
    function _mintERC2309(address to, uint256 quantity) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();
        if (quantity > MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit();

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

        // Overflows are unrealistic due to the above check for `quantity` to be below the limit.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _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] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);

            _currentIndex = startTokenId + quantity;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Returns the storage slot and value for the approved address of `tokenId`.
     */
    function _getApprovedAddress(uint256 tokenId)
        private
        view
        returns (uint256 approvedAddressSlot, address approvedAddress)
    {
        mapping(uint256 => address) storage tokenApprovalsPtr = _tokenApprovals;
        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId]`.
        assembly {
            // Compute the slot.
            mstore(0x00, tokenId)
            mstore(0x20, tokenApprovalsPtr.slot)
            approvedAddressSlot := keccak256(0x00, 0x40)
            // Load the slot's value from storage.
            approvedAddress := sload(approvedAddressSlot)
        }
    }

    /**
     * @dev Returns whether the `approvedAddress` is equals to `from` or `msgSender`.
     */
    function _isOwnerOrApproved(
        address approvedAddress,
        address from,
        address msgSender
    ) private pure returns (bool result) {
        assembly {
            // Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean.
            from := and(from, BITMASK_ADDRESS)
            // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
            msgSender := and(msgSender, BITMASK_ADDRESS)
            // `msgSender == from || msgSender == approvedAddress`.
            result := or(eq(msgSender, from), eq(msgSender, approvedAddress))
        }
    }

    /**
     * @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 transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

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

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedAddress(tokenId);

        // The nested ifs save around 20+ gas over a compound boolean condition.
        if (!_isOwnerOrApproved(approvedAddress, from, _msgSenderERC721A()))
            if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();

        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // 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] = _packOwnershipData(
                to,
                BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
            );

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

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedAddress(tokenId);

        if (approvalCheck) {
            // The nested ifs save around 20+ gas over a compound boolean condition.
            if (!_isOwnerOrApproved(approvedAddress, from, _msgSenderERC721A()))
                if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
        }

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

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // 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] = _packOwnershipData(
                from,
                (BITMASK_BURNED | BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
            );

            // 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 Directly sets the extra data for the ownership data `index`.
     */
    function _setExtraDataAt(uint256 index, uint24 extraData) internal {
        uint256 packed = _packedOwnerships[index];
        if (packed == 0) revert OwnershipNotInitializedForExtraData();
        uint256 extraDataCasted;
        // Cast `extraData` with assembly to avoid redundant masking.
        assembly {
            extraDataCasted := extraData
        }
        packed = (packed & BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << BITPOS_EXTRA_DATA);
        _packedOwnerships[index] = packed;
    }

    /**
     * @dev Returns the next extra data for the packed ownership data.
     * The returned result is shifted into position.
     */
    function _nextExtraData(
        address from,
        address to,
        uint256 prevOwnershipPacked
    ) private view returns (uint256) {
        uint24 extraData = uint24(prevOwnershipPacked >> BITPOS_EXTRA_DATA);
        return uint256(_extraData(from, to, extraData)) << BITPOS_EXTRA_DATA;
    }

    /**
     * @dev Called during each token transfer to set the 24bit `extraData` field.
     * Intended to be overridden by the cosumer contract.
     *
     * `previousExtraData` - the value of `extraData` before transfer.
     *
     * 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 _extraData(
        address from,
        address to,
        uint24 previousExtraData
    ) internal view virtual returns (uint24) {}

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

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

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

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

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

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

            let length := sub(end, ptr)
            // Move the pointer 32 bytes leftwards to make room for the length.
            ptr := sub(ptr, 32)
            // Store the length.
            mstore(ptr, length)
        }
    }
}
// File: @openzeppelin/contracts/utils/math/SignedMath.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two signed numbers.
     */
    function min(int256 a, int256 b) internal pure returns (int256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

// File: @openzeppelin/contracts/utils/math/Math.sol


// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

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


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

pragma solidity ^0.8.0;



/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _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) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

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

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

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


// OpenZeppelin Contracts (last updated v4.9.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
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, "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");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or 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 {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol


// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol


// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;




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

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

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

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to
     * 0 before setting it to a non-zero value.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
     * Revert on invalid signature.
     */
    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

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

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

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
        // and not revert is the subcall reverts.

        (bool success, bytes memory returndata) = address(token).call(data);
        return
            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
    }
}

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


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

pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/contracts/finance/PaymentSplitter.sol


// OpenZeppelin Contracts (last updated v4.8.0) (finance/PaymentSplitter.sol)

pragma solidity ^0.8.0;




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

    uint256 private _totalShares;
    uint256 private _totalReleased;

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Getter for the amount of payee's releasable Ether.
     */
    function releasable(address account) public view returns (uint256) {
        uint256 totalReceived = address(this).balance + totalReleased();
        return _pendingPayment(account, totalReceived, released(account));
    }

    /**
     * @dev Getter for the amount of payee's releasable `token` tokens. `token` should be the address of an
     * IERC20 contract.
     */
    function releasable(IERC20 token, address account) public view returns (uint256) {
        uint256 totalReceived = token.balanceOf(address(this)) + totalReleased(token);
        return _pendingPayment(account, totalReceived, released(token, account));
    }

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

        uint256 payment = releasable(account);

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

        // _totalReleased is the sum of all values in _released.
        // If "_totalReleased += payment" does not overflow, then "_released[account] += payment" cannot overflow.
        _totalReleased += payment;
        unchecked {
            _released[account] += payment;
        }

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

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

        uint256 payment = releasable(token, account);

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

        // _erc20TotalReleased[token] is the sum of all values in _erc20Released[token].
        // If "_erc20TotalReleased[token] += payment" does not overflow, then "_erc20Released[token][account] += payment"
        // cannot overflow.
        _erc20TotalReleased[token] += payment;
        unchecked {
            _erc20Released[token][account] += payment;
        }

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

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

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

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

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

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

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

// File: contracts/PonziBucks.sol


pragma solidity ^0.8.18;






contract PonziBucks is Ownable, ERC721A, PaymentSplitter {

    using Strings for uint256;

    string public baseURI;

    bool public saleOn = false;
    bool public whitelistSaleOn = false;

    uint256 public MAX_SUPPLY = 1000;
    uint256 public MAX_PER_WALLET_PUBLIC = 5;
    uint256 public PUBLIC_TOTAL = 500;

    uint256 public SalePrice = 0.00053233 ether;

    uint256 private teamLength;

    uint96 royaltyFeesInBips;
    address royaltyReceiver;

    bytes32 public merkleRoot1px;
    bytes32 public merkleRootWL;

    mapping (address => bool) private _burners;
    address[] public burnerList;

    mapping(address => uint256) public amountNFTsperWalletPUBLIC;
    mapping(address => uint256) public amountNFTsperWallet1px;
    mapping(address => uint256) public amountNFTsperWalletWL;

    constructor(uint96 _royaltyFeesInBips, address[] memory _team, uint256[] memory _teamShares, string memory _baseURI) ERC721A("PonziBucks", "PonziBucks")
    PaymentSplitter(_team, _teamShares) {
        baseURI = _baseURI;
        teamLength = _team.length;
        royaltyFeesInBips = _royaltyFeesInBips;
        royaltyReceiver = msg.sender;
    }

    modifier callerIsUser() {
        require(tx.origin == msg.sender, "The caller is another contract");
        _;
    }

    function currentTime() internal view returns(uint256) {
        return block.timestamp;
    }
    //MINTING
    function publicSaleMint(uint256 _quantity) external payable callerIsUser {
        require(saleOn == true, "Public sale is not activated");
        require(amountNFTsperWalletPUBLIC[msg.sender] + _quantity <= MAX_PER_WALLET_PUBLIC, "Max per wallet limit reached");
        require(totalSupply() + _quantity <= PUBLIC_TOTAL, "Max allocated amount exceeded");
        require(totalSupply() + _quantity <= MAX_SUPPLY,"Max supply exceeded");
        require(msg.value >= SalePrice * _quantity, "Not enought funds");
        amountNFTsperWalletPUBLIC[msg.sender] += _quantity;
        _safeMint(msg.sender, _quantity);
    }
    function holders1pxMint(bytes32[] calldata _proof) external payable callerIsUser{
        require(whitelistSaleOn == true, "Whitelist sale is not activated");
        require(isWhiteListed1px(msg.sender, _proof), "Not whitelisted");
        require(amountNFTsperWallet1px[msg.sender] + 3 <= 3, "Max per wallet limit reached");
        require(totalSupply() + 3 <= MAX_SUPPLY,"Max supply exceeded");
        require(msg.value >= SalePrice * 3, "Not enought funds");
        amountNFTsperWallet1px[msg.sender] += 3;
        _safeMint(msg.sender, 3);
    }
    function whitelistMint(bytes32[] calldata _proof) external payable callerIsUser{
        require(whitelistSaleOn == true, "Whitelist sale is not activated");
        require(isWhiteListedWL(msg.sender, _proof), "Not whitelisted");
        require(amountNFTsperWalletWL[msg.sender] + 1 <= 1, "Max per wallet limit reached");
        require(totalSupply() + 1 <= MAX_SUPPLY,"Max supply exceeded");
        require(msg.value >= SalePrice, "Not enought funds");
        amountNFTsperWalletWL[msg.sender] += 1;
        _safeMint(msg.sender, 1);
    }

    function gift(address _to, uint _quantity) external onlyOwner {
        _safeMint(_to, _quantity);
    }
    function burn(uint256 tokenId) public {
        require(msg.sender == ownerOf(tokenId), "You don't own it");
        require(!_burners[msg.sender], "You have already burnt an NFT");

        _burn(tokenId);

        _burners[msg.sender] = true;
        burnerList.push(msg.sender);
    }
    function getBurnerList() public view returns (address[] memory) {
        return burnerList;
    }
    //ADMIN
    function setSalePrice(uint _SalePrice) external onlyOwner {
        SalePrice = _SalePrice;
    }
    function setBaseUri(string memory _baseURI) external onlyOwner {
        baseURI = _baseURI;
    }
    function setSale(bool _saleOn, bool _whitelistSaleOn) external onlyOwner {
        saleOn = _saleOn;
        whitelistSaleOn = _whitelistSaleOn;
    }
    function lowerSupply(uint256 _MAX_SUPPLY) external onlyOwner {
        require(_MAX_SUPPLY < MAX_SUPPLY, "Cannot increase supply!");
        MAX_SUPPLY = _MAX_SUPPLY;
    }
    function setMaxPublic(uint256 _PUBLIC_TOTAL) external onlyOwner {
        PUBLIC_TOTAL = _PUBLIC_TOTAL;
    }
    function setMaxPerWalletPUBLIC(uint256 _MAX_PER_WALLET_PUBLIC)
        external
        onlyOwner
    {
        MAX_PER_WALLET_PUBLIC = _MAX_PER_WALLET_PUBLIC;
    }
    function setMerkleRootWL(bytes32 _merkleRootWL) external onlyOwner {
        merkleRootWL = _merkleRootWL;
    }
    function setMerkleRoot1px(bytes32 _merkleRoot1px) external onlyOwner {
        merkleRoot1px = _merkleRoot1px;
    }
    function isWhiteListedWL(address _account, bytes32[] calldata _proof)
        internal
        view
        returns (bool)
    {
        return _verifyWL(leaf(_account), _proof);
    }
     function isWhiteListed1px(address _account, bytes32[] calldata _proof)
        internal
        view
        returns (bool)
    {
        return _verify1px(leaf(_account), _proof);
    }

    function leaf(address _account) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked(_account));
    }

    function _verifyWL(bytes32 _leaf, bytes32[] memory _proof)
        internal
        view
        returns (bool)
    {
        return MerkleProof.verify(_proof, merkleRootWL, _leaf);
    }
    function _verify1px(bytes32 _leaf, bytes32[] memory _proof)
        internal
        view
        returns (bool)
    {
        return MerkleProof.verify(_proof, merkleRoot1px, _leaf);
    }
    function tokenURI(uint _tokenId) public view virtual override returns (string memory) {
        require(_exists(_tokenId), "URI query for nonexistent token");
        if(_tokenId % 2 == 0){
        return string(abi.encodePacked(baseURI, "front.json"));
        }
        else
            return string(abi.encodePacked(baseURI, "back.json"));
    }

    // ROYALTY
    function royaltyInfo (
    uint256 _tokenId,
    uint256 _salePrice
     ) external view returns (
        address receiver,
        uint256 royaltyAmount
     ){
         return (royaltyReceiver, calculateRoyalty(_salePrice));
     }

    function calculateRoyalty(uint256 _salePrice) view public returns (uint256){
        return(_salePrice / 10000) * royaltyFeesInBips;
    }

    function setRoyaltyInfo (address _receiver, uint96 _royaltyFeesInBips) public onlyOwner {
        royaltyReceiver = _receiver;
        royaltyFeesInBips = _royaltyFeesInBips;
    }

    //WITHDRAW
    function releaseAll() external onlyOwner {
        for(uint i = 0 ; i < teamLength ; i++) {
            release(payable(payee(i)));
        }
    }

    receive() override external payable {
        revert('Only if you mint');
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint96","name":"_royaltyFeesInBips","type":"uint96"},{"internalType":"address[]","name":"_team","type":"address[]"},{"internalType":"uint256[]","name":"_teamShares","type":"uint256[]"},{"internalType":"string","name":"_baseURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"PayeeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_PER_WALLET_PUBLIC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PUBLIC_TOTAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SalePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"amountNFTsperWallet1px","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"amountNFTsperWalletPUBLIC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"amountNFTsperWalletWL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"burnerList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"calculateRoyalty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBurnerList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"gift","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"holders1pxMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_MAX_SUPPLY","type":"uint256"}],"name":"lowerSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"merkleRoot1px","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRootWL","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"payee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"publicSaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"releasable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"releasable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"releaseAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleOn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_MAX_PER_WALLET_PUBLIC","type":"uint256"}],"name":"setMaxPerWalletPUBLIC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_PUBLIC_TOTAL","type":"uint256"}],"name":"setMaxPublic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot1px","type":"bytes32"}],"name":"setMerkleRoot1px","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRootWL","type":"bytes32"}],"name":"setMerkleRootWL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint96","name":"_royaltyFeesInBips","type":"uint96"}],"name":"setRoyaltyInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_saleOn","type":"bool"},{"internalType":"bool","name":"_whitelistSaleOn","type":"bool"}],"name":"setSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_SalePrice","type":"uint256"}],"name":"setSalePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"whitelistSaleOn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040526011805461ffff191690556103e860125560056013556101f46014556601e426bc8da4006015553480156200003857600080fd5b5060405162003a6338038062003a638339810160408190526200005b9162000601565b82826040518060400160405280600a815260200169506f6e7a694275636b7360b01b8152506040518060400160405280600a815260200169506f6e7a694275636b7360b01b815250620000bd620000b76200025060201b60201c565b62000254565b6003620000cb8382620007b7565b506004620000da8282620007b7565b506001805550508051825114620001535760405162461bcd60e51b815260206004820152603260248201527f5061796d656e7453706c69747465723a2070617965657320616e6420736861726044820152710cae640d8cadccee8d040dad2e6dac2e8c6d60731b60648201526084015b60405180910390fd5b6000825111620001a65760405162461bcd60e51b815260206004820152601a60248201527f5061796d656e7453706c69747465723a206e6f2070617965657300000000000060448201526064016200014a565b60005b82518110156200021257620001fd838281518110620001cc57620001cc62000883565b6020026020010151838381518110620001e957620001e962000883565b6020026020010151620002a460201b60201c565b806200020981620008af565b915050620001a9565b50601091506200022590508282620007b7565b50509051601655506001600160601b0316336c010000000000000000000000000217601755620008e7565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038216620003115760405162461bcd60e51b815260206004820152602c60248201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060448201526b7a65726f206164647265737360a01b60648201526084016200014a565b60008111620003635760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a2073686172657320617265203000000060448201526064016200014a565b6001600160a01b0382166000908152600b602052604090205415620003df5760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e7420616c726561647960448201526a206861732073686172657360a81b60648201526084016200014a565b600d8054600181019091557fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b0319166001600160a01b0384169081179091556000908152600b6020526040902081905560095462000449908290620008cb565b600955604080516001600160a01b0384168152602081018390527f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac910160405180910390a15050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620004d357620004d362000492565b604052919050565b60006001600160401b03821115620004f757620004f762000492565b5060051b60200190565b600082601f8301126200051357600080fd5b815160206200052c6200052683620004db565b620004a8565b82815260059290921b840181019181810190868411156200054c57600080fd5b8286015b8481101562000569578051835291830191830162000550565b509695505050505050565b600082601f8301126200058657600080fd5b81516001600160401b03811115620005a257620005a262000492565b6020620005b8601f8301601f19168201620004a8565b8281528582848701011115620005cd57600080fd5b60005b83811015620005ed578581018301518282018401528201620005d0565b506000928101909101919091529392505050565b600080600080608085870312156200061857600080fd5b84516001600160601b03811681146200063057600080fd5b602086810151919550906001600160401b03808211156200065057600080fd5b818801915088601f8301126200066557600080fd5b8151620006766200052682620004db565b81815260059190911b8301840190848101908b8311156200069657600080fd5b938501935b82851015620006cd5784516001600160a01b0381168114620006bd5760008081fd5b825293850193908501906200069b565b60408b01519098509450505080831115620006e757600080fd5b620006f589848a0162000501565b945060608801519250808311156200070c57600080fd5b50506200071c8782880162000574565b91505092959194509250565b600181811c908216806200073d57607f821691505b6020821081036200075e57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620007b257600081815260208120601f850160051c810160208610156200078d5750805b601f850160051c820191505b81811015620007ae5782815560010162000799565b5050505b505050565b81516001600160401b03811115620007d357620007d362000492565b620007eb81620007e4845462000728565b8462000764565b602080601f8311600181146200082357600084156200080a5750858301515b600019600386901b1c1916600185901b178555620007ae565b600085815260208120601f198616915b82811015620008545788860151825594840194600190910190840162000833565b5085821015620008735787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620008c457620008c462000899565b5060010190565b80820180821115620008e157620008e162000899565b92915050565b61316c80620008f76000396000f3fe6080604052600436106103905760003560e01c80638da5cb5b116101dc578063c45ac05011610102578063d79779b2116100a0578063ee82e5a01161006f578063ee82e5a014610b0c578063f15e309e14610b2c578063f2fde38b14610b59578063fbdb849414610b7957600080fd5b8063d79779b214610a62578063db72a75914610a98578063e33b7de314610aae578063e985e9c514610ac357600080fd5b8063cbce4c97116100dc578063cbce4c97146109e3578063ce7c2ac214610a03578063d6492d8114610a39578063d72cc78c14610a4f57600080fd5b8063c45ac05014610983578063c7153816146109a3578063c87b56dd146109c357600080fd5b8063a22cb4651161017a578063ac0cbfb811610149578063ac0cbfb814610910578063ad3e31b714610930578063b3ab66b014610950578063b88d4fde1461096357600080fd5b8063a22cb46514610890578063a2e69613146108b0578063a3f8eace146108d0578063abd8e23d146108f057600080fd5b806395d89b41116101b657806395d89b41146108035780639852595c146108185780639ae19a281461084e578063a0bcfc7f1461087057600080fd5b80638da5cb5b1461078b5780638eb478a6146107a9578063952aeab8146107d657600080fd5b8063406072a9116102c157806364affb401161025f57806374ed870d1161022e57806374ed870d1461071c578063773ef1cf1461073b57806379dd3082146107555780638b83209b1461076b57600080fd5b806364affb40146106bc5780636c0360eb146106d257806370a08231146106e7578063715018a61461070757600080fd5b806348b750441161029b57806348b750441461064757806355cf5912146106675780635be7fde8146106875780636352211e1461069c57600080fd5b8063406072a9146105c157806342842e0e1461060757806342966c681461062757600080fd5b8063191655871161032e5780632a55205a116103085780632a55205a1461054457806332cb6b0c14610583578063372f657c146105995780633a98ef39146105ac57600080fd5b806319165587146104e45780631919fed71461050457806323b872dd1461052457600080fd5b8063081812fc1161036a578063081812fc14610453578063095ea7b31461048b5780631292af48146104ab57806318160ddd146104cf57600080fd5b806301ffc9a7146103da57806302fa7c471461040f57806306fdde031461043157600080fd5b366103d55760405162461bcd60e51b815260206004820152601060248201526f13db9b1e481a59881e5bdd481b5a5b9d60821b60448201526064015b60405180910390fd5b600080fd5b3480156103e657600080fd5b506103fa6103f5366004612837565b610b99565b60405190151581526020015b60405180910390f35b34801561041b57600080fd5b5061042f61042a366004612869565b610c06565b005b34801561043d57600080fd5b50610446610c3d565b60405161040691906128fe565b34801561045f57600080fd5b5061047361046e366004612911565b610ccf565b6040516001600160a01b039091168152602001610406565b34801561049757600080fd5b5061042f6104a636600461292a565b610d13565b3480156104b757600080fd5b506104c160185481565b604051908152602001610406565b3480156104db57600080fd5b506104c1610db3565b3480156104f057600080fd5b5061042f6104ff366004612956565b610dc1565b34801561051057600080fd5b5061042f61051f366004612911565b610ea8565b34801561053057600080fd5b5061042f61053f366004612973565b610eb5565b34801561055057600080fd5b5061056461055f3660046129b4565b611058565b604080516001600160a01b039093168352602083019190915201610406565b34801561058f57600080fd5b506104c160125481565b61042f6105a73660046129d6565b611084565b3480156105b857600080fd5b506009546104c1565b3480156105cd57600080fd5b506104c16105dc366004612a4b565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205490565b34801561061357600080fd5b5061042f610622366004612973565b61120f565b34801561063357600080fd5b5061042f610642366004612911565b61122f565b34801561065357600080fd5b5061042f610662366004612a4b565b611353565b34801561067357600080fd5b5061042f610682366004612911565b611464565b34801561069357600080fd5b5061042f611471565b3480156106a857600080fd5b506104736106b7366004612911565b6114a7565b3480156106c857600080fd5b506104c160135481565b3480156106de57600080fd5b506104466114b2565b3480156106f357600080fd5b506104c1610702366004612956565b611540565b34801561071357600080fd5b5061042f61158f565b34801561072857600080fd5b506011546103fa90610100900460ff1681565b34801561074757600080fd5b506011546103fa9060ff1681565b34801561076157600080fd5b506104c160145481565b34801561077757600080fd5b50610473610786366004612911565b6115a3565b34801561079757600080fd5b506000546001600160a01b0316610473565b3480156107b557600080fd5b506104c16107c4366004612956565b601c6020526000908152604090205481565b3480156107e257600080fd5b506104c16107f1366004612956565b601e6020526000908152604090205481565b34801561080f57600080fd5b506104466115d3565b34801561082457600080fd5b506104c1610833366004612956565b6001600160a01b03166000908152600c602052604090205490565b34801561085a57600080fd5b506108636115e2565b6040516104069190612a79565b34801561087c57600080fd5b5061042f61088b366004612b52565b611643565b34801561089c57600080fd5b5061042f6108ab366004612ba9565b611657565b3480156108bc57600080fd5b506104c16108cb366004612911565b6116ec565b3480156108dc57600080fd5b506104c16108eb366004612956565b611711565b3480156108fc57600080fd5b5061047361090b366004612911565b611759565b34801561091c57600080fd5b5061042f61092b366004612911565b611783565b34801561093c57600080fd5b5061042f61094b366004612911565b611790565b61042f61095e366004612911565b61179d565b34801561096f57600080fd5b5061042f61097e366004612bd7565b611943565b34801561098f57600080fd5b506104c161099e366004612a4b565b61198d565b3480156109af57600080fd5b5061042f6109be366004612911565b611a58565b3480156109cf57600080fd5b506104466109de366004612911565b611ab6565b3480156109ef57600080fd5b5061042f6109fe36600461292a565b611b59565b348015610a0f57600080fd5b506104c1610a1e366004612956565b6001600160a01b03166000908152600b602052604090205490565b348015610a4557600080fd5b506104c160195481565b61042f610a5d3660046129d6565b611b6b565b348015610a6e57600080fd5b506104c1610a7d366004612956565b6001600160a01b03166000908152600e602052604090205490565b348015610aa457600080fd5b506104c160155481565b348015610aba57600080fd5b50600a546104c1565b348015610acf57600080fd5b506103fa610ade366004612a4b565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205460ff1690565b348015610b1857600080fd5b5061042f610b27366004612c57565b611cfd565b348015610b3857600080fd5b506104c1610b47366004612956565b601d6020526000908152604090205481565b348015610b6557600080fd5b5061042f610b74366004612956565b611d29565b348015610b8557600080fd5b5061042f610b94366004612911565b611d9f565b60006301ffc9a760e01b6001600160e01b031983161480610bca57506380ac58cd60e01b6001600160e01b03198316145b80610be5575063152a902d60e11b6001600160e01b03198316145b80610c005750635b5e139f60e01b6001600160e01b03198316145b92915050565b610c0e611dac565b6001600160601b03166001600160a01b03909116600160601b026bffffffffffffffffffffffff191617601755565b606060038054610c4c90612c75565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7890612c75565b8015610cc55780601f10610c9a57610100808354040283529160200191610cc5565b820191906000526020600020905b815481529060010190602001808311610ca857829003601f168201915b5050505050905090565b6000610cda82611e06565b610cf7576040516333d1c03960e21b815260040160405180910390fd5b506000908152600760205260409020546001600160a01b031690565b6000610d1e826114a7565b9050336001600160a01b03821614610d5757610d3a8133610ade565b610d57576040516367d9dca160e11b815260040160405180910390fd5b60008281526007602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600254600154036000190190565b6001600160a01b0381166000908152600b6020526040902054610df65760405162461bcd60e51b81526004016103cc90612caf565b6000610e0182611711565b905080600003610e235760405162461bcd60e51b81526004016103cc90612cf5565b80600a6000828254610e359190612d56565b90915550506001600160a01b0382166000908152600c60205260409020805482019055610e628282611e3b565b604080516001600160a01b0384168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a15050565b610eb0611dac565b601555565b6000610ec082611f54565b9050836001600160a01b0316816001600160a01b031614610ef35760405162a1148160e81b815260040160405180910390fd5b60008281526007602052604090208054610f1f8187335b6001600160a01b039081169116811491141790565b610f4a57610f2d8633610ade565b610f4a57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516610f7157604051633a954ecd60e21b815260040160405180910390fd5b8015610f7c57600082555b6001600160a01b038681166000908152600660205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260056020526040812091909155600160e11b8416900361100e5760018401600081815260056020526040812054900361100c57600154811461100c5760008181526005602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b6017546000908190600160601b90046001600160a01b0316611079846116ec565b915091509250929050565b3233146110a35760405162461bcd60e51b81526004016103cc90612d69565b60115460ff6101009091041615156001146111005760405162461bcd60e51b815260206004820152601f60248201527f57686974656c6973742073616c65206973206e6f74206163746976617465640060448201526064016103cc565b61110b338383611fc3565b6111495760405162461bcd60e51b815260206004820152600f60248201526e139bdd081dda1a5d195b1a5cdd1959608a1b60448201526064016103cc565b336000908152601e60205260409020546001906111669082612d56565b11156111845760405162461bcd60e51b81526004016103cc90612da0565b60125461118f610db3565b61119a906001612d56565b11156111b85760405162461bcd60e51b81526004016103cc90612dd7565b6015543410156111da5760405162461bcd60e51b81526004016103cc90612e04565b336000908152601e602052604081208054600192906111fa908490612d56565b9091555061120b905033600161200a565b5050565b61122a83838360405180602001604052806000815250611943565b505050565b611238816114a7565b6001600160a01b0316336001600160a01b03161461128b5760405162461bcd60e51b815260206004820152601060248201526f165bdd48191bdb89dd081bdddb881a5d60821b60448201526064016103cc565b336000908152601a602052604090205460ff16156112eb5760405162461bcd60e51b815260206004820152601d60248201527f596f75206861766520616c7265616479206275726e7420616e204e465400000060448201526064016103cc565b6112f481612024565b50336000818152601a60205260408120805460ff19166001908117909155601b805491820181559091527f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc10180546001600160a01b0319169091179055565b6001600160a01b0381166000908152600b60205260409020546113885760405162461bcd60e51b81526004016103cc90612caf565b6000611394838361198d565b9050806000036113b65760405162461bcd60e51b81526004016103cc90612cf5565b6001600160a01b0383166000908152600e6020526040812080548392906113de908490612d56565b90915550506001600160a01b038084166000908152600f6020908152604080832093861683529290522080548201905561141983838361202f565b604080516001600160a01b038481168252602082018490528516917f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a910160405180910390a2505050565b61146c611dac565b601355565b611479611dac565b60005b6016548110156114a4576114926104ff826115a3565b8061149c81612e2f565b91505061147c565b50565b6000610c0082611f54565b601080546114bf90612c75565b80601f01602080910402602001604051908101604052809291908181526020018280546114eb90612c75565b80156115385780601f1061150d57610100808354040283529160200191611538565b820191906000526020600020905b81548152906001019060200180831161151b57829003601f168201915b505050505081565b60006001600160a01b038216611569576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526006602052604090205467ffffffffffffffff1690565b611597611dac565b6115a16000612081565b565b6000600d82815481106115b8576115b8612e48565b6000918252602090912001546001600160a01b031692915050565b606060048054610c4c90612c75565b6060601b805480602002602001604051908101604052809291908181526020018280548015610cc557602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161161c575050505050905090565b61164b611dac565b601061120b8282612ea4565b336001600160a01b038316036116805760405163b06307db60e01b815260040160405180910390fd5b3360008181526008602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6017546000906001600160601b031661170761271084612f7a565b610c009190612f8e565b60008061171d600a5490565b6117279047612d56565b9050611752838261174d866001600160a01b03166000908152600c602052604090205490565b6120d1565b9392505050565b601b818154811061176957600080fd5b6000918252602090912001546001600160a01b0316905081565b61178b611dac565b601855565b611798611dac565b601955565b3233146117bc5760405162461bcd60e51b81526004016103cc90612d69565b60115460ff1615156001146118135760405162461bcd60e51b815260206004820152601c60248201527f5075626c69632073616c65206973206e6f74206163746976617465640000000060448201526064016103cc565b601354336000908152601c6020526040902054611831908390612d56565b111561184f5760405162461bcd60e51b81526004016103cc90612da0565b6014548161185b610db3565b6118659190612d56565b11156118b35760405162461bcd60e51b815260206004820152601d60248201527f4d617820616c6c6f636174656420616d6f756e7420657863656564656400000060448201526064016103cc565b601254816118bf610db3565b6118c99190612d56565b11156118e75760405162461bcd60e51b81526004016103cc90612dd7565b806015546118f59190612f8e565b3410156119145760405162461bcd60e51b81526004016103cc90612e04565b336000908152601c602052604081208054839290611933908490612d56565b909155506114a49050338261200a565b61194e848484610eb5565b6001600160a01b0383163b156119875761196a8484848461210f565b611987576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6001600160a01b0382166000908152600e602052604081205481906040516370a0823160e01b81523060048201526001600160a01b038616906370a0823190602401602060405180830381865afa1580156119ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a109190612fa5565b611a1a9190612d56565b6001600160a01b038086166000908152600f6020908152604080832093881683529290522054909150611a5090849083906120d1565b949350505050565b611a60611dac565b6012548110611ab15760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f7420696e63726561736520737570706c792100000000000000000060448201526064016103cc565b601255565b6060611ac182611e06565b611b0d5760405162461bcd60e51b815260206004820152601f60248201527f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e0060448201526064016103cc565b611b18600283612fbe565b600003611b47576010604051602001611b319190613045565b6040516020818303038152906040529050919050565b6010604051602001611b31919061306b565b611b61611dac565b61120b828261200a565b323314611b8a5760405162461bcd60e51b81526004016103cc90612d69565b60115460ff610100909104161515600114611be75760405162461bcd60e51b815260206004820152601f60248201527f57686974656c6973742073616c65206973206e6f74206163746976617465640060448201526064016103cc565b611bf23383836121fa565b611c305760405162461bcd60e51b815260206004820152600f60248201526e139bdd081dda1a5d195b1a5cdd1959608a1b60448201526064016103cc565b336000908152601d6020526040902054600390611c4d9082612d56565b1115611c6b5760405162461bcd60e51b81526004016103cc90612da0565b601254611c76610db3565b611c81906003612d56565b1115611c9f5760405162461bcd60e51b81526004016103cc90612dd7565b601554611cad906003612f8e565b341015611ccc5760405162461bcd60e51b81526004016103cc90612e04565b336000908152601d60205260408120805460039290611cec908490612d56565b9091555061120b905033600361200a565b611d05611dac565b6011805461ffff191692151561ff0019169290921761010091151591909102179055565b611d31611dac565b6001600160a01b038116611d965760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103cc565b6114a481612081565b611da7611dac565b601455565b6000546001600160a01b031633146115a15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103cc565b600081600111158015611e1a575060015482105b8015610c00575050600090815260056020526040902054600160e01b161590565b80471015611e8b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016103cc565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611ed8576040519150601f19603f3d011682016040523d82523d6000602084013e611edd565b606091505b505090508061122a5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016103cc565b60008180600111611faa57600154811015611faa5760008181526005602052604081205490600160e01b82169003611fa8575b80600003611752575060001901600081815260056020526040902054611f87565b505b604051636f96cda160e11b815260040160405180910390fd5b6000611a50611fd185612241565b84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061228092505050565b61120b82826040518060200160405280600081525061228f565b6114a48160006122fc565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261122a908490612447565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6009546001600160a01b0384166000908152600b6020526040812054909183916120fb9086612f8e565b6121059190612f7a565b611a509190613090565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906121449033908990889088906004016130a3565b6020604051808303816000875af192505050801561217f575060408051601f3d908101601f1916820190925261217c918101906130e0565b60015b6121dd573d8080156121ad576040519150601f19603f3d011682016040523d82523d6000602084013e6121b2565b606091505b5080516000036121d5576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b6000611a5061220885612241565b84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061251c92505050565b6040516bffffffffffffffffffffffff19606083901b166020820152600090603401604051602081830303815290604052805190602001209050919050565b60006117528260195485612527565b612299838361253d565b6001600160a01b0383163b1561122a576001548281035b6122c3600086838060010194508661210f565b6122e0576040516368d2bf6b60e11b815260040160405180910390fd5b8181106122b05781600154146122f557600080fd5b5050505050565b600061230783611f54565b90508060008061232586600090815260076020526040902080549091565b9150915084156123655761233a818433610f0a565b612365576123488333610ade565b61236557604051632ce44b5f60e11b815260040160405180910390fd5b801561237057600082555b6001600160a01b038316600081815260066020526040902080546fffffffffffffffffffffffffffffffff0190554260a01b17600360e01b17600087815260056020526040812091909155600160e11b851690036123fe576001860160008181526005602052604081205490036123fc5760015481146123fc5760008181526005602052604090208590555b505b60405186906000906001600160a01b038616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a4505060028054600101905550505050565b600061249c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661261d9092919063ffffffff16565b90508051600014806124bd5750808060200190518101906124bd91906130fd565b61122a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016103cc565b600061175282601854855b600082612534858461262c565b14949350505050565b6001546001600160a01b03831661256657604051622e076360e81b815260040160405180910390fd5b816000036125875760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600081815260066020526040902080546801000000000000000185020190554260a01b6001841460e11b1717600082815260056020526040902055808281015b6040516001830192906001600160a01b038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a48082106125d15760015550505050565b6060611a508484600085612679565b600081815b84518110156126715761265d8286838151811061265057612650612e48565b6020026020010151612754565b91508061266981612e2f565b915050612631565b509392505050565b6060824710156126da5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016103cc565b600080866001600160a01b031685876040516126f6919061311a565b60006040518083038185875af1925050503d8060008114612733576040519150601f19603f3d011682016040523d82523d6000602084013e612738565b606091505b509150915061274987838387612783565b979650505050505050565b6000818310612770576000828152602084905260409020611752565b6000838152602083905260409020611752565b606083156127f25782516000036127eb576001600160a01b0385163b6127eb5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103cc565b5081611a50565b611a5083838151156128075781518083602001fd5b8060405162461bcd60e51b81526004016103cc91906128fe565b6001600160e01b0319811681146114a457600080fd5b60006020828403121561284957600080fd5b813561175281612821565b6001600160a01b03811681146114a457600080fd5b6000806040838503121561287c57600080fd5b823561288781612854565b915060208301356001600160601b03811681146128a357600080fd5b809150509250929050565b60005b838110156128c95781810151838201526020016128b1565b50506000910152565b600081518084526128ea8160208601602086016128ae565b601f01601f19169290920160200192915050565b60208152600061175260208301846128d2565b60006020828403121561292357600080fd5b5035919050565b6000806040838503121561293d57600080fd5b823561294881612854565b946020939093013593505050565b60006020828403121561296857600080fd5b813561175281612854565b60008060006060848603121561298857600080fd5b833561299381612854565b925060208401356129a381612854565b929592945050506040919091013590565b600080604083850312156129c757600080fd5b50508035926020909101359150565b600080602083850312156129e957600080fd5b823567ffffffffffffffff80821115612a0157600080fd5b818501915085601f830112612a1557600080fd5b813581811115612a2457600080fd5b8660208260051b8501011115612a3957600080fd5b60209290920196919550909350505050565b60008060408385031215612a5e57600080fd5b8235612a6981612854565b915060208301356128a381612854565b6020808252825182820181905260009190848201906040850190845b81811015612aba5783516001600160a01b031683529284019291840191600101612a95565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612af757612af7612ac6565b604051601f8501601f19908116603f01168101908282118183101715612b1f57612b1f612ac6565b81604052809350858152868686011115612b3857600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215612b6457600080fd5b813567ffffffffffffffff811115612b7b57600080fd5b8201601f81018413612b8c57600080fd5b611a5084823560208401612adc565b80151581146114a457600080fd5b60008060408385031215612bbc57600080fd5b8235612bc781612854565b915060208301356128a381612b9b565b60008060008060808587031215612bed57600080fd5b8435612bf881612854565b93506020850135612c0881612854565b925060408501359150606085013567ffffffffffffffff811115612c2b57600080fd5b8501601f81018713612c3c57600080fd5b612c4b87823560208401612adc565b91505092959194509250565b60008060408385031215612c6a57600080fd5b8235612bc781612b9b565b600181811c90821680612c8957607f821691505b602082108103612ca957634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526026908201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060408201526573686172657360d01b606082015260800190565b6020808252602b908201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060408201526a191d59481c185e5b595b9d60aa1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b80820180821115610c0057610c00612d40565b6020808252601e908201527f5468652063616c6c657220697320616e6f7468657220636f6e74726163740000604082015260600190565b6020808252601c908201527f4d6178207065722077616c6c6574206c696d6974207265616368656400000000604082015260600190565b60208082526013908201527213585e081cdd5c1c1b1e48195e18d959591959606a1b604082015260600190565b6020808252601190820152704e6f7420656e6f756768742066756e647360781b604082015260600190565b600060018201612e4157612e41612d40565b5060010190565b634e487b7160e01b600052603260045260246000fd5b601f82111561122a57600081815260208120601f850160051c81016020861015612e855750805b601f850160051c820191505b8181101561105057828155600101612e91565b815167ffffffffffffffff811115612ebe57612ebe612ac6565b612ed281612ecc8454612c75565b84612e5e565b602080601f831160018114612f075760008415612eef5750858301515b600019600386901b1c1916600185901b178555611050565b600085815260208120601f198616915b82811015612f3657888601518255948401946001909101908401612f17565b5085821015612f545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601260045260246000fd5b600082612f8957612f89612f64565b500490565b8082028115828204841417610c0057610c00612d40565b600060208284031215612fb757600080fd5b5051919050565b600082612fcd57612fcd612f64565b500690565b60008154612fdf81612c75565b60018281168015612ff7576001811461300c5761303b565b60ff198416875282151583028701945061303b565b8560005260208060002060005b858110156130325781548a820152908401908201613019565b50505082870194505b5050505092915050565b60006130518284612fd2565b69333937b73a173539b7b760b11b8152600a019392505050565b60006130778284612fd2565b683130b1b5973539b7b760b91b81526009019392505050565b81810381811115610c0057610c00612d40565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906130d6908301846128d2565b9695505050505050565b6000602082840312156130f257600080fd5b815161175281612821565b60006020828403121561310f57600080fd5b815161175281612b9b565b6000825161312c8184602087016128ae565b919091019291505056fea26469706673582212206bc3e27dd703a62d70837ba66c69d31046f3c20a912d817bc91ef51bd5f26ffa64736f6c634300081200330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000003b416f02227c65930d23137bdcad2866172b69a1000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000043697066733a2f2f6261667962656962346a7a6a626c70666a363473326f69673633633266353472767578653535336169647a76353335366d37626f7535706c6e7a792f0000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106103905760003560e01c80638da5cb5b116101dc578063c45ac05011610102578063d79779b2116100a0578063ee82e5a01161006f578063ee82e5a014610b0c578063f15e309e14610b2c578063f2fde38b14610b59578063fbdb849414610b7957600080fd5b8063d79779b214610a62578063db72a75914610a98578063e33b7de314610aae578063e985e9c514610ac357600080fd5b8063cbce4c97116100dc578063cbce4c97146109e3578063ce7c2ac214610a03578063d6492d8114610a39578063d72cc78c14610a4f57600080fd5b8063c45ac05014610983578063c7153816146109a3578063c87b56dd146109c357600080fd5b8063a22cb4651161017a578063ac0cbfb811610149578063ac0cbfb814610910578063ad3e31b714610930578063b3ab66b014610950578063b88d4fde1461096357600080fd5b8063a22cb46514610890578063a2e69613146108b0578063a3f8eace146108d0578063abd8e23d146108f057600080fd5b806395d89b41116101b657806395d89b41146108035780639852595c146108185780639ae19a281461084e578063a0bcfc7f1461087057600080fd5b80638da5cb5b1461078b5780638eb478a6146107a9578063952aeab8146107d657600080fd5b8063406072a9116102c157806364affb401161025f57806374ed870d1161022e57806374ed870d1461071c578063773ef1cf1461073b57806379dd3082146107555780638b83209b1461076b57600080fd5b806364affb40146106bc5780636c0360eb146106d257806370a08231146106e7578063715018a61461070757600080fd5b806348b750441161029b57806348b750441461064757806355cf5912146106675780635be7fde8146106875780636352211e1461069c57600080fd5b8063406072a9146105c157806342842e0e1461060757806342966c681461062757600080fd5b8063191655871161032e5780632a55205a116103085780632a55205a1461054457806332cb6b0c14610583578063372f657c146105995780633a98ef39146105ac57600080fd5b806319165587146104e45780631919fed71461050457806323b872dd1461052457600080fd5b8063081812fc1161036a578063081812fc14610453578063095ea7b31461048b5780631292af48146104ab57806318160ddd146104cf57600080fd5b806301ffc9a7146103da57806302fa7c471461040f57806306fdde031461043157600080fd5b366103d55760405162461bcd60e51b815260206004820152601060248201526f13db9b1e481a59881e5bdd481b5a5b9d60821b60448201526064015b60405180910390fd5b600080fd5b3480156103e657600080fd5b506103fa6103f5366004612837565b610b99565b60405190151581526020015b60405180910390f35b34801561041b57600080fd5b5061042f61042a366004612869565b610c06565b005b34801561043d57600080fd5b50610446610c3d565b60405161040691906128fe565b34801561045f57600080fd5b5061047361046e366004612911565b610ccf565b6040516001600160a01b039091168152602001610406565b34801561049757600080fd5b5061042f6104a636600461292a565b610d13565b3480156104b757600080fd5b506104c160185481565b604051908152602001610406565b3480156104db57600080fd5b506104c1610db3565b3480156104f057600080fd5b5061042f6104ff366004612956565b610dc1565b34801561051057600080fd5b5061042f61051f366004612911565b610ea8565b34801561053057600080fd5b5061042f61053f366004612973565b610eb5565b34801561055057600080fd5b5061056461055f3660046129b4565b611058565b604080516001600160a01b039093168352602083019190915201610406565b34801561058f57600080fd5b506104c160125481565b61042f6105a73660046129d6565b611084565b3480156105b857600080fd5b506009546104c1565b3480156105cd57600080fd5b506104c16105dc366004612a4b565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205490565b34801561061357600080fd5b5061042f610622366004612973565b61120f565b34801561063357600080fd5b5061042f610642366004612911565b61122f565b34801561065357600080fd5b5061042f610662366004612a4b565b611353565b34801561067357600080fd5b5061042f610682366004612911565b611464565b34801561069357600080fd5b5061042f611471565b3480156106a857600080fd5b506104736106b7366004612911565b6114a7565b3480156106c857600080fd5b506104c160135481565b3480156106de57600080fd5b506104466114b2565b3480156106f357600080fd5b506104c1610702366004612956565b611540565b34801561071357600080fd5b5061042f61158f565b34801561072857600080fd5b506011546103fa90610100900460ff1681565b34801561074757600080fd5b506011546103fa9060ff1681565b34801561076157600080fd5b506104c160145481565b34801561077757600080fd5b50610473610786366004612911565b6115a3565b34801561079757600080fd5b506000546001600160a01b0316610473565b3480156107b557600080fd5b506104c16107c4366004612956565b601c6020526000908152604090205481565b3480156107e257600080fd5b506104c16107f1366004612956565b601e6020526000908152604090205481565b34801561080f57600080fd5b506104466115d3565b34801561082457600080fd5b506104c1610833366004612956565b6001600160a01b03166000908152600c602052604090205490565b34801561085a57600080fd5b506108636115e2565b6040516104069190612a79565b34801561087c57600080fd5b5061042f61088b366004612b52565b611643565b34801561089c57600080fd5b5061042f6108ab366004612ba9565b611657565b3480156108bc57600080fd5b506104c16108cb366004612911565b6116ec565b3480156108dc57600080fd5b506104c16108eb366004612956565b611711565b3480156108fc57600080fd5b5061047361090b366004612911565b611759565b34801561091c57600080fd5b5061042f61092b366004612911565b611783565b34801561093c57600080fd5b5061042f61094b366004612911565b611790565b61042f61095e366004612911565b61179d565b34801561096f57600080fd5b5061042f61097e366004612bd7565b611943565b34801561098f57600080fd5b506104c161099e366004612a4b565b61198d565b3480156109af57600080fd5b5061042f6109be366004612911565b611a58565b3480156109cf57600080fd5b506104466109de366004612911565b611ab6565b3480156109ef57600080fd5b5061042f6109fe36600461292a565b611b59565b348015610a0f57600080fd5b506104c1610a1e366004612956565b6001600160a01b03166000908152600b602052604090205490565b348015610a4557600080fd5b506104c160195481565b61042f610a5d3660046129d6565b611b6b565b348015610a6e57600080fd5b506104c1610a7d366004612956565b6001600160a01b03166000908152600e602052604090205490565b348015610aa457600080fd5b506104c160155481565b348015610aba57600080fd5b50600a546104c1565b348015610acf57600080fd5b506103fa610ade366004612a4b565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205460ff1690565b348015610b1857600080fd5b5061042f610b27366004612c57565b611cfd565b348015610b3857600080fd5b506104c1610b47366004612956565b601d6020526000908152604090205481565b348015610b6557600080fd5b5061042f610b74366004612956565b611d29565b348015610b8557600080fd5b5061042f610b94366004612911565b611d9f565b60006301ffc9a760e01b6001600160e01b031983161480610bca57506380ac58cd60e01b6001600160e01b03198316145b80610be5575063152a902d60e11b6001600160e01b03198316145b80610c005750635b5e139f60e01b6001600160e01b03198316145b92915050565b610c0e611dac565b6001600160601b03166001600160a01b03909116600160601b026bffffffffffffffffffffffff191617601755565b606060038054610c4c90612c75565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7890612c75565b8015610cc55780601f10610c9a57610100808354040283529160200191610cc5565b820191906000526020600020905b815481529060010190602001808311610ca857829003601f168201915b5050505050905090565b6000610cda82611e06565b610cf7576040516333d1c03960e21b815260040160405180910390fd5b506000908152600760205260409020546001600160a01b031690565b6000610d1e826114a7565b9050336001600160a01b03821614610d5757610d3a8133610ade565b610d57576040516367d9dca160e11b815260040160405180910390fd5b60008281526007602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600254600154036000190190565b6001600160a01b0381166000908152600b6020526040902054610df65760405162461bcd60e51b81526004016103cc90612caf565b6000610e0182611711565b905080600003610e235760405162461bcd60e51b81526004016103cc90612cf5565b80600a6000828254610e359190612d56565b90915550506001600160a01b0382166000908152600c60205260409020805482019055610e628282611e3b565b604080516001600160a01b0384168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a15050565b610eb0611dac565b601555565b6000610ec082611f54565b9050836001600160a01b0316816001600160a01b031614610ef35760405162a1148160e81b815260040160405180910390fd5b60008281526007602052604090208054610f1f8187335b6001600160a01b039081169116811491141790565b610f4a57610f2d8633610ade565b610f4a57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516610f7157604051633a954ecd60e21b815260040160405180910390fd5b8015610f7c57600082555b6001600160a01b038681166000908152600660205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260056020526040812091909155600160e11b8416900361100e5760018401600081815260056020526040812054900361100c57600154811461100c5760008181526005602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b6017546000908190600160601b90046001600160a01b0316611079846116ec565b915091509250929050565b3233146110a35760405162461bcd60e51b81526004016103cc90612d69565b60115460ff6101009091041615156001146111005760405162461bcd60e51b815260206004820152601f60248201527f57686974656c6973742073616c65206973206e6f74206163746976617465640060448201526064016103cc565b61110b338383611fc3565b6111495760405162461bcd60e51b815260206004820152600f60248201526e139bdd081dda1a5d195b1a5cdd1959608a1b60448201526064016103cc565b336000908152601e60205260409020546001906111669082612d56565b11156111845760405162461bcd60e51b81526004016103cc90612da0565b60125461118f610db3565b61119a906001612d56565b11156111b85760405162461bcd60e51b81526004016103cc90612dd7565b6015543410156111da5760405162461bcd60e51b81526004016103cc90612e04565b336000908152601e602052604081208054600192906111fa908490612d56565b9091555061120b905033600161200a565b5050565b61122a83838360405180602001604052806000815250611943565b505050565b611238816114a7565b6001600160a01b0316336001600160a01b03161461128b5760405162461bcd60e51b815260206004820152601060248201526f165bdd48191bdb89dd081bdddb881a5d60821b60448201526064016103cc565b336000908152601a602052604090205460ff16156112eb5760405162461bcd60e51b815260206004820152601d60248201527f596f75206861766520616c7265616479206275726e7420616e204e465400000060448201526064016103cc565b6112f481612024565b50336000818152601a60205260408120805460ff19166001908117909155601b805491820181559091527f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc10180546001600160a01b0319169091179055565b6001600160a01b0381166000908152600b60205260409020546113885760405162461bcd60e51b81526004016103cc90612caf565b6000611394838361198d565b9050806000036113b65760405162461bcd60e51b81526004016103cc90612cf5565b6001600160a01b0383166000908152600e6020526040812080548392906113de908490612d56565b90915550506001600160a01b038084166000908152600f6020908152604080832093861683529290522080548201905561141983838361202f565b604080516001600160a01b038481168252602082018490528516917f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a910160405180910390a2505050565b61146c611dac565b601355565b611479611dac565b60005b6016548110156114a4576114926104ff826115a3565b8061149c81612e2f565b91505061147c565b50565b6000610c0082611f54565b601080546114bf90612c75565b80601f01602080910402602001604051908101604052809291908181526020018280546114eb90612c75565b80156115385780601f1061150d57610100808354040283529160200191611538565b820191906000526020600020905b81548152906001019060200180831161151b57829003601f168201915b505050505081565b60006001600160a01b038216611569576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526006602052604090205467ffffffffffffffff1690565b611597611dac565b6115a16000612081565b565b6000600d82815481106115b8576115b8612e48565b6000918252602090912001546001600160a01b031692915050565b606060048054610c4c90612c75565b6060601b805480602002602001604051908101604052809291908181526020018280548015610cc557602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161161c575050505050905090565b61164b611dac565b601061120b8282612ea4565b336001600160a01b038316036116805760405163b06307db60e01b815260040160405180910390fd5b3360008181526008602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6017546000906001600160601b031661170761271084612f7a565b610c009190612f8e565b60008061171d600a5490565b6117279047612d56565b9050611752838261174d866001600160a01b03166000908152600c602052604090205490565b6120d1565b9392505050565b601b818154811061176957600080fd5b6000918252602090912001546001600160a01b0316905081565b61178b611dac565b601855565b611798611dac565b601955565b3233146117bc5760405162461bcd60e51b81526004016103cc90612d69565b60115460ff1615156001146118135760405162461bcd60e51b815260206004820152601c60248201527f5075626c69632073616c65206973206e6f74206163746976617465640000000060448201526064016103cc565b601354336000908152601c6020526040902054611831908390612d56565b111561184f5760405162461bcd60e51b81526004016103cc90612da0565b6014548161185b610db3565b6118659190612d56565b11156118b35760405162461bcd60e51b815260206004820152601d60248201527f4d617820616c6c6f636174656420616d6f756e7420657863656564656400000060448201526064016103cc565b601254816118bf610db3565b6118c99190612d56565b11156118e75760405162461bcd60e51b81526004016103cc90612dd7565b806015546118f59190612f8e565b3410156119145760405162461bcd60e51b81526004016103cc90612e04565b336000908152601c602052604081208054839290611933908490612d56565b909155506114a49050338261200a565b61194e848484610eb5565b6001600160a01b0383163b156119875761196a8484848461210f565b611987576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6001600160a01b0382166000908152600e602052604081205481906040516370a0823160e01b81523060048201526001600160a01b038616906370a0823190602401602060405180830381865afa1580156119ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a109190612fa5565b611a1a9190612d56565b6001600160a01b038086166000908152600f6020908152604080832093881683529290522054909150611a5090849083906120d1565b949350505050565b611a60611dac565b6012548110611ab15760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f7420696e63726561736520737570706c792100000000000000000060448201526064016103cc565b601255565b6060611ac182611e06565b611b0d5760405162461bcd60e51b815260206004820152601f60248201527f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e0060448201526064016103cc565b611b18600283612fbe565b600003611b47576010604051602001611b319190613045565b6040516020818303038152906040529050919050565b6010604051602001611b31919061306b565b611b61611dac565b61120b828261200a565b323314611b8a5760405162461bcd60e51b81526004016103cc90612d69565b60115460ff610100909104161515600114611be75760405162461bcd60e51b815260206004820152601f60248201527f57686974656c6973742073616c65206973206e6f74206163746976617465640060448201526064016103cc565b611bf23383836121fa565b611c305760405162461bcd60e51b815260206004820152600f60248201526e139bdd081dda1a5d195b1a5cdd1959608a1b60448201526064016103cc565b336000908152601d6020526040902054600390611c4d9082612d56565b1115611c6b5760405162461bcd60e51b81526004016103cc90612da0565b601254611c76610db3565b611c81906003612d56565b1115611c9f5760405162461bcd60e51b81526004016103cc90612dd7565b601554611cad906003612f8e565b341015611ccc5760405162461bcd60e51b81526004016103cc90612e04565b336000908152601d60205260408120805460039290611cec908490612d56565b9091555061120b905033600361200a565b611d05611dac565b6011805461ffff191692151561ff0019169290921761010091151591909102179055565b611d31611dac565b6001600160a01b038116611d965760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103cc565b6114a481612081565b611da7611dac565b601455565b6000546001600160a01b031633146115a15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103cc565b600081600111158015611e1a575060015482105b8015610c00575050600090815260056020526040902054600160e01b161590565b80471015611e8b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016103cc565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611ed8576040519150601f19603f3d011682016040523d82523d6000602084013e611edd565b606091505b505090508061122a5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016103cc565b60008180600111611faa57600154811015611faa5760008181526005602052604081205490600160e01b82169003611fa8575b80600003611752575060001901600081815260056020526040902054611f87565b505b604051636f96cda160e11b815260040160405180910390fd5b6000611a50611fd185612241565b84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061228092505050565b61120b82826040518060200160405280600081525061228f565b6114a48160006122fc565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261122a908490612447565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6009546001600160a01b0384166000908152600b6020526040812054909183916120fb9086612f8e565b6121059190612f7a565b611a509190613090565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906121449033908990889088906004016130a3565b6020604051808303816000875af192505050801561217f575060408051601f3d908101601f1916820190925261217c918101906130e0565b60015b6121dd573d8080156121ad576040519150601f19603f3d011682016040523d82523d6000602084013e6121b2565b606091505b5080516000036121d5576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b6000611a5061220885612241565b84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061251c92505050565b6040516bffffffffffffffffffffffff19606083901b166020820152600090603401604051602081830303815290604052805190602001209050919050565b60006117528260195485612527565b612299838361253d565b6001600160a01b0383163b1561122a576001548281035b6122c3600086838060010194508661210f565b6122e0576040516368d2bf6b60e11b815260040160405180910390fd5b8181106122b05781600154146122f557600080fd5b5050505050565b600061230783611f54565b90508060008061232586600090815260076020526040902080549091565b9150915084156123655761233a818433610f0a565b612365576123488333610ade565b61236557604051632ce44b5f60e11b815260040160405180910390fd5b801561237057600082555b6001600160a01b038316600081815260066020526040902080546fffffffffffffffffffffffffffffffff0190554260a01b17600360e01b17600087815260056020526040812091909155600160e11b851690036123fe576001860160008181526005602052604081205490036123fc5760015481146123fc5760008181526005602052604090208590555b505b60405186906000906001600160a01b038616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a4505060028054600101905550505050565b600061249c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661261d9092919063ffffffff16565b90508051600014806124bd5750808060200190518101906124bd91906130fd565b61122a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016103cc565b600061175282601854855b600082612534858461262c565b14949350505050565b6001546001600160a01b03831661256657604051622e076360e81b815260040160405180910390fd5b816000036125875760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600081815260066020526040902080546801000000000000000185020190554260a01b6001841460e11b1717600082815260056020526040902055808281015b6040516001830192906001600160a01b038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a48082106125d15760015550505050565b6060611a508484600085612679565b600081815b84518110156126715761265d8286838151811061265057612650612e48565b6020026020010151612754565b91508061266981612e2f565b915050612631565b509392505050565b6060824710156126da5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016103cc565b600080866001600160a01b031685876040516126f6919061311a565b60006040518083038185875af1925050503d8060008114612733576040519150601f19603f3d011682016040523d82523d6000602084013e612738565b606091505b509150915061274987838387612783565b979650505050505050565b6000818310612770576000828152602084905260409020611752565b6000838152602083905260409020611752565b606083156127f25782516000036127eb576001600160a01b0385163b6127eb5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103cc565b5081611a50565b611a5083838151156128075781518083602001fd5b8060405162461bcd60e51b81526004016103cc91906128fe565b6001600160e01b0319811681146114a457600080fd5b60006020828403121561284957600080fd5b813561175281612821565b6001600160a01b03811681146114a457600080fd5b6000806040838503121561287c57600080fd5b823561288781612854565b915060208301356001600160601b03811681146128a357600080fd5b809150509250929050565b60005b838110156128c95781810151838201526020016128b1565b50506000910152565b600081518084526128ea8160208601602086016128ae565b601f01601f19169290920160200192915050565b60208152600061175260208301846128d2565b60006020828403121561292357600080fd5b5035919050565b6000806040838503121561293d57600080fd5b823561294881612854565b946020939093013593505050565b60006020828403121561296857600080fd5b813561175281612854565b60008060006060848603121561298857600080fd5b833561299381612854565b925060208401356129a381612854565b929592945050506040919091013590565b600080604083850312156129c757600080fd5b50508035926020909101359150565b600080602083850312156129e957600080fd5b823567ffffffffffffffff80821115612a0157600080fd5b818501915085601f830112612a1557600080fd5b813581811115612a2457600080fd5b8660208260051b8501011115612a3957600080fd5b60209290920196919550909350505050565b60008060408385031215612a5e57600080fd5b8235612a6981612854565b915060208301356128a381612854565b6020808252825182820181905260009190848201906040850190845b81811015612aba5783516001600160a01b031683529284019291840191600101612a95565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612af757612af7612ac6565b604051601f8501601f19908116603f01168101908282118183101715612b1f57612b1f612ac6565b81604052809350858152868686011115612b3857600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215612b6457600080fd5b813567ffffffffffffffff811115612b7b57600080fd5b8201601f81018413612b8c57600080fd5b611a5084823560208401612adc565b80151581146114a457600080fd5b60008060408385031215612bbc57600080fd5b8235612bc781612854565b915060208301356128a381612b9b565b60008060008060808587031215612bed57600080fd5b8435612bf881612854565b93506020850135612c0881612854565b925060408501359150606085013567ffffffffffffffff811115612c2b57600080fd5b8501601f81018713612c3c57600080fd5b612c4b87823560208401612adc565b91505092959194509250565b60008060408385031215612c6a57600080fd5b8235612bc781612b9b565b600181811c90821680612c8957607f821691505b602082108103612ca957634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526026908201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060408201526573686172657360d01b606082015260800190565b6020808252602b908201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060408201526a191d59481c185e5b595b9d60aa1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b80820180821115610c0057610c00612d40565b6020808252601e908201527f5468652063616c6c657220697320616e6f7468657220636f6e74726163740000604082015260600190565b6020808252601c908201527f4d6178207065722077616c6c6574206c696d6974207265616368656400000000604082015260600190565b60208082526013908201527213585e081cdd5c1c1b1e48195e18d959591959606a1b604082015260600190565b6020808252601190820152704e6f7420656e6f756768742066756e647360781b604082015260600190565b600060018201612e4157612e41612d40565b5060010190565b634e487b7160e01b600052603260045260246000fd5b601f82111561122a57600081815260208120601f850160051c81016020861015612e855750805b601f850160051c820191505b8181101561105057828155600101612e91565b815167ffffffffffffffff811115612ebe57612ebe612ac6565b612ed281612ecc8454612c75565b84612e5e565b602080601f831160018114612f075760008415612eef5750858301515b600019600386901b1c1916600185901b178555611050565b600085815260208120601f198616915b82811015612f3657888601518255948401946001909101908401612f17565b5085821015612f545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601260045260246000fd5b600082612f8957612f89612f64565b500490565b8082028115828204841417610c0057610c00612d40565b600060208284031215612fb757600080fd5b5051919050565b600082612fcd57612fcd612f64565b500690565b60008154612fdf81612c75565b60018281168015612ff7576001811461300c5761303b565b60ff198416875282151583028701945061303b565b8560005260208060002060005b858110156130325781548a820152908401908201613019565b50505082870194505b5050505092915050565b60006130518284612fd2565b69333937b73a173539b7b760b11b8152600a019392505050565b60006130778284612fd2565b683130b1b5973539b7b760b91b81526009019392505050565b81810381811115610c0057610c00612d40565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906130d6908301846128d2565b9695505050505050565b6000602082840312156130f257600080fd5b815161175281612821565b60006020828403121561310f57600080fd5b815161175281612b9b565b6000825161312c8184602087016128ae565b919091019291505056fea26469706673582212206bc3e27dd703a62d70837ba66c69d31046f3c20a912d817bc91ef51bd5f26ffa64736f6c63430008120033

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

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000003b416f02227c65930d23137bdcad2866172b69a1000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000043697066733a2f2f6261667962656962346a7a6a626c70666a363473326f69673633633266353472767578653535336169647a76353335366d37626f7535706c6e7a792f0000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _royaltyFeesInBips (uint96): 0
Arg [1] : _team (address[]): 0x3B416f02227c65930D23137bdcAd2866172B69a1
Arg [2] : _teamShares (uint256[]): 100
Arg [3] : _baseURI (string): ipfs://bafybeib4jzjblpfj64s2oig63c2f54rvuxe553aidzv5356m7bou5plnzy/

-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [5] : 0000000000000000000000003b416f02227c65930d23137bdcad2866172b69a1
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000043
Arg [9] : 697066733a2f2f6261667962656962346a7a6a626c70666a363473326f696736
Arg [10] : 33633266353472767578653535336169647a76353335366d37626f7535706c6e
Arg [11] : 7a792f0000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

105986:6988:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;112935:26;;-1:-1:-1;;;112935:26:0;;216:2:1;112935:26:0;;;198:21:1;255:2;235:18;;;228:30;-1:-1:-1;;;274:18:1;;;267:46;330:18;;112935:26:0;;;;;;;;105986:6988;;;;24243:678;;;;;;;;;;-1:-1:-1;24243:678:0;;;;;:::i;:::-;;:::i;:::-;;;910:14:1;;903:22;885:41;;873:2;858:18;24243:678:0;;;;;;;;112522:183;;;;;;;;;;-1:-1:-1;112522:183:0;;;;;:::i;:::-;;:::i;:::-;;29953:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;31905:204::-;;;;;;;;;;-1:-1:-1;31905:204:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2618:32:1;;;2600:51;;2588:2;2573:18;31905:204:0;2454:203:1;31447:392:0;;;;;;;;;;-1:-1:-1;31447:392:0;;;;;:::i;:::-;;:::i;106471:28::-;;;;;;;;;;;;;;;;;;;3128:25:1;;;3116:2;3101:18;106471:28:0;2982:177:1;23297:315:0;;;;;;;;;;;;;:::i;100387:671::-;;;;;;;;;;-1:-1:-1;100387:671:0;;;;;:::i;:::-;;:::i;109724:99::-;;;;;;;;;;-1:-1:-1;109724:99:0;;;;;:::i;:::-;;:::i;41174:2800::-;;;;;;;;;;-1:-1:-1;41174:2800:0;;;;;:::i;:::-;;:::i;112124:242::-;;;;;;;;;;-1:-1:-1;112124:242:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;4512:32:1;;;4494:51;;4576:2;4561:18;;4554:34;;;;4467:18;112124:242:0;4320:274:1;106193:32:0;;;;;;;;;;;;;;;;108631:553;;;;;;:::i;:::-;;:::i;97997:91::-;;;;;;;;;;-1:-1:-1;98068:12:0;;97997:91;;99126:135;;;;;;;;;;-1:-1:-1;99126:135:0;;;;;:::i;:::-;-1:-1:-1;;;;;99223:21:0;;;99196:7;99223:21;;;:14;:21;;;;;;;;:30;;;;;;;;;;;;;99126:135;32799:185;;;;;;;;;;-1:-1:-1;32799:185:0;;;;;:::i;:::-;;:::i;109304:295::-;;;;;;;;;;-1:-1:-1;109304:295:0;;;;;:::i;:::-;;:::i;101326:792::-;;;;;;;;;;-1:-1:-1;101326:792:0;;;;;:::i;:::-;;:::i;110392:170::-;;;;;;;;;;-1:-1:-1;110392:170:0;;;;;:::i;:::-;;:::i;112729:151::-;;;;;;;;;;;;;:::i;29742:144::-;;;;;;;;;;-1:-1:-1;29742:144:0;;;;;:::i;:::-;;:::i;106232:40::-;;;;;;;;;;;;;;;;106086:21;;;;;;;;;;;;;:::i;24985:224::-;;;;;;;;;;-1:-1:-1;24985:224:0;;;;;:::i;:::-;;:::i;105092:103::-;;;;;;;;;;;;;:::i;106149:35::-;;;;;;;;;;-1:-1:-1;106149:35:0;;;;;;;;;;;106116:26;;;;;;;;;;-1:-1:-1;106116:26:0;;;;;;;;106279:33;;;;;;;;;;;;;;;;99352:100;;;;;;;;;;-1:-1:-1;99352:100:0;;;;;:::i;:::-;;:::i;104451:87::-;;;;;;;;;;-1:-1:-1;104497:7:0;104524:6;-1:-1:-1;;;;;104524:6:0;104451:87;;106627:60;;;;;;;;;;-1:-1:-1;106627:60:0;;;;;:::i;:::-;;;;;;;;;;;;;;106758:56;;;;;;;;;;-1:-1:-1;106758:56:0;;;;;:::i;:::-;;;;;;;;;;;;;;30122:104;;;;;;;;;;;;;:::i;98848:109::-;;;;;;;;;;-1:-1:-1;98848:109:0;;;;;:::i;:::-;-1:-1:-1;;;;;98931:18:0;98904:7;98931:18;;;:9;:18;;;;;;;98848:109;109605:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;109829:::-;;;;;;;;;;-1:-1:-1;109829:100:0;;;;;:::i;:::-;;:::i;32181:306::-;;;;;;;;;;-1:-1:-1;32181:306:0;;;;;:::i;:::-;;:::i;112374:140::-;;;;;;;;;;-1:-1:-1;112374:140:0;;;;;:::i;:::-;;:::i;99542:225::-;;;;;;;;;;-1:-1:-1;99542:225:0;;;;;:::i;:::-;;:::i;106591:27::-;;;;;;;;;;-1:-1:-1;106591:27:0;;;;;:::i;:::-;;:::i;110688:118::-;;;;;;;;;;-1:-1:-1;110688:118:0;;;;;:::i;:::-;;:::i;110568:114::-;;;;;;;;;;-1:-1:-1;110568:114:0;;;;;:::i;:::-;;:::i;107431:627::-;;;;;;:::i;:::-;;:::i;33055:399::-;;;;;;;;;;-1:-1:-1;33055:399:0;;;;;:::i;:::-;;:::i;99927:260::-;;;;;;;;;;-1:-1:-1;99927:260:0;;;;;:::i;:::-;;:::i;110094:175::-;;;;;;;;;;-1:-1:-1;110094:175:0;;;;;:::i;:::-;;:::i;111744:356::-;;;;;;;;;;-1:-1:-1;111744:356:0;;;;;:::i;:::-;;:::i;109192:106::-;;;;;;;;;;-1:-1:-1;109192:106:0;;;;;:::i;:::-;;:::i;98644:105::-;;;;;;;;;;-1:-1:-1;98644:105:0;;;;;:::i;:::-;-1:-1:-1;;;;;98725:16:0;98698:7;98725:16;;;:7;:16;;;;;;;98644:105;106506:27;;;;;;;;;;;;;;;;108064:561;;;;;;:::i;:::-;;:::i;98434:119::-;;;;;;;;;;-1:-1:-1;98434:119:0;;;;;:::i;:::-;-1:-1:-1;;;;;98519:26:0;98492:7;98519:26;;;:19;:26;;;;;;;98434:119;106321:43;;;;;;;;;;;;;;;;98182:95;;;;;;;;;;-1:-1:-1;98255:14:0;;98182:95;;32564:164;;;;;;;;;;-1:-1:-1;32564:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;32685:25:0;;;32661:4;32685:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;32564:164;109935:153;;;;;;;;;;-1:-1:-1;109935:153:0;;;;;:::i;:::-;;:::i;106694:57::-;;;;;;;;;;-1:-1:-1;106694:57:0;;;;;:::i;:::-;;;;;;;;;;;;;;105350:201;;;;;;;;;;-1:-1:-1;105350:201:0;;;;;:::i;:::-;;:::i;110275:111::-;;;;;;;;;;-1:-1:-1;110275:111:0;;;;;:::i;:::-;;:::i;24243:678::-;24328:4;-1:-1:-1;;;;;;;;;24628:25:0;;;;:102;;-1:-1:-1;;;;;;;;;;24705:25:0;;;24628:102;:179;;;-1:-1:-1;;;;;;;;;;24782:25:0;;;24628:179;:242;;;-1:-1:-1;;;;;;;;;;24845:25:0;;;24628:242;24608:262;24243:678;-1:-1:-1;;24243:678:0:o;112522:183::-;104337:13;:11;:13::i;:::-;-1:-1:-1;;;;;112659:38:0::1;-1:-1:-1::0;;;;;112621:27:0;;::::1;-1:-1:-1::0;;;112621:27:0::1;-1:-1:-1::0;;112659:38:0;::::1;112621:15;112659:38:::0;112522:183::o;29953:100::-;30007:13;30040:5;30033:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29953:100;:::o;31905:204::-;31973:7;31998:16;32006:7;31998;:16::i;:::-;31993:64;;32023:34;;-1:-1:-1;;;32023:34:0;;;;;;;;;;;31993:64;-1:-1:-1;32077:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;32077:24:0;;31905:204::o;31447:392::-;31528:13;31544:16;31552:7;31544;:16::i;:::-;31528:32;-1:-1:-1;52357:10:0;-1:-1:-1;;;;;31575:28:0;;;31571:175;;31623:44;31640:5;52357:10;32564:164;:::i;31623:44::-;31618:128;;31695:35;;-1:-1:-1;;;31695:35:0;;;;;;;;;;;31618:128;31758:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;31758:29:0;-1:-1:-1;;;;;31758:29:0;;;;;;;;;31803:28;;31758:24;;31803:28;;;;;;;31517:322;31447:392;;:::o;23297:315::-;23563:12;;22904:1;23547:13;:28;-1:-1:-1;;23547:46:0;;23297:315::o;100387:671::-;-1:-1:-1;;;;;100463:16:0;;100482:1;100463:16;;;:7;:16;;;;;;100455:71;;;;-1:-1:-1;;;100455:71:0;;;;;;;:::i;:::-;100539:15;100557:19;100568:7;100557:10;:19::i;:::-;100539:37;;100597:7;100608:1;100597:12;100589:68;;;;-1:-1:-1;;;100589:68:0;;;;;;;:::i;:::-;100870:7;100852:14;;:25;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;100913:18:0;;;;;;:9;:18;;;;;:29;;;;;;100966:35;100923:7;100935;100966:17;:35::i;:::-;101017:33;;;-1:-1:-1;;;;;4512:32:1;;4494:51;;4576:2;4561:18;;4554:34;;;101017:33:0;;4467:18:1;101017:33:0;;;;;;;100444:614;100387:671;:::o;109724:99::-;104337:13;:11;:13::i;:::-;109793:9:::1;:22:::0;109724:99::o;41174:2800::-;41308:27;41338;41357:7;41338:18;:27::i;:::-;41308:57;;41423:4;-1:-1:-1;;;;;41382:45:0;41398:19;-1:-1:-1;;;;;41382:45:0;;41378:86;;41436:28;;-1:-1:-1;;;41436:28:0;;;;;;;;;;;41378:86;41478:27;39904:21;;;39731:15;39946:4;39939:36;40028:4;40012:21;;40118:26;;41662:62;40118:26;41698:4;52357:10;41704:19;-1:-1:-1;;;;;40723:31:0;;;40569:26;;40850:19;;40871:30;;40847:55;;40275:645;41662:62;41657:174;;41744:43;41761:4;52357:10;32564:164;:::i;41744:43::-;41739:92;;41796:35;;-1:-1:-1;;;41796:35:0;;;;;;;;;;;41739:92;-1:-1:-1;;;;;41848:16:0;;41844:52;;41873:23;;-1:-1:-1;;;41873:23:0;;;;;;;;;;;41844:52;42045:15;42042:160;;;42185:1;42164:19;42157:30;42042:160;-1:-1:-1;;;;;42580:24:0;;;;;;;:18;:24;;;;;;42578:26;;-1:-1:-1;;42578:26:0;;;42649:22;;;;;;;;;42647:24;;-1:-1:-1;42647:24:0;;;29641:11;29617:22;29613:40;29600:62;-1:-1:-1;;;29600:62:0;42942:26;;;;:17;:26;;;;;:174;;;;-1:-1:-1;;;43236:46:0;;:51;;43232:626;;43340:1;43330:11;;43308:19;43463:30;;;:17;:30;;;;;;:35;;43459:384;;43601:13;;43586:11;:28;43582:242;;43748:30;;;;:17;:30;;;;;:52;;;43582:242;43289:569;43232:626;43905:7;43901:2;-1:-1:-1;;;;;43886:27:0;43895:4;-1:-1:-1;;;;;43886:27:0;;;;;;;;;;;43924:42;41297:2677;;;41174:2800;;;:::o;112124:242::-;112311:15;;112235:16;;;;-1:-1:-1;;;112311:15:0;;-1:-1:-1;;;;;112311:15:0;112328:28;112345:10;112328:16;:28::i;:::-;112303:54;;;;112124:242;;;;;:::o;108631:553::-;107229:9;107242:10;107229:23;107221:66;;;;-1:-1:-1;;;107221:66:0;;;;;;;:::i;:::-;108729:15:::1;::::0;::::1;;::::0;;::::1;;:23;;:15;:23;108721:67;;;::::0;-1:-1:-1;;;108721:67:0;;12617:2:1;108721:67:0::1;::::0;::::1;12599:21:1::0;12656:2;12636:18;;;12629:30;12695:33;12675:18;;;12668:61;12746:18;;108721:67:0::1;12415:355:1::0;108721:67:0::1;108807:35;108823:10;108835:6;;108807:15;:35::i;:::-;108799:63;;;::::0;-1:-1:-1;;;108799:63:0;;12977:2:1;108799:63:0::1;::::0;::::1;12959:21:1::0;13016:2;12996:18;;;12989:30;-1:-1:-1;;;13035:18:1;;;13028:45;13090:18;;108799:63:0::1;12775:339:1::0;108799:63:0::1;108903:10;108881:33;::::0;;;:21:::1;:33;::::0;;;;;108922:1:::1;::::0;108881:37:::1;::::0;108922:1;108881:37:::1;:::i;:::-;:42;;108873:83;;;;-1:-1:-1::0;;;108873:83:0::1;;;;;;;:::i;:::-;108996:10;;108975:13;:11;:13::i;:::-;:17;::::0;108991:1:::1;108975:17;:::i;:::-;:31;;108967:62;;;;-1:-1:-1::0;;;108967:62:0::1;;;;;;;:::i;:::-;109061:9;;109048;:22;;109040:52;;;;-1:-1:-1::0;;;109040:52:0::1;;;;;;;:::i;:::-;109125:10;109103:33;::::0;;;:21:::1;:33;::::0;;;;:38;;109140:1:::1;::::0;109103:33;:38:::1;::::0;109140:1;;109103:38:::1;:::i;:::-;::::0;;;-1:-1:-1;109152:24:0::1;::::0;-1:-1:-1;109162:10:0::1;109174:1;109152:9;:24::i;:::-;108631:553:::0;;:::o;32799:185::-;32937:39;32954:4;32960:2;32964:7;32937:39;;;;;;;;;;;;:16;:39::i;:::-;32799:185;;;:::o;109304:295::-;109375:16;109383:7;109375;:16::i;:::-;-1:-1:-1;;;;;109361:30:0;:10;-1:-1:-1;;;;;109361:30:0;;109353:59;;;;-1:-1:-1;;;109353:59:0;;14372:2:1;109353:59:0;;;14354:21:1;14411:2;14391:18;;;14384:30;-1:-1:-1;;;14430:18:1;;;14423:46;14486:18;;109353:59:0;14170:340:1;109353:59:0;109441:10;109432:20;;;;:8;:20;;;;;;;;109431:21;109423:63;;;;-1:-1:-1;;;109423:63:0;;14717:2:1;109423:63:0;;;14699:21:1;14756:2;14736:18;;;14729:30;14795:31;14775:18;;;14768:59;14844:18;;109423:63:0;14515:353:1;109423:63:0;109499:14;109505:7;109499:5;:14::i;:::-;-1:-1:-1;109535:10:0;109526:20;;;;:8;:20;;;;;:27;;-1:-1:-1;;109526:27:0;109549:4;109526:27;;;;;;109564:10;:27;;;;;;;;;;;;;;-1:-1:-1;;;;;;109564:27:0;;;;;;109304:295::o;101326:792::-;-1:-1:-1;;;;;101408:16:0;;101427:1;101408:16;;;:7;:16;;;;;;101400:71;;;;-1:-1:-1;;;101400:71:0;;;;;;;:::i;:::-;101484:15;101502:26;101513:5;101520:7;101502:10;:26::i;:::-;101484:44;;101549:7;101560:1;101549:12;101541:68;;;;-1:-1:-1;;;101541:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;101864:26:0;;;;;;:19;:26;;;;;:37;;101894:7;;101864:26;:37;;101894:7;;101864:37;:::i;:::-;;;;-1:-1:-1;;;;;;;101937:21:0;;;;;;;:14;:21;;;;;;;;:30;;;;;;;;;:41;;;;;;102002:47;101952:5;101959:7;101971;102002:22;:47::i;:::-;102065:45;;;-1:-1:-1;;;;;4512:32:1;;;4494:51;;4576:2;4561:18;;4554:34;;;102065:45:0;;;;;4467:18:1;102065:45:0;;;;;;;101389:729;101326:792;;:::o;110392:170::-;104337:13;:11;:13::i;:::-;110508:21:::1;:46:::0;110392:170::o;112729:151::-;104337:13;:11;:13::i;:::-;112785:6:::1;112781:92;112802:10;;112798:1;:14;112781:92;;;112835:26;112851:8;112857:1;112851:5;:8::i;112835:26::-;112815:3:::0;::::1;::::0;::::1;:::i;:::-;;;;112781:92;;;;112729:151::o:0;29742:144::-;29806:7;29849:27;29868:7;29849:18;:27::i;106086:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;24985:224::-;25049:7;-1:-1:-1;;;;;25073:19:0;;25069:60;;25101:28;;-1:-1:-1;;;25101:28:0;;;;;;;;;;;25069:60;-1:-1:-1;;;;;;25147:25:0;;;;;:18;:25;;;;;;19477:13;25147:54;;24985:224::o;105092:103::-;104337:13;:11;:13::i;:::-;105157:30:::1;105184:1;105157:18;:30::i;:::-;105092:103::o:0;99352:100::-;99403:7;99430;99438:5;99430:14;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;99430:14:0;;99352:100;-1:-1:-1;;99352:100:0:o;30122:104::-;30178:13;30211:7;30204:14;;;;;:::i;109605:100::-;109651:16;109687:10;109680:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;109680:17:0;;;;;;;;;;;;;;;;;;;;;;109605:100;:::o;109829:::-;104337:13;:11;:13::i;:::-;109903:7:::1;:18;109913:8:::0;109903:7;:18:::1;:::i;32181:306::-:0;52357:10;-1:-1:-1;;;;;32280:31:0;;;32276:61;;32320:17;;-1:-1:-1;;;32320:17:0;;;;;;;;;;;32276:61;52357:10;32348:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;32348:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;32348:60:0;;;;;;;;;;32424:55;;885:41:1;;;32348:49:0;;52357:10;32424:55;;858:18:1;32424:55:0;;;;;;;32181:306;;:::o;112374:140::-;112489:17;;112441:7;;-1:-1:-1;;;;;112489:17:0;112467:18;112480:5;112467:10;:18;:::i;:::-;112466:40;;;;:::i;99542:225::-;99600:7;99620:21;99668:15;98255:14;;;98182:95;99668:15;99644:39;;:21;:39;:::i;:::-;99620:63;;99701:58;99717:7;99726:13;99741:17;99750:7;-1:-1:-1;;;;;98931:18:0;98904:7;98931:18;;;:9;:18;;;;;;;98848:109;99741:17;99701:15;:58::i;:::-;99694:65;99542:225;-1:-1:-1;;;99542:225:0:o;106591:27::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;106591:27:0;;-1:-1:-1;106591:27:0;:::o;110688:118::-;104337:13;:11;:13::i;:::-;110768::::1;:30:::0;110688:118::o;110568:114::-;104337:13;:11;:13::i;:::-;110646:12:::1;:28:::0;110568:114::o;107431:627::-;107229:9;107242:10;107229:23;107221:66;;;;-1:-1:-1;;;107221:66:0;;;;;;;:::i;:::-;107523:6:::1;::::0;::::1;;:14;;:6:::0;:14:::1;107515:55;;;::::0;-1:-1:-1;;;107515:55:0;;17981:2:1;107515:55:0::1;::::0;::::1;17963:21:1::0;18020:2;18000:18;;;17993:30;18059;18039:18;;;18032:58;18107:18;;107515:55:0::1;17779:352:1::0;107515:55:0::1;107642:21;::::0;107615:10:::1;107589:37;::::0;;;:25:::1;:37;::::0;;;;;:49:::1;::::0;107629:9;;107589:49:::1;:::i;:::-;:74;;107581:115;;;;-1:-1:-1::0;;;107581:115:0::1;;;;;;;:::i;:::-;107744:12;;107731:9;107715:13;:11;:13::i;:::-;:25;;;;:::i;:::-;:41;;107707:83;;;::::0;-1:-1:-1;;;107707:83:0;;18338:2:1;107707:83:0::1;::::0;::::1;18320:21:1::0;18377:2;18357:18;;;18350:30;18416:31;18396:18;;;18389:59;18465:18;;107707:83:0::1;18136:353:1::0;107707:83:0::1;107838:10;;107825:9;107809:13;:11;:13::i;:::-;:25;;;;:::i;:::-;:39;;107801:70;;;;-1:-1:-1::0;;;107801:70:0::1;;;;;;;:::i;:::-;107915:9;107903;;:21;;;;:::i;:::-;107890:9;:34;;107882:64;;;;-1:-1:-1::0;;;107882:64:0::1;;;;;;;:::i;:::-;107983:10;107957:37;::::0;;;:25:::1;:37;::::0;;;;:50;;107998:9;;107957:37;:50:::1;::::0;107998:9;;107957:50:::1;:::i;:::-;::::0;;;-1:-1:-1;108018:32:0::1;::::0;-1:-1:-1;108028:10:0::1;108040:9:::0;108018::::1;:32::i;33055:399::-:0;33222:31;33235:4;33241:2;33245:7;33222:12;:31::i;:::-;-1:-1:-1;;;;;33268:14:0;;;:19;33264:183;;33307:56;33338:4;33344:2;33348:7;33357:5;33307:30;:56::i;:::-;33302:145;;33391:40;;-1:-1:-1;;;33391:40:0;;;;;;;;;;;33302:145;33055:399;;;;:::o;99927:260::-;-1:-1:-1;;;;;98519:26:0;;99999:7;98519:26;;;:19;:26;;;;;;99999:7;;100043:30;;-1:-1:-1;;;100043:30:0;;100067:4;100043:30;;;2600:51:1;-1:-1:-1;;;;;100043:15:0;;;;;2573:18:1;;100043:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;;;;:::i;:::-;-1:-1:-1;;;;;99223:21:0;;;99196:7;99223:21;;;:14;:21;;;;;;;;:30;;;;;;;;;;100019:77;;-1:-1:-1;100114:65:0;;100130:7;;100019:77;;99701:15;:58::i;100114:65::-;100107:72;99927:260;-1:-1:-1;;;;99927:260:0:o;110094:175::-;104337:13;:11;:13::i;:::-;110188:10:::1;;110174:11;:24;110166:60;;;::::0;-1:-1:-1;;;110166:60:0;;18885:2:1;110166:60:0::1;::::0;::::1;18867:21:1::0;18924:2;18904:18;;;18897:30;18963:25;18943:18;;;18936:53;19006:18;;110166:60:0::1;18683:347:1::0;110166:60:0::1;110237:10;:24:::0;110094:175::o;111744:356::-;111815:13;111849:17;111857:8;111849:7;:17::i;:::-;111841:61;;;;-1:-1:-1;;;111841:61:0;;19237:2:1;111841:61:0;;;19219:21:1;19276:2;19256:18;;;19249:30;19315:33;19295:18;;;19288:61;19366:18;;111841:61:0;19035:355:1;111841:61:0;111916:12;111927:1;111916:8;:12;:::i;:::-;111932:1;111916:17;111913:179;;111976:7;111959:39;;;;;;;;:::i;:::-;;;;;;;;;;;;;111945:54;;111744:356;;;:::o;111913:179::-;112070:7;112053:38;;;;;;;;:::i;109192:106::-;104337:13;:11;:13::i;:::-;109265:25:::1;109275:3;109280:9;109265;:25::i;108064:561::-:0;107229:9;107242:10;107229:23;107221:66;;;;-1:-1:-1;;;107221:66:0;;;;;;;:::i;:::-;108163:15:::1;::::0;::::1;;::::0;;::::1;;:23;;:15;:23;108155:67;;;::::0;-1:-1:-1;;;108155:67:0;;12617:2:1;108155:67:0::1;::::0;::::1;12599:21:1::0;12656:2;12636:18;;;12629:30;12695:33;12675:18;;;12668:61;12746:18;;108155:67:0::1;12415:355:1::0;108155:67:0::1;108241:36;108258:10;108270:6;;108241:16;:36::i;:::-;108233:64;;;::::0;-1:-1:-1;;;108233:64:0;;12977:2:1;108233:64:0::1;::::0;::::1;12959:21:1::0;13016:2;12996:18;;;12989:30;-1:-1:-1;;;13035:18:1;;;13028:45;13090:18;;108233:64:0::1;12775:339:1::0;108233:64:0::1;108339:10;108316:34;::::0;;;:22:::1;:34;::::0;;;;;108358:1:::1;::::0;108316:38:::1;::::0;108358:1;108316:38:::1;:::i;:::-;:43;;108308:84;;;;-1:-1:-1::0;;;108308:84:0::1;;;;;;;:::i;:::-;108432:10;;108411:13;:11;:13::i;:::-;:17;::::0;108427:1:::1;108411:17;:::i;:::-;:31;;108403:62;;;;-1:-1:-1::0;;;108403:62:0::1;;;;;;;:::i;:::-;108497:9;::::0;:13:::1;::::0;108509:1:::1;108497:13;:::i;:::-;108484:9;:26;;108476:56;;;;-1:-1:-1::0;;;108476:56:0::1;;;;;;;:::i;:::-;108566:10;108543:34;::::0;;;:22:::1;:34;::::0;;;;:39;;108581:1:::1;::::0;108543:34;:39:::1;::::0;108581:1;;108543:39:::1;:::i;:::-;::::0;;;-1:-1:-1;108593:24:0::1;::::0;-1:-1:-1;108603:10:0::1;108615:1;108593:9;:24::i;109935:153::-:0;104337:13;:11;:13::i;:::-;110019:6:::1;:16:::0;;-1:-1:-1;;110046:34:0;110019:16;::::1;;-1:-1:-1::0;;110046:34:0;;;;;110019:16:::1;110046:34:::0;::::1;;::::0;;;::::1;;::::0;;109935:153::o;105350:201::-;104337:13;:11;:13::i;:::-;-1:-1:-1;;;;;105439:22:0;::::1;105431:73;;;::::0;-1:-1:-1;;;105431:73:0;;21171:2:1;105431:73:0::1;::::0;::::1;21153:21:1::0;21210:2;21190:18;;;21183:30;21249:34;21229:18;;;21222:62;-1:-1:-1;;;21300:18:1;;;21293:36;21346:19;;105431:73:0::1;20969:402:1::0;105431:73:0::1;105515:28;105534:8;105515:18;:28::i;110275:111::-:0;104337:13;:11;:13::i;:::-;110350:12:::1;:28:::0;110275:111::o;104616:132::-;104497:7;104524:6;-1:-1:-1;;;;;104524:6:0;52357:10;104680:23;104672:68;;;;-1:-1:-1;;;104672:68:0;;21578:2:1;104672:68:0;;;21560:21:1;;;21597:18;;;21590:30;21656:34;21636:18;;;21629:62;21708:18;;104672:68:0;21376:356:1;33709:273:0;33766:4;33822:7;22904:1;33803:26;;:66;;;;;33856:13;;33846:7;:23;33803:66;:152;;;;-1:-1:-1;;33907:26:0;;;;:17;:26;;;;;;-1:-1:-1;;;33907:43:0;:48;;33709:273::o;74501:317::-;74616:6;74591:21;:31;;74583:73;;;;-1:-1:-1;;;74583:73:0;;21939:2:1;74583:73:0;;;21921:21:1;21978:2;21958:18;;;21951:30;22017:31;21997:18;;;21990:59;22066:18;;74583:73:0;21737:353:1;74583:73:0;74670:12;74688:9;-1:-1:-1;;;;;74688:14:0;74710:6;74688:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74669:52;;;74740:7;74732:78;;;;-1:-1:-1;;;74732:78:0;;22507:2:1;74732:78:0;;;22489:21:1;22546:2;22526:18;;;22519:30;22585:34;22565:18;;;22558:62;22656:28;22636:18;;;22629:56;22702:19;;74732:78:0;22305:422:1;26659:1129:0;26726:7;26761;;22904:1;26810:23;26806:915;;26863:13;;26856:4;:20;26852:869;;;26901:14;26918:23;;;:17;:23;;;;;;;-1:-1:-1;;;27007:23:0;;:28;;27003:699;;27526:113;27533:6;27543:1;27533:11;27526:113;;-1:-1:-1;;;27604:6:0;27586:25;;;;:17;:25;;;;;;27526:113;;27003:699;26878:843;26852:869;27749:31;;-1:-1:-1;;;27749:31:0;;;;;;;;;;;110812:190;110932:4;110961:33;110971:14;110976:8;110971:4;:14::i;:::-;110987:6;;110961:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;110961:9:0;;-1:-1:-1;;;110961:33:0:i;34066:104::-;34135:27;34145:2;34149:8;34135:27;;;;;;;;;;;;:9;:27::i;44052:89::-;44112:21;44118:7;44127:5;44112;:21::i;87516:177::-;87626:58;;;-1:-1:-1;;;;;4512:32:1;;87626:58:0;;;4494:51:1;4561:18;;;;4554:34;;;87626:58:0;;;;;;;;;;4467:18:1;;;;87626:58:0;;;;;;;;-1:-1:-1;;;;;87626:58:0;-1:-1:-1;;;87626:58:0;;;87599:86;;87619:5;;87599:19;:86::i;105711:191::-;105785:16;105804:6;;-1:-1:-1;;;;;105821:17:0;;;-1:-1:-1;;;;;;105821:17:0;;;;;;105854:40;;105804:6;;;;;;;105854:40;;105785:16;105854:40;105774:128;105711:191;:::o;102296:248::-;102506:12;;-1:-1:-1;;;;;102486:16:0;;102442:7;102486:16;;;:7;:16;;;;;;102442:7;;102521:15;;102470:32;;:13;:32;:::i;:::-;102469:49;;;;:::i;:::-;:67;;;;:::i;47925:716::-;48109:88;;-1:-1:-1;;;48109:88:0;;48088:4;;-1:-1:-1;;;;;48109:45:0;;;;;:88;;52357:10;;48176:4;;48182:7;;48191:5;;48109:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48109:88:0;;;;;;;;-1:-1:-1;;48109:88:0;;;;;;;;;;;;:::i;:::-;;;48105:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48392:6;:13;48409:1;48392:18;48388:235;;48438:40;;-1:-1:-1;;;48438:40:0;;;;;;;;;;;48388:235;48581:6;48575:13;48566:6;48562:2;48558:15;48551:38;48105:529;-1:-1:-1;;;;;;48268:64:0;-1:-1:-1;;;48268:64:0;;-1:-1:-1;47925:716:0;;;;;;:::o;111009:192::-;111130:4;111159:34;111170:14;111175:8;111170:4;:14::i;:::-;111186:6;;111159:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;111159:10:0;;-1:-1:-1;;;111159:34:0:i;111209:127::-;111301:26;;-1:-1:-1;;23762:2:1;23758:15;;;23754:53;111301:26:0;;;23742:66:1;111264:7:0;;23824:12:1;;111301:26:0;;;;;;;;;;;;111291:37;;;;;;111284:44;;111209:127;;;:::o;111344:193::-;111453:4;111482:47;111501:6;111509:12;;111523:5;111482:18;:47::i;34586:681::-;34709:19;34715:2;34719:8;34709:5;:19::i;:::-;-1:-1:-1;;;;;34770:14:0;;;:19;34766:483;;34824:13;;34872:14;;;34905:233;34936:62;34975:1;34979:2;34983:7;;;;;;34992:5;34936:30;:62::i;:::-;34931:167;;35034:40;;-1:-1:-1;;;35034:40:0;;;;;;;;;;;34931:167;35133:3;35125:5;:11;34905:233;;35220:3;35203:13;;:20;35199:34;;35225:8;;;35199:34;34791:458;;34586:681;;;:::o;44370:3063::-;44450:27;44480;44499:7;44480:18;:27::i;:::-;44450:57;-1:-1:-1;44450:57:0;44520:12;;44642:28;44662:7;39605:27;39904:21;;;39731:15;39946:4;39939:36;40028:4;40012:21;;40118:26;;40012:21;;39510:652;44642:28;44585:85;;;;44687:13;44683:310;;;44808:62;44827:15;44844:4;52357:10;44850:19;52270:105;44808:62;44803:178;;44894:43;44911:4;52357:10;32564:164;:::i;44894:43::-;44889:92;;44946:35;;-1:-1:-1;;;44946:35:0;;;;;;;;;;;44889:92;45149:15;45146:160;;;45289:1;45268:19;45261:30;45146:160;-1:-1:-1;;;;;45907:24:0;;;;;;:18;:24;;;;;:59;;45935:31;45907:59;;;29641:11;29617:22;29613:40;29600:62;-1:-1:-1;;;29600:62:0;46204:26;;;;:17;:26;;;;;:203;;;;-1:-1:-1;;;46527:46:0;;:51;;46523:626;;46631:1;46621:11;;46599:19;46754:30;;;:17;:30;;;;;;:35;;46750:384;;46892:13;;46877:11;:28;46873:242;;47039:30;;;;:17;:30;;;;;:52;;;46873:242;46580:569;46523:626;47177:35;;47204:7;;47200:1;;-1:-1:-1;;;;;47177:35:0;;;;;47200:1;;47177:35;-1:-1:-1;;47400:12:0;:14;;;;;;-1:-1:-1;;;;44370:3063:0:o;91839:649::-;92263:23;92289:69;92317:4;92289:69;;;;;;;;;;;;;;;;;92297:5;-1:-1:-1;;;;;92289:27:0;;;:69;;;;;:::i;:::-;92263:95;;92377:10;:17;92398:1;92377:22;:56;;;;92414:10;92403:30;;;;;;;;;;;;:::i;:::-;92369:111;;;;-1:-1:-1;;;92369:111:0;;24299:2:1;92369:111:0;;;24281:21:1;24338:2;24318:18;;;24311:30;24377:34;24357:18;;;24350:62;-1:-1:-1;;;24428:18:1;;;24421:40;24478:19;;92369:111:0;24097:406:1;111543:195:0;111653:4;111682:48;111701:6;111709:13;;111724:5;1222:156;1313:4;1366;1337:25;1350:5;1357:4;1337:12;:25::i;:::-;:33;;1222:156;-1:-1:-1;;;;1222:156:0:o;35540:1529::-;35628:13;;-1:-1:-1;;;;;35656:16:0;;35652:48;;35681:19;;-1:-1:-1;;;35681:19:0;;;;;;;;;;;35652:48;35715:8;35727:1;35715:13;35711:44;;35737:18;;-1:-1:-1;;;35737:18:0;;;;;;;;;;;35711:44;-1:-1:-1;;;;;36243:22:0;;;;;;:18;:22;;19614:2;36243:22;;:70;;36281:31;36269:44;;36243:70;;;29641:11;29617:22;29613:40;-1:-1:-1;31351:15:0;;31326:23;31322:45;29610:51;29600:62;36556:31;;;;:17;:31;;;;;:173;36574:12;36805:23;;;36843:101;36870:35;;36895:9;;;;;-1:-1:-1;;;;;36870:35:0;;;36887:1;;36870:35;;36887:1;;36870:35;36939:3;36929:7;:13;36843:101;;36960:13;:19;-1:-1:-1;32799:185:0;;;:::o;75997:229::-;76134:12;76166:52;76188:6;76196:4;76202:1;76205:12;76166:21;:52::i;2021:296::-;2104:7;2147:4;2104:7;2162:118;2186:5;:12;2182:1;:16;2162:118;;;2235:33;2245:12;2259:5;2265:1;2259:8;;;;;;;;:::i;:::-;;;;;;;2235:9;:33::i;:::-;2220:48;-1:-1:-1;2200:3:0;;;;:::i;:::-;;;;2162:118;;;-1:-1:-1;2297:12:0;2021:296;-1:-1:-1;;;2021:296:0:o;77083:455::-;77253:12;77311:5;77286:21;:30;;77278:81;;;;-1:-1:-1;;;77278:81:0;;24710:2:1;77278:81:0;;;24692:21:1;24749:2;24729:18;;;24722:30;24788:34;24768:18;;;24761:62;-1:-1:-1;;;24839:18:1;;;24832:36;24885:19;;77278:81:0;24508:402:1;77278:81:0;77371:12;77385:23;77412:6;-1:-1:-1;;;;;77412:11:0;77431:5;77438:4;77412:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77370:73;;;;77461:69;77488:6;77496:7;77505:10;77517:12;77461:26;:69::i;:::-;77454:76;77083:455;-1:-1:-1;;;;;;;77083:455:0:o;9225:149::-;9288:7;9319:1;9315;:5;:51;;9450:13;9544:15;;;9580:4;9573:15;;;9627:4;9611:21;;9315:51;;;9450:13;9544:15;;;9580:4;9573:15;;;9627:4;9611:21;;9323:20;9382:268;79656:644;79841:12;79870:7;79866:427;;;79898:10;:17;79919:1;79898:22;79894:290;;-1:-1:-1;;;;;73537:19:0;;;80108:60;;;;-1:-1:-1;;;80108:60:0;;25409:2:1;80108:60:0;;;25391:21:1;25448:2;25428:18;;;25421:30;25487:31;25467:18;;;25460:59;25536:18;;80108:60:0;25207:353:1;80108:60:0;-1:-1:-1;80205:10:0;80198:17;;79866:427;80248:33;80256:10;80268:12;81003:17;;:21;80999:388;;81235:10;81229:17;81292:15;81279:10;81275:2;81271:19;81264:44;80999:388;81362:12;81355:20;;-1:-1:-1;;;81355:20:0;;;;;;;;:::i;359:131:1:-;-1:-1:-1;;;;;;433:32:1;;423:43;;413:71;;480:1;477;470:12;495:245;553:6;606:2;594:9;585:7;581:23;577:32;574:52;;;622:1;619;612:12;574:52;661:9;648:23;680:30;704:5;680:30;:::i;937:131::-;-1:-1:-1;;;;;1012:31:1;;1002:42;;992:70;;1058:1;1055;1048:12;1073:435;1140:6;1148;1201:2;1189:9;1180:7;1176:23;1172:32;1169:52;;;1217:1;1214;1207:12;1169:52;1256:9;1243:23;1275:31;1300:5;1275:31;:::i;:::-;1325:5;-1:-1:-1;1382:2:1;1367:18;;1354:32;-1:-1:-1;;;;;1417:40:1;;1405:53;;1395:81;;1472:1;1469;1462:12;1395:81;1495:7;1485:17;;;1073:435;;;;;:::o;1513:250::-;1598:1;1608:113;1622:6;1619:1;1616:13;1608:113;;;1698:11;;;1692:18;1679:11;;;1672:39;1644:2;1637:10;1608:113;;;-1:-1:-1;;1755:1:1;1737:16;;1730:27;1513:250::o;1768:271::-;1810:3;1848:5;1842:12;1875:6;1870:3;1863:19;1891:76;1960:6;1953:4;1948:3;1944:14;1937:4;1930:5;1926:16;1891:76;:::i;:::-;2021:2;2000:15;-1:-1:-1;;1996:29:1;1987:39;;;;2028:4;1983:50;;1768:271;-1:-1:-1;;1768:271:1:o;2044:220::-;2193:2;2182:9;2175:21;2156:4;2213:45;2254:2;2243:9;2239:18;2231:6;2213:45;:::i;2269:180::-;2328:6;2381:2;2369:9;2360:7;2356:23;2352:32;2349:52;;;2397:1;2394;2387:12;2349:52;-1:-1:-1;2420:23:1;;2269:180;-1:-1:-1;2269:180:1:o;2662:315::-;2730:6;2738;2791:2;2779:9;2770:7;2766:23;2762:32;2759:52;;;2807:1;2804;2797:12;2759:52;2846:9;2833:23;2865:31;2890:5;2865:31;:::i;:::-;2915:5;2967:2;2952:18;;;;2939:32;;-1:-1:-1;;;2662:315:1:o;3346:255::-;3413:6;3466:2;3454:9;3445:7;3441:23;3437:32;3434:52;;;3482:1;3479;3472:12;3434:52;3521:9;3508:23;3540:31;3565:5;3540:31;:::i;3606:456::-;3683:6;3691;3699;3752:2;3740:9;3731:7;3727:23;3723:32;3720:52;;;3768:1;3765;3758:12;3720:52;3807:9;3794:23;3826:31;3851:5;3826:31;:::i;:::-;3876:5;-1:-1:-1;3933:2:1;3918:18;;3905:32;3946:33;3905:32;3946:33;:::i;:::-;3606:456;;3998:7;;-1:-1:-1;;;4052:2:1;4037:18;;;;4024:32;;3606:456::o;4067:248::-;4135:6;4143;4196:2;4184:9;4175:7;4171:23;4167:32;4164:52;;;4212:1;4209;4202:12;4164:52;-1:-1:-1;;4235:23:1;;;4305:2;4290:18;;;4277:32;;-1:-1:-1;4067:248:1:o;4599:615::-;4685:6;4693;4746:2;4734:9;4725:7;4721:23;4717:32;4714:52;;;4762:1;4759;4752:12;4714:52;4802:9;4789:23;4831:18;4872:2;4864:6;4861:14;4858:34;;;4888:1;4885;4878:12;4858:34;4926:6;4915:9;4911:22;4901:32;;4971:7;4964:4;4960:2;4956:13;4952:27;4942:55;;4993:1;4990;4983:12;4942:55;5033:2;5020:16;5059:2;5051:6;5048:14;5045:34;;;5075:1;5072;5065:12;5045:34;5128:7;5123:2;5113:6;5110:1;5106:14;5102:2;5098:23;5094:32;5091:45;5088:65;;;5149:1;5146;5139:12;5088:65;5180:2;5172:11;;;;;5202:6;;-1:-1:-1;4599:615:1;;-1:-1:-1;;;;4599:615:1:o;5219:403::-;5302:6;5310;5363:2;5351:9;5342:7;5338:23;5334:32;5331:52;;;5379:1;5376;5369:12;5331:52;5418:9;5405:23;5437:31;5462:5;5437:31;:::i;:::-;5487:5;-1:-1:-1;5544:2:1;5529:18;;5516:32;5557:33;5516:32;5557:33;:::i;5879:658::-;6050:2;6102:21;;;6172:13;;6075:18;;;6194:22;;;6021:4;;6050:2;6273:15;;;;6247:2;6232:18;;;6021:4;6316:195;6330:6;6327:1;6324:13;6316:195;;;6395:13;;-1:-1:-1;;;;;6391:39:1;6379:52;;6486:15;;;;6451:12;;;;6427:1;6345:9;6316:195;;;-1:-1:-1;6528:3:1;;5879:658;-1:-1:-1;;;;;;5879:658:1:o;6542:127::-;6603:10;6598:3;6594:20;6591:1;6584:31;6634:4;6631:1;6624:15;6658:4;6655:1;6648:15;6674:632;6739:5;6769:18;6810:2;6802:6;6799:14;6796:40;;;6816:18;;:::i;:::-;6891:2;6885:9;6859:2;6945:15;;-1:-1:-1;;6941:24:1;;;6967:2;6937:33;6933:42;6921:55;;;6991:18;;;7011:22;;;6988:46;6985:72;;;7037:18;;:::i;:::-;7077:10;7073:2;7066:22;7106:6;7097:15;;7136:6;7128;7121:22;7176:3;7167:6;7162:3;7158:16;7155:25;7152:45;;;7193:1;7190;7183:12;7152:45;7243:6;7238:3;7231:4;7223:6;7219:17;7206:44;7298:1;7291:4;7282:6;7274;7270:19;7266:30;7259:41;;;;6674:632;;;;;:::o;7311:451::-;7380:6;7433:2;7421:9;7412:7;7408:23;7404:32;7401:52;;;7449:1;7446;7439:12;7401:52;7489:9;7476:23;7522:18;7514:6;7511:30;7508:50;;;7554:1;7551;7544:12;7508:50;7577:22;;7630:4;7622:13;;7618:27;-1:-1:-1;7608:55:1;;7659:1;7656;7649:12;7608:55;7682:74;7748:7;7743:2;7730:16;7725:2;7721;7717:11;7682:74;:::i;7767:118::-;7853:5;7846:13;7839:21;7832:5;7829:32;7819:60;;7875:1;7872;7865:12;7890:382;7955:6;7963;8016:2;8004:9;7995:7;7991:23;7987:32;7984:52;;;8032:1;8029;8022:12;7984:52;8071:9;8058:23;8090:31;8115:5;8090:31;:::i;:::-;8140:5;-1:-1:-1;8197:2:1;8182:18;;8169:32;8210:30;8169:32;8210:30;:::i;8462:795::-;8557:6;8565;8573;8581;8634:3;8622:9;8613:7;8609:23;8605:33;8602:53;;;8651:1;8648;8641:12;8602:53;8690:9;8677:23;8709:31;8734:5;8709:31;:::i;:::-;8759:5;-1:-1:-1;8816:2:1;8801:18;;8788:32;8829:33;8788:32;8829:33;:::i;:::-;8881:7;-1:-1:-1;8935:2:1;8920:18;;8907:32;;-1:-1:-1;8990:2:1;8975:18;;8962:32;9017:18;9006:30;;9003:50;;;9049:1;9046;9039:12;9003:50;9072:22;;9125:4;9117:13;;9113:27;-1:-1:-1;9103:55:1;;9154:1;9151;9144:12;9103:55;9177:74;9243:7;9238:2;9225:16;9220:2;9216;9212:11;9177:74;:::i;:::-;9167:84;;;8462:795;;;;;;;:::o;9922:376::-;9984:6;9992;10045:2;10033:9;10024:7;10020:23;10016:32;10013:52;;;10061:1;10058;10051:12;10013:52;10100:9;10087:23;10119:28;10141:5;10119:28;:::i;10303:380::-;10382:1;10378:12;;;;10425;;;10446:61;;10500:4;10492:6;10488:17;10478:27;;10446:61;10553:2;10545:6;10542:14;10522:18;10519:38;10516:161;;10599:10;10594:3;10590:20;10587:1;10580:31;10634:4;10631:1;10624:15;10662:4;10659:1;10652:15;10516:161;;10303:380;;;:::o;10688:402::-;10890:2;10872:21;;;10929:2;10909:18;;;10902:30;10968:34;10963:2;10948:18;;10941:62;-1:-1:-1;;;11034:2:1;11019:18;;11012:36;11080:3;11065:19;;10688:402::o;11095:407::-;11297:2;11279:21;;;11336:2;11316:18;;;11309:30;11375:34;11370:2;11355:18;;11348:62;-1:-1:-1;;;11441:2:1;11426:18;;11419:41;11492:3;11477:19;;11095:407::o;11507:127::-;11568:10;11563:3;11559:20;11556:1;11549:31;11599:4;11596:1;11589:15;11623:4;11620:1;11613:15;11639:125;11704:9;;;11725:10;;;11722:36;;;11738:18;;:::i;12056:354::-;12258:2;12240:21;;;12297:2;12277:18;;;12270:30;12336:32;12331:2;12316:18;;12309:60;12401:2;12386:18;;12056:354::o;13119:352::-;13321:2;13303:21;;;13360:2;13340:18;;;13333:30;13399;13394:2;13379:18;;13372:58;13462:2;13447:18;;13119:352::o;13476:343::-;13678:2;13660:21;;;13717:2;13697:18;;;13690:30;-1:-1:-1;;;13751:2:1;13736:18;;13729:49;13810:2;13795:18;;13476:343::o;13824:341::-;14026:2;14008:21;;;14065:2;14045:18;;;14038:30;-1:-1:-1;;;14099:2:1;14084:18;;14077:47;14156:2;14141:18;;13824:341::o;14873:135::-;14912:3;14933:17;;;14930:43;;14953:18;;:::i;:::-;-1:-1:-1;15000:1:1;14989:13;;14873:135::o;15013:127::-;15074:10;15069:3;15065:20;15062:1;15055:31;15105:4;15102:1;15095:15;15129:4;15126:1;15119:15;15271:545;15373:2;15368:3;15365:11;15362:448;;;15409:1;15434:5;15430:2;15423:17;15479:4;15475:2;15465:19;15549:2;15537:10;15533:19;15530:1;15526:27;15520:4;15516:38;15585:4;15573:10;15570:20;15567:47;;;-1:-1:-1;15608:4:1;15567:47;15663:2;15658:3;15654:12;15651:1;15647:20;15641:4;15637:31;15627:41;;15718:82;15736:2;15729:5;15726:13;15718:82;;;15781:17;;;15762:1;15751:13;15718:82;;15992:1352;16118:3;16112:10;16145:18;16137:6;16134:30;16131:56;;;16167:18;;:::i;:::-;16196:97;16286:6;16246:38;16278:4;16272:11;16246:38;:::i;:::-;16240:4;16196:97;:::i;:::-;16348:4;;16412:2;16401:14;;16429:1;16424:663;;;;17131:1;17148:6;17145:89;;;-1:-1:-1;17200:19:1;;;17194:26;17145:89;-1:-1:-1;;15949:1:1;15945:11;;;15941:24;15937:29;15927:40;15973:1;15969:11;;;15924:57;17247:81;;16394:944;;16424:663;15218:1;15211:14;;;15255:4;15242:18;;-1:-1:-1;;16460:20:1;;;16578:236;16592:7;16589:1;16586:14;16578:236;;;16681:19;;;16675:26;16660:42;;16773:27;;;;16741:1;16729:14;;;;16608:19;;16578:236;;;16582:3;16842:6;16833:7;16830:19;16827:201;;;16903:19;;;16897:26;-1:-1:-1;;16986:1:1;16982:14;;;16998:3;16978:24;16974:37;16970:42;16955:58;16940:74;;16827:201;-1:-1:-1;;;;;17074:1:1;17058:14;;;17054:22;17041:36;;-1:-1:-1;15992:1352:1:o;17349:127::-;17410:10;17405:3;17401:20;17398:1;17391:31;17441:4;17438:1;17431:15;17465:4;17462:1;17455:15;17481:120;17521:1;17547;17537:35;;17552:18;;:::i;:::-;-1:-1:-1;17586:9:1;;17481:120::o;17606:168::-;17679:9;;;17710;;17727:15;;;17721:22;;17707:37;17697:71;;17748:18;;:::i;18494:184::-;18564:6;18617:2;18605:9;18596:7;18592:23;18588:32;18585:52;;;18633:1;18630;18623:12;18585:52;-1:-1:-1;18656:16:1;;18494:184;-1:-1:-1;18494:184:1:o;19395:112::-;19427:1;19453;19443:35;;19458:18;;:::i;:::-;-1:-1:-1;19492:9:1;;19395:112::o;19512:722::-;19562:3;19603:5;19597:12;19632:36;19658:9;19632:36;:::i;:::-;19687:1;19704:18;;;19731:133;;;;19878:1;19873:355;;;;19697:531;;19731:133;-1:-1:-1;;19764:24:1;;19752:37;;19837:14;;19830:22;19818:35;;19809:45;;;-1:-1:-1;19731:133:1;;19873:355;19904:5;19901:1;19894:16;19933:4;19978:2;19975:1;19965:16;20003:1;20017:165;20031:6;20028:1;20025:13;20017:165;;;20109:14;;20096:11;;;20089:35;20152:16;;;;20046:10;;20017:165;;;20021:3;;;20211:6;20206:3;20202:16;20195:23;;19697:531;;;;;19512:722;;;;:::o;20239:361::-;20468:3;20496:38;20530:3;20522:6;20496:38;:::i;:::-;-1:-1:-1;;;20543:24:1;;20591:2;20583:11;;20239:361;-1:-1:-1;;;20239:361:1:o;20605:359::-;20834:3;20862:38;20896:3;20888:6;20862:38;:::i;:::-;-1:-1:-1;;;20909:23:1;;20956:1;20948:10;;20605:359;-1:-1:-1;;;20605:359:1:o;22732:128::-;22799:9;;;22820:11;;;22817:37;;;22834:18;;:::i;22865:489::-;-1:-1:-1;;;;;23134:15:1;;;23116:34;;23186:15;;23181:2;23166:18;;23159:43;23233:2;23218:18;;23211:34;;;23281:3;23276:2;23261:18;;23254:31;;;23059:4;;23302:46;;23328:19;;23320:6;23302:46;:::i;:::-;23294:54;22865:489;-1:-1:-1;;;;;;22865:489:1:o;23359:249::-;23428:6;23481:2;23469:9;23460:7;23456:23;23452:32;23449:52;;;23497:1;23494;23487:12;23449:52;23529:9;23523:16;23548:30;23572:5;23548:30;:::i;23847:245::-;23914:6;23967:2;23955:9;23946:7;23942:23;23938:32;23935:52;;;23983:1;23980;23973:12;23935:52;24015:9;24009:16;24034:28;24056:5;24034:28;:::i;24915:287::-;25044:3;25082:6;25076:13;25098:66;25157:6;25152:3;25145:4;25137:6;25133:17;25098:66;:::i;:::-;25180:16;;;;;24915:287;-1:-1:-1;;24915:287:1:o

Swarm Source

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