ETH Price: $3,336.27 (-3.79%)

Token

Generative Avatars (GAVA)
 

Overview

Max Total Supply

2,600 GAVA

Holders

434

Market

Volume (24H)

0.0093 ETH

Min Price (24H)

$31.16 @ 0.009340 ETH

Max Price (24H)

$31.16 @ 0.009340 ETH
Balance
1 GAVA
0xb5d74F8BDB8AB8bb346e09eD3D09d29495B16849
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:
GenerativeAvatars

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// File: default_workspace/contracts/IDungeonRewards.sol


pragma solidity ^0.8.12;

interface IDungeonRewards {

    // so we can confirm whether a wallet holds any staked dungeons, useful for Generative Avatars gas-only mint
    function balanceOfDungeons(address owner) external view returns (uint256);
    // so we can confirm when a wallet staked their dungeons, useful for Generative Avatars gas-only mint
    function dungeonFirstStaked(address owner) external view returns (uint256);

    function balanceOfAvatars(address owner) external view returns (uint256);
    function avatarFirstStaked(address owner) external  view returns (uint256);

    function balanceOfQuests(address owner) external view returns (uint256);
    function questFirstStaked(address owner) external view returns (uint256);

    function getStakedTokens(address user) external view returns (uint256[] memory dungeons, uint256[] memory avatars, 
                                                                  uint256[] memory quests);
  
}
// File: erc721a/contracts/IERC721A.sol


// ERC721A Contracts v4.2.0
// 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();

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId`
     * (inclusive) is transferred from `from` to `to`, as defined in the
     * [ERC2309](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/extensions/IERC4907A.sol


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

pragma solidity ^0.8.4;


/**
 * @dev Interface of ERC4907A.
 */
interface IERC4907A is IERC721A {
    /**
     * The caller must own the token or be an approved operator.
     */
    error SetUserCallerNotOwnerNorApproved();

    /**
     * @dev Emitted when the `user` of an NFT or the `expires` of the `user` is changed.
     * The zero address for user indicates that there is no user address.
     */
    event UpdateUser(uint256 indexed tokenId, address indexed user, uint64 expires);

    /**
     * @dev Sets the `user` and `expires` for `tokenId`.
     * The zero address indicates there is no user.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function setUser(
        uint256 tokenId,
        address user,
        uint64 expires
    ) external;

    /**
     * @dev Returns the user address for `tokenId`.
     * The zero address indicates that there is no user or if the user is expired.
     */
    function userOf(uint256 tokenId) external view returns (address);

    /**
     * @dev Returns the user's expires of `tokenId`.
     */
    function userExpires(uint256 tokenId) external view returns (uint256);
}

// File: erc721a/contracts/ERC721A.sol


// ERC721A Contracts v4.2.0
// 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 {
    // Reference type for token approval.
    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 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 {
        if (operator == _msgSenderERC721A()) revert ApproveToCaller();

        _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]`.
        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 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 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 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.
            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`.
                )

                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 ptr) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit),
            // but we allocate 128 bytes to keep the free memory pointer 32-byte word aliged.
            // We will need 1 32-byte word to store the length,
            // and 3 32-byte words to store a maximum of 78 digits. Total: 32 + 3 * 32 = 128.
            ptr := add(mload(0x40), 128)
            // Update the free memory pointer to allocate.
            mstore(0x40, ptr)

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

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

            let length := sub(end, ptr)
            // Move the pointer 32 bytes leftwards to make room for the length.
            ptr := sub(ptr, 32)
            // Store the length.
            mstore(ptr, length)
        }
    }
}

// File: erc721a/contracts/extensions/IERC721AQueryable.sol


// ERC721A Contracts v4.2.0
// 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: erc721a/contracts/extensions/ERC721AQueryable.sol


// ERC721A Contracts v4.2.0
// 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: default_workspace/contracts/ERC4907AQueryable.sol


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

pragma solidity ^0.8.4;



/**
 * @title ERC4907A
 *
 * @dev [ERC4907](https://eips.ethereum.org/EIPS/eip-4907) compliant
 * extension of ERC721A, which allows owners and authorized addresses
 * to add a time-limited role with restricted permissions to ERC721 tokens.
 */
abstract contract ERC4907AQueryable is ERC721AQueryable, IERC4907A {
    // The bit position of `expires` in packed user info.
    uint256 private constant _BITPOS_EXPIRES = 160;

    // Mapping from token ID to user info.
    //
    // Bits Layout:
    // - [0..159]   `user`
    // - [160..223] `expires`
    mapping(uint256 => uint256) private _packedUserInfo;

    /**
     * @dev Sets the `user` and `expires` for `tokenId`.
     * The zero address indicates there is no user.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function setUser(
        uint256 tokenId,
        address user,
        uint64 expires
    ) public virtual {
        // Require the caller to be either the token owner or an approved operator.
        address owner = ownerOf(tokenId);
        if (_msgSenderERC721A() != owner)
            if (!isApprovedForAll(owner, _msgSenderERC721A()))
                if (getApproved(tokenId) != _msgSenderERC721A()) revert SetUserCallerNotOwnerNorApproved();

        _packedUserInfo[tokenId] = (uint256(expires) << _BITPOS_EXPIRES) | uint256(uint160(user));

        emit UpdateUser(tokenId, user, expires);
    }

    /**
     * @dev Returns the user address for `tokenId`.
     * The zero address indicates that there is no user or if the user is expired.
     */
    function userOf(uint256 tokenId) public view virtual returns (address) {
        uint256 packed = _packedUserInfo[tokenId];
        assembly {
            // Branchless `packed *= (block.timestamp <= expires ? 1 : 0)`.
            // If the `block.timestamp == expires`, the `lt` clause will be true
            // if there is a non-zero user address in the lower 160 bits of `packed`.
            packed := mul(
                packed,
                // `block.timestamp <= expires ? 1 : 0`.
                lt(shl(_BITPOS_EXPIRES, timestamp()), packed)
            )
        }
        return address(uint160(packed));
    }

    /**
     * @dev Returns the user's expires of `tokenId`.
     */
    function userExpires(uint256 tokenId) public view virtual returns (uint256) {
        return _packedUserInfo[tokenId] >> _BITPOS_EXPIRES;
    }

    /**
     * @dev Override of {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721A, IERC721A) returns (bool) {
        // The interface ID for ERC4907 is `0xad092b5c`,
        // as defined in [ERC4907](https://eips.ethereum.org/EIPS/eip-4907).
        return super.supportsInterface(interfaceId) || interfaceId == 0xad092b5c;
    }

    /**
     * @dev Returns the user address for `tokenId`, ignoring the expiry status.
     */
    function _explicitUserOf(uint256 tokenId) internal view virtual returns (address) {
        return address(uint160(_packedUserInfo[tokenId]));
    }
}

// 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 v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

// File: default_workspace/contracts/GenerativeAvatars.sol



pragma solidity ^0.8.12;

//import "erc721a/contracts/extensions/ERC721AQueryable.sol";


//import "./DungeonStaking/IDungeonRewards.sol";

/*

 ________  _______   ________   _______   ________  ________  _________  ___  ___      ___ _______      
|\   ____\|\  ___ \ |\   ___  \|\  ___ \ |\   __  \|\   __  \|\___   ___\\  \|\  \    /  /|\  ___ \     
\ \  \___|\ \   __/|\ \  \\ \  \ \   __/|\ \  \|\  \ \  \|\  \|___ \  \_\ \  \ \  \  /  / | \   __/|    
 \ \  \  __\ \  \_|/_\ \  \\ \  \ \  \_|/_\ \   _  _\ \   __  \   \ \  \ \ \  \ \  \/  / / \ \  \_|/__  
  \ \  \|\  \ \  \_|\ \ \  \\ \  \ \  \_|\ \ \  \\  \\ \  \ \  \   \ \  \ \ \  \ \    / /   \ \  \_|\ \ 
   \ \_______\ \_______\ \__\\ \__\ \_______\ \__\\ _\\ \__\ \__\   \ \__\ \ \__\ \__/ /     \ \_______\
    \|_______|\|_______|\|__| \|__|\|_______|\|__|\|__|\|__|\|__|    \|__|  \|__|\|__|/       \|_______|
                                                                                                        
                                                                                                        
                                                                                                        
 ________  ___      ___ ________  _________  ________  ________  ________                               
|\   __  \|\  \    /  /|\   __  \|\___   ___\\   __  \|\   __  \|\   ____\                              
\ \  \|\  \ \  \  /  / | \  \|\  \|___ \  \_\ \  \|\  \ \  \|\  \ \  \___|_                             
 \ \   __  \ \  \/  / / \ \   __  \   \ \  \ \ \   __  \ \   _  _\ \_____  \                            
  \ \  \ \  \ \    / /   \ \  \ \  \   \ \  \ \ \  \ \  \ \  \\  \\|____|\  \                           
   \ \__\ \__\ \__/ /     \ \__\ \__\   \ \__\ \ \__\ \__\ \__\\ _\ ____\_\  \                          
    \|__|\|__|\|__|/       \|__|\|__|    \|__|  \|__|\|__|\|__|\|__|\_________\                         
                                                                   \|_________|                         
                                                                                                        
*/

contract GenerativeAvatars is ERC4907AQueryable, Ownable {

    IDungeonRewards public dungeonRewardsContract;

    string public BASE_METADATA_URI = "";

    // max number of NFTs to batch mint at the same time
    uint256 MINT_BATCH_SIZE=10;

    uint256 public MAX_FREE_NFTS_PLUS_1=3001;
    uint256 public MAX_NONFREE_NFTS_PLUS_1=3001;

    // stored as seconds --> 1209600
    uint256 public MIN_STAKING_PERIOD = 4 days; // 4 days min initial staking period to qualify for free avatar mint

    uint256 public PRICE_WHITELIST = 0.05 ether;
    uint256 public PRICE_PUBLIC = 0.07 ether;

    uint256 public QUANTITY_LIMIT_WHITELIST_PLUS_1 = 2; // max 1 per whitelist
    uint256 public QUANTITY_LIMIT_PUBLIC_PLUS_1 = 6; // max 5 for each public mint transaction

    /**
      * store whether a dungeon has already used up its free mint
      */
    mapping(uint256 => bool) public dungeonFreeMints;
    /**
      * store the last time someone claimed a free mint (used to limit free mint claims to min staking period)
      */    
    mapping(address => uint256) public lastFreeMint;

    bool private locked; // for re-entrancy guard

    uint256 totalNonFree=0;
    uint256 totalFree=0;

    bool public publicSaleActive = false;
    bool public whitelistSaleActive = false; 
    bool public freeMintActive = false; 

    constructor(address _dungeonRewardsContract) ERC721A("Generative Avatars", "GAVA") {
        dungeonRewardsContract = IDungeonRewards(_dungeonRewardsContract);
    }

    modifier callerIsUser() {
        require(tx.origin == msg.sender, "Cannot be called by a contract");
        _;
    }

    modifier dungeonsStaked() {
        uint256 firstStakeDate = dungeonRewardsContract.dungeonFirstStaked(msg.sender);
        require(firstStakeDate!=0, "No dungeons staked");
        require(block.timestamp - firstStakeDate > MIN_STAKING_PERIOD && 
                block.timestamp - lastFreeMint[msg.sender] > MIN_STAKING_PERIOD, 
                        "Dungeons have not been staked long enough to qualify. If you have just minted, you must wait MIN_STAKING_PERIOD before trying again.");
        _;
    }

    // from openzeppelin-contracts/contracts/security/ReentrancyGuard.sol
    modifier nonReentrant() {
        require(!locked, "Reentrant call");
        locked = true;
        _;
        locked = false;
    }

    // for whitelisted mint 
	modifier onlyWhitelisted(uint8 _v,
                    		bytes32 _r,
		                    bytes32 _s
	) {
		require (owner() == ecrecover(
				keccak256( abi.encodePacked('\x19Ethereum Signed Message:\n32', 
                                            keccak256( abi.encodePacked(address(this), msg.sender)))), 
                                    _v, _r, _s), 
                'Not whitelisted');
		_;
	}

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

    function setBaseURI(string memory _baseMetaDataURI) public onlyOwner {
        BASE_METADATA_URI = _baseMetaDataURI;
    }

    /*
    * Pause public sale if active, make active if paused
    */
    function flipPublicSaleActive() public onlyOwner {
        publicSaleActive = !publicSaleActive;
    }
    function flipWhitelistSaleActive() public onlyOwner {
        whitelistSaleActive = !whitelistSaleActive;
    }
    function flipFreeMintActive() public onlyOwner {
        freeMintActive = !freeMintActive;
    }

    // in case we want to tweak (though mostly for testing)
    function setMinStakingPeriod(uint _minStakingPeriod) public onlyOwner {
        MIN_STAKING_PERIOD = _minStakingPeriod;
    }
    function setMaxFreeNfts(uint _maxFreeNfts) public onlyOwner {
        MAX_FREE_NFTS_PLUS_1 = _maxFreeNfts;
    }
    function setMaxNonFreeNfts(uint _maxNonFreeNfts) public onlyOwner {
        MAX_NONFREE_NFTS_PLUS_1 = _maxNonFreeNfts;
    }

    /*
    * in case Eth is volatile
    */
    function setPricePublic(uint256 _newPrice) public onlyOwner() {
        PRICE_PUBLIC = _newPrice;
    }
    /*
    * in case Eth is volatile
    */
    function setPriceWhitelist(uint256 _newPrice) public onlyOwner() {
        PRICE_WHITELIST = _newPrice;
    }
    /*
     * in case we need to adjust the wallet limit 
     */
    function setPublicQuantityLimit(uint256 _newLimit) public onlyOwner() {
        QUANTITY_LIMIT_PUBLIC_PLUS_1 = _newLimit;
    }
    /*
     * in case we need to adjust the wallet limit 
     */
    function setWhitelistQuantityLimit(uint256 _newLimit) public onlyOwner() {
        QUANTITY_LIMIT_WHITELIST_PLUS_1 = _newLimit;
    }

    /*
     * airdrops ignore wallet and per transaction limits
     */
    function airDrop(address _addr, uint256 _quantity) public onlyOwner {
        uint256 supply = totalSupply(); // store to save gas
        require(supply + _quantity < (MAX_NONFREE_NFTS_PLUS_1), "Exceeds max non-free NFT supply"); //use < rather than <= to save gas

        uint batchCount = _quantity / MINT_BATCH_SIZE;
        uint remainder = _quantity % MINT_BATCH_SIZE;

        for (uint i; i < batchCount; ++i) {
            _mint(_addr, MINT_BATCH_SIZE);
        }
        if (remainder > 0) {
            _mint(_addr, remainder);
        }

        totalNonFree+=_quantity;
    }

    function withdraw() external onlyOwner nonReentrant {
        (bool success, ) = msg.sender.call{value: address(this).balance}("");
        require(success, "Transfer failed.");
    }

    /**
      * check if your wallet qualifies for a free mint
      */
    function checkQualifyForFreeMint() public view returns (string memory)
    {
        uint256 firstStakeDate = dungeonRewardsContract.dungeonFirstStaked(msg.sender);
        if (firstStakeDate!=0 && block.timestamp - firstStakeDate > MIN_STAKING_PERIOD &&
            block.timestamp - lastFreeMint[msg.sender] > MIN_STAKING_PERIOD) {
            return "Your wallet qualifies for a free mint.";
        }
        else {
            return string.concat(string.concat(string.concat("You don't qualify for a free mint. Dungeon first staked: ", _toString(firstStakeDate)),","),
            _toString(lastFreeMint[msg.sender]));
        }
    }

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

    /**
      * return the number of free mints
      */
    function checkFreeMints() public view returns (uint256)
    {
        (uint256[] memory dungeons, uint256[] memory avatars, uint256[] memory quests) = 
                                    dungeonRewardsContract.getStakedTokens(msg.sender); 

        uint256 quantity = 0;
        for (uint256 i=0; i < dungeons.length; i++) {
            if (!dungeonFreeMints[dungeons[i]]) { // haven't already used up the free mint for this dungeon?
                quantity++;
            }
        }
        return quantity;
    }

    /**
      * free mint routine
      */
    function mintFree() external callerIsUser dungeonsStaked nonReentrant {
        require(freeMintActive, "Free mint paused");

        (uint256[] memory dungeons, uint256[] memory avatars, uint256[] memory quests) = 
                                    dungeonRewardsContract.getStakedTokens(msg.sender); 

        require (dungeons.length > 0, "You have no dungeons staked"); // not entirely necessary because of dungeonsStaked modifier, but leaving in as a sanity check

        uint256[] memory finalList = new uint256[](dungeons.length);
        uint256 quantity = 0;
        for (uint256 i=0; i < dungeons.length; i++) {
            if (!dungeonFreeMints[dungeons[i]]) { // haven't already used up the free mint for this dungeon?
                finalList[quantity++] = dungeons[i];
            }
        }

        require(quantity > 0, "You have used up all your free mints for the staked dungeons");
        require(totalFree + quantity < MAX_FREE_NFTS_PLUS_1, "Exceeds max free NFT supply"); // shouldn't need, but keeping as a sanity check

        // mint in batches so that transfers don't ever require more than 10 lookups to determine 
        // token ownership in the future (erc721a is cheap on mints, but not so cheap on transfers, which is why we do this to lower the cost of transfers)
        uint batchCount = quantity / MINT_BATCH_SIZE;
        uint remainder = quantity % MINT_BATCH_SIZE;

        for (uint i; i < batchCount; ++i) {
            _mint(msg.sender, MINT_BATCH_SIZE);
        }
        if (remainder > 0) {
            _mint(msg.sender, remainder);
        }

        for (uint i=0; i < quantity; i++) {
            dungeonFreeMints[finalList[i]]=true;  // mark these dungeon free mints as used
        }
        totalFree+=quantity;
        
        lastFreeMint[msg.sender] = block.timestamp;
    }

    /**
    * allows whitelisted addresses to mint NFTs
    */
    function mintWhitelist(uint256 _numberOfTokens, 
                            uint8 _v,
                    		bytes32 _r,
		                    bytes32 _s) public payable callerIsUser nonReentrant onlyWhitelisted(_v, _r, _s) {
        require(whitelistSaleActive, "Whitelist sale paused");
        require(_getAux(msg.sender)==0, "Already claimed whitelist spot");

        // we hold the whitelist data off-chain and verify on-chain via onlyWhilelisted; 
        // still have to check against max nft supply in case people whitelist late
        require(totalNonFree + _numberOfTokens < MAX_NONFREE_NFTS_PLUS_1, "Exceeds max non-free NFT supply"); //use < rather than <= to save gas
        require(msg.value >= PRICE_WHITELIST * _numberOfTokens, "Ether sent is not correct");
        require(_numberOfTokens < QUANTITY_LIMIT_WHITELIST_PLUS_1, "Requested too many tokens");

        _mint(msg.sender, _numberOfTokens);

        totalNonFree+=_numberOfTokens;

        _setAux(msg.sender, 1); // they claimed their whitelist spot
    }


    /**
    * Mints NFTs
    */
    function mintPublic(uint256 _numberOfTokens) public payable callerIsUser nonReentrant {
        require(publicSaleActive, "Public sale paused");
        require(totalNonFree + _numberOfTokens < MAX_NONFREE_NFTS_PLUS_1, "Exceeds max non-free NFT supply"); //use < rather than <= to save gas
        require(msg.value >= PRICE_PUBLIC * _numberOfTokens, "Ether sent is not correct");
        require(_numberOfTokens < QUANTITY_LIMIT_PUBLIC_PLUS_1, "Requested too many tokens");

        _mint(msg.sender, _numberOfTokens);
        totalNonFree+=_numberOfTokens;
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_dungeonRewardsContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"SetUserCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":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":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint64","name":"expires","type":"uint64"}],"name":"UpdateUser","type":"event"},{"inputs":[],"name":"BASE_METADATA_URI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FREE_NFTS_PLUS_1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_NONFREE_NFTS_PLUS_1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_STAKING_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE_PUBLIC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE_WHITELIST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"QUANTITY_LIMIT_PUBLIC_PLUS_1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"QUANTITY_LIMIT_WHITELIST_PLUS_1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"airDrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkFreeMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkQualifyForFreeMint","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dungeonFreeMints","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dungeonRewardsContract","outputs":[{"internalType":"contract IDungeonRewards","name":"","type":"address"}],"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":[],"name":"flipFreeMintActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipPublicSaleActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipWhitelistSaleActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"freeMintActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastFreeMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintFree","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_numberOfTokens","type":"uint256"}],"name":"mintPublic","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_numberOfTokens","type":"uint256"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"mintWhitelist","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":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSaleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseMetaDataURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxFreeNfts","type":"uint256"}],"name":"setMaxFreeNfts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxNonFreeNfts","type":"uint256"}],"name":"setMaxNonFreeNfts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minStakingPeriod","type":"uint256"}],"name":"setMinStakingPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setPricePublic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setPriceWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newLimit","type":"uint256"}],"name":"setPublicQuantityLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint64","name":"expires","type":"uint64"}],"name":"setUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newLimit","type":"uint256"}],"name":"setWhitelistQuantityLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"userExpires","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"userOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistSaleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a060405260006080908152600b906200001a908262000230565b50600a600c55610bb9600d819055600e5562054600600f5566b1a2bc2ec5000060105566f8b0a10e47000060115560026012556006601355600060178190556018556019805462ffffff191690553480156200007557600080fd5b50604051620038f0380380620038f08339810160408190526200009891620002fc565b6040518060400160405280601281526020017147656e65726174697665204176617461727360701b815250604051806040016040528060048152602001634741564160e01b8152508160029081620000f1919062000230565b50600362000100828262000230565b5050600160005550620001133362000139565b600a80546001600160a01b0319166001600160a01b03929092169190911790556200032e565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620001b657607f821691505b602082108103620001d757634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200022b57600081815260208120601f850160051c81016020861015620002065750805b601f850160051c820191505b81811015620002275782815560010162000212565b5050505b505050565b81516001600160401b038111156200024c576200024c6200018b565b62000264816200025d8454620001a1565b84620001dd565b602080601f8311600181146200029c5760008415620002835750858301515b600019600386901b1c1916600185901b17855562000227565b600085815260208120601f198616915b82811015620002cd57888601518255948401946001909101908401620002ac565b5085821015620002ec5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602082840312156200030f57600080fd5b81516001600160a01b03811681146200032757600080fd5b9392505050565b6135b2806200033e6000396000f3fe60806040526004361061036a5760003560e01c806388ee6a43116101c6578063b95f8b5f116100f7578063e030565e11610095578063efd0cbf91161006f578063efd0cbf914610a07578063f2fde38b14610a1a578063f6ecf21514610a3a578063f9f4738d14610a4f57600080fd5b8063e030565e14610989578063e985e9c5146109a9578063ee825b89146109f257600080fd5b8063c2f1f14a116100d1578063c2f1f14a146108ff578063c743dabb14610933578063c87b56dd14610949578063cb5bc2aa1461096957600080fd5b8063b95f8b5f14610898578063bc8893b4146108b8578063c23dc68f146108d257600080fd5b806399a2557a11610164578063a56d77301161013e578063a56d773014610815578063a693b19f1461082b578063b6d9ca5314610858578063b88d4fde1461087857600080fd5b806399a2557a146107bf578063a22cb465146107df578063a2769350146107ff57600080fd5b80638f430db0116101a05780638f430db0146107455780638fc88c481461075a57806395d89b411461078a578063966770c21461079f57600080fd5b806388ee6a43146106f25780638ab53447146107125780638da5cb5b1461072757600080fd5b80633ccfd60b116102a05780636352211e1161023e5780637fdc642f116102185780637fdc642f146106625780638462151c1461068257806386451396146106af578063867b7b1c146106c257600080fd5b80636352211e1461060d57806370a082311461062d578063715018a61461064d57600080fd5b80634fe8545a1161027a5780634fe8545a1461059457806355f804b3146105aa5780635bbb2177146105ca578063623c5f1e146105f757600080fd5b80633ccfd60b1461053f57806342842e0e146105545780634530a8321461057457600080fd5b8063148869d11161030d578063220b6764116102e7578063220b6764146104cb57806323b872dd146104e057806330ace69a146105005780633ad7f56c1461052057600080fd5b8063148869d11461048357806318160ddd146104995780631b5cb7f3146104b657600080fd5b806306fdde031161034957806306fdde03146103e9578063081812fc1461040b578063095ea7b31461044357806311bb5d2d1461046357600080fd5b80624b938f1461036f57806301ffc9a714610397578063045f7850146103c7575b600080fd5b34801561037b57600080fd5b50610384610a65565b6040519081526020015b60405180910390f35b3480156103a357600080fd5b506103b76103b2366004612b3c565b610b52565b604051901515815260200161038e565b3480156103d357600080fd5b506103e76103e2366004612b75565b610b7e565b005b3480156103f557600080fd5b506103fe610c6d565b60405161038e9190612bf7565b34801561041757600080fd5b5061042b610426366004612c0a565b610cff565b6040516001600160a01b03909116815260200161038e565b34801561044f57600080fd5b506103e761045e366004612b75565b610d43565b34801561046f57600080fd5b506103e761047e366004612c0a565b610de3565b34801561048f57600080fd5b50610384600e5481565b3480156104a557600080fd5b506001546000540360001901610384565b3480156104c257600080fd5b506103e7610e12565b3480156104d757600080fd5b506103fe610e50565b3480156104ec57600080fd5b506103e76104fb366004612c23565b610ede565b34801561050c57600080fd5b506103e761051b366004612c0a565b611077565b34801561052c57600080fd5b506019546103b790610100900460ff1681565b34801561054b57600080fd5b506103e76110a6565b34801561056057600080fd5b506103e761056f366004612c23565b611198565b34801561058057600080fd5b506103e761058f366004612c0a565b6111b8565b3480156105a057600080fd5b5061038460105481565b3480156105b657600080fd5b506103e76105c5366004612cfc565b6111e7565b3480156105d657600080fd5b506105ea6105e5366004612d44565b611221565b60405161038e9190612df4565b34801561060357600080fd5b50610384600d5481565b34801561061957600080fd5b5061042b610628366004612c0a565b6112e3565b34801561063957600080fd5b50610384610648366004612e36565b6112ee565b34801561065957600080fd5b506103e761133c565b34801561066e57600080fd5b506103e761067d366004612c0a565b611372565b34801561068e57600080fd5b506106a261069d366004612e36565b6113a1565b60405161038e9190612e51565b6103e76106bd366004612e89565b6114a9565b3480156106ce57600080fd5b506103b76106dd366004612c0a565b60146020526000908152604090205460ff1681565b3480156106fe57600080fd5b506103e761070d366004612c0a565b61181a565b34801561071e57600080fd5b506103e7611849565b34801561073357600080fd5b506009546001600160a01b031661042b565b34801561075157600080fd5b506103e7611e18565b34801561076657600080fd5b50610384610775366004612c0a565b60009081526008602052604090205460a01c90565b34801561079657600080fd5b506103fe611e61565b3480156107ab57600080fd5b506103e76107ba366004612c0a565b611e70565b3480156107cb57600080fd5b506106a26107da366004612ecc565b611e9f565b3480156107eb57600080fd5b506103e76107fa366004612eff565b612026565b34801561080b57600080fd5b5061038460125481565b34801561082157600080fd5b5061038460115481565b34801561083757600080fd5b50610384610846366004612e36565b60156020526000908152604090205481565b34801561086457600080fd5b50600a5461042b906001600160a01b031681565b34801561088457600080fd5b506103e7610893366004612f3b565b6120bb565b3480156108a457600080fd5b506103e76108b3366004612c0a565b612105565b3480156108c457600080fd5b506019546103b79060ff1681565b3480156108de57600080fd5b506108f26108ed366004612c0a565b612134565b60405161038e9190612fb6565b34801561090b57600080fd5b5061042b61091a366004612c0a565b6000908152600860205260409020544260a01b81110290565b34801561093f57600080fd5b50610384600f5481565b34801561095557600080fd5b506103fe610964366004612c0a565b6121bc565b34801561097557600080fd5b506019546103b79062010000900460ff1681565b34801561099557600080fd5b506103e76109a4366004612fc4565b61223f565b3480156109b557600080fd5b506103b76109c4366004613010565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156109fe57600080fd5b506103fe61230f565b6103e7610a15366004612c0a565b612468565b348015610a2657600080fd5b506103e7610a35366004612e36565b612600565b348015610a4657600080fd5b506103e761269b565b348015610a5b57600080fd5b5061038460135481565b600a546040516363c28db160e01b81523360048201526000918291829182916001600160a01b03909116906363c28db190602401600060405180830381865afa158015610ab6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ade91908101906130c2565b9250925092506000805b8451811015610b495760146000868381518110610b0757610b07613149565b60209081029190910181015182528101919091526040016000205460ff16610b375781610b3381613175565b9250505b80610b4181613175565b915050610ae8565b50949350505050565b6000610b5d826126e2565b80610b785750632b424ad760e21b6001600160e01b03198316145b92915050565b6009546001600160a01b03163314610bb15760405162461bcd60e51b8152600401610ba89061318e565b60405180910390fd5b6000610bc66001546000546000199190030190565b600e54909150610bd683836131c3565b10610bf35760405162461bcd60e51b8152600401610ba8906131db565b6000600c5483610c039190613228565b90506000600c5484610c15919061323c565b905060005b82811015610c3e57610c2e86600c54612730565b610c3781613175565b9050610c1a565b508015610c4f57610c4f8582612730565b8360176000828254610c6191906131c3565b90915550505050505050565b606060028054610c7c90613250565b80601f0160208091040260200160405190810160405280929190818152602001828054610ca890613250565b8015610cf55780601f10610cca57610100808354040283529160200191610cf5565b820191906000526020600020905b815481529060010190602001808311610cd857829003601f168201915b5050505050905090565b6000610d0a8261282e565b610d27576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610d4e826112e3565b9050336001600160a01b03821614610d8757610d6a81336109c4565b610d87576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6009546001600160a01b03163314610e0d5760405162461bcd60e51b8152600401610ba89061318e565b601355565b6009546001600160a01b03163314610e3c5760405162461bcd60e51b8152600401610ba89061318e565b6019805460ff19811660ff90911615179055565b600b8054610e5d90613250565b80601f0160208091040260200160405190810160405280929190818152602001828054610e8990613250565b8015610ed65780601f10610eab57610100808354040283529160200191610ed6565b820191906000526020600020905b815481529060010190602001808311610eb957829003601f168201915b505050505081565b6000610ee982612863565b9050836001600160a01b0316816001600160a01b031614610f1c5760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417610f6957610f4c86336109c4565b610f6957604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516610f9057604051633a954ecd60e21b815260040160405180910390fd5b8015610f9b57600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040812091909155600160e11b8416900361102d5760018401600081815260046020526040812054900361102b57600054811461102b5760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b6009546001600160a01b031633146110a15760405162461bcd60e51b8152600401610ba89061318e565b600d55565b6009546001600160a01b031633146110d05760405162461bcd60e51b8152600401610ba89061318e565b60165460ff16156110f35760405162461bcd60e51b8152600401610ba89061328a565b6016805460ff19166001179055604051600090339047908381818185875af1925050503d8060008114611142576040519150601f19603f3d011682016040523d82523d6000602084013e611147565b606091505b505090508061118b5760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b6044820152606401610ba8565b506016805460ff19169055565b6111b3838383604051806020016040528060008152506120bb565b505050565b6009546001600160a01b031633146111e25760405162461bcd60e51b8152600401610ba89061318e565b601155565b6009546001600160a01b031633146112115760405162461bcd60e51b8152600401610ba89061318e565b600b61121d82826132f8565b5050565b6060816000816001600160401b0381111561123e5761123e612c5f565b60405190808252806020026020018201604052801561129057816020015b60408051608081018252600080825260208083018290529282018190526060820152825260001990920191018161125c5790505b50905060005b828114610b49576112be8686838181106112b2576112b2613149565b90506020020135612134565b8282815181106112d0576112d0613149565b6020908102919091010152600101611296565b6000610b7882612863565b60006001600160a01b038216611317576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6009546001600160a01b031633146113665760405162461bcd60e51b8152600401610ba89061318e565b61137060006128d2565b565b6009546001600160a01b0316331461139c5760405162461bcd60e51b8152600401610ba89061318e565b601255565b606060008060006113b1856112ee565b90506000816001600160401b038111156113cd576113cd612c5f565b6040519080825280602002602001820160405280156113f6578160200160208202803683370190505b50905061142360408051608081018252600080825260208201819052918101829052606081019190915290565b60015b83861461149d5761143681612924565b915081604001516114955781516001600160a01b03161561145657815194505b876001600160a01b0316856001600160a01b031603611495578083878060010198508151811061148857611488613149565b6020026020010181815250505b600101611426565b50909695505050505050565b3233146114c85760405162461bcd60e51b8152600401610ba8906133b7565b60165460ff16156114eb5760405162461bcd60e51b8152600401610ba89061328a565b60168054600160ff1990911681179091556040516bffffffffffffffffffffffff1930606090811b8216602084015233901b1660348201528491849184919060480160408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160408051601f198184030181528282528051602091820120600084529083018083525260ff861690820152606081018490526080810183905260a0016020604051602081039080840390855afa1580156115d4573d6000803e3d6000fd5b505050602060405103516001600160a01b03166115f96009546001600160a01b031690565b6001600160a01b0316146116415760405162461bcd60e51b815260206004820152600f60248201526e139bdd081dda1a5d195b1a5cdd1959608a1b6044820152606401610ba8565b601954610100900460ff166116905760405162461bcd60e51b815260206004820152601560248201527415da1a5d195b1a5cdd081cd85b19481c185d5cd959605a1b6044820152606401610ba8565b3360009081526005602052604090205460c01c156116f05760405162461bcd60e51b815260206004820152601e60248201527f416c726561647920636c61696d65642077686974656c6973742073706f7400006044820152606401610ba8565b600e548760175461170191906131c3565b1061171e5760405162461bcd60e51b8152600401610ba8906131db565b8660105461172c91906133ee565b3410156117775760405162461bcd60e51b8152602060048201526019602482015278115d1a195c881cd95b9d081a5cc81b9bdd0818dbdc9c9958dd603a1b6044820152606401610ba8565b60125487106117c45760405162461bcd60e51b815260206004820152601960248201527852657175657374656420746f6f206d616e7920746f6b656e7360381b6044820152606401610ba8565b6117ce3388612730565b86601760008282546117e091906131c3565b909155505033600090815260056020526040902080546001600160c01b0316600160c01b17905550506016805460ff191690555050505050565b6009546001600160a01b031633146118445760405162461bcd60e51b8152600401610ba89061318e565b600f55565b3233146118685760405162461bcd60e51b8152600401610ba8906133b7565b600a54604051630eb12ceb60e21b81523360048201526000916001600160a01b031690633ac4b3ac90602401602060405180830381865afa1580156118b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d5919061340d565b90508060000361191c5760405162461bcd60e51b8152602060048201526012602482015271139bc8191d5b99d95bdb9cc81cdd185ad95960721b6044820152606401610ba8565b600f546119298242613426565b1180156119505750600f543360009081526015602052604090205461194e9042613426565b115b611a1c5760405162461bcd60e51b8152602060048201526084602482018190527f44756e67656f6e732068617665206e6f74206265656e207374616b6564206c6f60448301527f6e6720656e6f75676820746f207175616c6966792e20496620796f752068617660648301527f65206a757374206d696e7465642c20796f75206d7573742077616974204d494e908201527f5f5354414b494e475f504552494f44206265666f726520747279696e6720616760a48201526330b4b71760e11b60c482015260e401610ba8565b60165460ff1615611a3f5760405162461bcd60e51b8152600401610ba89061328a565b6016805460ff1916600117905560195462010000900460ff16611a975760405162461bcd60e51b815260206004820152601060248201526f119c9959481b5a5b9d081c185d5cd95960821b6044820152606401610ba8565b600a546040516363c28db160e01b8152336004820152600091829182916001600160a01b0316906363c28db190602401600060405180830381865afa158015611ae4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611b0c91908101906130c2565b9250925092506000835111611b635760405162461bcd60e51b815260206004820152601b60248201527f596f752068617665206e6f2064756e67656f6e73207374616b656400000000006044820152606401610ba8565b600083516001600160401b03811115611b7e57611b7e612c5f565b604051908082528060200260200182016040528015611ba7578160200160208202803683370190505b5090506000805b8551811015611c465760146000878381518110611bcd57611bcd613149565b60209081029190910181015182528101919091526040016000205460ff16611c3457858181518110611c0157611c01613149565b6020026020010151838380611c1590613175565b945081518110611c2757611c27613149565b6020026020010181815250505b80611c3e81613175565b915050611bae565b5060008111611cbd5760405162461bcd60e51b815260206004820152603c60248201527f596f752068617665207573656420757020616c6c20796f75722066726565206d60448201527f696e747320666f7220746865207374616b65642064756e67656f6e73000000006064820152608401610ba8565b600d5481601854611cce91906131c3565b10611d1b5760405162461bcd60e51b815260206004820152601b60248201527f45786365656473206d61782066726565204e465420737570706c7900000000006044820152606401610ba8565b6000600c5482611d2b9190613228565b90506000600c5483611d3d919061323c565b905060005b82811015611d6657611d5633600c54612730565b611d5f81613175565b9050611d42565b508015611d7757611d773382612730565b60005b83811015611dda57600160146000878481518110611d9a57611d9a613149565b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611dd290613175565b915050611d7a565b508260186000828254611ded91906131c3565b909155505033600090815260156020526040902042905550506016805460ff19169055505050505050565b6009546001600160a01b03163314611e425760405162461bcd60e51b8152600401610ba89061318e565b6019805462ff0000198116620100009182900460ff1615909102179055565b606060038054610c7c90613250565b6009546001600160a01b03163314611e9a5760405162461bcd60e51b8152600401610ba89061318e565b600e55565b6060818310611ec157604051631960ccad60e11b815260040160405180910390fd5b600080611ecd60005490565b90506001851015611edd57600194505b80841115611ee9578093505b6000611ef4876112ee565b905084861015611f135785850381811015611f0d578091505b50611f17565b5060005b6000816001600160401b03811115611f3157611f31612c5f565b604051908082528060200260200182016040528015611f5a578160200160208202803683370190505b50905081600003611f7057935061201f92505050565b6000611f7b88612134565b905060008160400151611f8c575080515b885b888114158015611f9e5750848714155b1561201357611fac81612924565b9250826040015161200b5782516001600160a01b031615611fcc57825191505b8a6001600160a01b0316826001600160a01b03160361200b5780848880600101995081518110611ffe57611ffe613149565b6020026020010181815250505b600101611f8e565b50505092835250909150505b9392505050565b336001600160a01b0383160361204f5760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6120c6848484610ede565b6001600160a01b0383163b156120ff576120e284848484612960565b6120ff576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6009546001600160a01b0316331461212f5760405162461bcd60e51b8152600401610ba89061318e565b601055565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152600183108061218d57506000548310155b156121985792915050565b6121a183612924565b90508060400151156121b35792915050565b61201f83612a4c565b60606121c78261282e565b6121e457604051630a14c4b560e41b815260040160405180910390fd5b60006121ee612a81565b9050805160000361220e576040518060200160405280600081525061201f565b8061221884612a90565b60405160200161222992919061343d565b6040516020818303038152906040529392505050565b600061224a846112e3565b9050336001600160a01b0382161461229b5761226681336109c4565b61229b573361227485610cff565b6001600160a01b03161461229b576040516309e3bb1d60e31b815260040160405180910390fd5b6000848152600860209081526040918290206001600160a01b03861660a086901b67ffffffffffffffff60a01b16811790915591516001600160401b038516815286917f4e06b4e7000e659094299b3533b47b6aa8ad048e95e872d23d1f4ee55af89cfe910160405180910390a350505050565b600a54604051630eb12ceb60e21b81523360048201526060916000916001600160a01b0390911690633ac4b3ac90602401602060405180830381865afa15801561235d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612381919061340d565b9050801580159061239c5750600f5461239a8242613426565b115b80156123c25750600f54336000908152601560205260409020546123c09042613426565b115b156123e6576040518060600160405280602681526020016135576026913991505090565b6123ef81612a90565b6040516020016123ff919061346c565b60408051601f198184030181529082905261241c916020016134d7565b60408051601f198184030181529181523360009081526015602052205461244290612a90565b60405160200161245392919061343d565b60405160208183030381529060405291505090565b3233146124875760405162461bcd60e51b8152600401610ba8906133b7565b60165460ff16156124aa5760405162461bcd60e51b8152600401610ba89061328a565b6016805460ff1916600117905560195460ff166124fe5760405162461bcd60e51b8152602060048201526012602482015271141d589b1a58c81cd85b19481c185d5cd95960721b6044820152606401610ba8565b600e548160175461250f91906131c3565b1061252c5760405162461bcd60e51b8152600401610ba8906131db565b8060115461253a91906133ee565b3410156125855760405162461bcd60e51b8152602060048201526019602482015278115d1a195c881cd95b9d081a5cc81b9bdd0818dbdc9c9958dd603a1b6044820152606401610ba8565b60135481106125d25760405162461bcd60e51b815260206004820152601960248201527852657175657374656420746f6f206d616e7920746f6b656e7360381b6044820152606401610ba8565b6125dc3382612730565b80601760008282546125ee91906131c3565b90915550506016805460ff1916905550565b6009546001600160a01b0316331461262a5760405162461bcd60e51b8152600401610ba89061318e565b6001600160a01b03811661268f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ba8565b612698816128d2565b50565b6009546001600160a01b031633146126c55760405162461bcd60e51b8152600401610ba89061318e565b6019805461ff001981166101009182900460ff1615909102179055565b60006301ffc9a760e01b6001600160e01b03198316148061271357506380ac58cd60e01b6001600160e01b03198316145b80610b785750506001600160e01b031916635b5e139f60e01b1490565b60008054908290036127555760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b81811461280457808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001016127cc565b508160000361282557604051622e076360e81b815260040160405180910390fd5b60005550505050565b600081600111158015612842575060005482105b8015610b78575050600090815260046020526040902054600160e01b161590565b600081806001116128b9576000548110156128b95760008181526004602052604081205490600160e01b821690036128b7575b8060000361201f575060001901600081815260046020526040902054612896565b505b604051636f96cda160e11b815260040160405180910390fd5b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604080516080810182526000808252602082018190529181018290526060810191909152600082815260046020526040902054610b7890612adf565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906129959033908990889088906004016134fc565b6020604051808303816000875af19250505080156129d0575060408051601f3d908101601f191682019092526129cd91810190613539565b60015b612a2e573d8080156129fe576040519150601f19603f3d011682016040523d82523d6000602084013e612a03565b606091505b508051600003612a26576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b604080516080810182526000808252602082018190529181018290526060810191909152610b78612a7c83612863565b612adf565b6060600b8054610c7c90613250565b604080516080810191829052607f0190826030600a8206018353600a90045b8015612acd57600183039250600a81066030018353600a9004612aaf565b50819003601f19909101908152919050565b604080516080810182526001600160a01b038316815260a083901c6001600160401b03166020820152600160e01b831615159181019190915260e89190911c606082015290565b6001600160e01b03198116811461269857600080fd5b600060208284031215612b4e57600080fd5b813561201f81612b26565b80356001600160a01b0381168114612b7057600080fd5b919050565b60008060408385031215612b8857600080fd5b612b9183612b59565b946020939093013593505050565b60005b83811015612bba578181015183820152602001612ba2565b838111156120ff5750506000910152565b60008151808452612be3816020860160208601612b9f565b601f01601f19169290920160200192915050565b60208152600061201f6020830184612bcb565b600060208284031215612c1c57600080fd5b5035919050565b600080600060608486031215612c3857600080fd5b612c4184612b59565b9250612c4f60208501612b59565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715612c9d57612c9d612c5f565b604052919050565b60006001600160401b03831115612cbe57612cbe612c5f565b612cd1601f8401601f1916602001612c75565b9050828152838383011115612ce557600080fd5b828260208301376000602084830101529392505050565b600060208284031215612d0e57600080fd5b81356001600160401b03811115612d2457600080fd5b8201601f81018413612d3557600080fd5b612a4484823560208401612ca5565b60008060208385031215612d5757600080fd5b82356001600160401b0380821115612d6e57600080fd5b818501915085601f830112612d8257600080fd5b813581811115612d9157600080fd5b8660208260051b8501011115612da657600080fd5b60209290920196919550909350505050565b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b6020808252825182820181905260009190848201906040850190845b8181101561149d57612e23838551612db8565b9284019260809290920191600101612e10565b600060208284031215612e4857600080fd5b61201f82612b59565b6020808252825182820181905260009190848201906040850190845b8181101561149d57835183529284019291840191600101612e6d565b60008060008060808587031215612e9f57600080fd5b84359350602085013560ff81168114612eb757600080fd5b93969395505050506040820135916060013590565b600080600060608486031215612ee157600080fd5b612eea84612b59565b95602085013595506040909401359392505050565b60008060408385031215612f1257600080fd5b612f1b83612b59565b915060208301358015158114612f3057600080fd5b809150509250929050565b60008060008060808587031215612f5157600080fd5b612f5a85612b59565b9350612f6860208601612b59565b92506040850135915060608501356001600160401b03811115612f8a57600080fd5b8501601f81018713612f9b57600080fd5b612faa87823560208401612ca5565b91505092959194509250565b60808101610b788284612db8565b600080600060608486031215612fd957600080fd5b83359250612fe960208501612b59565b915060408401356001600160401b038116811461300557600080fd5b809150509250925092565b6000806040838503121561302357600080fd5b61302c83612b59565b915061303a60208401612b59565b90509250929050565b600082601f83011261305457600080fd5b815160206001600160401b0382111561306f5761306f612c5f565b8160051b61307e828201612c75565b928352848101820192828101908785111561309857600080fd5b83870192505b848310156130b75782518252918301919083019061309e565b979650505050505050565b6000806000606084860312156130d757600080fd5b83516001600160401b03808211156130ee57600080fd5b6130fa87838801613043565b9450602086015191508082111561311057600080fd5b61311c87838801613043565b9350604086015191508082111561313257600080fd5b5061313f86828701613043565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016131875761318761315f565b5060010190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600082198211156131d6576131d661315f565b500190565b6020808252601f908201527f45786365656473206d6178206e6f6e2d66726565204e465420737570706c7900604082015260600190565b634e487b7160e01b600052601260045260246000fd5b60008261323757613237613212565b500490565b60008261324b5761324b613212565b500690565b600181811c9082168061326457607f821691505b60208210810361328457634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600e908201526d1499595b9d1c985b9d0818d85b1b60921b604082015260600190565b601f8211156111b357600081815260208120601f850160051c810160208610156132d95750805b601f850160051c820191505b8181101561106f578281556001016132e5565b81516001600160401b0381111561331157613311612c5f565b6133258161331f8454613250565b846132b2565b602080601f83116001811461335a57600084156133425750858301515b600019600386901b1c1916600185901b17855561106f565b600085815260208120601f198616915b828110156133895788860151825594840194600190910190840161336a565b50858210156133a75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252601e908201527f43616e6e6f742062652063616c6c6564206279206120636f6e74726163740000604082015260600190565b60008160001904831182151516156134085761340861315f565b500290565b60006020828403121561341f57600080fd5b5051919050565b6000828210156134385761343861315f565b500390565b6000835161344f818460208801612b9f565b835190830190613463818360208801612b9f565b01949350505050565b7f596f7520646f6e2774207175616c69667920666f7220612066726565206d696e81527f742e2044756e67656f6e206669727374207374616b65643a20000000000000006020820152600082516134ca816039850160208701612b9f565b9190910160390192915050565b600082516134e9818460208701612b9f565b600b60fa1b920191825250600101919050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061352f90830184612bcb565b9695505050505050565b60006020828403121561354b57600080fd5b815161201f81612b2656fe596f75722077616c6c6574207175616c696669657320666f7220612066726565206d696e742ea2646970667358221220f3c50bcc8d74b7423082ddf7ade229859a6e53f5f418b6a1d7fe2721cf7a483064736f6c634300080f0033000000000000000000000000287787f55723f7a816aa37de1dbd72a4671de1cc

Deployed Bytecode

0x60806040526004361061036a5760003560e01c806388ee6a43116101c6578063b95f8b5f116100f7578063e030565e11610095578063efd0cbf91161006f578063efd0cbf914610a07578063f2fde38b14610a1a578063f6ecf21514610a3a578063f9f4738d14610a4f57600080fd5b8063e030565e14610989578063e985e9c5146109a9578063ee825b89146109f257600080fd5b8063c2f1f14a116100d1578063c2f1f14a146108ff578063c743dabb14610933578063c87b56dd14610949578063cb5bc2aa1461096957600080fd5b8063b95f8b5f14610898578063bc8893b4146108b8578063c23dc68f146108d257600080fd5b806399a2557a11610164578063a56d77301161013e578063a56d773014610815578063a693b19f1461082b578063b6d9ca5314610858578063b88d4fde1461087857600080fd5b806399a2557a146107bf578063a22cb465146107df578063a2769350146107ff57600080fd5b80638f430db0116101a05780638f430db0146107455780638fc88c481461075a57806395d89b411461078a578063966770c21461079f57600080fd5b806388ee6a43146106f25780638ab53447146107125780638da5cb5b1461072757600080fd5b80633ccfd60b116102a05780636352211e1161023e5780637fdc642f116102185780637fdc642f146106625780638462151c1461068257806386451396146106af578063867b7b1c146106c257600080fd5b80636352211e1461060d57806370a082311461062d578063715018a61461064d57600080fd5b80634fe8545a1161027a5780634fe8545a1461059457806355f804b3146105aa5780635bbb2177146105ca578063623c5f1e146105f757600080fd5b80633ccfd60b1461053f57806342842e0e146105545780634530a8321461057457600080fd5b8063148869d11161030d578063220b6764116102e7578063220b6764146104cb57806323b872dd146104e057806330ace69a146105005780633ad7f56c1461052057600080fd5b8063148869d11461048357806318160ddd146104995780631b5cb7f3146104b657600080fd5b806306fdde031161034957806306fdde03146103e9578063081812fc1461040b578063095ea7b31461044357806311bb5d2d1461046357600080fd5b80624b938f1461036f57806301ffc9a714610397578063045f7850146103c7575b600080fd5b34801561037b57600080fd5b50610384610a65565b6040519081526020015b60405180910390f35b3480156103a357600080fd5b506103b76103b2366004612b3c565b610b52565b604051901515815260200161038e565b3480156103d357600080fd5b506103e76103e2366004612b75565b610b7e565b005b3480156103f557600080fd5b506103fe610c6d565b60405161038e9190612bf7565b34801561041757600080fd5b5061042b610426366004612c0a565b610cff565b6040516001600160a01b03909116815260200161038e565b34801561044f57600080fd5b506103e761045e366004612b75565b610d43565b34801561046f57600080fd5b506103e761047e366004612c0a565b610de3565b34801561048f57600080fd5b50610384600e5481565b3480156104a557600080fd5b506001546000540360001901610384565b3480156104c257600080fd5b506103e7610e12565b3480156104d757600080fd5b506103fe610e50565b3480156104ec57600080fd5b506103e76104fb366004612c23565b610ede565b34801561050c57600080fd5b506103e761051b366004612c0a565b611077565b34801561052c57600080fd5b506019546103b790610100900460ff1681565b34801561054b57600080fd5b506103e76110a6565b34801561056057600080fd5b506103e761056f366004612c23565b611198565b34801561058057600080fd5b506103e761058f366004612c0a565b6111b8565b3480156105a057600080fd5b5061038460105481565b3480156105b657600080fd5b506103e76105c5366004612cfc565b6111e7565b3480156105d657600080fd5b506105ea6105e5366004612d44565b611221565b60405161038e9190612df4565b34801561060357600080fd5b50610384600d5481565b34801561061957600080fd5b5061042b610628366004612c0a565b6112e3565b34801561063957600080fd5b50610384610648366004612e36565b6112ee565b34801561065957600080fd5b506103e761133c565b34801561066e57600080fd5b506103e761067d366004612c0a565b611372565b34801561068e57600080fd5b506106a261069d366004612e36565b6113a1565b60405161038e9190612e51565b6103e76106bd366004612e89565b6114a9565b3480156106ce57600080fd5b506103b76106dd366004612c0a565b60146020526000908152604090205460ff1681565b3480156106fe57600080fd5b506103e761070d366004612c0a565b61181a565b34801561071e57600080fd5b506103e7611849565b34801561073357600080fd5b506009546001600160a01b031661042b565b34801561075157600080fd5b506103e7611e18565b34801561076657600080fd5b50610384610775366004612c0a565b60009081526008602052604090205460a01c90565b34801561079657600080fd5b506103fe611e61565b3480156107ab57600080fd5b506103e76107ba366004612c0a565b611e70565b3480156107cb57600080fd5b506106a26107da366004612ecc565b611e9f565b3480156107eb57600080fd5b506103e76107fa366004612eff565b612026565b34801561080b57600080fd5b5061038460125481565b34801561082157600080fd5b5061038460115481565b34801561083757600080fd5b50610384610846366004612e36565b60156020526000908152604090205481565b34801561086457600080fd5b50600a5461042b906001600160a01b031681565b34801561088457600080fd5b506103e7610893366004612f3b565b6120bb565b3480156108a457600080fd5b506103e76108b3366004612c0a565b612105565b3480156108c457600080fd5b506019546103b79060ff1681565b3480156108de57600080fd5b506108f26108ed366004612c0a565b612134565b60405161038e9190612fb6565b34801561090b57600080fd5b5061042b61091a366004612c0a565b6000908152600860205260409020544260a01b81110290565b34801561093f57600080fd5b50610384600f5481565b34801561095557600080fd5b506103fe610964366004612c0a565b6121bc565b34801561097557600080fd5b506019546103b79062010000900460ff1681565b34801561099557600080fd5b506103e76109a4366004612fc4565b61223f565b3480156109b557600080fd5b506103b76109c4366004613010565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156109fe57600080fd5b506103fe61230f565b6103e7610a15366004612c0a565b612468565b348015610a2657600080fd5b506103e7610a35366004612e36565b612600565b348015610a4657600080fd5b506103e761269b565b348015610a5b57600080fd5b5061038460135481565b600a546040516363c28db160e01b81523360048201526000918291829182916001600160a01b03909116906363c28db190602401600060405180830381865afa158015610ab6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ade91908101906130c2565b9250925092506000805b8451811015610b495760146000868381518110610b0757610b07613149565b60209081029190910181015182528101919091526040016000205460ff16610b375781610b3381613175565b9250505b80610b4181613175565b915050610ae8565b50949350505050565b6000610b5d826126e2565b80610b785750632b424ad760e21b6001600160e01b03198316145b92915050565b6009546001600160a01b03163314610bb15760405162461bcd60e51b8152600401610ba89061318e565b60405180910390fd5b6000610bc66001546000546000199190030190565b600e54909150610bd683836131c3565b10610bf35760405162461bcd60e51b8152600401610ba8906131db565b6000600c5483610c039190613228565b90506000600c5484610c15919061323c565b905060005b82811015610c3e57610c2e86600c54612730565b610c3781613175565b9050610c1a565b508015610c4f57610c4f8582612730565b8360176000828254610c6191906131c3565b90915550505050505050565b606060028054610c7c90613250565b80601f0160208091040260200160405190810160405280929190818152602001828054610ca890613250565b8015610cf55780601f10610cca57610100808354040283529160200191610cf5565b820191906000526020600020905b815481529060010190602001808311610cd857829003601f168201915b5050505050905090565b6000610d0a8261282e565b610d27576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610d4e826112e3565b9050336001600160a01b03821614610d8757610d6a81336109c4565b610d87576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6009546001600160a01b03163314610e0d5760405162461bcd60e51b8152600401610ba89061318e565b601355565b6009546001600160a01b03163314610e3c5760405162461bcd60e51b8152600401610ba89061318e565b6019805460ff19811660ff90911615179055565b600b8054610e5d90613250565b80601f0160208091040260200160405190810160405280929190818152602001828054610e8990613250565b8015610ed65780601f10610eab57610100808354040283529160200191610ed6565b820191906000526020600020905b815481529060010190602001808311610eb957829003601f168201915b505050505081565b6000610ee982612863565b9050836001600160a01b0316816001600160a01b031614610f1c5760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417610f6957610f4c86336109c4565b610f6957604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516610f9057604051633a954ecd60e21b815260040160405180910390fd5b8015610f9b57600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040812091909155600160e11b8416900361102d5760018401600081815260046020526040812054900361102b57600054811461102b5760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b6009546001600160a01b031633146110a15760405162461bcd60e51b8152600401610ba89061318e565b600d55565b6009546001600160a01b031633146110d05760405162461bcd60e51b8152600401610ba89061318e565b60165460ff16156110f35760405162461bcd60e51b8152600401610ba89061328a565b6016805460ff19166001179055604051600090339047908381818185875af1925050503d8060008114611142576040519150601f19603f3d011682016040523d82523d6000602084013e611147565b606091505b505090508061118b5760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b6044820152606401610ba8565b506016805460ff19169055565b6111b3838383604051806020016040528060008152506120bb565b505050565b6009546001600160a01b031633146111e25760405162461bcd60e51b8152600401610ba89061318e565b601155565b6009546001600160a01b031633146112115760405162461bcd60e51b8152600401610ba89061318e565b600b61121d82826132f8565b5050565b6060816000816001600160401b0381111561123e5761123e612c5f565b60405190808252806020026020018201604052801561129057816020015b60408051608081018252600080825260208083018290529282018190526060820152825260001990920191018161125c5790505b50905060005b828114610b49576112be8686838181106112b2576112b2613149565b90506020020135612134565b8282815181106112d0576112d0613149565b6020908102919091010152600101611296565b6000610b7882612863565b60006001600160a01b038216611317576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6009546001600160a01b031633146113665760405162461bcd60e51b8152600401610ba89061318e565b61137060006128d2565b565b6009546001600160a01b0316331461139c5760405162461bcd60e51b8152600401610ba89061318e565b601255565b606060008060006113b1856112ee565b90506000816001600160401b038111156113cd576113cd612c5f565b6040519080825280602002602001820160405280156113f6578160200160208202803683370190505b50905061142360408051608081018252600080825260208201819052918101829052606081019190915290565b60015b83861461149d5761143681612924565b915081604001516114955781516001600160a01b03161561145657815194505b876001600160a01b0316856001600160a01b031603611495578083878060010198508151811061148857611488613149565b6020026020010181815250505b600101611426565b50909695505050505050565b3233146114c85760405162461bcd60e51b8152600401610ba8906133b7565b60165460ff16156114eb5760405162461bcd60e51b8152600401610ba89061328a565b60168054600160ff1990911681179091556040516bffffffffffffffffffffffff1930606090811b8216602084015233901b1660348201528491849184919060480160408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160408051601f198184030181528282528051602091820120600084529083018083525260ff861690820152606081018490526080810183905260a0016020604051602081039080840390855afa1580156115d4573d6000803e3d6000fd5b505050602060405103516001600160a01b03166115f96009546001600160a01b031690565b6001600160a01b0316146116415760405162461bcd60e51b815260206004820152600f60248201526e139bdd081dda1a5d195b1a5cdd1959608a1b6044820152606401610ba8565b601954610100900460ff166116905760405162461bcd60e51b815260206004820152601560248201527415da1a5d195b1a5cdd081cd85b19481c185d5cd959605a1b6044820152606401610ba8565b3360009081526005602052604090205460c01c156116f05760405162461bcd60e51b815260206004820152601e60248201527f416c726561647920636c61696d65642077686974656c6973742073706f7400006044820152606401610ba8565b600e548760175461170191906131c3565b1061171e5760405162461bcd60e51b8152600401610ba8906131db565b8660105461172c91906133ee565b3410156117775760405162461bcd60e51b8152602060048201526019602482015278115d1a195c881cd95b9d081a5cc81b9bdd0818dbdc9c9958dd603a1b6044820152606401610ba8565b60125487106117c45760405162461bcd60e51b815260206004820152601960248201527852657175657374656420746f6f206d616e7920746f6b656e7360381b6044820152606401610ba8565b6117ce3388612730565b86601760008282546117e091906131c3565b909155505033600090815260056020526040902080546001600160c01b0316600160c01b17905550506016805460ff191690555050505050565b6009546001600160a01b031633146118445760405162461bcd60e51b8152600401610ba89061318e565b600f55565b3233146118685760405162461bcd60e51b8152600401610ba8906133b7565b600a54604051630eb12ceb60e21b81523360048201526000916001600160a01b031690633ac4b3ac90602401602060405180830381865afa1580156118b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d5919061340d565b90508060000361191c5760405162461bcd60e51b8152602060048201526012602482015271139bc8191d5b99d95bdb9cc81cdd185ad95960721b6044820152606401610ba8565b600f546119298242613426565b1180156119505750600f543360009081526015602052604090205461194e9042613426565b115b611a1c5760405162461bcd60e51b8152602060048201526084602482018190527f44756e67656f6e732068617665206e6f74206265656e207374616b6564206c6f60448301527f6e6720656e6f75676820746f207175616c6966792e20496620796f752068617660648301527f65206a757374206d696e7465642c20796f75206d7573742077616974204d494e908201527f5f5354414b494e475f504552494f44206265666f726520747279696e6720616760a48201526330b4b71760e11b60c482015260e401610ba8565b60165460ff1615611a3f5760405162461bcd60e51b8152600401610ba89061328a565b6016805460ff1916600117905560195462010000900460ff16611a975760405162461bcd60e51b815260206004820152601060248201526f119c9959481b5a5b9d081c185d5cd95960821b6044820152606401610ba8565b600a546040516363c28db160e01b8152336004820152600091829182916001600160a01b0316906363c28db190602401600060405180830381865afa158015611ae4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611b0c91908101906130c2565b9250925092506000835111611b635760405162461bcd60e51b815260206004820152601b60248201527f596f752068617665206e6f2064756e67656f6e73207374616b656400000000006044820152606401610ba8565b600083516001600160401b03811115611b7e57611b7e612c5f565b604051908082528060200260200182016040528015611ba7578160200160208202803683370190505b5090506000805b8551811015611c465760146000878381518110611bcd57611bcd613149565b60209081029190910181015182528101919091526040016000205460ff16611c3457858181518110611c0157611c01613149565b6020026020010151838380611c1590613175565b945081518110611c2757611c27613149565b6020026020010181815250505b80611c3e81613175565b915050611bae565b5060008111611cbd5760405162461bcd60e51b815260206004820152603c60248201527f596f752068617665207573656420757020616c6c20796f75722066726565206d60448201527f696e747320666f7220746865207374616b65642064756e67656f6e73000000006064820152608401610ba8565b600d5481601854611cce91906131c3565b10611d1b5760405162461bcd60e51b815260206004820152601b60248201527f45786365656473206d61782066726565204e465420737570706c7900000000006044820152606401610ba8565b6000600c5482611d2b9190613228565b90506000600c5483611d3d919061323c565b905060005b82811015611d6657611d5633600c54612730565b611d5f81613175565b9050611d42565b508015611d7757611d773382612730565b60005b83811015611dda57600160146000878481518110611d9a57611d9a613149565b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611dd290613175565b915050611d7a565b508260186000828254611ded91906131c3565b909155505033600090815260156020526040902042905550506016805460ff19169055505050505050565b6009546001600160a01b03163314611e425760405162461bcd60e51b8152600401610ba89061318e565b6019805462ff0000198116620100009182900460ff1615909102179055565b606060038054610c7c90613250565b6009546001600160a01b03163314611e9a5760405162461bcd60e51b8152600401610ba89061318e565b600e55565b6060818310611ec157604051631960ccad60e11b815260040160405180910390fd5b600080611ecd60005490565b90506001851015611edd57600194505b80841115611ee9578093505b6000611ef4876112ee565b905084861015611f135785850381811015611f0d578091505b50611f17565b5060005b6000816001600160401b03811115611f3157611f31612c5f565b604051908082528060200260200182016040528015611f5a578160200160208202803683370190505b50905081600003611f7057935061201f92505050565b6000611f7b88612134565b905060008160400151611f8c575080515b885b888114158015611f9e5750848714155b1561201357611fac81612924565b9250826040015161200b5782516001600160a01b031615611fcc57825191505b8a6001600160a01b0316826001600160a01b03160361200b5780848880600101995081518110611ffe57611ffe613149565b6020026020010181815250505b600101611f8e565b50505092835250909150505b9392505050565b336001600160a01b0383160361204f5760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6120c6848484610ede565b6001600160a01b0383163b156120ff576120e284848484612960565b6120ff576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6009546001600160a01b0316331461212f5760405162461bcd60e51b8152600401610ba89061318e565b601055565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152600183108061218d57506000548310155b156121985792915050565b6121a183612924565b90508060400151156121b35792915050565b61201f83612a4c565b60606121c78261282e565b6121e457604051630a14c4b560e41b815260040160405180910390fd5b60006121ee612a81565b9050805160000361220e576040518060200160405280600081525061201f565b8061221884612a90565b60405160200161222992919061343d565b6040516020818303038152906040529392505050565b600061224a846112e3565b9050336001600160a01b0382161461229b5761226681336109c4565b61229b573361227485610cff565b6001600160a01b03161461229b576040516309e3bb1d60e31b815260040160405180910390fd5b6000848152600860209081526040918290206001600160a01b03861660a086901b67ffffffffffffffff60a01b16811790915591516001600160401b038516815286917f4e06b4e7000e659094299b3533b47b6aa8ad048e95e872d23d1f4ee55af89cfe910160405180910390a350505050565b600a54604051630eb12ceb60e21b81523360048201526060916000916001600160a01b0390911690633ac4b3ac90602401602060405180830381865afa15801561235d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612381919061340d565b9050801580159061239c5750600f5461239a8242613426565b115b80156123c25750600f54336000908152601560205260409020546123c09042613426565b115b156123e6576040518060600160405280602681526020016135576026913991505090565b6123ef81612a90565b6040516020016123ff919061346c565b60408051601f198184030181529082905261241c916020016134d7565b60408051601f198184030181529181523360009081526015602052205461244290612a90565b60405160200161245392919061343d565b60405160208183030381529060405291505090565b3233146124875760405162461bcd60e51b8152600401610ba8906133b7565b60165460ff16156124aa5760405162461bcd60e51b8152600401610ba89061328a565b6016805460ff1916600117905560195460ff166124fe5760405162461bcd60e51b8152602060048201526012602482015271141d589b1a58c81cd85b19481c185d5cd95960721b6044820152606401610ba8565b600e548160175461250f91906131c3565b1061252c5760405162461bcd60e51b8152600401610ba8906131db565b8060115461253a91906133ee565b3410156125855760405162461bcd60e51b8152602060048201526019602482015278115d1a195c881cd95b9d081a5cc81b9bdd0818dbdc9c9958dd603a1b6044820152606401610ba8565b60135481106125d25760405162461bcd60e51b815260206004820152601960248201527852657175657374656420746f6f206d616e7920746f6b656e7360381b6044820152606401610ba8565b6125dc3382612730565b80601760008282546125ee91906131c3565b90915550506016805460ff1916905550565b6009546001600160a01b0316331461262a5760405162461bcd60e51b8152600401610ba89061318e565b6001600160a01b03811661268f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ba8565b612698816128d2565b50565b6009546001600160a01b031633146126c55760405162461bcd60e51b8152600401610ba89061318e565b6019805461ff001981166101009182900460ff1615909102179055565b60006301ffc9a760e01b6001600160e01b03198316148061271357506380ac58cd60e01b6001600160e01b03198316145b80610b785750506001600160e01b031916635b5e139f60e01b1490565b60008054908290036127555760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b81811461280457808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001016127cc565b508160000361282557604051622e076360e81b815260040160405180910390fd5b60005550505050565b600081600111158015612842575060005482105b8015610b78575050600090815260046020526040902054600160e01b161590565b600081806001116128b9576000548110156128b95760008181526004602052604081205490600160e01b821690036128b7575b8060000361201f575060001901600081815260046020526040902054612896565b505b604051636f96cda160e11b815260040160405180910390fd5b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604080516080810182526000808252602082018190529181018290526060810191909152600082815260046020526040902054610b7890612adf565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906129959033908990889088906004016134fc565b6020604051808303816000875af19250505080156129d0575060408051601f3d908101601f191682019092526129cd91810190613539565b60015b612a2e573d8080156129fe576040519150601f19603f3d011682016040523d82523d6000602084013e612a03565b606091505b508051600003612a26576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b604080516080810182526000808252602082018190529181018290526060810191909152610b78612a7c83612863565b612adf565b6060600b8054610c7c90613250565b604080516080810191829052607f0190826030600a8206018353600a90045b8015612acd57600183039250600a81066030018353600a9004612aaf565b50819003601f19909101908152919050565b604080516080810182526001600160a01b038316815260a083901c6001600160401b03166020820152600160e01b831615159181019190915260e89190911c606082015290565b6001600160e01b03198116811461269857600080fd5b600060208284031215612b4e57600080fd5b813561201f81612b26565b80356001600160a01b0381168114612b7057600080fd5b919050565b60008060408385031215612b8857600080fd5b612b9183612b59565b946020939093013593505050565b60005b83811015612bba578181015183820152602001612ba2565b838111156120ff5750506000910152565b60008151808452612be3816020860160208601612b9f565b601f01601f19169290920160200192915050565b60208152600061201f6020830184612bcb565b600060208284031215612c1c57600080fd5b5035919050565b600080600060608486031215612c3857600080fd5b612c4184612b59565b9250612c4f60208501612b59565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715612c9d57612c9d612c5f565b604052919050565b60006001600160401b03831115612cbe57612cbe612c5f565b612cd1601f8401601f1916602001612c75565b9050828152838383011115612ce557600080fd5b828260208301376000602084830101529392505050565b600060208284031215612d0e57600080fd5b81356001600160401b03811115612d2457600080fd5b8201601f81018413612d3557600080fd5b612a4484823560208401612ca5565b60008060208385031215612d5757600080fd5b82356001600160401b0380821115612d6e57600080fd5b818501915085601f830112612d8257600080fd5b813581811115612d9157600080fd5b8660208260051b8501011115612da657600080fd5b60209290920196919550909350505050565b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b6020808252825182820181905260009190848201906040850190845b8181101561149d57612e23838551612db8565b9284019260809290920191600101612e10565b600060208284031215612e4857600080fd5b61201f82612b59565b6020808252825182820181905260009190848201906040850190845b8181101561149d57835183529284019291840191600101612e6d565b60008060008060808587031215612e9f57600080fd5b84359350602085013560ff81168114612eb757600080fd5b93969395505050506040820135916060013590565b600080600060608486031215612ee157600080fd5b612eea84612b59565b95602085013595506040909401359392505050565b60008060408385031215612f1257600080fd5b612f1b83612b59565b915060208301358015158114612f3057600080fd5b809150509250929050565b60008060008060808587031215612f5157600080fd5b612f5a85612b59565b9350612f6860208601612b59565b92506040850135915060608501356001600160401b03811115612f8a57600080fd5b8501601f81018713612f9b57600080fd5b612faa87823560208401612ca5565b91505092959194509250565b60808101610b788284612db8565b600080600060608486031215612fd957600080fd5b83359250612fe960208501612b59565b915060408401356001600160401b038116811461300557600080fd5b809150509250925092565b6000806040838503121561302357600080fd5b61302c83612b59565b915061303a60208401612b59565b90509250929050565b600082601f83011261305457600080fd5b815160206001600160401b0382111561306f5761306f612c5f565b8160051b61307e828201612c75565b928352848101820192828101908785111561309857600080fd5b83870192505b848310156130b75782518252918301919083019061309e565b979650505050505050565b6000806000606084860312156130d757600080fd5b83516001600160401b03808211156130ee57600080fd5b6130fa87838801613043565b9450602086015191508082111561311057600080fd5b61311c87838801613043565b9350604086015191508082111561313257600080fd5b5061313f86828701613043565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016131875761318761315f565b5060010190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600082198211156131d6576131d661315f565b500190565b6020808252601f908201527f45786365656473206d6178206e6f6e2d66726565204e465420737570706c7900604082015260600190565b634e487b7160e01b600052601260045260246000fd5b60008261323757613237613212565b500490565b60008261324b5761324b613212565b500690565b600181811c9082168061326457607f821691505b60208210810361328457634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600e908201526d1499595b9d1c985b9d0818d85b1b60921b604082015260600190565b601f8211156111b357600081815260208120601f850160051c810160208610156132d95750805b601f850160051c820191505b8181101561106f578281556001016132e5565b81516001600160401b0381111561331157613311612c5f565b6133258161331f8454613250565b846132b2565b602080601f83116001811461335a57600084156133425750858301515b600019600386901b1c1916600185901b17855561106f565b600085815260208120601f198616915b828110156133895788860151825594840194600190910190840161336a565b50858210156133a75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252601e908201527f43616e6e6f742062652063616c6c6564206279206120636f6e74726163740000604082015260600190565b60008160001904831182151516156134085761340861315f565b500290565b60006020828403121561341f57600080fd5b5051919050565b6000828210156134385761343861315f565b500390565b6000835161344f818460208801612b9f565b835190830190613463818360208801612b9f565b01949350505050565b7f596f7520646f6e2774207175616c69667920666f7220612066726565206d696e81527f742e2044756e67656f6e206669727374207374616b65643a20000000000000006020820152600082516134ca816039850160208701612b9f565b9190910160390192915050565b600082516134e9818460208701612b9f565b600b60fa1b920191825250600101919050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061352f90830184612bcb565b9695505050505050565b60006020828403121561354b57600080fd5b815161201f81612b2656fe596f75722077616c6c6574207175616c696669657320666f7220612066726565206d696e742ea2646970667358221220f3c50bcc8d74b7423082ddf7ade229859a6e53f5f418b6a1d7fe2721cf7a483064736f6c634300080f0033

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

000000000000000000000000287787f55723f7a816aa37de1dbd72a4671de1cc

-----Decoded View---------------
Arg [0] : _dungeonRewardsContract (address): 0x287787F55723f7a816aA37De1dbD72a4671De1cc

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000287787f55723f7a816aa37de1dbd72a4671de1cc


Deployed Bytecode Sourcemap

71628:10723:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78145:529;;;;;;;;;;;;;:::i;:::-;;;160:25:1;;;148:2;133:18;78145:529:0;;;;;;;;65365:337;;;;;;;;;;-1:-1:-1;65365:337:0;;;;;:::i;:::-;;:::i;:::-;;;747:14:1;;740:22;722:41;;710:2;695:18;65365:337:0;582:187:1;76422:604:0;;;;;;;;;;-1:-1:-1;76422:604:0;;;;;:::i;:::-;;:::i;:::-;;21737:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;28220:218::-;;;;;;;;;;-1:-1:-1;28220:218:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2311:32:1;;;2293:51;;2281:2;2266:18;28220:218:0;2147:203:1;27661:400:0;;;;;;;;;;-1:-1:-1;27661:400:0;;;;;:::i;:::-;;:::i;76000:129::-;;;;;;;;;;-1:-1:-1;76000:129:0;;;;;:::i;:::-;;:::i;71933:43::-;;;;;;;;;;;;;;;;17488:323;;;;;;;;;;-1:-1:-1;78054:1:0;17762:12;17549:7;17746:13;:28;-1:-1:-1;;17746:46:0;17488:323;;74826:104;;;;;;;;;;;;;:::i;71748:36::-;;;;;;;;;;;;;:::i;31927:2817::-;;;;;;;;;;-1:-1:-1;31927:2817:0;;;;;:::i;:::-;;:::i;75355:114::-;;;;;;;;;;-1:-1:-1;75355:114:0;;;;;:::i;:::-;;:::i;72905:39::-;;;;;;;;;;-1:-1:-1;72905:39:0;;;;;;;;;;;77034:186;;;;;;;;;;;;;:::i;34840:185::-;;;;;;;;;;-1:-1:-1;34840:185:0;;;;;:::i;:::-;;:::i;75656:105::-;;;;;;;;;;-1:-1:-1;75656:105:0;;;;;:::i;:::-;;:::i;72143:43::-;;;;;;;;;;;;;;;;74620:124;;;;;;;;;;-1:-1:-1;74620:124:0;;;;;:::i;:::-;;:::i;57839:528::-;;;;;;;;;;-1:-1:-1;57839:528:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;71886:40::-;;;;;;;;;;;;;;;;23130:152;;;;;;;;;;-1:-1:-1;23130:152:0;;;;;:::i;:::-;;:::i;18672:233::-;;;;;;;;;;-1:-1:-1;18672:233:0;;;;;:::i;:::-;;:::i;68572:103::-;;;;;;;;;;;;;:::i;76204:135::-;;;;;;;;;;-1:-1:-1;76204:135:0;;;;;:::i;:::-;;:::i;61715:900::-;;;;;;;;;;-1:-1:-1;61715:900:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;80676:1053::-;;;;;;:::i;:::-;;:::i;72506:48::-;;;;;;;;;;-1:-1:-1;72506:48:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;75222:127;;;;;;;;;;-1:-1:-1;75222:127:0;;;;;:::i;:::-;;:::i;78728:1874::-;;;;;;;;;;;;;:::i;67921:87::-;;;;;;;;;;-1:-1:-1;67994:6:0;;-1:-1:-1;;;;;67994:6:0;67921:87;;75055:98;;;;;;;;;;;;;:::i;65140:145::-;;;;;;;;;;-1:-1:-1;65140:145:0;;;;;:::i;:::-;65207:7;65234:24;;;:15;:24;;;;;;63200:3;65234:43;;65140:145;21913:104;;;;;;;;;;;;;:::i;75475:126::-;;;;;;;;;;-1:-1:-1;75475:126:0;;;;;:::i;:::-;;:::i;58755:2513::-;;;;;;;;;;-1:-1:-1;58755:2513:0;;;;;:::i;:::-;;:::i;28778:308::-;;;;;;;;;;-1:-1:-1;28778:308:0;;;;;:::i;:::-;;:::i;72242:50::-;;;;;;;;;;;;;;;;72193:40;;;;;;;;;;;;;;;;72696:47;;;;;;;;;;-1:-1:-1;72696:47:0;;;;;:::i;:::-;;;;;;;;;;;;;;71694:45;;;;;;;;;;-1:-1:-1;71694:45:0;;;;-1:-1:-1;;;;;71694:45:0;;;35623:399;;;;;;;;;;-1:-1:-1;35623:399:0;;;;;:::i;:::-;;:::i;75814:111::-;;;;;;;;;;-1:-1:-1;75814:111:0;;;;;:::i;:::-;;:::i;72862:36::-;;;;;;;;;;-1:-1:-1;72862:36:0;;;;;;;;57252:428;;;;;;;;;;-1:-1:-1;57252:428:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;64421:639::-;;;;;;;;;;-1:-1:-1;64421:639:0;;;;;:::i;:::-;64483:7;64520:24;;;:15;:24;;;;;;64964:11;64947:15;64943:33;64940:45;-1:-1:-1;64835:165:0;;64421:639;72023:42;;;;;;;;;;;;;;;;22123:318;;;;;;;;;;-1:-1:-1;22123:318:0;;;;;:::i;:::-;;:::i;72952:34::-;;;;;;;;;;-1:-1:-1;72952:34:0;;;;;;;;;;;63639:619;;;;;;;;;;-1:-1:-1;63639:619:0;;;;;:::i;:::-;;:::i;29243:164::-;;;;;;;;;;-1:-1:-1;29243:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;29364:25:0;;;29340:4;29364:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;29243:164;77303:651;;;;;;;;;;;;;:::i;81774:572::-;;;;;;:::i;:::-;;:::i;68830:201::-;;;;;;;;;;-1:-1:-1;68830:201:0;;;;;:::i;:::-;;:::i;74936:113::-;;;;;;;;;;;;;:::i;72322:47::-;;;;;;;;;;;;;;;;78145:529;78336:22;;:50;;-1:-1:-1;;;78336:50:0;;78375:10;78336:50;;;2293:51:1;78192:7:0;;;;;;;;-1:-1:-1;;;;;78336:22:0;;;;:38;;2266:18:1;;78336:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;78336:50:0;;;;;;;;;;;;:::i;:::-;78217:169;;;;;;78400:16;78436:9;78431:210;78453:8;:15;78449:1;:19;78431:210;;;78495:16;:29;78512:8;78521:1;78512:11;;;;;;;;:::i;:::-;;;;;;;;;;;;78495:29;;;;;;;;;;-1:-1:-1;78495:29:0;;;;78490:140;;78604:10;;;;:::i;:::-;;;;78490:140;78470:3;;;;:::i;:::-;;;;78431:210;;;-1:-1:-1;78658:8:0;78145:529;-1:-1:-1;;;;78145:529:0:o;65365:337::-;65469:4;65629:36;65653:11;65629:23;:36::i;:::-;:65;;;-1:-1:-1;;;;;;;;;;65669:25:0;;;65629:65;65622:72;65365:337;-1:-1:-1;;65365:337:0:o;76422:604::-;67994:6;;-1:-1:-1;;;;;67994:6:0;66725:10;68141:23;68133:68;;;;-1:-1:-1;;;68133:68:0;;;;;;;:::i;:::-;;;;;;;;;76501:14:::1;76518:13;78054:1:::0;17762:12;17549:7;17746:13;-1:-1:-1;;17746:28:0;;;:46;;17488:323;76518:13:::1;76593:23;::::0;76501:30;;-1:-1:-1;76571:18:0::1;76580:9:::0;76501:30;76571:18:::1;:::i;:::-;:46;76563:90;;;;-1:-1:-1::0;;;76563:90:0::1;;;;;;;:::i;:::-;76701:15;76731;;76719:9;:27;;;;:::i;:::-;76701:45;;76757:14;76786:15;;76774:9;:27;;;;:::i;:::-;76757:44;;76819:6;76814:90;76831:10;76827:1;:14;76814:90;;;76863:29;76869:5;76876:15;;76863:5;:29::i;:::-;76843:3;::::0;::::1;:::i;:::-;;;76814:90;;;-1:-1:-1::0;76918:13:0;;76914:69:::1;;76948:23;76954:5;76961:9;76948:5;:23::i;:::-;77009:9;76995:12;;:23;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;76422:604:0:o;21737:100::-;21791:13;21824:5;21817:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21737:100;:::o;28220:218::-;28296:7;28321:16;28329:7;28321;:16::i;:::-;28316:64;;28346:34;;-1:-1:-1;;;28346:34:0;;;;;;;;;;;28316:64;-1:-1:-1;28400:24:0;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;28400:30:0;;28220:218::o;27661:400::-;27742:13;27758:16;27766:7;27758;:16::i;:::-;27742:32;-1:-1:-1;66725:10:0;-1:-1:-1;;;;;27791:28:0;;;27787:175;;27839:44;27856:5;66725:10;29243:164;:::i;27839:44::-;27834:128;;27911:35;;-1:-1:-1;;;27911:35:0;;;;;;;;;;;27834:128;27974:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;;;;;27974:35:0;-1:-1:-1;;;;;27974:35:0;;;;;;;;;28025:28;;27974:24;;28025:28;;;;;;;27731:330;27661:400;;:::o;76000:129::-;67994:6;;-1:-1:-1;;;;;67994:6:0;66725:10;68141:23;68133:68;;;;-1:-1:-1;;;68133:68:0;;;;;;;:::i;:::-;76081:28:::1;:40:::0;76000:129::o;74826:104::-;67994:6;;-1:-1:-1;;;;;67994:6:0;66725:10;68141:23;68133:68;;;;-1:-1:-1;;;68133:68:0;;;;;;;:::i;:::-;74906:16:::1;::::0;;-1:-1:-1;;74886:36:0;::::1;74906:16;::::0;;::::1;74905:17;74886:36;::::0;;74826:104::o;71748:36::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;31927:2817::-;32061:27;32091;32110:7;32091:18;:27::i;:::-;32061:57;;32176:4;-1:-1:-1;;;;;32135:45:0;32151:19;-1:-1:-1;;;;;32135:45:0;;32131:86;;32189:28;;-1:-1:-1;;;32189:28:0;;;;;;;;;;;32131:86;32231:27;31041:24;;;:15;:24;;;;;31263:26;;66725:10;30666:30;;;-1:-1:-1;;;;;30359:28:0;;30644:20;;;30641:56;32417:180;;32510:43;32527:4;66725:10;29243:164;:::i;32510:43::-;32505:92;;32562:35;;-1:-1:-1;;;32562:35:0;;;;;;;;;;;32505:92;-1:-1:-1;;;;;32614:16:0;;32610:52;;32639:23;;-1:-1:-1;;;32639:23:0;;;;;;;;;;;32610:52;32811:15;32808:160;;;32951:1;32930:19;32923:30;32808:160;-1:-1:-1;;;;;33348:24:0;;;;;;;:18;:24;;;;;;33346:26;;-1:-1:-1;;33346:26:0;;;33417:22;;;;;;;;;33415:24;;-1:-1:-1;33415:24:0;;;26519:11;26494:23;26490:41;26477:63;-1:-1:-1;;;26477:63:0;33710:26;;;;:17;:26;;;;;:175;;;;-1:-1:-1;;;34005:47:0;;:52;;34001:627;;34110:1;34100:11;;34078:19;34233:30;;;:17;:30;;;;;;:35;;34229:384;;34371:13;;34356:11;:28;34352:242;;34518:30;;;;:17;:30;;;;;:52;;;34352:242;34059:569;34001:627;34675:7;34671:2;-1:-1:-1;;;;;34656:27:0;34665:4;-1:-1:-1;;;;;34656:27:0;;;;;;;;;;;34694:42;32050:2694;;;31927:2817;;;:::o;75355:114::-;67994:6;;-1:-1:-1;;;;;67994:6:0;66725:10;68141:23;68133:68;;;;-1:-1:-1;;;68133:68:0;;;;;;;:::i;:::-;75426:20:::1;:35:::0;75355:114::o;77034:186::-;67994:6;;-1:-1:-1;;;;;67994:6:0;66725:10;68141:23;68133:68;;;;-1:-1:-1;;;68133:68:0;;;;;;;:::i;:::-;73941:6:::1;::::0;::::1;;73940:7;73932:34;;;;-1:-1:-1::0;;;73932:34:0::1;;;;;;;:::i;:::-;73977:6;:13:::0;;-1:-1:-1;;73977:13:0::1;73986:4;73977:13;::::0;;77116:49:::2;::::0;-1:-1:-1;;77116:10:0::2;::::0;77139:21:::2;::::0;-1:-1:-1;77116:49:0;-1:-1:-1;77116:49:0;77139:21;77116:10;:49:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77097:68;;;77184:7;77176:36;;;::::0;-1:-1:-1;;;77176:36:0;;13859:2:1;77176:36:0::2;::::0;::::2;13841:21:1::0;13898:2;13878:18;;;13871:30;-1:-1:-1;;;13917:18:1;;;13910:46;13973:18;;77176:36:0::2;13657:340:1::0;77176:36:0::2;-1:-1:-1::0;74013:6:0::1;:14:::0;;-1:-1:-1;;74013:14:0::1;::::0;;77034:186::o;34840:185::-;34978:39;34995:4;35001:2;35005:7;34978:39;;;;;;;;;;;;:16;:39::i;:::-;34840:185;;;:::o;75656:105::-;67994:6;;-1:-1:-1;;;;;67994:6:0;66725:10;68141:23;68133:68;;;;-1:-1:-1;;;68133:68:0;;;;;;;:::i;:::-;75729:12:::1;:24:::0;75656:105::o;74620:124::-;67994:6;;-1:-1:-1;;;;;67994:6:0;66725:10;68141:23;68133:68;;;;-1:-1:-1;;;68133:68:0;;;;;;;:::i;:::-;74700:17:::1;:36;74720:16:::0;74700:17;:36:::1;:::i;:::-;;74620:124:::0;:::o;57839:528::-;57983:23;58074:8;58049:22;58074:8;-1:-1:-1;;;;;58141:36:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58141:36:0;;-1:-1:-1;;58141:36:0;;;;;;;;;;;;58104:73;;58197:9;58192:125;58213:14;58208:1;:19;58192:125;;58269:32;58289:8;;58298:1;58289:11;;;;;;;:::i;:::-;;;;;;;58269:19;:32::i;:::-;58253:10;58264:1;58253:13;;;;;;;;:::i;:::-;;;;;;;;;;:48;58229:3;;58192:125;;23130:152;23202:7;23245:27;23264:7;23245:18;:27::i;18672:233::-;18744:7;-1:-1:-1;;;;;18768:19:0;;18764:60;;18796:28;;-1:-1:-1;;;18796:28:0;;;;;;;;;;;18764:60;-1:-1:-1;;;;;;18842:25:0;;;;;:18;:25;;;;;;-1:-1:-1;;;;;18842:55:0;;18672:233::o;68572:103::-;67994:6;;-1:-1:-1;;;;;67994:6:0;66725:10;68141:23;68133:68;;;;-1:-1:-1;;;68133:68:0;;;;;;;:::i;:::-;68637:30:::1;68664:1;68637:18;:30::i;:::-;68572:103::o:0;76204:135::-;67994:6;;-1:-1:-1;;;;;67994:6:0;66725:10;68141:23;68133:68;;;;-1:-1:-1;;;68133:68:0;;;;;;;:::i;:::-;76288:31:::1;:43:::0;76204:135::o;61715:900::-;61793:16;61847:19;61881:25;61921:22;61946:16;61956:5;61946:9;:16::i;:::-;61921:41;;61977:25;62019:14;-1:-1:-1;;;;;62005:29:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62005:29:0;;61977:57;;62049:31;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62049:31:0;78054:1;62095:472;62144:14;62129:11;:29;62095:472;;62196:15;62209:1;62196:12;:15::i;:::-;62184:27;;62234:9;:16;;;62275:8;62230:73;62325:14;;-1:-1:-1;;;;;62325:28:0;;62321:111;;62398:14;;;-1:-1:-1;62321:111:0;62475:5;-1:-1:-1;;;;;62454:26:0;:17;-1:-1:-1;;;;;62454:26:0;;62450:102;;62531:1;62505:8;62514:13;;;;;;62505:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;62450:102;62160:3;;62095:472;;;-1:-1:-1;62588:8:0;;61715:900;-1:-1:-1;;;;;;61715:900:0:o;80676:1053::-;73214:9;73227:10;73214:23;73206:66;;;;-1:-1:-1;;;73206:66:0;;;;;;;:::i;:::-;73941:6:::1;::::0;::::1;;73940:7;73932:34;;;;-1:-1:-1::0;;;73932:34:0::1;;;;;;;:::i;:::-;73977:6;:13:::0;;73986:4:::1;-1:-1:-1::0;;73977:13:0;;::::1;::::0;::::1;::::0;;;74340:43:::2;::::0;-1:-1:-1;;74365:4:0::2;16792:2:1::0;16788:15;;;16784:24;;74340:43:0::2;::::0;::::2;16772:37:1::0;74372:10:0::2;16843:15:1::0;;16839:24;16825:12;;;16818:46;80891:2:0;;80895;;80899;;73986:4;16880:12:1;;74340:43:0::2;::::0;;-1:-1:-1;;74340:43:0;;::::2;::::0;;;;;;;74329:55;;74340:43:::2;74329:55:::0;;::::2;::::0;17145:66:1;74230:155:0;;::::2;17133:79:1::0;;;;17228:12;;;17221:28;17265:12;;74230:155:0::2;::::0;;-1:-1:-1;;74230:155:0;;::::2;::::0;;;;;;74219:167;;74230:155:::2;74219:167:::0;;::::2;::::0;74203:234:::2;::::0;;;;::::2;::::0;;;17515:25:1;17588:4;17576:17;;17556:18;;;17549:45;17610:18;;;17603:34;;;17653:18;;;17646:34;;;17487:19;;74203:234:0::2;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;-1:-1:-1::0;;;;;74192:245:0::2;:7;67994:6:::0;;-1:-1:-1;;;;;67994:6:0;;67921:87;74192:7:::2;-1:-1:-1::0;;;;;74192:245:0::2;;74183:292;;;::::0;-1:-1:-1;;;74183:292:0;;17893:2:1;74183:292:0::2;::::0;::::2;17875:21:1::0;17932:2;17912:18;;;17905:30;-1:-1:-1;;;17951:18:1;;;17944:45;18006:18;;74183:292:0::2;17691:339:1::0;74183:292:0::2;80922:19:::3;::::0;::::3;::::0;::::3;;;80914:53;;;::::0;-1:-1:-1;;;80914:53:0;;18237:2:1;80914:53:0::3;::::0;::::3;18219:21:1::0;18276:2;18256:18;;;18249:30;-1:-1:-1;;;18295:18:1;;;18288:51;18356:18;;80914:53:0::3;18035:345:1::0;80914:53:0::3;80994:10;19614:6:::0;19647:25;;;:18;:25;;;;;;13205:3;19647:40;80986:22;80978:65:::3;;;::::0;-1:-1:-1;;;80978:65:0;;18587:2:1;80978:65:0::3;::::0;::::3;18569:21:1::0;18626:2;18606:18;;;18599:30;18665:32;18645:18;;;18638:60;18715:18;;80978:65:0::3;18385:354:1::0;80978:65:0::3;81273:23;;81255:15;81240:12;;:30;;;;:::i;:::-;:56;81232:100;;;;-1:-1:-1::0;;;81232:100:0::3;;;;;;;:::i;:::-;81417:15;81399;;:33;;;;:::i;:::-;81386:9;:46;;81378:84;;;::::0;-1:-1:-1;;;81378:84:0;;19119:2:1;81378:84:0::3;::::0;::::3;19101:21:1::0;19158:2;19138:18;;;19131:30;-1:-1:-1;;;19177:18:1;;;19170:55;19242:18;;81378:84:0::3;18917:349:1::0;81378:84:0::3;81499:31;;81481:15;:49;81473:87;;;::::0;-1:-1:-1;;;81473:87:0;;19473:2:1;81473:87:0::3;::::0;::::3;19455:21:1::0;19512:2;19492:18;;;19485:30;-1:-1:-1;;;19531:18:1;;;19524:55;19596:18;;81473:87:0::3;19271:349:1::0;81473:87:0::3;81573:34;81579:10;81591:15;81573:5;:34::i;:::-;81634:15;81620:12;;:29;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;81670:10:0::3;19956:14:::0;19973:25;;;:18;:25;;;;;;;-1:-1:-1;;;;;20173:32:0;-1:-1:-1;;;20172:63:0;20246:34;;-1:-1:-1;;74013:6:0::1;:14:::0;;-1:-1:-1;;74013:14:0::1;::::0;;-1:-1:-1;;;;;80676:1053:0:o;75222:127::-;67994:6;;-1:-1:-1;;;;;67994:6:0;66725:10;68141:23;68133:68;;;;-1:-1:-1;;;68133:68:0;;;;;;;:::i;:::-;75303:18:::1;:38:::0;75222:127::o;78728:1874::-;73214:9;73227:10;73214:23;73206:66;;;;-1:-1:-1;;;73206:66:0;;;;;;;:::i;:::-;73362:22:::1;::::0;:53:::1;::::0;-1:-1:-1;;;73362:53:0;;73404:10:::1;73362:53;::::0;::::1;2293:51:1::0;73337:22:0::1;::::0;-1:-1:-1;;;;;73362:22:0::1;::::0;:41:::1;::::0;2266:18:1;;73362:53:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73337:78;;73434:14;73450:1;73434:17:::0;73426:48:::1;;;::::0;-1:-1:-1;;;73426:48:0;;20016:2:1;73426:48:0::1;::::0;::::1;19998:21:1::0;20055:2;20035:18;;;20028:30;-1:-1:-1;;;20074:18:1;;;20067:48;20132:18;;73426:48:0::1;19814:342:1::0;73426:48:0::1;73528:18;::::0;73493:32:::1;73511:14:::0;73493:15:::1;:32;:::i;:::-;:53;:138;;;;-1:-1:-1::0;73613:18:0::1;::::0;73599:10:::1;73586:24;::::0;;;:12:::1;:24;::::0;;;;;73568:42:::1;::::0;:15:::1;:42;:::i;:::-;:63;73493:138;73485:309;;;::::0;-1:-1:-1;;;73485:309:0;;20493:2:1;73485:309:0::1;::::0;::::1;20475:21:1::0;20532:3;20512:18;;;20505:31;;;20572:34;20552:18;;;20545:62;20643:34;20623:18;;;20616:62;20715:34;20694:19;;;20687:63;20787:34;20766:19;;;20759:63;-1:-1:-1;;;20838:19:1;;;20831:35;20883:19;;73485:309:0::1;20291:617:1::0;73485:309:0::1;73941:6:::2;::::0;::::2;;73940:7;73932:34;;;;-1:-1:-1::0;;;73932:34:0::2;;;;;;;:::i;:::-;73977:6;:13:::0;;-1:-1:-1;;73977:13:0::2;73986:4;73977:13;::::0;;78817:14:::3;::::0;;;::::3;73977:13:::2;78817:14:::3;78809:43;;;::::0;-1:-1:-1;;;78809:43:0;;21115:2:1;78809:43:0::3;::::0;::::3;21097:21:1::0;21154:2;21134:18;;;21127:30;-1:-1:-1;;;21173:18:1;;;21166:46;21229:18;;78809:43:0::3;20913:340:1::0;78809:43:0::3;78984:22;::::0;:50:::3;::::0;-1:-1:-1;;;78984:50:0;;79023:10:::3;78984:50;::::0;::::3;2293:51:1::0;78866:25:0::3;::::0;;;;;-1:-1:-1;;;;;78984:22:0::3;::::0;:38:::3;::::0;2266:18:1;;78984:50:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;::::0;;::::3;-1:-1:-1::0;;78984:50:0::3;::::0;::::3;;::::0;::::3;::::0;;;::::3;::::0;::::3;:::i;:::-;78865:169;;;;;;79075:1;79057:8;:15;:19;79048:60;;;::::0;-1:-1:-1;;;79048:60:0;;21460:2:1;79048:60:0::3;::::0;::::3;21442:21:1::0;21499:2;21479:18;;;21472:30;21538:29;21518:18;;;21511:57;21585:18;;79048:60:0::3;21258:351:1::0;79048:60:0::3;79216:26;79259:8;:15;-1:-1:-1::0;;;;;79245:30:0::3;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;79245:30:0::3;;79216:59;;79286:16;79322:9:::0;79317:235:::3;79339:8;:15;79335:1;:19;79317:235;;;79381:16;:29;79398:8;79407:1;79398:11;;;;;;;;:::i;:::-;;::::0;;::::3;::::0;;;;;;;79381:29;;;::::3;::::0;;;;;;-1:-1:-1;79381:29:0;;::::3;;79376:165;;79514:8;79523:1;79514:11;;;;;;;;:::i;:::-;;;;;;;79490:9;79500:10;;;;;:::i;:::-;;;79490:21;;;;;;;;:::i;:::-;;;;;;:35;;;::::0;::::3;79376:165;79356:3:::0;::::3;::::0;::::3;:::i;:::-;;;;79317:235;;;;79583:1;79572:8;:12;79564:85;;;::::0;-1:-1:-1;;;79564:85:0;;21816:2:1;79564:85:0::3;::::0;::::3;21798:21:1::0;21855:2;21835:18;;;21828:30;21894:34;21874:18;;;21867:62;21965:30;21945:18;;;21938:58;22013:19;;79564:85:0::3;21614:424:1::0;79564:85:0::3;79691:20;;79680:8;79668:9;;:20;;;;:::i;:::-;:43;79660:83;;;::::0;-1:-1:-1;;;79660:83:0;;22245:2:1;79660:83:0::3;::::0;::::3;22227:21:1::0;22284:2;22264:18;;;22257:30;22323:29;22303:18;;;22296:57;22370:18;;79660:83:0::3;22043:351:1::0;79660:83:0::3;80062:15;80091;;80080:8;:26;;;;:::i;:::-;80062:44;;80117:14;80145:15;;80134:8;:26;;;;:::i;:::-;80117:43;;80178:6;80173:95;80190:10;80186:1;:14;80173:95;;;80222:34;80228:10;80240:15;;80222:5;:34::i;:::-;80202:3;::::0;::::3;:::i;:::-;;;80173:95;;;-1:-1:-1::0;80282:13:0;;80278:74:::3;;80312:28;80318:10;80330:9;80312:5;:28::i;:::-;80369:6;80364:138;80383:8;80379:1;:12;80364:138;;;80444:4;80413:16;:30;80430:9;80440:1;80430:12;;;;;;;;:::i;:::-;;;;;;;80413:30;;;;;;;;;;;;:35;;;;;;;;;;;;;;;;;;80393:3;;;;;:::i;:::-;;;;80364:138;;;;80523:8;80512:9;;:19;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;80565:10:0::3;80552:24;::::0;;;:12:::3;:24;::::0;;;;80579:15:::3;80552:42:::0;;-1:-1:-1;;74013:6:0::2;:14:::0;;-1:-1:-1;;74013:14:0::2;::::0;;-1:-1:-1;;;;;;78728:1874:0:o;75055:98::-;67994:6;;-1:-1:-1;;;;;67994:6:0;66725:10;68141:23;68133:68;;;;-1:-1:-1;;;68133:68:0;;;;;;;:::i;:::-;75131:14:::1;::::0;;-1:-1:-1;;75113:32:0;::::1;75131:14:::0;;;;::::1;;;75130:15;75113:32:::0;;::::1;;::::0;;75055:98::o;21913:104::-;21969:13;22002:7;21995:14;;;;;:::i;75475:126::-;67994:6;;-1:-1:-1;;;;;67994:6:0;66725:10;68141:23;68133:68;;;;-1:-1:-1;;;68133:68:0;;;;;;;:::i;:::-;75552:23:::1;:41:::0;75475:126::o;58755:2513::-;58898:16;58965:4;58956:5;:13;58952:45;;58978:19;;-1:-1:-1;;;58978:19:0;;;;;;;;;;;58952:45;59012:19;59046:17;59066:14;17230:7;17257:13;;17175:103;59066:14;59046:34;-1:-1:-1;78054:1:0;59158:5;:23;59154:87;;;78054:1;59202:23;;59154:87;59317:9;59310:4;:16;59306:73;;;59354:9;59347:16;;59306:73;59393:25;59421:16;59431:5;59421:9;:16::i;:::-;59393:44;;59615:4;59607:5;:12;59603:278;;;59662:12;;;59697:31;;;59693:111;;;59773:11;59753:31;;59693:111;59621:198;59603:278;;;-1:-1:-1;59864:1:0;59603:278;59895:25;59937:17;-1:-1:-1;;;;;59923:32:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59923:32:0;;59895:60;;59974:17;59995:1;59974:22;59970:78;;60024:8;-1:-1:-1;60017:15:0;;-1:-1:-1;;;60017:15:0;59970:78;60192:31;60226:26;60246:5;60226:19;:26::i;:::-;60192:60;;60267:25;60512:9;:16;;;60507:92;;-1:-1:-1;60569:14:0;;60507:92;60630:5;60613:478;60642:4;60637:1;:9;;:45;;;;;60665:17;60650:11;:32;;60637:45;60613:478;;;60720:15;60733:1;60720:12;:15::i;:::-;60708:27;;60758:9;:16;;;60799:8;60754:73;60849:14;;-1:-1:-1;;;;;60849:28:0;;60845:111;;60922:14;;;-1:-1:-1;60845:111:0;60999:5;-1:-1:-1;;;;;60978:26:0;:17;-1:-1:-1;;;;;60978:26:0;;60974:102;;61055:1;61029:8;61038:13;;;;;;61029:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;60974:102;60684:3;;60613:478;;;-1:-1:-1;;;61176:29:0;;;-1:-1:-1;61183:8:0;;-1:-1:-1;;58755:2513:0;;;;;;:::o;28778:308::-;66725:10;-1:-1:-1;;;;;28877:31:0;;;28873:61;;28917:17;;-1:-1:-1;;;28917:17:0;;;;;;;;;;;28873:61;66725:10;28947:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;28947:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;28947:60:0;;;;;;;;;;29023:55;;722:41:1;;;28947:49:0;;66725:10;29023:55;;695:18:1;29023:55:0;;;;;;;28778:308;;:::o;35623:399::-;35790:31;35803:4;35809:2;35813:7;35790:12;:31::i;:::-;-1:-1:-1;;;;;35836:14:0;;;:19;35832:183;;35875:56;35906:4;35912:2;35916:7;35925:5;35875:30;:56::i;:::-;35870:145;;35959:40;;-1:-1:-1;;;35959:40:0;;;;;;;;;;;35870:145;35623:399;;;;:::o;75814:111::-;67994:6;;-1:-1:-1;;;;;67994:6:0;66725:10;68141:23;68133:68;;;;-1:-1:-1;;;68133:68:0;;;;;;;:::i;:::-;75890:15:::1;:27:::0;75814:111::o;57252:428::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78054:1:0;57416:7;:25;:54;;;-1:-1:-1;17230:7:0;17257:13;57445:7;:25;;57416:54;57412:103;;;57494:9;57252:428;-1:-1:-1;;57252:428:0:o;57412:103::-;57537:21;57550:7;57537:12;:21::i;:::-;57525:33;;57573:9;:16;;;57569:65;;;57613:9;57252:428;-1:-1:-1;;57252:428:0:o;57569:65::-;57651:21;57664:7;57651:12;:21::i;22123:318::-;22196:13;22227:16;22235:7;22227;:16::i;:::-;22222:59;;22252:29;;-1:-1:-1;;;22252:29:0;;;;;;;;;;;22222:59;22294:21;22318:10;:8;:10::i;:::-;22294:34;;22352:7;22346:21;22371:1;22346:26;:87;;;;;;;;;;;;;;;;;22399:7;22408:18;22418:7;22408:9;:18::i;:::-;22382:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;22339:94;22123:318;-1:-1:-1;;;22123:318:0:o;63639:619::-;63848:13;63864:16;63872:7;63864;:16::i;:::-;63848:32;-1:-1:-1;66725:10:0;-1:-1:-1;;;;;63895:28:0;;;63891:205;;63943:44;63960:5;66725:10;29243:164;:::i;63943:44::-;63938:158;;66725:10;64010:20;64022:7;64010:11;:20::i;:::-;-1:-1:-1;;;;;64010:43:0;;64006:90;;64062:34;;-1:-1:-1;;;64062:34:0;;;;;;;;;;;64006:90;64109:24;;;;:15;:24;;;;;;;;;-1:-1:-1;;;;;64176:22:0;;63200:3;64137:35;;;-1:-1:-1;;;64137:35:0;64136:62;;64109:89;;;64216:34;;-1:-1:-1;;;;;23036:31:1;;23018:50;;64109:24:0;;64216:34;;22991:18:1;64216:34:0;;;;;;;63752:506;63639:619;;;:::o;77303:651::-;77415:22;;:53;;-1:-1:-1;;;77415:53:0;;77457:10;77415:53;;;2293:51:1;77359:13:0;;77390:22;;-1:-1:-1;;;;;77415:22:0;;;;:41;;2266:18:1;;77415:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77390:78;-1:-1:-1;77483:17:0;;;;;:74;;-1:-1:-1;77539:18:0;;77504:32;77522:14;77504:15;:32;:::i;:::-;:53;77483:74;:154;;;;-1:-1:-1;77619:18:0;;77605:10;77592:24;;;;:12;:24;;;;;;77574:42;;:15;:42;:::i;:::-;:63;77483:154;77479:468;;;77654:47;;;;;;;;;;;;;;;;;;;;77303:651;:::o;77479:468::-;77853:25;77863:14;77853:9;:25::i;:::-;77778:101;;;;;;;;:::i;:::-;;;;-1:-1:-1;;77778:101:0;;;;;;;;;;77764:120;;77778:101;77764:120;;:::i;:::-;;;;-1:-1:-1;;77764:120:0;;;;;;;;;77922:10;77909:24;;;;:12;77764:120;77909:24;;;77899:35;;:9;:35::i;:::-;77750:185;;;;;;;;;:::i;:::-;;;;;;;;;;;;;77743:192;;;77303:651;:::o;81774:572::-;73214:9;73227:10;73214:23;73206:66;;;;-1:-1:-1;;;73206:66:0;;;;;;;:::i;:::-;73941:6:::1;::::0;::::1;;73940:7;73932:34;;;;-1:-1:-1::0;;;73932:34:0::1;;;;;;;:::i;:::-;73977:6;:13:::0;;-1:-1:-1;;73977:13:0::1;73986:4;73977:13;::::0;;81879:16:::2;::::0;73977:13:::1;81879:16:::2;81871:47;;;::::0;-1:-1:-1;;;81871:47:0;;24226:2:1;81871:47:0::2;::::0;::::2;24208:21:1::0;24265:2;24245:18;;;24238:30;-1:-1:-1;;;24284:18:1;;;24277:48;24342:18;;81871:47:0::2;24024:342:1::0;81871:47:0::2;81970:23;;81952:15;81937:12;;:30;;;;:::i;:::-;:56;81929:100;;;;-1:-1:-1::0;;;81929:100:0::2;;;;;;;:::i;:::-;82111:15;82096:12;;:30;;;;:::i;:::-;82083:9;:43;;82075:81;;;::::0;-1:-1:-1;;;82075:81:0;;19119:2:1;82075:81:0::2;::::0;::::2;19101:21:1::0;19158:2;19138:18;;;19131:30;-1:-1:-1;;;19177:18:1;;;19170:55;19242:18;;82075:81:0::2;18917:349:1::0;82075:81:0::2;82193:28;;82175:15;:46;82167:84;;;::::0;-1:-1:-1;;;82167:84:0;;19473:2:1;82167:84:0::2;::::0;::::2;19455:21:1::0;19512:2;19492:18;;;19485:30;-1:-1:-1;;;19531:18:1;;;19524:55;19596:18;;82167:84:0::2;19271:349:1::0;82167:84:0::2;82264:34;82270:10;82282:15;82264:5;:34::i;:::-;82323:15;82309:12;;:29;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;74013:6:0::1;:14:::0;;-1:-1:-1;;74013:14:0::1;::::0;;-1:-1:-1;81774:572:0:o;68830:201::-;67994:6;;-1:-1:-1;;;;;67994:6:0;66725:10;68141:23;68133:68;;;;-1:-1:-1;;;68133:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;68919:22:0;::::1;68911:73;;;::::0;-1:-1:-1;;;68911:73:0;;24573:2:1;68911:73:0::1;::::0;::::1;24555:21:1::0;24612:2;24592:18;;;24585:30;24651:34;24631:18;;;24624:62;-1:-1:-1;;;24702:18:1;;;24695:36;24748:19;;68911:73:0::1;24371:402:1::0;68911:73:0::1;68995:28;69014:8;68995:18;:28::i;:::-;68830:201:::0;:::o;74936:113::-;67994:6;;-1:-1:-1;;;;;67994:6:0;66725:10;68141:23;68133:68;;;;-1:-1:-1;;;68133:68:0;;;;;;;:::i;:::-;75022:19:::1;::::0;;-1:-1:-1;;74999:42:0;::::1;75022:19;::::0;;;::::1;;;75021:20;74999:42:::0;;::::1;;::::0;;74936:113::o;20835:639::-;20920:4;-1:-1:-1;;;;;;;;;21244:25:0;;;;:102;;-1:-1:-1;;;;;;;;;;21321:25:0;;;21244:102;:179;;;-1:-1:-1;;;;;;;;21398:25:0;-1:-1:-1;;;21398:25:0;;20835:639::o;39284:2454::-;39357:20;39380:13;;;39408;;;39404:44;;39430:18;;-1:-1:-1;;;39430:18:0;;;;;;;;;;;39404:44;-1:-1:-1;;;;;39936:22:0;;;;;;:18;:22;;;;12969:2;39936:22;;;:71;;39974:32;39962:45;;39936:71;;;40250:31;;;:17;:31;;;;;-1:-1:-1;26950:15:0;;26924:24;26920:46;26519:11;26494:23;26490:41;26487:52;26477:63;;40250:173;;40485:23;;;;40250:31;;39936:22;;40984:25;39936:22;;40837:335;41252:1;41238:12;41234:20;41192:346;41293:3;41284:7;41281:16;41192:346;;41511:7;41501:8;41498:1;41471:25;41468:1;41465;41460:59;41346:1;41333:15;41192:346;;;41196:77;41571:8;41583:1;41571:13;41567:45;;41593:19;;-1:-1:-1;;;41593:19:0;;;;;;;;;;;41567:45;41629:13;:19;-1:-1:-1;34840:185:0;;;:::o;29665:282::-;29730:4;29786:7;78054:1;29767:26;;:66;;;;;29820:13;;29810:7;:23;29767:66;:153;;;;-1:-1:-1;;29871:26:0;;;;:17;:26;;;;;;-1:-1:-1;;;29871:44:0;:49;;29665:282::o;24285:1275::-;24352:7;24387;;78054:1;24436:23;24432:1061;;24489:13;;24482:4;:20;24478:1015;;;24527:14;24544:23;;;:17;:23;;;;;;;-1:-1:-1;;;24633:24:0;;:29;;24629:845;;25298:113;25305:6;25315:1;25305:11;25298:113;;-1:-1:-1;;;25376:6:0;25358:25;;;;:17;:25;;;;;;25298:113;;24629:845;24504:989;24478:1015;25521:31;;-1:-1:-1;;;25521:31:0;;;;;;;;;;;69191:191;69284:6;;;-1:-1:-1;;;;;69301:17:0;;;-1:-1:-1;;;;;;69301:17:0;;;;;;;69334:40;;69284:6;;;69301:17;69284:6;;69334:40;;69265:16;;69334:40;69254:128;69191:191;:::o;23733:161::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23861:24:0;;;;:17;:24;;;;;;23842:44;;:18;:44::i;38106:716::-;38290:88;;-1:-1:-1;;;38290:88:0;;38269:4;;-1:-1:-1;;;;;38290:45:0;;;;;:88;;66725:10;;38357:4;;38363:7;;38372:5;;38290:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38290:88:0;;;;;;;;-1:-1:-1;;38290:88:0;;;;;;;;;;;;:::i;:::-;;;38286:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38573:6;:13;38590:1;38573:18;38569:235;;38619:40;;-1:-1:-1;;;38619:40:0;;;;;;;;;;;38569:235;38762:6;38756:13;38747:6;38743:2;38739:15;38732:38;38286:529;-1:-1:-1;;;;;;38449:64:0;-1:-1:-1;;;38449:64:0;;-1:-1:-1;38286:529:0;38106:716;;;;;;:::o;23471:166::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23582:47:0;23601:27;23620:7;23601:18;:27::i;:::-;23582:18;:47::i;74494:118::-;74554:13;74587:17;74580:24;;;;;:::i;51638:2002::-;52115:4;52109:11;;52122:3;52105:21;;52200:17;;;;52896:11;;;52775:5;53062:2;53076;53066:13;;53058:22;52896:11;53045:36;53117:2;53107:13;;52667:731;53136:4;52667:731;;;53327:1;53322:3;53318:11;53311:18;;53378:2;53372:4;53368:13;53364:2;53360:22;53355:3;53347:36;53231:2;53221:13;;52667:731;;;-1:-1:-1;53428:13:0;;;-1:-1:-1;;53543:12:0;;;53603:19;;;53543:12;51638:2002;-1:-1:-1;51638:2002:0:o;25659:366::-;-1:-1:-1;;;;;;;;;;;;;25769:41:0;;;;13490:3;25855:33;;;-1:-1:-1;;;;;25821:68:0;-1:-1:-1;;;25821:68:0;-1:-1:-1;;;25919:24:0;;:29;;-1:-1:-1;;;25900:48:0;;;;14011:3;25988:28;;;;-1:-1:-1;;;25959:58:0;-1:-1:-1;25659:366:0:o;196:131:1:-;-1:-1:-1;;;;;;270:32:1;;260:43;;250:71;;317:1;314;307:12;332:245;390:6;443:2;431:9;422:7;418:23;414:32;411:52;;;459:1;456;449:12;411:52;498:9;485:23;517:30;541:5;517:30;:::i;774:173::-;842:20;;-1:-1:-1;;;;;891:31:1;;881:42;;871:70;;937:1;934;927:12;871:70;774:173;;;:::o;952:254::-;1020:6;1028;1081:2;1069:9;1060:7;1056:23;1052:32;1049:52;;;1097:1;1094;1087:12;1049:52;1120:29;1139:9;1120:29;:::i;:::-;1110:39;1196:2;1181:18;;;;1168:32;;-1:-1:-1;;;952:254:1:o;1211:258::-;1283:1;1293:113;1307:6;1304:1;1301:13;1293:113;;;1383:11;;;1377:18;1364:11;;;1357:39;1329:2;1322:10;1293:113;;;1424:6;1421:1;1418:13;1415:48;;;-1:-1:-1;;1459:1:1;1441:16;;1434:27;1211:258::o;1474:::-;1516:3;1554:5;1548:12;1581:6;1576:3;1569:19;1597:63;1653:6;1646:4;1641:3;1637:14;1630:4;1623:5;1619:16;1597:63;:::i;:::-;1714:2;1693:15;-1:-1:-1;;1689:29:1;1680:39;;;;1721:4;1676:50;;1474:258;-1:-1:-1;;1474:258:1:o;1737:220::-;1886:2;1875:9;1868:21;1849:4;1906:45;1947:2;1936:9;1932:18;1924:6;1906:45;:::i;1962:180::-;2021:6;2074:2;2062:9;2053:7;2049:23;2045:32;2042:52;;;2090:1;2087;2080:12;2042:52;-1:-1:-1;2113:23:1;;1962:180;-1:-1:-1;1962:180:1:o;2355:328::-;2432:6;2440;2448;2501:2;2489:9;2480:7;2476:23;2472:32;2469:52;;;2517:1;2514;2507:12;2469:52;2540:29;2559:9;2540:29;:::i;:::-;2530:39;;2588:38;2622:2;2611:9;2607:18;2588:38;:::i;:::-;2578:48;;2673:2;2662:9;2658:18;2645:32;2635:42;;2355:328;;;;;:::o;2688:127::-;2749:10;2744:3;2740:20;2737:1;2730:31;2780:4;2777:1;2770:15;2804:4;2801:1;2794:15;2820:275;2891:2;2885:9;2956:2;2937:13;;-1:-1:-1;;2933:27:1;2921:40;;-1:-1:-1;;;;;2976:34:1;;3012:22;;;2973:62;2970:88;;;3038:18;;:::i;:::-;3074:2;3067:22;2820:275;;-1:-1:-1;2820:275:1:o;3100:407::-;3165:5;-1:-1:-1;;;;;3191:6:1;3188:30;3185:56;;;3221:18;;:::i;:::-;3259:57;3304:2;3283:15;;-1:-1:-1;;3279:29:1;3310:4;3275:40;3259:57;:::i;:::-;3250:66;;3339:6;3332:5;3325:21;3379:3;3370:6;3365:3;3361:16;3358:25;3355:45;;;3396:1;3393;3386:12;3355:45;3445:6;3440:3;3433:4;3426:5;3422:16;3409:43;3499:1;3492:4;3483:6;3476:5;3472:18;3468:29;3461:40;3100:407;;;;;:::o;3512:451::-;3581:6;3634:2;3622:9;3613:7;3609:23;3605:32;3602:52;;;3650:1;3647;3640:12;3602:52;3690:9;3677:23;-1:-1:-1;;;;;3715:6:1;3712:30;3709:50;;;3755:1;3752;3745:12;3709:50;3778:22;;3831:4;3823:13;;3819:27;-1:-1:-1;3809:55:1;;3860:1;3857;3850:12;3809:55;3883:74;3949:7;3944:2;3931:16;3926:2;3922;3918:11;3883:74;:::i;3968:615::-;4054:6;4062;4115:2;4103:9;4094:7;4090:23;4086:32;4083:52;;;4131:1;4128;4121:12;4083:52;4171:9;4158:23;-1:-1:-1;;;;;4241:2:1;4233:6;4230:14;4227:34;;;4257:1;4254;4247:12;4227:34;4295:6;4284:9;4280:22;4270:32;;4340:7;4333:4;4329:2;4325:13;4321:27;4311:55;;4362:1;4359;4352:12;4311:55;4402:2;4389:16;4428:2;4420:6;4417:14;4414:34;;;4444:1;4441;4434:12;4414:34;4497:7;4492:2;4482:6;4479:1;4475:14;4471:2;4467:23;4463:32;4460:45;4457:65;;;4518:1;4515;4508:12;4457:65;4549:2;4541:11;;;;;4571:6;;-1:-1:-1;3968:615:1;;-1:-1:-1;;;;3968:615:1:o;4588:349::-;4672:12;;-1:-1:-1;;;;;4668:38:1;4656:51;;4760:4;4749:16;;;4743:23;-1:-1:-1;;;;;4739:48:1;4723:14;;;4716:72;4851:4;4840:16;;;4834:23;4827:31;4820:39;4804:14;;;4797:63;4913:4;4902:16;;;4896:23;4921:8;4892:38;4876:14;;4869:62;4588:349::o;4942:722::-;5175:2;5227:21;;;5297:13;;5200:18;;;5319:22;;;5146:4;;5175:2;5398:15;;;;5372:2;5357:18;;;5146:4;5441:197;5455:6;5452:1;5449:13;5441:197;;;5504:52;5552:3;5543:6;5537:13;5504:52;:::i;:::-;5613:15;;;;5585:4;5576:14;;;;;5477:1;5470:9;5441:197;;5669:186;5728:6;5781:2;5769:9;5760:7;5756:23;5752:32;5749:52;;;5797:1;5794;5787:12;5749:52;5820:29;5839:9;5820:29;:::i;5860:632::-;6031:2;6083:21;;;6153:13;;6056:18;;;6175:22;;;6002:4;;6031:2;6254:15;;;;6228:2;6213:18;;;6002:4;6297:169;6311:6;6308:1;6305:13;6297:169;;;6372:13;;6360:26;;6441:15;;;;6406:12;;;;6333:1;6326:9;6297:169;;6497:474;6581:6;6589;6597;6605;6658:3;6646:9;6637:7;6633:23;6629:33;6626:53;;;6675:1;6672;6665:12;6626:53;6711:9;6698:23;6688:33;;6771:2;6760:9;6756:18;6743:32;6815:4;6808:5;6804:16;6797:5;6794:27;6784:55;;6835:1;6832;6825:12;6784:55;6497:474;;6858:5;;-1:-1:-1;;;;6910:2:1;6895:18;;6882:32;;6961:2;6946:18;6933:32;;6497:474::o;6976:322::-;7053:6;7061;7069;7122:2;7110:9;7101:7;7097:23;7093:32;7090:52;;;7138:1;7135;7128:12;7090:52;7161:29;7180:9;7161:29;:::i;:::-;7151:39;7237:2;7222:18;;7209:32;;-1:-1:-1;7288:2:1;7273:18;;;7260:32;;6976:322;-1:-1:-1;;;6976:322:1:o;7303:347::-;7368:6;7376;7429:2;7417:9;7408:7;7404:23;7400:32;7397:52;;;7445:1;7442;7435:12;7397:52;7468:29;7487:9;7468:29;:::i;:::-;7458:39;;7547:2;7536:9;7532:18;7519:32;7594:5;7587:13;7580:21;7573:5;7570:32;7560:60;;7616:1;7613;7606:12;7560:60;7639:5;7629:15;;;7303:347;;;;;:::o;7885:667::-;7980:6;7988;7996;8004;8057:3;8045:9;8036:7;8032:23;8028:33;8025:53;;;8074:1;8071;8064:12;8025:53;8097:29;8116:9;8097:29;:::i;:::-;8087:39;;8145:38;8179:2;8168:9;8164:18;8145:38;:::i;:::-;8135:48;;8230:2;8219:9;8215:18;8202:32;8192:42;;8285:2;8274:9;8270:18;8257:32;-1:-1:-1;;;;;8304:6:1;8301:30;8298:50;;;8344:1;8341;8334:12;8298:50;8367:22;;8420:4;8412:13;;8408:27;-1:-1:-1;8398:55:1;;8449:1;8446;8439:12;8398:55;8472:74;8538:7;8533:2;8520:16;8515:2;8511;8507:11;8472:74;:::i;:::-;8462:84;;;7885:667;;;;;;;:::o;8557:266::-;8753:3;8738:19;;8766:51;8742:9;8799:6;8766:51;:::i;8828:426::-;8904:6;8912;8920;8973:2;8961:9;8952:7;8948:23;8944:32;8941:52;;;8989:1;8986;8979:12;8941:52;9025:9;9012:23;9002:33;;9054:38;9088:2;9077:9;9073:18;9054:38;:::i;:::-;9044:48;;9142:2;9131:9;9127:18;9114:32;-1:-1:-1;;;;;9179:5:1;9175:30;9168:5;9165:41;9155:69;;9220:1;9217;9210:12;9155:69;9243:5;9233:15;;;8828:426;;;;;:::o;9259:260::-;9327:6;9335;9388:2;9376:9;9367:7;9363:23;9359:32;9356:52;;;9404:1;9401;9394:12;9356:52;9427:29;9446:9;9427:29;:::i;:::-;9417:39;;9475:38;9509:2;9498:9;9494:18;9475:38;:::i;:::-;9465:48;;9259:260;;;;;:::o;9524:709::-;9589:5;9642:3;9635:4;9627:6;9623:17;9619:27;9609:55;;9660:1;9657;9650:12;9609:55;9689:6;9683:13;9715:4;-1:-1:-1;;;;;9734:2:1;9731:26;9728:52;;;9760:18;;:::i;:::-;9806:2;9803:1;9799:10;9829:28;9853:2;9849;9845:11;9829:28;:::i;:::-;9891:15;;;9961;;;9957:24;;;9922:12;;;;9993:15;;;9990:35;;;10021:1;10018;10011:12;9990:35;10057:2;10049:6;10045:15;10034:26;;10069:135;10085:6;10080:3;10077:15;10069:135;;;10151:10;;10139:23;;10102:12;;;;10182;;;;10069:135;;;10222:5;9524:709;-1:-1:-1;;;;;;;9524:709:1:o;10238:844::-;10401:6;10409;10417;10470:2;10458:9;10449:7;10445:23;10441:32;10438:52;;;10486:1;10483;10476:12;10438:52;10519:9;10513:16;-1:-1:-1;;;;;10589:2:1;10581:6;10578:14;10575:34;;;10605:1;10602;10595:12;10575:34;10628:72;10692:7;10683:6;10672:9;10668:22;10628:72;:::i;:::-;10618:82;;10746:2;10735:9;10731:18;10725:25;10709:41;;10775:2;10765:8;10762:16;10759:36;;;10791:1;10788;10781:12;10759:36;10814:74;10880:7;10869:8;10858:9;10854:24;10814:74;:::i;:::-;10804:84;;10934:2;10923:9;10919:18;10913:25;10897:41;;10963:2;10953:8;10950:16;10947:36;;;10979:1;10976;10969:12;10947:36;;11002:74;11068:7;11057:8;11046:9;11042:24;11002:74;:::i;:::-;10992:84;;;10238:844;;;;;:::o;11087:127::-;11148:10;11143:3;11139:20;11136:1;11129:31;11179:4;11176:1;11169:15;11203:4;11200:1;11193:15;11219:127;11280:10;11275:3;11271:20;11268:1;11261:31;11311:4;11308:1;11301:15;11335:4;11332:1;11325:15;11351:135;11390:3;11411:17;;;11408:43;;11431:18;;:::i;:::-;-1:-1:-1;11478:1:1;11467:13;;11351:135::o;11491:356::-;11693:2;11675:21;;;11712:18;;;11705:30;11771:34;11766:2;11751:18;;11744:62;11838:2;11823:18;;11491:356::o;11852:128::-;11892:3;11923:1;11919:6;11916:1;11913:13;11910:39;;;11929:18;;:::i;:::-;-1:-1:-1;11965:9:1;;11852:128::o;11985:355::-;12187:2;12169:21;;;12226:2;12206:18;;;12199:30;12265:33;12260:2;12245:18;;12238:61;12331:2;12316:18;;11985:355::o;12345:127::-;12406:10;12401:3;12397:20;12394:1;12387:31;12437:4;12434:1;12427:15;12461:4;12458:1;12451:15;12477:120;12517:1;12543;12533:35;;12548:18;;:::i;:::-;-1:-1:-1;12582:9:1;;12477:120::o;12602:112::-;12634:1;12660;12650:35;;12665:18;;:::i;:::-;-1:-1:-1;12699:9:1;;12602:112::o;12719:380::-;12798:1;12794:12;;;;12841;;;12862:61;;12916:4;12908:6;12904:17;12894:27;;12862:61;12969:2;12961:6;12958:14;12938:18;12935:38;12932:161;;13015:10;13010:3;13006:20;13003:1;12996:31;13050:4;13047:1;13040:15;13078:4;13075:1;13068:15;12932:161;;12719:380;;;:::o;13104:338::-;13306:2;13288:21;;;13345:2;13325:18;;;13318:30;-1:-1:-1;;;13379:2:1;13364:18;;13357:44;13433:2;13418:18;;13104:338::o;14128:545::-;14230:2;14225:3;14222:11;14219:448;;;14266:1;14291:5;14287:2;14280:17;14336:4;14332:2;14322:19;14406:2;14394:10;14390:19;14387:1;14383:27;14377:4;14373:38;14442:4;14430:10;14427:20;14424:47;;;-1:-1:-1;14465:4:1;14424:47;14520:2;14515:3;14511:12;14508:1;14504:20;14498:4;14494:31;14484:41;;14575:82;14593:2;14586:5;14583:13;14575:82;;;14638:17;;;14619:1;14608:13;14575:82;;14849:1352;14975:3;14969:10;-1:-1:-1;;;;;14994:6:1;14991:30;14988:56;;;15024:18;;:::i;:::-;15053:97;15143:6;15103:38;15135:4;15129:11;15103:38;:::i;:::-;15097:4;15053:97;:::i;:::-;15205:4;;15269:2;15258:14;;15286:1;15281:663;;;;15988:1;16005:6;16002:89;;;-1:-1:-1;16057:19:1;;;16051:26;16002:89;-1:-1:-1;;14806:1:1;14802:11;;;14798:24;14794:29;14784:40;14830:1;14826:11;;;14781:57;16104:81;;15251:944;;15281:663;14075:1;14068:14;;;14112:4;14099:18;;-1:-1:-1;;15317:20:1;;;15435:236;15449:7;15446:1;15443:14;15435:236;;;15538:19;;;15532:26;15517:42;;15630:27;;;;15598:1;15586:14;;;;15465:19;;15435:236;;;15439:3;15699:6;15690:7;15687:19;15684:201;;;15760:19;;;15754:26;-1:-1:-1;;15843:1:1;15839:14;;;15855:3;15835:24;15831:37;15827:42;15812:58;15797:74;;15684:201;-1:-1:-1;;;;;15931:1:1;15915:14;;;15911:22;15898:36;;-1:-1:-1;14849:1352:1:o;16206:354::-;16408:2;16390:21;;;16447:2;16427:18;;;16420:30;16486:32;16481:2;16466:18;;16459:60;16551:2;16536:18;;16206:354::o;18744:168::-;18784:7;18850:1;18846;18842:6;18838:14;18835:1;18832:21;18827:1;18820:9;18813:17;18809:45;18806:71;;;18857:18;;:::i;:::-;-1:-1:-1;18897:9:1;;18744:168::o;19625:184::-;19695:6;19748:2;19736:9;19727:7;19723:23;19719:32;19716:52;;;19764:1;19761;19754:12;19716:52;-1:-1:-1;19787:16:1;;19625:184;-1:-1:-1;19625:184:1:o;20161:125::-;20201:4;20229:1;20226;20223:8;20220:34;;;20234:18;;:::i;:::-;-1:-1:-1;20271:9:1;;20161:125::o;22399:470::-;22578:3;22616:6;22610:13;22632:53;22678:6;22673:3;22666:4;22658:6;22654:17;22632:53;:::i;:::-;22748:13;;22707:16;;;;22770:57;22748:13;22707:16;22804:4;22792:17;;22770:57;:::i;:::-;22843:20;;22399:470;-1:-1:-1;;;;22399:470:1:o;23079:507::-;23341:34;23336:3;23329:47;23406:27;23401:2;23396:3;23392:12;23385:49;23311:3;23463:6;23457:13;23479:60;23532:6;23527:2;23522:3;23518:12;23513:2;23505:6;23501:15;23479:60;:::i;:::-;23559:16;;;;23577:2;23555:25;;23079:507;-1:-1:-1;;23079:507:1:o;23591:428::-;23812:3;23850:6;23844:13;23866:53;23912:6;23907:3;23900:4;23892:6;23888:17;23866:53;:::i;:::-;-1:-1:-1;;;23941:16:1;;23966:18;;;-1:-1:-1;24011:1:1;24000:13;;23591:428;-1:-1:-1;23591:428:1:o;24778:489::-;-1:-1:-1;;;;;25047:15:1;;;25029:34;;25099:15;;25094:2;25079:18;;25072:43;25146:2;25131:18;;25124:34;;;25194:3;25189:2;25174:18;;25167:31;;;24972:4;;25215:46;;25241:19;;25233:6;25215:46;:::i;:::-;25207:54;24778:489;-1:-1:-1;;;;;;24778:489:1:o;25272:249::-;25341:6;25394:2;25382:9;25373:7;25369:23;25365:32;25362:52;;;25410:1;25407;25400:12;25362:52;25442:9;25436:16;25461:30;25485:5;25461:30;:::i

Swarm Source

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