ETH Price: $3,414.88 (+3.60%)

Token

Boring Opepen (BOOP)
 

Overview

Max Total Supply

5,555 BOOP

Holders

460

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
5 BOOP
0x1b992bd1e12bfd9426a18f45fd78480f02a2b7c6
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:
BoringOpepen

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 1 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-10-15
*/

// File: erc721a/contracts/IERC721A.sol
    
    
    // ERC721A Contracts v4.2.3
    // Creator: Chiru Labs
    
    pragma solidity ^0.8.4;
    
    /**
     * @dev Interface of ERC721A.
     */
    interface IERC721A {
        /**
         * The caller must own the token or be an approved operator.
         */
        error ApprovalCallerNotOwnerNorApproved();
    
        /**
         * The token does not exist.
         */
        error ApprovalQueryForNonexistentToken();
    
        /**
         * Cannot query the balance for the zero address.
         */
        error BalanceQueryForZeroAddress();
    
        /**
         * Cannot mint to the zero address.
         */
        error MintToZeroAddress();
    
        /**
         * The quantity of tokens minted must be more than zero.
         */
        error MintZeroQuantity();
    
        /**
         * The token does not exist.
         */
        error OwnerQueryForNonexistentToken();
    
        /**
         * The caller must own the token or be an approved operator.
         */
        error TransferCallerNotOwnerNorApproved();
    
        /**
         * The token must be owned by 'from'.
         */
        error TransferFromIncorrectOwner();
    
        /**
         * Cannot safely transfer to a contract that does not implement the
         * ERC721Receiver interface.
         */
        error TransferToNonERC721ReceiverImplementer();
    
        /**
         * Cannot transfer to the zero address.
         */
        error TransferToZeroAddress();
    
        /**
         * The token does not exist.
         */
        error URIQueryForNonexistentToken();
    
        /**
         * The 'quantity' minted with ERC2309 exceeds the safety limit.
         */
        error MintERC2309QuantityExceedsLimit();
    
        /**
         * The 'extraData' cannot be set on an unintialized ownership slot.
         */
        error OwnershipNotInitializedForExtraData();
    
        // =============================================================
        //                            STRUCTS
        // =============================================================
    
        struct TokenOwnership {
            // The address of the owner.
            address addr;
            // Stores the start time of ownership with minimal overhead for tokenomics.
            uint64 startTimestamp;
            // Whether the token has been burned.
            bool burned;
            // Arbitrary data similar to 'startTimestamp' that can be set via {_extraData}.
            uint24 extraData;
        }
    
        // =============================================================
        //                         TOKEN COUNTERS
        // =============================================================
    
        /**
         * @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() external view returns (uint256);
    
        // =============================================================
        //                            IERC165
        // =============================================================
    
        /**
         * @dev Returns true if this contract implements the interface defined by
         * 'interfaceId'. See the corresponding
         * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
         * to learn more about how these ids are created.
         *
         * This function call must use less than 30000 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',
         * 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,
            bytes calldata data
        ) external payable;
    
        /**
         * @dev Equivalent to 'safeTransferFrom(from, to, tokenId, '')'.
         */
        function safeTransferFrom(
            address from,
            address to,
            uint256 tokenId
        ) external payable;
    
        /**
         * @dev Transfers 'tokenId' 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 payable;
    
        /**
         * @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 payable;
    
        /**
         * @dev Approve or remove 'operator' as an operator for the caller.
         * Operators can call {transferFrom} or {safeTransferFrom}
         * for any token owned by the caller.
         *
         * Requirements:
         *
         * - The 'operator' cannot be the caller.
         *
         * Emits an {ApprovalForAll} event.
         */
        function setApprovalForAll(address operator, bool _approved) external;
    
        /**
         * @dev Returns the account approved for 'tokenId' token.
         *
         * Requirements:
         *
         * - 'tokenId' must exist.
         */
        function getApproved(uint256 tokenId) external view returns (address operator);
    
        /**
         * @dev Returns if the 'operator' is allowed to manage all of the assets of 'owner'.
         *
         * See {setApprovalForAll}.
         */
        function isApprovedForAll(address owner, address operator) external view returns (bool);
    
        // =============================================================
        //                        IERC721Metadata
        // =============================================================
    
        /**
         * @dev Returns the token collection name.
         */
        function name() external view returns (string memory);
    
        /**
         * @dev Returns the token collection symbol.
         */
        function symbol() external view returns (string memory);
    
        /**
         * @dev Returns the Uniform Resource Identifier (URI) for 'tokenId' token.
         */
        function tokenURI(uint256 tokenId) external view returns (string memory);
    
        // =============================================================
        //                           IERC2309
        // =============================================================
    
        /**
         * @dev Emitted when tokens in 'fromTokenId' to 'toTokenId'
         * (inclusive) is transferred from 'from' to 'to', as defined in the
         * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
         *
         * See {_mintERC2309} for more details.
         */
        event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
    }
    
    // File: erc721a/contracts/ERC721A.sol
    
    
    // ERC721A Contracts v4.2.3
    // Creator: Chiru Labs
    
    pragma solidity ^0.8.4;
    
    
    /**
     * @dev Interface of ERC721 token receiver.
     */
    interface ERC721A__IERC721Receiver {
        function onERC721Received(
            address operator,
            address from,
            uint256 tokenId,
            bytes calldata data
        ) external returns (bytes4);
    }
    
    /**
     * @title ERC721A
     *
     * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721)
     * Non-Fungible Token Standard, including the Metadata extension.
     * Optimized for lower gas during batch mints.
     *
     * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...)
     * starting from '_startTokenId()'.
     *
     * Assumptions:
     *
     * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
     * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
     */
    contract ERC721A is IERC721A {
        // Bypass for a '--via-ir' bug (https://github.com/chiru-labs/ERC721A/pull/364).
        struct TokenApprovalRef {
            address value;
        }
    
        // =============================================================
        //                           CONSTANTS
        // =============================================================
    
        // Mask of an entry in packed address data.
        uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;
    
        // The bit position of 'numberMinted' in packed address data.
        uint256 private constant _BITPOS_NUMBER_MINTED = 64;
    
        // The bit position of 'numberBurned' in packed address data.
        uint256 private constant _BITPOS_NUMBER_BURNED = 128;
    
        // The bit position of 'aux' in packed address data.
        uint256 private constant _BITPOS_AUX = 192;
    
        // Mask of all 256 bits in packed address data except the 64 bits for 'aux'.
        uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;
    
        // The bit position of 'startTimestamp' in packed ownership.
        uint256 private constant _BITPOS_START_TIMESTAMP = 160;
    
        // The bit mask of the 'burned' bit in packed ownership.
        uint256 private constant _BITMASK_BURNED = 1 << 224;
    
        // The bit position of the 'nextInitialized' bit in packed ownership.
        uint256 private constant _BITPOS_NEXT_INITIALIZED = 225;
    
        // The bit mask of the 'nextInitialized' bit in packed ownership.
        uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225;
    
        // The bit position of 'extraData' in packed ownership.
        uint256 private constant _BITPOS_EXTRA_DATA = 232;
    
        // Mask of all 256 bits in a packed ownership except the 24 bits for 'extraData'.
        uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;
    
        // The mask of the lower 160 bits for addresses.
        uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;
    
        // The maximum 'quantity' that can be minted with {_mintERC2309}.
        // This limit is to prevent overflows on the address data entries.
        // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309}
        // is required to cause an overflow, which is unrealistic.
        uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;
    
        // The 'Transfer' event signature is given by:
        // 'keccak256(bytes("Transfer(address,address,uint256)"))'.
        bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
            0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;
    
        // =============================================================
        //                            STORAGE
        // =============================================================
    
        // The next token ID to be minted.
        uint256 private _currentIndex;
    
        // The number of tokens burned.
        uint256 private _burnCounter;
    
        // Token name
        string private _name;
    
        // Token symbol
        string private _symbol;
    
        // Mapping from token ID to ownership details
        // An empty struct value does not necessarily mean the token is unowned.
        // See {_packedOwnershipOf} implementation for details.
        //
        // Bits Layout:
        // - [0..159]   'addr'
        // - [160..223] 'startTimestamp'
        // - [224]      'burned'
        // - [225]      'nextInitialized'
        // - [232..255] 'extraData'
        mapping(uint256 => uint256) private _packedOwnerships;
    
        // Mapping owner address to address data.
        //
        // Bits Layout:
        // - [0..63]    'balance'
        // - [64..127]  'numberMinted'
        // - [128..191] 'numberBurned'
        // - [192..255] 'aux'
        mapping(address => uint256) private _packedAddressData;
    
        // Mapping from token ID to approved address.
        mapping(uint256 => TokenApprovalRef) private _tokenApprovals;
    
        // Mapping from owner to operator approvals
        mapping(address => mapping(address => bool)) private _operatorApprovals;
    
        // =============================================================
        //                          CONSTRUCTOR
        // =============================================================
    
        constructor(string memory name_, string memory symbol_) {
            _name = name_;
            _symbol = symbol_;
            _currentIndex = _startTokenId();
        }
    
        // =============================================================
        //                   TOKEN COUNTING OPERATIONS
        // =============================================================
    
        /**
         * @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 virtual 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 virtual 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 virtual 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 virtual returns (uint256) {
            return _burnCounter;
        }
    
        // =============================================================
        //                    ADDRESS DATA OPERATIONS
        // =============================================================
    
        /**
         * @dev Returns the number of tokens in 'owner''s account.
         */
        function balanceOf(address owner) public view virtual override returns (uint256) {
            if (owner == address(0)) revert BalanceQueryForZeroAddress();
            return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
        }
    
        /**
         * Returns the number of tokens minted by 'owner'.
         */
        function _numberMinted(address owner) internal view returns (uint256) {
            return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY;
        }
    
        /**
         * Returns the number of tokens burned by or on behalf of 'owner'.
         */
        function _numberBurned(address owner) internal view returns (uint256) {
            return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY;
        }
    
        /**
         * Returns the auxiliary data for 'owner'. (e.g. number of whitelist mint slots used).
         */
        function _getAux(address owner) internal view returns (uint64) {
            return uint64(_packedAddressData[owner] >> _BITPOS_AUX);
        }
    
        /**
         * Sets the auxiliary data for 'owner'. (e.g. number of whitelist mint slots used).
         * If there are multiple variables, please pack them into a uint64.
         */
        function _setAux(address owner, uint64 aux) internal virtual {
            uint256 packed = _packedAddressData[owner];
            uint256 auxCasted;
            // Cast 'aux' with assembly to avoid redundant masking.
            assembly {
                auxCasted := aux
            }
            packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX);
            _packedAddressData[owner] = packed;
        }
    
        // =============================================================
        //                            IERC165
        // =============================================================
    
        /**
         * @dev Returns true if this contract implements the interface defined by
         * 'interfaceId'. See the corresponding
         * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
         * to learn more about how these ids are created.
         *
         * This function call must use less than 30000 gas.
         */
        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: [ERC165](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.
        }
    
        // =============================================================
        //                        IERC721Metadata
        // =============================================================
    
        /**
         * @dev Returns the token collection name.
         */
        function name() public view virtual override returns (string memory) {
            return _name;
        }
    
        /**
         * @dev Returns the token collection symbol.
         */
        function symbol() public view virtual override returns (string memory) {
            return _symbol;
        }
    
        /**
         * @dev Returns the Uniform Resource Identifier (URI) for 'tokenId' token.
         */
        function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
            if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
    
            string memory baseURI = _baseURI();
            return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
        }
    
        /**
         * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
         * token will be the concatenation of the 'baseURI' and the 'tokenId'. Empty
         * by default, it can be overridden in child contracts.
         */
        function _baseURI() internal view virtual returns (string memory) {
            return '';
        }
    
        // =============================================================
        //                     OWNERSHIPS OPERATIONS
        // =============================================================
    
        /**
         * @dev Returns the owner of the 'tokenId' token.
         *
         * Requirements:
         *
         * - 'tokenId' must exist.
         */
        function ownerOf(uint256 tokenId) public view virtual override returns (address) {
            return address(uint160(_packedOwnershipOf(tokenId)));
        }
    
        /**
         * @dev Gas spent here starts off proportional to the maximum mint batch size.
         * It gradually moves to O(1) as tokens get transferred around over time.
         */
        function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) {
            return _unpackedOwnership(_packedOwnershipOf(tokenId));
        }
    
        /**
         * @dev Returns the unpacked 'TokenOwnership' struct at 'index'.
         */
        function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) {
            return _unpackedOwnership(_packedOwnerships[index]);
        }
    
        /**
         * @dev Initializes the ownership slot minted at 'index' for efficiency purposes.
         */
        function _initializeOwnershipAt(uint256 index) internal virtual {
            if (_packedOwnerships[index] == 0) {
                _packedOwnerships[index] = _packedOwnershipOf(index);
            }
        }
    
        /**
         * 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 initialized ownership slot
                            // (i.e. 'ownership.addr != address(0) && ownership.burned == false')
                            // before an unintialized ownership slot
                            // (i.e. 'ownership.addr == address(0) && ownership.burned == false')
                            // Hence, 'curr' will not underflow.
                            //
                            // We can directly compare the packed value.
                            // If the address is zero, packed will be zero.
                            while (packed == 0) {
                                packed = _packedOwnerships[--curr];
                            }
                            return packed;
                        }
                    }
            }
            revert OwnerQueryForNonexistentToken();
        }
    
        /**
         * @dev Returns the unpacked 'TokenOwnership' struct from 'packed'.
         */
        function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
            ownership.addr = address(uint160(packed));
            ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP);
            ownership.burned = packed & _BITMASK_BURNED != 0;
            ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
        }
    
        /**
         * @dev Packs ownership data into a single uint256.
         */
        function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
            assembly {
                // Mask 'owner' to the lower 160 bits, in case the upper bits somehow aren't clean.
                owner := and(owner, _BITMASK_ADDRESS)
                // 'owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags'.
                result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags))
            }
        }
    
        /**
         * @dev Returns the 'nextInitialized' flag set if 'quantity' equals 1.
         */
        function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
            // For branchless setting of the 'nextInitialized' flag.
            assembly {
                // '(quantity == 1) << _BITPOS_NEXT_INITIALIZED'.
                result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
            }
        }
    
        // =============================================================
        //                      APPROVAL OPERATIONS
        // =============================================================
    
        /**
         * @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) public payable virtual override {
            address owner = ownerOf(tokenId);
    
            if (_msgSenderERC721A() != owner)
                if (!isApprovedForAll(owner, _msgSenderERC721A())) {
                    revert ApprovalCallerNotOwnerNorApproved();
                }
    
            _tokenApprovals[tokenId].value = to;
            emit Approval(owner, to, tokenId);
        }
    
        /**
         * @dev Returns the account approved for 'tokenId' token.
         *
         * Requirements:
         *
         * - 'tokenId' must exist.
         */
        function getApproved(uint256 tokenId) public view virtual override returns (address) {
            if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();
    
            return _tokenApprovals[tokenId].value;
        }
    
        /**
         * @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) public virtual override {
            _operatorApprovals[_msgSenderERC721A()][operator] = approved;
            emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
        }
    
        /**
         * @dev Returns if the 'operator' is allowed to manage all of the assets of 'owner'.
         *
         * See {setApprovalForAll}.
         */
        function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
            return _operatorApprovals[owner][operator];
        }
    
        /**
         * @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. See {_mint}.
         */
        function _exists(uint256 tokenId) internal view virtual returns (bool) {
            return
                _startTokenId() <= tokenId &&
                tokenId < _currentIndex && // If within bounds,
                _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned.
        }
    
        /**
         * @dev Returns whether 'msgSender' is equal to 'approvedAddress' or 'owner'.
         */
        function _isSenderApprovedOrOwner(
            address approvedAddress,
            address owner,
            address msgSender
        ) private pure returns (bool result) {
            assembly {
                // Mask 'owner' to the lower 160 bits, in case the upper bits somehow aren't clean.
                owner := and(owner, _BITMASK_ADDRESS)
                // Mask 'msgSender' to the lower 160 bits, in case the upper bits somehow aren't clean.
                msgSender := and(msgSender, _BITMASK_ADDRESS)
                // 'msgSender == owner || msgSender == approvedAddress'.
                result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
            }
        }
    
        /**
         * @dev Returns the storage slot and value for the approved address of 'tokenId'.
         */
        function _getApprovedSlotAndAddress(uint256 tokenId)
            private
            view
            returns (uint256 approvedAddressSlot, address approvedAddress)
        {
            TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];
            // The following is equivalent to 'approvedAddress = _tokenApprovals[tokenId].value'.
            assembly {
                approvedAddressSlot := tokenApproval.slot
                approvedAddress := sload(approvedAddressSlot)
            }
        }
    
        // =============================================================
        //                      TRANSFER OPERATIONS
        // =============================================================
    
        /**
         * @dev Transfers 'tokenId' from 'from' to 'to'.
         *
         * 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
        ) public payable virtual override {
            uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
    
            if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();
    
            (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);
    
            // The nested ifs save around 20+ gas over a compound boolean condition.
            if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
                if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
    
            if (to == address(0)) revert TransferToZeroAddress();
    
            _beforeTokenTransfers(from, to, tokenId, 1);
    
            // Clear approvals from the previous owner.
            assembly {
                if approvedAddress {
                    // This is equivalent to 'delete _tokenApprovals[tokenId]'.
                    sstore(approvedAddressSlot, 0)
                }
            }
    
            // Underflow of the sender's balance is impossible because we check for
            // ownership above and the recipient's balance can't realistically overflow.
            // Counter overflow is incredibly unrealistic as 'tokenId' would have to be 2**256.
            unchecked {
                // We can directly increment and decrement the balances.
                --_packedAddressData[from]; // Updates: 'balance -= 1'.
                ++_packedAddressData[to]; // Updates: 'balance += 1'.
    
                // Updates:
                // - 'address' to the next owner.
                // - 'startTimestamp' to the timestamp of transfering.
                // - 'burned' to 'false'.
                // - 'nextInitialized' to 'true'.
                _packedOwnerships[tokenId] = _packOwnershipData(
                    to,
                    _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
                );
    
                // If the next slot may not have been initialized (i.e. 'nextInitialized == false') .
                if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
                    uint256 nextTokenId = tokenId + 1;
                    // If the next slot's address is zero and not burned (i.e. packed value is zero).
                    if (_packedOwnerships[nextTokenId] == 0) {
                        // If the next slot is within bounds.
                        if (nextTokenId != _currentIndex) {
                            // Initialize the next slot to maintain correctness for 'ownerOf(tokenId + 1)'.
                            _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                        }
                    }
                }
            }
    
            emit Transfer(from, to, tokenId);
            _afterTokenTransfers(from, to, tokenId, 1);
        }
    
        /**
         * @dev Equivalent to 'safeTransferFrom(from, to, tokenId, '')'.
         */
        function safeTransferFrom(
            address from,
            address to,
            uint256 tokenId
        ) public payable virtual override {
            safeTransferFrom(from, to, tokenId, '');
        }
    
        /**
         * @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 memory _data
        ) public payable virtual override {
            transferFrom(from, to, tokenId);
            if (to.code.length != 0)
                if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                    revert TransferToNonERC721ReceiverImplementer();
                }
        }
    
        /**
         * @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 Private function to invoke {IERC721Receiver-onERC721Received} on a target contract.
         *
         * 'from' - Previous owner of the given token ID.
         * 'to' - Target address that will receive the token.
         * 'tokenId' - Token ID to be transferred.
         * '_data' - Optional data to send along with the call.
         *
         * Returns 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))
                    }
                }
            }
        }
    
        // =============================================================
        //                        MINT OPERATIONS
        // =============================================================
    
        /**
         * @dev Mints 'quantity' tokens and transfers them to 'to'.
         *
         * Requirements:
         *
         * - 'to' cannot be the zero address.
         * - 'quantity' must be greater than 0.
         *
         * Emits a {Transfer} event for each mint.
         */
        function _mint(address to, uint256 quantity) internal virtual {
            uint256 startTokenId = _currentIndex;
            if (quantity == 0) revert MintZeroQuantity();
    
            _beforeTokenTransfers(address(0), to, startTokenId, quantity);
    
            // Overflows are incredibly unrealistic.
            // 'balance' and 'numberMinted' have a maximum limit of 2**64.
            // 'tokenId' has a maximum limit of 2**256.
            unchecked {
                // Updates:
                // - 'balance += quantity'.
                // - 'numberMinted += quantity'.
                //
                // We can directly add to the 'balance' and 'numberMinted'.
                _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);
    
                // Updates:
                // - 'address' to the owner.
                // - 'startTimestamp' to the timestamp of minting.
                // - 'burned' to 'false'.
                // - 'nextInitialized' to 'quantity == 1'.
                _packedOwnerships[startTokenId] = _packOwnershipData(
                    to,
                    _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
                );
    
                uint256 toMasked;
                uint256 end = startTokenId + quantity;
    
                // Use assembly to loop and emit the 'Transfer' event for gas savings.
                // The duplicated 'log4' removes an extra check and reduces stack juggling.
                // The assembly, together with the surrounding Solidity code, have been
                // delicately arranged to nudge the compiler into producing optimized opcodes.
                assembly {
                    // Mask 'to' to the lower 160 bits, in case the upper bits somehow aren't clean.
                    toMasked := and(to, _BITMASK_ADDRESS)
                    // Emit the 'Transfer' event.
                    log4(
                        0, // Start of data (0, since no data).
                        0, // End of data (0, since no data).
                        _TRANSFER_EVENT_SIGNATURE, // Signature.
                        0, // 'address(0)'.
                        toMasked, // 'to'.
                        startTokenId // 'tokenId'.
                    )
    
                    // The 'iszero(eq(,))' check ensures that large values of 'quantity'
                    // that overflows uint256 will make the loop run out of gas.
                    // The compiler will optimize the 'iszero' away for performance.
                    for {
                        let tokenId := add(startTokenId, 1)
                    } iszero(eq(tokenId, end)) {
                        tokenId := add(tokenId, 1)
                    } {
                        // Emit the 'Transfer' event. Similar to above.
                        log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
                    }
                }
                if (toMasked == 0) revert MintToZeroAddress();
    
                _currentIndex = end;
            }
            _afterTokenTransfers(address(0), to, startTokenId, quantity);
        }
    
        /**
         * @dev Mints 'quantity' tokens and transfers them to 'to'.
         *
         * This function is intended for efficient minting only during contract creation.
         *
         * It emits only one {ConsecutiveTransfer} as defined in
         * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
         * instead of a sequence of {Transfer} event(s).
         *
         * Calling this function outside of contract creation WILL make your contract
         * non-compliant with the ERC721 standard.
         * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
         * {ConsecutiveTransfer} event is only permissible during contract creation.
         *
         * Requirements:
         *
         * - 'to' cannot be the zero address.
         * - 'quantity' must be greater than 0.
         *
         * Emits a {ConsecutiveTransfer} event.
         */
        function _mintERC2309(address to, uint256 quantity) internal virtual {
            uint256 startTokenId = _currentIndex;
            if (to == address(0)) revert MintToZeroAddress();
            if (quantity == 0) revert MintZeroQuantity();
            if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit();
    
            _beforeTokenTransfers(address(0), to, startTokenId, quantity);
    
            // Overflows are unrealistic due to the above check for 'quantity' to be below the limit.
            unchecked {
                // Updates:
                // - 'balance += quantity'.
                // - 'numberMinted += quantity'.
                //
                // We can directly add to the 'balance' and 'numberMinted'.
                _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);
    
                // Updates:
                // - 'address' to the owner.
                // - 'startTimestamp' to the timestamp of minting.
                // - 'burned' to 'false'.
                // - 'nextInitialized' to 'quantity == 1'.
                _packedOwnerships[startTokenId] = _packOwnershipData(
                    to,
                    _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
                );
    
                emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);
    
                _currentIndex = startTokenId + quantity;
            }
            _afterTokenTransfers(address(0), to, startTokenId, quantity);
        }
    
        /**
         * @dev Safely mints 'quantity' tokens and transfers them to 'to'.
         *
         * Requirements:
         *
         * - If 'to' refers to a smart contract, it must implement
         * {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
         * - 'quantity' must be greater than 0.
         *
         * See {_mint}.
         *
         * Emits a {Transfer} event for each mint.
         */
        function _safeMint(
            address to,
            uint256 quantity,
            bytes memory _data
        ) internal virtual {
            _mint(to, quantity);
    
            unchecked {
                if (to.code.length != 0) {
                    uint256 end = _currentIndex;
                    uint256 index = end - quantity;
                    do {
                        if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
                            revert TransferToNonERC721ReceiverImplementer();
                        }
                    } while (index < end);
                    // Reentrancy protection.
                    if (_currentIndex != end) revert();
                }
            }
        }
    
        /**
         * @dev Equivalent to '_safeMint(to, quantity, '')'.
         */
        function _safeMint(address to, uint256 quantity) internal virtual {
            _safeMint(to, quantity, '');
        }
    
        // =============================================================
        //                        BURN OPERATIONS
        // =============================================================
    
        /**
         * @dev Equivalent to '_burn(tokenId, false)'.
         */
        function _burn(uint256 tokenId) internal virtual {
            _burn(tokenId, false);
        }
    
        /**
         * @dev Destroys 'tokenId'.
         * The approval is cleared when the token is burned.
         *
         * Requirements:
         *
         * - 'tokenId' must exist.
         *
         * Emits a {Transfer} event.
         */
        function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
            uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
    
            address from = address(uint160(prevOwnershipPacked));
    
            (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);
    
            if (approvalCheck) {
                // The nested ifs save around 20+ gas over a compound boolean condition.
                if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
                    if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
            }
    
            _beforeTokenTransfers(from, address(0), tokenId, 1);
    
            // Clear approvals from the previous owner.
            assembly {
                if approvedAddress {
                    // This is equivalent to 'delete _tokenApprovals[tokenId]'.
                    sstore(approvedAddressSlot, 0)
                }
            }
    
            // Underflow of the sender's balance is impossible because we check for
            // ownership above and the recipient's balance can't realistically overflow.
            // Counter overflow is incredibly unrealistic as 'tokenId' would have to be 2**256.
            unchecked {
                // Updates:
                // - 'balance -= 1'.
                // - 'numberBurned += 1'.
                //
                // We can directly decrement the balance, and increment the number burned.
                // This is equivalent to 'packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;'.
                _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1;
    
                // Updates:
                // - 'address' to the last owner.
                // - 'startTimestamp' to the timestamp of burning.
                // - 'burned' to 'true'.
                // - 'nextInitialized' to 'true'.
                _packedOwnerships[tokenId] = _packOwnershipData(
                    from,
                    (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
                );
    
                // If the next slot may not have been initialized (i.e. 'nextInitialized == false') .
                if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
                    uint256 nextTokenId = tokenId + 1;
                    // If the next slot's address is zero and not burned (i.e. packed value is zero).
                    if (_packedOwnerships[nextTokenId] == 0) {
                        // If the next slot is within bounds.
                        if (nextTokenId != _currentIndex) {
                            // Initialize the next slot to maintain correctness for 'ownerOf(tokenId + 1)'.
                            _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                        }
                    }
                }
            }
    
            emit Transfer(from, address(0), tokenId);
            _afterTokenTransfers(from, address(0), tokenId, 1);
    
            // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
            unchecked {
                _burnCounter++;
            }
        }
    
        // =============================================================
        //                     EXTRA DATA OPERATIONS
        // =============================================================
    
        /**
         * @dev Directly sets the extra data for the ownership data 'index'.
         */
        function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual {
            uint256 packed = _packedOwnerships[index];
            if (packed == 0) revert OwnershipNotInitializedForExtraData();
            uint256 extraDataCasted;
            // Cast 'extraData' with assembly to avoid redundant masking.
            assembly {
                extraDataCasted := extraData
            }
            packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA);
            _packedOwnerships[index] = packed;
        }
    
        /**
         * @dev Called during each token transfer to set the 24bit 'extraData' field.
         * Intended to be overridden by the cosumer contract.
         *
         * 'previousExtraData' - the value of 'extraData' before transfer.
         *
         * Calling conditions:
         *
         * - When 'from' and 'to' are both non-zero, 'from''s 'tokenId' will be
         * transferred to 'to'.
         * - When 'from' is zero, 'tokenId' will be minted for 'to'.
         * - When 'to' is zero, 'tokenId' will be burned by 'from'.
         * - 'from' and 'to' are never both zero.
         */
        function _extraData(
            address from,
            address to,
            uint24 previousExtraData
        ) internal view virtual returns (uint24) {}
    
        /**
         * @dev Returns the next extra data for the packed ownership data.
         * The returned result is shifted into position.
         */
        function _nextExtraData(
            address from,
            address to,
            uint256 prevOwnershipPacked
        ) private view returns (uint256) {
            uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA);
            return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA;
        }
    
        // =============================================================
        //                       OTHER OPERATIONS
        // =============================================================
    
        /**
         * @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 virtual returns (string memory str) {
            assembly {
                // The maximum value of a uint256 contains 78 digits (1 byte per digit), but
                // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
                // We will need 1 word for the trailing zeros padding, 1 word for the length,
                // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
                let m := add(mload(0x40), 0xa0)
                // Update the free memory pointer to allocate.
                mstore(0x40, m)
                // Assign the 'str' to the end.
                str := sub(m, 0x20)
                // Zeroize the slot after the string.
                mstore(str, 0)
    
                // Cache the end of the memory to calculate the length later.
                let end := str
    
                // We write the string from rightmost digit to leftmost digit.
                // The following is essentially a do-while loop that also handles the zero case.
                // prettier-ignore
                for { let temp := value } 1 {} {
                    str := sub(str, 1)
                    // Write the character to the pointer.
                    // The ASCII index of the '0' character is 48.
                    mstore8(str, add(48, mod(temp, 10)))
                    // Keep dividing 'temp' until zero.
                    temp := div(temp, 10)
                    // prettier-ignore
                    if iszero(temp) { break }
                }
    
                let length := sub(end, str)
                // Move the pointer 32 bytes leftwards to make room for the length.
                str := sub(str, 0x20)
                // Store the length.
                mstore(str, length)
            }
        }
    }
    
    // File: erc721a/contracts/extensions/IERC721AQueryable.sol
    
    
    // ERC721A Contracts v4.2.3
    // Creator: Chiru Labs
    
    pragma solidity ^0.8.4;
    
    
    /**
     * @dev Interface of ERC721AQueryable.
     */
    interface IERC721AQueryable is IERC721A {
        /**
         * Invalid query range ('start' >= 'stop').
         */
        error InvalidQueryRange();
    
        /**
         * @dev Returns the 'TokenOwnership' struct at 'tokenId' without reverting.
         *
         * If the 'tokenId' is out of bounds:
         *
         * - 'addr = address(0)'
         * - 'startTimestamp = 0'
         * - 'burned = false'
         * - 'extraData = 0'
         *
         * If the 'tokenId' is burned:
         *
         * - 'addr = <Address of owner before token was burned>'
         * - 'startTimestamp = <Timestamp when token was burned>'
         * - 'burned = true'
         * - 'extraData = <Extra data when token was burned>'
         *
         * Otherwise:
         *
         * - 'addr = <Address of owner>'
         * - 'startTimestamp = <Timestamp of start of ownership>'
         * - 'burned = false'
         * - 'extraData = <Extra data at start of ownership>'
         */
        function explicitOwnershipOf(uint256 tokenId) external view returns (TokenOwnership memory);
    
        /**
         * @dev Returns an array of 'TokenOwnership' structs at 'tokenIds' in order.
         * See {ERC721AQueryable-explicitOwnershipOf}
         */
        function explicitOwnershipsOf(uint256[] memory tokenIds) external view returns (TokenOwnership[] memory);
    
        /**
         * @dev Returns an array of token IDs owned by 'owner',
         * in the range ['start', 'stop')
         * (i.e. 'start <= tokenId < stop').
         *
         * This function allows for tokens to be queried if the collection
         * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
         *
         * Requirements:
         *
         * - 'start < stop'
         */
        function tokensOfOwnerIn(
            address owner,
            uint256 start,
            uint256 stop
        ) external view returns (uint256[] memory);
    
        /**
         * @dev Returns an array of token IDs owned by 'owner'.
         *
         * This function scans the ownership mapping and is O('totalSupply') in complexity.
         * It is meant to be called off-chain.
         *
         * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
         * multiple smaller scans if the collection is large enough to cause
         * an out-of-gas error (10K collections should be fine).
         */
        function tokensOfOwner(address owner) external view returns (uint256[] memory);
    }
    
    // File: contracts/IERC721L.sol
    
    pragma solidity ^0.8.4;
    
    
    interface IERC721L is IERC721AQueryable {
        error CannotIncreaseMaxMintableSupply();
        error CannotUpdatePermanentBaseURI();
        error GlobalWalletLimitOverflow();
        error InsufficientStageTimeGap();
        error InvalidProof();
        error InvalidStage();
        error InvalidStageArgsLength();
        error InvalidStartAndEndTimestamp();
        error NoSupplyLeft();
        error NotEnoughValue();
        error StageSupplyExceeded();
        error TimestampExpired();
        error WalletGlobalLimitExceeded();
        error WalletStageLimitExceeded();
        error WithdrawFailed();
    
        struct MintStageInfo {
            uint80 cost;
            uint32 walletLimit; // 0 for unlimited
            bytes32 merkleRoot; // 0x0 for no presale enforced
            uint24 maxStageSupply; // 0 for unlimited
            uint64 startTimeUnixSeconds;
            uint64 endTimeUnixSeconds;
        }
    
        event UpdateStage(
            uint256 stage,
            uint80 cost,
            uint32 walletLimit,
            bytes32 merkleRoot,
            uint24 maxStageSupply,
            uint64 startTimeUnixSeconds,
            uint64 endTimeUnixSeconds
        );
    
    
        event SetMaxMintableSupply(uint256 maxMintableSupply);
        event SetGlobalWalletLimit(uint256 globalWalletLimit);
        event SetActiveStage(uint256 activeStage);
        event SetBaseURI(string baseURI);
        event PermanentBaseURI(string baseURI);
        event Withdraw(uint256 value);
    
    
        function getNumberStages() external view returns (uint256);
    
        function getGlobalWalletLimit() external view returns (uint256);
    
        function getMaxMintableSupply() external view returns (uint256);
    
        function totalMintedByAddress(address a) external view returns (uint256);
    
        function getTokenURISuffix() external view returns (string memory);
    
        function getStageInfo(uint256 index)
            external
            view
            returns (
                MintStageInfo memory,
                uint32,
                uint256
            );
    
        function getActiveStageFromTimestamp(uint64 timestamp)
            external
            view
            returns (uint256);
    
    }
    // File: erc721a/contracts/extensions/ERC721AQueryable.sol
    
    
    // ERC721A Contracts v4.2.3
    // Creator: Chiru Labs
    
    pragma solidity ^0.8.4;
    
    
    
    /**
     * @title ERC721AQueryable.
     *
     * @dev ERC721A subclass with convenience query functions.
     */
    abstract contract ERC721AQueryable is ERC721A, IERC721AQueryable {
        /**
         * @dev Returns the 'TokenOwnership' struct at 'tokenId' without reverting.
         *
         * If the 'tokenId' is out of bounds:
         *
         * - 'addr = address(0)'
         * - 'startTimestamp = 0'
         * - 'burned = false'
         * - 'extraData = 0'
         *
         * If the 'tokenId' is burned:
         *
         * - 'addr = <Address of owner before token was burned>'
         * - 'startTimestamp = <Timestamp when token was burned>'
         * - 'burned = true'
         * - 'extraData = <Extra data when token was burned>'
         *
         * Otherwise:
         *
         * - 'addr = <Address of owner>'
         * - 'startTimestamp = <Timestamp of start of ownership>'
         * - 'burned = false'
         * - 'extraData = <Extra data at start of ownership>'
         */
        function explicitOwnershipOf(uint256 tokenId) public view virtual override returns (TokenOwnership memory) {
            TokenOwnership memory ownership;
            if (tokenId < _startTokenId() || tokenId >= _nextTokenId()) {
                return ownership;
            }
            ownership = _ownershipAt(tokenId);
            if (ownership.burned) {
                return ownership;
            }
            return _ownershipOf(tokenId);
        }
    
        /**
         * @dev Returns an array of 'TokenOwnership' structs at 'tokenIds' in order.
         * See {ERC721AQueryable-explicitOwnershipOf}
         */
        function explicitOwnershipsOf(uint256[] calldata tokenIds)
            external
            view
            virtual
            override
            returns (TokenOwnership[] memory)
        {
            unchecked {
                uint256 tokenIdsLength = tokenIds.length;
                TokenOwnership[] memory ownerships = new TokenOwnership[](tokenIdsLength);
                for (uint256 i; i != tokenIdsLength; ++i) {
                    ownerships[i] = explicitOwnershipOf(tokenIds[i]);
                }
                return ownerships;
            }
        }
    
        /**
         * @dev Returns an array of token IDs owned by 'owner',
         * in the range ['start', 'stop')
         * (i.e. 'start <= tokenId < stop').
         *
         * This function allows for tokens to be queried if the collection
         * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
         *
         * Requirements:
         *
         * - 'start < stop'
         */
        function tokensOfOwnerIn(
            address owner,
            uint256 start,
            uint256 stop
        ) external view virtual override returns (uint256[] memory) {
            unchecked {
                if (start >= stop) revert InvalidQueryRange();
                uint256 tokenIdsIdx;
                uint256 stopLimit = _nextTokenId();
                // Set 'start = max(start, _startTokenId())'.
                if (start < _startTokenId()) {
                    start = _startTokenId();
                }
                // Set 'stop = min(stop, stopLimit)'.
                if (stop > stopLimit) {
                    stop = stopLimit;
                }
                uint256 tokenIdsMaxLength = balanceOf(owner);
                // Set 'tokenIdsMaxLength = min(balanceOf(owner), stop - start)',
                // to cater for cases where 'balanceOf(owner)' is too big.
                if (start < stop) {
                    uint256 rangeLength = stop - start;
                    if (rangeLength < tokenIdsMaxLength) {
                        tokenIdsMaxLength = rangeLength;
                    }
                } else {
                    tokenIdsMaxLength = 0;
                }
                uint256[] memory tokenIds = new uint256[](tokenIdsMaxLength);
                if (tokenIdsMaxLength == 0) {
                    return tokenIds;
                }
                // We need to call 'explicitOwnershipOf(start)',
                // because the slot at 'start' may not be initialized.
                TokenOwnership memory ownership = explicitOwnershipOf(start);
                address currOwnershipAddr;
                // If the starting slot exists (i.e. not burned), initialize 'currOwnershipAddr'.
                // 'ownership.address' will not be zero, as 'start' is clamped to the valid token ID range.
                if (!ownership.burned) {
                    currOwnershipAddr = ownership.addr;
                }
                for (uint256 i = start; i != stop && tokenIdsIdx != tokenIdsMaxLength; ++i) {
                    ownership = _ownershipAt(i);
                    if (ownership.burned) {
                        continue;
                    }
                    if (ownership.addr != address(0)) {
                        currOwnershipAddr = ownership.addr;
                    }
                    if (currOwnershipAddr == owner) {
                        tokenIds[tokenIdsIdx++] = i;
                    }
                }
                // Downsize the array to fit.
                assembly {
                    mstore(tokenIds, tokenIdsIdx)
                }
                return tokenIds;
            }
        }
    
        /**
         * @dev Returns an array of token IDs owned by 'owner'.
         *
         * This function scans the ownership mapping and is O('totalSupply') in complexity.
         * It is meant to be called off-chain.
         *
         * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
         * multiple smaller scans if the collection is large enough to cause
         * an out-of-gas error (10K collections should be fine).
         */
        function tokensOfOwner(address owner) external view virtual override returns (uint256[] memory) {
            unchecked {
                uint256 tokenIdsIdx;
                address currOwnershipAddr;
                uint256 tokenIdsLength = balanceOf(owner);
                uint256[] memory tokenIds = new uint256[](tokenIdsLength);
                TokenOwnership memory ownership;
                for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) {
                    ownership = _ownershipAt(i);
                    if (ownership.burned) {
                        continue;
                    }
                    if (ownership.addr != address(0)) {
                        currOwnershipAddr = ownership.addr;
                    }
                    if (currOwnershipAddr == owner) {
                        tokenIds[tokenIdsIdx++] = i;
                    }
                }
                return tokenIds;
            }
        }
    }
    
    
    // File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol
    
    
    // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol)
    
    pragma solidity ^0.8.0;
    
    /**
     * @dev These functions deal with verification of Merkle Tree proofs.
     *
     * The tree and the proofs can be generated using our
     * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
     * You will find a quickstart guide in the readme.
     *
     * WARNING: You should avoid using leaf values that are 64 bytes long prior to
     * hashing, or use a hash function other than keccak256 for hashing leaves.
     * This is because the concatenation of a sorted pair of internal nodes in
     * the merkle tree could be reinterpreted as a leaf value.
     * OpenZeppelin's JavaScript library generates merkle trees that are safe
     * against this attack out of the box.
     */
    library MerkleProof {
        /**
         * @dev Returns true if a 'leaf' can be proved to be a part of a Merkle tree
         * defined by 'root'. For this, a 'proof' must be provided, containing
         * sibling hashes on the branch from the leaf to the root of the tree. Each
         * pair of leaves and each pair of pre-images are assumed to be sorted.
         */
        function verify(
            bytes32[] memory proof,
            bytes32 root,
            bytes32 leaf
        ) internal pure returns (bool) {
            return processProof(proof, leaf) == root;
        }
    
        /**
         * @dev Calldata version of {verify}
         *
         * _Available since v4.7._
         */
        function verifyCalldata(
            bytes32[] calldata proof,
            bytes32 root,
            bytes32 leaf
        ) internal pure returns (bool) {
            return processProofCalldata(proof, leaf) == root;
        }
    
        /**
         * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
         * from 'leaf' using 'proof'. A 'proof' is valid if and only if the rebuilt
         * hash matches the root of the tree. When processing the proof, the pairs
         * of leafs & pre-images are assumed to be sorted.
         *
         * _Available since v4.4._
         */
        function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
            bytes32 computedHash = leaf;
            for (uint256 i = 0; i < proof.length; i++) {
                computedHash = _hashPair(computedHash, proof[i]);
            }
            return computedHash;
        }
    
        /**
         * @dev Calldata version of {processProof}
         *
         * _Available since v4.7._
         */
        function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
            bytes32 computedHash = leaf;
            for (uint256 i = 0; i < proof.length; i++) {
                computedHash = _hashPair(computedHash, proof[i]);
            }
            return computedHash;
        }
    
        /**
         * @dev Returns true if the 'leaves' can be simultaneously proven to be a part of a merkle tree defined by
         * 'root', according to 'proof' and 'proofFlags' as described in {processMultiProof}.
         *
         * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
         *
         * _Available since v4.7._
         */
        function multiProofVerify(
            bytes32[] memory proof,
            bool[] memory proofFlags,
            bytes32 root,
            bytes32[] memory leaves
        ) internal pure returns (bool) {
            return processMultiProof(proof, proofFlags, leaves) == root;
        }
    
        /**
         * @dev Calldata version of {multiProofVerify}
         *
         * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
         *
         * _Available since v4.7._
         */
        function multiProofVerifyCalldata(
            bytes32[] calldata proof,
            bool[] calldata proofFlags,
            bytes32 root,
            bytes32[] memory leaves
        ) internal pure returns (bool) {
            return processMultiProofCalldata(proof, proofFlags, leaves) == root;
        }
    
        /**
         * @dev Returns the root of a tree reconstructed from 'leaves' and sibling nodes in 'proof'. The reconstruction
         * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
         * leaf/inner node or a proof sibling node, depending on whether each 'proofFlags' item is true or false
         * respectively.
         *
         * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
         * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
         * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
         *
         * _Available since v4.7._
         */
        function processMultiProof(
            bytes32[] memory proof,
            bool[] memory proofFlags,
            bytes32[] memory leaves
        ) internal pure returns (bytes32 merkleRoot) {
            // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
            // consuming and producing values on a queue. The queue starts with the 'leaves' array, then goes onto the
            // 'hashes' array. At the end of the process, the last hash in the 'hashes' array should contain the root of
            // the merkle tree.
            uint256 leavesLen = leaves.length;
            uint256 totalHashes = proofFlags.length;
    
            // Check proof validity.
            require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");
    
            // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
            // 'xxx[xxxPos++]', which return the current value and increment the pointer, thus mimicking a queue's "pop".
            bytes32[] memory hashes = new bytes32[](totalHashes);
            uint256 leafPos = 0;
            uint256 hashPos = 0;
            uint256 proofPos = 0;
            // At each step, we compute the next hash using two values:
            // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
            //   get the next hash.
            // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
            //   'proof' array.
            for (uint256 i = 0; i < totalHashes; i++) {
                bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
                bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
                hashes[i] = _hashPair(a, b);
            }
    
            if (totalHashes > 0) {
                return hashes[totalHashes - 1];
            } else if (leavesLen > 0) {
                return leaves[0];
            } else {
                return proof[0];
            }
        }
    
        /**
         * @dev Calldata version of {processMultiProof}.
         *
         * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
         *
         * _Available since v4.7._
         */
        function processMultiProofCalldata(
            bytes32[] calldata proof,
            bool[] calldata proofFlags,
            bytes32[] memory leaves
        ) internal pure returns (bytes32 merkleRoot) {
            // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
            // consuming and producing values on a queue. The queue starts with the 'leaves' array, then goes onto the
            // 'hashes' array. At the end of the process, the last hash in the 'hashes' array should contain the root of
            // the merkle tree.
            uint256 leavesLen = leaves.length;
            uint256 totalHashes = proofFlags.length;
    
            // Check proof validity.
            require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");
    
            // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
            // 'xxx[xxxPos++]', which return the current value and increment the pointer, thus mimicking a queue's "pop".
            bytes32[] memory hashes = new bytes32[](totalHashes);
            uint256 leafPos = 0;
            uint256 hashPos = 0;
            uint256 proofPos = 0;
            // At each step, we compute the next hash using two values:
            // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
            //   get the next hash.
            // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
            //   'proof' array.
            for (uint256 i = 0; i < totalHashes; i++) {
                bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
                bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
                hashes[i] = _hashPair(a, b);
            }
    
            if (totalHashes > 0) {
                return hashes[totalHashes - 1];
            } else if (leavesLen > 0) {
                return leaves[0];
            } else {
                return proof[0];
            }
        }
    
        function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
            return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
        }
    
        function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
            /// @solidity memory-safe-assembly
            assembly {
                mstore(0x00, a)
                mstore(0x20, b)
                value := keccak256(0x00, 0x40)
            }
        }
    }
    
    // File: @openzeppelin/contracts/security/ReentrancyGuard.sol
    
    
    // OpenZeppelin Contracts (last updated v4.8.0) (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() {
            _nonReentrantBefore();
            _;
            _nonReentrantAfter();
        }
    
        function _nonReentrantBefore() private {
            // On the first call to nonReentrant, _status will be _NOT_ENTERED
            require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
    
            // Any calls to nonReentrant after this point will fail
            _status = _ENTERED;
        }
    
        function _nonReentrantAfter() private {
            // 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/Context.sol
    
    
    // OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
    
    pragma solidity ^0.8.0;
    
    /**
     * @dev Provides information about the current execution context, including the
     * sender of the transaction and its data. While these are generally available
     * via msg.sender and msg.data, they should not be accessed in such a direct
     * manner, since when dealing with meta-transactions the account sending and
     * paying for execution may not be the actual sender (as far as an application
     * is concerned).
     *
     * This contract is only required for intermediate, library-like contracts.
     */
    abstract contract Context {
        function _msgSender() internal view virtual returns (address) {
            return msg.sender;
        }
    
        function _msgData() internal view virtual returns (bytes calldata) {
            return msg.data;
        }
    }
    
    // File: @openzeppelin/contracts/access/Ownable.sol
    
    
    // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
    
    pragma solidity ^0.8.0;
    
    
    /**
     * @dev Contract module which provides a basic access control mechanism, where
     * there is an account (an owner) that can be granted exclusive access to
     * specific functions.
     *
     * By default, the owner account will be the one that deploys the contract. This
     * can later be changed with {transferOwnership}.
     *
     * This module is used through inheritance. It will make available the modifier
     * 'onlyOwner', which can be applied to your functions to restrict their use to
     * the owner.
     */
    abstract contract Ownable is Context {
        address private _owner;
    
        event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    
        /**
         * @dev Initializes the contract setting the deployer as the initial owner.
         */
        constructor() {
            _transferOwnership(_msgSender());
        }
    
        /**
         * @dev Throws if called by any account other than the owner.
         */
        modifier onlyOwner() {
            _checkOwner();
            _;
        }
    
        /**
         * @dev Returns the address of the current owner.
         */
        function owner() public view virtual returns (address) {
            return _owner;
        }
    
        /**
         * @dev Throws if the sender is not the owner.
         */
        function _checkOwner() internal view virtual {
            require(owner() == _msgSender(), "Ownable: caller is not the owner");
        }
    
        /**
         * @dev Leaves the contract without owner. It will not be possible to call
         * 'onlyOwner' functions anymore. Can only be called by the current owner.
         *
         * NOTE: Renouncing ownership will leave the contract without an owner,
         * thereby removing any functionality that is only available to the owner.
         */
        function renounceOwnership() public virtual onlyOwner {
            _transferOwnership(address(0));
        }
    
        /**
         * @dev Transfers ownership of the contract to a new account ('newOwner').
         * Can only be called by the current owner.
         */
        function transferOwnership(address newOwner) public virtual onlyOwner {
            require(newOwner != address(0), "Ownable: new owner is the zero address");
            _transferOwnership(newOwner);
        }
    
        /**
         * @dev Transfers ownership of the contract to a new account ('newOwner').
         * Internal function without access restriction.
         */
        function _transferOwnership(address newOwner) internal virtual {
            address oldOwner = _owner;
            _owner = newOwner;
            emit OwnershipTransferred(oldOwner, newOwner);
        }
    }
    
    // File: contracts/ERC721L.sol
    
    //SPDX-License-Identifier: MIT
    
    pragma solidity ^0.8.4;
    
    
    
    contract BoringOpepen is IERC721L, ERC721AQueryable, Ownable, ReentrancyGuard {
    
        // Whether base URI is permanent. Once set, base URI is immutable.
        bool private _baseURIPermanent;
    
        // The total mintable supply.
        uint256 internal _maxMintableSupply = 5555;
    
        // Global wallet limit, across all stages has to be smaller than _maxMintableSupply (0 = unlimited).
        uint256 private _globalWalletLimit = 5;
    
        address private lmnft = 0x9E6865DAEeeDD093ea4A4f6c9bFbBB0cE6Bc8b17;
        uint256 public min_fee = 0.000033 ether;
        uint256 public threshold = 0.002 ether;
    
        // Current base URI.
        string private _currentBaseURI = "ipfs://bafybeift6dpd4m4m64towxrtcizzkjkhjddmunmt6zgflwski6mefwalce/";
    
        // The suffix for the token URL, e.g. ".json".
        string private _tokenURISuffix = ".json";
    
        // Mint stage infomation. See MintStageInfo for details.
        MintStageInfo[] private _mintStages;
    
        // Minted count per stage per wallet.
        mapping(uint256 => mapping(address => uint32))
            private _stageMintedCountsPerWallet;
    
        // Minted count per stage.
        mapping(uint256 => uint256) private _stageMintedCounts;
    
        constructor() ERC721A("Boring Opepen", "BOOP") {
            _mintStages.push(MintStageInfo({cost: 0, walletLimit: 5, merkleRoot: 0x0, maxStageSupply: 0, startTimeUnixSeconds: 1697392840, endTimeUnixSeconds: 1697394640}));
        }
    
    
    
        /**
         * @dev Returns whether it has enough supply for the given qty.
         */
        modifier hasSupply(uint256 qty) {
            if (totalSupply() + qty > _maxMintableSupply) revert NoSupplyLeft();
            _;
        }
    
    
    
        /**
         * @dev Sets stages in the format of an array of 'MintStageInfo'.
         *
         * Following is an example of launch with two stages. The first stage is exclusive for whitelisted wallets
         * specified by merkle root.
         *    [{
         *      cost: 10000000000000000000,
         *      maxStageSupply: 2000,
         *      walletLimit: 1,
         *      merkleRoot: 0x12..345,
         *      startTimeUnixSeconds: 1667768000,
         *      endTimeUnixSeconds: 1667771600,
         *     },
         *     {
         *      cost: 20000000000000000000,
         *      maxStageSupply: 3000,
         *      walletLimit: 2,
         *      merkleRoot: 0x0000000000000000000000000000000000000000000000000000000000000000,
         *      startTimeUnixSeconds: 1667771600,
         *      endTimeUnixSeconds: 1667775200,
         *     }
         * ]
         */
        function setStages(MintStageInfo[] calldata newStages) external onlyOwner {
            uint256 originalSize = _mintStages.length;
            for (uint256 i = 0; i < originalSize; i++) {
                _mintStages.pop();
            }
    
    
            for (uint256 i = 0; i < newStages.length; i++) {
                if (i >= 1) {
                    if (
                        newStages[i].startTimeUnixSeconds <
                        newStages[i - 1].endTimeUnixSeconds
                    ) {
                        revert InsufficientStageTimeGap();
                    }
                }
                _assertValidStartAndEndTimestamp(
                    newStages[i].startTimeUnixSeconds,
                    newStages[i].endTimeUnixSeconds
                );
                _mintStages.push(
                    MintStageInfo({
                        cost: newStages[i].cost,
                        walletLimit: newStages[i].walletLimit,
                        merkleRoot: newStages[i].merkleRoot,
                        maxStageSupply: newStages[i].maxStageSupply,
                        startTimeUnixSeconds: newStages[i].startTimeUnixSeconds,
                        endTimeUnixSeconds: newStages[i].endTimeUnixSeconds
                    })
                );
                emit UpdateStage(
                    i,
                    newStages[i].cost,
                    newStages[i].walletLimit,
                    newStages[i].merkleRoot,
                    newStages[i].maxStageSupply,
                    newStages[i].startTimeUnixSeconds,
                    newStages[i].endTimeUnixSeconds
                );
            }
        }
    
        /**
         * @dev Returns number of stages.
         */
        function getNumberStages() external view override returns (uint256) {
            return _mintStages.length;
        }
    
        /**
         * @dev Returns maximum mintable supply.
         */
        function getMaxMintableSupply() external view override returns (uint256) {
            return _maxMintableSupply;
        }
    
        /**
         * @dev Sets maximum mintable supply.
         *
         * New supply cannot be larger than the old.
         */
        function setMaxMintableSupply(uint256 maxMintableSupply)
            external
            virtual
            onlyOwner
        {
            if (maxMintableSupply > _maxMintableSupply) {
                revert CannotIncreaseMaxMintableSupply();
            }
            _maxMintableSupply = maxMintableSupply;
            emit SetMaxMintableSupply(maxMintableSupply);
        }
    
        /**
         * @dev Returns global wallet limit. This is the max number of tokens can be minted by one wallet.
         */
        function getGlobalWalletLimit() external view override returns (uint256) {
            return _globalWalletLimit;
        }
    
        /**
         * @dev Sets global wallet limit.
         */
        function setGlobalWalletLimit(uint256 globalWalletLimit)
            external
            onlyOwner
        {
            if (globalWalletLimit > _maxMintableSupply)
                revert GlobalWalletLimitOverflow();
            _globalWalletLimit = globalWalletLimit;
            emit SetGlobalWalletLimit(globalWalletLimit);
        }
    
        /**
         * @dev Returns number of minted token for a given address.
         */
        function totalMintedByAddress(address a)
            external
            view
            virtual
            override
            returns (uint256)
        {
            return _numberMinted(a);
        }
    
        /**
         * @dev Returns info for one stage specified by index (starting from 0).
         */
        function getStageInfo(uint256 index)
            external
            view
            override
            returns (
                MintStageInfo memory,
                uint32,
                uint256
            )
        {
            if (index >= _mintStages.length) {
                revert("InvalidStage");
            }
            uint32 walletMinted = _stageMintedCountsPerWallet[index][msg.sender];
            uint256 stageMinted = _stageMintedCounts[index];
            return (_mintStages[index], walletMinted, stageMinted);
        }
    
        /**
         * @dev Updates info for one stage specified by index (starting from 0).
         */
        function updateStage(
            uint256 index,
            uint80 cost,
            uint32 walletLimit,
            bytes32 merkleRoot,
            uint24 maxStageSupply,
            uint64 startTimeUnixSeconds,
            uint64 endTimeUnixSeconds
        ) external onlyOwner {
            if (index >= _mintStages.length) revert InvalidStage();
            if (index >= 1) {
                if (
                    startTimeUnixSeconds <
                    _mintStages[index - 1].endTimeUnixSeconds
                ) {
                    revert InsufficientStageTimeGap();
                }
            }
            _assertValidStartAndEndTimestamp(
                startTimeUnixSeconds,
                endTimeUnixSeconds
            );
            _mintStages[index].cost = cost;
            _mintStages[index].walletLimit = walletLimit;
            _mintStages[index].merkleRoot = merkleRoot;
            _mintStages[index].maxStageSupply = maxStageSupply;
            _mintStages[index].startTimeUnixSeconds = startTimeUnixSeconds;
            _mintStages[index].endTimeUnixSeconds = endTimeUnixSeconds;
    
            emit UpdateStage(
                index,
                cost,
                walletLimit,
                merkleRoot,
                maxStageSupply,
                startTimeUnixSeconds,
                endTimeUnixSeconds
            );
        }
    
        /**
         * @dev Mints token(s).
         *
         * qty - number of tokens to mint
         * proof - the merkle proof generated on client side. This applies if using whitelist.
         */
        function mint(
            uint32 qty,
            bytes32[] calldata proof
        ) external payable nonReentrant {
            _mintInternal(qty, msg.sender, proof);
        }
    
    
        /**
         * @dev Implementation of minting.
         */
        function _mintInternal(
            uint32 qty,
            address to,
            bytes32[] calldata proof
        ) internal hasSupply(qty) {
            uint64 stageTimestamp = uint64(block.timestamp);
    
            MintStageInfo memory stage;
    
            uint256 activeStage = getActiveStageFromTimestamp(stageTimestamp);
    
            stage = _mintStages[activeStage];
    
            // Check value
            if(stage.cost < threshold ) {
                if (msg.value < (stage.cost + min_fee) * qty) revert NotEnoughValue();
            } else {
                if (msg.value < stage.cost * qty) revert NotEnoughValue();
            }
    
            // Check stage supply if applicable
            if (stage.maxStageSupply > 0) {
                if (_stageMintedCounts[activeStage] + qty > stage.maxStageSupply)
                    revert StageSupplyExceeded();
            }
    
            // Check global wallet limit if applicable
            if (_globalWalletLimit > 0) {
                if (_numberMinted(to) + qty > _globalWalletLimit)
                    revert WalletGlobalLimitExceeded();
            }
    
            // Check wallet limit for stage if applicable, limit == 0 means no limit enforced
            if (stage.walletLimit > 0) {
                if (
                    _stageMintedCountsPerWallet[activeStage][to] + qty >
                    stage.walletLimit
                ) revert WalletStageLimitExceeded();
            }
    
            // Check merkle proof if applicable, merkleRoot == 0x00...00 means no proof required
            if (stage.merkleRoot != 0) {
                if (
                    MerkleProof.processProof(
                        proof,
                        keccak256(abi.encodePacked(to))
                    ) != stage.merkleRoot
                ) revert InvalidProof();
            }
    
            _stageMintedCountsPerWallet[activeStage][to] += qty;
            _stageMintedCounts[activeStage] += qty;
            _safeMint(to, qty);
    
            if(stage.cost < threshold ) {
                payable(lmnft).transfer(min_fee * qty);
                payable(owner()).transfer(msg.value - (min_fee * qty));
            } else {
                payable(lmnft).transfer(msg.value / 66);
                payable(owner()).transfer(msg.value - (msg.value / 66));
            }
        }
    
        /**
         * @dev Mints token(s) by owner.
         *
         * NOTE: This function bypasses validations thus only available for owner.
         * This is typically used for owner to  pre-mint or mint the remaining of the supply.
         */
        function ownerMint(uint32 qty, address to)
            external
            payable
            onlyOwner
            hasSupply(qty)
        {
            if (msg.value < min_fee * qty) revert NotEnoughValue();
            _safeMint(to, qty);
            payable(lmnft).transfer(msg.value);
        }
    
        /**
         * @dev Withdraws funds by owner.
         */
        function withdraw() external onlyOwner {
            uint256 value = address(this).balance;
            (bool success, ) = msg.sender.call{value: value}("");
            if (!success) revert WithdrawFailed();
            emit Withdraw(value);
        }
    
        
        /**
         * @dev Sets token base URI.
         */
        function setBaseURI(string calldata baseURI) external onlyOwner {
            if (_baseURIPermanent) revert CannotUpdatePermanentBaseURI();
            _currentBaseURI = baseURI;
            emit SetBaseURI(baseURI);
        }
    
        /**
         * @dev Sets token base URI permanent. Cannot revert.
         */
        function setBaseURIPermanent() external onlyOwner {
            _baseURIPermanent = true;
            emit PermanentBaseURI(_currentBaseURI);
        }
    
        /**
         * @dev Returns token URI suffix.
         */
        function getTokenURISuffix()
            external
            view
            override
            returns (string memory)
        {
            return _tokenURISuffix;
        }
    
        /**
         * @dev Sets token URI suffix. e.g. ".json".
         */
        function setTokenURISuffix(string calldata suffix) external onlyOwner {
            _tokenURISuffix = suffix;
        }
        
    
        /**
         * @dev Returns token URI for a given token id.
         */
        function tokenURI(uint256 tokenId)
            public
            view
            override(ERC721A, IERC721A)
            returns (string memory)
        {
            if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
    
            string memory baseURI = _currentBaseURI;
            return
                bytes(baseURI).length != 0
                    ? string(
                        abi.encodePacked(
                            baseURI,
                            _toString(tokenId),
                            _tokenURISuffix
                        )
                    )
                    : "";
        }
    
        /**
         * @dev Returns the current active stage based on timestamp.
         */
        function getActiveStageFromTimestamp(uint64 timestamp)
            public
            view
            override
            returns (uint256)
        {
            for (uint256 i = 0; i < _mintStages.length; i++) {
                if (
                    timestamp >= _mintStages[i].startTimeUnixSeconds &&
                    timestamp < _mintStages[i].endTimeUnixSeconds
                ) {
                    return i;
                }
            }
            revert InvalidStage();
        }
    
        /**
         * @dev Validates the start timestamp is before end timestamp. Used when updating stages.
         */
        function _assertValidStartAndEndTimestamp(uint64 start, uint64 end)
            internal
            pure
        {
            if (start >= end) revert InvalidStartAndEndTimestamp();
        }
    
        
    
    }

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"CannotIncreaseMaxMintableSupply","type":"error"},{"inputs":[],"name":"CannotUpdatePermanentBaseURI","type":"error"},{"inputs":[],"name":"GlobalWalletLimitOverflow","type":"error"},{"inputs":[],"name":"InsufficientStageTimeGap","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"InvalidStage","type":"error"},{"inputs":[],"name":"InvalidStageArgsLength","type":"error"},{"inputs":[],"name":"InvalidStartAndEndTimestamp","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"NoSupplyLeft","type":"error"},{"inputs":[],"name":"NotEnoughValue","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"StageSupplyExceeded","type":"error"},{"inputs":[],"name":"TimestampExpired","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"},{"inputs":[],"name":"WalletGlobalLimitExceeded","type":"error"},{"inputs":[],"name":"WalletStageLimitExceeded","type":"error"},{"inputs":[],"name":"WithdrawFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"baseURI","type":"string"}],"name":"PermanentBaseURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"activeStage","type":"uint256"}],"name":"SetActiveStage","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"baseURI","type":"string"}],"name":"SetBaseURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"globalWalletLimit","type":"uint256"}],"name":"SetGlobalWalletLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxMintableSupply","type":"uint256"}],"name":"SetMaxMintableSupply","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"stage","type":"uint256"},{"indexed":false,"internalType":"uint80","name":"cost","type":"uint80"},{"indexed":false,"internalType":"uint32","name":"walletLimit","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"indexed":false,"internalType":"uint24","name":"maxStageSupply","type":"uint24"},{"indexed":false,"internalType":"uint64","name":"startTimeUnixSeconds","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"endTimeUnixSeconds","type":"uint64"}],"name":"UpdateStage","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"timestamp","type":"uint64"}],"name":"getActiveStageFromTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGlobalWalletLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxMintableSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumberStages","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getStageInfo","outputs":[{"components":[{"internalType":"uint80","name":"cost","type":"uint80"},{"internalType":"uint32","name":"walletLimit","type":"uint32"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"uint24","name":"maxStageSupply","type":"uint24"},{"internalType":"uint64","name":"startTimeUnixSeconds","type":"uint64"},{"internalType":"uint64","name":"endTimeUnixSeconds","type":"uint64"}],"internalType":"struct IERC721L.MintStageInfo","name":"","type":"tuple"},{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokenURISuffix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"min_fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"qty","type":"uint32"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"qty","type":"uint32"},{"internalType":"address","name":"to","type":"address"}],"name":"ownerMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setBaseURIPermanent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"globalWalletLimit","type":"uint256"}],"name":"setGlobalWalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxMintableSupply","type":"uint256"}],"name":"setMaxMintableSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint80","name":"cost","type":"uint80"},{"internalType":"uint32","name":"walletLimit","type":"uint32"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"uint24","name":"maxStageSupply","type":"uint24"},{"internalType":"uint64","name":"startTimeUnixSeconds","type":"uint64"},{"internalType":"uint64","name":"endTimeUnixSeconds","type":"uint64"}],"internalType":"struct IERC721L.MintStageInfo[]","name":"newStages","type":"tuple[]"}],"name":"setStages","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"suffix","type":"string"}],"name":"setTokenURISuffix","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":[],"name":"threshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"a","type":"address"}],"name":"totalMintedByAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint80","name":"cost","type":"uint80"},{"internalType":"uint32","name":"walletLimit","type":"uint32"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"uint24","name":"maxStageSupply","type":"uint24"},{"internalType":"uint64","name":"startTimeUnixSeconds","type":"uint64"},{"internalType":"uint64","name":"endTimeUnixSeconds","type":"uint64"}],"name":"updateStage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6115b3600b556005600c55600d80546001600160a01b031916739e6865daeeedd093ea4a4f6c9bfbbb0ce6bc8b17179055651e0369471000600e5566071afd498d0000600f556101006040526043608081815290620037a260a0396010906200006990826200036d565b50604080518082019091526005815264173539b7b760d91b60208201526011906200009590826200036d565b50348015620000a357600080fd5b506040518060400160405280600d81526020016c2137b934b7339027b832b832b760991b815250604051806040016040528060048152602001630424f4f560e41b8152508160029081620000f891906200036d565b5060036200010782826200036d565b50506000805550620001193362000276565b600160098190556040805160c08101825260008082526005602083019081529282018181526060830182815263652c28c86080850190815263652c2fd060a08601908152601280549889018155909452935160039096027fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec344481018054965163ffffffff166a0100000000000000000000026001600160701b03199097166001600160501b03989098169790971795909517909555517fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec344584015592517fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34469092018054915193516001600160401b039081166b01000000000000000000000002600160581b600160981b0319959091166301000000026001600160581b031990931662ffffff9490941693909317919091179290921617905562000439565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620002f357607f821691505b6020821081036200031457634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200036857600081815260208120601f850160051c81016020861015620003435750805b601f850160051c820191505b8181101562000364578281556001016200034f565b5050505b505050565b81516001600160401b03811115620003895762000389620002c8565b620003a1816200039a8454620002de565b846200031a565b602080601f831160018114620003d95760008415620003c05750858301515b600019600386901b1c1916600185901b17855562000364565b600085815260208120601f198616915b828110156200040a57888601518255948401946001909101908401620003e9565b5085821015620004295787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61335980620004496000396000f3fe6080604052600436106101cb5760003560e01c806301ffc9a7146101d057806306fdde0314610205578063081812fc14610227578063095ea7b31461025f5780631053a81514610274578063107af24b1461028957806318160ddd1461029c57806323b872dd146102bf578063372992e4146102d25780633ccfd60b146102f257806342842e0e1461030757806342cde4e81461031a5780634b1c53b41461033057806355f804b3146103455780635bbb2177146103655780636352211e1461039257806367808a34146103b257806370a08231146103d257806370da24ee146103f2578063715018a61461040757806373e1607e1461041c5780638462151c1461043c5780638da5cb5b146104695780638dcdb09d1461047e57806395d89b411461049e57806397cf84fc146104b357806399a2557a146104d3578063a22cb465146104f3578063a3759f6014610513578063a9852bfb146105af578063aac5ab1f146105cf578063b7a9fa60146105e2578063b88d4fde146105f7578063c23dc68f1461060a578063c87b56dd14610637578063e985e9c514610657578063efdaa2ec146106a0578063f2fde38b146106b5578063f8d09696146106d5578063fa427177146106f5575b600080fd5b3480156101dc57600080fd5b506101f06101eb3660046127e3565b61070b565b60405190151581526020015b60405180910390f35b34801561021157600080fd5b5061021a61075d565b6040516101fc9190612858565b34801561023357600080fd5b5061024761024236600461286b565b6107ef565b6040516001600160a01b0390911681526020016101fc565b61027261026d3660046128a0565b610833565b005b34801561028057600080fd5b506102726108d3565b610272610297366004612929565b610923565b3480156102a857600080fd5b50600154600054035b6040519081526020016101fc565b6102726102cd36600461297b565b610946565b3480156102de57600080fd5b506102726102ed36600461286b565b610acd565b3480156102fe57600080fd5b50610272610b34565b61027261031536600461297b565b610bdf565b34801561032657600080fd5b506102b1600f5481565b34801561033c57600080fd5b50600b546102b1565b34801561035157600080fd5b506102726103603660046129b7565b610bfa565b34801561037157600080fd5b50610385610380366004612a28565b610c65565b6040516101fc9190612aa5565b34801561039e57600080fd5b506102476103ad36600461286b565b610d17565b3480156103be57600080fd5b506102b16103cd366004612afe565b610d22565b3480156103de57600080fd5b506102b16103ed366004612b19565b610dea565b3480156103fe57600080fd5b506012546102b1565b34801561041357600080fd5b50610272610e38565b34801561042857600080fd5b50610272610437366004612b5e565b610e4c565b34801561044857600080fd5b5061045c610457366004612b19565b6110af565b6040516101fc9190612bd6565b34801561047557600080fd5b50610247611195565b34801561048a57600080fd5b50610272610499366004612c0e565b6111a4565b3480156104aa57600080fd5b5061021a611638565b3480156104bf57600080fd5b506102b16104ce366004612b19565b611647565b3480156104df57600080fd5b5061045c6104ee366004612c70565b611652565b3480156104ff57600080fd5b5061027261050e366004612ca3565b6117cb565b34801561051f57600080fd5b5061053361052e36600461286b565b611837565b6040805184516001600160501b0316815260208086015163ffffffff90811691830191909152858301519282019290925260608086015162ffffff16908201526080808601516001600160401b039081169183019190915260a095860151169481019490945290911660c083015260e0820152610100016101fc565b3480156105bb57600080fd5b506102726105ca3660046129b7565b611956565b6102726105dd366004612cdf565b61196b565b3480156105ee57600080fd5b5061021a611a31565b610272610605366004612d28565b611a40565b34801561061657600080fd5b5061062a61062536600461286b565b611a84565b6040516101fc9190612e03565b34801561064357600080fd5b5061021a61065236600461286b565b611ac7565b34801561066357600080fd5b506101f0610672366004612e11565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156106ac57600080fd5b50600c546102b1565b3480156106c157600080fd5b506102726106d0366004612b19565b611bd0565b3480156106e157600080fd5b506102726106f036600461286b565b611c49565b34801561070157600080fd5b506102b1600e5481565b60006301ffc9a760e01b6001600160e01b03198316148061073c57506380ac58cd60e01b6001600160e01b03198316145b806107575750635b5e139f60e01b6001600160e01b03198316145b92915050565b60606002805461076c90612e2d565b80601f016020809104026020016040519081016040528092919081815260200182805461079890612e2d565b80156107e55780601f106107ba576101008083540402835291602001916107e5565b820191906000526020600020905b8154815290600101906020018083116107c857829003601f168201915b5050505050905090565b60006107fa82611ca9565b610817576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600061083e82610d17565b9050336001600160a01b038216146108775761085a8133610672565b610877576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6108db611cd0565b600a805460ff191660011790556040517fc6a6c2b165e62c9d37fc51a18ed76e5be22304bc1d337877c98f31c23e40b0f59061091990601090612e67565b60405180910390a1565b61092b611d2f565b61093783338484611d88565b6109416001600955565b505050565b6000610951826122b2565b9050836001600160a01b0316816001600160a01b0316146109845760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b038816909114176109d1576109b48633610672565b6109d157604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b0385166109f857604051633a954ecd60e21b815260040160405180910390fd5b8015610a0357600082555b6001600160a01b03868116600090815260056020526040808220805460001901905591871681522080546001019055610a4085600160e11b612319565b600085815260046020526040812091909155600160e11b84169003610a9557600184016000818152600460205260408120549003610a93576000548114610a935760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03166000805160206132e483398151915260405160405180910390a45b505050505050565b610ad5611cd0565b600b54811115610af857604051630590c51360e01b815260040160405180910390fd5b600c8190556040518181527f5307de8ad7d34d5ddfd5171435c143bdc645493980f453eb5d7cdb3e494a1b35906020015b60405180910390a150565b610b3c611cd0565b6040514790600090339083908381818185875af1925050503d8060008114610b80576040519150601f19603f3d011682016040523d82523d6000602084013e610b85565b606091505b5050905080610ba757604051631d42c86760e21b815260040160405180910390fd5b6040518281527f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d906020015b60405180910390a15050565b61094183838360405180602001604052806000815250611a40565b610c02611cd0565b600a5460ff1615610c26576040516306ccad4160e41b815260040160405180910390fd5b6010610c33828483612f38565b507f23c8c9488efebfd474e85a7956de6f39b17c7ab88502d42a623db2d8e382bbaa8282604051610bd3929190612ff7565b6060816000816001600160401b03811115610c8257610c82612d12565b604051908082528060200260200182016040528015610cbb57816020015b610ca8612771565b815260200190600190039081610ca05790505b50905060005b828114610d0e57610ce9868683818110610cdd57610cdd613026565b90506020020135611a84565b828281518110610cfb57610cfb613026565b6020908102919091010152600101610cc1565b50949350505050565b6000610757826122b2565b6000805b601254811015610dd05760128181548110610d4357610d43613026565b60009182526020909120600260039092020101546001600160401b036301000000909104811690841610801590610db3575060128181548110610d8857610d88613026565b60009182526020909120600260039092020101546001600160401b03600160581b9091048116908416105b15610dbe5792915050565b80610dc881613052565b915050610d26565b5060405163e82a532960e01b815260040160405180910390fd5b60006001600160a01b038216610e13576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b610e40611cd0565b610e4a600061232e565b565b610e54611cd0565b6012548710610e765760405163e82a532960e01b815260040160405180910390fd5b60018710610ee3576012610e8b60018961306b565b81548110610e9b57610e9b613026565b60009182526020909120600260039092020101546001600160401b03600160581b90910481169083161015610ee357604051636bc1af9360e01b815260040160405180910390fd5b610eed8282612380565b8560128881548110610f0157610f01613026565b906000526020600020906003020160000160006101000a8154816001600160501b0302191690836001600160501b031602179055508460128881548110610f4a57610f4a613026565b9060005260206000209060030201600001600a6101000a81548163ffffffff021916908363ffffffff1602179055508360128881548110610f8d57610f8d613026565b9060005260206000209060030201600101819055508260128881548110610fb657610fb6613026565b906000526020600020906003020160020160006101000a81548162ffffff021916908362ffffff1602179055508160128881548110610ff757610ff7613026565b906000526020600020906003020160020160036101000a8154816001600160401b0302191690836001600160401b03160217905550806012888154811061104057611040613026565b9060005260206000209060030201600201600b6101000a8154816001600160401b0302191690836001600160401b031602179055506000805160206133048339815191528787878787878760405161109e9796959493929190613082565b60405180910390a150505050505050565b606060008060006110bf85610dea565b90506000816001600160401b038111156110db576110db612d12565b604051908082528060200260200182016040528015611104578160200160208202803683370190505b50905061110f612771565b60005b83861461118957611122816123b6565b915081604001516111815781516001600160a01b03161561114257815194505b876001600160a01b0316856001600160a01b031603611181578083878060010198508151811061117457611174613026565b6020026020010181815250505b600101611112565b50909695505050505050565b6008546001600160a01b031690565b6111ac611cd0565b60125460005b8181101561121b5760128054806111cb576111cb6130d2565b60008281526020812060036000199093019283020180546001600160701b0319168155600181019190915560020180546001600160981b031916905590558061121381613052565b9150506111b2565b5060005b8281101561163257600181106112be57838361123c60018461306b565b81811061124b5761124b613026565b905060c0020160a00160208101906112639190612afe565b6001600160401b031684848381811061127e5761127e613026565b905060c0020160800160208101906112969190612afe565b6001600160401b031610156112be57604051636bc1af9360e01b815260040160405180910390fd5b61131a8484838181106112d3576112d3613026565b905060c0020160800160208101906112eb9190612afe565b8585848181106112fd576112fd613026565b905060c0020160a00160208101906113159190612afe565b612380565b60126040518060c0016040528086868581811061133957611339613026565b61134f92602060c09092020190810191506130e8565b6001600160501b0316815260200186868581811061136f5761136f613026565b905060c0020160200160208101906113879190613103565b63ffffffff1681526020018686858181106113a4576113a4613026565b905060c002016040013581526020018686858181106113c5576113c5613026565b905060c0020160600160208101906113dd919061311e565b62ffffff1681526020018686858181106113f9576113f9613026565b905060c0020160800160208101906114119190612afe565b6001600160401b0316815260200186868581811061143157611431613026565b905060c0020160a00160208101906114499190612afe565b6001600160401b039081169091528254600181810185556000948552602094859020845160039093020180549585015163ffffffff16600160501b026001600160701b03199096166001600160501b0390931692909217949094178155604083015193810193909355606082015160029093018054608084015160a0909401518316600160581b02600160581b600160981b0319949093166301000000026001600160581b031990911662ffffff9095169490941793909317919091161790556000805160206133048339815191528185858281811061152b5761152b613026565b61154192602060c09092020190810191506130e8565b86868581811061155357611553613026565b905060c00201602001602081019061156b9190613103565b87878681811061157d5761157d613026565b905060c002016040013588888781811061159957611599613026565b905060c0020160600160208101906115b1919061311e565b8989888181106115c3576115c3613026565b905060c0020160800160208101906115db9190612afe565b8a8a898181106115ed576115ed613026565b905060c0020160a00160208101906116059190612afe565b6040516116189796959493929190613082565b60405180910390a18061162a81613052565b91505061121f565b50505050565b60606003805461076c90612e2d565b6000610757826123d6565b606081831061167457604051631960ccad60e11b815260040160405180910390fd5b60008061168060005490565b90508084111561168e578093505b600061169987610dea565b9050848610156116b857858503818110156116b2578091505b506116bc565b5060005b6000816001600160401b038111156116d6576116d6612d12565b6040519080825280602002602001820160405280156116ff578160200160208202803683370190505b509050816000036117155793506117c492505050565b600061172088611a84565b905060008160400151611731575080515b885b8881141580156117435750848714155b156117b857611751816123b6565b925082604001516117b05782516001600160a01b03161561177157825191505b8a6001600160a01b0316826001600160a01b0316036117b057808488806001019950815181106117a3576117a3613026565b6020026020010181815250505b600101611733565b50505092835250909150505b9392505050565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61183f612798565b601254600090819084106118895760405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964537461676560a01b60448201526064015b60405180910390fd5b60008481526013602090815260408083203384528252808320548784526014909252909120546012805463ffffffff90931692879081106118cc576118cc613026565b60009182526020918290206040805160c08101825260039390930290910180546001600160501b0381168452600160501b900463ffffffff169383019390935260018301549082015260029091015462ffffff81166060830152630100000081046001600160401b039081166080840152600160581b9091041660a0820152969195509350915050565b61195e611cd0565b6011610941828483612f38565b611973611cd0565b8163ffffffff16600b548161198b6001546000540390565b6119959190613139565b11156119b45760405163800113cb60e01b815260040160405180910390fd5b8263ffffffff16600e546119c89190613151565b3410156119e857604051630717c22560e51b815260040160405180910390fd5b6119f8828463ffffffff166123fe565b600d546040516001600160a01b03909116903480156108fc02916000818181858888f19350505050158015611632573d6000803e3d6000fd5b60606011805461076c90612e2d565b611a4b848484610946565b6001600160a01b0383163b1561163257611a6784848484612418565b611632576040516368d2bf6b60e11b815260040160405180910390fd5b611a8c612771565b611a94612771565b6000548310611aa35792915050565b611aac836123b6565b9050806040015115611abe5792915050565b6117c483612503565b6060611ad282611ca9565b611aef57604051630a14c4b560e41b815260040160405180910390fd5b600060108054611afe90612e2d565b80601f0160208091040260200160405190810160405280929190818152602001828054611b2a90612e2d565b8015611b775780601f10611b4c57610100808354040283529160200191611b77565b820191906000526020600020905b815481529060010190602001808311611b5a57829003601f168201915b505050505090508051600003611b9c57604051806020016040528060008152506117c4565b80611ba68461251c565b6011604051602001611bba93929190613170565b6040516020818303038152906040529392505050565b611bd8611cd0565b6001600160a01b038116611c3d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401611880565b611c468161232e565b50565b611c51611cd0565b600b54811115611c745760405163430b83b160e11b815260040160405180910390fd5b600b8190556040518181527fc7bbc2b288fc13314546ea4aa51f6bcf71b7ba4740beeb3d32e9acef57b6668a90602001610b29565b6000805482108015610757575050600090815260046020526040902054600160e01b161590565b33611cd9611195565b6001600160a01b031614610e4a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401611880565b600260095403611d815760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611880565b6002600955565b8363ffffffff16600b5481611da06001546000540390565b611daa9190613139565b1115611dc95760405163800113cb60e01b815260040160405180910390fd5b42611dd2612798565b6000611ddd83610d22565b905060128181548110611df257611df2613026565b60009182526020918290206040805160c08101825260039390930290910180546001600160501b038116808552600160501b90910463ffffffff16948401949094526001810154918301919091526002015462ffffff81166060830152630100000081046001600160401b039081166080840152600160581b9091041660a0820152600f549093501115611ece57600e54825163ffffffff8a1691611e9f916001600160501b0316613139565b611ea99190613151565b341015611ec957604051630717c22560e51b815260040160405180910390fd5b611f0a565b8151611ee19063ffffffff8a1690613210565b6001600160501b0316341015611f0a57604051630717c22560e51b815260040160405180910390fd5b606082015162ffffff1615611f6457606082015160008281526014602052604090205462ffffff90911690611f469063ffffffff8b1690613139565b1115611f645760405162d0844960e21b815260040160405180910390fd5b600c5415611fa857600c548863ffffffff16611f7f896123d6565b611f899190613139565b1115611fa85760405163751304ed60e11b815260040160405180910390fd5b602082015163ffffffff161561201a5760208083015160008381526013835260408082206001600160a01b038c168352909352919091205463ffffffff91821691611ff5918b911661323f565b63ffffffff16111561201a5760405163b4f3729b60e01b815260040160405180910390fd5b6040820151156120b957816040015161209b878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040516001600160601b031960608e901b16602082015260340191506120809050565b60405160208183030381529060405280519060200120612560565b146120b9576040516309bde33960e01b815260040160405180910390fd5b60008181526013602090815260408083206001600160a01b038b168452909152812080548a92906120f190849063ffffffff1661323f565b92506101000a81548163ffffffff021916908363ffffffff1602179055508763ffffffff166014600083815260200190815260200160002060008282546121389190613139565b9091555061214e90508763ffffffff8a166123fe565b600f5482516001600160501b0316101561221257600d54600e546001600160a01b03909116906108fc906121899063ffffffff8c1690613151565b6040518115909202916000818181858888f193505050501580156121b1573d6000803e3d6000fd5b506121ba611195565b6001600160a01b03166108fc8963ffffffff16600e546121da9190613151565b6121e4903461306b565b6040518115909202916000818181858888f1935050505015801561220c573d6000803e3d6000fd5b506122a8565b600d546001600160a01b03166108fc61222c604234613267565b6040518115909202916000818181858888f19350505050158015612254573d6000803e3d6000fd5b5061225d611195565b6001600160a01b03166108fc612274604234613267565b61227e903461306b565b6040518115909202916000818181858888f193505050501580156122a6573d6000803e3d6000fd5b505b5050505050505050565b6000816000548110156123005760008181526004602052604081205490600160e01b821690036122fe575b806000036117c45750600019016000818152600460205260409020546122dd565b505b604051636f96cda160e11b815260040160405180910390fd5b4260a01b176001600160a01b03919091161790565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b806001600160401b0316826001600160401b0316106123b257604051631750215560e11b815260040160405180910390fd5b5050565b6123be612771565b600082815260046020526040902054610757906125ad565b6001600160a01b03166000908152600560205260409081902054901c6001600160401b031690565b6123b28282604051806020016040528060008152506125f0565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a029061244d903390899088908890600401613289565b6020604051808303816000875af1925050508015612488575060408051601f3d908101601f19168201909252612485918101906132c6565b60015b6124e6573d8080156124b6576040519150601f19603f3d011682016040523d82523d6000602084013e6124bb565b606091505b5080516000036124de576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b61250b612771565b610757612517836122b2565b6125ad565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a9004806125365750819003601f19909101908152919050565b600081815b84518110156125a5576125918286838151811061258457612584613026565b602002602001015161265d565b91508061259d81613052565b915050612565565b509392505050565b6125b5612771565b6001600160a01b03821681526001600160401b0360a083901c166020820152600160e01b82161515604082015260e89190911c606082015290565b6125fa8383612689565b6001600160a01b0383163b15610941576000548281035b6126246000868380600101945086612418565b612641576040516368d2bf6b60e11b815260040160405180910390fd5b81811061261157816000541461265657600080fd5b5050505050565b60008183106126795760008281526020849052604090206117c4565b5060009182526020526040902090565b60008054908290036126ae5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600090815260056020526040902080546001600160401b0184020190556126e5836001841460e11b612319565b6000828152600460205260408120919091556001600160a01b0384169083830190839083906000805160206132e48339815191528180a4600183015b81811461274757808360006000805160206132e4833981519152600080a4600101612721565b508160000361276857604051622e076360e81b815260040160405180910390fd5b60005550505050565b60408051608081018252600080825260208201819052918101829052606081019190915290565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6001600160e01b031981168114611c4657600080fd5b6000602082840312156127f557600080fd5b81356117c4816127cd565b60005b8381101561281b578181015183820152602001612803565b838111156116325750506000910152565b60008151808452612844816020860160208601612800565b601f01601f19169290920160200192915050565b6020815260006117c4602083018461282c565b60006020828403121561287d57600080fd5b5035919050565b80356001600160a01b038116811461289b57600080fd5b919050565b600080604083850312156128b357600080fd5b6128bc83612884565b946020939093013593505050565b803563ffffffff8116811461289b57600080fd5b60008083601f8401126128f057600080fd5b5081356001600160401b0381111561290757600080fd5b6020830191508360208260051b850101111561292257600080fd5b9250929050565b60008060006040848603121561293e57600080fd5b612947846128ca565b925060208401356001600160401b0381111561296257600080fd5b61296e868287016128de565b9497909650939450505050565b60008060006060848603121561299057600080fd5b61299984612884565b92506129a760208501612884565b9150604084013590509250925092565b600080602083850312156129ca57600080fd5b82356001600160401b03808211156129e157600080fd5b818501915085601f8301126129f557600080fd5b813581811115612a0457600080fd5b866020828501011115612a1657600080fd5b60209290920196919550909350505050565b60008060208385031215612a3b57600080fd5b82356001600160401b03811115612a5157600080fd5b612a5d858286016128de565b90969095509350505050565b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b6020808252825182820181905260009190848201906040850190845b8181101561118957612ad4838551612a69565b9284019260809290920191600101612ac1565b80356001600160401b038116811461289b57600080fd5b600060208284031215612b1057600080fd5b6117c482612ae7565b600060208284031215612b2b57600080fd5b6117c482612884565b80356001600160501b038116811461289b57600080fd5b803562ffffff8116811461289b57600080fd5b600080600080600080600060e0888a031215612b7957600080fd5b87359650612b8960208901612b34565b9550612b97604089016128ca565b945060608801359350612bac60808901612b4b565b9250612bba60a08901612ae7565b9150612bc860c08901612ae7565b905092959891949750929550565b6020808252825182820181905260009190848201906040850190845b8181101561118957835183529284019291840191600101612bf2565b60008060208385031215612c2157600080fd5b82356001600160401b0380821115612c3857600080fd5b818501915085601f830112612c4c57600080fd5b813581811115612c5b57600080fd5b86602060c083028501011115612a1657600080fd5b600080600060608486031215612c8557600080fd5b612c8e84612884565b95602085013595506040909401359392505050565b60008060408385031215612cb657600080fd5b612cbf83612884565b915060208301358015158114612cd457600080fd5b809150509250929050565b60008060408385031215612cf257600080fd5b612cfb836128ca565b9150612d0960208401612884565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215612d3e57600080fd5b612d4785612884565b9350612d5560208601612884565b92506040850135915060608501356001600160401b0380821115612d7857600080fd5b818701915087601f830112612d8c57600080fd5b813581811115612d9e57612d9e612d12565b604051601f8201601f19908116603f01168101908382118183101715612dc657612dc6612d12565b816040528281528a6020848701011115612ddf57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b608081016107578284612a69565b60008060408385031215612e2457600080fd5b612cfb83612884565b600181811c90821680612e4157607f821691505b602082108103612e6157634e487b7160e01b600052602260045260246000fd5b50919050565b6000602080835260008454612e7b81612e2d565b80848701526040600180841660008114612e9c5760018114612eb657612ee4565b60ff1985168984015283151560051b890183019550612ee4565b896000528660002060005b85811015612edc5781548b8201860152908301908801612ec1565b8a0184019650505b509398975050505050505050565b601f82111561094157600081815260208120601f850160051c81016020861015612f195750805b601f850160051c820191505b81811015610ac557828155600101612f25565b6001600160401b03831115612f4f57612f4f612d12565b612f6383612f5d8354612e2d565b83612ef2565b6000601f841160018114612f975760008515612f7f5750838201355b600019600387901b1c1916600186901b178355612656565b600083815260209020601f19861690835b82811015612fc85786850135825560209485019460019092019101612fa8565b5086821015612fe55760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016130645761306461303c565b5060010190565b60008282101561307d5761307d61303c565b500390565b9687526001600160501b0395909516602087015263ffffffff939093166040860152606085019190915262ffffff1660808401526001600160401b0390811660a08401521660c082015260e00190565b634e487b7160e01b600052603160045260246000fd5b6000602082840312156130fa57600080fd5b6117c482612b34565b60006020828403121561311557600080fd5b6117c4826128ca565b60006020828403121561313057600080fd5b6117c482612b4b565b6000821982111561314c5761314c61303c565b500190565b600081600019048311821515161561316b5761316b61303c565b500290565b6000845160206131838285838a01612800565b8551918401916131968184848a01612800565b85549201916000906131a781612e2d565b600182811680156131bf57600181146131d457613200565b60ff1984168752821515830287019450613200565b896000528560002060005b848110156131f8578154898201529083019087016131df565b505082870194505b50929a9950505050505050505050565b60006001600160501b03828116848216811515828404821116156132365761323661303c565b02949350505050565b600063ffffffff80831681851680830382111561325e5761325e61303c565b01949350505050565b60008261328457634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906132bc9083018461282c565b9695505050505050565b6000602082840312156132d857600080fd5b81516117c4816127cd56feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efb3268648542a1bb1b2dd12e3b14aeb5a3ab22c592de96bdd3e842154a5b394faa264697066735822122023973e674eedf342e0b68b80eea05fd83b57193907dd66901236874e41f7f7f264736f6c634300080f0033697066733a2f2f62616679626569667436647064346d346d3634746f7778727463697a7a6b6a6b686a64646d756e6d74367a67666c77736b69366d656677616c63652f

Deployed Bytecode

0x6080604052600436106101cb5760003560e01c806301ffc9a7146101d057806306fdde0314610205578063081812fc14610227578063095ea7b31461025f5780631053a81514610274578063107af24b1461028957806318160ddd1461029c57806323b872dd146102bf578063372992e4146102d25780633ccfd60b146102f257806342842e0e1461030757806342cde4e81461031a5780634b1c53b41461033057806355f804b3146103455780635bbb2177146103655780636352211e1461039257806367808a34146103b257806370a08231146103d257806370da24ee146103f2578063715018a61461040757806373e1607e1461041c5780638462151c1461043c5780638da5cb5b146104695780638dcdb09d1461047e57806395d89b411461049e57806397cf84fc146104b357806399a2557a146104d3578063a22cb465146104f3578063a3759f6014610513578063a9852bfb146105af578063aac5ab1f146105cf578063b7a9fa60146105e2578063b88d4fde146105f7578063c23dc68f1461060a578063c87b56dd14610637578063e985e9c514610657578063efdaa2ec146106a0578063f2fde38b146106b5578063f8d09696146106d5578063fa427177146106f5575b600080fd5b3480156101dc57600080fd5b506101f06101eb3660046127e3565b61070b565b60405190151581526020015b60405180910390f35b34801561021157600080fd5b5061021a61075d565b6040516101fc9190612858565b34801561023357600080fd5b5061024761024236600461286b565b6107ef565b6040516001600160a01b0390911681526020016101fc565b61027261026d3660046128a0565b610833565b005b34801561028057600080fd5b506102726108d3565b610272610297366004612929565b610923565b3480156102a857600080fd5b50600154600054035b6040519081526020016101fc565b6102726102cd36600461297b565b610946565b3480156102de57600080fd5b506102726102ed36600461286b565b610acd565b3480156102fe57600080fd5b50610272610b34565b61027261031536600461297b565b610bdf565b34801561032657600080fd5b506102b1600f5481565b34801561033c57600080fd5b50600b546102b1565b34801561035157600080fd5b506102726103603660046129b7565b610bfa565b34801561037157600080fd5b50610385610380366004612a28565b610c65565b6040516101fc9190612aa5565b34801561039e57600080fd5b506102476103ad36600461286b565b610d17565b3480156103be57600080fd5b506102b16103cd366004612afe565b610d22565b3480156103de57600080fd5b506102b16103ed366004612b19565b610dea565b3480156103fe57600080fd5b506012546102b1565b34801561041357600080fd5b50610272610e38565b34801561042857600080fd5b50610272610437366004612b5e565b610e4c565b34801561044857600080fd5b5061045c610457366004612b19565b6110af565b6040516101fc9190612bd6565b34801561047557600080fd5b50610247611195565b34801561048a57600080fd5b50610272610499366004612c0e565b6111a4565b3480156104aa57600080fd5b5061021a611638565b3480156104bf57600080fd5b506102b16104ce366004612b19565b611647565b3480156104df57600080fd5b5061045c6104ee366004612c70565b611652565b3480156104ff57600080fd5b5061027261050e366004612ca3565b6117cb565b34801561051f57600080fd5b5061053361052e36600461286b565b611837565b6040805184516001600160501b0316815260208086015163ffffffff90811691830191909152858301519282019290925260608086015162ffffff16908201526080808601516001600160401b039081169183019190915260a095860151169481019490945290911660c083015260e0820152610100016101fc565b3480156105bb57600080fd5b506102726105ca3660046129b7565b611956565b6102726105dd366004612cdf565b61196b565b3480156105ee57600080fd5b5061021a611a31565b610272610605366004612d28565b611a40565b34801561061657600080fd5b5061062a61062536600461286b565b611a84565b6040516101fc9190612e03565b34801561064357600080fd5b5061021a61065236600461286b565b611ac7565b34801561066357600080fd5b506101f0610672366004612e11565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156106ac57600080fd5b50600c546102b1565b3480156106c157600080fd5b506102726106d0366004612b19565b611bd0565b3480156106e157600080fd5b506102726106f036600461286b565b611c49565b34801561070157600080fd5b506102b1600e5481565b60006301ffc9a760e01b6001600160e01b03198316148061073c57506380ac58cd60e01b6001600160e01b03198316145b806107575750635b5e139f60e01b6001600160e01b03198316145b92915050565b60606002805461076c90612e2d565b80601f016020809104026020016040519081016040528092919081815260200182805461079890612e2d565b80156107e55780601f106107ba576101008083540402835291602001916107e5565b820191906000526020600020905b8154815290600101906020018083116107c857829003601f168201915b5050505050905090565b60006107fa82611ca9565b610817576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600061083e82610d17565b9050336001600160a01b038216146108775761085a8133610672565b610877576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6108db611cd0565b600a805460ff191660011790556040517fc6a6c2b165e62c9d37fc51a18ed76e5be22304bc1d337877c98f31c23e40b0f59061091990601090612e67565b60405180910390a1565b61092b611d2f565b61093783338484611d88565b6109416001600955565b505050565b6000610951826122b2565b9050836001600160a01b0316816001600160a01b0316146109845760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b038816909114176109d1576109b48633610672565b6109d157604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b0385166109f857604051633a954ecd60e21b815260040160405180910390fd5b8015610a0357600082555b6001600160a01b03868116600090815260056020526040808220805460001901905591871681522080546001019055610a4085600160e11b612319565b600085815260046020526040812091909155600160e11b84169003610a9557600184016000818152600460205260408120549003610a93576000548114610a935760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03166000805160206132e483398151915260405160405180910390a45b505050505050565b610ad5611cd0565b600b54811115610af857604051630590c51360e01b815260040160405180910390fd5b600c8190556040518181527f5307de8ad7d34d5ddfd5171435c143bdc645493980f453eb5d7cdb3e494a1b35906020015b60405180910390a150565b610b3c611cd0565b6040514790600090339083908381818185875af1925050503d8060008114610b80576040519150601f19603f3d011682016040523d82523d6000602084013e610b85565b606091505b5050905080610ba757604051631d42c86760e21b815260040160405180910390fd5b6040518281527f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d906020015b60405180910390a15050565b61094183838360405180602001604052806000815250611a40565b610c02611cd0565b600a5460ff1615610c26576040516306ccad4160e41b815260040160405180910390fd5b6010610c33828483612f38565b507f23c8c9488efebfd474e85a7956de6f39b17c7ab88502d42a623db2d8e382bbaa8282604051610bd3929190612ff7565b6060816000816001600160401b03811115610c8257610c82612d12565b604051908082528060200260200182016040528015610cbb57816020015b610ca8612771565b815260200190600190039081610ca05790505b50905060005b828114610d0e57610ce9868683818110610cdd57610cdd613026565b90506020020135611a84565b828281518110610cfb57610cfb613026565b6020908102919091010152600101610cc1565b50949350505050565b6000610757826122b2565b6000805b601254811015610dd05760128181548110610d4357610d43613026565b60009182526020909120600260039092020101546001600160401b036301000000909104811690841610801590610db3575060128181548110610d8857610d88613026565b60009182526020909120600260039092020101546001600160401b03600160581b9091048116908416105b15610dbe5792915050565b80610dc881613052565b915050610d26565b5060405163e82a532960e01b815260040160405180910390fd5b60006001600160a01b038216610e13576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b610e40611cd0565b610e4a600061232e565b565b610e54611cd0565b6012548710610e765760405163e82a532960e01b815260040160405180910390fd5b60018710610ee3576012610e8b60018961306b565b81548110610e9b57610e9b613026565b60009182526020909120600260039092020101546001600160401b03600160581b90910481169083161015610ee357604051636bc1af9360e01b815260040160405180910390fd5b610eed8282612380565b8560128881548110610f0157610f01613026565b906000526020600020906003020160000160006101000a8154816001600160501b0302191690836001600160501b031602179055508460128881548110610f4a57610f4a613026565b9060005260206000209060030201600001600a6101000a81548163ffffffff021916908363ffffffff1602179055508360128881548110610f8d57610f8d613026565b9060005260206000209060030201600101819055508260128881548110610fb657610fb6613026565b906000526020600020906003020160020160006101000a81548162ffffff021916908362ffffff1602179055508160128881548110610ff757610ff7613026565b906000526020600020906003020160020160036101000a8154816001600160401b0302191690836001600160401b03160217905550806012888154811061104057611040613026565b9060005260206000209060030201600201600b6101000a8154816001600160401b0302191690836001600160401b031602179055506000805160206133048339815191528787878787878760405161109e9796959493929190613082565b60405180910390a150505050505050565b606060008060006110bf85610dea565b90506000816001600160401b038111156110db576110db612d12565b604051908082528060200260200182016040528015611104578160200160208202803683370190505b50905061110f612771565b60005b83861461118957611122816123b6565b915081604001516111815781516001600160a01b03161561114257815194505b876001600160a01b0316856001600160a01b031603611181578083878060010198508151811061117457611174613026565b6020026020010181815250505b600101611112565b50909695505050505050565b6008546001600160a01b031690565b6111ac611cd0565b60125460005b8181101561121b5760128054806111cb576111cb6130d2565b60008281526020812060036000199093019283020180546001600160701b0319168155600181019190915560020180546001600160981b031916905590558061121381613052565b9150506111b2565b5060005b8281101561163257600181106112be57838361123c60018461306b565b81811061124b5761124b613026565b905060c0020160a00160208101906112639190612afe565b6001600160401b031684848381811061127e5761127e613026565b905060c0020160800160208101906112969190612afe565b6001600160401b031610156112be57604051636bc1af9360e01b815260040160405180910390fd5b61131a8484838181106112d3576112d3613026565b905060c0020160800160208101906112eb9190612afe565b8585848181106112fd576112fd613026565b905060c0020160a00160208101906113159190612afe565b612380565b60126040518060c0016040528086868581811061133957611339613026565b61134f92602060c09092020190810191506130e8565b6001600160501b0316815260200186868581811061136f5761136f613026565b905060c0020160200160208101906113879190613103565b63ffffffff1681526020018686858181106113a4576113a4613026565b905060c002016040013581526020018686858181106113c5576113c5613026565b905060c0020160600160208101906113dd919061311e565b62ffffff1681526020018686858181106113f9576113f9613026565b905060c0020160800160208101906114119190612afe565b6001600160401b0316815260200186868581811061143157611431613026565b905060c0020160a00160208101906114499190612afe565b6001600160401b039081169091528254600181810185556000948552602094859020845160039093020180549585015163ffffffff16600160501b026001600160701b03199096166001600160501b0390931692909217949094178155604083015193810193909355606082015160029093018054608084015160a0909401518316600160581b02600160581b600160981b0319949093166301000000026001600160581b031990911662ffffff9095169490941793909317919091161790556000805160206133048339815191528185858281811061152b5761152b613026565b61154192602060c09092020190810191506130e8565b86868581811061155357611553613026565b905060c00201602001602081019061156b9190613103565b87878681811061157d5761157d613026565b905060c002016040013588888781811061159957611599613026565b905060c0020160600160208101906115b1919061311e565b8989888181106115c3576115c3613026565b905060c0020160800160208101906115db9190612afe565b8a8a898181106115ed576115ed613026565b905060c0020160a00160208101906116059190612afe565b6040516116189796959493929190613082565b60405180910390a18061162a81613052565b91505061121f565b50505050565b60606003805461076c90612e2d565b6000610757826123d6565b606081831061167457604051631960ccad60e11b815260040160405180910390fd5b60008061168060005490565b90508084111561168e578093505b600061169987610dea565b9050848610156116b857858503818110156116b2578091505b506116bc565b5060005b6000816001600160401b038111156116d6576116d6612d12565b6040519080825280602002602001820160405280156116ff578160200160208202803683370190505b509050816000036117155793506117c492505050565b600061172088611a84565b905060008160400151611731575080515b885b8881141580156117435750848714155b156117b857611751816123b6565b925082604001516117b05782516001600160a01b03161561177157825191505b8a6001600160a01b0316826001600160a01b0316036117b057808488806001019950815181106117a3576117a3613026565b6020026020010181815250505b600101611733565b50505092835250909150505b9392505050565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61183f612798565b601254600090819084106118895760405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964537461676560a01b60448201526064015b60405180910390fd5b60008481526013602090815260408083203384528252808320548784526014909252909120546012805463ffffffff90931692879081106118cc576118cc613026565b60009182526020918290206040805160c08101825260039390930290910180546001600160501b0381168452600160501b900463ffffffff169383019390935260018301549082015260029091015462ffffff81166060830152630100000081046001600160401b039081166080840152600160581b9091041660a0820152969195509350915050565b61195e611cd0565b6011610941828483612f38565b611973611cd0565b8163ffffffff16600b548161198b6001546000540390565b6119959190613139565b11156119b45760405163800113cb60e01b815260040160405180910390fd5b8263ffffffff16600e546119c89190613151565b3410156119e857604051630717c22560e51b815260040160405180910390fd5b6119f8828463ffffffff166123fe565b600d546040516001600160a01b03909116903480156108fc02916000818181858888f19350505050158015611632573d6000803e3d6000fd5b60606011805461076c90612e2d565b611a4b848484610946565b6001600160a01b0383163b1561163257611a6784848484612418565b611632576040516368d2bf6b60e11b815260040160405180910390fd5b611a8c612771565b611a94612771565b6000548310611aa35792915050565b611aac836123b6565b9050806040015115611abe5792915050565b6117c483612503565b6060611ad282611ca9565b611aef57604051630a14c4b560e41b815260040160405180910390fd5b600060108054611afe90612e2d565b80601f0160208091040260200160405190810160405280929190818152602001828054611b2a90612e2d565b8015611b775780601f10611b4c57610100808354040283529160200191611b77565b820191906000526020600020905b815481529060010190602001808311611b5a57829003601f168201915b505050505090508051600003611b9c57604051806020016040528060008152506117c4565b80611ba68461251c565b6011604051602001611bba93929190613170565b6040516020818303038152906040529392505050565b611bd8611cd0565b6001600160a01b038116611c3d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401611880565b611c468161232e565b50565b611c51611cd0565b600b54811115611c745760405163430b83b160e11b815260040160405180910390fd5b600b8190556040518181527fc7bbc2b288fc13314546ea4aa51f6bcf71b7ba4740beeb3d32e9acef57b6668a90602001610b29565b6000805482108015610757575050600090815260046020526040902054600160e01b161590565b33611cd9611195565b6001600160a01b031614610e4a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401611880565b600260095403611d815760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611880565b6002600955565b8363ffffffff16600b5481611da06001546000540390565b611daa9190613139565b1115611dc95760405163800113cb60e01b815260040160405180910390fd5b42611dd2612798565b6000611ddd83610d22565b905060128181548110611df257611df2613026565b60009182526020918290206040805160c08101825260039390930290910180546001600160501b038116808552600160501b90910463ffffffff16948401949094526001810154918301919091526002015462ffffff81166060830152630100000081046001600160401b039081166080840152600160581b9091041660a0820152600f549093501115611ece57600e54825163ffffffff8a1691611e9f916001600160501b0316613139565b611ea99190613151565b341015611ec957604051630717c22560e51b815260040160405180910390fd5b611f0a565b8151611ee19063ffffffff8a1690613210565b6001600160501b0316341015611f0a57604051630717c22560e51b815260040160405180910390fd5b606082015162ffffff1615611f6457606082015160008281526014602052604090205462ffffff90911690611f469063ffffffff8b1690613139565b1115611f645760405162d0844960e21b815260040160405180910390fd5b600c5415611fa857600c548863ffffffff16611f7f896123d6565b611f899190613139565b1115611fa85760405163751304ed60e11b815260040160405180910390fd5b602082015163ffffffff161561201a5760208083015160008381526013835260408082206001600160a01b038c168352909352919091205463ffffffff91821691611ff5918b911661323f565b63ffffffff16111561201a5760405163b4f3729b60e01b815260040160405180910390fd5b6040820151156120b957816040015161209b878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040516001600160601b031960608e901b16602082015260340191506120809050565b60405160208183030381529060405280519060200120612560565b146120b9576040516309bde33960e01b815260040160405180910390fd5b60008181526013602090815260408083206001600160a01b038b168452909152812080548a92906120f190849063ffffffff1661323f565b92506101000a81548163ffffffff021916908363ffffffff1602179055508763ffffffff166014600083815260200190815260200160002060008282546121389190613139565b9091555061214e90508763ffffffff8a166123fe565b600f5482516001600160501b0316101561221257600d54600e546001600160a01b03909116906108fc906121899063ffffffff8c1690613151565b6040518115909202916000818181858888f193505050501580156121b1573d6000803e3d6000fd5b506121ba611195565b6001600160a01b03166108fc8963ffffffff16600e546121da9190613151565b6121e4903461306b565b6040518115909202916000818181858888f1935050505015801561220c573d6000803e3d6000fd5b506122a8565b600d546001600160a01b03166108fc61222c604234613267565b6040518115909202916000818181858888f19350505050158015612254573d6000803e3d6000fd5b5061225d611195565b6001600160a01b03166108fc612274604234613267565b61227e903461306b565b6040518115909202916000818181858888f193505050501580156122a6573d6000803e3d6000fd5b505b5050505050505050565b6000816000548110156123005760008181526004602052604081205490600160e01b821690036122fe575b806000036117c45750600019016000818152600460205260409020546122dd565b505b604051636f96cda160e11b815260040160405180910390fd5b4260a01b176001600160a01b03919091161790565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b806001600160401b0316826001600160401b0316106123b257604051631750215560e11b815260040160405180910390fd5b5050565b6123be612771565b600082815260046020526040902054610757906125ad565b6001600160a01b03166000908152600560205260409081902054901c6001600160401b031690565b6123b28282604051806020016040528060008152506125f0565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a029061244d903390899088908890600401613289565b6020604051808303816000875af1925050508015612488575060408051601f3d908101601f19168201909252612485918101906132c6565b60015b6124e6573d8080156124b6576040519150601f19603f3d011682016040523d82523d6000602084013e6124bb565b606091505b5080516000036124de576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b61250b612771565b610757612517836122b2565b6125ad565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a9004806125365750819003601f19909101908152919050565b600081815b84518110156125a5576125918286838151811061258457612584613026565b602002602001015161265d565b91508061259d81613052565b915050612565565b509392505050565b6125b5612771565b6001600160a01b03821681526001600160401b0360a083901c166020820152600160e01b82161515604082015260e89190911c606082015290565b6125fa8383612689565b6001600160a01b0383163b15610941576000548281035b6126246000868380600101945086612418565b612641576040516368d2bf6b60e11b815260040160405180910390fd5b81811061261157816000541461265657600080fd5b5050505050565b60008183106126795760008281526020849052604090206117c4565b5060009182526020526040902090565b60008054908290036126ae5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600090815260056020526040902080546001600160401b0184020190556126e5836001841460e11b612319565b6000828152600460205260408120919091556001600160a01b0384169083830190839083906000805160206132e48339815191528180a4600183015b81811461274757808360006000805160206132e4833981519152600080a4600101612721565b508160000361276857604051622e076360e81b815260040160405180910390fd5b60005550505050565b60408051608081018252600080825260208201819052918101829052606081019190915290565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6001600160e01b031981168114611c4657600080fd5b6000602082840312156127f557600080fd5b81356117c4816127cd565b60005b8381101561281b578181015183820152602001612803565b838111156116325750506000910152565b60008151808452612844816020860160208601612800565b601f01601f19169290920160200192915050565b6020815260006117c4602083018461282c565b60006020828403121561287d57600080fd5b5035919050565b80356001600160a01b038116811461289b57600080fd5b919050565b600080604083850312156128b357600080fd5b6128bc83612884565b946020939093013593505050565b803563ffffffff8116811461289b57600080fd5b60008083601f8401126128f057600080fd5b5081356001600160401b0381111561290757600080fd5b6020830191508360208260051b850101111561292257600080fd5b9250929050565b60008060006040848603121561293e57600080fd5b612947846128ca565b925060208401356001600160401b0381111561296257600080fd5b61296e868287016128de565b9497909650939450505050565b60008060006060848603121561299057600080fd5b61299984612884565b92506129a760208501612884565b9150604084013590509250925092565b600080602083850312156129ca57600080fd5b82356001600160401b03808211156129e157600080fd5b818501915085601f8301126129f557600080fd5b813581811115612a0457600080fd5b866020828501011115612a1657600080fd5b60209290920196919550909350505050565b60008060208385031215612a3b57600080fd5b82356001600160401b03811115612a5157600080fd5b612a5d858286016128de565b90969095509350505050565b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b6020808252825182820181905260009190848201906040850190845b8181101561118957612ad4838551612a69565b9284019260809290920191600101612ac1565b80356001600160401b038116811461289b57600080fd5b600060208284031215612b1057600080fd5b6117c482612ae7565b600060208284031215612b2b57600080fd5b6117c482612884565b80356001600160501b038116811461289b57600080fd5b803562ffffff8116811461289b57600080fd5b600080600080600080600060e0888a031215612b7957600080fd5b87359650612b8960208901612b34565b9550612b97604089016128ca565b945060608801359350612bac60808901612b4b565b9250612bba60a08901612ae7565b9150612bc860c08901612ae7565b905092959891949750929550565b6020808252825182820181905260009190848201906040850190845b8181101561118957835183529284019291840191600101612bf2565b60008060208385031215612c2157600080fd5b82356001600160401b0380821115612c3857600080fd5b818501915085601f830112612c4c57600080fd5b813581811115612c5b57600080fd5b86602060c083028501011115612a1657600080fd5b600080600060608486031215612c8557600080fd5b612c8e84612884565b95602085013595506040909401359392505050565b60008060408385031215612cb657600080fd5b612cbf83612884565b915060208301358015158114612cd457600080fd5b809150509250929050565b60008060408385031215612cf257600080fd5b612cfb836128ca565b9150612d0960208401612884565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215612d3e57600080fd5b612d4785612884565b9350612d5560208601612884565b92506040850135915060608501356001600160401b0380821115612d7857600080fd5b818701915087601f830112612d8c57600080fd5b813581811115612d9e57612d9e612d12565b604051601f8201601f19908116603f01168101908382118183101715612dc657612dc6612d12565b816040528281528a6020848701011115612ddf57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b608081016107578284612a69565b60008060408385031215612e2457600080fd5b612cfb83612884565b600181811c90821680612e4157607f821691505b602082108103612e6157634e487b7160e01b600052602260045260246000fd5b50919050565b6000602080835260008454612e7b81612e2d565b80848701526040600180841660008114612e9c5760018114612eb657612ee4565b60ff1985168984015283151560051b890183019550612ee4565b896000528660002060005b85811015612edc5781548b8201860152908301908801612ec1565b8a0184019650505b509398975050505050505050565b601f82111561094157600081815260208120601f850160051c81016020861015612f195750805b601f850160051c820191505b81811015610ac557828155600101612f25565b6001600160401b03831115612f4f57612f4f612d12565b612f6383612f5d8354612e2d565b83612ef2565b6000601f841160018114612f975760008515612f7f5750838201355b600019600387901b1c1916600186901b178355612656565b600083815260209020601f19861690835b82811015612fc85786850135825560209485019460019092019101612fa8565b5086821015612fe55760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016130645761306461303c565b5060010190565b60008282101561307d5761307d61303c565b500390565b9687526001600160501b0395909516602087015263ffffffff939093166040860152606085019190915262ffffff1660808401526001600160401b0390811660a08401521660c082015260e00190565b634e487b7160e01b600052603160045260246000fd5b6000602082840312156130fa57600080fd5b6117c482612b34565b60006020828403121561311557600080fd5b6117c4826128ca565b60006020828403121561313057600080fd5b6117c482612b4b565b6000821982111561314c5761314c61303c565b500190565b600081600019048311821515161561316b5761316b61303c565b500290565b6000845160206131838285838a01612800565b8551918401916131968184848a01612800565b85549201916000906131a781612e2d565b600182811680156131bf57600181146131d457613200565b60ff1984168752821515830287019450613200565b896000528560002060005b848110156131f8578154898201529083019087016131df565b505082870194505b50929a9950505050505050505050565b60006001600160501b03828116848216811515828404821116156132365761323661303c565b02949350505050565b600063ffffffff80831681851680830382111561325e5761325e61303c565b01949350505050565b60008261328457634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906132bc9083018461282c565b9695505050505050565b6000602082840312156132d857600080fd5b81516117c4816127cd56feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efb3268648542a1bb1b2dd12e3b14aeb5a3ab22c592de96bdd3e842154a5b394faa264697066735822122023973e674eedf342e0b68b80eea05fd83b57193907dd66901236874e41f7f7f264736f6c634300080f0033

Deployed Bytecode Sourcemap

87287:15400:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20568:675;;;;;;;;;;-1:-1:-1;20568:675:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;20568:675:0;;;;;;;;21542:108;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;28713:234::-;;;;;;;;;;-1:-1:-1;28713:234:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1692:32:1;;;1674:51;;1662:2;1647:18;28713:234:0;1528:203:1;28070:448:0;;;;;;:::i;:::-;;:::i;:::-;;100288:154;;;;;;;;;;;;;:::i;96227:183::-;;;;;;:::i;:::-;;:::i;16877:347::-;;;;;;;;;;-1:-1:-1;17167:12:0;;16938:7;17151:13;:28;16877:347;;;3373:25:1;;;3361:2;3346:18;16877:347:0;3227:177:1;32736:3069:0;;;;;;:::i;:::-;;:::i;93096:345::-;;;;;;;;;;-1:-1:-1;93096:345:0;;;;;:::i;:::-;;:::i;99606:257::-;;;;;;;;;;;;;:::i;35921:217::-;;;;;;:::i;:::-;;:::i;87895:38::-;;;;;;;;;;;;;;;;92067:125;;;;;;;;;;-1:-1:-1;92162:18:0;;92067:125;;99953:230;;;;;;;;;;-1:-1:-1;99953:230:0;;;;;:::i;:::-;;:::i;64131:588::-;;;;;;;;;;-1:-1:-1;64131:588:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;23099:160::-;;;;;;;;;;-1:-1:-1;23099:160:0;;;;;:::i;:::-;;:::i;101804:515::-;;;;;;;;;;-1:-1:-1;101804:515:0;;;;;:::i;:::-;;:::i;18193:245::-;;;;;;;;;;-1:-1:-1;18193:245:0;;;;;:::i;:::-;;:::i;91855:120::-;;;;;;;;;;-1:-1:-1;91945:11:0;:18;91855:120;;86243:111;;;;;;;;;;;;;:::i;94579:1422::-;;;;;;;;;;-1:-1:-1;94579:1422:0;;;;;:::i;:::-;;:::i;68407:984::-;;;;;;;;;;-1:-1:-1;68407:984:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;85523:95::-;;;;;;;;;;;;;:::i;90052:1718::-;;;;;;;;;;-1:-1:-1;90052:1718:0;;;;;:::i;:::-;;:::i;21746:112::-;;;;;;;;;;;;;:::i;93552:214::-;;;;;;;;;;-1:-1:-1;93552:214:0;;;;;:::i;:::-;;:::i;65163:2749::-;;;;;;;;;;-1:-1:-1;65163:2749:0;;;;;:::i;:::-;;:::i;29339:246::-;;;;;;;;;;-1:-1:-1;29339:246:0;;;;;:::i;:::-;;:::i;93890:565::-;;;;;;;;;;-1:-1:-1;93890:565:0;;;;;:::i;:::-;;:::i;:::-;;;;9632:13:1;;-1:-1:-1;;;;;9628:38:1;9610:57;;9714:4;9702:17;;;9696:24;9739:10;9787:21;;;9765:20;;;9758:51;;;;9853:17;;;9847:24;9825:20;;;9818:54;;;;9932:4;9920:17;;;9914:24;9940:8;9910:39;9888:20;;;9881:69;9999:4;9987:17;;;9981:24;-1:-1:-1;;;;;10080:23:1;;;10058:20;;;10051:53;;;;10164:4;10152:17;;;10146:24;10142:33;10120:20;;;10113:63;;;;10213:15;;;10207:3;10192:19;;10185:44;10260:3;10245:19;;10238:35;9597:3;9582:19;93890:565:0;9347:932:1;100809:121:0;;;;;;;;;;-1:-1:-1;100809:121:0;;;;;:::i;:::-;;:::i;99212:309::-;;;;;;:::i;:::-;;:::i;100527:186::-;;;;;;;;;;;;;:::i;36804:451::-;;;;;;:::i;:::-;;:::i;63480:468::-;;;;;;;;;;-1:-1:-1;63480:468:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;101039:653::-;;;;;;;;;;-1:-1:-1;101039:653:0;;;;;:::i;:::-;;:::i;29770:172::-;;;;;;;;;;-1:-1:-1;29770:172:0;;;;;:::i;:::-;-1:-1:-1;;;;;29895:25:0;;;29867:4;29895:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;29770:172;92886:125;;;;;;;;;;-1:-1:-1;92981:18:0;;92886:125;;86533:213;;;;;;;;;;-1:-1:-1;86533:213:0;;;;;:::i;:::-;;:::i;92347:389::-;;;;;;;;;;-1:-1:-1;92347:389:0;;;;;:::i;:::-;;:::i;87845:39::-;;;;;;;;;;;;;;;;20568:675;20653:4;-1:-1:-1;;;;;;;;;21001:25:0;;;;:106;;-1:-1:-1;;;;;;;;;;21082:25:0;;;21001:106;:187;;;-1:-1:-1;;;;;;;;;;21163:25:0;;;21001:187;20977:211;20568:675;-1:-1:-1;;20568:675:0:o;21542:108::-;21596:13;21633:5;21626:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21542:108;:::o;28713:234::-;28789:7;28818:16;28826:7;28818;:16::i;:::-;28813:64;;28843:34;;-1:-1:-1;;;28843:34:0;;;;;;;;;;;28813:64;-1:-1:-1;28905:24:0;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;28905:30:0;;28713:234::o;28070:448::-;28163:13;28179:16;28187:7;28179;:16::i;:::-;28163:32;-1:-1:-1;54891:10:0;-1:-1:-1;;;;;28220:28:0;;;28216:187;;28272:44;28289:5;54891:10;29770:172;:::i;28272:44::-;28267:136;;28348:35;;-1:-1:-1;;;28348:35:0;;;;;;;;;;;28267:136;28423:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;;;;;28423:35:0;-1:-1:-1;;;;;28423:35:0;;;;;;;;;28478:28;;28423:24;;28478:28;;;;;;;28148:370;28070:448;;:::o;100288:154::-;85381:13;:11;:13::i;:::-;100353:17:::1;:24:::0;;-1:-1:-1;;100353:24:0::1;100373:4;100353:24;::::0;;100397:33:::1;::::0;::::1;::::0;::::1;::::0;100414:15:::1;::::0;100397:33:::1;:::i;:::-;;;;;;;;100288:154::o:0;96227:183::-;82434:21;:19;:21::i;:::-;96361:37:::1;96375:3;96380:10;96392:5;;96361:13;:37::i;:::-;82486:20:::0;81804:1;83062:7;:22;82867:229;82486:20;96227:183;;;:::o;32736:3069::-;32898:27;32928;32947:7;32928:18;:27::i;:::-;32898:57;;33021:4;-1:-1:-1;;;;;32980:45:0;32996:19;-1:-1:-1;;;;;32980:45:0;;32976:86;;33034:28;;-1:-1:-1;;;33034:28:0;;;;;;;;;;;32976:86;33084:27;31744:24;;;:15;:24;;;;;31988:26;;54891:10;31321:30;;;-1:-1:-1;;;;;30998:28:0;;31299:20;;;31296:56;33282:184;;33379:43;33396:4;54891:10;29770:172;:::i;33379:43::-;33374:92;;33431:35;;-1:-1:-1;;;33431:35:0;;;;;;;;;;;33374:92;-1:-1:-1;;;;;33491:16:0;;33487:52;;33516:23;;-1:-1:-1;;;33516:23:0;;;;;;;;;;;33487:52;33712:15;33709:172;;;33860:1;33839:19;33832:30;33709:172;-1:-1:-1;;;;;34293:24:0;;;;;;;:18;:24;;;;;;34291:26;;-1:-1:-1;;34291:26:0;;;34366:22;;;;;;34364:24;;-1:-1:-1;34364:24:0;;;34716:158;34366:22;-1:-1:-1;;;34716:18:0;:158::i;:::-;34687:26;;;;:17;:26;;;;;:187;;;;-1:-1:-1;;;35006:47:0;;:52;;35002:667;;35115:1;35105:11;;35083:19;35246:30;;;:17;:30;;;;;;:35;;35242:408;;35392:13;;35377:11;:28;35373:254;;35547:30;;;;:17;:30;;;;;:52;;;35373:254;35060:609;35002:667;35728:7;35724:2;-1:-1:-1;;;;;35709:27:0;35718:4;-1:-1:-1;;;;;35709:27:0;-1:-1:-1;;;;;;;;;;;35709:27:0;;;;;;;;;35751:42;32883:2922;;;32736:3069;;;:::o;93096:345::-;85381:13;:11;:13::i;:::-;93246:18:::1;;93226:17;:38;93222:95;;;93290:27;;-1:-1:-1::0;;;93290:27:0::1;;;;;;;;;;;93222:95;93332:18;:38:::0;;;93390:39:::1;::::0;3373:25:1;;;93390:39:0::1;::::0;3361:2:1;3346:18;93390:39:0::1;;;;;;;;93096:345:::0;:::o;99606:257::-;85381:13;:11;:13::i;:::-;99731:33:::1;::::0;99676:21:::1;::::0;99660:13:::1;::::0;99731:10:::1;::::0;99676:21;;99660:13;99731:33;99660:13;99731:33;99676:21;99731:10;:33:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99712:52;;;99784:7;99779:37;;99800:16;;-1:-1:-1::0;;;99800:16:0::1;;;;;;;;;;;99779:37;99836:15;::::0;3373:25:1;;;99836:15:0::1;::::0;3361:2:1;3346:18;99836:15:0::1;;;;;;;;99645:218;;99606:257::o:0;35921:217::-;36087:39;36104:4;36110:2;36114:7;36087:39;;;;;;;;;;;;:16;:39::i;99953:230::-;85381:13;:11;:13::i;:::-;100036:17:::1;::::0;::::1;;100032:60;;;100062:30;;-1:-1:-1::0;;;100062:30:0::1;;;;;;;;;;;100032:60;100107:15;:25;100125:7:::0;;100107:15;:25:::1;:::i;:::-;;100152:19;100163:7;;100152:19;;;;;;;:::i;64131:588::-:0;64295:23;64398:8;64373:22;64398:8;-1:-1:-1;;;;;64469:36:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;64432:73;;64529:9;64524:133;64545:14;64540:1;:19;64524:133;;64605:32;64625:8;;64634:1;64625:11;;;;;;;:::i;:::-;;;;;;;64605:19;:32::i;:::-;64589:10;64600:1;64589:13;;;;;;;;:::i;:::-;;;;;;;;;;:48;64561:3;;64524:133;;;-1:-1:-1;64682:10:0;64131:588;-1:-1:-1;;;;64131:588:0:o;23099:160::-;23171:7;23218:27;23237:7;23218:18;:27::i;101804:515::-;101941:7;;101974:298;101998:11;:18;101994:22;;101974:298;;;102081:11;102093:1;102081:14;;;;;;;;:::i;:::-;;;;;;;;;:35;:14;;;;;:35;;-1:-1:-1;;;;;102081:35:0;;;;;;102068:48;;;;;;;:118;;;102153:11;102165:1;102153:14;;;;;;;;:::i;:::-;;;;;;;;;:33;:14;;;;;:33;;-1:-1:-1;;;;;;;;102153:33:0;;;;;102141:45;;;;102068:118;102042:215;;;102236:1;101804:515;-1:-1:-1;;101804:515:0:o;102042:215::-;102018:3;;;;:::i;:::-;;;;101974:298;;;;102293:14;;-1:-1:-1;;;102293:14:0;;;;;;;;;;;18193:245;18265:7;-1:-1:-1;;;;;18293:19:0;;18289:60;;18321:28;;-1:-1:-1;;;18321:28:0;;;;;;;;;;;18289:60;-1:-1:-1;;;;;;18371:25:0;;;;;:18;:25;;;;;;-1:-1:-1;;;;;18371:55:0;;18193:245::o;86243:111::-;85381:13;:11;:13::i;:::-;86312:30:::1;86339:1;86312:18;:30::i;:::-;86243:111::o:0;94579:1422::-;85381:13;:11;:13::i;:::-;94896:11:::1;:18:::0;94887:27;::::1;94883:54;;94923:14;;-1:-1:-1::0;;;94923:14:0::1;;;;;;;;;;;94883:54;94965:1;94956:5;:10;94952:257;;95057:11;95069:9;95077:1;95069:5:::0;:9:::1;:::i;:::-;95057:22;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;:41:::1;:22;::::0;;::::1;;:41;::::0;-1:-1:-1;;;;;;;;95057:41:0;;::::1;::::0;::::1;95013:85:::0;;::::1;;94987:207;;;95148:26;;-1:-1:-1::0;;;95148:26:0::1;;;;;;;;;;;94987:207;95223:123;95274:20;95313:18;95223:32;:123::i;:::-;95387:4;95361:11;95373:5;95361:18;;;;;;;;:::i;:::-;;;;;;;;;;;:23;;;:30;;;;;-1:-1:-1::0;;;;;95361:30:0::1;;;;;-1:-1:-1::0;;;;;95361:30:0::1;;;;;;95439:11;95406;95418:5;95406:18;;;;;;;;:::i;:::-;;;;;;;;;;;:30;;;:44;;;;;;;;;;;;;;;;;;95497:10;95465:11;95477:5;95465:18;;;;;;;;:::i;:::-;;;;;;;;;;;:29;;:42;;;;95558:14;95522:11;95534:5;95522:18;;;;;;;;:::i;:::-;;;;;;;;;;;:33;;;:50;;;;;;;;;;;;;;;;;;95629:20;95587:11;95599:5;95587:18;;;;;;;;:::i;:::-;;;;;;;;;;;:39;;;:62;;;;;-1:-1:-1::0;;;;;95587:62:0::1;;;;;-1:-1:-1::0;;;;;95587:62:0::1;;;;;;95704:18;95664:11;95676:5;95664:18;;;;;;;;:::i;:::-;;;;;;;;;;;:37;;;:58;;;;;-1:-1:-1::0;;;;;95664:58:0::1;;;;;-1:-1:-1::0;;;;;95664:58:0::1;;;;;;-1:-1:-1::0;;;;;;;;;;;95778:5:0::1;95802:4;95825:11;95855:10;95884:14;95917:20;95956:18;95748:241;;;;;;;;;;;;:::i;:::-;;;;;;;;94579:1422:::0;;;;;;;:::o;68407:984::-;68485:16;68547:19;68585:25;68629:22;68654:16;68664:5;68654:9;:16::i;:::-;68629:41;;68689:25;68731:14;-1:-1:-1;;;;;68717:29:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68717:29:0;;68689:57;;68765:31;;:::i;:::-;68820:9;68815:516;68864:14;68849:11;:29;68815:516;;68920:15;68933:1;68920:12;:15::i;:::-;68908:27;;68962:9;:16;;;69007:8;68958:81;69065:14;;-1:-1:-1;;;;;69065:28:0;;69061:119;;69142:14;;;-1:-1:-1;69061:119:0;69227:5;-1:-1:-1;;;;;69206:26:0;:17;-1:-1:-1;;;;;69206:26:0;;69202:110;;69287:1;69261:8;69270:13;;;;;;69261:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;69202:110;68880:3;;68815:516;;;-1:-1:-1;69356:8:0;;68407:984;-1:-1:-1;;;;;;68407:984:0:o;85523:95::-;85600:6;;-1:-1:-1;;;;;85600:6:0;;85523:95::o;90052:1718::-;85381:13;:11;:13::i;:::-;90164:11:::1;:18:::0;90141:20:::1;90197:95;90221:12;90217:1;:16;90197:95;;;90259:11;:17;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;::::1;-1:-1:-1::0;;90259:17:0;;;;;::::1;;::::0;;-1:-1:-1;;;;;;90259:17:0;;;::::1;::::0;::::1;::::0;;;;::::1;;::::0;;-1:-1:-1;;;;;;90259:17:0;;;;;90235:3;::::1;::::0;::::1;:::i;:::-;;;;90197:95;;;;90323:9;90318:1441;90338:20:::0;;::::1;90318:1441;;;90393:1;90388;:6;90384:288;;90510:9:::0;;90520:5:::1;90524:1;90520::::0;:5:::1;:::i;:::-;90510:16;;;;;;;:::i;:::-;;;;;;:35;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;90449:96:0::1;:9;;90459:1;90449:12;;;;;;;:::i;:::-;;;;;;:33;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;90449:96:0::1;;90419:234;;;90603:26;;-1:-1:-1::0;;;90603:26:0::1;;;;;;;;;;;90419:234;90690:161;90745:9;;90755:1;90745:12;;;;;;;:::i;:::-;;;;;;:33;;;;;;;;;;:::i;:::-;90801:9;;90811:1;90801:12;;;;;;;:::i;:::-;;;;;;:31;;;;;;;;;;:::i;:::-;90690:32;:161::i;:::-;90870:11;90909:444;;;;;;;;90956:9;;90966:1;90956:12;;;;;;;:::i;:::-;:17;::::0;::::1;:12;::::0;;::::1;;:17:::0;;::::1;::::0;-1:-1:-1;90956:17:0::1;:::i;:::-;-1:-1:-1::0;;;;;90909:444:0::1;;;;;91013:9;;91023:1;91013:12;;;;;;;:::i;:::-;;;;;;:24;;;;;;;;;;:::i;:::-;90909:444;;;;;;91076:9;;91086:1;91076:12;;;;;;;:::i;:::-;;;;;;:23;;;90909:444;;;;91142:9;;91152:1;91142:12;;;;;;;:::i;:::-;;;;;;:27;;;;;;;;;;:::i;:::-;90909:444;;;;;;91218:9;;91228:1;91218:12;;;;;;;:::i;:::-;;;;;;:33;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;90909:444:0::1;;;;;91298:9;;91308:1;91298:12;;;;;;;:::i;:::-;;;;;;:31;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;90909:444:0;;::::1;::::0;;;90870:502;;::::1;::::0;;::::1;::::0;;-1:-1:-1;90870:502:0;;;::::1;::::0;;;;;;::::1;::::0;;::::1;;::::0;;;;::::1;::::0;::::1;;-1:-1:-1::0;;;90870:502:0::1;-1:-1:-1::0;;;;;;90870:502:0;;;-1:-1:-1;;;;;90870:502:0;;::::1;::::0;;;;;;;::::1;::::0;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;::::1;-1:-1:-1::0;;;90870:502:0::1;-1:-1:-1::0;;;;;;;;90870:502:0;;;::::1;::::0;::::1;-1:-1:-1::0;;;;;;90870:502:0;;;::::1;::::0;;::::1;::::0;;;;;;;::::1;::::0;;;::::1;;::::0;;-1:-1:-1;;;;;;;;;;;91430:1:0;91454:9;;91430:1;91454:12;;::::1;;;;;:::i;:::-;:17;::::0;::::1;:12;::::0;;::::1;;:17:::0;;::::1;::::0;-1:-1:-1;91454:17:0::1;:::i;:::-;91494:9;;91504:1;91494:12;;;;;;;:::i;:::-;;;;;;:24;;;;;;;;;;:::i;:::-;91541:9;;91551:1;91541:12;;;;;;;:::i;:::-;;;;;;:23;;;91587:9;;91597:1;91587:12;;;;;;;:::i;:::-;;;;;;:27;;;;;;;;;;:::i;:::-;91637:9;;91647:1;91637:12;;;;;;;:::i;:::-;;;;;;:33;;;;;;;;;;:::i;:::-;91693:9;;91703:1;91693:12;;;;;;;:::i;:::-;;;;;;:31;;;;;;;;;;:::i;:::-;91396:347;;;;;;;;;;;;:::i;:::-;;;;;;;;90360:3:::0;::::1;::::0;::::1;:::i;:::-;;;;90318:1441;;;;90126:1644;90052:1718:::0;;:::o;21746:112::-;21802:13;21839:7;21832:14;;;;;:::i;93552:214::-;93698:7;93738:16;93752:1;93738:13;:16::i;65163:2749::-;65322:16;65397:4;65388:5;:13;65384:45;;65410:19;;-1:-1:-1;;;65410:19:0;;;;;;;;;;;65384:45;65448:19;65486:17;65506:14;16583:7;16614:13;;16528:111;65506:14;65486:34;-1:-1:-1;65781:9:0;65774:4;:16;65770:81;;;65822:9;65815:16;;65770:81;65869:25;65897:16;65907:5;65897:9;:16::i;:::-;65869:44;;66103:4;66095:5;:12;66091:306;;;66154:12;;;66193:31;;;66189:119;;;66273:11;66253:31;;66189:119;66109:218;66091:306;;;-1:-1:-1;66376:1:0;66091:306;66415:25;66457:17;-1:-1:-1;;;;;66443:32:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66443:32:0;;66415:60;;66498:17;66519:1;66498:22;66494:86;;66552:8;-1:-1:-1;66545:15:0;;-1:-1:-1;;;66545:15:0;66494:86;66736:31;66770:26;66790:5;66770:19;:26::i;:::-;66736:60;;66815:25;67072:9;:16;;;67067:100;;-1:-1:-1;67133:14:0;;67067:100;67202:5;67185:522;67214:4;67209:1;:9;;:45;;;;;67237:17;67222:11;:32;;67209:45;67185:522;;;67296:15;67309:1;67296:12;:15::i;:::-;67284:27;;67338:9;:16;;;67383:8;67334:81;67441:14;;-1:-1:-1;;;;;67441:28:0;;67437:119;;67518:14;;;-1:-1:-1;67437:119:0;67603:5;-1:-1:-1;;;;;67582:26:0;:17;-1:-1:-1;;;;;67582:26:0;;67578:110;;67663:1;67637:8;67646:13;;;;;;67637:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;67578:110;67256:3;;67185:522;;;-1:-1:-1;;;67804:29:0;;;-1:-1:-1;67811:8:0;;-1:-1:-1;;65163:2749:0;;;;;;:::o;29339:246::-;54891:10;29438:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;29438:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;29438:60:0;;;;;;;;;;29518:55;;540:41:1;;;29438:49:0;;54891:10;29518:55;;513:18:1;29518:55:0;;;;;;;29339:246;;:::o;93890:565::-;94029:20;;:::i;:::-;94153:11;:18;94068:6;;;;94144:27;;94140:90;;94192:22;;-1:-1:-1;;;94192:22:0;;18521:2:1;94192:22:0;;;18503:21:1;18560:2;18540:18;;;18533:30;-1:-1:-1;;;18579:18:1;;;18572:42;18631:18;;94192:22:0;;;;;;;;94140:90;94244:19;94266:34;;;:27;:34;;;;;;;;94301:10;94266:46;;;;;;;;94349:25;;;:18;:25;;;;;;;94397:11;:18;;94266:46;;;;;94294:5;;94397:18;;;;;;:::i;:::-;;;;;;;;;;94389:54;;;;;;;;94397:18;;;;;;;;94389:54;;-1:-1:-1;;;;;94389:54:0;;;;-1:-1:-1;;;94389:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;94389:54:0;;;;;;;-1:-1:-1;;;94389:54:0;;;;;;;;;94417:12;;-1:-1:-1;94417:12:0;-1:-1:-1;93890:565:0;-1:-1:-1;;93890:565:0:o;100809:121::-;85381:13;:11;:13::i;:::-;100894:15:::1;:24;100912:6:::0;;100894:15;:24:::1;:::i;99212:309::-:0;85381:13;:11;:13::i;:::-;99344:3:::1;88957:142;;89030:18;;89024:3;89008:13;17167:12:::0;;16938:7;17151:13;:28;;16877:347;89008:13:::1;:19;;;;:::i;:::-;:40;89004:67;;;89057:14;;-1:-1:-1::0;;;89057:14:0::1;;;;;;;;;;;89004:67;99399:3:::2;99389:13;;:7;;:13;;;;:::i;:::-;99377:9;:25;99373:54;;;99411:16;;-1:-1:-1::0;;;99411:16:0::2;;;;;;;;;;;99373:54;99442:18;99452:2;99456:3;99442:18;;:9;:18::i;:::-;99483:5;::::0;99475:34:::2;::::0;-1:-1:-1;;;;;99483:5:0;;::::2;::::0;99499:9:::2;99475:34:::0;::::2;;;::::0;99483:5:::2;99475:34:::0;99483:5;99475:34;99499:9;99483:5;99475:34;::::2;;;;;;;;;;;;;::::0;::::2;;;;100527:186:::0;100640:13;100686:15;100679:22;;;;;:::i;36804:451::-;37003:31;37016:4;37022:2;37026:7;37003:12;:31::i;:::-;-1:-1:-1;;;;;37053:14:0;;;:19;37049:195;;37096:56;37127:4;37133:2;37137:7;37146:5;37096:30;:56::i;:::-;37091:153;;37184:40;;-1:-1:-1;;;37184:40:0;;;;;;;;;;;63480:468;63564:21;;:::i;:::-;63602:31;;:::i;:::-;16583:7;16614:13;63681:7;:25;63648:111;;63734:9;63480:468;-1:-1:-1;;63480:468:0:o;63648:111::-;63785:21;63798:7;63785:12;:21::i;:::-;63773:33;;63825:9;:16;;;63821:73;;;63869:9;63480:468;-1:-1:-1;;63480:468:0:o;63821:73::-;63915:21;63928:7;63915:12;:21::i;101039:653::-;101175:13;101219:16;101227:7;101219;:16::i;:::-;101214:59;;101244:29;;-1:-1:-1;;;101244:29:0;;;;;;;;;;;101214:59;101294:21;101318:15;101294:39;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101378:7;101372:21;101397:1;101372:26;:308;;;;;;;;;;;;;;;;;101502:7;101540:18;101550:7;101540:9;:18::i;:::-;101589:15;101455:176;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;101348:332;101039:653;-1:-1:-1;;;101039:653:0:o;86533:213::-;85381:13;:11;:13::i;:::-;-1:-1:-1;;;;;86626:22:0;::::1;86618:73;;;::::0;-1:-1:-1;;;86618:73:0;;20403:2:1;86618:73:0::1;::::0;::::1;20385:21:1::0;20442:2;20422:18;;;20415:30;20481:34;20461:18;;;20454:62;-1:-1:-1;;;20532:18:1;;;20525:36;20578:19;;86618:73:0::1;20201:402:1::0;86618:73:0::1;86706:28;86725:8;86706:18;:28::i;:::-;86533:213:::0;:::o;92347:389::-;85381:13;:11;:13::i;:::-;92518:18:::1;;92498:17;:38;92494:119;;;92564:33;;-1:-1:-1::0;;;92564:33:0::1;;;;;;;;;;;92494:119;92627:18;:38:::0;;;92685:39:::1;::::0;3373:25:1;;;92685:39:0::1;::::0;3361:2:1;3346:18;92685:39:0::1;3227:177:1::0;30236:302:0;30301:4;30403:13;;30393:7;:23;30346:161;;;;-1:-1:-1;;30458:26:0;;;;:17;:26;;;;;;-1:-1:-1;;;30458:44:0;:49;;30236:302::o;85716:140::-;54891:10;85784:7;:5;:7::i;:::-;-1:-1:-1;;;;;85784:23:0;;85776:68;;;;-1:-1:-1;;;85776:68:0;;20810:2:1;85776:68:0;;;20792:21:1;;;20829:18;;;20822:30;20888:34;20868:18;;;20861:62;20940:18;;85776:68:0;20608:356:1;82534:317:0;81852:1;82676:7;;:19;82668:63;;;;-1:-1:-1;;;82668:63:0;;21171:2:1;82668:63:0;;;21153:21:1;21210:2;21190:18;;;21183:30;21249:33;21229:18;;;21222:61;21300:18;;82668:63:0;20969:355:1;82668:63:0;81852:1;82821:7;:18;82534:317::o;96502:2435::-;96644:3;88957:142;;89030:18;;89024:3;89008:13;17167:12;;16938:7;17151:13;:28;;16877:347;89008:13;:19;;;;:::i;:::-;:40;89004:67;;;89057:14;;-1:-1:-1;;;89057:14:0;;;;;;;;;;;89004:67;96695:15:::1;96732:26;;:::i;:::-;96779:19;96801:43;96829:14;96801:27;:43::i;:::-;96779:65;;96873:11;96885;96873:24;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;96865:32:::1;::::0;;::::1;::::0;::::1;::::0;;96873:24:::1;::::0;;;::::1;::::0;;::::1;96865:32:::0;;-1:-1:-1;;;;;96865:32:0;::::1;::::0;;;-1:-1:-1;;;96865:32:0;;::::1;;;::::0;;::::1;::::0;;;;;;::::1;::::0;;;;;;;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;;;::::1;-1:-1:-1::0;;;;;96865:32:0;;::::1;::::0;;;;-1:-1:-1;;;96865:32:0;;::::1;;::::0;;;;96962:9:::1;::::0;96865:32;;-1:-1:-1;;96946:230:0::1;;;97023:7;::::0;97010:10;;97009:28:::1;::::0;::::1;::::0;97010:20:::1;::::0;-1:-1:-1;;;;;97010:20:0::1;;:::i;:::-;97009:28;;;;:::i;:::-;96997:9;:40;96993:69;;;97046:16;;-1:-1:-1::0;;;97046:16:0::1;;;;;;;;;;;96993:69;96946:230;;;97119:10:::0;;:16:::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;;;;;97107:28:0::1;:9;:28;97103:57;;;97144:16;;-1:-1:-1::0;;;97144:16:0::1;;;;;;;;;;;97103:57;97249:20;::::0;::::1;::::0;:24:::1;;::::0;97245:180:::1;;97338:20;::::0;::::1;::::0;97298:31:::1;::::0;;;:18:::1;:31;::::0;;;;;:60:::1;::::0;;::::1;::::0;:37:::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;:60;97294:115;;;97388:21;;-1:-1:-1::0;;;97388:21:0::1;;;;;;;;;;;97294:115;97505:18;::::0;:22;97501:168:::1;;97578:18;;97572:3;97552:23;;:17;97566:2;97552:13;:17::i;:::-;:23;;;;:::i;:::-;:44;97548:105;;;97626:27;;-1:-1:-1::0;;;97626:27:0::1;;;;;;;;;;;97548:105;97788:17;::::0;::::1;::::0;:21:::1;;::::0;97784:232:::1;;97930:17;::::0;;::::1;::::0;97856:40:::1;::::0;;;:27:::1;:40:::0;;;;;;-1:-1:-1;;;;;97856:44:0;::::1;::::0;;;;;;;;;;:91:::1;::::0;;::::1;::::0;:50:::1;::::0;97903:3;;97856:44:::1;:50;:::i;:::-;:91;;;97830:170;;;97974:26;;-1:-1:-1::0;;;97974:26:0::1;;;;;;;;;;;97830:170;98138:16;::::0;::::1;::::0;:21;98134:286:::1;;98347:5;:16;;;98206:137;98257:5;;98206:137;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;98299:20:0::1;::::0;-1:-1:-1;;;;;;22011:2:1;21982:15;;;21978:45;98299:20:0::1;::::0;::::1;21966:58:1::0;22040:12;;;-1:-1:-1;98299:20:0::1;::::0;-1:-1:-1;21837:221:1;98299:20:0::1;;;;;;;;;;;;;98289:31;;;;;;98206:24;:137::i;:::-;:157;98180:224;;98390:14;;-1:-1:-1::0;;;98390:14:0::1;;;;;;;;;;;98180:224;98440:40;::::0;;;:27:::1;:40;::::0;;;;;;;-1:-1:-1;;;;;98440:44:0;::::1;::::0;;;;;;;:51;;98488:3;;98440:40;:51:::1;::::0;98488:3;;98440:51:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;98541:3;98506:38;;:18;:31;98525:11;98506:31;;;;;;;;;;;;:38;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;98559:18:0::1;::::0;-1:-1:-1;98569:2:0;98559:18:::1;::::0;::::1;:9;:18::i;:::-;98614:9;::::0;98601:10;;-1:-1:-1;;;;;98601:22:0::1;;98598:328;;;98653:5;::::0;98669:7:::1;::::0;-1:-1:-1;;;;;98653:5:0;;::::1;::::0;98645:38:::1;::::0;98669:13:::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;98645:38;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;98710:7;:5;:7::i;:::-;-1:-1:-1::0;;;;;98702:25:0::1;:54;98751:3;98741:13;;:7;;:13;;;;:::i;:::-;98728:27;::::0;:9:::1;:27;:::i;:::-;98702:54;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;98598:328;;;98805:5;::::0;-1:-1:-1;;;;;98805:5:0::1;98797:39;98821:14;98833:2;98821:9;:14;:::i;:::-;98797:39;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;98863:7;:5;:7::i;:::-;-1:-1:-1::0;;;;;98855:25:0::1;:55;98894:14;98906:2;98894:9;:14;:::i;:::-;98881:28;::::0;:9:::1;:28;:::i;:::-;98855:55;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;98598:328;96649:2288;;;96502:2435:::0;;;;;:::o;24378:1379::-;24445:7;24484;24602:13;;24595:4;:20;24591:1087;;;24644:14;24661:23;;;:17;:23;;;;;;;-1:-1:-1;;;24758:24:0;;:29;;24754:901;;25463:121;25470:6;25480:1;25470:11;25463:121;;-1:-1:-1;;;25545:6:0;25527:25;;;;:17;:25;;;;;;25463:121;;24754:901;24617:1061;24591:1087;25714:31;;-1:-1:-1;;;25714:31:0;;;;;;;;;;;26365:478;26796:11;26771:23;26767:41;26764:52;-1:-1:-1;;;;;26614:28:0;;;;26754:63;;26365:478::o;86930:207::-;87027:6;;;-1:-1:-1;;;;;87048:17:0;;;-1:-1:-1;;;;;;87048:17:0;;;;;;;87085:40;;87027:6;;;87048:17;87027:6;;87085:40;;87008:16;;87085:40;86993:144;86930:207;:::o;102460:198::-;102605:3;-1:-1:-1;;;;;102596:12:0;:5;-1:-1:-1;;;;;102596:12:0;;102592:54;;102617:29;;-1:-1:-1;;;102617:29:0;;;;;;;;;;;102592:54;102460:198;;:::o;23762:169::-;23830:21;;:::i;:::-;23894:24;;;;:17;:24;;;;;;23875:44;;:18;:44::i;18540:186::-;-1:-1:-1;;;;;18633:25:0;18601:7;18633:25;;;:18;:25;;11878:2;18633:25;;;;;:50;;-1:-1:-1;;;;;18632:82:0;;18540:186::o;48016:120::-;48097:27;48107:2;48111:8;48097:27;;;;;;;;;;;;:9;:27::i;39571:792::-;39779:88;;-1:-1:-1;;;39779:88:0;;39754:4;;-1:-1:-1;;;;;39779:45:0;;;;;:88;;54891:10;;39846:4;;39852:7;;39861:5;;39779:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39779:88:0;;;;;;;;-1:-1:-1;;39779:88:0;;;;;;;;;;;;:::i;:::-;;;39775:577;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40082:6;:13;40099:1;40082:18;40078:259;;40132:40;;-1:-1:-1;;;40132:40:0;;;;;;;;;;;40078:259;40287:6;40281:13;40272:6;40268:2;40264:15;40257:38;39775:577;-1:-1:-1;;;;;;39950:64:0;-1:-1:-1;;;39950:64:0;;-1:-1:-1;39571:792:0;;;;;;:::o;23472:174::-;23542:21;;:::i;:::-;23587:47;23606:27;23625:7;23606:18;:27::i;:::-;23587:18;:47::i;55035:1893::-;55100:17;55558:4;55551;55545:11;55541:22;55658:1;55652:4;55645:15;55741:4;55738:1;55734:12;55727:19;;;55831:1;55826:3;55819:14;55947:3;56206:5;56188:464;56258:1;56253:3;56249:11;56242:18;;56441:2;56435:4;56431:13;56427:2;56423:22;56418:3;56410:36;56543:2;56533:13;;56608:25;56188:464;56608:25;-1:-1:-1;56690:13:0;;;-1:-1:-1;;56813:14:0;;;56883:19;;;56813:14;55035:1893;-1:-1:-1;55035:1893:0:o;71733:320::-;71816:7;71863:4;71816:7;71882:126;71906:5;:12;71902:1;:16;71882:126;;;71959:33;71969:12;71983:5;71989:1;71983:8;;;;;;;;:::i;:::-;;;;;;;71959:9;:33::i;:::-;71944:48;-1:-1:-1;71920:3:0;;;;:::i;:::-;;;;71882:126;;;-1:-1:-1;72029:12:0;71733:320;-1:-1:-1;;;71733:320:0:o;25876:386::-;25942:31;;:::i;:::-;-1:-1:-1;;;;;25990:41:0;;;;-1:-1:-1;;;;;12447:3:0;26080:33;;;26046:68;:24;;;:68;-1:-1:-1;;;26148:24:0;;:29;;26129:16;;;:48;13016:3;26221:28;;;;26192:19;;;:58;25990:9;25876:386::o;47143:769::-;47294:19;47300:2;47304:8;47294:5;:19::i;:::-;-1:-1:-1;;;;;47367:14:0;;;:19;47363:523;;47411:11;47425:13;47477:14;;;47514:249;47549:62;47588:1;47592:2;47596:7;;;;;;47605:5;47549:30;:62::i;:::-;47544:175;;47651:40;;-1:-1:-1;;;47651:40:0;;;;;;;;;;;47544:175;47758:3;47750:5;:11;47514:249;;47853:3;47836:13;;:20;47832:34;;47858:8;;;47832:34;47388:498;;47143:769;;;:::o;79393:157::-;79456:7;79491:1;79487;:5;:51;;79634:13;79740:15;;;79780:4;79773:15;;;79831:4;79815:21;;79487:51;;;-1:-1:-1;79634:13:0;79740:15;;;79780:4;79773:15;79831:4;79815:21;;;79393:157::o;40889:3222::-;40966:20;40989:13;;;41021;;;41017:44;;41043:18;;-1:-1:-1;;;41043:18:0;;;;;;;;;;;41017:44;-1:-1:-1;;;;;41601:22:0;;;;;;:18;:22;;11878:2;41601:22;;:71;;-1:-1:-1;;;;;41627:45:0;;41601:71;;;41977:151;41601:22;-1:-1:-1;27271:15:0;;27245:24;27241:46;41977:18;:151::i;:::-;41943:31;;;;:17;:31;;;;;:185;;;;-1:-1:-1;;;;;42762:25:0;;;42202:23;;;;41961:12;;42762:25;;-1:-1:-1;;;;;;;;;;;41943:31:0;;42860:363;43573:1;43559:12;43555:20;43509:374;43618:3;43609:7;43606:16;43509:374;;43852:7;43842:8;43839:1;-1:-1:-1;;;;;;;;;;;43809:1:0;43806;43801:59;43675:1;43662:15;43509:374;;;43513:85;43924:8;43936:1;43924:13;43920:45;;43946:19;;-1:-1:-1;;;43946:19:0;;;;;;;;;;;43920:45;43990:13;:19;-1:-1:-1;96227:183:0;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:::-;897:3;935:5;929:12;962:6;957:3;950:19;978:63;1034:6;1027:4;1022:3;1018:14;1011:4;1004:5;1000:16;978:63;:::i;:::-;1095:2;1074:15;-1:-1:-1;;1070:29:1;1061:39;;;;1102:4;1057:50;;855:258;-1:-1:-1;;855:258:1:o;1118:220::-;1267:2;1256:9;1249:21;1230:4;1287:45;1328:2;1317:9;1313:18;1305:6;1287:45;:::i;1343:180::-;1402:6;1455:2;1443:9;1434:7;1430:23;1426:32;1423:52;;;1471:1;1468;1461:12;1423:52;-1:-1:-1;1494:23:1;;1343:180;-1:-1:-1;1343:180:1:o;1736:173::-;1804:20;;-1:-1:-1;;;;;1853:31:1;;1843:42;;1833:70;;1899:1;1896;1889:12;1833:70;1736:173;;;:::o;1914:254::-;1982:6;1990;2043:2;2031:9;2022:7;2018:23;2014:32;2011:52;;;2059:1;2056;2049:12;2011:52;2082:29;2101:9;2082:29;:::i;:::-;2072:39;2158:2;2143:18;;;;2130:32;;-1:-1:-1;;;1914:254:1:o;2173:163::-;2240:20;;2300:10;2289:22;;2279:33;;2269:61;;2326:1;2323;2316:12;2341:367;2404:8;2414:6;2468:3;2461:4;2453:6;2449:17;2445:27;2435:55;;2486:1;2483;2476:12;2435:55;-1:-1:-1;2509:20:1;;-1:-1:-1;;;;;2541:30:1;;2538:50;;;2584:1;2581;2574:12;2538:50;2621:4;2613:6;2609:17;2597:29;;2681:3;2674:4;2664:6;2661:1;2657:14;2649:6;2645:27;2641:38;2638:47;2635:67;;;2698:1;2695;2688:12;2635:67;2341:367;;;;;:::o;2713:509::-;2807:6;2815;2823;2876:2;2864:9;2855:7;2851:23;2847:32;2844:52;;;2892:1;2889;2882:12;2844:52;2915:28;2933:9;2915:28;:::i;:::-;2905:38;-1:-1:-1;2994:2:1;2979:18;;2966:32;-1:-1:-1;;;;;3010:30:1;;3007:50;;;3053:1;3050;3043:12;3007:50;3092:70;3154:7;3145:6;3134:9;3130:22;3092:70;:::i;:::-;2713:509;;3181:8;;-1:-1:-1;3066:96:1;;-1:-1:-1;;;;2713:509:1:o;3409:328::-;3486:6;3494;3502;3555:2;3543:9;3534:7;3530:23;3526:32;3523:52;;;3571:1;3568;3561:12;3523:52;3594:29;3613:9;3594:29;:::i;:::-;3584:39;;3642:38;3676:2;3665:9;3661:18;3642:38;:::i;:::-;3632:48;;3727:2;3716:9;3712:18;3699:32;3689:42;;3409:328;;;;;:::o;3742:592::-;3813:6;3821;3874:2;3862:9;3853:7;3849:23;3845:32;3842:52;;;3890:1;3887;3880:12;3842:52;3917:23;;-1:-1:-1;;;;;3989:14:1;;;3986:34;;;4016:1;4013;4006:12;3986:34;4054:6;4043:9;4039:22;4029:32;;4099:7;4092:4;4088:2;4084:13;4080:27;4070:55;;4121:1;4118;4111:12;4070:55;4161:2;4148:16;4187:2;4179:6;4176:14;4173:34;;;4203:1;4200;4193:12;4173:34;4248:7;4243:2;4234:6;4230:2;4226:15;4222:24;4219:37;4216:57;;;4269:1;4266;4259:12;4216:57;4300:2;4292:11;;;;;4322:6;;-1:-1:-1;3742:592:1;;-1:-1:-1;;;;3742:592:1:o;4339:437::-;4425:6;4433;4486:2;4474:9;4465:7;4461:23;4457:32;4454:52;;;4502:1;4499;4492:12;4454:52;4529:23;;-1:-1:-1;;;;;4564:30:1;;4561:50;;;4607:1;4604;4597:12;4561:50;4646:70;4708:7;4699:6;4688:9;4684:22;4646:70;:::i;:::-;4735:8;;4620:96;;-1:-1:-1;4339:437:1;-1:-1:-1;;;;4339:437:1:o;4781:349::-;4865:12;;-1:-1:-1;;;;;4861:38:1;4849:51;;4953:4;4942:16;;;4936:23;-1:-1:-1;;;;;4932:48:1;4916:14;;;4909:72;4969:2;5033:16;;;5027:23;5020:31;5013:39;4997:14;;;4990:63;5106:4;5095:16;;;5089:23;5114:8;5085:38;5069:14;;5062:62;4781:349::o;5135:720::-;5366:2;5418:21;;;5488:13;;5391:18;;;5510:22;;;5337:4;;5366:2;5589:15;;;;5563:2;5548:18;;;5337:4;5632:197;5646:6;5643:1;5640:13;5632:197;;;5695:52;5743:3;5734:6;5728:13;5695:52;:::i;:::-;5804:15;;;;5776:4;5767:14;;;;;5668:1;5661:9;5632:197;;5860:171;5927:20;;-1:-1:-1;;;;;5976:30:1;;5966:41;;5956:69;;6021:1;6018;6011:12;6036:184;6094:6;6147:2;6135:9;6126:7;6122:23;6118:32;6115:52;;;6163:1;6160;6153:12;6115:52;6186:28;6204:9;6186:28;:::i;6225:186::-;6284:6;6337:2;6325:9;6316:7;6312:23;6308:32;6305:52;;;6353:1;6350;6343:12;6305:52;6376:29;6395:9;6376:29;:::i;6416:171::-;6483:20;;-1:-1:-1;;;;;6532:30:1;;6522:41;;6512:69;;6577:1;6574;6567:12;6592:161;6659:20;;6719:8;6708:20;;6698:31;;6688:59;;6743:1;6740;6733:12;6758:612;6866:6;6874;6882;6890;6898;6906;6914;6967:3;6955:9;6946:7;6942:23;6938:33;6935:53;;;6984:1;6981;6974:12;6935:53;7020:9;7007:23;6997:33;;7049:37;7082:2;7071:9;7067:18;7049:37;:::i;:::-;7039:47;;7105:37;7138:2;7127:9;7123:18;7105:37;:::i;:::-;7095:47;;7189:2;7178:9;7174:18;7161:32;7151:42;;7212:38;7245:3;7234:9;7230:19;7212:38;:::i;:::-;7202:48;;7269:38;7302:3;7291:9;7287:19;7269:38;:::i;:::-;7259:48;;7326:38;7359:3;7348:9;7344:19;7326:38;:::i;:::-;7316:48;;6758:612;;;;;;;;;;:::o;7375:632::-;7546:2;7598:21;;;7668:13;;7571:18;;;7690:22;;;7517:4;;7546:2;7769:15;;;;7743:2;7728:18;;;7517:4;7812:169;7826:6;7823:1;7820:13;7812:169;;;7887:13;;7875:26;;7956:15;;;;7921:12;;;;7848:1;7841:9;7812:169;;8012:651;8131:6;8139;8192:2;8180:9;8171:7;8167:23;8163:32;8160:52;;;8208:1;8205;8198:12;8160:52;8235:23;;-1:-1:-1;;;;;8307:14:1;;;8304:34;;;8334:1;8331;8324:12;8304:34;8372:6;8361:9;8357:22;8347:32;;8417:7;8410:4;8406:2;8402:13;8398:27;8388:55;;8439:1;8436;8429:12;8388:55;8479:2;8466:16;8505:2;8497:6;8494:14;8491:34;;;8521:1;8518;8511:12;8491:34;8577:7;8572:2;8564:4;8556:6;8552:17;8548:2;8544:26;8540:35;8537:48;8534:68;;;8598:1;8595;8588:12;8668:322;8745:6;8753;8761;8814:2;8802:9;8793:7;8789:23;8785:32;8782:52;;;8830:1;8827;8820:12;8782:52;8853:29;8872:9;8853:29;:::i;:::-;8843:39;8929:2;8914:18;;8901:32;;-1:-1:-1;8980:2:1;8965:18;;;8952:32;;8668:322;-1:-1:-1;;;8668:322:1:o;8995:347::-;9060:6;9068;9121:2;9109:9;9100:7;9096:23;9092:32;9089:52;;;9137:1;9134;9127:12;9089:52;9160:29;9179:9;9160:29;:::i;:::-;9150:39;;9239:2;9228:9;9224:18;9211:32;9286:5;9279:13;9272:21;9265:5;9262:32;9252:60;;9308:1;9305;9298:12;9252:60;9331:5;9321:15;;;8995:347;;;;;:::o;10284:258::-;10351:6;10359;10412:2;10400:9;10391:7;10387:23;10383:32;10380:52;;;10428:1;10425;10418:12;10380:52;10451:28;10469:9;10451:28;:::i;:::-;10441:38;;10498;10532:2;10521:9;10517:18;10498:38;:::i;:::-;10488:48;;10284:258;;;;;:::o;10547:127::-;10608:10;10603:3;10599:20;10596:1;10589:31;10639:4;10636:1;10629:15;10663:4;10660:1;10653:15;10679:1138;10774:6;10782;10790;10798;10851:3;10839:9;10830:7;10826:23;10822:33;10819:53;;;10868:1;10865;10858:12;10819:53;10891:29;10910:9;10891:29;:::i;:::-;10881:39;;10939:38;10973:2;10962:9;10958:18;10939:38;:::i;:::-;10929:48;-1:-1:-1;11024:2:1;11009:18;;10996:32;;-1:-1:-1;11079:2:1;11064:18;;11051:32;-1:-1:-1;;;;;11132:14:1;;;11129:34;;;11159:1;11156;11149:12;11129:34;11197:6;11186:9;11182:22;11172:32;;11242:7;11235:4;11231:2;11227:13;11223:27;11213:55;;11264:1;11261;11254:12;11213:55;11300:2;11287:16;11322:2;11318;11315:10;11312:36;;;11328:18;;:::i;:::-;11403:2;11397:9;11371:2;11457:13;;-1:-1:-1;;11453:22:1;;;11477:2;11449:31;11445:40;11433:53;;;11501:18;;;11521:22;;;11498:46;11495:72;;;11547:18;;:::i;:::-;11587:10;11583:2;11576:22;11622:2;11614:6;11607:18;11662:7;11657:2;11652;11648;11644:11;11640:20;11637:33;11634:53;;;11683:1;11680;11673:12;11634:53;11739:2;11734;11730;11726:11;11721:2;11713:6;11709:15;11696:46;11784:1;11779:2;11774;11766:6;11762:15;11758:24;11751:35;11805:6;11795:16;;;;;;;10679:1138;;;;;;;:::o;11822:264::-;12016:3;12001:19;;12029:51;12005:9;12062:6;12029:51;:::i;12091:260::-;12159:6;12167;12220:2;12208:9;12199:7;12195:23;12191:32;12188:52;;;12236:1;12233;12226:12;12188:52;12259:29;12278:9;12259:29;:::i;12356:380::-;12435:1;12431:12;;;;12478;;;12499:61;;12553:4;12545:6;12541:17;12531:27;;12499:61;12606:2;12598:6;12595:14;12575:18;12572:38;12569:161;;12652:10;12647:3;12643:20;12640:1;12633:31;12687:4;12684:1;12677:15;12715:4;12712:1;12705:15;12569:161;;12356:380;;;:::o;12867:963::-;12976:4;13005:2;13034;13023:9;13016:21;13057:1;13090:6;13084:13;13120:36;13146:9;13120:36;:::i;:::-;13192:6;13187:2;13176:9;13172:18;13165:34;13218:2;13239:1;13271:2;13260:9;13256:18;13288:1;13283:158;;;;13455:1;13450:354;;;;13249:555;;13283:158;-1:-1:-1;;13331:24:1;;13311:18;;;13304:52;13409:14;;13402:22;13399:1;13395:30;13380:46;;13376:55;;;-1:-1:-1;13283:158:1;;13450:354;13481:6;13478:1;13471:17;13529:2;13526:1;13516:16;13554:1;13568:180;13582:6;13579:1;13576:13;13568:180;;;13675:14;;13651:17;;;13647:26;;13640:50;13718:16;;;;13597:10;;13568:180;;;13772:17;;13768:26;;;-1:-1:-1;;13249:555:1;-1:-1:-1;13821:3:1;;12867:963;-1:-1:-1;;;;;;;;12867:963:1:o;14045:545::-;14147:2;14142:3;14139:11;14136:448;;;14183:1;14208:5;14204:2;14197:17;14253:4;14249:2;14239:19;14323:2;14311:10;14307:19;14304:1;14300:27;14294:4;14290:38;14359:4;14347:10;14344:20;14341:47;;;-1:-1:-1;14382:4:1;14341:47;14437:2;14432:3;14428:12;14425:1;14421:20;14415:4;14411:31;14401:41;;14492:82;14510:2;14503:5;14500:13;14492:82;;;14555:17;;;14536:1;14525:13;14492:82;;14766:1206;-1:-1:-1;;;;;14882:27:1;;14879:53;;;14912:18;;:::i;:::-;14941:94;15031:3;14991:38;15023:4;15017:11;14991:38;:::i;:::-;14985:4;14941:94;:::i;:::-;15061:1;15086:2;15081:3;15078:11;15103:1;15098:616;;;;15758:1;15775:3;15772:93;;;-1:-1:-1;15831:19:1;;;15818:33;15772:93;-1:-1:-1;;14723:1:1;14719:11;;;14715:24;14711:29;14701:40;14747:1;14743:11;;;14698:57;15878:78;;15071:895;;15098:616;12814:1;12807:14;;;12851:4;12838:18;;-1:-1:-1;;15134:17:1;;;15235:9;15257:229;15271:7;15268:1;15265:14;15257:229;;;15360:19;;;15347:33;15332:49;;15467:4;15452:20;;;;15420:1;15408:14;;;;15287:12;15257:229;;;15261:3;15514;15505:7;15502:16;15499:159;;;15638:1;15634:6;15628:3;15622;15619:1;15615:11;15611:21;15607:34;15603:39;15590:9;15585:3;15581:19;15568:33;15564:79;15556:6;15549:95;15499:159;;;15701:1;15695:3;15692:1;15688:11;15684:19;15678:4;15671:33;15071:895;;14766:1206;;;:::o;15977:390::-;16136:2;16125:9;16118:21;16175:6;16170:2;16159:9;16155:18;16148:34;16232:6;16224;16219:2;16208:9;16204:18;16191:48;16288:1;16259:22;;;16283:2;16255:31;;;16248:42;;;;16351:2;16330:15;;;-1:-1:-1;;16326:29:1;16311:45;16307:54;;15977:390;-1:-1:-1;15977:390:1:o;16372:127::-;16433:10;16428:3;16424:20;16421:1;16414:31;16464:4;16461:1;16454:15;16488:4;16485:1;16478:15;16504:127;16565:10;16560:3;16556:20;16553:1;16546:31;16596:4;16593:1;16586:15;16620:4;16617:1;16610:15;16636:135;16675:3;16696:17;;;16693:43;;16716:18;;:::i;:::-;-1:-1:-1;16763:1:1;16752:13;;16636:135::o;16776:125::-;16816:4;16844:1;16841;16838:8;16835:34;;;16849:18;;:::i;:::-;-1:-1:-1;16886:9:1;;16776:125::o;16906:709::-;17211:25;;;-1:-1:-1;;;;;17272:31:1;;;;17267:2;17252:18;;17245:59;17352:10;17340:23;;;;17335:2;17320:18;;17313:51;17395:2;17380:18;;17373:34;;;;17456:8;17444:21;17438:3;17423:19;;17416:50;-1:-1:-1;;;;;17540:15:1;;;17534:3;17519:19;;17512:44;17593:15;17587:3;17572:19;;17565:44;17198:3;17183:19;;16906:709::o;17620:127::-;17681:10;17676:3;17672:20;17669:1;17662:31;17712:4;17709:1;17702:15;17736:4;17733:1;17726:15;17752:184;17810:6;17863:2;17851:9;17842:7;17838:23;17834:32;17831:52;;;17879:1;17876;17869:12;17831:52;17902:28;17920:9;17902:28;:::i;17941:184::-;17999:6;18052:2;18040:9;18031:7;18027:23;18023:32;18020:52;;;18068:1;18065;18058:12;18020:52;18091:28;18109:9;18091:28;:::i;18130:184::-;18188:6;18241:2;18229:9;18220:7;18216:23;18212:32;18209:52;;;18257:1;18254;18247:12;18209:52;18280:28;18298:9;18280:28;:::i;18660:128::-;18700:3;18731:1;18727:6;18724:1;18721:13;18718:39;;;18737:18;;:::i;:::-;-1:-1:-1;18773:9:1;;18660:128::o;18793:168::-;18833:7;18899:1;18895;18891:6;18887:14;18884:1;18881:21;18876:1;18869:9;18862:17;18858:45;18855:71;;;18906:18;;:::i;:::-;-1:-1:-1;18946:9:1;;18793:168::o;18966:1230::-;19190:3;19228:6;19222:13;19254:4;19267:51;19311:6;19306:3;19301:2;19293:6;19289:15;19267:51;:::i;:::-;19381:13;;19340:16;;;;19403:55;19381:13;19340:16;19425:15;;;19403:55;:::i;:::-;19547:13;;19480:20;;;19520:1;;19585:36;19547:13;19585:36;:::i;:::-;19640:1;19657:18;;;19684:141;;;;19839:1;19834:337;;;;19650:521;;19684:141;-1:-1:-1;;19719:24:1;;19705:39;;19796:16;;19789:24;19775:39;;19764:51;;;-1:-1:-1;19684:141:1;;19834:337;19865:6;19862:1;19855:17;19913:2;19910:1;19900:16;19938:1;19952:169;19966:8;19963:1;19960:15;19952:169;;;20048:14;;20033:13;;;20026:37;20091:16;;;;19983:10;;19952:169;;;19956:3;;20152:8;20145:5;20141:20;20134:27;;19650:521;-1:-1:-1;20187:3:1;;18966:1230;-1:-1:-1;;;;;;;;;;18966:1230:1:o;21329:270::-;21368:7;-1:-1:-1;;;;;21438:10:1;;;21468;;;21501:11;;21494:19;21523:12;;;21515:21;;21490:47;21487:73;;;21540:18;;:::i;:::-;21580:13;;21329:270;-1:-1:-1;;;;21329:270:1:o;21604:228::-;21643:3;21671:10;21708:2;21705:1;21701:10;21738:2;21735:1;21731:10;21769:3;21765:2;21761:12;21756:3;21753:21;21750:47;;;21777:18;;:::i;:::-;21813:13;;21604:228;-1:-1:-1;;;;21604:228:1:o;22063:217::-;22103:1;22129;22119:132;;22173:10;22168:3;22164:20;22161:1;22154:31;22208:4;22205:1;22198:15;22236:4;22233:1;22226:15;22119:132;-1:-1:-1;22265:9:1;;22063:217::o;22285:489::-;-1:-1:-1;;;;;22554:15:1;;;22536:34;;22606:15;;22601:2;22586:18;;22579:43;22653:2;22638:18;;22631:34;;;22701:3;22696:2;22681:18;;22674:31;;;22479:4;;22722:46;;22748:19;;22740:6;22722:46;:::i;:::-;22714:54;22285:489;-1:-1:-1;;;;;;22285:489:1:o;22779:249::-;22848:6;22901:2;22889:9;22880:7;22876:23;22872:32;22869:52;;;22917:1;22914;22907:12;22869:52;22949:9;22943:16;22968:30;22992:5;22968:30;:::i

Swarm Source

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