// SPDX-License-Identifier: MIT
pragma solidity ^0.8.11;

// NFTC Open Source Contracts See: https://github.com/NFTCulture/nftc-open-contracts
import '@nftculture/nftc-open-contracts/contracts/financial/LockedPaymentSplitter.sol';

// NFTC Prerelease Contracts
import '@nftculture/nftc-contract-library/contracts/token/PrivilegedMinter.sol';
import '@nftculture/nftc-contract-library/contracts/token/ERC721A_NFTCExtended.sol';
import '@nftculture/nftc-contract-library/contracts/token/phased/PhasedMintThree.sol';
import '@nftculture/nftc-contract-library/contracts/token/phased/PhaseOneIsIndexed.sol';
import '@nftculture/nftc-contract-library/contracts/token/phased/PhaseTwoIsIndexed.sol';

// OZ Libraries
import '@openzeppelin/contracts/security/ReentrancyGuard.sol';
import '@openzeppelin/contracts/utils/Strings.sol';

import './CosmicBloomDelegateEnforcer.sol';

// Error Codes
error ExceedsBatchSize();
error ExceedsPurchaseLimit();
error ExceedsSupplyCap();
error InvalidPayment();

/**
 * @title CosmicBloomBase
 * @author @NiftyMike | @NFTCulture
 * @dev ERC721a Implementation with @NFTCulture standardized components.
 * 
 * OperatorFilterer support via ClosedSea (by Vectorized).
 *
 * "MintTokensFor" methods are compatible with Delegate.cash (use at your own risk).
 */
abstract contract CosmicBloomBase is
    ERC721A_NFTCExtended,
    ReentrancyGuard,
    LockedPaymentSplitter,
    PhasedMintThree,
    PhaseOneIsIndexed,
    PhaseTwoIsIndexed,
    PrivilegedMinter,
    CosmicBloomDelegateEnforcer
{
    using Strings for uint256;

    uint256 private constant MAX_RESERVE_BATCH_SIZE = 100;

    uint256 private constant PHASE_ONE_BATCH_SIZE = 25;
    uint256 private constant PHASE_ONE_PURCHASE_LIMIT = 1300;
    uint256 private constant PHASE_ONE_SUPPLY_CAP = 1300; // Unrestricted, since controlled by Merkletree

    uint256 private constant PHASE_TWO_BATCH_SIZE = 25;
    uint256 private constant PHASE_TWO_PURCHASE_LIMIT = 1132;
    uint256 private constant PHASE_TWO_SUPPLY_CAP = 1132; // Lower cap to allow space for studio/team/Leo mints

    uint256 private constant PUBLIC_MINT_BATCH_SIZE = 25;
    uint256 private constant PUBLIC_MINT_PURCHASE_LIMIT = 1300;
    uint256 private constant PUBLIC_MINT_SUPPLY_CAP = 1300;

    string public baseURI;

    constructor(
        string memory __name,
        string memory __symbol,
        string memory __baseURI,
        address[] memory __addresses,
        uint256[] memory __splits,
        uint256 __phaseOnePricePerNft,
        uint256 __phaseTwoPricePerNft,
        uint256 __phaseThreePricePerNft
    )
        ERC721A(__name, __symbol)
        SlimPaymentSplitter(__addresses, __splits)
        PhasedMintThree(__phaseOnePricePerNft, __phaseTwoPricePerNft, __phaseThreePricePerNft)
        PrivilegedMinter(msg.sender)
    {
        baseURI = __baseURI;

        _registerForOperatorFiltering();
        operatorFilteringEnabled = true;
    }

    function nftcContractDefinition() external pure returns (string memory) {
        // NFTC Contract Definition for front-end websites.
        return
            string(
                abi.encodePacked('{', '"ncdVersion":1,', '"phases":3,', '"type":"Static",', '"openEdition":false', '}')
            );
    }

    function maxSupply() external pure returns (uint256) {
        return PUBLIC_MINT_SUPPLY_CAP;
    }

    function exists(uint256 tokenId) external view returns (bool) {
        return _exists(tokenId);
    }

    function phaseOneBatchSize() external pure returns (uint256) {
        return PHASE_ONE_BATCH_SIZE;
    }

    function phaseTwoBatchSize() external pure returns (uint256) {
        return PHASE_TWO_BATCH_SIZE;
    }

    function publicMintBatchSize() external pure returns (uint256) {
        return PUBLIC_MINT_BATCH_SIZE;
    }

    function setBaseURI(string memory __baseUri) external onlyOwner {
        baseURI = __baseUri;
    }

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

    function _tokenFilename(uint256 tokenId) internal pure virtual returns (string memory) {
        return tokenId.toString();
    }

    function setPrivilegedMinter(address __newPrivilegedMinter) external onlyOwner {
        _setPrivilegedMinter(__newPrivilegedMinter);
    }

    function setMerkleRoots(bytes32 __indexedRootPhaseOne, bytes32 __indexedRootPhaseTwo) external onlyOwner {
        _setMerkleRoots(__indexedRootPhaseOne, __indexedRootPhaseTwo);
    }

    function _setMerkleRoots(bytes32 __phaseOneRoot, bytes32 __phaseTwoRoot) internal {
        if (__phaseOneRoot != 0) {
            _setPhaseOneRoot(__phaseOneRoot);
        }

        if (__phaseTwoRoot != 0) {
            _setPhaseTwoRoot(__phaseTwoRoot);
        }
    }

    function _getPackedPurchasesAs64(
        address wallet
    ) internal view virtual override(PhaseOneIsIndexed, PhaseTwoIsIndexed) returns (uint64) {
        return _getAux(wallet);
    }

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), 'No token');

        string memory base = _baseURI();
        require(bytes(base).length > 0, 'Base unset');

        return string(abi.encodePacked(base, _tokenFilename(tokenId)));
    }

    /**
     * @notice Owner: reserve tokens for team.
     *
     * @param friends addresses to send tokens to.
     * @param count the number of tokens to mint.
     */
    function reserveTokens(address[] memory friends, uint256 count) external payable onlyOwner {
        if (0 >= count || count > MAX_RESERVE_BATCH_SIZE) revert ExceedsBatchSize();
        if (_totalMinted() + (friends.length * count) > PUBLIC_MINT_SUPPLY_CAP) revert ExceedsSupplyCap();

        uint256 idx;
        for (idx = 0; idx < friends.length; idx++) {
            _internalMintTokens(friends[idx], count);
        }
    }

    /**
     * @notice Mint tokens - purchase bound by terms & conditions of project.
     *
     * @param count the number of tokens to mint.
     */
    function publicMintTokens(uint256 count) external payable nonReentrant isPublicMinting {
        if (0 >= count || count > PUBLIC_MINT_BATCH_SIZE) revert ExceedsBatchSize();
        if (msg.value != publicMintPricePerNft * count) revert InvalidPayment();
        if (_totalMinted() + count > PUBLIC_MINT_SUPPLY_CAP) revert ExceedsSupplyCap();

        _internalMintTokens(msg.sender, count);
    }

    /**
     * @notice Same as publicMintTokens(), but with a "to" for purchasing / custodial wallet platforms.
     *
     * @param count the number of tokens to mint.
     * @param to address where the new token should be sent.
     */
    function publicMintTokensTo(
        uint256 count,
        address to
    ) external payable nonReentrant isPublicMinting onlyPrivilegedMinter {
        if (0 >= count || count > PUBLIC_MINT_BATCH_SIZE) revert ExceedsBatchSize();
        if (msg.value != publicMintPricePerNft * count) revert InvalidPayment();
        if (_totalMinted() + count > PUBLIC_MINT_SUPPLY_CAP) revert ExceedsSupplyCap();

        _internalMintTokens(to, count);
    }

    /**
     * @notice Mint tokens (Phase One) - purchase bound by terms & conditions of project.
     *
     * @param proof the merkle proof for this purchase.
     * @param count the number of tokens to mint.
     */
    function phaseOneMintTokens(bytes32[] calldata proof, uint256 count) external payable nonReentrant isPhaseOne {
        if (0 >= count || count > PHASE_ONE_BATCH_SIZE) revert ExceedsBatchSize();
        if (msg.value != phaseOnePricePerNft * count) revert InvalidPayment();
        if (_totalMinted() + count > PHASE_ONE_SUPPLY_CAP) revert ExceedsSupplyCap();

        (uint32 phaseOnePurchases, uint32 otherPhase) = _unpack32(_getAux(msg.sender));

        uint256 newBalance = phaseOnePurchases + count;
        if (newBalance > PHASE_ONE_PURCHASE_LIMIT) revert ExceedsPurchaseLimit();

        _setAux(msg.sender, _pack32(uint16(newBalance), otherPhase));

        _proofMintTokens_PhaseOne(msg.sender, proof, newBalance, count, msg.sender);
    }

    /**
     * @notice Mint tokens (Phase One) - purchase bound by terms & conditions of project.
     *
     * @param proof the merkle proof for this purchase.
     * @param count the number of tokens to mint.
     * @param coldWallet The cold wallet, if caller is a delegated hot wallet.
     */
    function phaseOneMintTokensFor(
        bytes32[] calldata proof,
        uint256 count,
        address coldWallet
    ) external payable nonReentrant isPhaseOne {
        if (0 >= count || count > PHASE_ONE_BATCH_SIZE) revert ExceedsBatchSize();
        if (msg.value != phaseOnePricePerNft * count) revert InvalidPayment();
        if (_totalMinted() + count > PHASE_ONE_SUPPLY_CAP) revert ExceedsSupplyCap();

        address operator = _TryDelegate(msg.sender, coldWallet);

        (uint32 phaseOnePurchases, uint32 otherPhase) = _unpack32(_getAux(operator));

        uint256 newBalance = phaseOnePurchases + count;
        if (newBalance > PHASE_ONE_PURCHASE_LIMIT) revert ExceedsPurchaseLimit();

        _setAux(operator, _pack32(uint16(newBalance), otherPhase));

        _proofMintTokens_PhaseOne(operator, proof, newBalance, count, msg.sender);
    }

    /**
     * @notice Mint tokens (Phase Two) - purchase bound by terms & conditions of project.
     *
     * @param proof the merkle proof for this purchase.
     * @param count the number of tokens to mint.
     */
    function phaseTwoMintTokens(bytes32[] calldata proof, uint256 count) external payable nonReentrant isPhaseTwo {
        if (0 >= count || count > PHASE_TWO_BATCH_SIZE) revert ExceedsBatchSize();
        if (msg.value != phaseTwoPricePerNft * count) revert InvalidPayment();
        if (_totalMinted() + count > PHASE_TWO_SUPPLY_CAP) revert ExceedsSupplyCap();

        (uint32 otherPhase, uint32 phaseTwoPurchases) = _unpack32(_getAux(msg.sender));

        uint256 newBalance = phaseTwoPurchases + count;
        if (newBalance > PHASE_TWO_PURCHASE_LIMIT) revert ExceedsPurchaseLimit();

        _setAux(msg.sender, _pack32(otherPhase, uint16(newBalance)));

        _proofMintTokens_PhaseTwo(msg.sender, proof, newBalance, count, msg.sender);
    }

    /**
     * @notice Mint tokens (Phase Two) - purchase bound by terms & conditions of project.
     *
     * @param proof the merkle proof for this purchase.
     * @param count the number of tokens to mint.
     * @param coldWallet The cold wallet, if caller is a delegated hot wallet.
     */
    function phaseTwoMintTokensFor(
        bytes32[] calldata proof,
        uint256 count,
        address coldWallet
    ) external payable nonReentrant isPhaseTwo {
        if (0 >= count || count > PHASE_TWO_BATCH_SIZE) revert ExceedsBatchSize();
        if (msg.value != phaseTwoPricePerNft * count) revert InvalidPayment();
        if (_totalMinted() + count > PHASE_TWO_SUPPLY_CAP) revert ExceedsSupplyCap();

        address operator = _TryDelegate(msg.sender, coldWallet);

        (uint32 otherPhase, uint32 phaseTwoPurchases) = _unpack32(_getAux(operator));

        uint256 newBalance = phaseTwoPurchases + count;
        if (newBalance > PHASE_TWO_PURCHASE_LIMIT) revert ExceedsPurchaseLimit();

        _setAux(operator, _pack32(otherPhase, uint16(newBalance)));

        _proofMintTokens_PhaseTwo(operator, proof, newBalance, count, msg.sender);
    }

    function _internalMintTokens(
        address minter,
        uint256 count
    ) internal override(PhaseOneIsIndexed, PhaseTwoIsIndexed) {
        _safeMint(minter, count);
    }

    function _internalMintTokens(
        address minter,
        uint256 count,
        uint256 flavorId
    ) internal override(PhaseOneIsIndexed, PhaseTwoIsIndexed) {
        // Do nothing
    }
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"ExceedsBatchSize","type":"error"},{"inputs":[],"name":"ExceedsPurchaseLimit","type":"error"},{"inputs":[],"name":"ExceedsSupplyCap","type":"error"},{"inputs":[],"name":"IndexedProofInvalid_PhaseOne","type":"error"},{"inputs":[],"name":"IndexedProofInvalid_PhaseTwo","type":"error"},{"inputs":[],"name":"InvalidColdWallet","type":"error"},{"inputs":[],"name":"InvalidPayment","type":"error"},{"inputs":[],"name":"InvalidQueryRange","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":"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":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"PayeeTransferred","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":"DELEGATION_REGISTRY","outputs":[{"internalType":"contract IDelegationRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","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":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"checkProof_PhaseOne","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"checkProof_PhaseTwo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getIndexedLeafFor","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"getLeafFor","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"getNextEntryIndex_PhaseOne","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"getNextEntryIndex_PhaseTwo","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPrivilegedMinter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"getTokensPurchased_PhaseOne","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"getTokensPurchased_PhaseTwo","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPhaseOneActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPhaseTwoActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPublicMintingActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftcContractDefinition","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"operatorFilteringEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[],"name":"phaseOneBatchSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"phaseOneMintTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"address","name":"coldWallet","type":"address"}],"name":"phaseOneMintTokensFor","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"phaseOnePricePerNft","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phaseTwoBatchSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"phaseTwoMintTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"address","name":"coldWallet","type":"address"}],"name":"phaseTwoMintTokensFor","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"phaseTwoPricePerNft","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicMintBatchSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"publicMintPricePerNft","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"publicMintTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"publicMintTokensTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"subscription","type":"address"},{"internalType":"bool","name":"subscribe","type":"bool"}],"name":"registerForOperatorFiltering","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"releaseToSelf","outputs":[],"stateMutability":"nonpayable","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":[],"name":"repeatRegistration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"friends","type":"address[]"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"reserveTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","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":"payable","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":"bytes32","name":"__indexedRootPhaseOne","type":"bytes32"},{"internalType":"bytes32","name":"__indexedRootPhaseTwo","type":"bytes32"}],"name":"setMerkleRoots","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"__phaseOneActive","type":"bool"},{"internalType":"bool","name":"__phaseTwoActive","type":"bool"},{"internalType":"bool","name":"__publicMintingActive","type":"bool"},{"internalType":"uint256","name":"__phaseOnePricePerNft","type":"uint256"},{"internalType":"uint256","name":"__phaseTwoPricePerNft","type":"uint256"},{"internalType":"uint256","name":"__publicMintPricePerNft","type":"uint256"}],"name":"setMintingState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"setOperatorFilteringEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"__newPrivilegedMinter","type":"address"}],"name":"setPrivilegedMinter","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":[],"name":"supportedPhases","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":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newOwner","type":"address"}],"name":"transferPayee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]