ETH Price: $3,390.14 (-1.52%)
Gas: 2 Gwei

Token

Hoodiemigos (HOOD)
 

Overview

Max Total Supply

2,373 HOOD

Holders

226

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
worldwide.eth
Balance
1 HOOD
0x43e730ddea1192d1b455f38eb0f43c61ac4f8f26
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:
Hoodiemigos

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-04
*/

// 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 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 Hoodiemigos 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 = 3333;

    // 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://bafybeidad6fozuzcdnp3njy4ujphl3ak2o2rjeydydelq65zypkiznyb3e/";

    // 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("Hoodiemigos", "HOOD") {
        _mintStages.push(MintStageInfo({cost: 0, walletLimit: 5, merkleRoot: 0x0, maxStageSupply: 0, startTimeUnixSeconds: 1696364015, endTimeUnixSeconds: 1701548015}));
    }



    /**
     * @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 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":[{"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":"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":"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"}]

610d05600b556005600c55600d80546001600160a01b031916739e6865daeeedd093ea4a4f6c9bfbbb0ce6bc8b17179055651e0369471000600e5566071afd498d0000600f5561010060405260436080818152906200343260a0396010906200006990826200036b565b50604080518082019091526005815264173539b7b760d91b60208201526011906200009590826200036b565b50348015620000a357600080fd5b506040518060400160405280600b81526020016a486f6f6469656d69676f7360a81b815250604051806040016040528060048152602001631213d3d160e21b8152508160029081620000f691906200036b565b5060036200010582826200036b565b50506000805550620001173362000274565b600160098190556040805160c08101825260008082526005602083019081529282018181526060830182815263651c75ef6080850190815263656b8fef60a08601908152601280549889018155909452935160039096027fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec344481018054965163ffffffff166a0100000000000000000000026001600160701b03199097166001600160501b03989098169790971795909517909555517fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec344584015592517fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34469092018054915193516001600160401b039081166b01000000000000000000000002600160581b600160981b0319959091166301000000026001600160581b031990931662ffffff9490941693909317919091179290921617905562000437565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620002f157607f821691505b6020821081036200031257634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200036657600081815260208120601f850160051c81016020861015620003415750805b601f850160051c820191505b8181101562000362578281556001016200034d565b5050505b505050565b81516001600160401b03811115620003875762000387620002c6565b6200039f81620003988454620002dc565b8462000318565b602080601f831160018114620003d75760008415620003be5750858301515b600019600386901b1c1916600185901b17855562000362565b600085815260208120601f198616915b828110156200040857888601518255948401946001909101908401620003e7565b5085821015620004275787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b612feb80620004476000396000f3fe60806040526004361061019f5760003560e01c806301ffc9a7146101a457806306fdde03146101d9578063081812fc146101fb578063095ea7b314610233578063107af24b1461024857806318160ddd1461025b57806323b872dd1461027e578063372992e4146102915780633ccfd60b146102b157806342842e0e146102c657806342cde4e8146102d95780634b1c53b4146102ef5780635bbb2177146103045780636352211e1461033157806367808a341461035157806370a082311461037157806370da24ee14610391578063715018a6146103a657806373e1607e146103bb5780638462151c146103db5780638da5cb5b146104085780638dcdb09d1461041d57806395d89b411461043d57806397cf84fc1461045257806399a2557a14610472578063a22cb46514610492578063a3759f60146104b2578063aac5ab1f1461054e578063b88d4fde14610561578063c23dc68f14610574578063c87b56dd146105a1578063e985e9c5146105c1578063efdaa2ec1461060a578063f2fde38b1461061f578063f8d096961461063f578063fa4271771461065f575b600080fd5b3480156101b057600080fd5b506101c46101bf36600461266c565b610675565b60405190151581526020015b60405180910390f35b3480156101e557600080fd5b506101ee6106c7565b6040516101d091906126e1565b34801561020757600080fd5b5061021b6102163660046126f4565b610759565b6040516001600160a01b0390911681526020016101d0565b610246610241366004612729565b61079d565b005b6102466102563660046127b2565b61083d565b34801561026757600080fd5b50600154600054035b6040519081526020016101d0565b61024661028c366004612804565b610860565b34801561029d57600080fd5b506102466102ac3660046126f4565b6109e6565b3480156102bd57600080fd5b50610246610a4d565b6102466102d4366004612804565b610af7565b3480156102e557600080fd5b50610270600f5481565b3480156102fb57600080fd5b50600b54610270565b34801561031057600080fd5b5061032461031f366004612840565b610b12565b6040516101d091906128bd565b34801561033d57600080fd5b5061021b61034c3660046126f4565b610bc4565b34801561035d57600080fd5b5061027061036c366004612916565b610bcf565b34801561037d57600080fd5b5061027061038c366004612931565b610c97565b34801561039d57600080fd5b50601254610270565b3480156103b257600080fd5b50610246610ce5565b3480156103c757600080fd5b506102466103d6366004612976565b610cf9565b3480156103e757600080fd5b506103fb6103f6366004612931565b610f5c565b6040516101d091906129ee565b34801561041457600080fd5b5061021b611042565b34801561042957600080fd5b50610246610438366004612a26565b611051565b34801561044957600080fd5b506101ee6114e5565b34801561045e57600080fd5b5061027061046d366004612931565b6114f4565b34801561047e57600080fd5b506103fb61048d366004612a9a565b6114ff565b34801561049e57600080fd5b506102466104ad366004612acd565b611678565b3480156104be57600080fd5b506104d26104cd3660046126f4565b6116e4565b6040805184516001600160501b0316815260208086015163ffffffff90811691830191909152858301519282019290925260608086015162ffffff16908201526080808601516001600160401b039081169183019190915260a095860151169481019490945290911660c083015260e0820152610100016101d0565b61024661055c366004612b09565b611803565b61024661056f366004612b52565b6118c9565b34801561058057600080fd5b5061059461058f3660046126f4565b61190d565b6040516101d09190612c2d565b3480156105ad57600080fd5b506101ee6105bc3660046126f4565b611950565b3480156105cd57600080fd5b506101c46105dc366004612c3b565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561061657600080fd5b50600c54610270565b34801561062b57600080fd5b5061024661063a366004612931565b611a59565b34801561064b57600080fd5b5061024661065a3660046126f4565b611ad2565b34801561066b57600080fd5b50610270600e5481565b60006301ffc9a760e01b6001600160e01b0319831614806106a657506380ac58cd60e01b6001600160e01b03198316145b806106c15750635b5e139f60e01b6001600160e01b03198316145b92915050565b6060600280546106d690612c57565b80601f016020809104026020016040519081016040528092919081815260200182805461070290612c57565b801561074f5780601f106107245761010080835404028352916020019161074f565b820191906000526020600020905b81548152906001019060200180831161073257829003601f168201915b5050505050905090565b600061076482611b32565b610781576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b60006107a882610bc4565b9050336001600160a01b038216146107e1576107c481336105dc565b6107e1576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b610845611b59565b61085183338484611bb2565b61085b6001600955565b505050565b600061086b826120dc565b9050836001600160a01b0316816001600160a01b03161461089e5760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b038816909114176108eb576108ce86336105dc565b6108eb57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b03851661091257604051633a954ecd60e21b815260040160405180910390fd5b801561091d57600082555b6001600160a01b0386811660009081526005602052604080822080546000190190559187168152208054600101905561095a85600160e11b612143565b600085815260046020526040812091909155600160e11b841690036109af576001840160008181526004602052604081205490036109ad5760005481146109ad5760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b0316600080516020612f7683398151915260405160405180910390a4505050505050565b6109ee612158565b600b54811115610a1157604051630590c51360e01b815260040160405180910390fd5b600c8190556040518181527f5307de8ad7d34d5ddfd5171435c143bdc645493980f453eb5d7cdb3e494a1b35906020015b60405180910390a150565b610a55612158565b6040514790600090339083908381818185875af1925050503d8060008114610a99576040519150601f19603f3d011682016040523d82523d6000602084013e610a9e565b606091505b5050905080610ac057604051631d42c86760e21b815260040160405180910390fd5b6040518281527f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d9060200160405180910390a15050565b61085b838383604051806020016040528060008152506118c9565b6060816000816001600160401b03811115610b2f57610b2f612b3c565b604051908082528060200260200182016040528015610b6857816020015b610b556125fa565b815260200190600190039081610b4d5790505b50905060005b828114610bbb57610b96868683818110610b8a57610b8a612c91565b9050602002013561190d565b828281518110610ba857610ba8612c91565b6020908102919091010152600101610b6e565b50949350505050565b60006106c1826120dc565b6000805b601254811015610c7d5760128181548110610bf057610bf0612c91565b60009182526020909120600260039092020101546001600160401b036301000000909104811690841610801590610c60575060128181548110610c3557610c35612c91565b60009182526020909120600260039092020101546001600160401b03600160581b9091048116908416105b15610c6b5792915050565b80610c7581612cbd565b915050610bd3565b5060405163e82a532960e01b815260040160405180910390fd5b60006001600160a01b038216610cc0576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b610ced612158565b610cf760006121b7565b565b610d01612158565b6012548710610d235760405163e82a532960e01b815260040160405180910390fd5b60018710610d90576012610d38600189612cd6565b81548110610d4857610d48612c91565b60009182526020909120600260039092020101546001600160401b03600160581b90910481169083161015610d9057604051636bc1af9360e01b815260040160405180910390fd5b610d9a8282612209565b8560128881548110610dae57610dae612c91565b906000526020600020906003020160000160006101000a8154816001600160501b0302191690836001600160501b031602179055508460128881548110610df757610df7612c91565b9060005260206000209060030201600001600a6101000a81548163ffffffff021916908363ffffffff1602179055508360128881548110610e3a57610e3a612c91565b9060005260206000209060030201600101819055508260128881548110610e6357610e63612c91565b906000526020600020906003020160020160006101000a81548162ffffff021916908362ffffff1602179055508160128881548110610ea457610ea4612c91565b906000526020600020906003020160020160036101000a8154816001600160401b0302191690836001600160401b031602179055508060128881548110610eed57610eed612c91565b9060005260206000209060030201600201600b6101000a8154816001600160401b0302191690836001600160401b03160217905550600080516020612f9683398151915287878787878787604051610f4b9796959493929190612ced565b60405180910390a150505050505050565b60606000806000610f6c85610c97565b90506000816001600160401b03811115610f8857610f88612b3c565b604051908082528060200260200182016040528015610fb1578160200160208202803683370190505b509050610fbc6125fa565b60005b83861461103657610fcf8161223f565b9150816040015161102e5781516001600160a01b031615610fef57815194505b876001600160a01b0316856001600160a01b03160361102e578083878060010198508151811061102157611021612c91565b6020026020010181815250505b600101610fbf565b50909695505050505050565b6008546001600160a01b031690565b611059612158565b60125460005b818110156110c857601280548061107857611078612d3d565b60008281526020812060036000199093019283020180546001600160701b0319168155600181019190915560020180546001600160981b03191690559055806110c081612cbd565b91505061105f565b5060005b828110156114df576001811061116b5783836110e9600184612cd6565b8181106110f8576110f8612c91565b905060c0020160a00160208101906111109190612916565b6001600160401b031684848381811061112b5761112b612c91565b905060c0020160800160208101906111439190612916565b6001600160401b0316101561116b57604051636bc1af9360e01b815260040160405180910390fd5b6111c784848381811061118057611180612c91565b905060c0020160800160208101906111989190612916565b8585848181106111aa576111aa612c91565b905060c0020160a00160208101906111c29190612916565b612209565b60126040518060c001604052808686858181106111e6576111e6612c91565b6111fc92602060c0909202019081019150612d53565b6001600160501b0316815260200186868581811061121c5761121c612c91565b905060c0020160200160208101906112349190612d6e565b63ffffffff16815260200186868581811061125157611251612c91565b905060c0020160400135815260200186868581811061127257611272612c91565b905060c00201606001602081019061128a9190612d89565b62ffffff1681526020018686858181106112a6576112a6612c91565b905060c0020160800160208101906112be9190612916565b6001600160401b031681526020018686858181106112de576112de612c91565b905060c0020160a00160208101906112f69190612916565b6001600160401b039081169091528254600181810185556000948552602094859020845160039093020180549585015163ffffffff16600160501b026001600160701b03199096166001600160501b0390931692909217949094178155604083015193810193909355606082015160029093018054608084015160a0909401518316600160581b02600160581b600160981b0319949093166301000000026001600160581b031990911662ffffff909516949094179390931791909116179055600080516020612f96833981519152818585828181106113d8576113d8612c91565b6113ee92602060c0909202019081019150612d53565b86868581811061140057611400612c91565b905060c0020160200160208101906114189190612d6e565b87878681811061142a5761142a612c91565b905060c002016040013588888781811061144657611446612c91565b905060c00201606001602081019061145e9190612d89565b89898881811061147057611470612c91565b905060c0020160800160208101906114889190612916565b8a8a8981811061149a5761149a612c91565b905060c0020160a00160208101906114b29190612916565b6040516114c59796959493929190612ced565b60405180910390a1806114d781612cbd565b9150506110cc565b50505050565b6060600380546106d690612c57565b60006106c18261225f565b606081831061152157604051631960ccad60e11b815260040160405180910390fd5b60008061152d60005490565b90508084111561153b578093505b600061154687610c97565b905084861015611565578585038181101561155f578091505b50611569565b5060005b6000816001600160401b0381111561158357611583612b3c565b6040519080825280602002602001820160405280156115ac578160200160208202803683370190505b509050816000036115c257935061167192505050565b60006115cd8861190d565b9050600081604001516115de575080515b885b8881141580156115f05750848714155b15611665576115fe8161223f565b9250826040015161165d5782516001600160a01b03161561161e57825191505b8a6001600160a01b0316826001600160a01b03160361165d578084888060010199508151811061165057611650612c91565b6020026020010181815250505b6001016115e0565b50505092835250909150505b9392505050565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6116ec612621565b601254600090819084106117365760405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964537461676560a01b60448201526064015b60405180910390fd5b60008481526013602090815260408083203384528252808320548784526014909252909120546012805463ffffffff909316928790811061177957611779612c91565b60009182526020918290206040805160c08101825260039390930290910180546001600160501b0381168452600160501b900463ffffffff169383019390935260018301549082015260029091015462ffffff81166060830152630100000081046001600160401b039081166080840152600160581b9091041660a0820152969195509350915050565b61180b612158565b8163ffffffff16600b54816118236001546000540390565b61182d9190612da4565b111561184c5760405163800113cb60e01b815260040160405180910390fd5b8263ffffffff16600e546118609190612dbc565b34101561188057604051630717c22560e51b815260040160405180910390fd5b611890828463ffffffff16612287565b600d546040516001600160a01b03909116903480156108fc02916000818181858888f193505050501580156114df573d6000803e3d6000fd5b6118d4848484610860565b6001600160a01b0383163b156114df576118f0848484846122a1565b6114df576040516368d2bf6b60e11b815260040160405180910390fd5b6119156125fa565b61191d6125fa565b600054831061192c5792915050565b6119358361223f565b90508060400151156119475792915050565b6116718361238c565b606061195b82611b32565b61197857604051630a14c4b560e41b815260040160405180910390fd5b60006010805461198790612c57565b80601f01602080910402602001604051908101604052809291908181526020018280546119b390612c57565b8015611a005780601f106119d557610100808354040283529160200191611a00565b820191906000526020600020905b8154815290600101906020018083116119e357829003601f168201915b505050505090508051600003611a255760405180602001604052806000815250611671565b80611a2f846123a5565b6011604051602001611a4393929190612ddb565b6040516020818303038152906040529392505050565b611a61612158565b6001600160a01b038116611ac65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161172d565b611acf816121b7565b50565b611ada612158565b600b54811115611afd5760405163430b83b160e11b815260040160405180910390fd5b600b8190556040518181527fc7bbc2b288fc13314546ea4aa51f6bcf71b7ba4740beeb3d32e9acef57b6668a90602001610a42565b60008054821080156106c1575050600090815260046020526040902054600160e01b161590565b600260095403611bab5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161172d565b6002600955565b8363ffffffff16600b5481611bca6001546000540390565b611bd49190612da4565b1115611bf35760405163800113cb60e01b815260040160405180910390fd5b42611bfc612621565b6000611c0783610bcf565b905060128181548110611c1c57611c1c612c91565b60009182526020918290206040805160c08101825260039390930290910180546001600160501b038116808552600160501b90910463ffffffff16948401949094526001810154918301919091526002015462ffffff81166060830152630100000081046001600160401b039081166080840152600160581b9091041660a0820152600f549093501115611cf857600e54825163ffffffff8a1691611cc9916001600160501b0316612da4565b611cd39190612dbc565b341015611cf357604051630717c22560e51b815260040160405180910390fd5b611d34565b8151611d0b9063ffffffff8a1690612ea2565b6001600160501b0316341015611d3457604051630717c22560e51b815260040160405180910390fd5b606082015162ffffff1615611d8e57606082015160008281526014602052604090205462ffffff90911690611d709063ffffffff8b1690612da4565b1115611d8e5760405162d0844960e21b815260040160405180910390fd5b600c5415611dd257600c548863ffffffff16611da98961225f565b611db39190612da4565b1115611dd25760405163751304ed60e11b815260040160405180910390fd5b602082015163ffffffff1615611e445760208083015160008381526013835260408082206001600160a01b038c168352909352919091205463ffffffff91821691611e1f918b9116612ed1565b63ffffffff161115611e445760405163b4f3729b60e01b815260040160405180910390fd5b604082015115611ee3578160400151611ec5878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040516001600160601b031960608e901b1660208201526034019150611eaa9050565b604051602081830303815290604052805190602001206123e9565b14611ee3576040516309bde33960e01b815260040160405180910390fd5b60008181526013602090815260408083206001600160a01b038b168452909152812080548a9290611f1b90849063ffffffff16612ed1565b92506101000a81548163ffffffff021916908363ffffffff1602179055508763ffffffff16601460008381526020019081526020016000206000828254611f629190612da4565b90915550611f7890508763ffffffff8a16612287565b600f5482516001600160501b0316101561203c57600d54600e546001600160a01b03909116906108fc90611fb39063ffffffff8c1690612dbc565b6040518115909202916000818181858888f19350505050158015611fdb573d6000803e3d6000fd5b50611fe4611042565b6001600160a01b03166108fc8963ffffffff16600e546120049190612dbc565b61200e9034612cd6565b6040518115909202916000818181858888f19350505050158015612036573d6000803e3d6000fd5b506120d2565b600d546001600160a01b03166108fc612056604234612ef9565b6040518115909202916000818181858888f1935050505015801561207e573d6000803e3d6000fd5b50612087611042565b6001600160a01b03166108fc61209e604234612ef9565b6120a89034612cd6565b6040518115909202916000818181858888f193505050501580156120d0573d6000803e3d6000fd5b505b5050505050505050565b60008160005481101561212a5760008181526004602052604081205490600160e01b82169003612128575b80600003611671575060001901600081815260046020526040902054612107565b505b604051636f96cda160e11b815260040160405180910390fd5b4260a01b176001600160a01b03919091161790565b33612161611042565b6001600160a01b031614610cf75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161172d565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b806001600160401b0316826001600160401b03161061223b57604051631750215560e11b815260040160405180910390fd5b5050565b6122476125fa565b6000828152600460205260409020546106c190612436565b6001600160a01b03166000908152600560205260409081902054901c6001600160401b031690565b61223b828260405180602001604052806000815250612479565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906122d6903390899088908890600401612f1b565b6020604051808303816000875af1925050508015612311575060408051601f3d908101601f1916820190925261230e91810190612f58565b60015b61236f573d80801561233f576040519150601f19603f3d011682016040523d82523d6000602084013e612344565b606091505b508051600003612367576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b6123946125fa565b6106c16123a0836120dc565b612436565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a9004806123bf5750819003601f19909101908152919050565b600081815b845181101561242e5761241a8286838151811061240d5761240d612c91565b60200260200101516124e6565b91508061242681612cbd565b9150506123ee565b509392505050565b61243e6125fa565b6001600160a01b03821681526001600160401b0360a083901c166020820152600160e01b82161515604082015260e89190911c606082015290565b6124838383612512565b6001600160a01b0383163b1561085b576000548281035b6124ad60008683806001019450866122a1565b6124ca576040516368d2bf6b60e11b815260040160405180910390fd5b81811061249a5781600054146124df57600080fd5b5050505050565b6000818310612502576000828152602084905260409020611671565b5060009182526020526040902090565b60008054908290036125375760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600090815260056020526040902080546001600160401b01840201905561256e836001841460e11b612143565b6000828152600460205260408120919091556001600160a01b038416908383019083908390600080516020612f768339815191528180a4600183015b8181146125d05780836000600080516020612f76833981519152600080a46001016125aa565b50816000036125f157604051622e076360e81b815260040160405180910390fd5b60005550505050565b60408051608081018252600080825260208201819052918101829052606081019190915290565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6001600160e01b031981168114611acf57600080fd5b60006020828403121561267e57600080fd5b813561167181612656565b60005b838110156126a457818101518382015260200161268c565b838111156114df5750506000910152565b600081518084526126cd816020860160208601612689565b601f01601f19169290920160200192915050565b60208152600061167160208301846126b5565b60006020828403121561270657600080fd5b5035919050565b80356001600160a01b038116811461272457600080fd5b919050565b6000806040838503121561273c57600080fd5b6127458361270d565b946020939093013593505050565b803563ffffffff8116811461272457600080fd5b60008083601f84011261277957600080fd5b5081356001600160401b0381111561279057600080fd5b6020830191508360208260051b85010111156127ab57600080fd5b9250929050565b6000806000604084860312156127c757600080fd5b6127d084612753565b925060208401356001600160401b038111156127eb57600080fd5b6127f786828701612767565b9497909650939450505050565b60008060006060848603121561281957600080fd5b6128228461270d565b92506128306020850161270d565b9150604084013590509250925092565b6000806020838503121561285357600080fd5b82356001600160401b0381111561286957600080fd5b61287585828601612767565b90969095509350505050565b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b6020808252825182820181905260009190848201906040850190845b81811015611036576128ec838551612881565b92840192608092909201916001016128d9565b80356001600160401b038116811461272457600080fd5b60006020828403121561292857600080fd5b611671826128ff565b60006020828403121561294357600080fd5b6116718261270d565b80356001600160501b038116811461272457600080fd5b803562ffffff8116811461272457600080fd5b600080600080600080600060e0888a03121561299157600080fd5b873596506129a16020890161294c565b95506129af60408901612753565b9450606088013593506129c460808901612963565b92506129d260a089016128ff565b91506129e060c089016128ff565b905092959891949750929550565b6020808252825182820181905260009190848201906040850190845b8181101561103657835183529284019291840191600101612a0a565b60008060208385031215612a3957600080fd5b82356001600160401b0380821115612a5057600080fd5b818501915085601f830112612a6457600080fd5b813581811115612a7357600080fd5b86602060c083028501011115612a8857600080fd5b60209290920196919550909350505050565b600080600060608486031215612aaf57600080fd5b612ab88461270d565b95602085013595506040909401359392505050565b60008060408385031215612ae057600080fd5b612ae98361270d565b915060208301358015158114612afe57600080fd5b809150509250929050565b60008060408385031215612b1c57600080fd5b612b2583612753565b9150612b336020840161270d565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215612b6857600080fd5b612b718561270d565b9350612b7f6020860161270d565b92506040850135915060608501356001600160401b0380821115612ba257600080fd5b818701915087601f830112612bb657600080fd5b813581811115612bc857612bc8612b3c565b604051601f8201601f19908116603f01168101908382118183101715612bf057612bf0612b3c565b816040528281528a6020848701011115612c0957600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b608081016106c18284612881565b60008060408385031215612c4e57600080fd5b612b258361270d565b600181811c90821680612c6b57607f821691505b602082108103612c8b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201612ccf57612ccf612ca7565b5060010190565b600082821015612ce857612ce8612ca7565b500390565b9687526001600160501b0395909516602087015263ffffffff939093166040860152606085019190915262ffffff1660808401526001600160401b0390811660a08401521660c082015260e00190565b634e487b7160e01b600052603160045260246000fd5b600060208284031215612d6557600080fd5b6116718261294c565b600060208284031215612d8057600080fd5b61167182612753565b600060208284031215612d9b57600080fd5b61167182612963565b60008219821115612db757612db7612ca7565b500190565b6000816000190483118215151615612dd657612dd6612ca7565b500290565b600084516020612dee8285838a01612689565b855191840191612e018184848a01612689565b8554920191600090600181811c9080831680612e1e57607f831692505b8583108103612e3b57634e487b7160e01b85526022600452602485fd5b808015612e4f5760018114612e6457612e91565b60ff1985168852831515840288019550612e91565b60008b81526020902060005b85811015612e895781548a820152908401908801612e70565b505083880195505b50939b9a5050505050505050505050565b60006001600160501b0382811684821681151582840482111615612ec857612ec8612ca7565b02949350505050565b600063ffffffff808316818516808303821115612ef057612ef0612ca7565b01949350505050565b600082612f1657634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612f4e908301846126b5565b9695505050505050565b600060208284031215612f6a57600080fd5b81516116718161265656feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efb3268648542a1bb1b2dd12e3b14aeb5a3ab22c592de96bdd3e842154a5b394faa2646970667358221220d9efd538fc0e65c82d4b81ca32bb2966b0069f0c87c6d027e5bb137866561d9364736f6c634300080f0033697066733a2f2f6261667962656964616436666f7a757a63646e70336e6a7934756a70686c33616b326f32726a6579647964656c7136357a79706b697a6e796233652f

Deployed Bytecode

0x60806040526004361061019f5760003560e01c806301ffc9a7146101a457806306fdde03146101d9578063081812fc146101fb578063095ea7b314610233578063107af24b1461024857806318160ddd1461025b57806323b872dd1461027e578063372992e4146102915780633ccfd60b146102b157806342842e0e146102c657806342cde4e8146102d95780634b1c53b4146102ef5780635bbb2177146103045780636352211e1461033157806367808a341461035157806370a082311461037157806370da24ee14610391578063715018a6146103a657806373e1607e146103bb5780638462151c146103db5780638da5cb5b146104085780638dcdb09d1461041d57806395d89b411461043d57806397cf84fc1461045257806399a2557a14610472578063a22cb46514610492578063a3759f60146104b2578063aac5ab1f1461054e578063b88d4fde14610561578063c23dc68f14610574578063c87b56dd146105a1578063e985e9c5146105c1578063efdaa2ec1461060a578063f2fde38b1461061f578063f8d096961461063f578063fa4271771461065f575b600080fd5b3480156101b057600080fd5b506101c46101bf36600461266c565b610675565b60405190151581526020015b60405180910390f35b3480156101e557600080fd5b506101ee6106c7565b6040516101d091906126e1565b34801561020757600080fd5b5061021b6102163660046126f4565b610759565b6040516001600160a01b0390911681526020016101d0565b610246610241366004612729565b61079d565b005b6102466102563660046127b2565b61083d565b34801561026757600080fd5b50600154600054035b6040519081526020016101d0565b61024661028c366004612804565b610860565b34801561029d57600080fd5b506102466102ac3660046126f4565b6109e6565b3480156102bd57600080fd5b50610246610a4d565b6102466102d4366004612804565b610af7565b3480156102e557600080fd5b50610270600f5481565b3480156102fb57600080fd5b50600b54610270565b34801561031057600080fd5b5061032461031f366004612840565b610b12565b6040516101d091906128bd565b34801561033d57600080fd5b5061021b61034c3660046126f4565b610bc4565b34801561035d57600080fd5b5061027061036c366004612916565b610bcf565b34801561037d57600080fd5b5061027061038c366004612931565b610c97565b34801561039d57600080fd5b50601254610270565b3480156103b257600080fd5b50610246610ce5565b3480156103c757600080fd5b506102466103d6366004612976565b610cf9565b3480156103e757600080fd5b506103fb6103f6366004612931565b610f5c565b6040516101d091906129ee565b34801561041457600080fd5b5061021b611042565b34801561042957600080fd5b50610246610438366004612a26565b611051565b34801561044957600080fd5b506101ee6114e5565b34801561045e57600080fd5b5061027061046d366004612931565b6114f4565b34801561047e57600080fd5b506103fb61048d366004612a9a565b6114ff565b34801561049e57600080fd5b506102466104ad366004612acd565b611678565b3480156104be57600080fd5b506104d26104cd3660046126f4565b6116e4565b6040805184516001600160501b0316815260208086015163ffffffff90811691830191909152858301519282019290925260608086015162ffffff16908201526080808601516001600160401b039081169183019190915260a095860151169481019490945290911660c083015260e0820152610100016101d0565b61024661055c366004612b09565b611803565b61024661056f366004612b52565b6118c9565b34801561058057600080fd5b5061059461058f3660046126f4565b61190d565b6040516101d09190612c2d565b3480156105ad57600080fd5b506101ee6105bc3660046126f4565b611950565b3480156105cd57600080fd5b506101c46105dc366004612c3b565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561061657600080fd5b50600c54610270565b34801561062b57600080fd5b5061024661063a366004612931565b611a59565b34801561064b57600080fd5b5061024661065a3660046126f4565b611ad2565b34801561066b57600080fd5b50610270600e5481565b60006301ffc9a760e01b6001600160e01b0319831614806106a657506380ac58cd60e01b6001600160e01b03198316145b806106c15750635b5e139f60e01b6001600160e01b03198316145b92915050565b6060600280546106d690612c57565b80601f016020809104026020016040519081016040528092919081815260200182805461070290612c57565b801561074f5780601f106107245761010080835404028352916020019161074f565b820191906000526020600020905b81548152906001019060200180831161073257829003601f168201915b5050505050905090565b600061076482611b32565b610781576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b60006107a882610bc4565b9050336001600160a01b038216146107e1576107c481336105dc565b6107e1576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b610845611b59565b61085183338484611bb2565b61085b6001600955565b505050565b600061086b826120dc565b9050836001600160a01b0316816001600160a01b03161461089e5760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b038816909114176108eb576108ce86336105dc565b6108eb57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b03851661091257604051633a954ecd60e21b815260040160405180910390fd5b801561091d57600082555b6001600160a01b0386811660009081526005602052604080822080546000190190559187168152208054600101905561095a85600160e11b612143565b600085815260046020526040812091909155600160e11b841690036109af576001840160008181526004602052604081205490036109ad5760005481146109ad5760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b0316600080516020612f7683398151915260405160405180910390a4505050505050565b6109ee612158565b600b54811115610a1157604051630590c51360e01b815260040160405180910390fd5b600c8190556040518181527f5307de8ad7d34d5ddfd5171435c143bdc645493980f453eb5d7cdb3e494a1b35906020015b60405180910390a150565b610a55612158565b6040514790600090339083908381818185875af1925050503d8060008114610a99576040519150601f19603f3d011682016040523d82523d6000602084013e610a9e565b606091505b5050905080610ac057604051631d42c86760e21b815260040160405180910390fd5b6040518281527f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d9060200160405180910390a15050565b61085b838383604051806020016040528060008152506118c9565b6060816000816001600160401b03811115610b2f57610b2f612b3c565b604051908082528060200260200182016040528015610b6857816020015b610b556125fa565b815260200190600190039081610b4d5790505b50905060005b828114610bbb57610b96868683818110610b8a57610b8a612c91565b9050602002013561190d565b828281518110610ba857610ba8612c91565b6020908102919091010152600101610b6e565b50949350505050565b60006106c1826120dc565b6000805b601254811015610c7d5760128181548110610bf057610bf0612c91565b60009182526020909120600260039092020101546001600160401b036301000000909104811690841610801590610c60575060128181548110610c3557610c35612c91565b60009182526020909120600260039092020101546001600160401b03600160581b9091048116908416105b15610c6b5792915050565b80610c7581612cbd565b915050610bd3565b5060405163e82a532960e01b815260040160405180910390fd5b60006001600160a01b038216610cc0576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b610ced612158565b610cf760006121b7565b565b610d01612158565b6012548710610d235760405163e82a532960e01b815260040160405180910390fd5b60018710610d90576012610d38600189612cd6565b81548110610d4857610d48612c91565b60009182526020909120600260039092020101546001600160401b03600160581b90910481169083161015610d9057604051636bc1af9360e01b815260040160405180910390fd5b610d9a8282612209565b8560128881548110610dae57610dae612c91565b906000526020600020906003020160000160006101000a8154816001600160501b0302191690836001600160501b031602179055508460128881548110610df757610df7612c91565b9060005260206000209060030201600001600a6101000a81548163ffffffff021916908363ffffffff1602179055508360128881548110610e3a57610e3a612c91565b9060005260206000209060030201600101819055508260128881548110610e6357610e63612c91565b906000526020600020906003020160020160006101000a81548162ffffff021916908362ffffff1602179055508160128881548110610ea457610ea4612c91565b906000526020600020906003020160020160036101000a8154816001600160401b0302191690836001600160401b031602179055508060128881548110610eed57610eed612c91565b9060005260206000209060030201600201600b6101000a8154816001600160401b0302191690836001600160401b03160217905550600080516020612f9683398151915287878787878787604051610f4b9796959493929190612ced565b60405180910390a150505050505050565b60606000806000610f6c85610c97565b90506000816001600160401b03811115610f8857610f88612b3c565b604051908082528060200260200182016040528015610fb1578160200160208202803683370190505b509050610fbc6125fa565b60005b83861461103657610fcf8161223f565b9150816040015161102e5781516001600160a01b031615610fef57815194505b876001600160a01b0316856001600160a01b03160361102e578083878060010198508151811061102157611021612c91565b6020026020010181815250505b600101610fbf565b50909695505050505050565b6008546001600160a01b031690565b611059612158565b60125460005b818110156110c857601280548061107857611078612d3d565b60008281526020812060036000199093019283020180546001600160701b0319168155600181019190915560020180546001600160981b03191690559055806110c081612cbd565b91505061105f565b5060005b828110156114df576001811061116b5783836110e9600184612cd6565b8181106110f8576110f8612c91565b905060c0020160a00160208101906111109190612916565b6001600160401b031684848381811061112b5761112b612c91565b905060c0020160800160208101906111439190612916565b6001600160401b0316101561116b57604051636bc1af9360e01b815260040160405180910390fd5b6111c784848381811061118057611180612c91565b905060c0020160800160208101906111989190612916565b8585848181106111aa576111aa612c91565b905060c0020160a00160208101906111c29190612916565b612209565b60126040518060c001604052808686858181106111e6576111e6612c91565b6111fc92602060c0909202019081019150612d53565b6001600160501b0316815260200186868581811061121c5761121c612c91565b905060c0020160200160208101906112349190612d6e565b63ffffffff16815260200186868581811061125157611251612c91565b905060c0020160400135815260200186868581811061127257611272612c91565b905060c00201606001602081019061128a9190612d89565b62ffffff1681526020018686858181106112a6576112a6612c91565b905060c0020160800160208101906112be9190612916565b6001600160401b031681526020018686858181106112de576112de612c91565b905060c0020160a00160208101906112f69190612916565b6001600160401b039081169091528254600181810185556000948552602094859020845160039093020180549585015163ffffffff16600160501b026001600160701b03199096166001600160501b0390931692909217949094178155604083015193810193909355606082015160029093018054608084015160a0909401518316600160581b02600160581b600160981b0319949093166301000000026001600160581b031990911662ffffff909516949094179390931791909116179055600080516020612f96833981519152818585828181106113d8576113d8612c91565b6113ee92602060c0909202019081019150612d53565b86868581811061140057611400612c91565b905060c0020160200160208101906114189190612d6e565b87878681811061142a5761142a612c91565b905060c002016040013588888781811061144657611446612c91565b905060c00201606001602081019061145e9190612d89565b89898881811061147057611470612c91565b905060c0020160800160208101906114889190612916565b8a8a8981811061149a5761149a612c91565b905060c0020160a00160208101906114b29190612916565b6040516114c59796959493929190612ced565b60405180910390a1806114d781612cbd565b9150506110cc565b50505050565b6060600380546106d690612c57565b60006106c18261225f565b606081831061152157604051631960ccad60e11b815260040160405180910390fd5b60008061152d60005490565b90508084111561153b578093505b600061154687610c97565b905084861015611565578585038181101561155f578091505b50611569565b5060005b6000816001600160401b0381111561158357611583612b3c565b6040519080825280602002602001820160405280156115ac578160200160208202803683370190505b509050816000036115c257935061167192505050565b60006115cd8861190d565b9050600081604001516115de575080515b885b8881141580156115f05750848714155b15611665576115fe8161223f565b9250826040015161165d5782516001600160a01b03161561161e57825191505b8a6001600160a01b0316826001600160a01b03160361165d578084888060010199508151811061165057611650612c91565b6020026020010181815250505b6001016115e0565b50505092835250909150505b9392505050565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6116ec612621565b601254600090819084106117365760405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964537461676560a01b60448201526064015b60405180910390fd5b60008481526013602090815260408083203384528252808320548784526014909252909120546012805463ffffffff909316928790811061177957611779612c91565b60009182526020918290206040805160c08101825260039390930290910180546001600160501b0381168452600160501b900463ffffffff169383019390935260018301549082015260029091015462ffffff81166060830152630100000081046001600160401b039081166080840152600160581b9091041660a0820152969195509350915050565b61180b612158565b8163ffffffff16600b54816118236001546000540390565b61182d9190612da4565b111561184c5760405163800113cb60e01b815260040160405180910390fd5b8263ffffffff16600e546118609190612dbc565b34101561188057604051630717c22560e51b815260040160405180910390fd5b611890828463ffffffff16612287565b600d546040516001600160a01b03909116903480156108fc02916000818181858888f193505050501580156114df573d6000803e3d6000fd5b6118d4848484610860565b6001600160a01b0383163b156114df576118f0848484846122a1565b6114df576040516368d2bf6b60e11b815260040160405180910390fd5b6119156125fa565b61191d6125fa565b600054831061192c5792915050565b6119358361223f565b90508060400151156119475792915050565b6116718361238c565b606061195b82611b32565b61197857604051630a14c4b560e41b815260040160405180910390fd5b60006010805461198790612c57565b80601f01602080910402602001604051908101604052809291908181526020018280546119b390612c57565b8015611a005780601f106119d557610100808354040283529160200191611a00565b820191906000526020600020905b8154815290600101906020018083116119e357829003601f168201915b505050505090508051600003611a255760405180602001604052806000815250611671565b80611a2f846123a5565b6011604051602001611a4393929190612ddb565b6040516020818303038152906040529392505050565b611a61612158565b6001600160a01b038116611ac65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161172d565b611acf816121b7565b50565b611ada612158565b600b54811115611afd5760405163430b83b160e11b815260040160405180910390fd5b600b8190556040518181527fc7bbc2b288fc13314546ea4aa51f6bcf71b7ba4740beeb3d32e9acef57b6668a90602001610a42565b60008054821080156106c1575050600090815260046020526040902054600160e01b161590565b600260095403611bab5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161172d565b6002600955565b8363ffffffff16600b5481611bca6001546000540390565b611bd49190612da4565b1115611bf35760405163800113cb60e01b815260040160405180910390fd5b42611bfc612621565b6000611c0783610bcf565b905060128181548110611c1c57611c1c612c91565b60009182526020918290206040805160c08101825260039390930290910180546001600160501b038116808552600160501b90910463ffffffff16948401949094526001810154918301919091526002015462ffffff81166060830152630100000081046001600160401b039081166080840152600160581b9091041660a0820152600f549093501115611cf857600e54825163ffffffff8a1691611cc9916001600160501b0316612da4565b611cd39190612dbc565b341015611cf357604051630717c22560e51b815260040160405180910390fd5b611d34565b8151611d0b9063ffffffff8a1690612ea2565b6001600160501b0316341015611d3457604051630717c22560e51b815260040160405180910390fd5b606082015162ffffff1615611d8e57606082015160008281526014602052604090205462ffffff90911690611d709063ffffffff8b1690612da4565b1115611d8e5760405162d0844960e21b815260040160405180910390fd5b600c5415611dd257600c548863ffffffff16611da98961225f565b611db39190612da4565b1115611dd25760405163751304ed60e11b815260040160405180910390fd5b602082015163ffffffff1615611e445760208083015160008381526013835260408082206001600160a01b038c168352909352919091205463ffffffff91821691611e1f918b9116612ed1565b63ffffffff161115611e445760405163b4f3729b60e01b815260040160405180910390fd5b604082015115611ee3578160400151611ec5878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040516001600160601b031960608e901b1660208201526034019150611eaa9050565b604051602081830303815290604052805190602001206123e9565b14611ee3576040516309bde33960e01b815260040160405180910390fd5b60008181526013602090815260408083206001600160a01b038b168452909152812080548a9290611f1b90849063ffffffff16612ed1565b92506101000a81548163ffffffff021916908363ffffffff1602179055508763ffffffff16601460008381526020019081526020016000206000828254611f629190612da4565b90915550611f7890508763ffffffff8a16612287565b600f5482516001600160501b0316101561203c57600d54600e546001600160a01b03909116906108fc90611fb39063ffffffff8c1690612dbc565b6040518115909202916000818181858888f19350505050158015611fdb573d6000803e3d6000fd5b50611fe4611042565b6001600160a01b03166108fc8963ffffffff16600e546120049190612dbc565b61200e9034612cd6565b6040518115909202916000818181858888f19350505050158015612036573d6000803e3d6000fd5b506120d2565b600d546001600160a01b03166108fc612056604234612ef9565b6040518115909202916000818181858888f1935050505015801561207e573d6000803e3d6000fd5b50612087611042565b6001600160a01b03166108fc61209e604234612ef9565b6120a89034612cd6565b6040518115909202916000818181858888f193505050501580156120d0573d6000803e3d6000fd5b505b5050505050505050565b60008160005481101561212a5760008181526004602052604081205490600160e01b82169003612128575b80600003611671575060001901600081815260046020526040902054612107565b505b604051636f96cda160e11b815260040160405180910390fd5b4260a01b176001600160a01b03919091161790565b33612161611042565b6001600160a01b031614610cf75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161172d565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b806001600160401b0316826001600160401b03161061223b57604051631750215560e11b815260040160405180910390fd5b5050565b6122476125fa565b6000828152600460205260409020546106c190612436565b6001600160a01b03166000908152600560205260409081902054901c6001600160401b031690565b61223b828260405180602001604052806000815250612479565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906122d6903390899088908890600401612f1b565b6020604051808303816000875af1925050508015612311575060408051601f3d908101601f1916820190925261230e91810190612f58565b60015b61236f573d80801561233f576040519150601f19603f3d011682016040523d82523d6000602084013e612344565b606091505b508051600003612367576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b6123946125fa565b6106c16123a0836120dc565b612436565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a9004806123bf5750819003601f19909101908152919050565b600081815b845181101561242e5761241a8286838151811061240d5761240d612c91565b60200260200101516124e6565b91508061242681612cbd565b9150506123ee565b509392505050565b61243e6125fa565b6001600160a01b03821681526001600160401b0360a083901c166020820152600160e01b82161515604082015260e89190911c606082015290565b6124838383612512565b6001600160a01b0383163b1561085b576000548281035b6124ad60008683806001019450866122a1565b6124ca576040516368d2bf6b60e11b815260040160405180910390fd5b81811061249a5781600054146124df57600080fd5b5050505050565b6000818310612502576000828152602084905260409020611671565b5060009182526020526040902090565b60008054908290036125375760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600090815260056020526040902080546001600160401b01840201905561256e836001841460e11b612143565b6000828152600460205260408120919091556001600160a01b038416908383019083908390600080516020612f768339815191528180a4600183015b8181146125d05780836000600080516020612f76833981519152600080a46001016125aa565b50816000036125f157604051622e076360e81b815260040160405180910390fd5b60005550505050565b60408051608081018252600080825260208201819052918101829052606081019190915290565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6001600160e01b031981168114611acf57600080fd5b60006020828403121561267e57600080fd5b813561167181612656565b60005b838110156126a457818101518382015260200161268c565b838111156114df5750506000910152565b600081518084526126cd816020860160208601612689565b601f01601f19169290920160200192915050565b60208152600061167160208301846126b5565b60006020828403121561270657600080fd5b5035919050565b80356001600160a01b038116811461272457600080fd5b919050565b6000806040838503121561273c57600080fd5b6127458361270d565b946020939093013593505050565b803563ffffffff8116811461272457600080fd5b60008083601f84011261277957600080fd5b5081356001600160401b0381111561279057600080fd5b6020830191508360208260051b85010111156127ab57600080fd5b9250929050565b6000806000604084860312156127c757600080fd5b6127d084612753565b925060208401356001600160401b038111156127eb57600080fd5b6127f786828701612767565b9497909650939450505050565b60008060006060848603121561281957600080fd5b6128228461270d565b92506128306020850161270d565b9150604084013590509250925092565b6000806020838503121561285357600080fd5b82356001600160401b0381111561286957600080fd5b61287585828601612767565b90969095509350505050565b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b6020808252825182820181905260009190848201906040850190845b81811015611036576128ec838551612881565b92840192608092909201916001016128d9565b80356001600160401b038116811461272457600080fd5b60006020828403121561292857600080fd5b611671826128ff565b60006020828403121561294357600080fd5b6116718261270d565b80356001600160501b038116811461272457600080fd5b803562ffffff8116811461272457600080fd5b600080600080600080600060e0888a03121561299157600080fd5b873596506129a16020890161294c565b95506129af60408901612753565b9450606088013593506129c460808901612963565b92506129d260a089016128ff565b91506129e060c089016128ff565b905092959891949750929550565b6020808252825182820181905260009190848201906040850190845b8181101561103657835183529284019291840191600101612a0a565b60008060208385031215612a3957600080fd5b82356001600160401b0380821115612a5057600080fd5b818501915085601f830112612a6457600080fd5b813581811115612a7357600080fd5b86602060c083028501011115612a8857600080fd5b60209290920196919550909350505050565b600080600060608486031215612aaf57600080fd5b612ab88461270d565b95602085013595506040909401359392505050565b60008060408385031215612ae057600080fd5b612ae98361270d565b915060208301358015158114612afe57600080fd5b809150509250929050565b60008060408385031215612b1c57600080fd5b612b2583612753565b9150612b336020840161270d565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215612b6857600080fd5b612b718561270d565b9350612b7f6020860161270d565b92506040850135915060608501356001600160401b0380821115612ba257600080fd5b818701915087601f830112612bb657600080fd5b813581811115612bc857612bc8612b3c565b604051601f8201601f19908116603f01168101908382118183101715612bf057612bf0612b3c565b816040528281528a6020848701011115612c0957600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b608081016106c18284612881565b60008060408385031215612c4e57600080fd5b612b258361270d565b600181811c90821680612c6b57607f821691505b602082108103612c8b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201612ccf57612ccf612ca7565b5060010190565b600082821015612ce857612ce8612ca7565b500390565b9687526001600160501b0395909516602087015263ffffffff939093166040860152606085019190915262ffffff1660808401526001600160401b0390811660a08401521660c082015260e00190565b634e487b7160e01b600052603160045260246000fd5b600060208284031215612d6557600080fd5b6116718261294c565b600060208284031215612d8057600080fd5b61167182612753565b600060208284031215612d9b57600080fd5b61167182612963565b60008219821115612db757612db7612ca7565b500190565b6000816000190483118215151615612dd657612dd6612ca7565b500290565b600084516020612dee8285838a01612689565b855191840191612e018184848a01612689565b8554920191600090600181811c9080831680612e1e57607f831692505b8583108103612e3b57634e487b7160e01b85526022600452602485fd5b808015612e4f5760018114612e6457612e91565b60ff1985168852831515840288019550612e91565b60008b81526020902060005b85811015612e895781548a820152908401908801612e70565b505083880195505b50939b9a5050505050505050505050565b60006001600160501b0382811684821681151582840482111615612ec857612ec8612ca7565b02949350505050565b600063ffffffff808316818516808303821115612ef057612ef0612ca7565b01949350505050565b600082612f1657634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612f4e908301846126b5565b9695505050505050565b600060208284031215612f6a57600080fd5b81516116718161265656feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efb3268648542a1bb1b2dd12e3b14aeb5a3ab22c592de96bdd3e842154a5b394faa2646970667358221220d9efd538fc0e65c82d4b81ca32bb2966b0069f0c87c6d027e5bb137866561d9364736f6c634300080f0033

Deployed Bytecode Sourcemap

78688:12716:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18404:639;;;;;;;;;;-1:-1:-1;18404:639:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;18404:639:0;;;;;;;;19306:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;25797:218::-;;;;;;;;;;-1:-1:-1;25797:218:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1692:32:1;;;1674:51;;1662:2;1647:18;25797:218:0;1528:203:1;25230:408:0;;;;;;:::i;:::-;;:::i;:::-;;86641:163;;;;;;:::i;:::-;;:::i;15057:323::-;;;;;;;;;;-1:-1:-1;15331:12:0;;15118:7;15315:13;:28;15057:323;;;3373:25:1;;;3361:2;3346:18;15057:323:0;3227:177:1;29436:2825:0;;;;;;:::i;:::-;;:::i;83882:313::-;;;;;;;;;;-1:-1:-1;83882:313:0;;;;;:::i;:::-;;:::i;89644:237::-;;;;;;;;;;;;;:::i;32357:193::-;;;;;;:::i;:::-;;:::i;79243:38::-;;;;;;;;;;;;;;;;82977:117;;;;;;;;;;-1:-1:-1;83068:18:0;;82977:117;;57704:528;;;;;;;;;;-1:-1:-1;57704:528:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;20699:152::-;;;;;;;;;;-1:-1:-1;20699:152:0;;;;;:::i;:::-;;:::i;90637:455::-;;;;;;;;;;-1:-1:-1;90637:455:0;;;;;:::i;:::-;;:::i;16241:233::-;;;;;;;;;;-1:-1:-1;16241:233:0;;;;;:::i;:::-;;:::i;82793:112::-;;;;;;;;;;-1:-1:-1;82879:11:0;:18;82793:112;;77772:103;;;;;;;;;;;;;:::i;85177:1270::-;;;;;;;;;;-1:-1:-1;85177:1270:0;;;;;:::i;:::-;;:::i;61580:900::-;;;;;;;;;;-1:-1:-1;61580:900:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;77124:87::-;;;;;;;;;;;;;:::i;81170:1558::-;;;;;;;;;;-1:-1:-1;81170:1558:0;;;;;:::i;:::-;;:::i;19482:104::-;;;;;;;;;;;;;:::i;84286:182::-;;;;;;;;;;-1:-1:-1;84286:182:0;;;;;:::i;:::-;;:::i;58620:2513::-;;;;;;;;;;-1:-1:-1;58620:2513:0;;;;;:::i;:::-;;:::i;26355:234::-;;;;;;;;;;-1:-1:-1;26355:234:0;;;;;:::i;:::-;;:::i;84572:501::-;;;;;;;;;;-1:-1:-1;84572:501:0;;;;;:::i;:::-;;:::i;:::-;;;;9035:13:1;;-1:-1:-1;;;;;9031:38:1;9013:57;;9117:4;9105:17;;;9099:24;9142:10;9190:21;;;9168:20;;;9161:51;;;;9256:17;;;9250:24;9228:20;;;9221:54;;;;9335:4;9323:17;;;9317:24;9343:8;9313:39;9291:20;;;9284:69;9402:4;9390:17;;;9384:24;-1:-1:-1;;;;;9483:23:1;;;9461:20;;;9454:53;;;;9567:4;9555:17;;;9549:24;9545:33;9523:20;;;9516:63;;;;9616:15;;;9610:3;9595:19;;9588:44;9663:3;9648:19;;9641:35;9000:3;8985:19;84572:501:0;8750:932:1;89306:273:0;;;;;;:::i;:::-;;:::i;33148:407::-;;;;;;:::i;:::-;;:::i;57117:428::-;;;;;;;;;;-1:-1:-1;57117:428:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;89968:577::-;;;;;;;;;;-1:-1:-1;89968:577:0;;;;;:::i;:::-;;:::i;26746:164::-;;;;;;;;;;-1:-1:-1;26746:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;26867:25:0;;;26843:4;26867:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;26746:164;83700:117;;;;;;;;;;-1:-1:-1;83791:18:0;;83700:117;;78030:201;;;;;;;;;;-1:-1:-1;78030:201:0;;;;;:::i;:::-;;:::i;83221:349::-;;;;;;;;;;-1:-1:-1;83221:349:0;;;;;:::i;:::-;;:::i;79197:39::-;;;;;;;;;;;;;;;;18404:639;18489:4;-1:-1:-1;;;;;;;;;18813:25:0;;;;:102;;-1:-1:-1;;;;;;;;;;18890:25:0;;;18813:102;:179;;;-1:-1:-1;;;;;;;;;;18967:25:0;;;18813:179;18793:199;18404:639;-1:-1:-1;;18404:639:0:o;19306:100::-;19360:13;19393:5;19386:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19306:100;:::o;25797:218::-;25873:7;25898:16;25906:7;25898;:16::i;:::-;25893:64;;25923:34;;-1:-1:-1;;;25923:34:0;;;;;;;;;;;25893:64;-1:-1:-1;25977:24:0;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;25977:30:0;;25797:218::o;25230:408::-;25319:13;25335:16;25343:7;25335;:16::i;:::-;25319:32;-1:-1:-1;49563:10:0;-1:-1:-1;;;;;25368:28:0;;;25364:175;;25416:44;25433:5;49563:10;26746:164;:::i;25416:44::-;25411:128;;25488:35;;-1:-1:-1;;;25488:35:0;;;;;;;;;;;25411:128;25551:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;;;;;25551:35:0;-1:-1:-1;;;;;25551:35:0;;;;;;;;;25602:28;;25551:24;;25602:28;;;;;;;25308:330;25230:408;;:::o;86641:163::-;74395:21;:19;:21::i;:::-;86759:37:::1;86773:3;86778:10;86790:5;;86759:13;:37::i;:::-;74439:20:::0;73833:1;74959:7;:22;74776:213;74439:20;86641:163;;;:::o;29436:2825::-;29578:27;29608;29627:7;29608:18;:27::i;:::-;29578:57;;29693:4;-1:-1:-1;;;;;29652:45:0;29668:19;-1:-1:-1;;;;;29652:45:0;;29648:86;;29706:28;;-1:-1:-1;;;29706:28:0;;;;;;;;;;;29648:86;29748:27;28544:24;;;:15;:24;;;;;28772:26;;49563:10;28169:30;;;-1:-1:-1;;;;;27862:28:0;;28147:20;;;28144:56;29934:180;;30027:43;30044:4;49563:10;26746:164;:::i;30027:43::-;30022:92;;30079:35;;-1:-1:-1;;;30079:35:0;;;;;;;;;;;30022:92;-1:-1:-1;;;;;30131:16:0;;30127:52;;30156:23;;-1:-1:-1;;;30156:23:0;;;;;;;;;;;30127:52;30328:15;30325:160;;;30468:1;30447:19;30440:30;30325:160;-1:-1:-1;;;;;30865:24:0;;;;;;;:18;:24;;;;;;30863:26;;-1:-1:-1;;30863:26:0;;;30934:22;;;;;;30932:24;;-1:-1:-1;30932:24:0;;;31256:146;30934:22;-1:-1:-1;;;31256:18:0;:146::i;:::-;31227:26;;;;:17;:26;;;;;:175;;;;-1:-1:-1;;;31522:47:0;;:52;;31518:627;;31627:1;31617:11;;31595:19;31750:30;;;:17;:30;;;;;;:35;;31746:384;;31888:13;;31873:11;:28;31869:242;;32035:30;;;;:17;:30;;;;;:52;;;31869:242;31576:569;31518:627;32192:7;32188:2;-1:-1:-1;;;;;32173:27:0;32182:4;-1:-1:-1;;;;;32173:27:0;-1:-1:-1;;;;;;;;;;;32173:27:0;;;;;;;;;29567:2694;;;29436:2825;;;:::o;83882:313::-;77010:13;:11;:13::i;:::-;84016:18:::1;;83996:17;:38;83992:91;;;84056:27;;-1:-1:-1::0;;;84056:27:0::1;;;;;;;;;;;83992:91;84094:18;:38:::0;;;84148:39:::1;::::0;3373:25:1;;;84148:39:0::1;::::0;3361:2:1;3346:18;84148:39:0::1;;;;;;;;83882:313:::0;:::o;89644:237::-;77010:13;:11;:13::i;:::-;89761:33:::1;::::0;89710:21:::1;::::0;89694:13:::1;::::0;89761:10:::1;::::0;89710:21;;89694:13;89761:33;89694:13;89761:33;89710:21;89761:10;:33:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89742:52;;;89810:7;89805:37;;89826:16;;-1:-1:-1::0;;;89826:16:0::1;;;;;;;;;;;89805:37;89858:15;::::0;3373:25:1;;;89858:15:0::1;::::0;3361:2:1;3346:18;89858:15:0::1;;;;;;;89683:198;;89644:237::o:0;32357:193::-;32503:39;32520:4;32526:2;32530:7;32503:39;;;;;;;;;;;;:16;:39::i;57704:528::-;57848:23;57939:8;57914:22;57939:8;-1:-1:-1;;;;;58006:36:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;57969:73;;58062:9;58057:125;58078:14;58073:1;:19;58057:125;;58134:32;58154:8;;58163:1;58154:11;;;;;;;:::i;:::-;;;;;;;58134:19;:32::i;:::-;58118:10;58129:1;58118:13;;;;;;;;:::i;:::-;;;;;;;;;;:48;58094:3;;58057:125;;;-1:-1:-1;58203:10:0;57704:528;-1:-1:-1;;;;57704:528:0:o;20699:152::-;20771:7;20814:27;20833:7;20814:18;:27::i;90637:455::-;90758:7;;90783:270;90807:11;:18;90803:22;;90783:270;;;90882:11;90894:1;90882:14;;;;;;;;:::i;:::-;;;;;;;;;:35;:14;;;;;:35;;-1:-1:-1;;;;;90882:35:0;;;;;;90869:48;;;;;;;:114;;;90950:11;90962:1;90950:14;;;;;;;;:::i;:::-;;;;;;;;;:33;:14;;;;;:33;;-1:-1:-1;;;;;;;;90950:33:0;;;;;90938:45;;;;90869:114;90847:195;;;91025:1;90637:455;-1:-1:-1;;90637:455:0:o;90847:195::-;90827:3;;;;:::i;:::-;;;;90783:270;;;;91070:14;;-1:-1:-1;;;91070:14:0;;;;;;;;;;;16241:233;16313:7;-1:-1:-1;;;;;16337:19:0;;16333:60;;16365:28;;-1:-1:-1;;;16365:28:0;;;;;;;;;;;16333:60;-1:-1:-1;;;;;;16411:25:0;;;;;:18;:25;;;;;;-1:-1:-1;;;;;16411:55:0;;16241:233::o;77772:103::-;77010:13;:11;:13::i;:::-;77837:30:::1;77864:1;77837:18;:30::i;:::-;77772:103::o:0;85177:1270::-;77010:13;:11;:13::i;:::-;85458:11:::1;:18:::0;85449:27;::::1;85445:54;;85485:14;;-1:-1:-1::0;;;85485:14:0::1;;;;;;;;;;;85445:54;85523:1;85514:5;:10;85510:229;;85603:11;85615:9;85623:1;85615:5:::0;:9:::1;:::i;:::-;85603:22;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;:41:::1;:22;::::0;;::::1;;:41;::::0;-1:-1:-1;;;;;;;;85603:41:0;;::::1;::::0;::::1;85563:81:::0;;::::1;;85541:187;;;85686:26;;-1:-1:-1::0;;;85686:26:0::1;;;;;;;;;;;85541:187;85749:111;85796:20;85831:18;85749:32;:111::i;:::-;85897:4;85871:11;85883:5;85871:18;;;;;;;;:::i;:::-;;;;;;;;;;;:23;;;:30;;;;;-1:-1:-1::0;;;;;85871:30:0::1;;;;;-1:-1:-1::0;;;;;85871:30:0::1;;;;;;85945:11;85912;85924:5;85912:18;;;;;;;;:::i;:::-;;;;;;;;;;;:30;;;:44;;;;;;;;;;;;;;;;;;85999:10;85967:11;85979:5;85967:18;;;;;;;;:::i;:::-;;;;;;;;;;;:29;;:42;;;;86056:14;86020:11;86032:5;86020:18;;;;;;;;:::i;:::-;;;;;;;;;;;:33;;;:50;;;;;;;;;;;;;;;;;;86123:20;86081:11;86093:5;86081:18;;;;;;;;:::i;:::-;;;;;;;;;;;:39;;;:62;;;;;-1:-1:-1::0;;;;;86081:62:0::1;;;;;-1:-1:-1::0;;;;;86081:62:0::1;;;;;;86194:18;86154:11;86166:5;86154:18;;;;;;;;:::i;:::-;;;;;;;;;;;:37;;;:58;;;;;-1:-1:-1::0;;;;;86154:58:0::1;;;;;-1:-1:-1::0;;;;;86154:58:0::1;;;;;;-1:-1:-1::0;;;;;;;;;;;86256:5:0::1;86276:4;86295:11;86321:10;86346:14;86375:20;86410:18;86230:209;;;;;;;;;;;;:::i;:::-;;;;;;;;85177:1270:::0;;;;;;;:::o;61580:900::-;61658:16;61712:19;61746:25;61786:22;61811:16;61821:5;61811:9;:16::i;:::-;61786:41;;61842:25;61884:14;-1:-1:-1;;;;;61870:29:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61870:29:0;;61842:57;;61914:31;;:::i;:::-;61965:9;61960:472;62009:14;61994:11;:29;61960:472;;62061:15;62074:1;62061:12;:15::i;:::-;62049:27;;62099:9;:16;;;62140:8;62095:73;62190:14;;-1:-1:-1;;;;;62190:28:0;;62186:111;;62263:14;;;-1:-1:-1;62186:111:0;62340:5;-1:-1:-1;;;;;62319:26:0;:17;-1:-1:-1;;;;;62319:26:0;;62315:102;;62396:1;62370:8;62379:13;;;;;;62370:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;62315:102;62025:3;;61960:472;;;-1:-1:-1;62453:8:0;;61580:900;-1:-1:-1;;;;;;61580:900:0:o;77124:87::-;77197:6;;-1:-1:-1;;;;;77197:6:0;;77124:87::o;81170:1558::-;77010:13;:11;:13::i;:::-;81278:11:::1;:18:::0;81255:20:::1;81307:87;81331:12;81327:1;:16;81307:87;;;81365:11;:17;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;::::1;-1:-1:-1::0;;81365:17:0;;;;;::::1;;::::0;;-1:-1:-1;;;;;;81365:17:0;;;::::1;::::0;::::1;::::0;;;;::::1;;::::0;;-1:-1:-1;;;;;;81365:17:0;;;;;81345:3;::::1;::::0;::::1;:::i;:::-;;;;81307:87;;;;81413:9;81408:1313;81428:20:::0;;::::1;81408:1313;;;81479:1;81474;:6;81470:260;;81584:9:::0;;81594:5:::1;81598:1;81594::::0;:5:::1;:::i;:::-;81584:16;;;;;;;:::i;:::-;;;;;;:35;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;81527:92:0::1;:9;;81537:1;81527:12;;;;;;;:::i;:::-;;;;;;:33;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;81527:92:0::1;;81501:214;;;81669:26;;-1:-1:-1::0;;;81669:26:0::1;;;;;;;;;;;81501:214;81744:149;81795:9;;81805:1;81795:12;;;;;;;:::i;:::-;;;;;;:33;;;;;;;;;;:::i;:::-;81847:9;;81857:1;81847:12;;;;;;;:::i;:::-;;;;;;:31;;;;;;;;;;:::i;:::-;81744:32;:149::i;:::-;81908:11;81943:416;;;;;;;;81986:9;;81996:1;81986:12;;;;;;;:::i;:::-;:17;::::0;::::1;:12;::::0;;::::1;;:17:::0;;::::1;::::0;-1:-1:-1;81986:17:0::1;:::i;:::-;-1:-1:-1::0;;;;;81943:416:0::1;;;;;82039:9;;82049:1;82039:12;;;;;;;:::i;:::-;;;;;;:24;;;;;;;;;;:::i;:::-;81943:416;;;;;;82098:9;;82108:1;82098:12;;;;;;;:::i;:::-;;;;;;:23;;;81943:416;;;;82160:9;;82170:1;82160:12;;;;;;;:::i;:::-;;;;;;:27;;;;;;;;;;:::i;:::-;81943:416;;;;;;82232:9;;82242:1;82232:12;;;;;;;:::i;:::-;;;;;;:33;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;81943:416:0::1;;;;;82308:9;;82318:1;82308:12;;;;;;;:::i;:::-;;;;;;:31;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;81943:416:0;;::::1;::::0;;;81908:466;;::::1;::::0;;::::1;::::0;;-1:-1:-1;81908:466:0;;;::::1;::::0;;;;;;::::1;::::0;;::::1;;::::0;;;;::::1;::::0;::::1;;-1:-1:-1::0;;;81908:466:0::1;-1:-1:-1::0;;;;;;81908:466:0;;;-1:-1:-1;;;;;81908:466: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;;;81908:466:0::1;-1:-1:-1::0;;;;;;;;81908:466:0;;;::::1;::::0;::::1;-1:-1:-1::0;;;;;;81908:466:0;;;::::1;::::0;;::::1;::::0;;;;;;;::::1;::::0;;;::::1;;::::0;;-1:-1:-1;;;;;;;;;;;82424:1:0;82444:9;;82424:1;82444:12;;::::1;;;;;:::i;:::-;:17;::::0;::::1;:12;::::0;;::::1;;:17:::0;;::::1;::::0;-1:-1:-1;82444:17:0::1;:::i;:::-;82480:9;;82490:1;82480:12;;;;;;;:::i;:::-;;;;;;:24;;;;;;;;;;:::i;:::-;82523:9;;82533:1;82523:12;;;;;;;:::i;:::-;;;;;;:23;;;82565:9;;82575:1;82565:12;;;;;;;:::i;:::-;;;;;;:27;;;;;;;;;;:::i;:::-;82611:9;;82621:1;82611:12;;;;;;;:::i;:::-;;;;;;:33;;;;;;;;;;:::i;:::-;82663:9;;82673:1;82663:12;;;;;;;:::i;:::-;;;;;;:31;;;;;;;;;;:::i;:::-;82394:315;;;;;;;;;;;;:::i;:::-;;;;;;;;81450:3:::0;::::1;::::0;::::1;:::i;:::-;;;;81408:1313;;;;81244:1484;81170:1558:::0;;:::o;19482:104::-;19538:13;19571:7;19564:14;;;;;:::i;84286:182::-;84412:7;84444:16;84458:1;84444:13;:16::i;58620:2513::-;58763:16;58830:4;58821:5;:13;58817:45;;58843:19;;-1:-1:-1;;;58843:19:0;;;;;;;;;;;58817:45;58877:19;58911:17;58931:14;14799:7;14826:13;;14744:103;58931:14;58911:34;-1:-1:-1;59182:9:0;59175:4;:16;59171:73;;;59219:9;59212:16;;59171:73;59258:25;59286:16;59296:5;59286:9;:16::i;:::-;59258:44;;59480:4;59472:5;:12;59468:278;;;59527:12;;;59562:31;;;59558:111;;;59638:11;59618:31;;59558:111;59486:198;59468:278;;;-1:-1:-1;59729:1:0;59468:278;59760:25;59802:17;-1:-1:-1;;;;;59788:32:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59788:32:0;;59760:60;;59839:17;59860:1;59839:22;59835:78;;59889:8;-1:-1:-1;59882:15:0;;-1:-1:-1;;;59882:15:0;59835:78;60057:31;60091:26;60111:5;60091:19;:26::i;:::-;60057:60;;60132:25;60377:9;:16;;;60372:92;;-1:-1:-1;60434:14:0;;60372:92;60495:5;60478:478;60507:4;60502:1;:9;;:45;;;;;60530:17;60515:11;:32;;60502:45;60478:478;;;60585:15;60598:1;60585:12;:15::i;:::-;60573:27;;60623:9;:16;;;60664:8;60619:73;60714:14;;-1:-1:-1;;;;;60714:28:0;;60710:111;;60787:14;;;-1:-1:-1;60710:111:0;60864:5;-1:-1:-1;;;;;60843:26:0;:17;-1:-1:-1;;;;;60843:26:0;;60839:102;;60920:1;60894:8;60903:13;;;;;;60894:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;60839:102;60549:3;;60478:478;;;-1:-1:-1;;;61041:29:0;;;-1:-1:-1;61048:8:0;;-1:-1:-1;;58620:2513:0;;;;;;:::o;26355:234::-;49563:10;26450:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;26450:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;26450:60:0;;;;;;;;;;26526:55;;540:41:1;;;26450:49:0;;49563:10;26526:55;;513:18:1;26526:55:0;;;;;;;26355:234;;:::o;84572:501::-;84691:20;;:::i;:::-;84795:11;:18;84726:6;;;;84786:27;;84782:82;;84830:22;;-1:-1:-1;;;84830:22:0;;14503:2:1;84830:22:0;;;14485:21:1;14542:2;14522:18;;;14515:30;-1:-1:-1;;;14561:18:1;;;14554:42;14613:18;;84830:22:0;;;;;;;;84782:82;84874:19;84896:34;;;:27;:34;;;;;;;;84931:10;84896:46;;;;;;;;84975:25;;;:18;:25;;;;;;;85019:11;:18;;84896:46;;;;;84924:5;;85019:18;;;;;;:::i;:::-;;;;;;;;;;85011:54;;;;;;;;85019:18;;;;;;;;85011:54;;-1:-1:-1;;;;;85011:54:0;;;;-1:-1:-1;;;85011:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;85011:54:0;;;;;;;-1:-1:-1;;;85011:54:0;;;;;;;;;85039:12;;-1:-1:-1;85039:12:0;-1:-1:-1;84572:501:0;-1:-1:-1;;84572:501:0:o;89306:273::-;77010:13;:11;:13::i;:::-;89422:3:::1;80195:130;;80264:18;;80258:3;80242:13;15331:12:::0;;15118:7;15315:13;:28;;15057:323;80242:13:::1;:19;;;;:::i;:::-;:40;80238:67;;;80291:14;;-1:-1:-1::0;;;80291:14:0::1;;;;;;;;;;;80238:67;89469:3:::2;89459:13;;:7;;:13;;;;:::i;:::-;89447:9;:25;89443:54;;;89481:16;;-1:-1:-1::0;;;89481:16:0::2;;;;;;;;;;;89443:54;89508:18;89518:2;89522:3;89508:18;;:9;:18::i;:::-;89545:5;::::0;89537:34:::2;::::0;-1:-1:-1;;;;;89545:5:0;;::::2;::::0;89561:9:::2;89537:34:::0;::::2;;;::::0;89545:5:::2;89537:34:::0;89545:5;89537:34;89561:9;89545:5;89537:34;::::2;;;;;;;;;;;;;::::0;::::2;;;;33148:407:::0;33323:31;33336:4;33342:2;33346:7;33323:12;:31::i;:::-;-1:-1:-1;;;;;33369:14:0;;;:19;33365:183;;33408:56;33439:4;33445:2;33449:7;33458:5;33408:30;:56::i;:::-;33403:145;;33492:40;;-1:-1:-1;;;33492:40:0;;;;;;;;;;;57117:428;57201:21;;:::i;:::-;57235:31;;:::i;:::-;14799:7;14826:13;57310:7;:25;57277:103;;57359:9;57117:428;-1:-1:-1;;57117:428:0:o;57277:103::-;57402:21;57415:7;57402:12;:21::i;:::-;57390:33;;57438:9;:16;;;57434:65;;;57478:9;57117:428;-1:-1:-1;;57117:428:0:o;57434:65::-;57516:21;57529:7;57516:12;:21::i;89968:577::-;90088:13;90124:16;90132:7;90124;:16::i;:::-;90119:59;;90149:29;;-1:-1:-1;;;90149:29:0;;;;;;;;;;;90119:59;90191:21;90215:15;90191:39;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90267:7;90261:21;90286:1;90261:26;:276;;;;;;;;;;;;;;;;;90379:7;90413:18;90423:7;90413:9;:18::i;:::-;90458:15;90336:160;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;90241:296;89968:577;-1:-1:-1;;;89968:577:0:o;78030:201::-;77010:13;:11;:13::i;:::-;-1:-1:-1;;;;;78119:22:0;::::1;78111:73;;;::::0;-1:-1:-1;;;78111:73:0;;16839:2:1;78111:73:0::1;::::0;::::1;16821:21:1::0;16878:2;16858:18;;;16851:30;16917:34;16897:18;;;16890:62;-1:-1:-1;;;16968:18:1;;;16961:36;17014:19;;78111:73:0::1;16637:402:1::0;78111:73:0::1;78195:28;78214:8;78195:18;:28::i;:::-;78030:201:::0;:::o;83221:349::-;77010:13;:11;:13::i;:::-;83372:18:::1;;83352:17;:38;83348:111;;;83414:33;;-1:-1:-1::0;;;83414:33:0::1;;;;;;;;;;;83348:111;83469:18;:38:::0;;;83523:39:::1;::::0;3373:25:1;;;83523:39:0::1;::::0;3361:2:1;3346:18;83523:39:0::1;3227:177:1::0;27168:282:0;27233:4;27323:13;;27313:7;:23;27270:153;;;;-1:-1:-1;;27374:26:0;;;;:17;:26;;;;;;-1:-1:-1;;;27374:44:0;:49;;27168:282::o;74475:293::-;73877:1;74609:7;;:19;74601:63;;;;-1:-1:-1;;;74601:63:0;;17246:2:1;74601:63:0;;;17228:21:1;17285:2;17265:18;;;17258:30;17324:33;17304:18;;;17297:61;17375:18;;74601:63:0;17044:355:1;74601:63:0;73877:1;74742:7;:18;74475:293::o;86872:2191::-;86998:3;80195:130;;80264:18;;80258:3;80242:13;15331:12;;15118:7;15315:13;:28;;15057:323;80242:13;:19;;;;:::i;:::-;:40;80238:67;;;80291:14;;-1:-1:-1;;;80291:14:0;;;;;;;;;;;80238:67;87045:15:::1;87074:26;;:::i;:::-;87113:19;87135:43;87163:14;87135:27;:43::i;:::-;87113:65;;87199:11;87211;87199:24;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;87191:32:::1;::::0;;::::1;::::0;::::1;::::0;;87199:24:::1;::::0;;;::::1;::::0;;::::1;87191:32:::0;;-1:-1:-1;;;;;87191:32:0;::::1;::::0;;;-1:-1:-1;;;87191:32:0;;::::1;;;::::0;;::::1;::::0;;;;;;::::1;::::0;;;;;;;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;;;::::1;-1:-1:-1::0;;;;;87191:32:0;;::::1;::::0;;;;-1:-1:-1;;;87191:32:0;;::::1;;::::0;;;;87276:9:::1;::::0;87191:32;;-1:-1:-1;;87260:214:0::1;;;87333:7;::::0;87320:10;;87319:28:::1;::::0;::::1;::::0;87320:20:::1;::::0;-1:-1:-1;;;;;87320:20:0::1;;:::i;:::-;87319:28;;;;:::i;:::-;87307:9;:40;87303:69;;;87356:16;;-1:-1:-1::0;;;87356:16:0::1;;;;;;;;;;;87303:69;87260:214;;;87421:10:::0;;:16:::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;;;;;87409:28:0::1;:9;:28;87405:57;;;87446:16;;-1:-1:-1::0;;;87446:16:0::1;;;;;;;;;;;87405:57;87535:20;::::0;::::1;::::0;:24:::1;;::::0;87531:168:::1;;87620:20;::::0;::::1;::::0;87580:31:::1;::::0;;;:18:::1;:31;::::0;;;;;:60:::1;::::0;;::::1;::::0;:37:::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;:60;87576:111;;;87666:21;;-1:-1:-1::0;;;87666:21:0::1;;;;;;;;;;;87576:111;87767:18;::::0;:22;87763:156:::1;;87836:18;;87830:3;87810:23;;:17;87824:2;87810:13;:17::i;:::-;:23;;;;:::i;:::-;:44;87806:101;;;87880:27;;-1:-1:-1::0;;;87880:27:0::1;;;;;;;;;;;87806:101;88026:17;::::0;::::1;::::0;:21:::1;;::::0;88022:212:::1;;88156:17;::::0;;::::1;::::0;88086:40:::1;::::0;;;:27:::1;:40:::0;;;;;;-1:-1:-1;;;;;88086:44:0;::::1;::::0;;;;;;;;;;:87:::1;::::0;;::::1;::::0;:50:::1;::::0;88133:3;;88086:44:::1;:50;:::i;:::-;:87;;;88064:158;;;88196:26;;-1:-1:-1::0;;;88196:26:0::1;;;;;;;;;;;88064:158;88344:16;::::0;::::1;::::0;:21;88340:258:::1;;88533:5;:16;;;88404:125;88451:5;;88404:125;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;88489:20:0::1;::::0;-1:-1:-1;;;;;;18086:2:1;18057:15;;;18053:45;88489:20:0::1;::::0;::::1;18041:58:1::0;18115:12;;;-1:-1:-1;88489:20:0::1;::::0;-1:-1:-1;17912:221:1;88489:20:0::1;;;;;;;;;;;;;88479:31;;;;;;88404:24;:125::i;:::-;:145;88382:204;;88572:14;;-1:-1:-1::0;;;88572:14:0::1;;;;;;;;;;;88382:204;88610:40;::::0;;;:27:::1;:40;::::0;;;;;;;-1:-1:-1;;;;;88610:44:0;::::1;::::0;;;;;;;:51;;88658:3;;88610:40;:51:::1;::::0;88658:3;;88610:51:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;88707:3;88672:38;;:18;:31;88691:11;88672:31;;;;;;;;;;;;:38;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;88721:18:0::1;::::0;-1:-1:-1;88731:2:0;88721:18:::1;::::0;::::1;:9;:18::i;:::-;88768:9;::::0;88755:10;;-1:-1:-1;;;;;88755:22:0::1;;88752:304;;;88803:5;::::0;88819:7:::1;::::0;-1:-1:-1;;;;;88803:5:0;;::::1;::::0;88795:38:::1;::::0;88819:13:::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;88795:38;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;88856:7;:5;:7::i;:::-;-1:-1:-1::0;;;;;88848:25:0::1;:54;88897:3;88887:13;;:7;;:13;;;;:::i;:::-;88874:27;::::0;:9:::1;:27;:::i;:::-;88848:54;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;88752:304;;;88943:5;::::0;-1:-1:-1;;;;;88943:5:0::1;88935:39;88959:14;88971:2;88959:9;:14;:::i;:::-;88935:39;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;88997:7;:5;:7::i;:::-;-1:-1:-1::0;;;;;88989:25:0::1;:55;89028:14;89040:2;89028:9;:14;:::i;:::-;89015:28;::::0;:9:::1;:28;:::i;:::-;88989:55;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;88752:304;87003:2060;;;86872:2191:::0;;;;;:::o;21854:1275::-;21921:7;21956;22058:13;;22051:4;:20;22047:1015;;;22096:14;22113:23;;;:17;:23;;;;;;;-1:-1:-1;;;22202:24:0;;:29;;22198:845;;22867:113;22874:6;22884:1;22874:11;22867:113;;-1:-1:-1;;;22945:6:0;22927:25;;;;:17;:25;;;;;;22867:113;;22198:845;22073:989;22047:1015;23090:31;;-1:-1:-1;;;23090:31:0;;;;;;;;;;;23677:450;24088:11;24063:23;24059:41;24056:52;-1:-1:-1;;;;;23914:28:0;;;;24046:63;;23677:450::o;77289:132::-;49563:10;77353:7;:5;:7::i;:::-;-1:-1:-1;;;;;77353:23:0;;77345:68;;;;-1:-1:-1;;;77345:68:0;;18562:2:1;77345:68:0;;;18544:21:1;;;18581:18;;;18574:30;18640:34;18620:18;;;18613:62;18692:18;;77345:68:0;18360:356:1;78391:191:0;78484:6;;;-1:-1:-1;;;;;78501:17:0;;;-1:-1:-1;;;;;;78501:17:0;;;;;;;78534:40;;78484:6;;;78501:17;78484:6;;78534:40;;78465:16;;78534:40;78454:128;78391:191;:::o;91213:178::-;91342:3;-1:-1:-1;;;;;91333:12:0;:5;-1:-1:-1;;;;;91333:12:0;;91329:54;;91354:29;;-1:-1:-1;;;91354:29:0;;;;;;;;;;;91329:54;91213:178;;:::o;21302:161::-;21370:21;;:::i;:::-;21430:24;;;;:17;:24;;;;;;21411:44;;:18;:44::i;16556:178::-;-1:-1:-1;;;;;16645:25:0;16617:7;16645:25;;;:18;:25;;10538:2;16645:25;;;;;:50;;-1:-1:-1;;;;;16644:82:0;;16556:178::o;43308:112::-;43385:27;43395:2;43399:8;43385:27;;;;;;;;;;;;:9;:27::i;35639:716::-;35823:88;;-1:-1:-1;;;35823:88:0;;35802:4;;-1:-1:-1;;;;;35823:45:0;;;;;:88;;49563:10;;35890:4;;35896:7;;35905:5;;35823:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35823:88:0;;;;;;;;-1:-1:-1;;35823:88:0;;;;;;;;;;;;:::i;:::-;;;35819:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36106:6;:13;36123:1;36106:18;36102:235;;36152:40;;-1:-1:-1;;;36152:40:0;;;;;;;;;;;36102:235;36295:6;36289:13;36280:6;36276:2;36272:15;36265:38;35819:529;-1:-1:-1;;;;;;35982:64:0;-1:-1:-1;;;35982:64:0;;-1:-1:-1;35639:716:0;;;;;;:::o;21040:166::-;21110:21;;:::i;:::-;21151:47;21170:27;21189:7;21170:18;:27::i;:::-;21151:18;:47::i;49683:1745::-;49748:17;50182:4;50175;50169:11;50165:22;50274:1;50268:4;50261:15;50349:4;50346:1;50342:12;50335:19;;;50431:1;50426:3;50419:14;50535:3;50774:5;50756:428;50822:1;50817:3;50813:11;50806:18;;50993:2;50987:4;50983:13;50979:2;50975:22;50970:3;50962:36;51087:2;51077:13;;51144:25;50756:428;51144:25;-1:-1:-1;51214:13:0;;;-1:-1:-1;;51329:14:0;;;51391:19;;;51329:14;49683:1745;-1:-1:-1;49683:1745:0:o;64578:296::-;64661:7;64704:4;64661:7;64719:118;64743:5;:12;64739:1;:16;64719:118;;;64792:33;64802:12;64816:5;64822:1;64816:8;;;;;;;;:::i;:::-;;;;;;;64792:9;:33::i;:::-;64777:48;-1:-1:-1;64757:3:0;;;;:::i;:::-;;;;64719:118;;;-1:-1:-1;64854:12:0;64578:296;-1:-1:-1;;;64578:296:0:o;23228:366::-;23294:31;;:::i;:::-;-1:-1:-1;;;;;23338:41:0;;;;-1:-1:-1;;;;;11059:3:0;23424:33;;;23390:68;:24;;;:68;-1:-1:-1;;;23488:24:0;;:29;;23469:16;;;:48;11580:3;23557:28;;;;23528:19;;;:58;23338:9;23228:366::o;42535:689::-;42666:19;42672:2;42676:8;42666:5;:19::i;:::-;-1:-1:-1;;;;;42727:14:0;;;:19;42723:483;;42767:11;42781:13;42829:14;;;42862:233;42893:62;42932:1;42936:2;42940:7;;;;;;42949:5;42893:30;:62::i;:::-;42888:167;;42991:40;;-1:-1:-1;;;42991:40:0;;;;;;;;;;;42888:167;43090:3;43082:5;:11;42862:233;;43177:3;43160:13;;:20;43156:34;;43182:8;;;43156:34;42748:458;;42535:689;;;:::o;71618:149::-;71681:7;71712:1;71708;:5;:51;;71843:13;71937:15;;;71973:4;71966:15;;;72020:4;72004:21;;71708:51;;;-1:-1:-1;71843:13:0;71937:15;;;71973:4;71966:15;72020:4;72004:21;;;71618:149::o;36817:2966::-;36890:20;36913:13;;;36941;;;36937:44;;36963:18;;-1:-1:-1;;;36963:18:0;;;;;;;;;;;36937:44;-1:-1:-1;;;;;37469:22:0;;;;;;:18;:22;;10538:2;37469:22;;:71;;-1:-1:-1;;;;;37495:45:0;;37469:71;;;37817:139;37469:22;-1:-1:-1;24519:15:0;;24493:24;24489:46;37817:18;:139::i;:::-;37783:31;;;;:17;:31;;;;;:173;;;;-1:-1:-1;;;;;38546:25:0;;;38018:23;;;;37801:12;;38546:25;;-1:-1:-1;;;;;;;;;;;37783:31:0;;38636:335;39297:1;39283:12;39279:20;39237:346;39338:3;39329:7;39326:16;39237:346;;39556:7;39546:8;39543:1;-1:-1:-1;;;;;;;;;;;39513:1:0;39510;39505:59;39391:1;39378:15;39237:346;;;39241:77;39616:8;39628:1;39616:13;39612:45;;39638:19;;-1:-1:-1;;;39638:19:0;;;;;;;;;;;39612:45;39674:13;:19;-1:-1:-1;86641:163: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:437::-;3828:6;3836;3889:2;3877:9;3868:7;3864:23;3860:32;3857:52;;;3905:1;3902;3895:12;3857:52;3932:23;;-1:-1:-1;;;;;3967:30:1;;3964:50;;;4010:1;4007;4000:12;3964:50;4049:70;4111:7;4102:6;4091:9;4087:22;4049:70;:::i;:::-;4138:8;;4023:96;;-1:-1:-1;3742:437:1;-1:-1:-1;;;;3742:437:1:o;4184:349::-;4268:12;;-1:-1:-1;;;;;4264:38:1;4252:51;;4356:4;4345:16;;;4339:23;-1:-1:-1;;;;;4335:48:1;4319:14;;;4312:72;4372:2;4436:16;;;4430:23;4423:31;4416:39;4400:14;;;4393:63;4509:4;4498:16;;;4492:23;4517:8;4488:38;4472:14;;4465:62;4184:349::o;4538:720::-;4769:2;4821:21;;;4891:13;;4794:18;;;4913:22;;;4740:4;;4769:2;4992:15;;;;4966:2;4951:18;;;4740:4;5035:197;5049:6;5046:1;5043:13;5035:197;;;5098:52;5146:3;5137:6;5131:13;5098:52;:::i;:::-;5207:15;;;;5179:4;5170:14;;;;;5071:1;5064:9;5035:197;;5263:171;5330:20;;-1:-1:-1;;;;;5379:30:1;;5369:41;;5359:69;;5424:1;5421;5414:12;5439:184;5497:6;5550:2;5538:9;5529:7;5525:23;5521:32;5518:52;;;5566:1;5563;5556:12;5518:52;5589:28;5607:9;5589:28;:::i;5628:186::-;5687:6;5740:2;5728:9;5719:7;5715:23;5711:32;5708:52;;;5756:1;5753;5746:12;5708:52;5779:29;5798:9;5779:29;:::i;5819:171::-;5886:20;;-1:-1:-1;;;;;5935:30:1;;5925:41;;5915:69;;5980:1;5977;5970:12;5995:161;6062:20;;6122:8;6111:20;;6101:31;;6091:59;;6146:1;6143;6136:12;6161:612;6269:6;6277;6285;6293;6301;6309;6317;6370:3;6358:9;6349:7;6345:23;6341:33;6338:53;;;6387:1;6384;6377:12;6338:53;6423:9;6410:23;6400:33;;6452:37;6485:2;6474:9;6470:18;6452:37;:::i;:::-;6442:47;;6508:37;6541:2;6530:9;6526:18;6508:37;:::i;:::-;6498:47;;6592:2;6581:9;6577:18;6564:32;6554:42;;6615:38;6648:3;6637:9;6633:19;6615:38;:::i;:::-;6605:48;;6672:38;6705:3;6694:9;6690:19;6672:38;:::i;:::-;6662:48;;6729:38;6762:3;6751:9;6747:19;6729:38;:::i;:::-;6719:48;;6161:612;;;;;;;;;;:::o;6778:632::-;6949:2;7001:21;;;7071:13;;6974:18;;;7093:22;;;6920:4;;6949:2;7172:15;;;;7146:2;7131:18;;;6920:4;7215:169;7229:6;7226:1;7223:13;7215:169;;;7290:13;;7278:26;;7359:15;;;;7324:12;;;;7251:1;7244:9;7215:169;;7415:651;7534:6;7542;7595:2;7583:9;7574:7;7570:23;7566:32;7563:52;;;7611:1;7608;7601:12;7563:52;7638:23;;-1:-1:-1;;;;;7710:14:1;;;7707:34;;;7737:1;7734;7727:12;7707:34;7775:6;7764:9;7760:22;7750:32;;7820:7;7813:4;7809:2;7805:13;7801:27;7791:55;;7842:1;7839;7832:12;7791:55;7882:2;7869:16;7908:2;7900:6;7897:14;7894:34;;;7924:1;7921;7914:12;7894:34;7980:7;7975:2;7967:4;7959:6;7955:17;7951:2;7947:26;7943:35;7940:48;7937:68;;;8001:1;7998;7991:12;7937:68;8032:2;8024:11;;;;;8054:6;;-1:-1:-1;7415:651:1;;-1:-1:-1;;;;7415:651:1:o;8071:322::-;8148:6;8156;8164;8217:2;8205:9;8196:7;8192:23;8188:32;8185:52;;;8233:1;8230;8223:12;8185:52;8256:29;8275:9;8256:29;:::i;:::-;8246:39;8332:2;8317:18;;8304:32;;-1:-1:-1;8383:2:1;8368:18;;;8355:32;;8071:322;-1:-1:-1;;;8071:322:1:o;8398:347::-;8463:6;8471;8524:2;8512:9;8503:7;8499:23;8495:32;8492:52;;;8540:1;8537;8530:12;8492:52;8563:29;8582:9;8563:29;:::i;:::-;8553:39;;8642:2;8631:9;8627:18;8614:32;8689:5;8682:13;8675:21;8668:5;8665:32;8655:60;;8711:1;8708;8701:12;8655:60;8734:5;8724:15;;;8398:347;;;;;:::o;9687:258::-;9754:6;9762;9815:2;9803:9;9794:7;9790:23;9786:32;9783:52;;;9831:1;9828;9821:12;9783:52;9854:28;9872:9;9854:28;:::i;:::-;9844:38;;9901;9935:2;9924:9;9920:18;9901:38;:::i;:::-;9891:48;;9687:258;;;;;:::o;9950:127::-;10011:10;10006:3;10002:20;9999:1;9992:31;10042:4;10039:1;10032:15;10066:4;10063:1;10056:15;10082:1138;10177:6;10185;10193;10201;10254:3;10242:9;10233:7;10229:23;10225:33;10222:53;;;10271:1;10268;10261:12;10222:53;10294:29;10313:9;10294:29;:::i;:::-;10284:39;;10342:38;10376:2;10365:9;10361:18;10342:38;:::i;:::-;10332:48;-1:-1:-1;10427:2:1;10412:18;;10399:32;;-1:-1:-1;10482:2:1;10467:18;;10454:32;-1:-1:-1;;;;;10535:14:1;;;10532:34;;;10562:1;10559;10552:12;10532:34;10600:6;10589:9;10585:22;10575:32;;10645:7;10638:4;10634:2;10630:13;10626:27;10616:55;;10667:1;10664;10657:12;10616:55;10703:2;10690:16;10725:2;10721;10718:10;10715:36;;;10731:18;;:::i;:::-;10806:2;10800:9;10774:2;10860:13;;-1:-1:-1;;10856:22:1;;;10880:2;10852:31;10848:40;10836:53;;;10904:18;;;10924:22;;;10901:46;10898:72;;;10950:18;;:::i;:::-;10990:10;10986:2;10979:22;11025:2;11017:6;11010:18;11065:7;11060:2;11055;11051;11047:11;11043:20;11040:33;11037:53;;;11086:1;11083;11076:12;11037:53;11142:2;11137;11133;11129:11;11124:2;11116:6;11112:15;11099:46;11187:1;11182:2;11177;11169:6;11165:15;11161:24;11154:35;11208:6;11198:16;;;;;;;10082:1138;;;;;;;:::o;11225:264::-;11419:3;11404:19;;11432:51;11408:9;11465:6;11432:51;:::i;11494:260::-;11562:6;11570;11623:2;11611:9;11602:7;11598:23;11594:32;11591:52;;;11639:1;11636;11629:12;11591:52;11662:29;11681:9;11662:29;:::i;11759:380::-;11838:1;11834:12;;;;11881;;;11902:61;;11956:4;11948:6;11944:17;11934:27;;11902:61;12009:2;12001:6;11998:14;11978:18;11975:38;11972:161;;12055:10;12050:3;12046:20;12043:1;12036:31;12090:4;12087:1;12080:15;12118:4;12115:1;12108:15;11972:161;;11759:380;;;:::o;12354:127::-;12415:10;12410:3;12406:20;12403:1;12396:31;12446:4;12443:1;12436:15;12470:4;12467:1;12460:15;12486:127;12547:10;12542:3;12538:20;12535:1;12528:31;12578:4;12575:1;12568:15;12602:4;12599:1;12592:15;12618:135;12657:3;12678:17;;;12675:43;;12698:18;;:::i;:::-;-1:-1:-1;12745:1:1;12734:13;;12618:135::o;12758:125::-;12798:4;12826:1;12823;12820:8;12817:34;;;12831:18;;:::i;:::-;-1:-1:-1;12868:9:1;;12758:125::o;12888:709::-;13193:25;;;-1:-1:-1;;;;;13254:31:1;;;;13249:2;13234:18;;13227:59;13334:10;13322:23;;;;13317:2;13302:18;;13295:51;13377:2;13362:18;;13355:34;;;;13438:8;13426:21;13420:3;13405:19;;13398:50;-1:-1:-1;;;;;13522:15:1;;;13516:3;13501:19;;13494:44;13575:15;13569:3;13554:19;;13547:44;13180:3;13165:19;;12888:709::o;13602:127::-;13663:10;13658:3;13654:20;13651:1;13644:31;13694:4;13691:1;13684:15;13718:4;13715:1;13708:15;13734:184;13792:6;13845:2;13833:9;13824:7;13820:23;13816:32;13813:52;;;13861:1;13858;13851:12;13813:52;13884:28;13902:9;13884:28;:::i;13923:184::-;13981:6;14034:2;14022:9;14013:7;14009:23;14005:32;14002:52;;;14050:1;14047;14040:12;14002:52;14073:28;14091:9;14073:28;:::i;14112:184::-;14170:6;14223:2;14211:9;14202:7;14198:23;14194:32;14191:52;;;14239:1;14236;14229:12;14191:52;14262:28;14280:9;14262:28;:::i;14642:128::-;14682:3;14713:1;14709:6;14706:1;14703:13;14700:39;;;14719:18;;:::i;:::-;-1:-1:-1;14755:9:1;;14642:128::o;14775:168::-;14815:7;14881:1;14877;14873:6;14869:14;14866:1;14863:21;14858:1;14851:9;14844:17;14840:45;14837:71;;;14888:18;;:::i;:::-;-1:-1:-1;14928:9:1;;14775:168::o;15074:1558::-;15298:3;15336:6;15330:13;15362:4;15375:51;15419:6;15414:3;15409:2;15401:6;15397:15;15375:51;:::i;:::-;15489:13;;15448:16;;;;15511:55;15489:13;15448:16;15533:15;;;15511:55;:::i;:::-;15655:13;;15588:20;;;15628:1;;15715;15737:18;;;;15790;;;;15817:93;;15895:4;15885:8;15881:19;15869:31;;15817:93;15958:2;15948:8;15945:16;15925:18;15922:40;15919:167;;-1:-1:-1;;;15985:33:1;;16041:4;16038:1;16031:15;16071:4;15992:3;16059:17;15919:167;16102:18;16129:141;;;;16284:1;16279:328;;;;16095:512;;16129:141;-1:-1:-1;;16164:24:1;;16150:39;;16241:16;;16234:24;16220:39;;16209:51;;;-1:-1:-1;16129:141:1;;16279:328;15021:1;15014:14;;;15058:4;15045:18;;16374:1;16388:169;16402:8;16399:1;16396:15;16388:169;;;16484:14;;16469:13;;;16462:37;16527:16;;;;16419:10;;16388:169;;;16392:3;;16588:8;16581:5;16577:20;16570:27;;16095:512;-1:-1:-1;16623:3:1;;15074:1558;-1:-1:-1;;;;;;;;;;;15074:1558:1:o;17404:270::-;17443:7;-1:-1:-1;;;;;17513:10:1;;;17543;;;17576:11;;17569:19;17598:12;;;17590:21;;17565:47;17562:73;;;17615:18;;:::i;:::-;17655:13;;17404:270;-1:-1:-1;;;;17404:270:1:o;17679:228::-;17718:3;17746:10;17783:2;17780:1;17776:10;17813:2;17810:1;17806:10;17844:3;17840:2;17836:12;17831:3;17828:21;17825:47;;;17852:18;;:::i;:::-;17888:13;;17679:228;-1:-1:-1;;;;17679:228:1:o;18138:217::-;18178:1;18204;18194:132;;18248:10;18243:3;18239:20;18236:1;18229:31;18283:4;18280:1;18273:15;18311:4;18308:1;18301:15;18194:132;-1:-1:-1;18340:9:1;;18138:217::o;18721:489::-;-1:-1:-1;;;;;18990:15:1;;;18972:34;;19042:15;;19037:2;19022:18;;19015:43;19089:2;19074:18;;19067:34;;;19137:3;19132:2;19117:18;;19110:31;;;18915:4;;19158:46;;19184:19;;19176:6;19158:46;:::i;:::-;19150:54;18721:489;-1:-1:-1;;;;;;18721:489:1:o;19215:249::-;19284:6;19337:2;19325:9;19316:7;19312:23;19308:32;19305:52;;;19353:1;19350;19343:12;19305:52;19385:9;19379:16;19404:30;19428:5;19404:30;:::i

Swarm Source

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