ETH Price: $3,300.57 (-1.62%)

Token

Eggz By Soakverse (EGGZ)
 

Overview

Max Total Supply

5,000 EGGZ

Holders

730

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
phi1iqq.eth
Balance
1 EGGZ
0xE9275ac6c2378c0Fb93C738fF55D54a80b3E2d8a
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Eggz by Soakverse is a collection of 5,000 utility-enabled Eggz. Each Eggz is your key to accessing the broad Soakverse Ecosystem. Despite being tasty alone, we prefer Stake & Eggz... we think you will too!

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
EggzNFT

Compiler Version
v0.8.12+commit.f00d7308

Optimization Enabled:
Yes with 1500 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity Multiple files format)

File 2 of 11: EggzNFT.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;

//@author Soakverse
//@title Eggz by Soakverse

import "./Ownable.sol";
import "./Strings.sol";
import "./MerkleProof.sol";
import "./ERC721LockRegistry.sol";

contract EggzNFT is Ownable, ERC721X {
    using Strings for uint256;

    enum Step {
        Before,
        OGWhitelist,
        PremiumWhitelist,
        Whitelist,
        Public,
        Soldout
    }

    string public baseURI;

    Step public sellingStep;

    uint256 private constant MAX_SUPPLY = 5000;
    uint256 private constant MAX_FREEMINT = 4580;

    bytes32 public ogMerkleRoot;
    bytes32 public premiumMerkleRoot;
    bytes32 public merkleRoot;

    mapping(address => uint256) public amountNftPerWallet;

    bool public canStake;

    mapping(uint256 => uint256) public tokensLastStakedAt; // tokenId => timestamp

    event Stake(uint256 tokenId, address by, uint256 stakedAt);
    event Unstake(
        uint256 tokenId,
        address by,
        uint256 stakedAt,
        uint256 unstakedAt
    );

    constructor(
        bytes32 _ogMerkleRoot,
        bytes32 _premiumMerkleRoot,
        bytes32 _merkleRoot,
        string memory _baseURI
    ) ERC721X("Eggz By Soakverse", "EGGZ") {
        ogMerkleRoot = _ogMerkleRoot;
        premiumMerkleRoot = _premiumMerkleRoot;
        merkleRoot = _merkleRoot;
        baseURI = _baseURI;
    }

    modifier callerIsUser() {
        require(tx.origin == msg.sender, "The caller is another contract");
        _;
    }

    function ogWhitelistMint(uint256 _quantity, bytes32[] calldata _proof)
        external
        callerIsUser
    {
        require(
            sellingStep >= Step.OGWhitelist,
            "Whitelist sale is not activated"
        );
        require(
            isOGWhiteListed(msg.sender, _quantity, _proof),
            "Not OG whitelisted"
        );
        require(
            amountNftPerWallet[msg.sender] + _quantity <= _quantity,
            "You reached maximum on OG Whitelist Sale"
        );
        require(
            totalSupply() + _quantity <= MAX_FREEMINT,
            "Max freemint supply exceeded"
        );
        amountNftPerWallet[msg.sender] += _quantity;
        _safeMint(msg.sender, _quantity);
    }

    function premiumWhitelistMint(bytes32[] calldata _proof)
        external
        callerIsUser
    {
        require(
            sellingStep >= Step.PremiumWhitelist,
            "Premium Whitelist sale is not activated"
        );
        require(
            isPremiumWhiteListed(msg.sender, _proof),
            "Not Premium whitelisted"
        );
        require(
            amountNftPerWallet[msg.sender] + 2 <= 2,
            "You can only get 2 NFT on the Premium Whitelist Sale"
        );
        require(
            totalSupply() + 2 <= MAX_FREEMINT,
            "Max freemint supply exceeded"
        );
        amountNftPerWallet[msg.sender] += 2;
        _safeMint(msg.sender, 2);
    }

    function whitelistMint(bytes32[] calldata _proof) external callerIsUser {
        require(
            sellingStep >= Step.Whitelist,
            "Whitelist sale is not activated"
        );
        require(isWhiteListed(msg.sender, _proof), "Not whitelisted");
        require(
            amountNftPerWallet[msg.sender] + 1 <= 1,
            "You can only get 1 NFT on the Whitelist Sale"
        );
        require(
            totalSupply() + 1 <= MAX_FREEMINT,
            "Max freemint supply exceeded"
        );
        amountNftPerWallet[msg.sender] += 1;
        _safeMint(msg.sender, 1);
    }

    function mint() external callerIsUser {
        require(sellingStep >= Step.Public, "Public sale is not activated");
        require(
            amountNftPerWallet[msg.sender] + 1 <= 1,
            "You can only get 1 NFT on the Public Sale"
        );
        require(
            totalSupply() + 1 <= MAX_FREEMINT,
            "Max freemint supply exceeded"
        );
        amountNftPerWallet[msg.sender] += 1;
        _safeMint(msg.sender, 1);
    }

    function giveaway(address _to, uint256 _quantity) external onlyOwner {
        require(sellingStep > Step.Public, "Giveaway is after the public sale");
        require(totalSupply() + _quantity <= MAX_SUPPLY, "Max supply exceeded");
        _safeMint(_to, _quantity);
    }

    function setStep(uint256 _step) external onlyOwner {
        sellingStep = Step(_step);
    }

    function setBaseUri(string memory _baseURI) external onlyOwner {
        baseURI = _baseURI;
    }

    function tokenURI(uint256 _tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(_exists(_tokenId), "URI query for nonexistent token");

        return string(abi.encodePacked(baseURI, _tokenId.toString(), ".json"));
    }

    // ---- OG Whitelist ----
    function setOGMerkleRoot(bytes32 _merkleRoot) external onlyOwner {
        ogMerkleRoot = _merkleRoot;
    }

    function isOGWhiteListed(
        address _account,
        uint256 _quantity,
        bytes32[] calldata _proof
    ) internal view returns (bool) {
        bytes32 _leaf = keccak256(abi.encodePacked(_account, _quantity));
        return _verify(_leaf, ogMerkleRoot, _proof);
    }

    // ---- Premium Whitelist ----
    function setPremiumMerkleRoot(bytes32 _merkleRoot) external onlyOwner {
        premiumMerkleRoot = _merkleRoot;
    }

    function isPremiumWhiteListed(address _account, bytes32[] calldata _proof)
        internal
        view
        returns (bool)
    {
        bytes32 _leaf = keccak256(abi.encodePacked(_account));
        return _verify(_leaf, premiumMerkleRoot, _proof);
    }

    // ---- Whitelist ----
    function setMerkleRoot(bytes32 _merkleRoot) external onlyOwner {
        merkleRoot = _merkleRoot;
    }

    function isWhiteListed(address _account, bytes32[] calldata _proof)
        internal
        view
        returns (bool)
    {
        bytes32 _leaf = keccak256(abi.encodePacked(_account));
        return _verify(_leaf, merkleRoot, _proof);
    }

    function _verify(
        bytes32 _leaf,
        bytes32 _root,
        bytes32[] memory _proof
    ) internal pure returns (bool) {
        return MerkleProof.verify(_proof, _root, _leaf);
    }

    // ---- STAKING ----
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable override(ERC721X) {
        require(
            tokensLastStakedAt[tokenId] == 0,
            "Cannot transfer staked token"
        );
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public payable override(ERC721X) {
        require(
            tokensLastStakedAt[tokenId] == 0,
            "Cannot transfer staked token"
        );
        super.safeTransferFrom(from, to, tokenId, _data);
    }

    function stake(uint256 tokenId) public {
        require(canStake, "staking not open");
        require(
            msg.sender == ownerOf(tokenId) || msg.sender == owner(),
            "caller must be owner of token or contract owner"
        );
        require(tokensLastStakedAt[tokenId] == 0, "already staking");
        tokensLastStakedAt[tokenId] = block.timestamp;
        emit Stake(tokenId, msg.sender, tokensLastStakedAt[tokenId]);
    }

    function unstake(uint256 tokenId) public {
        require(
            msg.sender == ownerOf(tokenId) || msg.sender == owner(),
            "caller must be owner of token or contract owner"
        );
        require(tokensLastStakedAt[tokenId] > 0, "not staking");
        uint256 lsa = tokensLastStakedAt[tokenId];
        tokensLastStakedAt[tokenId] = 0;
        emit Unstake(tokenId, msg.sender, block.timestamp, lsa);
    }

    function setTokensStakeStatus(uint256[] memory tokenIds, bool setStake)
        external
    {
        for (uint256 i; i < tokenIds.length; i++) {
            uint256 tokenId = tokenIds[i];
            if (setStake) {
                stake(tokenId);
            } else {
                unstake(tokenId);
            }
        }
    }

    function setCanStake(bool b) external onlyOwner {
        canStake = b;
    }

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

    function withdrawAll() external onlyOwner {
        uint256 balance = address(this).balance;
        require(balance > 0, "there is nothing to withdraw");
        _withdraw(owner(), address(this).balance);
    }

    function _withdraw(address _address, uint256 _amount) private {
        (bool success, ) = _address.call{value: _amount}("");
        require(success, "could not withdraw");
    }
}

File 1 of 11: Context.sol
// SPDX-License-Identifier: MIT
// 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 3 of 11: ERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import "./IERC721A.sol";

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

/**
 * @title ERC721A
 *
 * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721)
 * Non-Fungible Token Standard, including the Metadata extension.
 * Optimized for lower gas during batch mints.
 *
 * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...)
 * starting from `_startTokenId()`.
 *
 * Assumptions:
 *
 * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364).
    struct TokenApprovalRef {
        address value;
    }

    // =============================================================
    //                           CONSTANTS
    // =============================================================

    // Mask of an entry in packed address data.
    uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

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

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

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

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

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

    // The bit mask of the `burned` bit in packed ownership.
    uint256 private constant _BITMASK_BURNED = 1 << 224;

    // The bit position of the `nextInitialized` bit in packed ownership.
    uint256 private constant _BITPOS_NEXT_INITIALIZED = 225;

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

    // The bit position of `extraData` in packed ownership.
    uint256 private constant _BITPOS_EXTRA_DATA = 232;

    // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`.
    uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;

    // The mask of the lower 160 bits for addresses.
    uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;

    // The maximum `quantity` that can be minted with {_mintERC2309}.
    // This limit is to prevent overflows on the address data entries.
    // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309}
    // is required to cause an overflow, which is unrealistic.
    uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;

    // The `Transfer` event signature is given by:
    // `keccak256(bytes("Transfer(address,address,uint256)"))`.
    bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

    // =============================================================
    //                            STORAGE
    // =============================================================

    // The next token ID to be minted.
    uint256 private _currentIndex;

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

    // =============================================================
    //                          CONSTRUCTOR
    // =============================================================

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

    // =============================================================
    //                   TOKEN COUNTING OPERATIONS
    // =============================================================

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

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

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

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

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

    // =============================================================
    //                    ADDRESS DATA OPERATIONS
    // =============================================================

    /**
     * @dev Returns the number of tokens in `owner`'s account.
     */
    function balanceOf(address owner)
        public
        view
        virtual
        override
        returns (uint256)
    {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
    }

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

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

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

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

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

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override
        returns (bool)
    {
        // The interface IDs are constants representing the first 4 bytes
        // of the XOR of all function selectors in the interface.
        // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165)
        // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`)
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

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

    /**
     * @dev Returns the token collection name.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

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

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

    // =============================================================
    //                     OWNERSHIPS OPERATIONS
    // =============================================================

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId)
        public
        view
        virtual
        override
        returns (address)
    {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

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

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

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

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

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & _BITMASK_BURNED == 0) {
                        // Invariant:
                        // There will always be an initialized ownership slot
                        // (i.e. `ownership.addr != address(0) && ownership.burned == false`)
                        // before an unintialized ownership slot
                        // (i.e. `ownership.addr == address(0) && ownership.burned == false`)
                        // Hence, `curr` will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed will be zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @dev Returns the unpacked `TokenOwnership` struct from `packed`.
     */
    function _unpackedOwnership(uint256 packed)
        private
        pure
        returns (TokenOwnership memory ownership)
    {
        ownership.addr = address(uint160(packed));
        ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP);
        ownership.burned = packed & _BITMASK_BURNED != 0;
        ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
    }

    /**
     * @dev Packs ownership data into a single uint256.
     */
    function _packOwnershipData(address owner, uint256 flags)
        private
        view
        returns (uint256 result)
    {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`.
            result := or(
                owner,
                or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)
            )
        }
    }

    /**
     * @dev Returns the `nextInitialized` flag set if `quantity` equals 1.
     */
    function _nextInitializedFlag(uint256 quantity)
        private
        pure
        returns (uint256 result)
    {
        // For branchless setting of the `nextInitialized` flag.
        assembly {
            // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`.
            result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
        }
    }

    // =============================================================
    //                      APPROVAL OPERATIONS
    // =============================================================

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

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

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

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId)
        public
        view
        virtual
        override
        returns (address)
    {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId].value;
    }

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom}
     * for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool approved)
        public
        virtual
        override
    {
        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
    }

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

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

    /**
     * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`.
     */
    function _isSenderApprovedOrOwner(
        address approvedAddress,
        address owner,
        address msgSender
    ) private pure returns (bool result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
            msgSender := and(msgSender, _BITMASK_ADDRESS)
            // `msgSender == owner || msgSender == approvedAddress`.
            result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
        }
    }

    /**
     * @dev Returns the storage slot and value for the approved address of `tokenId`.
     */
    function _getApprovedSlotAndAddress(uint256 tokenId)
        private
        view
        returns (uint256 approvedAddressSlot, address approvedAddress)
    {
        TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];
        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`.
        assembly {
            approvedAddressSlot := tokenApproval.slot
            approvedAddress := sload(approvedAddressSlot)
        }
    }

    // =============================================================
    //                      TRANSFER OPERATIONS
    // =============================================================

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

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

        (
            uint256 approvedAddressSlot,
            address approvedAddress
        ) = _getApprovedSlotAndAddress(tokenId);

        // The nested ifs save around 20+ gas over a compound boolean condition.
        if (
            !_isSenderApprovedOrOwner(
                approvedAddress,
                from,
                _msgSenderERC721A()
            )
        )
            if (!isApprovedForAll(from, _msgSenderERC721A()))
                revert TransferCallerNotOwnerNorApproved();

        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

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

            // Updates:
            // - `address` to the next owner.
            // - `startTimestamp` to the timestamp of transfering.
            // - `burned` to `false`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                to,
                _BITMASK_NEXT_INITIALIZED |
                    _nextExtraData(from, to, prevOwnershipPacked)
            );

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

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

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement
     * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public payable virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

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

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

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

    // =============================================================
    //                        MINT OPERATIONS
    // =============================================================

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

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

        // Overflows are incredibly unrealistic.
        // `balance` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] +=
                quantity *
                ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) |
                    _nextExtraData(address(0), to, 0)
            );

            uint256 toMasked;
            uint256 end = startTokenId + quantity;

            // Use assembly to loop and emit the `Transfer` event for gas savings.
            // The duplicated `log4` removes an extra check and reduces stack juggling.
            // The assembly, together with the surrounding Solidity code, have been
            // delicately arranged to nudge the compiler into producing optimized opcodes.
            assembly {
                // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
                toMasked := and(to, _BITMASK_ADDRESS)
                // Emit the `Transfer` event.
                log4(
                    0, // Start of data (0, since no data).
                    0, // End of data (0, since no data).
                    _TRANSFER_EVENT_SIGNATURE, // Signature.
                    0, // `address(0)`.
                    toMasked, // `to`.
                    startTokenId // `tokenId`.
                )

                // The `iszero(eq(,))` check ensures that large values of `quantity`
                // that overflows uint256 will make the loop run out of gas.
                // The compiler will optimize the `iszero` away for performance.
                for {
                    let tokenId := add(startTokenId, 1)
                } iszero(eq(tokenId, end)) {
                    tokenId := add(tokenId, 1)
                } {
                    // Emit the `Transfer` event. Similar to above.
                    log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
                }
            }
            if (toMasked == 0) revert MintToZeroAddress();

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

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * This function is intended for efficient minting only during contract creation.
     *
     * It emits only one {ConsecutiveTransfer} as defined in
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
     * instead of a sequence of {Transfer} event(s).
     *
     * Calling this function outside of contract creation WILL make your contract
     * non-compliant with the ERC721 standard.
     * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
     * {ConsecutiveTransfer} event is only permissible during contract creation.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {ConsecutiveTransfer} event.
     */
    function _mintERC2309(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();
        if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT)
            revert MintERC2309QuantityExceedsLimit();

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

        // Overflows are unrealistic due to the above check for `quantity` to be below the limit.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] +=
                quantity *
                ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) |
                    _nextExtraData(address(0), to, 0)
            );

            emit ConsecutiveTransfer(
                startTokenId,
                startTokenId + quantity - 1,
                address(0),
                to
            );

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

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

        unchecked {
            if (to.code.length != 0) {
                uint256 end = _currentIndex;
                uint256 index = end - quantity;
                do {
                    if (
                        !_checkContractOnERC721Received(
                            address(0),
                            to,
                            index++,
                            _data
                        )
                    ) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (index < end);
                // Reentrancy protection.
                if (_currentIndex != end) revert();
            }
        }
    }

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

    // =============================================================
    //                        BURN OPERATIONS
    // =============================================================

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

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

        address from = address(uint160(prevOwnershipPacked));

        (
            uint256 approvedAddressSlot,
            address approvedAddress
        ) = _getApprovedSlotAndAddress(tokenId);

        if (approvalCheck) {
            // The nested ifs save around 20+ gas over a compound boolean condition.
            if (
                !_isSenderApprovedOrOwner(
                    approvedAddress,
                    from,
                    _msgSenderERC721A()
                )
            )
                if (!isApprovedForAll(from, _msgSenderERC721A()))
                    revert TransferCallerNotOwnerNorApproved();
        }

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

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

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

            // Updates:
            // - `address` to the last owner.
            // - `startTimestamp` to the timestamp of burning.
            // - `burned` to `true`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                from,
                (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) |
                    _nextExtraData(from, address(0), prevOwnershipPacked)
            );

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

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

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

    // =============================================================
    //                     EXTRA DATA OPERATIONS
    // =============================================================

    /**
     * @dev Directly sets the extra data for the ownership data `index`.
     */
    function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual {
        uint256 packed = _packedOwnerships[index];
        if (packed == 0) revert OwnershipNotInitializedForExtraData();
        uint256 extraDataCasted;
        // Cast `extraData` with assembly to avoid redundant masking.
        assembly {
            extraDataCasted := extraData
        }
        packed =
            (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) |
            (extraDataCasted << _BITPOS_EXTRA_DATA);
        _packedOwnerships[index] = packed;
    }

    /**
     * @dev Called during each token transfer to set the 24bit `extraData` field.
     * Intended to be overridden by the cosumer contract.
     *
     * `previousExtraData` - the value of `extraData` before transfer.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _extraData(
        address from,
        address to,
        uint24 previousExtraData
    ) internal view virtual returns (uint24) {}

    /**
     * @dev Returns the next extra data for the packed ownership data.
     * The returned result is shifted into position.
     */
    function _nextExtraData(
        address from,
        address to,
        uint256 prevOwnershipPacked
    ) private view returns (uint256) {
        uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA);
        return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA;
    }

    // =============================================================
    //                       OTHER OPERATIONS
    // =============================================================

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

    /**
     * @dev Converts a uint256 to its ASCII string decimal representation.
     */
    function _toString(uint256 value)
        internal
        pure
        virtual
        returns (string memory str)
    {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit), but
            // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
            // We will need 1 word for the trailing zeros padding, 1 word for the length,
            // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
            let m := add(mload(0x40), 0xa0)
            // Update the free memory pointer to allocate.
            mstore(0x40, m)
            // Assign the `str` to the end.
            str := sub(m, 0x20)
            // Zeroize the slot after the string.
            mstore(str, 0)

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

            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // prettier-ignore
            for { let temp := value } 1 {} {
                str := sub(str, 1)
                // Write the character to the pointer.
                // The ASCII index of the '0' character is 48.
                mstore8(str, add(48, mod(temp, 10)))
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
                // prettier-ignore
                if iszero(temp) { break }
            }

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

File 4 of 11: ERC721LockRegistry.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.2;

/*
 *     ,_,
 *    (',')
 *    {/"\}
 *    -"-"-
 */

import "./ERC721A.sol";
import "./LockRegistry.sol";

contract ERC721X is LockRegistry, ERC721A {
    /*
     *     bytes4(keccak256('freeId(uint256,address)')) == 0x94d216d6
     *     bytes4(keccak256('isUnlocked(uint256)')) == 0x72abc8b7
     *     bytes4(keccak256('lockCount(uint256)')) == 0x650b00f6
     *     bytes4(keccak256('lockId(uint256)')) == 0x2799cde0
     *     bytes4(keccak256('lockMap(uint256,uint256)')) == 0x2cba8123
     *     bytes4(keccak256('lockMapIndex(uint256,address)')) == 0x09308e5d
     *     bytes4(keccak256('unlockId(uint256)')) == 0x40a9c8df
     *     bytes4(keccak256('approvedContract(address)')) == 0xb1a6505f
     *
     *     => 0x94d216d6 ^ 0x72abc8b7 ^ 0x650b00f6 ^ 0x2799cde0 ^
     *        0x2cba8123 ^ 0x09308e5d ^ 0x40a9c8df ^ 0xb1a6505f == 0x706e8489
     */

    bytes4 private constant _INTERFACE_ID_ERC721x = 0x706e8489;

    constructor(string memory _name, string memory _symbol)
        ERC721A(_name, _symbol)
    {}

    function supportsInterface(bytes4 _interfaceId)
        public
        view
        virtual
        override(ERC721A)
        returns (bool)
    {
        return
            _interfaceId == _INTERFACE_ID_ERC721x ||
            super.supportsInterface(_interfaceId);
    }

    function transferFrom(
        address _from,
        address _to,
        uint256 _tokenId
    ) public payable virtual override {
        require(isUnlocked(_tokenId), "Token is locked");
        ERC721A.transferFrom(_from, _to, _tokenId);
    }

    function safeTransferFrom(
        address _from,
        address _to,
        uint256 _tokenId,
        bytes memory _data
    ) public payable virtual override {
        require(isUnlocked(_tokenId), "Token is locked");
        ERC721A.safeTransferFrom(_from, _to, _tokenId, _data);
    }

    function lockId(uint256 _id) external virtual override {
        require(_exists(_id), "Token !exist");
        _lockId(_id);
    }

    function unlockId(uint256 _id) external virtual override {
        require(_exists(_id), "Token !exist");
        _unlockId(_id);
    }

    function freeId(uint256 _id, address _contract) external virtual override {
        require(_exists(_id), "Token !exist");
        _freeId(_id, _contract);
    }
}

File 5 of 11: IERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

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

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

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

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

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

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

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

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

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

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

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

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

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

    // =============================================================
    //                            STRUCTS
    // =============================================================

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Stores the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
        // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.
        uint24 extraData;
    }

    // =============================================================
    //                         TOKEN COUNTERS
    // =============================================================

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId`
     * (inclusive) is transferred from `from` to `to`, as defined in the
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
     *
     * See {_mintERC2309} for more details.
     */
    event ConsecutiveTransfer(
        uint256 indexed fromTokenId,
        uint256 toTokenId,
        address indexed from,
        address indexed to
    );
}

File 6 of 11: IERC721X.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.2;

interface IERC721X {
    /**
     * @dev Returns if the token is locked (non-transferrable) or not.
     */
    function isUnlocked(uint256 _id) external view returns (bool);

    /**
     * @dev Returns the amount of locks on the token.
     */
    function lockCount(uint256 _tokenId) external view returns (uint256);

    /**
     * @dev Returns if a contract is allowed to lock/unlock tokens.
     */
    function approvedContract(address _contract) external view returns (bool);

    /**
     * @dev Returns the contract that locked a token at a specific index in the mapping.
     */
    function lockMap(uint256 _tokenId, uint256 _index)
        external
        view
        returns (address);

    /**
     * @dev Returns the mapping index of a contract that locked a token.
     */
    function lockMapIndex(uint256 _tokenId, address _contract)
        external
        view
        returns (uint256);

    /**
     * @dev Locks a token, preventing it from being transferrable
     */
    function lockId(uint256 _id) external;

    /**
     * @dev Unlocks a token.
     */
    function unlockId(uint256 _id) external;

    /**
     * @dev Unlocks a token from a given contract if the contract is no longer approved.
     */
    function freeId(uint256 _id, address _contract) external;
}

File 7 of 11: LockRegistry.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.2;

/*
 *     ,_,
 *    (',')
 *    {/"\}
 *    -"-"-
 */

import "./Ownable.sol";
import "./IERC721X.sol";

abstract contract LockRegistry is Ownable, IERC721X {
    mapping(address => bool) public override approvedContract;
    mapping(uint256 => uint256) public override lockCount;
    mapping(uint256 => mapping(uint256 => address)) public override lockMap;
    mapping(uint256 => mapping(address => uint256))
        public
        override lockMapIndex;

    event TokenLocked(
        uint256 indexed tokenId,
        address indexed approvedContract
    );
    event TokenUnlocked(
        uint256 indexed tokenId,
        address indexed approvedContract
    );

    function isUnlocked(uint256 _id) public view override returns (bool) {
        return lockCount[_id] == 0;
    }

    function updateApprovedContracts(
        address[] calldata _contracts,
        bool[] calldata _values
    ) external onlyOwner {
        require(_contracts.length == _values.length, "!length");
        for (uint256 i = 0; i < _contracts.length; i++)
            approvedContract[_contracts[i]] = _values[i];
    }

    function _lockId(uint256 _id) internal {
        require(approvedContract[msg.sender], "Cannot update map");
        require(
            lockMapIndex[_id][msg.sender] == 0,
            "ID already locked by caller"
        );

        uint256 count = lockCount[_id] + 1;
        lockMap[_id][count] = msg.sender;
        lockMapIndex[_id][msg.sender] = count;
        lockCount[_id]++;
        emit TokenLocked(_id, msg.sender);
    }

    function _unlockId(uint256 _id) internal {
        require(approvedContract[msg.sender], "Cannot update map");
        uint256 index = lockMapIndex[_id][msg.sender];
        require(index != 0, "ID not locked by caller");

        uint256 last = lockCount[_id];
        if (index != last) {
            address lastContract = lockMap[_id][last];
            lockMap[_id][index] = lastContract;
            lockMap[_id][last] = address(0);
            lockMapIndex[_id][lastContract] = index;
        } else lockMap[_id][index] = address(0);
        lockMapIndex[_id][msg.sender] = 0;
        lockCount[_id]--;
        emit TokenUnlocked(_id, msg.sender);
    }

    function _freeId(uint256 _id, address _contract) internal {
        require(!approvedContract[_contract], "Cannot update map");
        uint256 index = lockMapIndex[_id][_contract];
        require(index != 0, "ID not locked");

        uint256 last = lockCount[_id];
        if (index != last) {
            address lastContract = lockMap[_id][last];
            lockMap[_id][index] = lastContract;
            lockMap[_id][last] = address(0);
            lockMapIndex[_id][lastContract] = index;
        } else lockMap[_id][index] = address(0);
        lockMapIndex[_id][_contract] = 0;
        lockCount[_id]--;
        emit TokenUnlocked(_id, _contract);
    }
}

File 8 of 11: Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding)
        internal
        pure
        returns (uint256)
    {
        unchecked {
            uint256 result = sqrt(a);
            return
                result +
                (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding)
        internal
        pure
        returns (uint256)
    {
        unchecked {
            uint256 result = log2(value);
            return
                result +
                (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10**64) {
                value /= 10**64;
                result += 64;
            }
            if (value >= 10**32) {
                value /= 10**32;
                result += 32;
            }
            if (value >= 10**16) {
                value /= 10**16;
                result += 16;
            }
            if (value >= 10**8) {
                value /= 10**8;
                result += 8;
            }
            if (value >= 10**4) {
                value /= 10**4;
                result += 4;
            }
            if (value >= 10**2) {
                value /= 10**2;
                result += 2;
            }
            if (value >= 10**1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding)
        internal
        pure
        returns (uint256)
    {
        unchecked {
            uint256 result = log10(value);
            return
                result +
                (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding)
        internal
        pure
        returns (uint256)
    {
        unchecked {
            uint256 result = log256(value);
            return
                result +
                (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

File 9 of 11: MerkleProof.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

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

    /**
     * @dev Calldata version of {verify}
     *
     * _Available since v4.7._
     */
    function verifyCalldata(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf)
        internal
        pure
        returns (bytes32)
    {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Calldata version of {processProof}
     *
     * _Available since v4.7._
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf)
        internal
        pure
        returns (bytes32)
    {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
     * respectively.
     *
     * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(
            leavesLen + proof.length - 1 == totalHashes,
            "MerkleProof: invalid multiproof"
        );

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen
                ? leaves[leafPos++]
                : hashes[hashPos++];
            bytes32 b = proofFlags[i]
                ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]
                : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(
            leavesLen + proof.length - 1 == totalHashes,
            "MerkleProof: invalid multiproof"
        );

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen
                ? leaves[leafPos++]
                : hashes[hashPos++];
            bytes32 b = proofFlags[i]
                ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]
                : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b)
        private
        pure
        returns (bytes32 value)
    {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

File 10 of 11: Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "./Context.sol";

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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

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

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

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

File 11 of 11: Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

import "./Math.sol";

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

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

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"bytes32","name":"_ogMerkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"_premiumMerkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"},{"internalType":"string","name":"_baseURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"by","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakedAt","type":"uint256"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"approvedContract","type":"address"}],"name":"TokenLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"approvedContract","type":"address"}],"name":"TokenUnlocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"by","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakedAt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unstakedAt","type":"uint256"}],"name":"Unstake","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"amountNftPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"approvedContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canStake","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"address","name":"_contract","type":"address"}],"name":"freeId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"giveaway","outputs":[],"stateMutability":"nonpayable","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":"uint256","name":"_id","type":"uint256"}],"name":"isUnlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lockCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"lockId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"lockMap","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"lockMapIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ogMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"ogWhitelistMint","outputs":[],"stateMutability":"nonpayable","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":"premiumMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"premiumWhitelistMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"sellingStep","outputs":[{"internalType":"enum EggzNFT.Step","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"b","type":"bool"}],"name":"setCanStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setOGMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setPremiumMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_step","type":"uint256"}],"name":"setStep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"bool","name":"setStake","type":"bool"}],"name":"setTokensStakeStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"stake","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":"uint256","name":"","type":"uint256"}],"name":"tokensLastStakedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"unlockId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_contracts","type":"address[]"},{"internalType":"bool[]","name":"_values","type":"bool[]"}],"name":"updateApprovedContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"whitelistMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060405162003c0438038062003c0483398101604081905262000034916200020b565b604051806040016040528060118152602001704567677a20427920536f616b766572736560781b8152506040518060400160405280600481526020016322a3a3ad60e11b81525081816200009762000091620000fb60201b60201c565b620000ff565b8151620000ac9060079060208501906200014f565b508051620000c29060089060208401906200014f565b506001600555505050600f85905550601083905560118290558051620000f090600d9060208401906200014f565b505050505062000344565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8280546200015d9062000307565b90600052602060002090601f016020900481019282620001815760008555620001cc565b82601f106200019c57805160ff1916838001178555620001cc565b82800160010185558215620001cc579182015b82811115620001cc578251825591602001919060010190620001af565b50620001da929150620001de565b5090565b5b80821115620001da5760008155600101620001df565b634e487b7160e01b600052604160045260246000fd5b600080600080608085870312156200022257600080fd5b8451602080870151604088015160608901519397509095509350906001600160401b03808211156200025357600080fd5b818801915088601f8301126200026857600080fd5b8151818111156200027d576200027d620001f5565b604051601f8201601f19908116603f01168101908382118183101715620002a857620002a8620001f5565b816040528281528b86848701011115620002c157600080fd5b600093505b82841015620002e55784840186015181850187015292850192620002c6565b82841115620002f75760008684830101525b989b979a50959850505050505050565b600181811c908216806200031c57607f821691505b602082108114156200033e57634e487b7160e01b600052602260045260246000fd5b50919050565b6138b080620003546000396000f3fe60806040526004361061031e5760003560e01c8063715018a6116101a5578063ac52e644116100ec578063e886718011610095578063f2fde38b1161006f578063f2fde38b1461091c578063f3ea198c1461093c578063f8dcbddb1461095c578063f90a82c81461097c57600080fd5b8063e886718014610893578063e985e9c5146108b3578063ee0eeb09146108fc57600080fd5b8063c87b56dd116100c6578063c87b56dd14610836578063cbccefb214610856578063e396d5251461087d57600080fd5b8063ac52e644146107d3578063b1a6505f146107f3578063b88d4fde1461082357600080fd5b806394d216d61161014e578063a0bcfc7f11610128578063a0bcfc7f14610773578063a22cb46514610793578063a694fc3a146107b357600080fd5b806394d216d61461072457806395d89b41146107445780639ed278091461075957600080fd5b8063853828b61161017f578063853828b6146106c45780638c4c2d49146106d95780638da5cb5b1461070657600080fd5b8063715018a61461066157806372abc8b7146106765780637cb64759146106a457600080fd5b80632799cde01161026957806340a9c8df11610212578063650b00f6116101ec578063650b00f6146105ff5780636c0360eb1461062c57806370a082311461064157600080fd5b806340a9c8df146105ac57806342842e0e146105cc5780636352211e146105df57600080fd5b80632eb4a7ab116102435780632eb4a7ab1461054957806335b504c51461055f578063372f657c1461058c57600080fd5b80632799cde0146104c85780632cba8123146104e85780632e17de781461052957600080fd5b80630a302530116102cb57806323b872dd116102a557806323b872dd14610475578063258a69f71461048857806325c2c020146104a857600080fd5b80630a3025301461042d5780631249c58b1461044357806318160ddd1461045857600080fd5b8063081812fc116102fc578063081812fc1461039c57806309308e5d146103d4578063095ea7b31461041a57600080fd5b806301ffc9a714610323578063050225ea1461035857806306fdde031461037a575b600080fd5b34801561032f57600080fd5b5061034361033e3660046130df565b61099c565b60405190151581526020015b60405180910390f35b34801561036457600080fd5b50610378610373366004613118565b6109e0565b005b34801561038657600080fd5b5061038f610af0565b60405161034f919061319a565b3480156103a857600080fd5b506103bc6103b73660046131ad565b610b82565b6040516001600160a01b03909116815260200161034f565b3480156103e057600080fd5b5061040c6103ef3660046131c6565b600460209081526000928352604080842090915290825290205481565b60405190815260200161034f565b610378610428366004613118565b610bdf565b34801561043957600080fd5b5061040c600f5481565b34801561044f57600080fd5b50610378610c98565b34801561046457600080fd5b50600654600554036000190161040c565b6103786104833660046131f2565b610e7b565b34801561049457600080fd5b506103786104a336600461327a565b610ee7565b3480156104b457600080fd5b506103786104c33660046131ad565b611145565b3480156104d457600080fd5b506103786104e33660046131ad565b611152565b3480156104f457600080fd5b506103bc6105033660046132bc565b60036020908152600092835260408084209091529082529020546001600160a01b031681565b34801561053557600080fd5b506103786105443660046131ad565b6111a2565b34801561055557600080fd5b5061040c60115481565b34801561056b57600080fd5b5061040c61057a3660046131ad565b60146020526000908152604090205481565b34801561059857600080fd5b506103786105a736600461327a565b6112ff565b3480156105b857600080fd5b506103786105c73660046131ad565b611537565b6103786105da3660046131f2565b611584565b3480156105eb57600080fd5b506103bc6105fa3660046131ad565b61159f565b34801561060b57600080fd5b5061040c61061a3660046131ad565b60026020526000908152604090205481565b34801561063857600080fd5b5061038f6115aa565b34801561064d57600080fd5b5061040c61065c3660046132de565b611638565b34801561066d57600080fd5b506103786116a0565b34801561068257600080fd5b506103436106913660046131ad565b6000908152600260205260409020541590565b3480156106b057600080fd5b506103786106bf3660046131ad565b6116b2565b3480156106d057600080fd5b506103786116bf565b3480156106e557600080fd5b5061040c6106f43660046132de565b60126020526000908152604090205481565b34801561071257600080fd5b506000546001600160a01b03166103bc565b34801561073057600080fd5b5061037861073f3660046131c6565b611730565b34801561075057600080fd5b5061038f61177e565b34801561076557600080fd5b506013546103439060ff1681565b34801561077f57600080fd5b5061037861078e366004613398565b61178d565b34801561079f57600080fd5b506103786107ae3660046133f1565b6117a8565b3480156107bf57600080fd5b506103786107ce3660046131ad565b611814565b3480156107df57600080fd5b506103786107ee36600461341b565b6119bd565b3480156107ff57600080fd5b5061034361080e3660046132de565b60016020526000908152604090205460ff1681565b610378610831366004613487565b611ab2565b34801561084257600080fd5b5061038f6108513660046131ad565b611b20565b34801561086257600080fd5b50600e546108709060ff1681565b60405161034f9190613519565b34801561088957600080fd5b5061040c60105481565b34801561089f57600080fd5b506103786108ae366004613541565b611ba9565b3480156108bf57600080fd5b506103436108ce36600461355c565b6001600160a01b039182166000908152600c6020908152604080832093909416825291909152205460ff1690565b34801561090857600080fd5b506103786109173660046131ad565b611bc4565b34801561092857600080fd5b506103786109373660046132de565b611bd1565b34801561094857600080fd5b50610378610957366004613586565b611c5e565b34801561096857600080fd5b506103786109773660046131ad565b611e95565b34801561098857600080fd5b506103786109973660046135d2565b611ed3565b60006001600160e01b031982167f706e84890000000000000000000000000000000000000000000000000000000014806109da57506109da82611f2d565b92915050565b6109e8611fc6565b6004600e5460ff166005811115610a0157610a01613503565b11610a795760405162461bcd60e51b815260206004820152602160248201527f476976656177617920697320616674657220746865207075626c69632073616c60448201527f650000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6006546005546113889183910360001901610a9491906136a0565b1115610ae25760405162461bcd60e51b815260206004820152601360248201527f4d617820737570706c79206578636565646564000000000000000000000000006044820152606401610a70565b610aec8282612020565b5050565b606060078054610aff906136b8565b80601f0160208091040260200160405190810160405280929190818152602001828054610b2b906136b8565b8015610b785780601f10610b4d57610100808354040283529160200191610b78565b820191906000526020600020905b815481529060010190602001808311610b5b57829003601f168201915b5050505050905090565b6000610b8d8261203a565b610bc3576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000908152600b60205260409020546001600160a01b031690565b6000610bea8261159f565b9050336001600160a01b03821614610c3c57610c0681336108ce565b610c3c576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600b602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b323314610ce75760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610a70565b6004600e5460ff166005811115610d0057610d00613503565b1015610d4e5760405162461bcd60e51b815260206004820152601c60248201527f5075626c69632073616c65206973206e6f7420616374697661746564000000006044820152606401610a70565b33600090815260126020526040902054600190610d6b90826136a0565b1115610ddf5760405162461bcd60e51b815260206004820152602960248201527f596f752063616e206f6e6c79206765742031204e4654206f6e2074686520507560448201527f626c69632053616c6500000000000000000000000000000000000000000000006064820152608401610a70565b6006546005546111e491900360001901610dfa9060016136a0565b1115610e485760405162461bcd60e51b815260206004820152601c60248201527f4d617820667265656d696e7420737570706c79206578636565646564000000006044820152606401610a70565b336000908152601260205260408120805460019290610e689084906136a0565b90915550610e799050336001612020565b565b60008181526014602052604090205415610ed75760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f74207472616e73666572207374616b656420746f6b656e000000006044820152606401610a70565b610ee283838361206f565b505050565b323314610f365760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610a70565b6002600e5460ff166005811115610f4f57610f4f613503565b1015610fc35760405162461bcd60e51b815260206004820152602760248201527f5072656d69756d2057686974656c6973742073616c65206973206e6f7420616360448201527f74697661746564000000000000000000000000000000000000000000000000006064820152608401610a70565b610fce3383836120d6565b61101a5760405162461bcd60e51b815260206004820152601760248201527f4e6f74205072656d69756d2077686974656c69737465640000000000000000006044820152606401610a70565b3360009081526012602052604090205460029061103790826136a0565b11156110ab5760405162461bcd60e51b815260206004820152603460248201527f596f752063616e206f6e6c79206765742032204e4654206f6e2074686520507260448201527f656d69756d2057686974656c6973742053616c650000000000000000000000006064820152608401610a70565b6006546005546111e4919003600019016110c69060026136a0565b11156111145760405162461bcd60e51b815260206004820152601c60248201527f4d617820667265656d696e7420737570706c79206578636565646564000000006044820152606401610a70565b3360009081526012602052604081208054600292906111349084906136a0565b90915550610aec9050336002612020565b61114d611fc6565b600f55565b61115b8161203a565b6111965760405162461bcd60e51b815260206004820152600c60248201526b151bdad95b8808595e1a5cdd60a21b6044820152606401610a70565b61119f8161215b565b50565b6111ab8161159f565b6001600160a01b0316336001600160a01b031614806111d457506000546001600160a01b031633145b6112465760405162461bcd60e51b815260206004820152602f60248201527f63616c6c6572206d757374206265206f776e6572206f6620746f6b656e206f7260448201527f20636f6e7472616374206f776e657200000000000000000000000000000000006064820152608401610a70565b6000818152601460205260409020546112a15760405162461bcd60e51b815260206004820152600b60248201527f6e6f74207374616b696e670000000000000000000000000000000000000000006044820152606401610a70565b6000818152601460209081526040808320805493905580518481523392810192909252428282015260608201839052517fc1e00202ee2c06861d326fc6374026b751863ff64218ccbaa38c3e603a8e72c29181900360800190a15050565b32331461134e5760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610a70565b6003600e5460ff16600581111561136757611367613503565b10156113b55760405162461bcd60e51b815260206004820152601f60248201527f57686974656c6973742073616c65206973206e6f7420616374697661746564006044820152606401610a70565b6113c03383836122cb565b61140c5760405162461bcd60e51b815260206004820152600f60248201527f4e6f742077686974656c697374656400000000000000000000000000000000006044820152606401610a70565b3360009081526012602052604090205460019061142990826136a0565b111561149d5760405162461bcd60e51b815260206004820152602c60248201527f596f752063616e206f6e6c79206765742031204e4654206f6e2074686520576860448201527f6974656c6973742053616c6500000000000000000000000000000000000000006064820152608401610a70565b6006546005546111e4919003600019016114b89060016136a0565b11156115065760405162461bcd60e51b815260206004820152601c60248201527f4d617820667265656d696e7420737570706c79206578636565646564000000006044820152606401610a70565b3360009081526012602052604081208054600192906115269084906136a0565b90915550610aec9050336001612020565b6115408161203a565b61157b5760405162461bcd60e51b815260206004820152600c60248201526b151bdad95b8808595e1a5cdd60a21b6044820152606401610a70565b61119f81612347565b610ee283838360405180602001604052806000815250611ab2565b60006109da82612514565b600d80546115b7906136b8565b80601f01602080910402602001604051908101604052809291908181526020018280546115e3906136b8565b80156116305780601f1061160557610100808354040283529160200191611630565b820191906000526020600020905b81548152906001019060200180831161161357829003601f168201915b505050505081565b60006001600160a01b03821661167a576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b03166000908152600a602052604090205467ffffffffffffffff1690565b6116a8611fc6565b610e79600061259d565b6116ba611fc6565b601155565b6116c7611fc6565b47806117155760405162461bcd60e51b815260206004820152601c60248201527f7468657265206973206e6f7468696e6720746f207769746864726177000000006044820152606401610a70565b61119f61172a6000546001600160a01b031690565b476125ed565b6117398261203a565b6117745760405162461bcd60e51b815260206004820152600c60248201526b151bdad95b8808595e1a5cdd60a21b6044820152606401610a70565b610aec8282612690565b606060088054610aff906136b8565b611795611fc6565b8051610aec90600d906020840190613030565b336000818152600c602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60135460ff166118665760405162461bcd60e51b815260206004820152601060248201527f7374616b696e67206e6f74206f70656e000000000000000000000000000000006044820152606401610a70565b61186f8161159f565b6001600160a01b0316336001600160a01b0316148061189857506000546001600160a01b031633145b61190a5760405162461bcd60e51b815260206004820152602f60248201527f63616c6c6572206d757374206265206f776e6572206f6620746f6b656e206f7260448201527f20636f6e7472616374206f776e657200000000000000000000000000000000006064820152608401610a70565b600081815260146020526040902054156119665760405162461bcd60e51b815260206004820152600f60248201527f616c7265616479207374616b696e6700000000000000000000000000000000006044820152606401610a70565b6000818152601460209081526040918290204290819055825184815233928101929092528183015290517f02567b2553aeb44e4ddd5d68462774dc3de158cb0f2c2da1740e729b22086aff9181900360600190a150565b6119c5611fc6565b828114611a145760405162461bcd60e51b815260206004820152600760248201527f216c656e677468000000000000000000000000000000000000000000000000006044820152606401610a70565b60005b83811015611aab57828282818110611a3157611a316136f3565b9050602002016020810190611a469190613541565b60016000878785818110611a5c57611a5c6136f3565b9050602002016020810190611a7191906132de565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905580611aa381613709565b915050611a17565b5050505050565b60008281526014602052604090205415611b0e5760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f74207472616e73666572207374616b656420746f6b656e000000006044820152606401610a70565b611b1a84848484612883565b50505050565b6060611b2b8261203a565b611b775760405162461bcd60e51b815260206004820152601f60248201527f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e006044820152606401610a70565b600d611b82836128eb565b604051602001611b93929190613740565b6040516020818303038152906040529050919050565b611bb1611fc6565b6013805460ff1916911515919091179055565b611bcc611fc6565b601055565b611bd9611fc6565b6001600160a01b038116611c555760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610a70565b61119f8161259d565b323314611cad5760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610a70565b6001600e5460ff166005811115611cc657611cc6613503565b1015611d145760405162461bcd60e51b815260206004820152601f60248201527f57686974656c6973742073616c65206973206e6f7420616374697661746564006044820152606401610a70565b611d2033848484612995565b611d6c5760405162461bcd60e51b815260206004820152601260248201527f4e6f74204f472077686974656c697374656400000000000000000000000000006044820152606401610a70565b336000908152601260205260409020548390611d899082906136a0565b1115611dfd5760405162461bcd60e51b815260206004820152602860248201527f596f752072656163686564206d6178696d756d206f6e204f472057686974656c60448201527f6973742053616c650000000000000000000000000000000000000000000000006064820152608401610a70565b6006546005546111e49185910360001901611e1891906136a0565b1115611e665760405162461bcd60e51b815260206004820152601c60248201527f4d617820667265656d696e7420737570706c79206578636565646564000000006044820152606401610a70565b3360009081526012602052604081208054859290611e859084906136a0565b90915550610ee290503384612020565b611e9d611fc6565b806005811115611eaf57611eaf613503565b600e805460ff19166001836005811115611ecb57611ecb613503565b021790555050565b60005b8251811015610ee2576000838281518110611ef357611ef36136f3565b602002602001015190508215611f1157611f0c81611814565b611f1a565b611f1a816111a2565b5080611f2581613709565b915050611ed6565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b031983161480611f9057507f80ac58cd000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b806109da5750506001600160e01b0319167f5b5e139f000000000000000000000000000000000000000000000000000000001490565b6000546001600160a01b03163314610e795760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a70565b610aec828260405180602001604052806000815250612a24565b60008160011115801561204e575060055482105b80156109da575050600090815260096020526040902054600160e01b161590565b600081815260026020526040902054156120cb5760405162461bcd60e51b815260206004820152600f60248201527f546f6b656e206973206c6f636b656400000000000000000000000000000000006044820152606401610a70565b610ee2838383612a8a565b6040516bffffffffffffffffffffffff19606085901b166020820152600090819060340160405160208183030381529060405280519060200120905061215281601054868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c6792505050565b95945050505050565b3360009081526001602052604090205460ff166121ba5760405162461bcd60e51b815260206004820152601160248201527f43616e6e6f7420757064617465206d61700000000000000000000000000000006044820152606401610a70565b6000818152600460209081526040808320338452909152902054156122215760405162461bcd60e51b815260206004820152601b60248201527f494420616c7265616479206c6f636b65642062792063616c6c657200000000006044820152606401610a70565b60008181526002602052604081205461223b9060016136a0565b6000838152600360209081526040808320848452825280832080546001600160a01b031916339081179091558684526004835281842090845282528083208490558583526002909152812080549293509061229583613709565b9091555050604051339083907f9ecfd70e9ff36df72989324a49559383d39f9290d700b10cf5ac10dcb68d264390600090a35050565b6040516bffffffffffffffffffffffff19606085901b166020820152600090819060340160405160208183030381529060405280519060200120905061215281601154868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c6792505050565b3360009081526001602052604090205460ff166123a65760405162461bcd60e51b815260206004820152601160248201527f43616e6e6f7420757064617465206d61700000000000000000000000000000006044820152606401610a70565b60008181526004602090815260408083203384529091529020548061240d5760405162461bcd60e51b815260206004820152601760248201527f4944206e6f74206c6f636b65642062792063616c6c65720000000000000000006044820152606401610a70565b6000828152600260205260409020548181146124835760008381526003602090815260408083208484528252808320805486855282852080546001600160a01b03199081166001600160a01b039093169283179091558254169091558684526004835281842090845290915290208290556124ab565b6000838152600360209081526040808320858452909152902080546001600160a01b03191690555b60008381526004602090815260408083203384528252808320839055858352600290915281208054916124dd8361380a565b9091555050604051339084907f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3790600090a3505050565b6000818060011161256b5760055481101561256b57600081815260096020526040902054600160e01b8116612569575b80612562575060001901600081815260096020526040902054612544565b9392505050565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461263a576040519150601f19603f3d011682016040523d82523d6000602084013e61263f565b606091505b5050905080610ee25760405162461bcd60e51b815260206004820152601260248201527f636f756c64206e6f7420776974686472617700000000000000000000000000006044820152606401610a70565b6001600160a01b03811660009081526001602052604090205460ff16156126f95760405162461bcd60e51b815260206004820152601160248201527f43616e6e6f7420757064617465206d61700000000000000000000000000000006044820152606401610a70565b60008281526004602090815260408083206001600160a01b0385168452909152902054806127695760405162461bcd60e51b815260206004820152600d60248201527f4944206e6f74206c6f636b6564000000000000000000000000000000000000006044820152606401610a70565b6000838152600260205260409020548181146127df5760008481526003602090815260408083208484528252808320805486855282852080546001600160a01b03199081166001600160a01b03909316928317909155825416909155878452600483528184209084529091529020829055612807565b6000848152600360209081526040808320858452909152902080546001600160a01b03191690555b60008481526004602090815260408083206001600160a01b03871684528252808320839055868352600290915281208054916128428361380a565b90915550506040516001600160a01b0384169085907f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3790600090a350505050565b600082815260026020526040902054156128df5760405162461bcd60e51b815260206004820152600f60248201527f546f6b656e206973206c6f636b656400000000000000000000000000000000006044820152606401610a70565b611b1a84848484612c74565b606060006128f883612cb8565b600101905060008167ffffffffffffffff811115612918576129186132f9565b6040519080825280601f01601f191660200182016040528015612942576020820181803683370190505b5090508181016020015b600019017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85049450846129885761298d565b61294c565b509392505050565b6040516bffffffffffffffffffffffff19606086901b166020820152603481018490526000908190605401604051602081830303815290604052805190602001209050612a1881600f54868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c6792505050565b9150505b949350505050565b612a2e8383612d9a565b6001600160a01b0383163b15610ee2576005548281035b612a586000868380600101945086612ec4565b612a75576040516368d2bf6b60e11b815260040160405180910390fd5b818110612a45578160055414611aab57600080fd5b6000612a9582612514565b9050836001600160a01b0316816001600160a01b031614612ae2576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600b602052604090208054338082146001600160a01b03881690911417612b4857612b1286336108ce565b612b48576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038516612b88576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8015612b9357600082555b6001600160a01b038681166000908152600a60205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260096020526040902055600160e11b8316612c1e5760018401600081815260096020526040902054612c1c576005548114612c1c5760008181526009602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b6000612a1c828486612fa9565b612c7f848484610e7b565b6001600160a01b0383163b15611b1a57612c9b84848484612ec4565b611b1a576040516368d2bf6b60e11b815260040160405180910390fd5b6000807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612d01577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310612d2d576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310612d4b57662386f26fc10000830492506010015b6305f5e1008310612d63576305f5e100830492506008015b6127108310612d7757612710830492506004015b60648310612d89576064830492506002015b600a83106109da5760010192915050565b60055481612dd4576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383166000818152600a602090815260408083208054680100000000000000018802019055848352600990915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b818114612e8357808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101612e4b565b5081612ebb576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055550505050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290612ef9903390899088908890600401613821565b6020604051808303816000875af1925050508015612f34575060408051601f3d908101601f19168201909252612f319181019061385d565b60015b612f8f573d808015612f62576040519150601f19603f3d011682016040523d82523d6000602084013e612f67565b606091505b508051612f87576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612a1c565b600082612fb68584612fbf565b14949350505050565b600081815b845181101561298d57612ff082868381518110612fe357612fe36136f3565b6020026020010151613004565b915080612ffc81613709565b915050612fc4565b6000818310613020576000828152602084905260409020612562565b5060009182526020526040902090565b82805461303c906136b8565b90600052602060002090601f01602090048101928261305e57600085556130a4565b82601f1061307757805160ff19168380011785556130a4565b828001600101855582156130a4579182015b828111156130a4578251825591602001919060010190613089565b506130b09291506130b4565b5090565b5b808211156130b057600081556001016130b5565b6001600160e01b03198116811461119f57600080fd5b6000602082840312156130f157600080fd5b8135612562816130c9565b80356001600160a01b038116811461311357600080fd5b919050565b6000806040838503121561312b57600080fd5b613134836130fc565b946020939093013593505050565b60005b8381101561315d578181015183820152602001613145565b83811115611b1a5750506000910152565b60008151808452613186816020860160208601613142565b601f01601f19169290920160200192915050565b602081526000612562602083018461316e565b6000602082840312156131bf57600080fd5b5035919050565b600080604083850312156131d957600080fd5b823591506131e9602084016130fc565b90509250929050565b60008060006060848603121561320757600080fd5b613210846130fc565b925061321e602085016130fc565b9150604084013590509250925092565b60008083601f84011261324057600080fd5b50813567ffffffffffffffff81111561325857600080fd5b6020830191508360208260051b850101111561327357600080fd5b9250929050565b6000806020838503121561328d57600080fd5b823567ffffffffffffffff8111156132a457600080fd5b6132b08582860161322e565b90969095509350505050565b600080604083850312156132cf57600080fd5b50508035926020909101359150565b6000602082840312156132f057600080fd5b612562826130fc565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613338576133386132f9565b604052919050565b600067ffffffffffffffff83111561335a5761335a6132f9565b61336d601f8401601f191660200161330f565b905082815283838301111561338157600080fd5b828260208301376000602084830101529392505050565b6000602082840312156133aa57600080fd5b813567ffffffffffffffff8111156133c157600080fd5b8201601f810184136133d257600080fd5b612a1c84823560208401613340565b8035801515811461311357600080fd5b6000806040838503121561340457600080fd5b61340d836130fc565b91506131e9602084016133e1565b6000806000806040858703121561343157600080fd5b843567ffffffffffffffff8082111561344957600080fd5b6134558883890161322e565b9096509450602087013591508082111561346e57600080fd5b5061347b8782880161322e565b95989497509550505050565b6000806000806080858703121561349d57600080fd5b6134a6856130fc565b93506134b4602086016130fc565b925060408501359150606085013567ffffffffffffffff8111156134d757600080fd5b8501601f810187136134e857600080fd5b6134f787823560208401613340565b91505092959194509250565b634e487b7160e01b600052602160045260246000fd5b602081016006831061353b57634e487b7160e01b600052602160045260246000fd5b91905290565b60006020828403121561355357600080fd5b612562826133e1565b6000806040838503121561356f57600080fd5b613578836130fc565b91506131e9602084016130fc565b60008060006040848603121561359b57600080fd5b83359250602084013567ffffffffffffffff8111156135b957600080fd5b6135c58682870161322e565b9497909650939450505050565b600080604083850312156135e557600080fd5b823567ffffffffffffffff808211156135fd57600080fd5b818501915085601f83011261361157600080fd5b8135602082821115613625576136256132f9565b8160051b925061363681840161330f565b828152928401810192818101908985111561365057600080fd5b948201945b8486101561366e57853582529482019490820190613655565b965061367d90508782016133e1565b9450505050509250929050565b634e487b7160e01b600052601160045260246000fd5b600082198211156136b3576136b361368a565b500190565b600181811c908216806136cc57607f821691505b602082108114156136ed57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600060001982141561371d5761371d61368a565b5060010190565b60008151613736818560208601613142565b9290920192915050565b600080845481600182811c91508083168061375c57607f831692505b602080841082141561377c57634e487b7160e01b86526022600452602486fd5b81801561379057600181146137a1576137ce565b60ff198616895284890196506137ce565b60008b81526020902060005b868110156137c65781548b8201529085019083016137ad565b505084890196505b5050505050506121526137e18286613724565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000815260050190565b6000816138195761381961368a565b506000190190565b60006001600160a01b03808716835280861660208401525083604083015260806060830152613853608083018461316e565b9695505050505050565b60006020828403121561386f57600080fd5b8151612562816130c956fea264697066735822122005f92bfdbff70a84131e076ea8893046ed01df5e998b0913b5383f87efd3a90964736f6c634300080c0033d8a5ef9b558a496a4ca83e444305247c81d0f5d6fd3e1a956b172509239e31f3d88df37125fbaf36fb8f1c4751d1dd015f7b67b90a71f1530fa754e330aa23deba8f4b48ecc9e8c5d70630df4500684c6d3f59a51316ab198f212a165bc96f2700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000036697066733a2f2f516d614651765432596b38696d5764794255546a646f55744254467274785042745844784775764c554e575553382f00000000000000000000

Deployed Bytecode

0x60806040526004361061031e5760003560e01c8063715018a6116101a5578063ac52e644116100ec578063e886718011610095578063f2fde38b1161006f578063f2fde38b1461091c578063f3ea198c1461093c578063f8dcbddb1461095c578063f90a82c81461097c57600080fd5b8063e886718014610893578063e985e9c5146108b3578063ee0eeb09146108fc57600080fd5b8063c87b56dd116100c6578063c87b56dd14610836578063cbccefb214610856578063e396d5251461087d57600080fd5b8063ac52e644146107d3578063b1a6505f146107f3578063b88d4fde1461082357600080fd5b806394d216d61161014e578063a0bcfc7f11610128578063a0bcfc7f14610773578063a22cb46514610793578063a694fc3a146107b357600080fd5b806394d216d61461072457806395d89b41146107445780639ed278091461075957600080fd5b8063853828b61161017f578063853828b6146106c45780638c4c2d49146106d95780638da5cb5b1461070657600080fd5b8063715018a61461066157806372abc8b7146106765780637cb64759146106a457600080fd5b80632799cde01161026957806340a9c8df11610212578063650b00f6116101ec578063650b00f6146105ff5780636c0360eb1461062c57806370a082311461064157600080fd5b806340a9c8df146105ac57806342842e0e146105cc5780636352211e146105df57600080fd5b80632eb4a7ab116102435780632eb4a7ab1461054957806335b504c51461055f578063372f657c1461058c57600080fd5b80632799cde0146104c85780632cba8123146104e85780632e17de781461052957600080fd5b80630a302530116102cb57806323b872dd116102a557806323b872dd14610475578063258a69f71461048857806325c2c020146104a857600080fd5b80630a3025301461042d5780631249c58b1461044357806318160ddd1461045857600080fd5b8063081812fc116102fc578063081812fc1461039c57806309308e5d146103d4578063095ea7b31461041a57600080fd5b806301ffc9a714610323578063050225ea1461035857806306fdde031461037a575b600080fd5b34801561032f57600080fd5b5061034361033e3660046130df565b61099c565b60405190151581526020015b60405180910390f35b34801561036457600080fd5b50610378610373366004613118565b6109e0565b005b34801561038657600080fd5b5061038f610af0565b60405161034f919061319a565b3480156103a857600080fd5b506103bc6103b73660046131ad565b610b82565b6040516001600160a01b03909116815260200161034f565b3480156103e057600080fd5b5061040c6103ef3660046131c6565b600460209081526000928352604080842090915290825290205481565b60405190815260200161034f565b610378610428366004613118565b610bdf565b34801561043957600080fd5b5061040c600f5481565b34801561044f57600080fd5b50610378610c98565b34801561046457600080fd5b50600654600554036000190161040c565b6103786104833660046131f2565b610e7b565b34801561049457600080fd5b506103786104a336600461327a565b610ee7565b3480156104b457600080fd5b506103786104c33660046131ad565b611145565b3480156104d457600080fd5b506103786104e33660046131ad565b611152565b3480156104f457600080fd5b506103bc6105033660046132bc565b60036020908152600092835260408084209091529082529020546001600160a01b031681565b34801561053557600080fd5b506103786105443660046131ad565b6111a2565b34801561055557600080fd5b5061040c60115481565b34801561056b57600080fd5b5061040c61057a3660046131ad565b60146020526000908152604090205481565b34801561059857600080fd5b506103786105a736600461327a565b6112ff565b3480156105b857600080fd5b506103786105c73660046131ad565b611537565b6103786105da3660046131f2565b611584565b3480156105eb57600080fd5b506103bc6105fa3660046131ad565b61159f565b34801561060b57600080fd5b5061040c61061a3660046131ad565b60026020526000908152604090205481565b34801561063857600080fd5b5061038f6115aa565b34801561064d57600080fd5b5061040c61065c3660046132de565b611638565b34801561066d57600080fd5b506103786116a0565b34801561068257600080fd5b506103436106913660046131ad565b6000908152600260205260409020541590565b3480156106b057600080fd5b506103786106bf3660046131ad565b6116b2565b3480156106d057600080fd5b506103786116bf565b3480156106e557600080fd5b5061040c6106f43660046132de565b60126020526000908152604090205481565b34801561071257600080fd5b506000546001600160a01b03166103bc565b34801561073057600080fd5b5061037861073f3660046131c6565b611730565b34801561075057600080fd5b5061038f61177e565b34801561076557600080fd5b506013546103439060ff1681565b34801561077f57600080fd5b5061037861078e366004613398565b61178d565b34801561079f57600080fd5b506103786107ae3660046133f1565b6117a8565b3480156107bf57600080fd5b506103786107ce3660046131ad565b611814565b3480156107df57600080fd5b506103786107ee36600461341b565b6119bd565b3480156107ff57600080fd5b5061034361080e3660046132de565b60016020526000908152604090205460ff1681565b610378610831366004613487565b611ab2565b34801561084257600080fd5b5061038f6108513660046131ad565b611b20565b34801561086257600080fd5b50600e546108709060ff1681565b60405161034f9190613519565b34801561088957600080fd5b5061040c60105481565b34801561089f57600080fd5b506103786108ae366004613541565b611ba9565b3480156108bf57600080fd5b506103436108ce36600461355c565b6001600160a01b039182166000908152600c6020908152604080832093909416825291909152205460ff1690565b34801561090857600080fd5b506103786109173660046131ad565b611bc4565b34801561092857600080fd5b506103786109373660046132de565b611bd1565b34801561094857600080fd5b50610378610957366004613586565b611c5e565b34801561096857600080fd5b506103786109773660046131ad565b611e95565b34801561098857600080fd5b506103786109973660046135d2565b611ed3565b60006001600160e01b031982167f706e84890000000000000000000000000000000000000000000000000000000014806109da57506109da82611f2d565b92915050565b6109e8611fc6565b6004600e5460ff166005811115610a0157610a01613503565b11610a795760405162461bcd60e51b815260206004820152602160248201527f476976656177617920697320616674657220746865207075626c69632073616c60448201527f650000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6006546005546113889183910360001901610a9491906136a0565b1115610ae25760405162461bcd60e51b815260206004820152601360248201527f4d617820737570706c79206578636565646564000000000000000000000000006044820152606401610a70565b610aec8282612020565b5050565b606060078054610aff906136b8565b80601f0160208091040260200160405190810160405280929190818152602001828054610b2b906136b8565b8015610b785780601f10610b4d57610100808354040283529160200191610b78565b820191906000526020600020905b815481529060010190602001808311610b5b57829003601f168201915b5050505050905090565b6000610b8d8261203a565b610bc3576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000908152600b60205260409020546001600160a01b031690565b6000610bea8261159f565b9050336001600160a01b03821614610c3c57610c0681336108ce565b610c3c576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600b602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b323314610ce75760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610a70565b6004600e5460ff166005811115610d0057610d00613503565b1015610d4e5760405162461bcd60e51b815260206004820152601c60248201527f5075626c69632073616c65206973206e6f7420616374697661746564000000006044820152606401610a70565b33600090815260126020526040902054600190610d6b90826136a0565b1115610ddf5760405162461bcd60e51b815260206004820152602960248201527f596f752063616e206f6e6c79206765742031204e4654206f6e2074686520507560448201527f626c69632053616c6500000000000000000000000000000000000000000000006064820152608401610a70565b6006546005546111e491900360001901610dfa9060016136a0565b1115610e485760405162461bcd60e51b815260206004820152601c60248201527f4d617820667265656d696e7420737570706c79206578636565646564000000006044820152606401610a70565b336000908152601260205260408120805460019290610e689084906136a0565b90915550610e799050336001612020565b565b60008181526014602052604090205415610ed75760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f74207472616e73666572207374616b656420746f6b656e000000006044820152606401610a70565b610ee283838361206f565b505050565b323314610f365760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610a70565b6002600e5460ff166005811115610f4f57610f4f613503565b1015610fc35760405162461bcd60e51b815260206004820152602760248201527f5072656d69756d2057686974656c6973742073616c65206973206e6f7420616360448201527f74697661746564000000000000000000000000000000000000000000000000006064820152608401610a70565b610fce3383836120d6565b61101a5760405162461bcd60e51b815260206004820152601760248201527f4e6f74205072656d69756d2077686974656c69737465640000000000000000006044820152606401610a70565b3360009081526012602052604090205460029061103790826136a0565b11156110ab5760405162461bcd60e51b815260206004820152603460248201527f596f752063616e206f6e6c79206765742032204e4654206f6e2074686520507260448201527f656d69756d2057686974656c6973742053616c650000000000000000000000006064820152608401610a70565b6006546005546111e4919003600019016110c69060026136a0565b11156111145760405162461bcd60e51b815260206004820152601c60248201527f4d617820667265656d696e7420737570706c79206578636565646564000000006044820152606401610a70565b3360009081526012602052604081208054600292906111349084906136a0565b90915550610aec9050336002612020565b61114d611fc6565b600f55565b61115b8161203a565b6111965760405162461bcd60e51b815260206004820152600c60248201526b151bdad95b8808595e1a5cdd60a21b6044820152606401610a70565b61119f8161215b565b50565b6111ab8161159f565b6001600160a01b0316336001600160a01b031614806111d457506000546001600160a01b031633145b6112465760405162461bcd60e51b815260206004820152602f60248201527f63616c6c6572206d757374206265206f776e6572206f6620746f6b656e206f7260448201527f20636f6e7472616374206f776e657200000000000000000000000000000000006064820152608401610a70565b6000818152601460205260409020546112a15760405162461bcd60e51b815260206004820152600b60248201527f6e6f74207374616b696e670000000000000000000000000000000000000000006044820152606401610a70565b6000818152601460209081526040808320805493905580518481523392810192909252428282015260608201839052517fc1e00202ee2c06861d326fc6374026b751863ff64218ccbaa38c3e603a8e72c29181900360800190a15050565b32331461134e5760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610a70565b6003600e5460ff16600581111561136757611367613503565b10156113b55760405162461bcd60e51b815260206004820152601f60248201527f57686974656c6973742073616c65206973206e6f7420616374697661746564006044820152606401610a70565b6113c03383836122cb565b61140c5760405162461bcd60e51b815260206004820152600f60248201527f4e6f742077686974656c697374656400000000000000000000000000000000006044820152606401610a70565b3360009081526012602052604090205460019061142990826136a0565b111561149d5760405162461bcd60e51b815260206004820152602c60248201527f596f752063616e206f6e6c79206765742031204e4654206f6e2074686520576860448201527f6974656c6973742053616c6500000000000000000000000000000000000000006064820152608401610a70565b6006546005546111e4919003600019016114b89060016136a0565b11156115065760405162461bcd60e51b815260206004820152601c60248201527f4d617820667265656d696e7420737570706c79206578636565646564000000006044820152606401610a70565b3360009081526012602052604081208054600192906115269084906136a0565b90915550610aec9050336001612020565b6115408161203a565b61157b5760405162461bcd60e51b815260206004820152600c60248201526b151bdad95b8808595e1a5cdd60a21b6044820152606401610a70565b61119f81612347565b610ee283838360405180602001604052806000815250611ab2565b60006109da82612514565b600d80546115b7906136b8565b80601f01602080910402602001604051908101604052809291908181526020018280546115e3906136b8565b80156116305780601f1061160557610100808354040283529160200191611630565b820191906000526020600020905b81548152906001019060200180831161161357829003601f168201915b505050505081565b60006001600160a01b03821661167a576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b03166000908152600a602052604090205467ffffffffffffffff1690565b6116a8611fc6565b610e79600061259d565b6116ba611fc6565b601155565b6116c7611fc6565b47806117155760405162461bcd60e51b815260206004820152601c60248201527f7468657265206973206e6f7468696e6720746f207769746864726177000000006044820152606401610a70565b61119f61172a6000546001600160a01b031690565b476125ed565b6117398261203a565b6117745760405162461bcd60e51b815260206004820152600c60248201526b151bdad95b8808595e1a5cdd60a21b6044820152606401610a70565b610aec8282612690565b606060088054610aff906136b8565b611795611fc6565b8051610aec90600d906020840190613030565b336000818152600c602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60135460ff166118665760405162461bcd60e51b815260206004820152601060248201527f7374616b696e67206e6f74206f70656e000000000000000000000000000000006044820152606401610a70565b61186f8161159f565b6001600160a01b0316336001600160a01b0316148061189857506000546001600160a01b031633145b61190a5760405162461bcd60e51b815260206004820152602f60248201527f63616c6c6572206d757374206265206f776e6572206f6620746f6b656e206f7260448201527f20636f6e7472616374206f776e657200000000000000000000000000000000006064820152608401610a70565b600081815260146020526040902054156119665760405162461bcd60e51b815260206004820152600f60248201527f616c7265616479207374616b696e6700000000000000000000000000000000006044820152606401610a70565b6000818152601460209081526040918290204290819055825184815233928101929092528183015290517f02567b2553aeb44e4ddd5d68462774dc3de158cb0f2c2da1740e729b22086aff9181900360600190a150565b6119c5611fc6565b828114611a145760405162461bcd60e51b815260206004820152600760248201527f216c656e677468000000000000000000000000000000000000000000000000006044820152606401610a70565b60005b83811015611aab57828282818110611a3157611a316136f3565b9050602002016020810190611a469190613541565b60016000878785818110611a5c57611a5c6136f3565b9050602002016020810190611a7191906132de565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905580611aa381613709565b915050611a17565b5050505050565b60008281526014602052604090205415611b0e5760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f74207472616e73666572207374616b656420746f6b656e000000006044820152606401610a70565b611b1a84848484612883565b50505050565b6060611b2b8261203a565b611b775760405162461bcd60e51b815260206004820152601f60248201527f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e006044820152606401610a70565b600d611b82836128eb565b604051602001611b93929190613740565b6040516020818303038152906040529050919050565b611bb1611fc6565b6013805460ff1916911515919091179055565b611bcc611fc6565b601055565b611bd9611fc6565b6001600160a01b038116611c555760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610a70565b61119f8161259d565b323314611cad5760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610a70565b6001600e5460ff166005811115611cc657611cc6613503565b1015611d145760405162461bcd60e51b815260206004820152601f60248201527f57686974656c6973742073616c65206973206e6f7420616374697661746564006044820152606401610a70565b611d2033848484612995565b611d6c5760405162461bcd60e51b815260206004820152601260248201527f4e6f74204f472077686974656c697374656400000000000000000000000000006044820152606401610a70565b336000908152601260205260409020548390611d899082906136a0565b1115611dfd5760405162461bcd60e51b815260206004820152602860248201527f596f752072656163686564206d6178696d756d206f6e204f472057686974656c60448201527f6973742053616c650000000000000000000000000000000000000000000000006064820152608401610a70565b6006546005546111e49185910360001901611e1891906136a0565b1115611e665760405162461bcd60e51b815260206004820152601c60248201527f4d617820667265656d696e7420737570706c79206578636565646564000000006044820152606401610a70565b3360009081526012602052604081208054859290611e859084906136a0565b90915550610ee290503384612020565b611e9d611fc6565b806005811115611eaf57611eaf613503565b600e805460ff19166001836005811115611ecb57611ecb613503565b021790555050565b60005b8251811015610ee2576000838281518110611ef357611ef36136f3565b602002602001015190508215611f1157611f0c81611814565b611f1a565b611f1a816111a2565b5080611f2581613709565b915050611ed6565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b031983161480611f9057507f80ac58cd000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b806109da5750506001600160e01b0319167f5b5e139f000000000000000000000000000000000000000000000000000000001490565b6000546001600160a01b03163314610e795760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a70565b610aec828260405180602001604052806000815250612a24565b60008160011115801561204e575060055482105b80156109da575050600090815260096020526040902054600160e01b161590565b600081815260026020526040902054156120cb5760405162461bcd60e51b815260206004820152600f60248201527f546f6b656e206973206c6f636b656400000000000000000000000000000000006044820152606401610a70565b610ee2838383612a8a565b6040516bffffffffffffffffffffffff19606085901b166020820152600090819060340160405160208183030381529060405280519060200120905061215281601054868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c6792505050565b95945050505050565b3360009081526001602052604090205460ff166121ba5760405162461bcd60e51b815260206004820152601160248201527f43616e6e6f7420757064617465206d61700000000000000000000000000000006044820152606401610a70565b6000818152600460209081526040808320338452909152902054156122215760405162461bcd60e51b815260206004820152601b60248201527f494420616c7265616479206c6f636b65642062792063616c6c657200000000006044820152606401610a70565b60008181526002602052604081205461223b9060016136a0565b6000838152600360209081526040808320848452825280832080546001600160a01b031916339081179091558684526004835281842090845282528083208490558583526002909152812080549293509061229583613709565b9091555050604051339083907f9ecfd70e9ff36df72989324a49559383d39f9290d700b10cf5ac10dcb68d264390600090a35050565b6040516bffffffffffffffffffffffff19606085901b166020820152600090819060340160405160208183030381529060405280519060200120905061215281601154868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c6792505050565b3360009081526001602052604090205460ff166123a65760405162461bcd60e51b815260206004820152601160248201527f43616e6e6f7420757064617465206d61700000000000000000000000000000006044820152606401610a70565b60008181526004602090815260408083203384529091529020548061240d5760405162461bcd60e51b815260206004820152601760248201527f4944206e6f74206c6f636b65642062792063616c6c65720000000000000000006044820152606401610a70565b6000828152600260205260409020548181146124835760008381526003602090815260408083208484528252808320805486855282852080546001600160a01b03199081166001600160a01b039093169283179091558254169091558684526004835281842090845290915290208290556124ab565b6000838152600360209081526040808320858452909152902080546001600160a01b03191690555b60008381526004602090815260408083203384528252808320839055858352600290915281208054916124dd8361380a565b9091555050604051339084907f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3790600090a3505050565b6000818060011161256b5760055481101561256b57600081815260096020526040902054600160e01b8116612569575b80612562575060001901600081815260096020526040902054612544565b9392505050565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461263a576040519150601f19603f3d011682016040523d82523d6000602084013e61263f565b606091505b5050905080610ee25760405162461bcd60e51b815260206004820152601260248201527f636f756c64206e6f7420776974686472617700000000000000000000000000006044820152606401610a70565b6001600160a01b03811660009081526001602052604090205460ff16156126f95760405162461bcd60e51b815260206004820152601160248201527f43616e6e6f7420757064617465206d61700000000000000000000000000000006044820152606401610a70565b60008281526004602090815260408083206001600160a01b0385168452909152902054806127695760405162461bcd60e51b815260206004820152600d60248201527f4944206e6f74206c6f636b6564000000000000000000000000000000000000006044820152606401610a70565b6000838152600260205260409020548181146127df5760008481526003602090815260408083208484528252808320805486855282852080546001600160a01b03199081166001600160a01b03909316928317909155825416909155878452600483528184209084529091529020829055612807565b6000848152600360209081526040808320858452909152902080546001600160a01b03191690555b60008481526004602090815260408083206001600160a01b03871684528252808320839055868352600290915281208054916128428361380a565b90915550506040516001600160a01b0384169085907f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3790600090a350505050565b600082815260026020526040902054156128df5760405162461bcd60e51b815260206004820152600f60248201527f546f6b656e206973206c6f636b656400000000000000000000000000000000006044820152606401610a70565b611b1a84848484612c74565b606060006128f883612cb8565b600101905060008167ffffffffffffffff811115612918576129186132f9565b6040519080825280601f01601f191660200182016040528015612942576020820181803683370190505b5090508181016020015b600019017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85049450846129885761298d565b61294c565b509392505050565b6040516bffffffffffffffffffffffff19606086901b166020820152603481018490526000908190605401604051602081830303815290604052805190602001209050612a1881600f54868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c6792505050565b9150505b949350505050565b612a2e8383612d9a565b6001600160a01b0383163b15610ee2576005548281035b612a586000868380600101945086612ec4565b612a75576040516368d2bf6b60e11b815260040160405180910390fd5b818110612a45578160055414611aab57600080fd5b6000612a9582612514565b9050836001600160a01b0316816001600160a01b031614612ae2576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600b602052604090208054338082146001600160a01b03881690911417612b4857612b1286336108ce565b612b48576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038516612b88576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8015612b9357600082555b6001600160a01b038681166000908152600a60205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260096020526040902055600160e11b8316612c1e5760018401600081815260096020526040902054612c1c576005548114612c1c5760008181526009602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b6000612a1c828486612fa9565b612c7f848484610e7b565b6001600160a01b0383163b15611b1a57612c9b84848484612ec4565b611b1a576040516368d2bf6b60e11b815260040160405180910390fd5b6000807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612d01577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310612d2d576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310612d4b57662386f26fc10000830492506010015b6305f5e1008310612d63576305f5e100830492506008015b6127108310612d7757612710830492506004015b60648310612d89576064830492506002015b600a83106109da5760010192915050565b60055481612dd4576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383166000818152600a602090815260408083208054680100000000000000018802019055848352600990915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b818114612e8357808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101612e4b565b5081612ebb576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055550505050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290612ef9903390899088908890600401613821565b6020604051808303816000875af1925050508015612f34575060408051601f3d908101601f19168201909252612f319181019061385d565b60015b612f8f573d808015612f62576040519150601f19603f3d011682016040523d82523d6000602084013e612f67565b606091505b508051612f87576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612a1c565b600082612fb68584612fbf565b14949350505050565b600081815b845181101561298d57612ff082868381518110612fe357612fe36136f3565b6020026020010151613004565b915080612ffc81613709565b915050612fc4565b6000818310613020576000828152602084905260409020612562565b5060009182526020526040902090565b82805461303c906136b8565b90600052602060002090601f01602090048101928261305e57600085556130a4565b82601f1061307757805160ff19168380011785556130a4565b828001600101855582156130a4579182015b828111156130a4578251825591602001919060010190613089565b506130b09291506130b4565b5090565b5b808211156130b057600081556001016130b5565b6001600160e01b03198116811461119f57600080fd5b6000602082840312156130f157600080fd5b8135612562816130c9565b80356001600160a01b038116811461311357600080fd5b919050565b6000806040838503121561312b57600080fd5b613134836130fc565b946020939093013593505050565b60005b8381101561315d578181015183820152602001613145565b83811115611b1a5750506000910152565b60008151808452613186816020860160208601613142565b601f01601f19169290920160200192915050565b602081526000612562602083018461316e565b6000602082840312156131bf57600080fd5b5035919050565b600080604083850312156131d957600080fd5b823591506131e9602084016130fc565b90509250929050565b60008060006060848603121561320757600080fd5b613210846130fc565b925061321e602085016130fc565b9150604084013590509250925092565b60008083601f84011261324057600080fd5b50813567ffffffffffffffff81111561325857600080fd5b6020830191508360208260051b850101111561327357600080fd5b9250929050565b6000806020838503121561328d57600080fd5b823567ffffffffffffffff8111156132a457600080fd5b6132b08582860161322e565b90969095509350505050565b600080604083850312156132cf57600080fd5b50508035926020909101359150565b6000602082840312156132f057600080fd5b612562826130fc565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613338576133386132f9565b604052919050565b600067ffffffffffffffff83111561335a5761335a6132f9565b61336d601f8401601f191660200161330f565b905082815283838301111561338157600080fd5b828260208301376000602084830101529392505050565b6000602082840312156133aa57600080fd5b813567ffffffffffffffff8111156133c157600080fd5b8201601f810184136133d257600080fd5b612a1c84823560208401613340565b8035801515811461311357600080fd5b6000806040838503121561340457600080fd5b61340d836130fc565b91506131e9602084016133e1565b6000806000806040858703121561343157600080fd5b843567ffffffffffffffff8082111561344957600080fd5b6134558883890161322e565b9096509450602087013591508082111561346e57600080fd5b5061347b8782880161322e565b95989497509550505050565b6000806000806080858703121561349d57600080fd5b6134a6856130fc565b93506134b4602086016130fc565b925060408501359150606085013567ffffffffffffffff8111156134d757600080fd5b8501601f810187136134e857600080fd5b6134f787823560208401613340565b91505092959194509250565b634e487b7160e01b600052602160045260246000fd5b602081016006831061353b57634e487b7160e01b600052602160045260246000fd5b91905290565b60006020828403121561355357600080fd5b612562826133e1565b6000806040838503121561356f57600080fd5b613578836130fc565b91506131e9602084016130fc565b60008060006040848603121561359b57600080fd5b83359250602084013567ffffffffffffffff8111156135b957600080fd5b6135c58682870161322e565b9497909650939450505050565b600080604083850312156135e557600080fd5b823567ffffffffffffffff808211156135fd57600080fd5b818501915085601f83011261361157600080fd5b8135602082821115613625576136256132f9565b8160051b925061363681840161330f565b828152928401810192818101908985111561365057600080fd5b948201945b8486101561366e57853582529482019490820190613655565b965061367d90508782016133e1565b9450505050509250929050565b634e487b7160e01b600052601160045260246000fd5b600082198211156136b3576136b361368a565b500190565b600181811c908216806136cc57607f821691505b602082108114156136ed57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600060001982141561371d5761371d61368a565b5060010190565b60008151613736818560208601613142565b9290920192915050565b600080845481600182811c91508083168061375c57607f831692505b602080841082141561377c57634e487b7160e01b86526022600452602486fd5b81801561379057600181146137a1576137ce565b60ff198616895284890196506137ce565b60008b81526020902060005b868110156137c65781548b8201529085019083016137ad565b505084890196505b5050505050506121526137e18286613724565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000815260050190565b6000816138195761381961368a565b506000190190565b60006001600160a01b03808716835280861660208401525083604083015260806060830152613853608083018461316e565b9695505050505050565b60006020828403121561386f57600080fd5b8151612562816130c956fea264697066735822122005f92bfdbff70a84131e076ea8893046ed01df5e998b0913b5383f87efd3a90964736f6c634300080c0033

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

d8a5ef9b558a496a4ca83e444305247c81d0f5d6fd3e1a956b172509239e31f3d88df37125fbaf36fb8f1c4751d1dd015f7b67b90a71f1530fa754e330aa23deba8f4b48ecc9e8c5d70630df4500684c6d3f59a51316ab198f212a165bc96f2700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000036697066733a2f2f516d614651765432596b38696d5764794255546a646f55744254467274785042745844784775764c554e575553382f00000000000000000000

-----Decoded View---------------
Arg [0] : _ogMerkleRoot (bytes32): 0xd8a5ef9b558a496a4ca83e444305247c81d0f5d6fd3e1a956b172509239e31f3
Arg [1] : _premiumMerkleRoot (bytes32): 0xd88df37125fbaf36fb8f1c4751d1dd015f7b67b90a71f1530fa754e330aa23de
Arg [2] : _merkleRoot (bytes32): 0xba8f4b48ecc9e8c5d70630df4500684c6d3f59a51316ab198f212a165bc96f27
Arg [3] : _baseURI (string): ipfs://QmaFQvT2Yk8imWdyBUTjdoUtBTFrtxPBtXDxGuvLUNWUS8/

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : d8a5ef9b558a496a4ca83e444305247c81d0f5d6fd3e1a956b172509239e31f3
Arg [1] : d88df37125fbaf36fb8f1c4751d1dd015f7b67b90a71f1530fa754e330aa23de
Arg [2] : ba8f4b48ecc9e8c5d70630df4500684c6d3f59a51316ab198f212a165bc96f27
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000036
Arg [5] : 697066733a2f2f516d614651765432596b38696d5764794255546a646f557442
Arg [6] : 54467274785042745844784775764c554e575553382f00000000000000000000


Deployed Bytecode Sourcemap

218:8531:3:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1099:271:2;;;;;;;;;;-1:-1:-1;1099:271:2;;;;;:::i;:::-;;:::i;:::-;;;611:14:11;;604:22;586:41;;574:2;559:18;1099:271:2;;;;;;;;4038:273:3;;;;;;;;;;-1:-1:-1;4038:273:3;;;;;:::i;:::-;;:::i;:::-;;10199:98:1;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;16918:258::-;;;;;;;;;;-1:-1:-1;16918:258:1;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2220:55:11;;;2202:74;;2190:2;2175:18;16918:258:1;2056:226:11;426:92:6;;;;;;;;;;-1:-1:-1;426:92:6;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;2692:25:11;;;2680:2;2665:18;426:92:6;2546:177:11;16334:434:1;;;;;;:::i;:::-;;:::i;587:27:3:-;;;;;;;;;;;;;;;;3576:456;;;;;;;;;;;;;:::i;5894:317:1:-;;;;;;;;;;-1:-1:-1;6164:12:1;;6148:13;;:28;-1:-1:-1;;6148:46:1;5894:317;;6290:299:3;;;;;;:::i;:::-;;:::i;2257:703::-;;;;;;;;;;-1:-1:-1;2257:703:3;;;;;:::i;:::-;;:::i;4848:108::-;;;;;;;;;;-1:-1:-1;4848:108:3;;;;;:::i;:::-;;:::i;1925:131:2:-;;;;;;;;;;-1:-1:-1;1925:131:2;;;;;:::i;:::-;;:::i;349:71:6:-;;;;;;;;;;-1:-1:-1;349:71:6;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;349:71:6;;;7396:429:3;;;;;;;;;;-1:-1:-1;7396:429:3;;;;;:::i;:::-;;:::i;658:25::-;;;;;;;;;;;;;;;;777:53;;;;;;;;;;-1:-1:-1;777:53:3;;;;;:::i;:::-;;;;;;;;;;;;;;2966:604;;;;;;;;;;-1:-1:-1;2966:604:3;;;;;:::i;:::-;;:::i;2062:135:2:-;;;;;;;;;;-1:-1:-1;2062:135:2;;;;;:::i;:::-;;:::i;23598:187:1:-;;;;;;:::i;:::-;;:::i;11639:194::-;;;;;;;;;;-1:-1:-1;11639:194:1;;;;;:::i;:::-;;:::i;290:53:6:-;;;;;;;;;;-1:-1:-1;290:53:6;;;;;:::i;:::-;;;;;;;;;;;;;;430:21:3;;;;;;;;;;;;;:::i;7045:274:1:-;;;;;;;;;;-1:-1:-1;7045:274:1;;;;;:::i;:::-;;:::i;1846:101:9:-;;;;;;;;;;;;;:::i;736:112:6:-;;;;;;;;;;-1:-1:-1;736:112:6;;;;;:::i;:::-;799:4;822:14;;;:9;:14;;;;;;:19;;736:112;5702:104:3;;;;;;;;;;-1:-1:-1;5702:104:3;;;;;:::i;:::-;;:::i;8351:211::-;;;;;;;;;;;;;:::i;690:53::-;;;;;;;;;;-1:-1:-1;690:53:3;;;;;:::i;:::-;;;;;;;;;;;;;;1216:85:9;;;;;;;;;;-1:-1:-1;1262:7:9;1288:6;-1:-1:-1;;;;;1288:6:9;1216:85;;2203:161:2;;;;;;;;;;-1:-1:-1;2203:161:2;;;;;:::i;:::-;;:::i;10368:102:1:-;;;;;;;;;;;;;:::i;750:20:3:-;;;;;;;;;;-1:-1:-1;750:20:3;;;;;;;;4416:98;;;;;;;;;;-1:-1:-1;4416:98:3;;;;;:::i;:::-;;:::i;17503:259:1:-;;;;;;;;;;-1:-1:-1;17503:259:1;;;;;:::i;:::-;;:::i;6943:447:3:-;;;;;;;;;;-1:-1:-1;6943:447:3;;;;;:::i;:::-;;:::i;854:316:6:-;;;;;;;;;;-1:-1:-1;854:316:6;;;;;:::i;:::-;;:::i;227:57::-;;;;;;;;;;-1:-1:-1;227:57:6;;;;;:::i;:::-;;;;;;;;;;;;;;;;6595:342:3;;;;;;:::i;:::-;;:::i;4520:292::-;;;;;;;;;;-1:-1:-1;4520:292:3;;;;;:::i;:::-;;:::i;458:23::-;;;;;;;;;;-1:-1:-1;458:23:3;;;;;;;;;;;;;;;:::i;620:32::-;;;;;;;;;;;;;;;;8171:77;;;;;;;;;;-1:-1:-1;8171:77:3;;;;;:::i;:::-;;:::i;17912:206:1:-;;;;;;;;;;-1:-1:-1;17912:206:1;;;;;:::i;:::-;-1:-1:-1;;;;;18076:25:1;;;18049:4;18076:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;17912:206;5285:118:3;;;;;;;;;;-1:-1:-1;5285:118:3;;;;;:::i;:::-;;:::i;2096:232:9:-;;;;;;;;;;-1:-1:-1;2096:232:9;;;;;:::i;:::-;;:::i;1518:733:3:-;;;;;;;;;;-1:-1:-1;1518:733:3;;;;;:::i;:::-;;:::i;4317:93::-;;;;;;;;;;-1:-1:-1;4317:93:3;;;;;:::i;:::-;;:::i;7831:334::-;;;;;;;;;;-1:-1:-1;7831:334:3;;;;;:::i;:::-;;:::i;1099:271:2:-;1234:4;-1:-1:-1;;;;;;1273:37:2;;1289:21;1273:37;;:90;;;1326:37;1350:12;1326:23;:37::i;:::-;1254:109;1099:271;-1:-1:-1;;1099:271:2:o;4038:273:3:-;1109:13:9;:11;:13::i;:::-;4139:11:3::1;4125;::::0;::::1;;:25;::::0;::::1;;;;;;:::i;:::-;;4117:71;;;::::0;-1:-1:-1;;;4117:71:3;;10665:2:11;4117:71:3::1;::::0;::::1;10647:21:11::0;10704:2;10684:18;;;10677:30;10743:34;10723:18;;;10716:62;10814:3;10794:18;;;10787:31;10835:19;;4117:71:3::1;;;;;;;;;6164:12:1::0;;6148:13;;526:4:3::1;::::0;4222:9;;6148:28:1;-1:-1:-1;;6148:46:1;4206:25:3::1;;;;:::i;:::-;:39;;4198:71;;;::::0;-1:-1:-1;;;4198:71:3;;11389:2:11;4198:71:3::1;::::0;::::1;11371:21:11::0;11428:2;11408:18;;;11401:30;11467:21;11447:18;;;11440:49;11506:18;;4198:71:3::1;11187:343:11::0;4198:71:3::1;4279:25;4289:3;4294:9;4279;:25::i;:::-;4038:273:::0;;:::o;10199:98:1:-;10253:13;10285:5;10278:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10199:98;:::o;16918:258::-;17034:7;17062:16;17070:7;17062;:16::i;:::-;17057:64;;17087:34;;;;;;;;;;;;;;17057:64;-1:-1:-1;17139:24:1;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;17139:30:1;;16918:258::o;16334:434::-;16458:13;16474:16;16482:7;16474;:16::i;:::-;16458:32;-1:-1:-1;41055:10:1;-1:-1:-1;;;;;16505:28:1;;;16501:172;;16552:44;16569:5;41055:10;17912:206;:::i;16552:44::-;16547:126;;16623:35;;;;;;;;;;;;;;16547:126;16683:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;;;;;16683:35:1;-1:-1:-1;;;;;16683:35:1;;;;;;;;;16733:28;;16683:24;;16733:28;;;;;;;16448:320;16334:434;;:::o;3576:456:3:-;1436:9;1449:10;1436:23;1428:66;;;;-1:-1:-1;;;1428:66:3;;12179:2:11;1428:66:3;;;12161:21:11;12218:2;12198:18;;;12191:30;12257:32;12237:18;;;12230:60;12307:18;;1428:66:3;11977:354:11;1428:66:3;3647:11:::1;3632;::::0;::::1;;:26;::::0;::::1;;;;;;:::i;:::-;;;3624:67;;;::::0;-1:-1:-1;;;3624:67:3;;12538:2:11;3624:67:3::1;::::0;::::1;12520:21:11::0;12577:2;12557:18;;;12550:30;12616;12596:18;;;12589:58;12664:18;;3624:67:3::1;12336:352:11::0;3624:67:3::1;3741:10;3722:30;::::0;;;:18:::1;:30;::::0;;;;;3760:1:::1;::::0;3722:34:::1;::::0;3760:1;3722:34:::1;:::i;:::-;:39;;3701:127;;;::::0;-1:-1:-1;;;3701:127:3;;12895:2:11;3701:127:3::1;::::0;::::1;12877:21:11::0;12934:2;12914:18;;;12907:30;12973:34;12953:18;;;12946:62;13044:11;13024:18;;;13017:39;13073:19;;3701:127:3::1;12693:405:11::0;3701:127:3::1;6164:12:1::0;;6148:13;;576:4:3::1;::::0;6148:28:1;;-1:-1:-1;;6148:46:1;3859:17:3::1;::::0;3875:1:::1;3859:17;:::i;:::-;:33;;3838:108;;;::::0;-1:-1:-1;;;3838:108:3;;13305:2:11;3838:108:3::1;::::0;::::1;13287:21:11::0;13344:2;13324:18;;;13317:30;13383;13363:18;;;13356:58;13431:18;;3838:108:3::1;13103:352:11::0;3838:108:3::1;3975:10;3956:30;::::0;;;:18:::1;:30;::::0;;;;:35;;3990:1:::1;::::0;3956:30;:35:::1;::::0;3990:1;;3956:35:::1;:::i;:::-;::::0;;;-1:-1:-1;4001:24:3::1;::::0;-1:-1:-1;4011:10:3::1;4023:1;4001:9;:24::i;:::-;3576:456::o:0;6290:299::-;6449:27;;;;:18;:27;;;;;;:32;6428:107;;;;-1:-1:-1;;;6428:107:3;;13662:2:11;6428:107:3;;;13644:21:11;13701:2;13681:18;;;13674:30;13740;13720:18;;;13713:58;13788:18;;6428:107:3;13460:352:11;6428:107:3;6545:37;6564:4;6570:2;6574:7;6545:18;:37::i;:::-;6290:299;;;:::o;2257:703::-;1436:9;1449:10;1436:23;1428:66;;;;-1:-1:-1;;;1428:66:3;;12179:2:11;1428:66:3;;;12161:21:11;12218:2;12198:18;;;12191:30;12257:32;12237:18;;;12230:60;12307:18;;1428:66:3;11977:354:11;1428:66:3;2402:21:::1;2387:11;::::0;::::1;;:36;::::0;::::1;;;;;;:::i;:::-;;;2366:122;;;::::0;-1:-1:-1;;;2366:122:3;;14019:2:11;2366:122:3::1;::::0;::::1;14001:21:11::0;14058:2;14038:18;;;14031:30;14097:34;14077:18;;;14070:62;14168:9;14148:18;;;14141:37;14195:19;;2366:122:3::1;13817:403:11::0;2366:122:3::1;2519:40;2540:10;2552:6;;2519:20;:40::i;:::-;2498:110;;;::::0;-1:-1:-1;;;2498:110:3;;14427:2:11;2498:110:3::1;::::0;::::1;14409:21:11::0;14466:2;14446:18;;;14439:30;14505:25;14485:18;;;14478:53;14548:18;;2498:110:3::1;14225:347:11::0;2498:110:3::1;2658:10;2639:30;::::0;;;:18:::1;:30;::::0;;;;;2677:1:::1;::::0;2639:34:::1;::::0;2677:1;2639:34:::1;:::i;:::-;:39;;2618:138;;;::::0;-1:-1:-1;;;2618:138:3;;14779:2:11;2618:138:3::1;::::0;::::1;14761:21:11::0;14818:2;14798:18;;;14791:30;14857:34;14837:18;;;14830:62;14928:22;14908:18;;;14901:50;14968:19;;2618:138:3::1;14577:416:11::0;2618:138:3::1;6164:12:1::0;;6148:13;;576:4:3::1;::::0;6148:28:1;;-1:-1:-1;;6148:46:1;2787:17:3::1;::::0;2803:1:::1;2787:17;:::i;:::-;:33;;2766:108;;;::::0;-1:-1:-1;;;2766:108:3;;13305:2:11;2766:108:3::1;::::0;::::1;13287:21:11::0;13344:2;13324:18;;;13317:30;13383;13363:18;;;13356:58;13431:18;;2766:108:3::1;13103:352:11::0;2766:108:3::1;2903:10;2884:30;::::0;;;:18:::1;:30;::::0;;;;:35;;2918:1:::1;::::0;2884:30;:35:::1;::::0;2918:1;;2884:35:::1;:::i;:::-;::::0;;;-1:-1:-1;2929:24:3::1;::::0;-1:-1:-1;2939:10:3::1;2951:1;2929:9;:24::i;4848:108::-:0;1109:13:9;:11;:13::i;:::-;4923:12:3::1;:26:::0;4848:108::o;1925:131:2:-;1998:12;2006:3;1998:7;:12::i;:::-;1990:37;;;;-1:-1:-1;;;1990:37:2;;15200:2:11;1990:37:2;;;15182:21:11;15239:2;15219:18;;;15212:30;-1:-1:-1;;;15258:18:11;;;15251:42;15310:18;;1990:37:2;14998:336:11;1990:37:2;2037:12;2045:3;2037:7;:12::i;:::-;1925:131;:::o;7396:429:3:-;7482:16;7490:7;7482;:16::i;:::-;-1:-1:-1;;;;;7468:30:3;:10;-1:-1:-1;;;;;7468:30:3;;:55;;;-1:-1:-1;1262:7:9;1288:6;-1:-1:-1;;;;;1288:6:9;7502:10:3;:21;7468:55;7447:149;;;;-1:-1:-1;;;7447:149:3;;15541:2:11;7447:149:3;;;15523:21:11;15580:2;15560:18;;;15553:30;15619:34;15599:18;;;15592:62;15690:17;15670:18;;;15663:45;15725:19;;7447:149:3;15339:411:11;7447:149:3;7644:1;7614:27;;;:18;:27;;;;;;7606:55;;;;-1:-1:-1;;;7606:55:3;;15957:2:11;7606:55:3;;;15939:21:11;15996:2;15976:18;;;15969:30;16035:13;16015:18;;;16008:41;16066:18;;7606:55:3;15755:335:11;7606:55:3;7671:11;7685:27;;;:18;:27;;;;;;;;;;7722:31;;;7768:50;;16326:25:11;;;7785:10:3;16367:18:11;;;16360:83;;;;7797:15:3;16459:18:11;;;16452:34;16517:2;16502:18;;16495:34;;;7768:50:3;;;;;;16313:3:11;7768:50:3;;;7437:388;7396:429;:::o;2966:604::-;1436:9;1449:10;1436:23;1428:66;;;;-1:-1:-1;;;1428:66:3;;12179:2:11;1428:66:3;;;12161:21:11;12218:2;12198:18;;;12191:30;12257:32;12237:18;;;12230:60;12307:18;;1428:66:3;11977:354:11;1428:66:3;3084:14:::1;3069:11;::::0;::::1;;:29;::::0;::::1;;;;;;:::i;:::-;;;3048:107;;;::::0;-1:-1:-1;;;3048:107:3;;16742:2:11;3048:107:3::1;::::0;::::1;16724:21:11::0;16781:2;16761:18;;;16754:30;16820:33;16800:18;;;16793:61;16871:18;;3048:107:3::1;16540:355:11::0;3048:107:3::1;3173:33;3187:10;3199:6;;3173:13;:33::i;:::-;3165:61;;;::::0;-1:-1:-1;;;3165:61:3;;17102:2:11;3165:61:3::1;::::0;::::1;17084:21:11::0;17141:2;17121:18;;;17114:30;17180:17;17160:18;;;17153:45;17215:18;;3165:61:3::1;16900:339:11::0;3165:61:3::1;3276:10;3257:30;::::0;;;:18:::1;:30;::::0;;;;;3295:1:::1;::::0;3257:34:::1;::::0;3295:1;3257:34:::1;:::i;:::-;:39;;3236:130;;;::::0;-1:-1:-1;;;3236:130:3;;17446:2:11;3236:130:3::1;::::0;::::1;17428:21:11::0;17485:2;17465:18;;;17458:30;17524:34;17504:18;;;17497:62;17595:14;17575:18;;;17568:42;17627:19;;3236:130:3::1;17244:408:11::0;3236:130:3::1;6164:12:1::0;;6148:13;;576:4:3::1;::::0;6148:28:1;;-1:-1:-1;;6148:46:1;3397:17:3::1;::::0;3413:1:::1;3397:17;:::i;:::-;:33;;3376:108;;;::::0;-1:-1:-1;;;3376:108:3;;13305:2:11;3376:108:3::1;::::0;::::1;13287:21:11::0;13344:2;13324:18;;;13317:30;13383;13363:18;;;13356:58;13431:18;;3376:108:3::1;13103:352:11::0;3376:108:3::1;3513:10;3494:30;::::0;;;:18:::1;:30;::::0;;;;:35;;3528:1:::1;::::0;3494:30;:35:::1;::::0;3528:1;;3494:35:::1;:::i;:::-;::::0;;;-1:-1:-1;3539:24:3::1;::::0;-1:-1:-1;3549:10:3::1;3561:1;3539:9;:24::i;2062:135:2:-:0;2137:12;2145:3;2137:7;:12::i;:::-;2129:37;;;;-1:-1:-1;;;2129:37:2;;15200:2:11;2129:37:2;;;15182:21:11;15239:2;15219:18;;;15212:30;-1:-1:-1;;;15258:18:11;;;15251:42;15310:18;;2129:37:2;14998:336:11;2129:37:2;2176:14;2186:3;2176:9;:14::i;23598:187:1:-;23739:39;23756:4;23762:2;23766:7;23739:39;;;;;;;;;;;;:16;:39::i;11639:194::-;11751:7;11797:27;11816:7;11797:18;:27::i;430:21:3:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7045:274:1:-;7157:7;-1:-1:-1;;;;;7184:19:1;;7180:60;;7212:28;;;;;;;;;;;;;;7180:60;-1:-1:-1;;;;;;7257:25:1;;;;;:18;:25;;;;;;1360:13;7257:55;;7045:274::o;1846:101:9:-;1109:13;:11;:13::i;:::-;1910:30:::1;1937:1;1910:18;:30::i;5702:104:3:-:0;1109:13:9;:11;:13::i;:::-;5775:10:3::1;:24:::0;5702:104::o;8351:211::-;1109:13:9;:11;:13::i;:::-;8421:21:3::1;8460:11:::0;8452:52:::1;;;::::0;-1:-1:-1;;;8452:52:3;;17859:2:11;8452:52:3::1;::::0;::::1;17841:21:11::0;17898:2;17878:18;;;17871:30;17937;17917:18;;;17910:58;17985:18;;8452:52:3::1;17657:352:11::0;8452:52:3::1;8514:41;8524:7;1262::9::0;1288:6;-1:-1:-1;;;;;1288:6:9;;1216:85;8524:7:3::1;8533:21;8514:9;:41::i;2203:161:2:-:0;2295:12;2303:3;2295:7;:12::i;:::-;2287:37;;;;-1:-1:-1;;;2287:37:2;;15200:2:11;2287:37:2;;;15182:21:11;15239:2;15219:18;;;15212:30;-1:-1:-1;;;15258:18:11;;;15251:42;15310:18;;2287:37:2;14998:336:11;2287:37:2;2334:23;2342:3;2347:9;2334:7;:23::i;10368:102:1:-;10424:13;10456:7;10449:14;;;;;:::i;4416:98:3:-;1109:13:9;:11;:13::i;:::-;4489:18:3;;::::1;::::0;:7:::1;::::0;:18:::1;::::0;::::1;::::0;::::1;:::i;17503:259:1:-:0;41055:10;17625:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;17625:49:1;;;;;;;;;;;;:60;;-1:-1:-1;;17625:60:1;;;;;;;;;;17700:55;;586:41:11;;;17625:49:1;;41055:10;17700:55;;559:18:11;17700:55:1;;;;;;;17503:259;;:::o;6943:447:3:-;7000:8;;;;6992:37;;;;-1:-1:-1;;;6992:37:3;;18216:2:11;6992:37:3;;;18198:21:11;18255:2;18235:18;;;18228:30;18294:18;18274;;;18267:46;18330:18;;6992:37:3;18014:340:11;6992:37:3;7074:16;7082:7;7074;:16::i;:::-;-1:-1:-1;;;;;7060:30:3;:10;-1:-1:-1;;;;;7060:30:3;;:55;;;-1:-1:-1;1262:7:9;1288:6;-1:-1:-1;;;;;1288:6:9;7094:10:3;:21;7060:55;7039:149;;;;-1:-1:-1;;;7039:149:3;;15541:2:11;7039:149:3;;;15523:21:11;15580:2;15560:18;;;15553:30;15619:34;15599:18;;;15592:62;15690:17;15670:18;;;15663:45;15725:19;;7039:149:3;15339:411:11;7039:149:3;7206:27;;;;:18;:27;;;;;;:32;7198:60;;;;-1:-1:-1;;;7198:60:3;;18561:2:11;7198:60:3;;;18543:21:11;18600:2;18580:18;;;18573:30;18639:17;18619:18;;;18612:45;18674:18;;7198:60:3;18359:339:11;7198:60:3;7268:27;;;;:18;:27;;;;;;;;;7298:15;7268:45;;;;7328:55;;18905:25:11;;;7343:10:3;18946:18:11;;;18939:83;;;;19038:18;;;19031:34;7328:55:3;;;;;;;18893:2:11;7328:55:3;;;6943:447;:::o;854:316:6:-;1109:13:9;:11;:13::i;:::-;1002:35:6;;::::1;994:55;;;::::0;-1:-1:-1;;;994:55:6;;19278:2:11;994:55:6::1;::::0;::::1;19260:21:11::0;19317:1;19297:18;;;19290:29;19355:9;19335:18;;;19328:37;19382:18;;994:55:6::1;19076:330:11::0;994:55:6::1;1064:9;1059:104;1079:21:::0;;::::1;1059:104;;;1153:7;;1161:1;1153:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;1119:16;:31;1136:10;;1147:1;1136:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;1119:31:6::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;1119:31:6;:44;;-1:-1:-1;;1119:44:6::1;::::0;::::1;;::::0;;;::::1;::::0;;1102:3;::::1;::::0;::::1;:::i;:::-;;;;1059:104;;;;854:316:::0;;;;:::o;6595:342:3:-;6786:27;;;;:18;:27;;;;;;:32;6765:107;;;;-1:-1:-1;;;6765:107:3;;13662:2:11;6765:107:3;;;13644:21:11;13701:2;13681:18;;;13674:30;13740;13720:18;;;13713:58;13788:18;;6765:107:3;13460:352:11;6765:107:3;6882:48;6905:4;6911:2;6915:7;6924:5;6882:22;:48::i;:::-;6595:342;;;;:::o;4520:292::-;4634:13;4671:17;4679:8;4671:7;:17::i;:::-;4663:61;;;;-1:-1:-1;;;4663:61:3;;19942:2:11;4663:61:3;;;19924:21:11;19981:2;19961:18;;;19954:30;20020:33;20000:18;;;19993:61;20071:18;;4663:61:3;19740:355:11;4663:61:3;4766:7;4775:19;:8;:17;:19::i;:::-;4749:55;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4735:70;;4520:292;;;:::o;8171:77::-;1109:13:9;:11;:13::i;:::-;8229:8:3::1;:12:::0;;-1:-1:-1;;8229:12:3::1;::::0;::::1;;::::0;;;::::1;::::0;;8171:77::o;5285:118::-;1109:13:9;:11;:13::i;:::-;5365:17:3::1;:31:::0;5285:118::o;2096:232:9:-;1109:13;:11;:13::i;:::-;-1:-1:-1;;;;;2197:22:9;::::1;2176:107;;;::::0;-1:-1:-1;;;2176:107:9;;22099:2:11;2176:107:9::1;::::0;::::1;22081:21:11::0;22138:2;22118:18;;;22111:30;22177:34;22157:18;;;22150:62;22248:8;22228:18;;;22221:36;22274:19;;2176:107:9::1;21897:402:11::0;2176:107:9::1;2293:28;2312:8;2293:18;:28::i;1518:733:3:-:0;1436:9;1449:10;1436:23;1428:66;;;;-1:-1:-1;;;1428:66:3;;12179:2:11;1428:66:3;;;12161:21:11;12218:2;12198:18;;;12191:30;12257:32;12237:18;;;12230:60;12307:18;;1428:66:3;11977:354:11;1428:66:3;1677:16:::1;1662:11;::::0;::::1;;:31;::::0;::::1;;;;;;:::i;:::-;;;1641:109;;;::::0;-1:-1:-1;;;1641:109:3;;16742:2:11;1641:109:3::1;::::0;::::1;16724:21:11::0;16781:2;16761:18;;;16754:30;16820:33;16800:18;;;16793:61;16871:18;;1641:109:3::1;16540:355:11::0;1641:109:3::1;1781:46;1797:10;1809:9;1820:6;;1781:15;:46::i;:::-;1760:111;;;::::0;-1:-1:-1;;;1760:111:3;;22506:2:11;1760:111:3::1;::::0;::::1;22488:21:11::0;22545:2;22525:18;;;22518:30;22584:20;22564:18;;;22557:48;22622:18;;1760:111:3::1;22304:342:11::0;1760:111:3::1;1921:10;1902:30;::::0;;;:18:::1;:30;::::0;;;;;1948:9;;1902:42:::1;::::0;1948:9;;1902:42:::1;:::i;:::-;:55;;1881:142;;;::::0;-1:-1:-1;;;1881:142:3;;22853:2:11;1881:142:3::1;::::0;::::1;22835:21:11::0;22892:2;22872:18;;;22865:30;22931:34;22911:18;;;22904:62;23002:10;22982:18;;;22975:38;23030:19;;1881:142:3::1;22651:404:11::0;1881:142:3::1;6164:12:1::0;;6148:13;;576:4:3::1;::::0;2070:9;;6148:28:1;-1:-1:-1;;6148:46:1;2054:25:3::1;;;;:::i;:::-;:41;;2033:116;;;::::0;-1:-1:-1;;;2033:116:3;;13305:2:11;2033:116:3::1;::::0;::::1;13287:21:11::0;13344:2;13324:18;;;13317:30;13383;13363:18;;;13356:58;13431:18;;2033:116:3::1;13103:352:11::0;2033:116:3::1;2178:10;2159:30;::::0;;;:18:::1;:30;::::0;;;;:43;;2193:9;;2159:30;:43:::1;::::0;2193:9;;2159:43:::1;:::i;:::-;::::0;;;-1:-1:-1;2212:32:3::1;::::0;-1:-1:-1;2222:10:3::1;2234:9:::0;2212::::1;:32::i;4317:93::-:0;1109:13:9;:11;:13::i;:::-;4397:5:3::1;4392:11;;;;;;;;:::i;:::-;4378;:25:::0;;-1:-1:-1;;4378:25:3::1;::::0;;::::1;::::0;::::1;;;;;;:::i;:::-;;;;;;4317:93:::0;:::o;7831:334::-;7939:9;7934:225;7954:8;:15;7950:1;:19;7934:225;;;7990:15;8008:8;8017:1;8008:11;;;;;;;;:::i;:::-;;;;;;;7990:29;;8037:8;8033:116;;;8065:14;8071:7;8065:5;:14::i;:::-;8033:116;;;8118:16;8126:7;8118;:16::i;:::-;-1:-1:-1;7971:3:3;;;;:::i;:::-;;;;7934:225;;9271:674:1;9396:4;9718:25;-1:-1:-1;;;;;;9718:25:1;;;;:101;;-1:-1:-1;9794:25:1;-1:-1:-1;;;;;;9794:25:1;;;9718:101;:177;;;-1:-1:-1;;;;;;;;9870:25:1;;;;9271:674::o;1374:130:9:-;1262:7;1288:6;-1:-1:-1;;;;;1288:6:9;41055:10:1;1437:23:9;1429:68;;;;-1:-1:-1;;;1429:68:9;;23262:2:11;1429:68:9;;;23244:21:11;;;23281:18;;;23274:30;23340:34;23320:18;;;23313:62;23392:18;;1429:68:9;23060:356:11;34749:110:1;34825:27;34835:2;34839:8;34825:27;;;;;;;;;;;;:9;:27::i;18367:277::-;18432:4;18486:7;8337:1:3;18467:26:1;;:65;;;;;18519:13;;18509:7;:23;18467:65;:151;;;;-1:-1:-1;;18569:26:1;;;;:17;:26;;;;;;-1:-1:-1;;;18569:44:1;:49;;18367:277::o;1376:247:2:-;799:4:6;822:14;;;:9;:14;;;;;;:19;1516:48:2;;;;-1:-1:-1;;;1516:48:2;;23623:2:11;1516:48:2;;;23605:21:11;23662:2;23642:18;;;23635:30;23701:17;23681:18;;;23674:45;23736:18;;1516:48:2;23421:339:11;1516:48:2;1574:42;1595:5;1602:3;1607:8;1574:20;:42::i;5409:260:3:-;5577:26;;-1:-1:-1;;23914:2:11;23910:15;;;23906:88;5577:26:3;;;23894:101:11;5531:4:3;;;;24011:12:11;;5577:26:3;;;;;;;;;;;;5567:37;;;;;;5551:53;;5621:41;5629:5;5636:17;;5655:6;;5621:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5621:7:3;;-1:-1:-1;;;5621:41:3:i;:::-;5614:48;5409:260;-1:-1:-1;;;;;5409:260:3:o;1176:435:6:-;1250:10;1233:28;;;;:16;:28;;;;;;;;1225:58;;;;-1:-1:-1;;;1225:58:6;;24236:2:11;1225:58:6;;;24218:21:11;24275:2;24255:18;;;24248:30;24314:19;24294:18;;;24287:47;24351:18;;1225:58:6;24034:341:11;1225:58:6;1314:17;;;;:12;:17;;;;;;;;1332:10;1314:29;;;;;;;;:34;1293:108;;;;-1:-1:-1;;;1293:108:6;;24582:2:11;1293:108:6;;;24564:21:11;24621:2;24601:18;;;24594:30;24660:29;24640:18;;;24633:57;24707:18;;1293:108:6;24380:351:11;1293:108:6;1412:13;1428:14;;;:9;:14;;;;;;:18;;1445:1;1428:18;:::i;:::-;1456:12;;;;:7;:12;;;;;;;;:19;;;;;;;;:32;;-1:-1:-1;;;;;;1456:32:6;1478:10;1456:32;;;;;;1498:17;;;:12;:17;;;;;:29;;;;;;;;:37;;;1545:14;;;:9;:14;;;;;:16;;1412:34;;-1:-1:-1;1545:14:6;:16;;;:::i;:::-;;;;-1:-1:-1;;1576:28:6;;1593:10;;1588:3;;1576:28;;;;;1215:396;1176:435;:::o;5812:246:3:-;5973:26;;-1:-1:-1;;23914:2:11;23910:15;;;23906:88;5973:26:3;;;23894:101:11;5927:4:3;;;;24011:12:11;;5973:26:3;;;;;;;;;;;;5963:37;;;;;;5947:53;;6017:34;6025:5;6032:10;;6044:6;;6017:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6017:7:3;;-1:-1:-1;;;6017:34:3:i;1617:660:6:-;1693:10;1676:28;;;;:16;:28;;;;;;;;1668:58;;;;-1:-1:-1;;;1668:58:6;;24236:2:11;1668:58:6;;;24218:21:11;24275:2;24255:18;;;24248:30;24314:19;24294:18;;;24287:47;24351:18;;1668:58:6;24034:341:11;1668:58:6;1736:13;1752:17;;;:12;:17;;;;;;;;1770:10;1752:29;;;;;;;;1799:10;1791:46;;;;-1:-1:-1;;;1791:46:6;;24938:2:11;1791:46:6;;;24920:21:11;24977:2;24957:18;;;24950:30;25016:25;24996:18;;;24989:53;25059:18;;1791:46:6;24736:347:11;1791:46:6;1848:12;1863:14;;;:9;:14;;;;;;1891:13;;;1887:269;;1920:20;1943:12;;;:7;:12;;;;;;;;:18;;;;;;;;;;1975:19;;;;;;:34;;-1:-1:-1;;;;;;1975:34:6;;;-1:-1:-1;;;;;1943:18:6;;;1975:34;;;;;;2023:31;;;;;;2068:17;;;:12;:17;;;;;:31;;;;;;;;:39;;;1887:269;;;2154:1;2124:12;;;:7;:12;;;;;;;;:19;;;;;;;;:32;;-1:-1:-1;;;;;;2124:32:6;;;1887:269;2198:1;2166:17;;;:12;:17;;;;;;;;2184:10;2166:29;;;;;;;:33;;;2209:14;;;:9;:14;;;;;:16;;;;;;:::i;:::-;;;;-1:-1:-1;;2240:30:6;;2259:10;;2254:3;;2240:30;;;;;1658:619;;1617:660;:::o;12879:1277:1:-;12970:7;13008;;8337:1:3;13054:23:1;13050:1042;;13106:13;;13099:4;:20;13095:997;;;13143:14;13160:23;;;:17;:23;;;;;;-1:-1:-1;;;13247:24:1;;13243:831;;13902:111;13909:11;13902:111;;-1:-1:-1;;;13979:6:1;13961:25;;;;:17;:25;;;;;;13902:111;;;14045:6;12879:1277;-1:-1:-1;;;12879:1277:1:o;13243:831::-;13121:971;13095:997;14118:31;;;;;;;;;;;;;;2482:187:9;2555:16;2574:6;;-1:-1:-1;;;;;2590:17:9;;;-1:-1:-1;;;;;;2590:17:9;;;;;;2622:40;;2574:6;;;;;;;2622:40;;2555:16;2622:40;2545:124;2482:187;:::o;8568:179:3:-;8641:12;8659:8;-1:-1:-1;;;;;8659:13:3;8680:7;8659:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8640:52;;;8710:7;8702:38;;;;-1:-1:-1;;;8702:38:3;;25641:2:11;8702:38:3;;;25623:21:11;25680:2;25660:18;;;25653:30;25719:20;25699:18;;;25692:48;25757:18;;8702:38:3;25439:342:11;2283:664:6;-1:-1:-1;;;;;2360:27:6;;;;;;:16;:27;;;;;;;;2359:28;2351:58;;;;-1:-1:-1;;;2351:58:6;;24236:2:11;2351:58:6;;;24218:21:11;24275:2;24255:18;;;24248:30;24314:19;24294:18;;;24287:47;24351:18;;2351:58:6;24034:341:11;2351:58:6;2419:13;2435:17;;;:12;:17;;;;;;;;-1:-1:-1;;;;;2435:28:6;;;;;;;;;;2481:10;2473:36;;;;-1:-1:-1;;;2473:36:6;;25988:2:11;2473:36:6;;;25970:21:11;26027:2;26007:18;;;26000:30;26066:15;26046:18;;;26039:43;26099:18;;2473:36:6;25786:337:11;2473:36:6;2520:12;2535:14;;;:9;:14;;;;;;2563:13;;;2559:269;;2592:20;2615:12;;;:7;:12;;;;;;;;:18;;;;;;;;;;2647:19;;;;;;:34;;-1:-1:-1;;;;;;2647:34:6;;;-1:-1:-1;;;;;2615:18:6;;;2647:34;;;;;;2695:31;;;;;;2740:17;;;:12;:17;;;;;:31;;;;;;;;:39;;;2559:269;;;2826:1;2796:12;;;:7;:12;;;;;;;;:19;;;;;;;;:32;;-1:-1:-1;;;;;;2796:32:6;;;2559:269;2869:1;2838:17;;;:12;:17;;;;;;;;-1:-1:-1;;;;;2838:28:6;;;;;;;;;:32;;;2880:14;;;:9;:14;;;;;:16;;;;;;:::i;:::-;;;;-1:-1:-1;;2911:29:6;;-1:-1:-1;;;;;2911:29:6;;;2925:3;;2911:29;;;;;2341:606;;2283:664;;:::o;1629:290:2:-;799:4:6;822:14;;;:9;:14;;;;;;:19;1801:48:2;;;;-1:-1:-1;;;1801:48:2;;23623:2:11;1801:48:2;;;23605:21:11;23662:2;23642:18;;;23635:30;23701:17;23681:18;;;23674:45;23736:18;;1801:48:2;23421:339:11;1801:48:2;1859:53;1884:5;1891:3;1896:8;1906:5;1859:24;:53::i;410:696:10:-;466:13;515:14;532:17;543:5;532:10;:17::i;:::-;552:1;532:21;515:38;;567:20;601:6;590:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;590:18:10;-1:-1:-1;567:41:10;-1:-1:-1;728:28:10;;;744:2;728:28;783:280;-1:-1:-1;;814:5:10;953:8;948:2;937:14;;932:30;814:5;919:44;1007:2;998:11;;;-1:-1:-1;1031:10:10;1027:21;;1043:5;;1027:21;783:280;;;-1:-1:-1;1083:6:10;410:696;-1:-1:-1;;;410:696:10:o;4962:282:3:-;5146:37;;-1:-1:-1;;26494:2:11;26490:15;;;26486:88;5146:37:3;;;26474:101:11;26591:12;;;26584:28;;;5104:4:3;;;;26628:12:11;;5146:37:3;;;;;;;;;;;;5136:48;;;;;;5120:64;;5201:36;5209:5;5216:12;;5230:6;;5201:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5201:7:3;;-1:-1:-1;;;5201:36:3:i;:::-;5194:43;;;4962:282;;;;;;;:::o;33817:853:1:-;33943:19;33949:2;33953:8;33943:5;:19::i;:::-;-1:-1:-1;;;;;34001:14:1;;;:19;33997:657;;34054:13;;34101:14;;;34133:413;34188:200;34256:1;34288:2;34320:7;;;;;;34357:5;34188:30;:200::i;:::-;34158:349;;34444:40;;-1:-1:-1;;;34444:40:1;;;;;;;;;;;34158:349;34541:3;34533:5;:11;34133:413;;34626:3;34609:13;;:20;34605:34;;34631:8;;;20577:2930;20714:27;20744;20763:7;20744:18;:27::i;:::-;20714:57;;20827:4;-1:-1:-1;;;;;20786:45:1;20802:19;-1:-1:-1;;;;;20786:45:1;;20782:98;;20852:28;;;;;;;;;;;;;;20782:98;20905:27;19710:24;;;:15;:24;;;;;19934:26;;41055:10;19347:30;;;-1:-1:-1;;;;;19044:28:1;;19325:20;;;19322:56;21109:279;;21285:43;21302:4;41055:10;17912:206;:::i;21285:43::-;21280:108;;21353:35;;;;;;;;;;;;;;21280:108;-1:-1:-1;;;;;21403:16:1;;21399:52;;21428:23;;;;;;;;;;;;;;21399:52;21594:15;21591:157;;;21732:1;21711:19;21704:30;21591:157;-1:-1:-1;;;;;22120:24:1;;;;;;;:18;:24;;;;;;22118:26;;-1:-1:-1;;22118:26:1;;;22188:22;;;;;;;;;22186:24;;-1:-1:-1;22186:24:1;;;15184:11;15159:23;15155:41;15109:109;-1:-1:-1;;;15109:109:1;22474:26;;;;:17;:26;;;;;:192;-1:-1:-1;;;22783:47:1;;22779:617;;22887:1;22877:11;;22855:19;23008:30;;;:17;:30;;;;;;23004:378;;23144:13;;23129:11;:28;23125:239;;23289:30;;;;:17;:30;;;;;:52;;;23125:239;22837:559;22779:617;23440:7;23436:2;-1:-1:-1;;;;;23421:27:1;23430:4;-1:-1:-1;;;;;23421:27:1;;;;;;;;;;;20704:2803;;;20577:2930;;;:::o;6064:195:3:-;6189:4;6212:40;6231:6;6239:5;6246;6212:18;:40::i;24366:396:1:-;24535:31;24548:4;24554:2;24558:7;24535:12;:31::i;:::-;-1:-1:-1;;;;;24580:14:1;;;:19;24576:180;;24618:56;24649:4;24655:2;24659:7;24668:5;24618:30;:56::i;:::-;24613:143;;24701:40;;-1:-1:-1;;;24701:40:1;;;;;;;;;;;10009:890:7;10062:7;;10146:6;10137:15;;10133:99;;10181:6;10172:15;;;-1:-1:-1;10215:2:7;10205:12;10133:99;10258:6;10249:5;:15;10245:99;;10293:6;10284:15;;;-1:-1:-1;10327:2:7;10317:12;10245:99;10370:6;10361:5;:15;10357:99;;10405:6;10396:15;;;-1:-1:-1;10439:2:7;10429:12;10357:99;10482:5;10473;:14;10469:96;;10516:5;10507:14;;;-1:-1:-1;10549:1:7;10539:11;10469:96;10591:5;10582;:14;10578:96;;10625:5;10616:14;;;-1:-1:-1;10658:1:7;10648:11;10578:96;10700:5;10691;:14;10687:96;;10734:5;10725:14;;;-1:-1:-1;10767:1:7;10757:11;10687:96;10809:5;10800;:14;10796:64;;10844:1;10834:11;10886:6;10009:890;-1:-1:-1;;10009:890:7:o;28039:2954:1:-;28134:13;;28161;28157:44;;28183:18;;;;;;;;;;;;;;28157:44;-1:-1:-1;;;;;28676:22:1;;;;;;:18;:22;;;;1495:2;28676:22;;;:103;;28746:32;28718:61;;28676:103;;;29015:31;;;:17;:31;;;;;-1:-1:-1;15645:15:1;;15619:24;15615:46;15184:11;15159:23;15155:41;15152:52;15109:109;;29015:190;;29264:23;;;;29015:31;;28676:22;;30016:25;28676:22;;29872:328;30520:1;30506:12;30502:20;30461:339;30560:3;30551:7;30548:16;30461:339;;30774:7;30764:8;30761:1;30734:25;30731:1;30728;30723:59;30612:1;30599:15;30461:339;;;-1:-1:-1;30831:13:1;30827:45;;30853:19;;;;;;;;;;;;;;30827:45;30887:13;:19;-1:-1:-1;6290:299:3;;;:::o;26788:805:1:-;26978:166;;-1:-1:-1;;;26978:166:1;;26946:4;;-1:-1:-1;;;;;26978:45:1;;;;;:166;;41055:10;;27078:4;;27100:7;;27125:5;;26978:166;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26978:166:1;;;;;;;;-1:-1:-1;;26978:166:1;;;;;;;;;;;;:::i;:::-;;;26962:625;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27352:13:1;;27348:229;;27397:40;;-1:-1:-1;;;27397:40:1;;;;;;;;;;;27348:229;27537:6;27531:13;27522:6;27518:2;27514:15;27507:38;26962:625;-1:-1:-1;;;;;;27214:80:1;-1:-1:-1;;;27214:80:1;;-1:-1:-1;27191:103:1;;1153:184:8;1274:4;1326;1297:25;1310:5;1317:4;1297:12;:25::i;:::-;:33;;1153:184;-1:-1:-1;;;;1153:184:8:o;1991:318::-;2098:7;2144:4;2098:7;2158:116;2182:5;:12;2178:1;:16;2158:116;;;2230:33;2240:12;2254:5;2260:1;2254:8;;;;;;;;:::i;:::-;;;;;;;2230:9;:33::i;:::-;2215:48;-1:-1:-1;2196:3:8;;;;:::i;:::-;;;;2158:116;;9128:147;9191:7;9221:1;9217;:5;:51;;9373:13;9468:15;;;9503:4;9496:15;;;9549:4;9533:21;;9217:51;;;-1:-1:-1;9373:13:8;9468:15;;;9503:4;9496:15;9549:4;9533:21;;;9128:147::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:177:11;-1:-1:-1;;;;;;92:5:11;88:78;81:5;78:89;68:117;;181:1;178;171:12;196:245;254:6;307:2;295:9;286:7;282:23;278:32;275:52;;;323:1;320;313:12;275:52;362:9;349:23;381:30;405:5;381:30;:::i;638:196::-;706:20;;-1:-1:-1;;;;;755:54:11;;745:65;;735:93;;824:1;821;814:12;735:93;638:196;;;:::o;839:254::-;907:6;915;968:2;956:9;947:7;943:23;939:32;936:52;;;984:1;981;974:12;936:52;1007:29;1026:9;1007:29;:::i;:::-;997:39;1083:2;1068:18;;;;1055:32;;-1:-1:-1;;;839:254:11:o;1098:258::-;1170:1;1180:113;1194:6;1191:1;1188:13;1180:113;;;1270:11;;;1264:18;1251:11;;;1244:39;1216:2;1209:10;1180:113;;;1311:6;1308:1;1305:13;1302:48;;;-1:-1:-1;;1346:1:11;1328:16;;1321:27;1098:258::o;1361:269::-;1414:3;1452:5;1446:12;1479:6;1474:3;1467:19;1495:63;1551:6;1544:4;1539:3;1535:14;1528:4;1521:5;1517:16;1495:63;:::i;:::-;1612:2;1591:15;-1:-1:-1;;1587:29:11;1578:39;;;;1619:4;1574:50;;1361:269;-1:-1:-1;;1361:269:11:o;1635:231::-;1784:2;1773:9;1766:21;1747:4;1804:56;1856:2;1845:9;1841:18;1833:6;1804:56;:::i;1871:180::-;1930:6;1983:2;1971:9;1962:7;1958:23;1954:32;1951:52;;;1999:1;1996;1989:12;1951:52;-1:-1:-1;2022:23:11;;1871:180;-1:-1:-1;1871:180:11:o;2287:254::-;2355:6;2363;2416:2;2404:9;2395:7;2391:23;2387:32;2384:52;;;2432:1;2429;2422:12;2384:52;2468:9;2455:23;2445:33;;2497:38;2531:2;2520:9;2516:18;2497:38;:::i;:::-;2487:48;;2287:254;;;;;:::o;2910:328::-;2987:6;2995;3003;3056:2;3044:9;3035:7;3031:23;3027:32;3024:52;;;3072:1;3069;3062:12;3024:52;3095:29;3114:9;3095:29;:::i;:::-;3085:39;;3143:38;3177:2;3166:9;3162:18;3143:38;:::i;:::-;3133:48;;3228:2;3217:9;3213:18;3200:32;3190:42;;2910:328;;;;;:::o;3243:367::-;3306:8;3316:6;3370:3;3363:4;3355:6;3351:17;3347:27;3337:55;;3388:1;3385;3378:12;3337:55;-1:-1:-1;3411:20:11;;3454:18;3443:30;;3440:50;;;3486:1;3483;3476:12;3440:50;3523:4;3515:6;3511:17;3499:29;;3583:3;3576:4;3566:6;3563:1;3559:14;3551:6;3547:27;3543:38;3540:47;3537:67;;;3600:1;3597;3590:12;3537:67;3243:367;;;;;:::o;3615:437::-;3701:6;3709;3762:2;3750:9;3741:7;3737:23;3733:32;3730:52;;;3778:1;3775;3768:12;3730:52;3818:9;3805:23;3851:18;3843:6;3840:30;3837:50;;;3883:1;3880;3873:12;3837:50;3922:70;3984:7;3975:6;3964:9;3960:22;3922:70;:::i;:::-;4011:8;;3896:96;;-1:-1:-1;3615:437:11;-1:-1:-1;;;;3615:437:11:o;4242:248::-;4310:6;4318;4371:2;4359:9;4350:7;4346:23;4342:32;4339:52;;;4387:1;4384;4377:12;4339:52;-1:-1:-1;;4410:23:11;;;4480:2;4465:18;;;4452:32;;-1:-1:-1;4242:248:11:o;4495:186::-;4554:6;4607:2;4595:9;4586:7;4582:23;4578:32;4575:52;;;4623:1;4620;4613:12;4575:52;4646:29;4665:9;4646:29;:::i;4686:184::-;-1:-1:-1;;;4735:1:11;4728:88;4835:4;4832:1;4825:15;4859:4;4856:1;4849:15;4875:275;4946:2;4940:9;5011:2;4992:13;;-1:-1:-1;;4988:27:11;4976:40;;5046:18;5031:34;;5067:22;;;5028:62;5025:88;;;5093:18;;:::i;:::-;5129:2;5122:22;4875:275;;-1:-1:-1;4875:275:11:o;5155:407::-;5220:5;5254:18;5246:6;5243:30;5240:56;;;5276:18;;:::i;:::-;5314:57;5359:2;5338:15;;-1:-1:-1;;5334:29:11;5365:4;5330:40;5314:57;:::i;:::-;5305:66;;5394:6;5387:5;5380:21;5434:3;5425:6;5420:3;5416:16;5413:25;5410:45;;;5451:1;5448;5441:12;5410:45;5500:6;5495:3;5488:4;5481:5;5477:16;5464:43;5554:1;5547:4;5538:6;5531:5;5527:18;5523:29;5516:40;5155:407;;;;;:::o;5567:451::-;5636:6;5689:2;5677:9;5668:7;5664:23;5660:32;5657:52;;;5705:1;5702;5695:12;5657:52;5745:9;5732:23;5778:18;5770:6;5767:30;5764:50;;;5810:1;5807;5800:12;5764:50;5833:22;;5886:4;5878:13;;5874:27;-1:-1:-1;5864:55:11;;5915:1;5912;5905:12;5864:55;5938:74;6004:7;5999:2;5986:16;5981:2;5977;5973:11;5938:74;:::i;6023:160::-;6088:20;;6144:13;;6137:21;6127:32;;6117:60;;6173:1;6170;6163:12;6188:254;6253:6;6261;6314:2;6302:9;6293:7;6289:23;6285:32;6282:52;;;6330:1;6327;6320:12;6282:52;6353:29;6372:9;6353:29;:::i;:::-;6343:39;;6401:35;6432:2;6421:9;6417:18;6401:35;:::i;6447:770::-;6566:6;6574;6582;6590;6643:2;6631:9;6622:7;6618:23;6614:32;6611:52;;;6659:1;6656;6649:12;6611:52;6699:9;6686:23;6728:18;6769:2;6761:6;6758:14;6755:34;;;6785:1;6782;6775:12;6755:34;6824:70;6886:7;6877:6;6866:9;6862:22;6824:70;:::i;:::-;6913:8;;-1:-1:-1;6798:96:11;-1:-1:-1;7001:2:11;6986:18;;6973:32;;-1:-1:-1;7017:16:11;;;7014:36;;;7046:1;7043;7036:12;7014:36;;7085:72;7149:7;7138:8;7127:9;7123:24;7085:72;:::i;:::-;6447:770;;;;-1:-1:-1;7176:8:11;-1:-1:-1;;;;6447:770:11:o;7222:667::-;7317:6;7325;7333;7341;7394:3;7382:9;7373:7;7369:23;7365:33;7362:53;;;7411:1;7408;7401:12;7362:53;7434:29;7453:9;7434:29;:::i;:::-;7424:39;;7482:38;7516:2;7505:9;7501:18;7482:38;:::i;:::-;7472:48;;7567:2;7556:9;7552:18;7539:32;7529:42;;7622:2;7611:9;7607:18;7594:32;7649:18;7641:6;7638:30;7635:50;;;7681:1;7678;7671:12;7635:50;7704:22;;7757:4;7749:13;;7745:27;-1:-1:-1;7735:55:11;;7786:1;7783;7776:12;7735:55;7809:74;7875:7;7870:2;7857:16;7852:2;7848;7844:11;7809:74;:::i;:::-;7799:84;;;7222:667;;;;;;;:::o;7894:184::-;-1:-1:-1;;;7943:1:11;7936:88;8043:4;8040:1;8033:15;8067:4;8064:1;8057:15;8083:394;8224:2;8209:18;;8257:1;8246:13;;8236:201;;-1:-1:-1;;;8290:1:11;8283:88;8394:4;8391:1;8384:15;8422:4;8419:1;8412:15;8236:201;8446:25;;;8083:394;:::o;8482:180::-;8538:6;8591:2;8579:9;8570:7;8566:23;8562:32;8559:52;;;8607:1;8604;8597:12;8559:52;8630:26;8646:9;8630:26;:::i;8667:260::-;8735:6;8743;8796:2;8784:9;8775:7;8771:23;8767:32;8764:52;;;8812:1;8809;8802:12;8764:52;8835:29;8854:9;8835:29;:::i;:::-;8825:39;;8883:38;8917:2;8906:9;8902:18;8883:38;:::i;8932:505::-;9027:6;9035;9043;9096:2;9084:9;9075:7;9071:23;9067:32;9064:52;;;9112:1;9109;9102:12;9064:52;9148:9;9135:23;9125:33;;9209:2;9198:9;9194:18;9181:32;9236:18;9228:6;9225:30;9222:50;;;9268:1;9265;9258:12;9222:50;9307:70;9369:7;9360:6;9349:9;9345:22;9307:70;:::i;:::-;8932:505;;9396:8;;-1:-1:-1;9281:96:11;;-1:-1:-1;;;;8932:505:11:o;9442:1016::-;9532:6;9540;9593:2;9581:9;9572:7;9568:23;9564:32;9561:52;;;9609:1;9606;9599:12;9561:52;9649:9;9636:23;9678:18;9719:2;9711:6;9708:14;9705:34;;;9735:1;9732;9725:12;9705:34;9773:6;9762:9;9758:22;9748:32;;9818:7;9811:4;9807:2;9803:13;9799:27;9789:55;;9840:1;9837;9830:12;9789:55;9876:2;9863:16;9898:4;9921:2;9917;9914:10;9911:36;;;9927:18;;:::i;:::-;9973:2;9970:1;9966:10;9956:20;;9996:28;10020:2;10016;10012:11;9996:28;:::i;:::-;10058:15;;;10128:11;;;10124:20;;;10089:12;;;;10156:19;;;10153:39;;;10188:1;10185;10178:12;10153:39;10212:11;;;;10232:142;10248:6;10243:3;10240:15;10232:142;;;10314:17;;10302:30;;10265:12;;;;10352;;;;10232:142;;;10393:5;-1:-1:-1;10417:35:11;;-1:-1:-1;10433:18:11;;;10417:35;:::i;:::-;10407:45;;;;;;9442:1016;;;;;:::o;10865:184::-;-1:-1:-1;;;10914:1:11;10907:88;11014:4;11011:1;11004:15;11038:4;11035:1;11028:15;11054:128;11094:3;11125:1;11121:6;11118:1;11115:13;11112:39;;;11131:18;;:::i;:::-;-1:-1:-1;11167:9:11;;11054:128::o;11535:437::-;11614:1;11610:12;;;;11657;;;11678:61;;11732:4;11724:6;11720:17;11710:27;;11678:61;11785:2;11777:6;11774:14;11754:18;11751:38;11748:218;;;-1:-1:-1;;;11819:1:11;11812:88;11923:4;11920:1;11913:15;11951:4;11948:1;11941:15;11748:218;;11535:437;;;:::o;19411:184::-;-1:-1:-1;;;19460:1:11;19453:88;19560:4;19557:1;19550:15;19584:4;19581:1;19574:15;19600:135;19639:3;-1:-1:-1;;19660:17:11;;19657:43;;;19680:18;;:::i;:::-;-1:-1:-1;19727:1:11;19716:13;;19600:135::o;20226:185::-;20268:3;20306:5;20300:12;20321:52;20366:6;20361:3;20354:4;20347:5;20343:16;20321:52;:::i;:::-;20389:16;;;;;20226:185;-1:-1:-1;;20226:185:11:o;20534:1358::-;20811:3;20840:1;20873:6;20867:13;20903:3;20925:1;20953:9;20949:2;20945:18;20935:28;;21013:2;21002:9;20998:18;21035;21025:61;;21079:4;21071:6;21067:17;21057:27;;21025:61;21105:2;21153;21145:6;21142:14;21122:18;21119:38;21116:222;;;-1:-1:-1;;;21187:3:11;21180:90;21293:4;21290:1;21283:15;21323:4;21318:3;21311:17;21116:222;21354:18;21381:104;;;;21499:1;21494:320;;;;21347:467;;21381:104;-1:-1:-1;;21414:24:11;;21402:37;;21459:16;;;;-1:-1:-1;21381:104:11;;21494:320;20173:1;20166:14;;;20210:4;20197:18;;21589:1;21603:165;21617:6;21614:1;21611:13;21603:165;;;21695:14;;21682:11;;;21675:35;21738:16;;;;21632:10;;21603:165;;;21607:3;;21797:6;21792:3;21788:16;21781:23;;21347:467;;;;;;;21830:56;21855:30;21881:3;21873:6;21855:30;:::i;:::-;20488:7;20476:20;;20521:1;20512:11;;20416:113;25088:136;25127:3;25155:5;25145:39;;25164:18;;:::i;:::-;-1:-1:-1;;;25200:18:11;;25088:136::o;26651:523::-;26845:4;-1:-1:-1;;;;;26955:2:11;26947:6;26943:15;26932:9;26925:34;27007:2;26999:6;26995:15;26990:2;26979:9;26975:18;26968:43;;27047:6;27042:2;27031:9;27027:18;27020:34;27090:3;27085:2;27074:9;27070:18;27063:31;27111:57;27163:3;27152:9;27148:19;27140:6;27111:57;:::i;:::-;27103:65;26651:523;-1:-1:-1;;;;;;26651:523:11:o;27179:249::-;27248:6;27301:2;27289:9;27280:7;27276:23;27272:32;27269:52;;;27317:1;27314;27307:12;27269:52;27349:9;27343:16;27368:30;27392:5;27368:30;:::i

Swarm Source

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