ETH Price: $3,292.18 (-0.23%)

Token

Demorgussy (DMGY)
 

Overview

Max Total Supply

1,802 DMGY

Holders

328

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
2 DMGY
0x0544f1ab9b1c7219d4e733638faa8b8050c5ed7a
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:
Demorgussy

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

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


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

pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/interfaces/IERC2981.sol


// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

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


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

pragma solidity ^0.8.0;

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

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

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

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

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

// File: erc721a/contracts/IERC721A.sol


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

pragma solidity ^0.8.4;

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

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

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

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

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

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

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

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

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

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

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

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

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

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
    }

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

    // ==============================
    //            IERC165
    // ==============================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);

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

    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: erc721a/contracts/ERC721A.sol


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

pragma solidity ^0.8.4;


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

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

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

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

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

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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned.
    // See `_packedOwnershipOf` implementation for details.
    //
    // Bits Layout:
    // - [0..159]   `addr`
    // - [160..223] `startTimestamp`
    // - [224]      `burned`
    // - [225]      `nextInitialized`
    mapping(uint256 => uint256) private _packedOwnerships;

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

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

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

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

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

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

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

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

    /**
     * @dev Returns the total number of tokens burned.
     */
    function _totalBurned() internal view returns (uint256) {
        return _burnCounter;
    }

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

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

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

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

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

    /**
     * Sets the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        assembly { // Cast aux without masking.
            auxCasted := aux
        }
        packed = (packed & BITMASK_AUX_COMPLEMENT) | (auxCasted << BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

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

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & BITMASK_BURNED == 0) {
                        // Invariant:
                        // There will always be an ownership that has an address and is not burned
                        // before an ownership that does not have an address and is not burned.
                        // Hence, curr will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed is zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Casts the address to uint256 without masking.
     */
    function _addressToUint256(address value) private pure returns (uint256 result) {
        assembly {
            result := value
        }
    }

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

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

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

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

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        if (operator == _msgSenderERC721A()) revert ApproveToCaller();

        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
    }

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

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

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

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        _transfer(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & BITMASK_BURNED == 0; // and not burned.
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, '');
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement
     *   {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);

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

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

            if (to.code.length != 0) {
                do {
                    emit Transfer(address(0), to, updatedIndex);
                    if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (updatedIndex < end);
                // Reentrancy protection
                if (_currentIndex != startTokenId) revert();
            } else {
                do {
                    emit Transfer(address(0), to, updatedIndex++);
                } while (updatedIndex < end);
            }
            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 quantity) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);

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

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

            do {
                emit Transfer(address(0), to, updatedIndex++);
            } while (updatedIndex < end);

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) private {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

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

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

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

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        delete _tokenApprovals[tokenId];

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            // We can directly increment and decrement the balances.
            --_packedAddressData[from]; // Updates: `balance -= 1`.
            ++_packedAddressData[to]; // Updates: `balance += 1`.

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

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

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

    /**
     * @dev Equivalent to `_burn(tokenId, false)`.
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

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

        address from = address(uint160(prevOwnershipPacked));

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

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

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

        // Clear approvals from the previous owner.
        delete _tokenApprovals[tokenId];

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            // Updates:
            // - `balance -= 1`.
            // - `numberBurned += 1`.
            //
            // We can directly decrement the balance, and increment the number burned.
            // This is equivalent to `packed -= 1; packed += 1 << BITPOS_NUMBER_BURNED;`.
            _packedAddressData[from] += (1 << BITPOS_NUMBER_BURNED) - 1;

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

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

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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

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


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

pragma solidity ^0.8.0;

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

    /**
     * @dev 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++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = _efficientHash(computedHash, proofElement);
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = _efficientHash(proofElement, computedHash);
            }
        }
        return computedHash;
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

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


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

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


// OpenZeppelin Contracts (last updated v4.6.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 v4.4.1 (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;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

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

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    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");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @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");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

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


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

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

// 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 v4.4.1 (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.
 *
 * `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 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 totalReceived = address(this).balance + totalReleased();
        uint256 payment = _pendingPayment(account, totalReceived, released(account));

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

        _released[account] += payment;
        _totalReleased += 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 totalReceived = token.balanceOf(address(this)) + totalReleased(token);
        uint256 payment = _pendingPayment(account, totalReceived, released(token, account));

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

        _erc20Released[token][account] += payment;
        _erc20TotalReleased[token] += 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 v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

// File: Demorgussy.sol


pragma solidity ^0.8.2;









contract Demorgussy is ERC721A, IERC2981, Ownable, ReentrancyGuard {
    using Strings for uint256;
    uint256 public constant MAX_SUPPLY = 6699;
    bool public _publicSaleStarted = false;
    string public baseURI;
    address public royaltyAddress;

    constructor()
        ERC721A("Demorgussy", "DMGY")
    {}

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

    function flipPublicSaleStarted() public onlyOwner {
        _publicSaleStarted = !_publicSaleStarted;
    }

    function numberMinted(address owner) public view returns (uint256) {
        return _numberMinted(owner);
    }

    function setRoyaltyAddress(address _royaltyAddress) external onlyOwner {
        royaltyAddress = _royaltyAddress;
    }

    function checkMaxSupply(uint256 amount) view private {
        require(totalSupply() + amount <= MAX_SUPPLY, "Will exceed maximum supply");
    }

    function publicMintToken() public nonReentrant {
        require(_publicSaleStarted, "Sale must be active to mint tokens");
        checkMaxSupply(2);
        _safeMint(msg.sender, 2);
    }

    function ownerMint(address to, uint256 amount) public onlyOwner {
        checkMaxSupply(amount);
        _safeMint(to, amount);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "URI query for nonexistent token"
        );
        return string(abi.encodePacked(baseURI,Strings.toString(tokenId),'.json'));
    }

    // ERC165
    function supportsInterface(bytes4 interfaceId) public view override(ERC721A, IERC165) returns (bool) {
        return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
    }

    // IERC2981
    function royaltyInfo(uint256 _tokenId, uint256 _salePrice) override external view returns (address, uint256 royaltyAmount) {
        _tokenId; // silence solc warning
        royaltyAmount = (_salePrice / 100) * 7;
        return (royaltyAddress, royaltyAmount);
    }

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_publicSaleStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[],"name":"flipPublicSaleStarted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicMintToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"royaltyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"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":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_URI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_royaltyAddress","type":"address"}],"name":"setRoyaltyAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526000600a60006101000a81548160ff0219169083151502179055503480156200002c57600080fd5b506040518060400160405280600a81526020017f44656d6f726775737379000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f444d4759000000000000000000000000000000000000000000000000000000008152508160029080519060200190620000b1929190620001e8565b508060039080519060200190620000ca929190620001e8565b50620000db6200011160201b60201c565b600081905550505062000103620000f76200011a60201b60201c565b6200012260201b60201c565b6001600981905550620002fd565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620001f69062000298565b90600052602060002090601f0160209004810192826200021a576000855562000266565b82601f106200023557805160ff191683800117855562000266565b8280016001018555821562000266579182015b828111156200026557825182559160200191906001019062000248565b5b50905062000275919062000279565b5090565b5b80821115620002945760008160009055506001016200027a565b5090565b60006002820490506001821680620002b157607f821691505b60208210811415620002c857620002c7620002ce565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b612f5d806200030d6000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80636352211e116100f9578063ad2f852a11610097578063dc33e68111610071578063dc33e681146104ce578063e6b0bbd8146104fe578063e985e9c514610508578063f2fde38b14610538576101c4565b8063ad2f852a14610464578063b88d4fde14610482578063c87b56dd1461049e576101c4565b8063715018a6116100d3578063715018a6146104025780638da5cb5b1461040c57806395d89b411461042a578063a22cb46514610448576101c4565b80636352211e146103845780636c0360eb146103b457806370a08231146103d2576101c4565b806323b872dd1161016657806342842e0e1161014057806342842e0e14610312578063484b973c1461032e57806355f804b31461034a578063600e97f614610366576101c4565b806323b872dd146102a75780632a55205a146102c357806332cb6b0c146102f4576101c4565b8063081812fc116101a2578063081812fc14610233578063095ea7b3146102635780631291e33e1461027f57806318160ddd14610289576101c4565b806301ffc9a7146101c957806306d254da146101f957806306fdde0314610215575b600080fd5b6101e360048036038101906101de919061239e565b610554565b6040516101f091906127b1565b60405180910390f35b610213600480360381019061020e91906121db565b6105ce565b005b61021d61068e565b60405161022a91906127cc565b60405180910390f35b61024d60048036038101906102489190612441565b610720565b60405161025a9190612721565b60405180910390f35b61027d6004803603810190610278919061235e565b61079c565b005b610287610943565b005b6102916109eb565b60405161029e91906128ae565b60405180910390f35b6102c160048036038101906102bc9190612248565b610a02565b005b6102dd60048036038101906102d8919061246e565b610a12565b6040516102eb929190612788565b60405180910390f35b6102fc610a5c565b60405161030991906128ae565b60405180910390f35b61032c60048036038101906103279190612248565b610a62565b005b6103486004803603810190610343919061235e565b610a82565b005b610364600480360381019061035f91906123f8565b610b15565b005b61036e610bab565b60405161037b91906127b1565b60405180910390f35b61039e60048036038101906103999190612441565b610bbe565b6040516103ab9190612721565b60405180910390f35b6103bc610bd0565b6040516103c991906127cc565b60405180910390f35b6103ec60048036038101906103e791906121db565b610c5e565b6040516103f991906128ae565b60405180910390f35b61040a610d17565b005b610414610d9f565b6040516104219190612721565b60405180910390f35b610432610dc9565b60405161043f91906127cc565b60405180910390f35b610462600480360381019061045d919061231e565b610e5b565b005b61046c610fd3565b6040516104799190612721565b60405180910390f35b61049c6004803603810190610497919061229b565b610ff9565b005b6104b860048036038101906104b39190612441565b61106c565b6040516104c591906127cc565b60405180910390f35b6104e860048036038101906104e391906121db565b6110e8565b6040516104f591906128ae565b60405180910390f35b6105066110fa565b005b610522600480360381019061051d9190612208565b6111b6565b60405161052f91906127b1565b60405180910390f35b610552600480360381019061054d91906121db565b61124a565b005b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806105c757506105c682611342565b5b9050919050565b6105d66113d4565b73ffffffffffffffffffffffffffffffffffffffff166105f4610d9f565b73ffffffffffffffffffffffffffffffffffffffff161461064a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106419061284e565b60405180910390fd5b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60606002805461069d90612b73565b80601f01602080910402602001604051908101604052809291908181526020018280546106c990612b73565b80156107165780601f106106eb57610100808354040283529160200191610716565b820191906000526020600020905b8154815290600101906020018083116106f957829003601f168201915b5050505050905090565b600061072b826113dc565b610761576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006107a78261143b565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561080f576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661082e611509565b73ffffffffffffffffffffffffffffffffffffffff16146108915761085a81610855611509565b6111b6565b610890576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b61094b6113d4565b73ffffffffffffffffffffffffffffffffffffffff16610969610d9f565b73ffffffffffffffffffffffffffffffffffffffff16146109bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109b69061284e565b60405180910390fd5b600a60009054906101000a900460ff1615600a60006101000a81548160ff021916908315150217905550565b60006109f5611511565b6001546000540303905090565b610a0d83838361151a565b505050565b6000806007606484610a2491906129fe565b610a2e9190612a2f565b9050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691509250929050565b611a2b81565b610a7d83838360405180602001604052806000815250610ff9565b505050565b610a8a6113d4565b73ffffffffffffffffffffffffffffffffffffffff16610aa8610d9f565b73ffffffffffffffffffffffffffffffffffffffff1614610afe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af59061284e565b60405180910390fd5b610b07816118c4565b610b11828261191e565b5050565b610b1d6113d4565b73ffffffffffffffffffffffffffffffffffffffff16610b3b610d9f565b73ffffffffffffffffffffffffffffffffffffffff1614610b91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b889061284e565b60405180910390fd5b80600b9080519060200190610ba7929190611fef565b5050565b600a60009054906101000a900460ff1681565b6000610bc98261143b565b9050919050565b600b8054610bdd90612b73565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0990612b73565b8015610c565780601f10610c2b57610100808354040283529160200191610c56565b820191906000526020600020905b815481529060010190602001808311610c3957829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610cc6576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b610d1f6113d4565b73ffffffffffffffffffffffffffffffffffffffff16610d3d610d9f565b73ffffffffffffffffffffffffffffffffffffffff1614610d93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d8a9061284e565b60405180910390fd5b610d9d600061193c565b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054610dd890612b73565b80601f0160208091040260200160405190810160405280929190818152602001828054610e0490612b73565b8015610e515780601f10610e2657610100808354040283529160200191610e51565b820191906000526020600020905b815481529060010190602001808311610e3457829003601f168201915b5050505050905090565b610e63611509565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610ec8576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060076000610ed5611509565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16610f82611509565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610fc791906127b1565b60405180910390a35050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61100484848461151a565b60008373ffffffffffffffffffffffffffffffffffffffff163b146110665761102f84848484611a02565b611065576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6060611077826113dc565b6110b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ad906127ee565b60405180910390fd5b600b6110c183611b62565b6040516020016110d29291906126f2565b6040516020818303038152906040529050919050565b60006110f382611cc3565b9050919050565b60026009541415611140576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111379061288e565b60405180910390fd5b6002600981905550600a60009054906101000a900460ff16611197576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118e9061286e565b60405180910390fd5b6111a160026118c4565b6111ac33600261191e565b6001600981905550565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6112526113d4565b73ffffffffffffffffffffffffffffffffffffffff16611270610d9f565b73ffffffffffffffffffffffffffffffffffffffff16146112c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112bd9061284e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611336576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132d9061280e565b60405180910390fd5b61133f8161193c565b50565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061139d57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806113cd5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600033905090565b6000816113e7611511565b111580156113f6575060005482105b8015611434575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b6000808290508061144a611511565b116114d2576000548110156114d15760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821614156114cf575b60008114156114c557600460008360019003935083815260200190815260200160002054905061149a565b8092505050611504565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b60006001905090565b60006115258261143b565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461158c576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff166115ad611509565b73ffffffffffffffffffffffffffffffffffffffff1614806115dc57506115db856115d6611509565b6111b6565b5b8061162157506115ea611509565b73ffffffffffffffffffffffffffffffffffffffff1661160984610720565b73ffffffffffffffffffffffffffffffffffffffff16145b90508061165a576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156116c1576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116ce8585856001611d1a565b6006600084815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b6117cb86611d20565b1717600460008581526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000083161415611855576000600184019050600060046000838152602001908152602001600020541415611853576000548114611852578260046000838152602001908152602001600020819055505b5b505b828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46118bd8585856001611d2a565b5050505050565b611a2b816118d06109eb565b6118da91906129a8565b111561191b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119129061282e565b60405180910390fd5b50565b611938828260405180602001604052806000815250611d30565b5050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611a28611509565b8786866040518563ffffffff1660e01b8152600401611a4a949392919061273c565b602060405180830381600087803b158015611a6457600080fd5b505af1925050508015611a9557506040513d601f19601f82011682018060405250810190611a9291906123cb565b60015b611b0f573d8060008114611ac5576040519150601f19603f3d011682016040523d82523d6000602084013e611aca565b606091505b50600081511415611b07576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606000821415611baa576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611cbe565b600082905060005b60008214611bdc578080611bc590612bd6565b915050600a82611bd591906129fe565b9150611bb2565b60008167ffffffffffffffff811115611bf857611bf7612d0c565b5b6040519080825280601f01601f191660200182016040528015611c2a5781602001600182028036833780820191505090505b5090505b60008514611cb757600182611c439190612a89565b9150600a85611c529190612c1f565b6030611c5e91906129a8565b60f81b818381518110611c7457611c73612cdd565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85611cb091906129fe565b9450611c2e565b8093505050505b919050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b50505050565b6000819050919050565b50505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611d9d576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000831415611dd8576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611de56000858386611d1a565b600160406001901b178302600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e1611e4a60018514611fe5565b901b60a042901b611e5a86611d20565b1717600460008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b14611f5e575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611f0e6000878480600101955087611a02565b611f44576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808210611e9f578260005414611f5957600080fd5b611fc9565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808210611f5f575b816000819055505050611fdf6000858386611d2a565b50505050565b6000819050919050565b828054611ffb90612b73565b90600052602060002090601f01602090048101928261201d5760008555612064565b82601f1061203657805160ff1916838001178555612064565b82800160010185558215612064579182015b82811115612063578251825591602001919060010190612048565b5b5090506120719190612075565b5090565b5b8082111561208e576000816000905550600101612076565b5090565b60006120a56120a0846128ee565b6128c9565b9050828152602081018484840111156120c1576120c0612d40565b5b6120cc848285612b31565b509392505050565b60006120e76120e28461291f565b6128c9565b90508281526020810184848401111561210357612102612d40565b5b61210e848285612b31565b509392505050565b60008135905061212581612ecb565b92915050565b60008135905061213a81612ee2565b92915050565b60008135905061214f81612ef9565b92915050565b60008151905061216481612ef9565b92915050565b600082601f83011261217f5761217e612d3b565b5b813561218f848260208601612092565b91505092915050565b600082601f8301126121ad576121ac612d3b565b5b81356121bd8482602086016120d4565b91505092915050565b6000813590506121d581612f10565b92915050565b6000602082840312156121f1576121f0612d4a565b5b60006121ff84828501612116565b91505092915050565b6000806040838503121561221f5761221e612d4a565b5b600061222d85828601612116565b925050602061223e85828601612116565b9150509250929050565b60008060006060848603121561226157612260612d4a565b5b600061226f86828701612116565b935050602061228086828701612116565b9250506040612291868287016121c6565b9150509250925092565b600080600080608085870312156122b5576122b4612d4a565b5b60006122c387828801612116565b94505060206122d487828801612116565b93505060406122e5878288016121c6565b925050606085013567ffffffffffffffff81111561230657612305612d45565b5b6123128782880161216a565b91505092959194509250565b6000806040838503121561233557612334612d4a565b5b600061234385828601612116565b92505060206123548582860161212b565b9150509250929050565b6000806040838503121561237557612374612d4a565b5b600061238385828601612116565b9250506020612394858286016121c6565b9150509250929050565b6000602082840312156123b4576123b3612d4a565b5b60006123c284828501612140565b91505092915050565b6000602082840312156123e1576123e0612d4a565b5b60006123ef84828501612155565b91505092915050565b60006020828403121561240e5761240d612d4a565b5b600082013567ffffffffffffffff81111561242c5761242b612d45565b5b61243884828501612198565b91505092915050565b60006020828403121561245757612456612d4a565b5b6000612465848285016121c6565b91505092915050565b6000806040838503121561248557612484612d4a565b5b6000612493858286016121c6565b92505060206124a4858286016121c6565b9150509250929050565b6124b781612abd565b82525050565b6124c681612acf565b82525050565b60006124d782612965565b6124e1818561297b565b93506124f1818560208601612b40565b6124fa81612d4f565b840191505092915050565b600061251082612970565b61251a818561298c565b935061252a818560208601612b40565b61253381612d4f565b840191505092915050565b600061254982612970565b612553818561299d565b9350612563818560208601612b40565b80840191505092915050565b6000815461257c81612b73565b612586818661299d565b945060018216600081146125a157600181146125b2576125e5565b60ff198316865281860193506125e5565b6125bb85612950565b60005b838110156125dd578154818901526001820191506020810190506125be565b838801955050505b50505092915050565b60006125fb601f8361298c565b915061260682612d60565b602082019050919050565b600061261e60268361298c565b915061262982612d89565b604082019050919050565b6000612641601a8361298c565b915061264c82612dd8565b602082019050919050565b600061266460058361299d565b915061266f82612e01565b600582019050919050565b600061268760208361298c565b915061269282612e2a565b602082019050919050565b60006126aa60228361298c565b91506126b582612e53565b604082019050919050565b60006126cd601f8361298c565b91506126d882612ea2565b602082019050919050565b6126ec81612b27565b82525050565b60006126fe828561256f565b915061270a828461253e565b915061271582612657565b91508190509392505050565b600060208201905061273660008301846124ae565b92915050565b600060808201905061275160008301876124ae565b61275e60208301866124ae565b61276b60408301856126e3565b818103606083015261277d81846124cc565b905095945050505050565b600060408201905061279d60008301856124ae565b6127aa60208301846126e3565b9392505050565b60006020820190506127c660008301846124bd565b92915050565b600060208201905081810360008301526127e68184612505565b905092915050565b60006020820190508181036000830152612807816125ee565b9050919050565b6000602082019050818103600083015261282781612611565b9050919050565b6000602082019050818103600083015261284781612634565b9050919050565b600060208201905081810360008301526128678161267a565b9050919050565b600060208201905081810360008301526128878161269d565b9050919050565b600060208201905081810360008301526128a7816126c0565b9050919050565b60006020820190506128c360008301846126e3565b92915050565b60006128d36128e4565b90506128df8282612ba5565b919050565b6000604051905090565b600067ffffffffffffffff82111561290957612908612d0c565b5b61291282612d4f565b9050602081019050919050565b600067ffffffffffffffff82111561293a57612939612d0c565b5b61294382612d4f565b9050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b60006129b382612b27565b91506129be83612b27565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156129f3576129f2612c50565b5b828201905092915050565b6000612a0982612b27565b9150612a1483612b27565b925082612a2457612a23612c7f565b5b828204905092915050565b6000612a3a82612b27565b9150612a4583612b27565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612a7e57612a7d612c50565b5b828202905092915050565b6000612a9482612b27565b9150612a9f83612b27565b925082821015612ab257612ab1612c50565b5b828203905092915050565b6000612ac882612b07565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612b5e578082015181840152602081019050612b43565b83811115612b6d576000848401525b50505050565b60006002820490506001821680612b8b57607f821691505b60208210811415612b9f57612b9e612cae565b5b50919050565b612bae82612d4f565b810181811067ffffffffffffffff82111715612bcd57612bcc612d0c565b5b80604052505050565b6000612be182612b27565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612c1457612c13612c50565b5b600182019050919050565b6000612c2a82612b27565b9150612c3583612b27565b925082612c4557612c44612c7f565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e00600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f57696c6c20657863656564206d6178696d756d20737570706c79000000000000600082015250565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f53616c65206d7573742062652061637469766520746f206d696e7420746f6b6560008201527f6e73000000000000000000000000000000000000000000000000000000000000602082015250565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b612ed481612abd565b8114612edf57600080fd5b50565b612eeb81612acf565b8114612ef657600080fd5b50565b612f0281612adb565b8114612f0d57600080fd5b50565b612f1981612b27565b8114612f2457600080fd5b5056fea26469706673582212204fd44030763d02efd65c4df707f77dba4d792e2be0466950ccd3f7f8e49d626264736f6c63430008070033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101c45760003560e01c80636352211e116100f9578063ad2f852a11610097578063dc33e68111610071578063dc33e681146104ce578063e6b0bbd8146104fe578063e985e9c514610508578063f2fde38b14610538576101c4565b8063ad2f852a14610464578063b88d4fde14610482578063c87b56dd1461049e576101c4565b8063715018a6116100d3578063715018a6146104025780638da5cb5b1461040c57806395d89b411461042a578063a22cb46514610448576101c4565b80636352211e146103845780636c0360eb146103b457806370a08231146103d2576101c4565b806323b872dd1161016657806342842e0e1161014057806342842e0e14610312578063484b973c1461032e57806355f804b31461034a578063600e97f614610366576101c4565b806323b872dd146102a75780632a55205a146102c357806332cb6b0c146102f4576101c4565b8063081812fc116101a2578063081812fc14610233578063095ea7b3146102635780631291e33e1461027f57806318160ddd14610289576101c4565b806301ffc9a7146101c957806306d254da146101f957806306fdde0314610215575b600080fd5b6101e360048036038101906101de919061239e565b610554565b6040516101f091906127b1565b60405180910390f35b610213600480360381019061020e91906121db565b6105ce565b005b61021d61068e565b60405161022a91906127cc565b60405180910390f35b61024d60048036038101906102489190612441565b610720565b60405161025a9190612721565b60405180910390f35b61027d6004803603810190610278919061235e565b61079c565b005b610287610943565b005b6102916109eb565b60405161029e91906128ae565b60405180910390f35b6102c160048036038101906102bc9190612248565b610a02565b005b6102dd60048036038101906102d8919061246e565b610a12565b6040516102eb929190612788565b60405180910390f35b6102fc610a5c565b60405161030991906128ae565b60405180910390f35b61032c60048036038101906103279190612248565b610a62565b005b6103486004803603810190610343919061235e565b610a82565b005b610364600480360381019061035f91906123f8565b610b15565b005b61036e610bab565b60405161037b91906127b1565b60405180910390f35b61039e60048036038101906103999190612441565b610bbe565b6040516103ab9190612721565b60405180910390f35b6103bc610bd0565b6040516103c991906127cc565b60405180910390f35b6103ec60048036038101906103e791906121db565b610c5e565b6040516103f991906128ae565b60405180910390f35b61040a610d17565b005b610414610d9f565b6040516104219190612721565b60405180910390f35b610432610dc9565b60405161043f91906127cc565b60405180910390f35b610462600480360381019061045d919061231e565b610e5b565b005b61046c610fd3565b6040516104799190612721565b60405180910390f35b61049c6004803603810190610497919061229b565b610ff9565b005b6104b860048036038101906104b39190612441565b61106c565b6040516104c591906127cc565b60405180910390f35b6104e860048036038101906104e391906121db565b6110e8565b6040516104f591906128ae565b60405180910390f35b6105066110fa565b005b610522600480360381019061051d9190612208565b6111b6565b60405161052f91906127b1565b60405180910390f35b610552600480360381019061054d91906121db565b61124a565b005b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806105c757506105c682611342565b5b9050919050565b6105d66113d4565b73ffffffffffffffffffffffffffffffffffffffff166105f4610d9f565b73ffffffffffffffffffffffffffffffffffffffff161461064a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106419061284e565b60405180910390fd5b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60606002805461069d90612b73565b80601f01602080910402602001604051908101604052809291908181526020018280546106c990612b73565b80156107165780601f106106eb57610100808354040283529160200191610716565b820191906000526020600020905b8154815290600101906020018083116106f957829003601f168201915b5050505050905090565b600061072b826113dc565b610761576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006107a78261143b565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561080f576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661082e611509565b73ffffffffffffffffffffffffffffffffffffffff16146108915761085a81610855611509565b6111b6565b610890576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b61094b6113d4565b73ffffffffffffffffffffffffffffffffffffffff16610969610d9f565b73ffffffffffffffffffffffffffffffffffffffff16146109bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109b69061284e565b60405180910390fd5b600a60009054906101000a900460ff1615600a60006101000a81548160ff021916908315150217905550565b60006109f5611511565b6001546000540303905090565b610a0d83838361151a565b505050565b6000806007606484610a2491906129fe565b610a2e9190612a2f565b9050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691509250929050565b611a2b81565b610a7d83838360405180602001604052806000815250610ff9565b505050565b610a8a6113d4565b73ffffffffffffffffffffffffffffffffffffffff16610aa8610d9f565b73ffffffffffffffffffffffffffffffffffffffff1614610afe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af59061284e565b60405180910390fd5b610b07816118c4565b610b11828261191e565b5050565b610b1d6113d4565b73ffffffffffffffffffffffffffffffffffffffff16610b3b610d9f565b73ffffffffffffffffffffffffffffffffffffffff1614610b91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b889061284e565b60405180910390fd5b80600b9080519060200190610ba7929190611fef565b5050565b600a60009054906101000a900460ff1681565b6000610bc98261143b565b9050919050565b600b8054610bdd90612b73565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0990612b73565b8015610c565780601f10610c2b57610100808354040283529160200191610c56565b820191906000526020600020905b815481529060010190602001808311610c3957829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610cc6576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b610d1f6113d4565b73ffffffffffffffffffffffffffffffffffffffff16610d3d610d9f565b73ffffffffffffffffffffffffffffffffffffffff1614610d93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d8a9061284e565b60405180910390fd5b610d9d600061193c565b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054610dd890612b73565b80601f0160208091040260200160405190810160405280929190818152602001828054610e0490612b73565b8015610e515780601f10610e2657610100808354040283529160200191610e51565b820191906000526020600020905b815481529060010190602001808311610e3457829003601f168201915b5050505050905090565b610e63611509565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610ec8576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060076000610ed5611509565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16610f82611509565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610fc791906127b1565b60405180910390a35050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61100484848461151a565b60008373ffffffffffffffffffffffffffffffffffffffff163b146110665761102f84848484611a02565b611065576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6060611077826113dc565b6110b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ad906127ee565b60405180910390fd5b600b6110c183611b62565b6040516020016110d29291906126f2565b6040516020818303038152906040529050919050565b60006110f382611cc3565b9050919050565b60026009541415611140576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111379061288e565b60405180910390fd5b6002600981905550600a60009054906101000a900460ff16611197576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118e9061286e565b60405180910390fd5b6111a160026118c4565b6111ac33600261191e565b6001600981905550565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6112526113d4565b73ffffffffffffffffffffffffffffffffffffffff16611270610d9f565b73ffffffffffffffffffffffffffffffffffffffff16146112c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112bd9061284e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611336576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132d9061280e565b60405180910390fd5b61133f8161193c565b50565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061139d57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806113cd5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600033905090565b6000816113e7611511565b111580156113f6575060005482105b8015611434575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b6000808290508061144a611511565b116114d2576000548110156114d15760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821614156114cf575b60008114156114c557600460008360019003935083815260200190815260200160002054905061149a565b8092505050611504565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b60006001905090565b60006115258261143b565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461158c576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff166115ad611509565b73ffffffffffffffffffffffffffffffffffffffff1614806115dc57506115db856115d6611509565b6111b6565b5b8061162157506115ea611509565b73ffffffffffffffffffffffffffffffffffffffff1661160984610720565b73ffffffffffffffffffffffffffffffffffffffff16145b90508061165a576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156116c1576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116ce8585856001611d1a565b6006600084815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b6117cb86611d20565b1717600460008581526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000083161415611855576000600184019050600060046000838152602001908152602001600020541415611853576000548114611852578260046000838152602001908152602001600020819055505b5b505b828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46118bd8585856001611d2a565b5050505050565b611a2b816118d06109eb565b6118da91906129a8565b111561191b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119129061282e565b60405180910390fd5b50565b611938828260405180602001604052806000815250611d30565b5050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611a28611509565b8786866040518563ffffffff1660e01b8152600401611a4a949392919061273c565b602060405180830381600087803b158015611a6457600080fd5b505af1925050508015611a9557506040513d601f19601f82011682018060405250810190611a9291906123cb565b60015b611b0f573d8060008114611ac5576040519150601f19603f3d011682016040523d82523d6000602084013e611aca565b606091505b50600081511415611b07576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606000821415611baa576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611cbe565b600082905060005b60008214611bdc578080611bc590612bd6565b915050600a82611bd591906129fe565b9150611bb2565b60008167ffffffffffffffff811115611bf857611bf7612d0c565b5b6040519080825280601f01601f191660200182016040528015611c2a5781602001600182028036833780820191505090505b5090505b60008514611cb757600182611c439190612a89565b9150600a85611c529190612c1f565b6030611c5e91906129a8565b60f81b818381518110611c7457611c73612cdd565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85611cb091906129fe565b9450611c2e565b8093505050505b919050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b50505050565b6000819050919050565b50505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611d9d576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000831415611dd8576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611de56000858386611d1a565b600160406001901b178302600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e1611e4a60018514611fe5565b901b60a042901b611e5a86611d20565b1717600460008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b14611f5e575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611f0e6000878480600101955087611a02565b611f44576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808210611e9f578260005414611f5957600080fd5b611fc9565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808210611f5f575b816000819055505050611fdf6000858386611d2a565b50505050565b6000819050919050565b828054611ffb90612b73565b90600052602060002090601f01602090048101928261201d5760008555612064565b82601f1061203657805160ff1916838001178555612064565b82800160010185558215612064579182015b82811115612063578251825591602001919060010190612048565b5b5090506120719190612075565b5090565b5b8082111561208e576000816000905550600101612076565b5090565b60006120a56120a0846128ee565b6128c9565b9050828152602081018484840111156120c1576120c0612d40565b5b6120cc848285612b31565b509392505050565b60006120e76120e28461291f565b6128c9565b90508281526020810184848401111561210357612102612d40565b5b61210e848285612b31565b509392505050565b60008135905061212581612ecb565b92915050565b60008135905061213a81612ee2565b92915050565b60008135905061214f81612ef9565b92915050565b60008151905061216481612ef9565b92915050565b600082601f83011261217f5761217e612d3b565b5b813561218f848260208601612092565b91505092915050565b600082601f8301126121ad576121ac612d3b565b5b81356121bd8482602086016120d4565b91505092915050565b6000813590506121d581612f10565b92915050565b6000602082840312156121f1576121f0612d4a565b5b60006121ff84828501612116565b91505092915050565b6000806040838503121561221f5761221e612d4a565b5b600061222d85828601612116565b925050602061223e85828601612116565b9150509250929050565b60008060006060848603121561226157612260612d4a565b5b600061226f86828701612116565b935050602061228086828701612116565b9250506040612291868287016121c6565b9150509250925092565b600080600080608085870312156122b5576122b4612d4a565b5b60006122c387828801612116565b94505060206122d487828801612116565b93505060406122e5878288016121c6565b925050606085013567ffffffffffffffff81111561230657612305612d45565b5b6123128782880161216a565b91505092959194509250565b6000806040838503121561233557612334612d4a565b5b600061234385828601612116565b92505060206123548582860161212b565b9150509250929050565b6000806040838503121561237557612374612d4a565b5b600061238385828601612116565b9250506020612394858286016121c6565b9150509250929050565b6000602082840312156123b4576123b3612d4a565b5b60006123c284828501612140565b91505092915050565b6000602082840312156123e1576123e0612d4a565b5b60006123ef84828501612155565b91505092915050565b60006020828403121561240e5761240d612d4a565b5b600082013567ffffffffffffffff81111561242c5761242b612d45565b5b61243884828501612198565b91505092915050565b60006020828403121561245757612456612d4a565b5b6000612465848285016121c6565b91505092915050565b6000806040838503121561248557612484612d4a565b5b6000612493858286016121c6565b92505060206124a4858286016121c6565b9150509250929050565b6124b781612abd565b82525050565b6124c681612acf565b82525050565b60006124d782612965565b6124e1818561297b565b93506124f1818560208601612b40565b6124fa81612d4f565b840191505092915050565b600061251082612970565b61251a818561298c565b935061252a818560208601612b40565b61253381612d4f565b840191505092915050565b600061254982612970565b612553818561299d565b9350612563818560208601612b40565b80840191505092915050565b6000815461257c81612b73565b612586818661299d565b945060018216600081146125a157600181146125b2576125e5565b60ff198316865281860193506125e5565b6125bb85612950565b60005b838110156125dd578154818901526001820191506020810190506125be565b838801955050505b50505092915050565b60006125fb601f8361298c565b915061260682612d60565b602082019050919050565b600061261e60268361298c565b915061262982612d89565b604082019050919050565b6000612641601a8361298c565b915061264c82612dd8565b602082019050919050565b600061266460058361299d565b915061266f82612e01565b600582019050919050565b600061268760208361298c565b915061269282612e2a565b602082019050919050565b60006126aa60228361298c565b91506126b582612e53565b604082019050919050565b60006126cd601f8361298c565b91506126d882612ea2565b602082019050919050565b6126ec81612b27565b82525050565b60006126fe828561256f565b915061270a828461253e565b915061271582612657565b91508190509392505050565b600060208201905061273660008301846124ae565b92915050565b600060808201905061275160008301876124ae565b61275e60208301866124ae565b61276b60408301856126e3565b818103606083015261277d81846124cc565b905095945050505050565b600060408201905061279d60008301856124ae565b6127aa60208301846126e3565b9392505050565b60006020820190506127c660008301846124bd565b92915050565b600060208201905081810360008301526127e68184612505565b905092915050565b60006020820190508181036000830152612807816125ee565b9050919050565b6000602082019050818103600083015261282781612611565b9050919050565b6000602082019050818103600083015261284781612634565b9050919050565b600060208201905081810360008301526128678161267a565b9050919050565b600060208201905081810360008301526128878161269d565b9050919050565b600060208201905081810360008301526128a7816126c0565b9050919050565b60006020820190506128c360008301846126e3565b92915050565b60006128d36128e4565b90506128df8282612ba5565b919050565b6000604051905090565b600067ffffffffffffffff82111561290957612908612d0c565b5b61291282612d4f565b9050602081019050919050565b600067ffffffffffffffff82111561293a57612939612d0c565b5b61294382612d4f565b9050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b60006129b382612b27565b91506129be83612b27565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156129f3576129f2612c50565b5b828201905092915050565b6000612a0982612b27565b9150612a1483612b27565b925082612a2457612a23612c7f565b5b828204905092915050565b6000612a3a82612b27565b9150612a4583612b27565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612a7e57612a7d612c50565b5b828202905092915050565b6000612a9482612b27565b9150612a9f83612b27565b925082821015612ab257612ab1612c50565b5b828203905092915050565b6000612ac882612b07565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612b5e578082015181840152602081019050612b43565b83811115612b6d576000848401525b50505050565b60006002820490506001821680612b8b57607f821691505b60208210811415612b9f57612b9e612cae565b5b50919050565b612bae82612d4f565b810181811067ffffffffffffffff82111715612bcd57612bcc612d0c565b5b80604052505050565b6000612be182612b27565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612c1457612c13612c50565b5b600182019050919050565b6000612c2a82612b27565b9150612c3583612b27565b925082612c4557612c44612c7f565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e00600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f57696c6c20657863656564206d6178696d756d20737570706c79000000000000600082015250565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f53616c65206d7573742062652061637469766520746f206d696e7420746f6b6560008201527f6e73000000000000000000000000000000000000000000000000000000000000602082015250565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b612ed481612abd565b8114612edf57600080fd5b50565b612eeb81612acf565b8114612ef657600080fd5b50565b612f0281612adb565b8114612f0d57600080fd5b50565b612f1981612b27565b8114612f2457600080fd5b5056fea26469706673582212204fd44030763d02efd65c4df707f77dba4d792e2be0466950ccd3f7f8e49d626264736f6c63430008070033

Deployed Bytecode Sourcemap

75668:2280:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77331:208;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76337:122;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;22025:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24093:204;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;23553:474;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76099:109;;;:::i;:::-;;16066:315;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24979:170;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;77564:272;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;75774:41;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25220:185;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76824:137;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76001:90;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75822:38;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21814:144;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75867:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17691:224;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74779:103;;;:::i;:::-;;74128:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22194:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24369:308;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75895:29;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25476:396;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76969:339;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76216:113;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76622:194;;;:::i;:::-;;24748:164;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75037:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;77331:208;77426:4;77465:26;77450:41;;;:11;:41;;;;:81;;;;77495:36;77519:11;77495:23;:36::i;:::-;77450:81;77443:88;;77331:208;;;:::o;76337:122::-;74359:12;:10;:12::i;:::-;74348:23;;:7;:5;:7::i;:::-;:23;;;74340:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;76436:15:::1;76419:14;;:32;;;;;;;;;;;;;;;;;;76337:122:::0;:::o;22025:100::-;22079:13;22112:5;22105:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22025:100;:::o;24093:204::-;24161:7;24186:16;24194:7;24186;:16::i;:::-;24181:64;;24211:34;;;;;;;;;;;;;;24181:64;24265:15;:24;24281:7;24265:24;;;;;;;;;;;;;;;;;;;;;24258:31;;24093:204;;;:::o;23553:474::-;23626:13;23658:27;23677:7;23658:18;:27::i;:::-;23626:61;;23708:5;23702:11;;:2;:11;;;23698:48;;;23722:24;;;;;;;;;;;;;;23698:48;23786:5;23763:28;;:19;:17;:19::i;:::-;:28;;;23759:175;;23811:44;23828:5;23835:19;:17;:19::i;:::-;23811:16;:44::i;:::-;23806:128;;23883:35;;;;;;;;;;;;;;23806:128;23759:175;23973:2;23946:15;:24;23962:7;23946:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;24011:7;24007:2;23991:28;;24000:5;23991:28;;;;;;;;;;;;23615:412;23553:474;;:::o;76099:109::-;74359:12;:10;:12::i;:::-;74348:23;;:7;:5;:7::i;:::-;:23;;;74340:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;76182:18:::1;;;;;;;;;;;76181:19;76160:18;;:40;;;;;;;;;;;;;;;;;;76099:109::o:0;16066:315::-;16119:7;16347:15;:13;:15::i;:::-;16332:12;;16316:13;;:28;:46;16309:53;;16066:315;:::o;24979:170::-;25113:28;25123:4;25129:2;25133:7;25113:9;:28::i;:::-;24979:170;;;:::o;77564:272::-;77655:7;77664:21;77778:1;77771:3;77758:10;:16;;;;:::i;:::-;77757:22;;;;:::i;:::-;77741:38;;77798:14;;;;;;;;;;;77790:38;;77564:272;;;;;:::o;75774:41::-;75811:4;75774:41;:::o;25220:185::-;25358:39;25375:4;25381:2;25385:7;25358:39;;;;;;;;;;;;:16;:39::i;:::-;25220:185;;;:::o;76824:137::-;74359:12;:10;:12::i;:::-;74348:23;;:7;:5;:7::i;:::-;:23;;;74340:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;76899:22:::1;76914:6;76899:14;:22::i;:::-;76932:21;76942:2;76946:6;76932:9;:21::i;:::-;76824:137:::0;;:::o;76001:90::-;74359:12;:10;:12::i;:::-;74348:23;;:7;:5;:7::i;:::-;:23;;;74340:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;76079:4:::1;76069:7;:14;;;;;;;;;;;;:::i;:::-;;76001:90:::0;:::o;75822:38::-;;;;;;;;;;;;;:::o;21814:144::-;21878:7;21921:27;21940:7;21921:18;:27::i;:::-;21898:52;;21814:144;;;:::o;75867:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;17691:224::-;17755:7;17796:1;17779:19;;:5;:19;;;17775:60;;;17807:28;;;;;;;;;;;;;;17775:60;13030:13;17853:18;:25;17872:5;17853:25;;;;;;;;;;;;;;;;:54;17846:61;;17691:224;;;:::o;74779:103::-;74359:12;:10;:12::i;:::-;74348:23;;:7;:5;:7::i;:::-;:23;;;74340:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;74844:30:::1;74871:1;74844:18;:30::i;:::-;74779:103::o:0;74128:87::-;74174:7;74201:6;;;;;;;;;;;74194:13;;74128:87;:::o;22194:104::-;22250:13;22283:7;22276:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22194:104;:::o;24369:308::-;24480:19;:17;:19::i;:::-;24468:31;;:8;:31;;;24464:61;;;24508:17;;;;;;;;;;;;;;24464:61;24590:8;24538:18;:39;24557:19;:17;:19::i;:::-;24538:39;;;;;;;;;;;;;;;:49;24578:8;24538:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;24650:8;24614:55;;24629:19;:17;:19::i;:::-;24614:55;;;24660:8;24614:55;;;;;;:::i;:::-;;;;;;;;24369:308;;:::o;75895:29::-;;;;;;;;;;;;;:::o;25476:396::-;25643:28;25653:4;25659:2;25663:7;25643:9;:28::i;:::-;25704:1;25686:2;:14;;;:19;25682:183;;25725:56;25756:4;25762:2;25766:7;25775:5;25725:30;:56::i;:::-;25720:145;;25809:40;;;;;;;;;;;;;;25720:145;25682:183;25476:396;;;;:::o;76969:339::-;77087:13;77140:16;77148:7;77140;:16::i;:::-;77118:97;;;;;;;;;;;;:::i;:::-;;;;;;;;;77257:7;77265:25;77282:7;77265:16;:25::i;:::-;77240:59;;;;;;;;;:::i;:::-;;;;;;;;;;;;;77226:74;;76969:339;;;:::o;76216:113::-;76274:7;76301:20;76315:5;76301:13;:20::i;:::-;76294:27;;76216:113;;;:::o;76622:194::-;44098:1;44696:7;;:19;;44688:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;44098:1;44829:7;:18;;;;76688::::1;;;;;;;;;;;76680:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;76756:17;76771:1;76756:14;:17::i;:::-;76784:24;76794:10;76806:1;76784:9;:24::i;:::-;44054:1:::0;45008:7;:22;;;;76622:194::o;24748:164::-;24845:4;24869:18;:25;24888:5;24869:25;;;;;;;;;;;;;;;:35;24895:8;24869:35;;;;;;;;;;;;;;;;;;;;;;;;;24862:42;;24748:164;;;;:::o;75037:201::-;74359:12;:10;:12::i;:::-;74348:23;;:7;:5;:7::i;:::-;:23;;;74340:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;75146:1:::1;75126:22;;:8;:22;;;;75118:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;75202:28;75221:8;75202:18;:28::i;:::-;75037:201:::0;:::o;17012:615::-;17097:4;17412:10;17397:25;;:11;:25;;;;:102;;;;17489:10;17474:25;;:11;:25;;;;17397:102;:179;;;;17566:10;17551:25;;:11;:25;;;;17397:179;17377:199;;17012:615;;;:::o;65249:98::-;65302:7;65329:10;65322:17;;65249:98;:::o;26127:273::-;26184:4;26240:7;26221:15;:13;:15::i;:::-;:26;;:66;;;;;26274:13;;26264:7;:23;26221:66;:152;;;;;26372:1;13800:8;26325:17;:26;26343:7;26325:26;;;;;;;;;;;;:43;:48;26221:152;26201:172;;26127:273;;;:::o;19329:1129::-;19396:7;19416:12;19431:7;19416:22;;19499:4;19480:15;:13;:15::i;:::-;:23;19476:915;;19533:13;;19526:4;:20;19522:869;;;19571:14;19588:17;:23;19606:4;19588:23;;;;;;;;;;;;19571:40;;19704:1;13800:8;19677:6;:23;:28;19673:699;;;20196:113;20213:1;20203:6;:11;20196:113;;;20256:17;:25;20274:6;;;;;;;20256:25;;;;;;;;;;;;20247:34;;20196:113;;;20342:6;20335:13;;;;;;19673:699;19548:843;19522:869;19476:915;20419:31;;;;;;;;;;;;;;19329:1129;;;;:::o;40109:105::-;40169:7;40196:10;40189:17;;40109:105;:::o;77844:101::-;77909:7;77936:1;77929:8;;77844:101;:::o;31366:2515::-;31481:27;31511;31530:7;31511:18;:27::i;:::-;31481:57;;31596:4;31555:45;;31571:19;31555:45;;;31551:86;;31609:28;;;;;;;;;;;;;;31551:86;31650:22;31699:4;31676:27;;:19;:17;:19::i;:::-;:27;;;:87;;;;31720:43;31737:4;31743:19;:17;:19::i;:::-;31720:16;:43::i;:::-;31676:87;:147;;;;31804:19;:17;:19::i;:::-;31780:43;;:20;31792:7;31780:11;:20::i;:::-;:43;;;31676:147;31650:174;;31842:17;31837:66;;31868:35;;;;;;;;;;;;;;31837:66;31932:1;31918:16;;:2;:16;;;31914:52;;;31943:23;;;;;;;;;;;;;;31914:52;31979:43;32001:4;32007:2;32011:7;32020:1;31979:21;:43::i;:::-;32095:15;:24;32111:7;32095:24;;;;;;;;;;;;32088:31;;;;;;;;;;;32487:18;:24;32506:4;32487:24;;;;;;;;;;;;;;;;32485:26;;;;;;;;;;;;32556:18;:22;32575:2;32556:22;;;;;;;;;;;;;;;;32554:24;;;;;;;;;;;14082:8;13684:3;32937:15;:41;;32895:21;32913:2;32895:17;:21::i;:::-;:84;:128;32849:17;:26;32867:7;32849:26;;;;;;;;;;;:174;;;;33193:1;14082:8;33143:19;:46;:51;33139:626;;;33215:19;33247:1;33237:7;:11;33215:33;;33404:1;33370:17;:30;33388:11;33370:30;;;;;;;;;;;;:35;33366:384;;;33508:13;;33493:11;:28;33489:242;;33688:19;33655:17;:30;33673:11;33655:30;;;;;;;;;;;:52;;;;33489:242;33366:384;33196:569;33139:626;33812:7;33808:2;33793:27;;33802:4;33793:27;;;;;;;;;;;;33831:42;33852:4;33858:2;33862:7;33871:1;33831:20;:42::i;:::-;31470:2411;;31366:2515;;;:::o;76467:147::-;75811:4;76555:6;76539:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:36;;76531:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;76467:147;:::o;26484:104::-;26553:27;26563:2;26567:8;26553:27;;;;;;;;;;;;:9;:27::i;:::-;26484:104;;:::o;75398:191::-;75472:16;75491:6;;;;;;;;;;;75472:25;;75517:8;75508:6;;:17;;;;;;;;;;;;;;;;;;75572:8;75541:40;;75562:8;75541:40;;;;;;;;;;;;75461:128;75398:191;:::o;37578:716::-;37741:4;37787:2;37762:45;;;37808:19;:17;:19::i;:::-;37829:4;37835:7;37844:5;37762:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;37758:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38062:1;38045:6;:13;:18;38041:235;;;38091:40;;;;;;;;;;;;;;38041:235;38234:6;38228:13;38219:6;38215:2;38211:15;38204:38;37758:529;37931:54;;;37921:64;;;:6;:64;;;;37914:71;;;37578:716;;;;;;:::o;2180:723::-;2236:13;2466:1;2457:5;:10;2453:53;;;2484:10;;;;;;;;;;;;;;;;;;;;;2453:53;2516:12;2531:5;2516:20;;2547:14;2572:78;2587:1;2579:4;:9;2572:78;;2605:8;;;;;:::i;:::-;;;;2636:2;2628:10;;;;;:::i;:::-;;;2572:78;;;2660:19;2692:6;2682:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2660:39;;2710:154;2726:1;2717:5;:10;2710:154;;2754:1;2744:11;;;;;:::i;:::-;;;2821:2;2813:5;:10;;;;:::i;:::-;2800:2;:24;;;;:::i;:::-;2787:39;;2770:6;2777;2770:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;2850:2;2841:11;;;;;:::i;:::-;;;2710:154;;;2888:6;2874:21;;;;;2180:723;;;;:::o;17997:176::-;18058:7;13030:13;13167:2;18086:18;:25;18105:5;18086:25;;;;;;;;;;;;;;;;:49;;18085:80;18078:87;;17997:176;;;:::o;38942:159::-;;;;;:::o;23114:148::-;23178:14;23239:5;23229:15;;23114:148;;;:::o;39760:158::-;;;;;:::o;26961:2236::-;27084:20;27107:13;;27084:36;;27149:1;27135:16;;:2;:16;;;27131:48;;;27160:19;;;;;;;;;;;;;;27131:48;27206:1;27194:8;:13;27190:44;;;27216:18;;;;;;;;;;;;;;27190:44;27247:61;27277:1;27281:2;27285:12;27299:8;27247:21;:61::i;:::-;27851:1;13167:2;27822:1;:25;;27821:31;27809:8;:44;27783:18;:22;27802:2;27783:22;;;;;;;;;;;;;;;;:70;;;;;;;;;;;13947:3;28252:29;28279:1;28267:8;:13;28252:14;:29::i;:::-;:56;;13684:3;28189:15;:41;;28147:21;28165:2;28147:17;:21::i;:::-;:84;:162;28096:17;:31;28114:12;28096:31;;;;;;;;;;;:213;;;;28326:20;28349:12;28326:35;;28376:11;28405:8;28390:12;:23;28376:37;;28452:1;28434:2;:14;;;:19;28430:635;;28474:313;28530:12;28526:2;28505:38;;28522:1;28505:38;;;;;;;;;;;;28571:69;28610:1;28614:2;28618:14;;;;;;28634:5;28571:30;:69::i;:::-;28566:174;;28676:40;;;;;;;;;;;;;;28566:174;28782:3;28767:12;:18;28474:313;;28868:12;28851:13;;:29;28847:43;;28882:8;;;28847:43;28430:635;;;28931:119;28987:14;;;;;;28983:2;28962:40;;28979:1;28962:40;;;;;;;;;;;;29045:3;29030:12;:18;28931:119;;28430:635;29095:12;29079:13;:28;;;;27560:1559;;29129:60;29158:1;29162:2;29166:12;29180:8;29129:20;:60::i;:::-;27073:2124;26961:2236;;;:::o;23349:142::-;23407:14;23468:5;23458:15;;23349:142;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:410:1:-;84:5;109:65;125:48;166:6;125:48;:::i;:::-;109:65;:::i;:::-;100:74;;197:6;190:5;183:21;235:4;228:5;224:16;273:3;264:6;259:3;255:16;252:25;249:112;;;280:79;;:::i;:::-;249:112;370:41;404:6;399:3;394;370:41;:::i;:::-;90:327;7:410;;;;;:::o;423:412::-;501:5;526:66;542:49;584:6;542:49;:::i;:::-;526:66;:::i;:::-;517:75;;615:6;608:5;601:21;653:4;646:5;642:16;691:3;682:6;677:3;673:16;670:25;667:112;;;698:79;;:::i;:::-;667:112;788:41;822:6;817:3;812;788:41;:::i;:::-;507:328;423:412;;;;;:::o;841:139::-;887:5;925:6;912:20;903:29;;941:33;968:5;941:33;:::i;:::-;841:139;;;;:::o;986:133::-;1029:5;1067:6;1054:20;1045:29;;1083:30;1107:5;1083:30;:::i;:::-;986:133;;;;:::o;1125:137::-;1170:5;1208:6;1195:20;1186:29;;1224:32;1250:5;1224:32;:::i;:::-;1125:137;;;;:::o;1268:141::-;1324:5;1355:6;1349:13;1340:22;;1371:32;1397:5;1371:32;:::i;:::-;1268:141;;;;:::o;1428:338::-;1483:5;1532:3;1525:4;1517:6;1513:17;1509:27;1499:122;;1540:79;;:::i;:::-;1499:122;1657:6;1644:20;1682:78;1756:3;1748:6;1741:4;1733:6;1729:17;1682:78;:::i;:::-;1673:87;;1489:277;1428:338;;;;:::o;1786:340::-;1842:5;1891:3;1884:4;1876:6;1872:17;1868:27;1858:122;;1899:79;;:::i;:::-;1858:122;2016:6;2003:20;2041:79;2116:3;2108:6;2101:4;2093:6;2089:17;2041:79;:::i;:::-;2032:88;;1848:278;1786:340;;;;:::o;2132:139::-;2178:5;2216:6;2203:20;2194:29;;2232:33;2259:5;2232:33;:::i;:::-;2132:139;;;;:::o;2277:329::-;2336:6;2385:2;2373:9;2364:7;2360:23;2356:32;2353:119;;;2391:79;;:::i;:::-;2353:119;2511:1;2536:53;2581:7;2572:6;2561:9;2557:22;2536:53;:::i;:::-;2526:63;;2482:117;2277:329;;;;:::o;2612:474::-;2680:6;2688;2737:2;2725:9;2716:7;2712:23;2708:32;2705:119;;;2743:79;;:::i;:::-;2705:119;2863:1;2888:53;2933:7;2924:6;2913:9;2909:22;2888:53;:::i;:::-;2878:63;;2834:117;2990:2;3016:53;3061:7;3052:6;3041:9;3037:22;3016:53;:::i;:::-;3006:63;;2961:118;2612:474;;;;;:::o;3092:619::-;3169:6;3177;3185;3234:2;3222:9;3213:7;3209:23;3205:32;3202:119;;;3240:79;;:::i;:::-;3202:119;3360:1;3385:53;3430:7;3421:6;3410:9;3406:22;3385:53;:::i;:::-;3375:63;;3331:117;3487:2;3513:53;3558:7;3549:6;3538:9;3534:22;3513:53;:::i;:::-;3503:63;;3458:118;3615:2;3641:53;3686:7;3677:6;3666:9;3662:22;3641:53;:::i;:::-;3631:63;;3586:118;3092:619;;;;;:::o;3717:943::-;3812:6;3820;3828;3836;3885:3;3873:9;3864:7;3860:23;3856:33;3853:120;;;3892:79;;:::i;:::-;3853:120;4012:1;4037:53;4082:7;4073:6;4062:9;4058:22;4037:53;:::i;:::-;4027:63;;3983:117;4139:2;4165:53;4210:7;4201:6;4190:9;4186:22;4165:53;:::i;:::-;4155:63;;4110:118;4267:2;4293:53;4338:7;4329:6;4318:9;4314:22;4293:53;:::i;:::-;4283:63;;4238:118;4423:2;4412:9;4408:18;4395:32;4454:18;4446:6;4443:30;4440:117;;;4476:79;;:::i;:::-;4440:117;4581:62;4635:7;4626:6;4615:9;4611:22;4581:62;:::i;:::-;4571:72;;4366:287;3717:943;;;;;;;:::o;4666:468::-;4731:6;4739;4788:2;4776:9;4767:7;4763:23;4759:32;4756:119;;;4794:79;;:::i;:::-;4756:119;4914:1;4939:53;4984:7;4975:6;4964:9;4960:22;4939:53;:::i;:::-;4929:63;;4885:117;5041:2;5067:50;5109:7;5100:6;5089:9;5085:22;5067:50;:::i;:::-;5057:60;;5012:115;4666:468;;;;;:::o;5140:474::-;5208:6;5216;5265:2;5253:9;5244:7;5240:23;5236:32;5233:119;;;5271:79;;:::i;:::-;5233:119;5391:1;5416:53;5461:7;5452:6;5441:9;5437:22;5416:53;:::i;:::-;5406:63;;5362:117;5518:2;5544:53;5589:7;5580:6;5569:9;5565:22;5544:53;:::i;:::-;5534:63;;5489:118;5140:474;;;;;:::o;5620:327::-;5678:6;5727:2;5715:9;5706:7;5702:23;5698:32;5695:119;;;5733:79;;:::i;:::-;5695:119;5853:1;5878:52;5922:7;5913:6;5902:9;5898:22;5878:52;:::i;:::-;5868:62;;5824:116;5620:327;;;;:::o;5953:349::-;6022:6;6071:2;6059:9;6050:7;6046:23;6042:32;6039:119;;;6077:79;;:::i;:::-;6039:119;6197:1;6222:63;6277:7;6268:6;6257:9;6253:22;6222:63;:::i;:::-;6212:73;;6168:127;5953:349;;;;:::o;6308:509::-;6377:6;6426:2;6414:9;6405:7;6401:23;6397:32;6394:119;;;6432:79;;:::i;:::-;6394:119;6580:1;6569:9;6565:17;6552:31;6610:18;6602:6;6599:30;6596:117;;;6632:79;;:::i;:::-;6596:117;6737:63;6792:7;6783:6;6772:9;6768:22;6737:63;:::i;:::-;6727:73;;6523:287;6308:509;;;;:::o;6823:329::-;6882:6;6931:2;6919:9;6910:7;6906:23;6902:32;6899:119;;;6937:79;;:::i;:::-;6899:119;7057:1;7082:53;7127:7;7118:6;7107:9;7103:22;7082:53;:::i;:::-;7072:63;;7028:117;6823:329;;;;:::o;7158:474::-;7226:6;7234;7283:2;7271:9;7262:7;7258:23;7254:32;7251:119;;;7289:79;;:::i;:::-;7251:119;7409:1;7434:53;7479:7;7470:6;7459:9;7455:22;7434:53;:::i;:::-;7424:63;;7380:117;7536:2;7562:53;7607:7;7598:6;7587:9;7583:22;7562:53;:::i;:::-;7552:63;;7507:118;7158:474;;;;;:::o;7638:118::-;7725:24;7743:5;7725:24;:::i;:::-;7720:3;7713:37;7638:118;;:::o;7762:109::-;7843:21;7858:5;7843:21;:::i;:::-;7838:3;7831:34;7762:109;;:::o;7877:360::-;7963:3;7991:38;8023:5;7991:38;:::i;:::-;8045:70;8108:6;8103:3;8045:70;:::i;:::-;8038:77;;8124:52;8169:6;8164:3;8157:4;8150:5;8146:16;8124:52;:::i;:::-;8201:29;8223:6;8201:29;:::i;:::-;8196:3;8192:39;8185:46;;7967:270;7877:360;;;;:::o;8243:364::-;8331:3;8359:39;8392:5;8359:39;:::i;:::-;8414:71;8478:6;8473:3;8414:71;:::i;:::-;8407:78;;8494:52;8539:6;8534:3;8527:4;8520:5;8516:16;8494:52;:::i;:::-;8571:29;8593:6;8571:29;:::i;:::-;8566:3;8562:39;8555:46;;8335:272;8243:364;;;;:::o;8613:377::-;8719:3;8747:39;8780:5;8747:39;:::i;:::-;8802:89;8884:6;8879:3;8802:89;:::i;:::-;8795:96;;8900:52;8945:6;8940:3;8933:4;8926:5;8922:16;8900:52;:::i;:::-;8977:6;8972:3;8968:16;8961:23;;8723:267;8613:377;;;;:::o;9020:845::-;9123:3;9160:5;9154:12;9189:36;9215:9;9189:36;:::i;:::-;9241:89;9323:6;9318:3;9241:89;:::i;:::-;9234:96;;9361:1;9350:9;9346:17;9377:1;9372:137;;;;9523:1;9518:341;;;;9339:520;;9372:137;9456:4;9452:9;9441;9437:25;9432:3;9425:38;9492:6;9487:3;9483:16;9476:23;;9372:137;;9518:341;9585:38;9617:5;9585:38;:::i;:::-;9645:1;9659:154;9673:6;9670:1;9667:13;9659:154;;;9747:7;9741:14;9737:1;9732:3;9728:11;9721:35;9797:1;9788:7;9784:15;9773:26;;9695:4;9692:1;9688:12;9683:17;;9659:154;;;9842:6;9837:3;9833:16;9826:23;;9525:334;;9339:520;;9127:738;;9020:845;;;;:::o;9871:366::-;10013:3;10034:67;10098:2;10093:3;10034:67;:::i;:::-;10027:74;;10110:93;10199:3;10110:93;:::i;:::-;10228:2;10223:3;10219:12;10212:19;;9871:366;;;:::o;10243:::-;10385:3;10406:67;10470:2;10465:3;10406:67;:::i;:::-;10399:74;;10482:93;10571:3;10482:93;:::i;:::-;10600:2;10595:3;10591:12;10584:19;;10243:366;;;:::o;10615:::-;10757:3;10778:67;10842:2;10837:3;10778:67;:::i;:::-;10771:74;;10854:93;10943:3;10854:93;:::i;:::-;10972:2;10967:3;10963:12;10956:19;;10615:366;;;:::o;10987:400::-;11147:3;11168:84;11250:1;11245:3;11168:84;:::i;:::-;11161:91;;11261:93;11350:3;11261:93;:::i;:::-;11379:1;11374:3;11370:11;11363:18;;10987:400;;;:::o;11393:366::-;11535:3;11556:67;11620:2;11615:3;11556:67;:::i;:::-;11549:74;;11632:93;11721:3;11632:93;:::i;:::-;11750:2;11745:3;11741:12;11734:19;;11393:366;;;:::o;11765:::-;11907:3;11928:67;11992:2;11987:3;11928:67;:::i;:::-;11921:74;;12004:93;12093:3;12004:93;:::i;:::-;12122:2;12117:3;12113:12;12106:19;;11765:366;;;:::o;12137:::-;12279:3;12300:67;12364:2;12359:3;12300:67;:::i;:::-;12293:74;;12376:93;12465:3;12376:93;:::i;:::-;12494:2;12489:3;12485:12;12478:19;;12137:366;;;:::o;12509:118::-;12596:24;12614:5;12596:24;:::i;:::-;12591:3;12584:37;12509:118;;:::o;12633:695::-;12911:3;12933:92;13021:3;13012:6;12933:92;:::i;:::-;12926:99;;13042:95;13133:3;13124:6;13042:95;:::i;:::-;13035:102;;13154:148;13298:3;13154:148;:::i;:::-;13147:155;;13319:3;13312:10;;12633:695;;;;;:::o;13334:222::-;13427:4;13465:2;13454:9;13450:18;13442:26;;13478:71;13546:1;13535:9;13531:17;13522:6;13478:71;:::i;:::-;13334:222;;;;:::o;13562:640::-;13757:4;13795:3;13784:9;13780:19;13772:27;;13809:71;13877:1;13866:9;13862:17;13853:6;13809:71;:::i;:::-;13890:72;13958:2;13947:9;13943:18;13934:6;13890:72;:::i;:::-;13972;14040:2;14029:9;14025:18;14016:6;13972:72;:::i;:::-;14091:9;14085:4;14081:20;14076:2;14065:9;14061:18;14054:48;14119:76;14190:4;14181:6;14119:76;:::i;:::-;14111:84;;13562:640;;;;;;;:::o;14208:332::-;14329:4;14367:2;14356:9;14352:18;14344:26;;14380:71;14448:1;14437:9;14433:17;14424:6;14380:71;:::i;:::-;14461:72;14529:2;14518:9;14514:18;14505:6;14461:72;:::i;:::-;14208:332;;;;;:::o;14546:210::-;14633:4;14671:2;14660:9;14656:18;14648:26;;14684:65;14746:1;14735:9;14731:17;14722:6;14684:65;:::i;:::-;14546:210;;;;:::o;14762:313::-;14875:4;14913:2;14902:9;14898:18;14890:26;;14962:9;14956:4;14952:20;14948:1;14937:9;14933:17;14926:47;14990:78;15063:4;15054:6;14990:78;:::i;:::-;14982:86;;14762:313;;;;:::o;15081:419::-;15247:4;15285:2;15274:9;15270:18;15262:26;;15334:9;15328:4;15324:20;15320:1;15309:9;15305:17;15298:47;15362:131;15488:4;15362:131;:::i;:::-;15354:139;;15081:419;;;:::o;15506:::-;15672:4;15710:2;15699:9;15695:18;15687:26;;15759:9;15753:4;15749:20;15745:1;15734:9;15730:17;15723:47;15787:131;15913:4;15787:131;:::i;:::-;15779:139;;15506:419;;;:::o;15931:::-;16097:4;16135:2;16124:9;16120:18;16112:26;;16184:9;16178:4;16174:20;16170:1;16159:9;16155:17;16148:47;16212:131;16338:4;16212:131;:::i;:::-;16204:139;;15931:419;;;:::o;16356:::-;16522:4;16560:2;16549:9;16545:18;16537:26;;16609:9;16603:4;16599:20;16595:1;16584:9;16580:17;16573:47;16637:131;16763:4;16637:131;:::i;:::-;16629:139;;16356:419;;;:::o;16781:::-;16947:4;16985:2;16974:9;16970:18;16962:26;;17034:9;17028:4;17024:20;17020:1;17009:9;17005:17;16998:47;17062:131;17188:4;17062:131;:::i;:::-;17054:139;;16781:419;;;:::o;17206:::-;17372:4;17410:2;17399:9;17395:18;17387:26;;17459:9;17453:4;17449:20;17445:1;17434:9;17430:17;17423:47;17487:131;17613:4;17487:131;:::i;:::-;17479:139;;17206:419;;;:::o;17631:222::-;17724:4;17762:2;17751:9;17747:18;17739:26;;17775:71;17843:1;17832:9;17828:17;17819:6;17775:71;:::i;:::-;17631:222;;;;:::o;17859:129::-;17893:6;17920:20;;:::i;:::-;17910:30;;17949:33;17977:4;17969:6;17949:33;:::i;:::-;17859:129;;;:::o;17994:75::-;18027:6;18060:2;18054:9;18044:19;;17994:75;:::o;18075:307::-;18136:4;18226:18;18218:6;18215:30;18212:56;;;18248:18;;:::i;:::-;18212:56;18286:29;18308:6;18286:29;:::i;:::-;18278:37;;18370:4;18364;18360:15;18352:23;;18075:307;;;:::o;18388:308::-;18450:4;18540:18;18532:6;18529:30;18526:56;;;18562:18;;:::i;:::-;18526:56;18600:29;18622:6;18600:29;:::i;:::-;18592:37;;18684:4;18678;18674:15;18666:23;;18388:308;;;:::o;18702:141::-;18751:4;18774:3;18766:11;;18797:3;18794:1;18787:14;18831:4;18828:1;18818:18;18810:26;;18702:141;;;:::o;18849:98::-;18900:6;18934:5;18928:12;18918:22;;18849:98;;;:::o;18953:99::-;19005:6;19039:5;19033:12;19023:22;;18953:99;;;:::o;19058:168::-;19141:11;19175:6;19170:3;19163:19;19215:4;19210:3;19206:14;19191:29;;19058:168;;;;:::o;19232:169::-;19316:11;19350:6;19345:3;19338:19;19390:4;19385:3;19381:14;19366:29;;19232:169;;;;:::o;19407:148::-;19509:11;19546:3;19531:18;;19407:148;;;;:::o;19561:305::-;19601:3;19620:20;19638:1;19620:20;:::i;:::-;19615:25;;19654:20;19672:1;19654:20;:::i;:::-;19649:25;;19808:1;19740:66;19736:74;19733:1;19730:81;19727:107;;;19814:18;;:::i;:::-;19727:107;19858:1;19855;19851:9;19844:16;;19561:305;;;;:::o;19872:185::-;19912:1;19929:20;19947:1;19929:20;:::i;:::-;19924:25;;19963:20;19981:1;19963:20;:::i;:::-;19958:25;;20002:1;19992:35;;20007:18;;:::i;:::-;19992:35;20049:1;20046;20042:9;20037:14;;19872:185;;;;:::o;20063:348::-;20103:7;20126:20;20144:1;20126:20;:::i;:::-;20121:25;;20160:20;20178:1;20160:20;:::i;:::-;20155:25;;20348:1;20280:66;20276:74;20273:1;20270:81;20265:1;20258:9;20251:17;20247:105;20244:131;;;20355:18;;:::i;:::-;20244:131;20403:1;20400;20396:9;20385:20;;20063:348;;;;:::o;20417:191::-;20457:4;20477:20;20495:1;20477:20;:::i;:::-;20472:25;;20511:20;20529:1;20511:20;:::i;:::-;20506:25;;20550:1;20547;20544:8;20541:34;;;20555:18;;:::i;:::-;20541:34;20600:1;20597;20593:9;20585:17;;20417:191;;;;:::o;20614:96::-;20651:7;20680:24;20698:5;20680:24;:::i;:::-;20669:35;;20614:96;;;:::o;20716:90::-;20750:7;20793:5;20786:13;20779:21;20768:32;;20716:90;;;:::o;20812:149::-;20848:7;20888:66;20881:5;20877:78;20866:89;;20812:149;;;:::o;20967:126::-;21004:7;21044:42;21037:5;21033:54;21022:65;;20967:126;;;:::o;21099:77::-;21136:7;21165:5;21154:16;;21099:77;;;:::o;21182:154::-;21266:6;21261:3;21256;21243:30;21328:1;21319:6;21314:3;21310:16;21303:27;21182:154;;;:::o;21342:307::-;21410:1;21420:113;21434:6;21431:1;21428:13;21420:113;;;21519:1;21514:3;21510:11;21504:18;21500:1;21495:3;21491:11;21484:39;21456:2;21453:1;21449:10;21444:15;;21420:113;;;21551:6;21548:1;21545:13;21542:101;;;21631:1;21622:6;21617:3;21613:16;21606:27;21542:101;21391:258;21342:307;;;:::o;21655:320::-;21699:6;21736:1;21730:4;21726:12;21716:22;;21783:1;21777:4;21773:12;21804:18;21794:81;;21860:4;21852:6;21848:17;21838:27;;21794:81;21922:2;21914:6;21911:14;21891:18;21888:38;21885:84;;;21941:18;;:::i;:::-;21885:84;21706:269;21655:320;;;:::o;21981:281::-;22064:27;22086:4;22064:27;:::i;:::-;22056:6;22052:40;22194:6;22182:10;22179:22;22158:18;22146:10;22143:34;22140:62;22137:88;;;22205:18;;:::i;:::-;22137:88;22245:10;22241:2;22234:22;22024:238;21981:281;;:::o;22268:233::-;22307:3;22330:24;22348:5;22330:24;:::i;:::-;22321:33;;22376:66;22369:5;22366:77;22363:103;;;22446:18;;:::i;:::-;22363:103;22493:1;22486:5;22482:13;22475:20;;22268:233;;;:::o;22507:176::-;22539:1;22556:20;22574:1;22556:20;:::i;:::-;22551:25;;22590:20;22608:1;22590:20;:::i;:::-;22585:25;;22629:1;22619:35;;22634:18;;:::i;:::-;22619:35;22675:1;22672;22668:9;22663:14;;22507:176;;;;:::o;22689:180::-;22737:77;22734:1;22727:88;22834:4;22831:1;22824:15;22858:4;22855:1;22848:15;22875:180;22923:77;22920:1;22913:88;23020:4;23017:1;23010:15;23044:4;23041:1;23034:15;23061:180;23109:77;23106:1;23099:88;23206:4;23203:1;23196:15;23230:4;23227:1;23220:15;23247:180;23295:77;23292:1;23285:88;23392:4;23389:1;23382:15;23416:4;23413:1;23406:15;23433:180;23481:77;23478:1;23471:88;23578:4;23575:1;23568:15;23602:4;23599:1;23592:15;23619:117;23728:1;23725;23718:12;23742:117;23851:1;23848;23841:12;23865:117;23974:1;23971;23964:12;23988:117;24097:1;24094;24087:12;24111:102;24152:6;24203:2;24199:7;24194:2;24187:5;24183:14;24179:28;24169:38;;24111:102;;;:::o;24219:181::-;24359:33;24355:1;24347:6;24343:14;24336:57;24219:181;:::o;24406:225::-;24546:34;24542:1;24534:6;24530:14;24523:58;24615:8;24610:2;24602:6;24598:15;24591:33;24406:225;:::o;24637:176::-;24777:28;24773:1;24765:6;24761:14;24754:52;24637:176;:::o;24819:155::-;24959:7;24955:1;24947:6;24943:14;24936:31;24819:155;:::o;24980:182::-;25120:34;25116:1;25108:6;25104:14;25097:58;24980:182;:::o;25168:221::-;25308:34;25304:1;25296:6;25292:14;25285:58;25377:4;25372:2;25364:6;25360:15;25353:29;25168:221;:::o;25395:181::-;25535:33;25531:1;25523:6;25519:14;25512:57;25395:181;:::o;25582:122::-;25655:24;25673:5;25655:24;:::i;:::-;25648:5;25645:35;25635:63;;25694:1;25691;25684:12;25635:63;25582:122;:::o;25710:116::-;25780:21;25795:5;25780:21;:::i;:::-;25773:5;25770:32;25760:60;;25816:1;25813;25806:12;25760:60;25710:116;:::o;25832:120::-;25904:23;25921:5;25904:23;:::i;:::-;25897:5;25894:34;25884:62;;25942:1;25939;25932:12;25884:62;25832:120;:::o;25958:122::-;26031:24;26049:5;26031:24;:::i;:::-;26024:5;26021:35;26011:63;;26070:1;26067;26060:12;26011:63;25958:122;:::o

Swarm Source

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